1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Device access for Dialog DA9055 PMICs.
5 * Copyright(c) 2012 Dialog Semiconductor Ltd.
7 * Author: David Dajun Chen <dchen@diasemi.com>
10 #include <linux/module.h>
11 #include <linux/device.h>
12 #include <linux/input.h>
13 #include <linux/irq.h>
14 #include <linux/mutex.h>
16 #include <linux/mfd/core.h>
17 #include <linux/mfd/da9055/core.h>
18 #include <linux/mfd/da9055/pdata.h>
19 #include <linux/mfd/da9055/reg.h>
21 #define DA9055_IRQ_NONKEY_MASK 0x01
22 #define DA9055_IRQ_ALM_MASK 0x02
23 #define DA9055_IRQ_TICK_MASK 0x04
24 #define DA9055_IRQ_ADC_MASK 0x08
25 #define DA9055_IRQ_BUCK_ILIM_MASK 0x08
27 static bool da9055_register_readable(struct device
*dev
, unsigned int reg
)
30 case DA9055_REG_STATUS_A
:
31 case DA9055_REG_STATUS_B
:
32 case DA9055_REG_EVENT_A
:
33 case DA9055_REG_EVENT_B
:
34 case DA9055_REG_EVENT_C
:
35 case DA9055_REG_IRQ_MASK_A
:
36 case DA9055_REG_IRQ_MASK_B
:
37 case DA9055_REG_IRQ_MASK_C
:
39 case DA9055_REG_CONTROL_A
:
40 case DA9055_REG_CONTROL_B
:
41 case DA9055_REG_CONTROL_C
:
42 case DA9055_REG_CONTROL_D
:
43 case DA9055_REG_CONTROL_E
:
45 case DA9055_REG_ADC_MAN
:
46 case DA9055_REG_ADC_CONT
:
47 case DA9055_REG_VSYS_MON
:
48 case DA9055_REG_ADC_RES_L
:
49 case DA9055_REG_ADC_RES_H
:
50 case DA9055_REG_VSYS_RES
:
51 case DA9055_REG_ADCIN1_RES
:
52 case DA9055_REG_ADCIN2_RES
:
53 case DA9055_REG_ADCIN3_RES
:
55 case DA9055_REG_COUNT_S
:
56 case DA9055_REG_COUNT_MI
:
57 case DA9055_REG_COUNT_H
:
58 case DA9055_REG_COUNT_D
:
59 case DA9055_REG_COUNT_MO
:
60 case DA9055_REG_COUNT_Y
:
61 case DA9055_REG_ALARM_H
:
62 case DA9055_REG_ALARM_D
:
63 case DA9055_REG_ALARM_MI
:
64 case DA9055_REG_ALARM_MO
:
65 case DA9055_REG_ALARM_Y
:
67 case DA9055_REG_GPIO0_1
:
68 case DA9055_REG_GPIO2
:
69 case DA9055_REG_GPIO_MODE0_2
:
71 case DA9055_REG_BCORE_CONT
:
72 case DA9055_REG_BMEM_CONT
:
73 case DA9055_REG_LDO1_CONT
:
74 case DA9055_REG_LDO2_CONT
:
75 case DA9055_REG_LDO3_CONT
:
76 case DA9055_REG_LDO4_CONT
:
77 case DA9055_REG_LDO5_CONT
:
78 case DA9055_REG_LDO6_CONT
:
79 case DA9055_REG_BUCK_LIM
:
80 case DA9055_REG_BCORE_MODE
:
81 case DA9055_REG_VBCORE_A
:
82 case DA9055_REG_VBMEM_A
:
83 case DA9055_REG_VLDO1_A
:
84 case DA9055_REG_VLDO2_A
:
85 case DA9055_REG_VLDO3_A
:
86 case DA9055_REG_VLDO4_A
:
87 case DA9055_REG_VLDO5_A
:
88 case DA9055_REG_VLDO6_A
:
89 case DA9055_REG_VBCORE_B
:
90 case DA9055_REG_VBMEM_B
:
91 case DA9055_REG_VLDO1_B
:
92 case DA9055_REG_VLDO2_B
:
93 case DA9055_REG_VLDO3_B
:
94 case DA9055_REG_VLDO4_B
:
95 case DA9055_REG_VLDO5_B
:
96 case DA9055_REG_VLDO6_B
:
103 static bool da9055_register_writeable(struct device
*dev
, unsigned int reg
)
106 case DA9055_REG_STATUS_A
:
107 case DA9055_REG_STATUS_B
:
108 case DA9055_REG_EVENT_A
:
109 case DA9055_REG_EVENT_B
:
110 case DA9055_REG_EVENT_C
:
111 case DA9055_REG_IRQ_MASK_A
:
112 case DA9055_REG_IRQ_MASK_B
:
113 case DA9055_REG_IRQ_MASK_C
:
115 case DA9055_REG_CONTROL_A
:
116 case DA9055_REG_CONTROL_B
:
117 case DA9055_REG_CONTROL_C
:
118 case DA9055_REG_CONTROL_D
:
119 case DA9055_REG_CONTROL_E
:
121 case DA9055_REG_ADC_MAN
:
122 case DA9055_REG_ADC_CONT
:
123 case DA9055_REG_VSYS_MON
:
124 case DA9055_REG_ADC_RES_L
:
125 case DA9055_REG_ADC_RES_H
:
126 case DA9055_REG_VSYS_RES
:
127 case DA9055_REG_ADCIN1_RES
:
128 case DA9055_REG_ADCIN2_RES
:
129 case DA9055_REG_ADCIN3_RES
:
131 case DA9055_REG_COUNT_S
:
132 case DA9055_REG_COUNT_MI
:
133 case DA9055_REG_COUNT_H
:
134 case DA9055_REG_COUNT_D
:
135 case DA9055_REG_COUNT_MO
:
136 case DA9055_REG_COUNT_Y
:
137 case DA9055_REG_ALARM_H
:
138 case DA9055_REG_ALARM_D
:
139 case DA9055_REG_ALARM_MI
:
140 case DA9055_REG_ALARM_MO
:
141 case DA9055_REG_ALARM_Y
:
143 case DA9055_REG_GPIO0_1
:
144 case DA9055_REG_GPIO2
:
145 case DA9055_REG_GPIO_MODE0_2
:
147 case DA9055_REG_BCORE_CONT
:
148 case DA9055_REG_BMEM_CONT
:
149 case DA9055_REG_LDO1_CONT
:
150 case DA9055_REG_LDO2_CONT
:
151 case DA9055_REG_LDO3_CONT
:
152 case DA9055_REG_LDO4_CONT
:
153 case DA9055_REG_LDO5_CONT
:
154 case DA9055_REG_LDO6_CONT
:
155 case DA9055_REG_BUCK_LIM
:
156 case DA9055_REG_BCORE_MODE
:
157 case DA9055_REG_VBCORE_A
:
158 case DA9055_REG_VBMEM_A
:
159 case DA9055_REG_VLDO1_A
:
160 case DA9055_REG_VLDO2_A
:
161 case DA9055_REG_VLDO3_A
:
162 case DA9055_REG_VLDO4_A
:
163 case DA9055_REG_VLDO5_A
:
164 case DA9055_REG_VLDO6_A
:
165 case DA9055_REG_VBCORE_B
:
166 case DA9055_REG_VBMEM_B
:
167 case DA9055_REG_VLDO1_B
:
168 case DA9055_REG_VLDO2_B
:
169 case DA9055_REG_VLDO3_B
:
170 case DA9055_REG_VLDO4_B
:
171 case DA9055_REG_VLDO5_B
:
172 case DA9055_REG_VLDO6_B
:
179 static bool da9055_register_volatile(struct device
*dev
, unsigned int reg
)
182 case DA9055_REG_STATUS_A
:
183 case DA9055_REG_STATUS_B
:
184 case DA9055_REG_EVENT_A
:
185 case DA9055_REG_EVENT_B
:
186 case DA9055_REG_EVENT_C
:
188 case DA9055_REG_CONTROL_A
:
189 case DA9055_REG_CONTROL_E
:
191 case DA9055_REG_ADC_MAN
:
192 case DA9055_REG_ADC_RES_L
:
193 case DA9055_REG_ADC_RES_H
:
194 case DA9055_REG_VSYS_RES
:
195 case DA9055_REG_ADCIN1_RES
:
196 case DA9055_REG_ADCIN2_RES
:
197 case DA9055_REG_ADCIN3_RES
:
199 case DA9055_REG_COUNT_S
:
200 case DA9055_REG_COUNT_MI
:
201 case DA9055_REG_COUNT_H
:
202 case DA9055_REG_COUNT_D
:
203 case DA9055_REG_COUNT_MO
:
204 case DA9055_REG_COUNT_Y
:
205 case DA9055_REG_ALARM_MI
:
207 case DA9055_REG_BCORE_CONT
:
208 case DA9055_REG_BMEM_CONT
:
209 case DA9055_REG_LDO1_CONT
:
210 case DA9055_REG_LDO2_CONT
:
211 case DA9055_REG_LDO3_CONT
:
212 case DA9055_REG_LDO4_CONT
:
213 case DA9055_REG_LDO5_CONT
:
214 case DA9055_REG_LDO6_CONT
:
221 static const struct regmap_irq da9055_irqs
[] = {
222 [DA9055_IRQ_NONKEY
] = {
224 .mask
= DA9055_IRQ_NONKEY_MASK
,
226 [DA9055_IRQ_ALARM
] = {
228 .mask
= DA9055_IRQ_ALM_MASK
,
230 [DA9055_IRQ_TICK
] = {
232 .mask
= DA9055_IRQ_TICK_MASK
,
234 [DA9055_IRQ_HWMON
] = {
236 .mask
= DA9055_IRQ_ADC_MASK
,
238 [DA9055_IRQ_REGULATOR
] = {
240 .mask
= DA9055_IRQ_BUCK_ILIM_MASK
,
244 const struct regmap_config da9055_regmap_config
= {
248 .cache_type
= REGCACHE_RBTREE
,
250 .max_register
= DA9055_MAX_REGISTER_CNT
,
251 .readable_reg
= da9055_register_readable
,
252 .writeable_reg
= da9055_register_writeable
,
253 .volatile_reg
= da9055_register_volatile
,
255 EXPORT_SYMBOL_GPL(da9055_regmap_config
);
257 static const struct resource da9055_onkey_resource
= {
259 .start
= DA9055_IRQ_NONKEY
,
260 .end
= DA9055_IRQ_NONKEY
,
261 .flags
= IORESOURCE_IRQ
,
264 static const struct resource da9055_rtc_resource
[] = {
267 .start
= DA9055_IRQ_ALARM
,
268 .end
= DA9055_IRQ_ALARM
,
269 .flags
= IORESOURCE_IRQ
,
273 .start
= DA9055_IRQ_TICK
,
274 .end
= DA9055_IRQ_TICK
,
275 .flags
= IORESOURCE_IRQ
,
279 static const struct resource da9055_hwmon_resource
= {
281 .start
= DA9055_IRQ_HWMON
,
282 .end
= DA9055_IRQ_HWMON
,
283 .flags
= IORESOURCE_IRQ
,
286 static const struct resource da9055_ld05_6_resource
= {
288 .start
= DA9055_IRQ_REGULATOR
,
289 .end
= DA9055_IRQ_REGULATOR
,
290 .flags
= IORESOURCE_IRQ
,
293 static const struct mfd_cell da9055_devs
[] = {
295 .of_compatible
= "dlg,da9055-gpio",
296 .name
= "da9055-gpio",
299 .of_compatible
= "dlg,da9055-regulator",
300 .name
= "da9055-regulator",
304 .of_compatible
= "dlg,da9055-regulator",
305 .name
= "da9055-regulator",
309 .of_compatible
= "dlg,da9055-regulator",
310 .name
= "da9055-regulator",
314 .of_compatible
= "dlg,da9055-regulator",
315 .name
= "da9055-regulator",
319 .of_compatible
= "dlg,da9055-regulator",
320 .name
= "da9055-regulator",
324 .of_compatible
= "dlg,da9055-regulator",
325 .name
= "da9055-regulator",
329 .of_compatible
= "dlg,da9055-regulator",
330 .name
= "da9055-regulator",
332 .resources
= &da9055_ld05_6_resource
,
336 .of_compatible
= "dlg,da9055-regulator",
337 .name
= "da9055-regulator",
338 .resources
= &da9055_ld05_6_resource
,
343 .of_compatible
= "dlg,da9055-onkey",
344 .name
= "da9055-onkey",
345 .resources
= &da9055_onkey_resource
,
349 .of_compatible
= "dlg,da9055-rtc",
350 .name
= "da9055-rtc",
351 .resources
= da9055_rtc_resource
,
352 .num_resources
= ARRAY_SIZE(da9055_rtc_resource
),
355 .of_compatible
= "dlg,da9055-hwmon",
356 .name
= "da9055-hwmon",
357 .resources
= &da9055_hwmon_resource
,
361 .of_compatible
= "dlg,da9055-watchdog",
362 .name
= "da9055-watchdog",
366 static const struct regmap_irq_chip da9055_regmap_irq_chip
= {
367 .name
= "da9055_irq",
368 .status_base
= DA9055_REG_EVENT_A
,
369 .mask_base
= DA9055_REG_IRQ_MASK_A
,
370 .ack_base
= DA9055_REG_EVENT_A
,
373 .num_irqs
= ARRAY_SIZE(da9055_irqs
),
376 int da9055_device_init(struct da9055
*da9055
)
378 struct da9055_pdata
*pdata
= dev_get_platdata(da9055
->dev
);
380 uint8_t clear_events
[3] = {0xFF, 0xFF, 0xFF};
382 if (pdata
&& pdata
->init
!= NULL
)
385 if (!pdata
|| !pdata
->irq_base
)
386 da9055
->irq_base
= -1;
388 da9055
->irq_base
= pdata
->irq_base
;
390 ret
= da9055_group_write(da9055
, DA9055_REG_EVENT_A
, 3, clear_events
);
394 ret
= regmap_add_irq_chip(da9055
->regmap
, da9055
->chip_irq
,
395 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
,
396 da9055
->irq_base
, &da9055_regmap_irq_chip
,
401 da9055
->irq_base
= regmap_irq_chip_get_base(da9055
->irq_data
);
403 ret
= mfd_add_devices(da9055
->dev
, -1,
404 da9055_devs
, ARRAY_SIZE(da9055_devs
),
405 NULL
, da9055
->irq_base
, NULL
);
412 mfd_remove_devices(da9055
->dev
);
416 void da9055_device_exit(struct da9055
*da9055
)
418 regmap_del_irq_chip(da9055
->chip_irq
, da9055
->irq_data
);
419 mfd_remove_devices(da9055
->dev
);
422 MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
423 MODULE_LICENSE("GPL");
424 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");