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/mfd/core.h>
20 #include <linux/slab.h>
21 #include <linux/module.h>
23 #include <linux/mfd/da9052/da9052.h>
24 #include <linux/mfd/da9052/pdata.h>
25 #include <linux/mfd/da9052/reg.h>
27 #define DA9052_NUM_IRQ_REGS 4
28 #define DA9052_IRQ_MASK_POS_1 0x01
29 #define DA9052_IRQ_MASK_POS_2 0x02
30 #define DA9052_IRQ_MASK_POS_3 0x04
31 #define DA9052_IRQ_MASK_POS_4 0x08
32 #define DA9052_IRQ_MASK_POS_5 0x10
33 #define DA9052_IRQ_MASK_POS_6 0x20
34 #define DA9052_IRQ_MASK_POS_7 0x40
35 #define DA9052_IRQ_MASK_POS_8 0x80
37 static bool da9052_reg_readable(struct device
*dev
, unsigned int reg
)
40 case DA9052_PAGE0_CON_REG
:
41 case DA9052_STATUS_A_REG
:
42 case DA9052_STATUS_B_REG
:
43 case DA9052_STATUS_C_REG
:
44 case DA9052_STATUS_D_REG
:
45 case DA9052_EVENT_A_REG
:
46 case DA9052_EVENT_B_REG
:
47 case DA9052_EVENT_C_REG
:
48 case DA9052_EVENT_D_REG
:
49 case DA9052_FAULTLOG_REG
:
50 case DA9052_IRQ_MASK_A_REG
:
51 case DA9052_IRQ_MASK_B_REG
:
52 case DA9052_IRQ_MASK_C_REG
:
53 case DA9052_IRQ_MASK_D_REG
:
54 case DA9052_CONTROL_A_REG
:
55 case DA9052_CONTROL_B_REG
:
56 case DA9052_CONTROL_C_REG
:
57 case DA9052_CONTROL_D_REG
:
58 case DA9052_PDDIS_REG
:
59 case DA9052_INTERFACE_REG
:
60 case DA9052_RESET_REG
:
61 case DA9052_GPIO_0_1_REG
:
62 case DA9052_GPIO_2_3_REG
:
63 case DA9052_GPIO_4_5_REG
:
64 case DA9052_GPIO_6_7_REG
:
65 case DA9052_GPIO_14_15_REG
:
66 case DA9052_ID_0_1_REG
:
67 case DA9052_ID_2_3_REG
:
68 case DA9052_ID_4_5_REG
:
69 case DA9052_ID_6_7_REG
:
70 case DA9052_ID_8_9_REG
:
71 case DA9052_ID_10_11_REG
:
72 case DA9052_ID_12_13_REG
:
73 case DA9052_ID_14_15_REG
:
74 case DA9052_ID_16_17_REG
:
75 case DA9052_ID_18_19_REG
:
76 case DA9052_ID_20_21_REG
:
77 case DA9052_SEQ_STATUS_REG
:
78 case DA9052_SEQ_A_REG
:
79 case DA9052_SEQ_B_REG
:
80 case DA9052_SEQ_TIMER_REG
:
81 case DA9052_BUCKA_REG
:
82 case DA9052_BUCKB_REG
:
83 case DA9052_BUCKCORE_REG
:
84 case DA9052_BUCKPRO_REG
:
85 case DA9052_BUCKMEM_REG
:
86 case DA9052_BUCKPERI_REG
:
96 case DA9052_LDO10_REG
:
97 case DA9052_SUPPLY_REG
:
98 case DA9052_PULLDOWN_REG
:
99 case DA9052_CHGBUCK_REG
:
100 case DA9052_WAITCONT_REG
:
101 case DA9052_ISET_REG
:
102 case DA9052_BATCHG_REG
:
103 case DA9052_CHG_CONT_REG
:
104 case DA9052_INPUT_CONT_REG
:
105 case DA9052_CHG_TIME_REG
:
106 case DA9052_BBAT_CONT_REG
:
107 case DA9052_BOOST_REG
:
108 case DA9052_LED_CONT_REG
:
109 case DA9052_LEDMIN123_REG
:
110 case DA9052_LED1_CONF_REG
:
111 case DA9052_LED2_CONF_REG
:
112 case DA9052_LED3_CONF_REG
:
113 case DA9052_LED1CONT_REG
:
114 case DA9052_LED2CONT_REG
:
115 case DA9052_LED3CONT_REG
:
116 case DA9052_LED_CONT_4_REG
:
117 case DA9052_LED_CONT_5_REG
:
118 case DA9052_ADC_MAN_REG
:
119 case DA9052_ADC_CONT_REG
:
120 case DA9052_ADC_RES_L_REG
:
121 case DA9052_ADC_RES_H_REG
:
122 case DA9052_VDD_RES_REG
:
123 case DA9052_VDD_MON_REG
:
124 case DA9052_ICHG_AV_REG
:
125 case DA9052_ICHG_THD_REG
:
126 case DA9052_ICHG_END_REG
:
127 case DA9052_TBAT_RES_REG
:
128 case DA9052_TBAT_HIGHP_REG
:
129 case DA9052_TBAT_HIGHN_REG
:
130 case DA9052_TBAT_LOW_REG
:
131 case DA9052_T_OFFSET_REG
:
132 case DA9052_ADCIN4_RES_REG
:
133 case DA9052_AUTO4_HIGH_REG
:
134 case DA9052_AUTO4_LOW_REG
:
135 case DA9052_ADCIN5_RES_REG
:
136 case DA9052_AUTO5_HIGH_REG
:
137 case DA9052_AUTO5_LOW_REG
:
138 case DA9052_ADCIN6_RES_REG
:
139 case DA9052_AUTO6_HIGH_REG
:
140 case DA9052_AUTO6_LOW_REG
:
141 case DA9052_TJUNC_RES_REG
:
142 case DA9052_TSI_CONT_A_REG
:
143 case DA9052_TSI_CONT_B_REG
:
144 case DA9052_TSI_X_MSB_REG
:
145 case DA9052_TSI_Y_MSB_REG
:
146 case DA9052_TSI_LSB_REG
:
147 case DA9052_TSI_Z_MSB_REG
:
148 case DA9052_COUNT_S_REG
:
149 case DA9052_COUNT_MI_REG
:
150 case DA9052_COUNT_H_REG
:
151 case DA9052_COUNT_D_REG
:
152 case DA9052_COUNT_MO_REG
:
153 case DA9052_COUNT_Y_REG
:
154 case DA9052_ALARM_MI_REG
:
155 case DA9052_ALARM_H_REG
:
156 case DA9052_ALARM_D_REG
:
157 case DA9052_ALARM_MO_REG
:
158 case DA9052_ALARM_Y_REG
:
159 case DA9052_SECOND_A_REG
:
160 case DA9052_SECOND_B_REG
:
161 case DA9052_SECOND_C_REG
:
162 case DA9052_SECOND_D_REG
:
163 case DA9052_PAGE1_CON_REG
:
170 static bool da9052_reg_writeable(struct device
*dev
, unsigned int reg
)
173 case DA9052_PAGE0_CON_REG
:
174 case DA9052_EVENT_A_REG
:
175 case DA9052_EVENT_B_REG
:
176 case DA9052_EVENT_C_REG
:
177 case DA9052_EVENT_D_REG
:
178 case DA9052_IRQ_MASK_A_REG
:
179 case DA9052_IRQ_MASK_B_REG
:
180 case DA9052_IRQ_MASK_C_REG
:
181 case DA9052_IRQ_MASK_D_REG
:
182 case DA9052_CONTROL_A_REG
:
183 case DA9052_CONTROL_B_REG
:
184 case DA9052_CONTROL_C_REG
:
185 case DA9052_CONTROL_D_REG
:
186 case DA9052_PDDIS_REG
:
187 case DA9052_RESET_REG
:
188 case DA9052_GPIO_0_1_REG
:
189 case DA9052_GPIO_2_3_REG
:
190 case DA9052_GPIO_4_5_REG
:
191 case DA9052_GPIO_6_7_REG
:
192 case DA9052_GPIO_14_15_REG
:
193 case DA9052_ID_0_1_REG
:
194 case DA9052_ID_2_3_REG
:
195 case DA9052_ID_4_5_REG
:
196 case DA9052_ID_6_7_REG
:
197 case DA9052_ID_8_9_REG
:
198 case DA9052_ID_10_11_REG
:
199 case DA9052_ID_12_13_REG
:
200 case DA9052_ID_14_15_REG
:
201 case DA9052_ID_16_17_REG
:
202 case DA9052_ID_18_19_REG
:
203 case DA9052_ID_20_21_REG
:
204 case DA9052_SEQ_STATUS_REG
:
205 case DA9052_SEQ_A_REG
:
206 case DA9052_SEQ_B_REG
:
207 case DA9052_SEQ_TIMER_REG
:
208 case DA9052_BUCKA_REG
:
209 case DA9052_BUCKB_REG
:
210 case DA9052_BUCKCORE_REG
:
211 case DA9052_BUCKPRO_REG
:
212 case DA9052_BUCKMEM_REG
:
213 case DA9052_BUCKPERI_REG
:
214 case DA9052_LDO1_REG
:
215 case DA9052_LDO2_REG
:
216 case DA9052_LDO3_REG
:
217 case DA9052_LDO4_REG
:
218 case DA9052_LDO5_REG
:
219 case DA9052_LDO6_REG
:
220 case DA9052_LDO7_REG
:
221 case DA9052_LDO8_REG
:
222 case DA9052_LDO9_REG
:
223 case DA9052_LDO10_REG
:
224 case DA9052_SUPPLY_REG
:
225 case DA9052_PULLDOWN_REG
:
226 case DA9052_CHGBUCK_REG
:
227 case DA9052_WAITCONT_REG
:
228 case DA9052_ISET_REG
:
229 case DA9052_BATCHG_REG
:
230 case DA9052_CHG_CONT_REG
:
231 case DA9052_INPUT_CONT_REG
:
232 case DA9052_BBAT_CONT_REG
:
233 case DA9052_BOOST_REG
:
234 case DA9052_LED_CONT_REG
:
235 case DA9052_LEDMIN123_REG
:
236 case DA9052_LED1_CONF_REG
:
237 case DA9052_LED2_CONF_REG
:
238 case DA9052_LED3_CONF_REG
:
239 case DA9052_LED1CONT_REG
:
240 case DA9052_LED2CONT_REG
:
241 case DA9052_LED3CONT_REG
:
242 case DA9052_LED_CONT_4_REG
:
243 case DA9052_LED_CONT_5_REG
:
244 case DA9052_ADC_MAN_REG
:
245 case DA9052_ADC_CONT_REG
:
246 case DA9052_ADC_RES_L_REG
:
247 case DA9052_ADC_RES_H_REG
:
248 case DA9052_VDD_RES_REG
:
249 case DA9052_VDD_MON_REG
:
250 case DA9052_ICHG_THD_REG
:
251 case DA9052_ICHG_END_REG
:
252 case DA9052_TBAT_HIGHP_REG
:
253 case DA9052_TBAT_HIGHN_REG
:
254 case DA9052_TBAT_LOW_REG
:
255 case DA9052_T_OFFSET_REG
:
256 case DA9052_AUTO4_HIGH_REG
:
257 case DA9052_AUTO4_LOW_REG
:
258 case DA9052_AUTO5_HIGH_REG
:
259 case DA9052_AUTO5_LOW_REG
:
260 case DA9052_AUTO6_HIGH_REG
:
261 case DA9052_AUTO6_LOW_REG
:
262 case DA9052_TSI_CONT_A_REG
:
263 case DA9052_TSI_CONT_B_REG
:
264 case DA9052_COUNT_S_REG
:
265 case DA9052_COUNT_MI_REG
:
266 case DA9052_COUNT_H_REG
:
267 case DA9052_COUNT_D_REG
:
268 case DA9052_COUNT_MO_REG
:
269 case DA9052_COUNT_Y_REG
:
270 case DA9052_ALARM_MI_REG
:
271 case DA9052_ALARM_H_REG
:
272 case DA9052_ALARM_D_REG
:
273 case DA9052_ALARM_MO_REG
:
274 case DA9052_ALARM_Y_REG
:
275 case DA9052_PAGE1_CON_REG
:
282 static bool da9052_reg_volatile(struct device
*dev
, unsigned int reg
)
285 case DA9052_STATUS_A_REG
:
286 case DA9052_STATUS_B_REG
:
287 case DA9052_STATUS_C_REG
:
288 case DA9052_STATUS_D_REG
:
289 case DA9052_EVENT_A_REG
:
290 case DA9052_EVENT_B_REG
:
291 case DA9052_EVENT_C_REG
:
292 case DA9052_EVENT_D_REG
:
293 case DA9052_FAULTLOG_REG
:
294 case DA9052_CHG_TIME_REG
:
295 case DA9052_ADC_RES_L_REG
:
296 case DA9052_ADC_RES_H_REG
:
297 case DA9052_VDD_RES_REG
:
298 case DA9052_ICHG_AV_REG
:
299 case DA9052_TBAT_RES_REG
:
300 case DA9052_ADCIN4_RES_REG
:
301 case DA9052_ADCIN5_RES_REG
:
302 case DA9052_ADCIN6_RES_REG
:
303 case DA9052_TJUNC_RES_REG
:
304 case DA9052_TSI_X_MSB_REG
:
305 case DA9052_TSI_Y_MSB_REG
:
306 case DA9052_TSI_LSB_REG
:
307 case DA9052_TSI_Z_MSB_REG
:
308 case DA9052_COUNT_S_REG
:
309 case DA9052_COUNT_MI_REG
:
310 case DA9052_COUNT_H_REG
:
311 case DA9052_COUNT_D_REG
:
312 case DA9052_COUNT_MO_REG
:
313 case DA9052_COUNT_Y_REG
:
314 case DA9052_ALARM_MI_REG
:
321 static struct resource da9052_rtc_resource
= {
323 .start
= DA9052_IRQ_ALARM
,
324 .end
= DA9052_IRQ_ALARM
,
325 .flags
= IORESOURCE_IRQ
,
328 static struct resource da9052_onkey_resource
= {
330 .start
= DA9052_IRQ_NONKEY
,
331 .end
= DA9052_IRQ_NONKEY
,
332 .flags
= IORESOURCE_IRQ
,
335 static struct resource da9052_bat_resources
[] = {
338 .start
= DA9052_IRQ_TBAT
,
339 .end
= DA9052_IRQ_TBAT
,
340 .flags
= IORESOURCE_IRQ
,
344 .start
= DA9052_IRQ_DCIN
,
345 .end
= DA9052_IRQ_DCIN
,
346 .flags
= IORESOURCE_IRQ
,
350 .start
= DA9052_IRQ_DCINREM
,
351 .end
= DA9052_IRQ_DCINREM
,
352 .flags
= IORESOURCE_IRQ
,
356 .start
= DA9052_IRQ_VBUS
,
357 .end
= DA9052_IRQ_VBUS
,
358 .flags
= IORESOURCE_IRQ
,
362 .start
= DA9052_IRQ_VBUSREM
,
363 .end
= DA9052_IRQ_VBUSREM
,
364 .flags
= IORESOURCE_IRQ
,
368 .start
= DA9052_IRQ_CHGEND
,
369 .end
= DA9052_IRQ_CHGEND
,
370 .flags
= IORESOURCE_IRQ
,
374 static struct resource da9052_tsi_resources
[] = {
377 .start
= DA9052_IRQ_PENDOWN
,
378 .end
= DA9052_IRQ_PENDOWN
,
379 .flags
= IORESOURCE_IRQ
,
383 .start
= DA9052_IRQ_TSIREADY
,
384 .end
= DA9052_IRQ_TSIREADY
,
385 .flags
= IORESOURCE_IRQ
,
389 static struct mfd_cell __devinitdata da9052_subdev_info
[] = {
391 .name
= "da9052-regulator",
395 .name
= "da9052-regulator",
399 .name
= "da9052-regulator",
403 .name
= "da9052-regulator",
407 .name
= "da9052-regulator",
411 .name
= "da9052-regulator",
415 .name
= "da9052-regulator",
419 .name
= "da9052-regulator",
423 .name
= "da9052-regulator",
427 .name
= "da9052-regulator",
431 .name
= "da9052-regulator",
435 .name
= "da9052-regulator",
439 .name
= "da9052-regulator",
443 .name
= "da9052-regulator",
447 .name
= "da9052-onkey",
448 .resources
= &da9052_onkey_resource
,
452 .name
= "da9052-rtc",
453 .resources
= &da9052_rtc_resource
,
457 .name
= "da9052-gpio",
460 .name
= "da9052-hwmon",
463 .name
= "da9052-leds",
466 .name
= "da9052-wled1",
469 .name
= "da9052-wled2",
472 .name
= "da9052-wled3",
475 .name
= "da9052-tsi",
476 .resources
= da9052_tsi_resources
,
477 .num_resources
= ARRAY_SIZE(da9052_tsi_resources
),
480 .name
= "da9052-bat",
481 .resources
= da9052_bat_resources
,
482 .num_resources
= ARRAY_SIZE(da9052_bat_resources
),
485 .name
= "da9052-watchdog",
489 static struct regmap_irq da9052_irqs
[] = {
490 [DA9052_IRQ_DCIN
] = {
492 .mask
= DA9052_IRQ_MASK_POS_1
,
494 [DA9052_IRQ_VBUS
] = {
496 .mask
= DA9052_IRQ_MASK_POS_2
,
498 [DA9052_IRQ_DCINREM
] = {
500 .mask
= DA9052_IRQ_MASK_POS_3
,
502 [DA9052_IRQ_VBUSREM
] = {
504 .mask
= DA9052_IRQ_MASK_POS_4
,
506 [DA9052_IRQ_VDDLOW
] = {
508 .mask
= DA9052_IRQ_MASK_POS_5
,
510 [DA9052_IRQ_ALARM
] = {
512 .mask
= DA9052_IRQ_MASK_POS_6
,
514 [DA9052_IRQ_SEQRDY
] = {
516 .mask
= DA9052_IRQ_MASK_POS_7
,
518 [DA9052_IRQ_COMP1V2
] = {
520 .mask
= DA9052_IRQ_MASK_POS_8
,
522 [DA9052_IRQ_NONKEY
] = {
524 .mask
= DA9052_IRQ_MASK_POS_1
,
526 [DA9052_IRQ_IDFLOAT
] = {
528 .mask
= DA9052_IRQ_MASK_POS_2
,
530 [DA9052_IRQ_IDGND
] = {
532 .mask
= DA9052_IRQ_MASK_POS_3
,
534 [DA9052_IRQ_CHGEND
] = {
536 .mask
= DA9052_IRQ_MASK_POS_4
,
538 [DA9052_IRQ_TBAT
] = {
540 .mask
= DA9052_IRQ_MASK_POS_5
,
542 [DA9052_IRQ_ADC_EOM
] = {
544 .mask
= DA9052_IRQ_MASK_POS_6
,
546 [DA9052_IRQ_PENDOWN
] = {
548 .mask
= DA9052_IRQ_MASK_POS_7
,
550 [DA9052_IRQ_TSIREADY
] = {
552 .mask
= DA9052_IRQ_MASK_POS_8
,
554 [DA9052_IRQ_GPI0
] = {
556 .mask
= DA9052_IRQ_MASK_POS_1
,
558 [DA9052_IRQ_GPI1
] = {
560 .mask
= DA9052_IRQ_MASK_POS_2
,
562 [DA9052_IRQ_GPI2
] = {
564 .mask
= DA9052_IRQ_MASK_POS_3
,
566 [DA9052_IRQ_GPI3
] = {
568 .mask
= DA9052_IRQ_MASK_POS_4
,
570 [DA9052_IRQ_GPI4
] = {
572 .mask
= DA9052_IRQ_MASK_POS_5
,
574 [DA9052_IRQ_GPI5
] = {
576 .mask
= DA9052_IRQ_MASK_POS_6
,
578 [DA9052_IRQ_GPI6
] = {
580 .mask
= DA9052_IRQ_MASK_POS_7
,
582 [DA9052_IRQ_GPI7
] = {
584 .mask
= DA9052_IRQ_MASK_POS_8
,
586 [DA9052_IRQ_GPI8
] = {
588 .mask
= DA9052_IRQ_MASK_POS_1
,
590 [DA9052_IRQ_GPI9
] = {
592 .mask
= DA9052_IRQ_MASK_POS_2
,
594 [DA9052_IRQ_GPI10
] = {
596 .mask
= DA9052_IRQ_MASK_POS_3
,
598 [DA9052_IRQ_GPI11
] = {
600 .mask
= DA9052_IRQ_MASK_POS_4
,
602 [DA9052_IRQ_GPI12
] = {
604 .mask
= DA9052_IRQ_MASK_POS_5
,
606 [DA9052_IRQ_GPI13
] = {
608 .mask
= DA9052_IRQ_MASK_POS_6
,
610 [DA9052_IRQ_GPI14
] = {
612 .mask
= DA9052_IRQ_MASK_POS_7
,
614 [DA9052_IRQ_GPI15
] = {
616 .mask
= DA9052_IRQ_MASK_POS_8
,
620 static struct regmap_irq_chip da9052_regmap_irq_chip
= {
621 .name
= "da9052_irq",
622 .status_base
= DA9052_EVENT_A_REG
,
623 .mask_base
= DA9052_IRQ_MASK_A_REG
,
624 .ack_base
= DA9052_EVENT_A_REG
,
625 .num_regs
= DA9052_NUM_IRQ_REGS
,
627 .num_irqs
= ARRAY_SIZE(da9052_irqs
),
630 struct regmap_config da9052_regmap_config
= {
634 .cache_type
= REGCACHE_RBTREE
,
636 .max_register
= DA9052_PAGE1_CON_REG
,
637 .readable_reg
= da9052_reg_readable
,
638 .writeable_reg
= da9052_reg_writeable
,
639 .volatile_reg
= da9052_reg_volatile
,
641 EXPORT_SYMBOL_GPL(da9052_regmap_config
);
643 int __devinit
da9052_device_init(struct da9052
*da9052
, u8 chip_id
)
645 struct da9052_pdata
*pdata
= da9052
->dev
->platform_data
;
646 struct irq_desc
*desc
;
649 if (pdata
&& pdata
->init
!= NULL
)
652 da9052
->chip_id
= chip_id
;
654 if (!pdata
|| !pdata
->irq_base
)
655 da9052
->irq_base
= -1;
657 da9052
->irq_base
= pdata
->irq_base
;
659 ret
= regmap_add_irq_chip(da9052
->regmap
, da9052
->chip_irq
,
660 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
,
661 da9052
->irq_base
, &da9052_regmap_irq_chip
,
666 desc
= irq_to_desc(da9052
->chip_irq
);
667 da9052
->irq_base
= regmap_irq_chip_get_base(desc
->action
->dev_id
);
669 ret
= mfd_add_devices(da9052
->dev
, -1, da9052_subdev_info
,
670 ARRAY_SIZE(da9052_subdev_info
), NULL
, 0);
677 mfd_remove_devices(da9052
->dev
);
682 void da9052_device_exit(struct da9052
*da9052
)
684 regmap_del_irq_chip(da9052
->chip_irq
,
685 irq_get_irq_data(da9052
->irq_base
)->chip_data
);
686 mfd_remove_devices(da9052
->dev
);
689 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
690 MODULE_DESCRIPTION("DA9052 MFD Core");
691 MODULE_LICENSE("GPL");