2 * Device access for Dialog DA9052 PMICs.
4 * Copyright(c) 2011 Dialog Semiconductor Ltd.
6 * Author: David Dajun Chen <dchen@diasemi.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
14 #include <linux/device.h>
15 #include <linux/delay.h>
16 #include <linux/input.h>
17 #include <linux/interrupt.h>
18 #include <linux/irq.h>
19 #include <linux/mutex.h>
20 #include <linux/mfd/core.h>
21 #include <linux/slab.h>
22 #include <linux/module.h>
24 #include <linux/mfd/da9052/da9052.h>
25 #include <linux/mfd/da9052/pdata.h>
26 #include <linux/mfd/da9052/reg.h>
28 #define DA9052_NUM_IRQ_REGS 4
29 #define DA9052_IRQ_MASK_POS_1 0x01
30 #define DA9052_IRQ_MASK_POS_2 0x02
31 #define DA9052_IRQ_MASK_POS_3 0x04
32 #define DA9052_IRQ_MASK_POS_4 0x08
33 #define DA9052_IRQ_MASK_POS_5 0x10
34 #define DA9052_IRQ_MASK_POS_6 0x20
35 #define DA9052_IRQ_MASK_POS_7 0x40
36 #define DA9052_IRQ_MASK_POS_8 0x80
38 static bool da9052_reg_readable(struct device
*dev
, unsigned int reg
)
41 case DA9052_PAGE0_CON_REG
:
42 case DA9052_STATUS_A_REG
:
43 case DA9052_STATUS_B_REG
:
44 case DA9052_STATUS_C_REG
:
45 case DA9052_STATUS_D_REG
:
46 case DA9052_EVENT_A_REG
:
47 case DA9052_EVENT_B_REG
:
48 case DA9052_EVENT_C_REG
:
49 case DA9052_EVENT_D_REG
:
50 case DA9052_FAULTLOG_REG
:
51 case DA9052_IRQ_MASK_A_REG
:
52 case DA9052_IRQ_MASK_B_REG
:
53 case DA9052_IRQ_MASK_C_REG
:
54 case DA9052_IRQ_MASK_D_REG
:
55 case DA9052_CONTROL_A_REG
:
56 case DA9052_CONTROL_B_REG
:
57 case DA9052_CONTROL_C_REG
:
58 case DA9052_CONTROL_D_REG
:
59 case DA9052_PDDIS_REG
:
60 case DA9052_INTERFACE_REG
:
61 case DA9052_RESET_REG
:
62 case DA9052_GPIO_0_1_REG
:
63 case DA9052_GPIO_2_3_REG
:
64 case DA9052_GPIO_4_5_REG
:
65 case DA9052_GPIO_6_7_REG
:
66 case DA9052_GPIO_14_15_REG
:
67 case DA9052_ID_0_1_REG
:
68 case DA9052_ID_2_3_REG
:
69 case DA9052_ID_4_5_REG
:
70 case DA9052_ID_6_7_REG
:
71 case DA9052_ID_8_9_REG
:
72 case DA9052_ID_10_11_REG
:
73 case DA9052_ID_12_13_REG
:
74 case DA9052_ID_14_15_REG
:
75 case DA9052_ID_16_17_REG
:
76 case DA9052_ID_18_19_REG
:
77 case DA9052_ID_20_21_REG
:
78 case DA9052_SEQ_STATUS_REG
:
79 case DA9052_SEQ_A_REG
:
80 case DA9052_SEQ_B_REG
:
81 case DA9052_SEQ_TIMER_REG
:
82 case DA9052_BUCKA_REG
:
83 case DA9052_BUCKB_REG
:
84 case DA9052_BUCKCORE_REG
:
85 case DA9052_BUCKPRO_REG
:
86 case DA9052_BUCKMEM_REG
:
87 case DA9052_BUCKPERI_REG
:
97 case DA9052_LDO10_REG
:
98 case DA9052_SUPPLY_REG
:
99 case DA9052_PULLDOWN_REG
:
100 case DA9052_CHGBUCK_REG
:
101 case DA9052_WAITCONT_REG
:
102 case DA9052_ISET_REG
:
103 case DA9052_BATCHG_REG
:
104 case DA9052_CHG_CONT_REG
:
105 case DA9052_INPUT_CONT_REG
:
106 case DA9052_CHG_TIME_REG
:
107 case DA9052_BBAT_CONT_REG
:
108 case DA9052_BOOST_REG
:
109 case DA9052_LED_CONT_REG
:
110 case DA9052_LEDMIN123_REG
:
111 case DA9052_LED1_CONF_REG
:
112 case DA9052_LED2_CONF_REG
:
113 case DA9052_LED3_CONF_REG
:
114 case DA9052_LED1CONT_REG
:
115 case DA9052_LED2CONT_REG
:
116 case DA9052_LED3CONT_REG
:
117 case DA9052_LED_CONT_4_REG
:
118 case DA9052_LED_CONT_5_REG
:
119 case DA9052_ADC_MAN_REG
:
120 case DA9052_ADC_CONT_REG
:
121 case DA9052_ADC_RES_L_REG
:
122 case DA9052_ADC_RES_H_REG
:
123 case DA9052_VDD_RES_REG
:
124 case DA9052_VDD_MON_REG
:
125 case DA9052_ICHG_AV_REG
:
126 case DA9052_ICHG_THD_REG
:
127 case DA9052_ICHG_END_REG
:
128 case DA9052_TBAT_RES_REG
:
129 case DA9052_TBAT_HIGHP_REG
:
130 case DA9052_TBAT_HIGHN_REG
:
131 case DA9052_TBAT_LOW_REG
:
132 case DA9052_T_OFFSET_REG
:
133 case DA9052_ADCIN4_RES_REG
:
134 case DA9052_AUTO4_HIGH_REG
:
135 case DA9052_AUTO4_LOW_REG
:
136 case DA9052_ADCIN5_RES_REG
:
137 case DA9052_AUTO5_HIGH_REG
:
138 case DA9052_AUTO5_LOW_REG
:
139 case DA9052_ADCIN6_RES_REG
:
140 case DA9052_AUTO6_HIGH_REG
:
141 case DA9052_AUTO6_LOW_REG
:
142 case DA9052_TJUNC_RES_REG
:
143 case DA9052_TSI_CONT_A_REG
:
144 case DA9052_TSI_CONT_B_REG
:
145 case DA9052_TSI_X_MSB_REG
:
146 case DA9052_TSI_Y_MSB_REG
:
147 case DA9052_TSI_LSB_REG
:
148 case DA9052_TSI_Z_MSB_REG
:
149 case DA9052_COUNT_S_REG
:
150 case DA9052_COUNT_MI_REG
:
151 case DA9052_COUNT_H_REG
:
152 case DA9052_COUNT_D_REG
:
153 case DA9052_COUNT_MO_REG
:
154 case DA9052_COUNT_Y_REG
:
155 case DA9052_ALARM_MI_REG
:
156 case DA9052_ALARM_H_REG
:
157 case DA9052_ALARM_D_REG
:
158 case DA9052_ALARM_MO_REG
:
159 case DA9052_ALARM_Y_REG
:
160 case DA9052_SECOND_A_REG
:
161 case DA9052_SECOND_B_REG
:
162 case DA9052_SECOND_C_REG
:
163 case DA9052_SECOND_D_REG
:
164 case DA9052_PAGE1_CON_REG
:
171 static bool da9052_reg_writeable(struct device
*dev
, unsigned int reg
)
174 case DA9052_PAGE0_CON_REG
:
175 case DA9052_EVENT_A_REG
:
176 case DA9052_EVENT_B_REG
:
177 case DA9052_EVENT_C_REG
:
178 case DA9052_EVENT_D_REG
:
179 case DA9052_IRQ_MASK_A_REG
:
180 case DA9052_IRQ_MASK_B_REG
:
181 case DA9052_IRQ_MASK_C_REG
:
182 case DA9052_IRQ_MASK_D_REG
:
183 case DA9052_CONTROL_A_REG
:
184 case DA9052_CONTROL_B_REG
:
185 case DA9052_CONTROL_C_REG
:
186 case DA9052_CONTROL_D_REG
:
187 case DA9052_PDDIS_REG
:
188 case DA9052_RESET_REG
:
189 case DA9052_GPIO_0_1_REG
:
190 case DA9052_GPIO_2_3_REG
:
191 case DA9052_GPIO_4_5_REG
:
192 case DA9052_GPIO_6_7_REG
:
193 case DA9052_GPIO_14_15_REG
:
194 case DA9052_ID_0_1_REG
:
195 case DA9052_ID_2_3_REG
:
196 case DA9052_ID_4_5_REG
:
197 case DA9052_ID_6_7_REG
:
198 case DA9052_ID_8_9_REG
:
199 case DA9052_ID_10_11_REG
:
200 case DA9052_ID_12_13_REG
:
201 case DA9052_ID_14_15_REG
:
202 case DA9052_ID_16_17_REG
:
203 case DA9052_ID_18_19_REG
:
204 case DA9052_ID_20_21_REG
:
205 case DA9052_SEQ_STATUS_REG
:
206 case DA9052_SEQ_A_REG
:
207 case DA9052_SEQ_B_REG
:
208 case DA9052_SEQ_TIMER_REG
:
209 case DA9052_BUCKA_REG
:
210 case DA9052_BUCKB_REG
:
211 case DA9052_BUCKCORE_REG
:
212 case DA9052_BUCKPRO_REG
:
213 case DA9052_BUCKMEM_REG
:
214 case DA9052_BUCKPERI_REG
:
215 case DA9052_LDO1_REG
:
216 case DA9052_LDO2_REG
:
217 case DA9052_LDO3_REG
:
218 case DA9052_LDO4_REG
:
219 case DA9052_LDO5_REG
:
220 case DA9052_LDO6_REG
:
221 case DA9052_LDO7_REG
:
222 case DA9052_LDO8_REG
:
223 case DA9052_LDO9_REG
:
224 case DA9052_LDO10_REG
:
225 case DA9052_SUPPLY_REG
:
226 case DA9052_PULLDOWN_REG
:
227 case DA9052_CHGBUCK_REG
:
228 case DA9052_WAITCONT_REG
:
229 case DA9052_ISET_REG
:
230 case DA9052_BATCHG_REG
:
231 case DA9052_CHG_CONT_REG
:
232 case DA9052_INPUT_CONT_REG
:
233 case DA9052_BBAT_CONT_REG
:
234 case DA9052_BOOST_REG
:
235 case DA9052_LED_CONT_REG
:
236 case DA9052_LEDMIN123_REG
:
237 case DA9052_LED1_CONF_REG
:
238 case DA9052_LED2_CONF_REG
:
239 case DA9052_LED3_CONF_REG
:
240 case DA9052_LED1CONT_REG
:
241 case DA9052_LED2CONT_REG
:
242 case DA9052_LED3CONT_REG
:
243 case DA9052_LED_CONT_4_REG
:
244 case DA9052_LED_CONT_5_REG
:
245 case DA9052_ADC_MAN_REG
:
246 case DA9052_ADC_CONT_REG
:
247 case DA9052_ADC_RES_L_REG
:
248 case DA9052_ADC_RES_H_REG
:
249 case DA9052_VDD_RES_REG
:
250 case DA9052_VDD_MON_REG
:
251 case DA9052_ICHG_THD_REG
:
252 case DA9052_ICHG_END_REG
:
253 case DA9052_TBAT_HIGHP_REG
:
254 case DA9052_TBAT_HIGHN_REG
:
255 case DA9052_TBAT_LOW_REG
:
256 case DA9052_T_OFFSET_REG
:
257 case DA9052_AUTO4_HIGH_REG
:
258 case DA9052_AUTO4_LOW_REG
:
259 case DA9052_AUTO5_HIGH_REG
:
260 case DA9052_AUTO5_LOW_REG
:
261 case DA9052_AUTO6_HIGH_REG
:
262 case DA9052_AUTO6_LOW_REG
:
263 case DA9052_TSI_CONT_A_REG
:
264 case DA9052_TSI_CONT_B_REG
:
265 case DA9052_COUNT_S_REG
:
266 case DA9052_COUNT_MI_REG
:
267 case DA9052_COUNT_H_REG
:
268 case DA9052_COUNT_D_REG
:
269 case DA9052_COUNT_MO_REG
:
270 case DA9052_COUNT_Y_REG
:
271 case DA9052_ALARM_MI_REG
:
272 case DA9052_ALARM_H_REG
:
273 case DA9052_ALARM_D_REG
:
274 case DA9052_ALARM_MO_REG
:
275 case DA9052_ALARM_Y_REG
:
276 case DA9052_PAGE1_CON_REG
:
283 static bool da9052_reg_volatile(struct device
*dev
, unsigned int reg
)
286 case DA9052_STATUS_A_REG
:
287 case DA9052_STATUS_B_REG
:
288 case DA9052_STATUS_C_REG
:
289 case DA9052_STATUS_D_REG
:
290 case DA9052_EVENT_A_REG
:
291 case DA9052_EVENT_B_REG
:
292 case DA9052_EVENT_C_REG
:
293 case DA9052_EVENT_D_REG
:
294 case DA9052_FAULTLOG_REG
:
295 case DA9052_CHG_TIME_REG
:
296 case DA9052_ADC_RES_L_REG
:
297 case DA9052_ADC_RES_H_REG
:
298 case DA9052_VDD_RES_REG
:
299 case DA9052_ICHG_AV_REG
:
300 case DA9052_TBAT_RES_REG
:
301 case DA9052_ADCIN4_RES_REG
:
302 case DA9052_ADCIN5_RES_REG
:
303 case DA9052_ADCIN6_RES_REG
:
304 case DA9052_TJUNC_RES_REG
:
305 case DA9052_TSI_X_MSB_REG
:
306 case DA9052_TSI_Y_MSB_REG
:
307 case DA9052_TSI_LSB_REG
:
308 case DA9052_TSI_Z_MSB_REG
:
309 case DA9052_COUNT_S_REG
:
310 case DA9052_COUNT_MI_REG
:
311 case DA9052_COUNT_H_REG
:
312 case DA9052_COUNT_D_REG
:
313 case DA9052_COUNT_MO_REG
:
314 case DA9052_COUNT_Y_REG
:
315 case DA9052_ALARM_MI_REG
:
322 static struct resource da9052_rtc_resource
= {
324 .start
= DA9052_IRQ_ALARM
,
325 .end
= DA9052_IRQ_ALARM
,
326 .flags
= IORESOURCE_IRQ
,
329 static struct resource da9052_onkey_resource
= {
331 .start
= DA9052_IRQ_NONKEY
,
332 .end
= DA9052_IRQ_NONKEY
,
333 .flags
= IORESOURCE_IRQ
,
336 static struct resource da9052_bat_resources
[] = {
339 .start
= DA9052_IRQ_TBAT
,
340 .end
= DA9052_IRQ_TBAT
,
341 .flags
= IORESOURCE_IRQ
,
345 .start
= DA9052_IRQ_DCIN
,
346 .end
= DA9052_IRQ_DCIN
,
347 .flags
= IORESOURCE_IRQ
,
351 .start
= DA9052_IRQ_DCINREM
,
352 .end
= DA9052_IRQ_DCINREM
,
353 .flags
= IORESOURCE_IRQ
,
357 .start
= DA9052_IRQ_VBUS
,
358 .end
= DA9052_IRQ_VBUS
,
359 .flags
= IORESOURCE_IRQ
,
363 .start
= DA9052_IRQ_VBUSREM
,
364 .end
= DA9052_IRQ_VBUSREM
,
365 .flags
= IORESOURCE_IRQ
,
369 .start
= DA9052_IRQ_CHGEND
,
370 .end
= DA9052_IRQ_CHGEND
,
371 .flags
= IORESOURCE_IRQ
,
375 static struct resource da9052_tsi_resources
[] = {
378 .start
= DA9052_IRQ_PENDOWN
,
379 .end
= DA9052_IRQ_PENDOWN
,
380 .flags
= IORESOURCE_IRQ
,
384 .start
= DA9052_IRQ_TSIREADY
,
385 .end
= DA9052_IRQ_TSIREADY
,
386 .flags
= IORESOURCE_IRQ
,
390 static struct mfd_cell __devinitdata da9052_subdev_info
[] = {
392 .name
= "da9052-regulator",
396 .name
= "da9052-regulator",
400 .name
= "da9052-regulator",
404 .name
= "da9052-regulator",
408 .name
= "da9052-regulator",
412 .name
= "da9052-regulator",
416 .name
= "da9052-regulator",
420 .name
= "da9052-regulator",
424 .name
= "da9052-regulator",
428 .name
= "da9052-regulator",
432 .name
= "da9052-regulator",
436 .name
= "da9052-regulator",
440 .name
= "da9052-regulator",
444 .name
= "da9052-regulator",
448 .name
= "da9052-onkey",
449 .resources
= &da9052_onkey_resource
,
453 .name
= "da9052-rtc",
454 .resources
= &da9052_rtc_resource
,
458 .name
= "da9052-gpio",
461 .name
= "da9052-hwmon",
464 .name
= "da9052-leds",
467 .name
= "da9052-wled1",
470 .name
= "da9052-wled2",
473 .name
= "da9052-wled3",
476 .name
= "da9052-tsi",
477 .resources
= da9052_tsi_resources
,
478 .num_resources
= ARRAY_SIZE(da9052_tsi_resources
),
481 .name
= "da9052-bat",
482 .resources
= da9052_bat_resources
,
483 .num_resources
= ARRAY_SIZE(da9052_bat_resources
),
486 .name
= "da9052-watchdog",
490 static struct regmap_irq da9052_irqs
[] = {
491 [DA9052_IRQ_DCIN
] = {
493 .mask
= DA9052_IRQ_MASK_POS_1
,
495 [DA9052_IRQ_VBUS
] = {
497 .mask
= DA9052_IRQ_MASK_POS_2
,
499 [DA9052_IRQ_DCINREM
] = {
501 .mask
= DA9052_IRQ_MASK_POS_3
,
503 [DA9052_IRQ_VBUSREM
] = {
505 .mask
= DA9052_IRQ_MASK_POS_4
,
507 [DA9052_IRQ_VDDLOW
] = {
509 .mask
= DA9052_IRQ_MASK_POS_5
,
511 [DA9052_IRQ_ALARM
] = {
513 .mask
= DA9052_IRQ_MASK_POS_6
,
515 [DA9052_IRQ_SEQRDY
] = {
517 .mask
= DA9052_IRQ_MASK_POS_7
,
519 [DA9052_IRQ_COMP1V2
] = {
521 .mask
= DA9052_IRQ_MASK_POS_8
,
523 [DA9052_IRQ_NONKEY
] = {
525 .mask
= DA9052_IRQ_MASK_POS_1
,
527 [DA9052_IRQ_IDFLOAT
] = {
529 .mask
= DA9052_IRQ_MASK_POS_2
,
531 [DA9052_IRQ_IDGND
] = {
533 .mask
= DA9052_IRQ_MASK_POS_3
,
535 [DA9052_IRQ_CHGEND
] = {
537 .mask
= DA9052_IRQ_MASK_POS_4
,
539 [DA9052_IRQ_TBAT
] = {
541 .mask
= DA9052_IRQ_MASK_POS_5
,
543 [DA9052_IRQ_ADC_EOM
] = {
545 .mask
= DA9052_IRQ_MASK_POS_6
,
547 [DA9052_IRQ_PENDOWN
] = {
549 .mask
= DA9052_IRQ_MASK_POS_7
,
551 [DA9052_IRQ_TSIREADY
] = {
553 .mask
= DA9052_IRQ_MASK_POS_8
,
555 [DA9052_IRQ_GPI0
] = {
557 .mask
= DA9052_IRQ_MASK_POS_1
,
559 [DA9052_IRQ_GPI1
] = {
561 .mask
= DA9052_IRQ_MASK_POS_2
,
563 [DA9052_IRQ_GPI2
] = {
565 .mask
= DA9052_IRQ_MASK_POS_3
,
567 [DA9052_IRQ_GPI3
] = {
569 .mask
= DA9052_IRQ_MASK_POS_4
,
571 [DA9052_IRQ_GPI4
] = {
573 .mask
= DA9052_IRQ_MASK_POS_5
,
575 [DA9052_IRQ_GPI5
] = {
577 .mask
= DA9052_IRQ_MASK_POS_6
,
579 [DA9052_IRQ_GPI6
] = {
581 .mask
= DA9052_IRQ_MASK_POS_7
,
583 [DA9052_IRQ_GPI7
] = {
585 .mask
= DA9052_IRQ_MASK_POS_8
,
587 [DA9052_IRQ_GPI8
] = {
589 .mask
= DA9052_IRQ_MASK_POS_1
,
591 [DA9052_IRQ_GPI9
] = {
593 .mask
= DA9052_IRQ_MASK_POS_2
,
595 [DA9052_IRQ_GPI10
] = {
597 .mask
= DA9052_IRQ_MASK_POS_3
,
599 [DA9052_IRQ_GPI11
] = {
601 .mask
= DA9052_IRQ_MASK_POS_4
,
603 [DA9052_IRQ_GPI12
] = {
605 .mask
= DA9052_IRQ_MASK_POS_5
,
607 [DA9052_IRQ_GPI13
] = {
609 .mask
= DA9052_IRQ_MASK_POS_6
,
611 [DA9052_IRQ_GPI14
] = {
613 .mask
= DA9052_IRQ_MASK_POS_7
,
615 [DA9052_IRQ_GPI15
] = {
617 .mask
= DA9052_IRQ_MASK_POS_8
,
621 static struct regmap_irq_chip da9052_regmap_irq_chip
= {
622 .name
= "da9052_irq",
623 .status_base
= DA9052_EVENT_A_REG
,
624 .mask_base
= DA9052_IRQ_MASK_A_REG
,
625 .ack_base
= DA9052_EVENT_A_REG
,
626 .num_regs
= DA9052_NUM_IRQ_REGS
,
628 .num_irqs
= ARRAY_SIZE(da9052_irqs
),
631 struct regmap_config da9052_regmap_config
= {
635 .cache_type
= REGCACHE_RBTREE
,
637 .max_register
= DA9052_PAGE1_CON_REG
,
638 .readable_reg
= da9052_reg_readable
,
639 .writeable_reg
= da9052_reg_writeable
,
640 .volatile_reg
= da9052_reg_volatile
,
642 EXPORT_SYMBOL_GPL(da9052_regmap_config
);
644 int __devinit
da9052_device_init(struct da9052
*da9052
, u8 chip_id
)
646 struct da9052_pdata
*pdata
= da9052
->dev
->platform_data
;
647 struct irq_desc
*desc
;
650 mutex_init(&da9052
->io_lock
);
652 if (pdata
&& pdata
->init
!= NULL
)
655 da9052
->chip_id
= chip_id
;
657 if (!pdata
|| !pdata
->irq_base
)
658 da9052
->irq_base
= -1;
660 da9052
->irq_base
= pdata
->irq_base
;
662 ret
= regmap_add_irq_chip(da9052
->regmap
, da9052
->chip_irq
,
663 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
,
664 da9052
->irq_base
, &da9052_regmap_irq_chip
,
669 desc
= irq_to_desc(da9052
->chip_irq
);
670 da9052
->irq_base
= regmap_irq_chip_get_base(desc
->action
->dev_id
);
672 ret
= mfd_add_devices(da9052
->dev
, -1, da9052_subdev_info
,
673 ARRAY_SIZE(da9052_subdev_info
), NULL
, 0);
680 mfd_remove_devices(da9052
->dev
);
685 void da9052_device_exit(struct da9052
*da9052
)
687 regmap_del_irq_chip(da9052
->chip_irq
,
688 irq_get_irq_data(da9052
->irq_base
)->chip_data
);
689 mfd_remove_devices(da9052
->dev
);
692 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
693 MODULE_DESCRIPTION("DA9052 MFD Core");
694 MODULE_LICENSE("GPL");