diff options
Diffstat (limited to 'drivers/mfd/da9052-core.c')
-rw-r--r-- | drivers/mfd/da9052-core.c | 694 |
1 files changed, 694 insertions, 0 deletions
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c new file mode 100644 index 000000000000..5ddde2a9176a --- /dev/null +++ b/drivers/mfd/da9052-core.c | |||
@@ -0,0 +1,694 @@ | |||
1 | /* | ||
2 | * Device access for Dialog DA9052 PMICs. | ||
3 | * | ||
4 | * Copyright(c) 2011 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: David Dajun Chen <dchen@diasemi.com> | ||
7 | * | ||
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. | ||
12 | */ | ||
13 | |||
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> | ||
23 | |||
24 | #include <linux/mfd/da9052/da9052.h> | ||
25 | #include <linux/mfd/da9052/pdata.h> | ||
26 | #include <linux/mfd/da9052/reg.h> | ||
27 | |||
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 | ||
37 | |||
38 | static bool da9052_reg_readable(struct device *dev, unsigned int reg) | ||
39 | { | ||
40 | switch (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: | ||
88 | case DA9052_LDO1_REG: | ||
89 | case DA9052_LDO2_REG: | ||
90 | case DA9052_LDO3_REG: | ||
91 | case DA9052_LDO4_REG: | ||
92 | case DA9052_LDO5_REG: | ||
93 | case DA9052_LDO6_REG: | ||
94 | case DA9052_LDO7_REG: | ||
95 | case DA9052_LDO8_REG: | ||
96 | case DA9052_LDO9_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: | ||
165 | return true; | ||
166 | default: | ||
167 | return false; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | static bool da9052_reg_writeable(struct device *dev, unsigned int reg) | ||
172 | { | ||
173 | switch (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: | ||
277 | return true; | ||
278 | default: | ||
279 | return false; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | static bool da9052_reg_volatile(struct device *dev, unsigned int reg) | ||
284 | { | ||
285 | switch (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: | ||
316 | return true; | ||
317 | default: | ||
318 | return false; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | static struct resource da9052_rtc_resource = { | ||
323 | .name = "ALM", | ||
324 | .start = DA9052_IRQ_ALARM, | ||
325 | .end = DA9052_IRQ_ALARM, | ||
326 | .flags = IORESOURCE_IRQ, | ||
327 | }; | ||
328 | |||
329 | static struct resource da9052_onkey_resource = { | ||
330 | .name = "ONKEY", | ||
331 | .start = DA9052_IRQ_NONKEY, | ||
332 | .end = DA9052_IRQ_NONKEY, | ||
333 | .flags = IORESOURCE_IRQ, | ||
334 | }; | ||
335 | |||
336 | static struct resource da9052_bat_resources[] = { | ||
337 | { | ||
338 | .name = "BATT TEMP", | ||
339 | .start = DA9052_IRQ_TBAT, | ||
340 | .end = DA9052_IRQ_TBAT, | ||
341 | .flags = IORESOURCE_IRQ, | ||
342 | }, | ||
343 | { | ||
344 | .name = "DCIN DET", | ||
345 | .start = DA9052_IRQ_DCIN, | ||
346 | .end = DA9052_IRQ_DCIN, | ||
347 | .flags = IORESOURCE_IRQ, | ||
348 | }, | ||
349 | { | ||
350 | .name = "DCIN REM", | ||
351 | .start = DA9052_IRQ_DCINREM, | ||
352 | .end = DA9052_IRQ_DCINREM, | ||
353 | .flags = IORESOURCE_IRQ, | ||
354 | }, | ||
355 | { | ||
356 | .name = "VBUS DET", | ||
357 | .start = DA9052_IRQ_VBUS, | ||
358 | .end = DA9052_IRQ_VBUS, | ||
359 | .flags = IORESOURCE_IRQ, | ||
360 | }, | ||
361 | { | ||
362 | .name = "VBUS REM", | ||
363 | .start = DA9052_IRQ_VBUSREM, | ||
364 | .end = DA9052_IRQ_VBUSREM, | ||
365 | .flags = IORESOURCE_IRQ, | ||
366 | }, | ||
367 | { | ||
368 | .name = "CHG END", | ||
369 | .start = DA9052_IRQ_CHGEND, | ||
370 | .end = DA9052_IRQ_CHGEND, | ||
371 | .flags = IORESOURCE_IRQ, | ||
372 | }, | ||
373 | }; | ||
374 | |||
375 | static struct resource da9052_tsi_resources[] = { | ||
376 | { | ||
377 | .name = "PENDWN", | ||
378 | .start = DA9052_IRQ_PENDOWN, | ||
379 | .end = DA9052_IRQ_PENDOWN, | ||
380 | .flags = IORESOURCE_IRQ, | ||
381 | }, | ||
382 | { | ||
383 | .name = "TSIRDY", | ||
384 | .start = DA9052_IRQ_TSIREADY, | ||
385 | .end = DA9052_IRQ_TSIREADY, | ||
386 | .flags = IORESOURCE_IRQ, | ||
387 | }, | ||
388 | }; | ||
389 | |||
390 | static struct mfd_cell __devinitdata da9052_subdev_info[] = { | ||
391 | { | ||
392 | .name = "da9052-regulator", | ||
393 | .id = 1, | ||
394 | }, | ||
395 | { | ||
396 | .name = "da9052-regulator", | ||
397 | .id = 2, | ||
398 | }, | ||
399 | { | ||
400 | .name = "da9052-regulator", | ||
401 | .id = 3, | ||
402 | }, | ||
403 | { | ||
404 | .name = "da9052-regulator", | ||
405 | .id = 4, | ||
406 | }, | ||
407 | { | ||
408 | .name = "da9052-regulator", | ||
409 | .id = 5, | ||
410 | }, | ||
411 | { | ||
412 | .name = "da9052-regulator", | ||
413 | .id = 6, | ||
414 | }, | ||
415 | { | ||
416 | .name = "da9052-regulator", | ||
417 | .id = 7, | ||
418 | }, | ||
419 | { | ||
420 | .name = "da9052-regulator", | ||
421 | .id = 8, | ||
422 | }, | ||
423 | { | ||
424 | .name = "da9052-regulator", | ||
425 | .id = 9, | ||
426 | }, | ||
427 | { | ||
428 | .name = "da9052-regulator", | ||
429 | .id = 10, | ||
430 | }, | ||
431 | { | ||
432 | .name = "da9052-regulator", | ||
433 | .id = 11, | ||
434 | }, | ||
435 | { | ||
436 | .name = "da9052-regulator", | ||
437 | .id = 12, | ||
438 | }, | ||
439 | { | ||
440 | .name = "da9052-regulator", | ||
441 | .id = 13, | ||
442 | }, | ||
443 | { | ||
444 | .name = "da9052-regulator", | ||
445 | .id = 14, | ||
446 | }, | ||
447 | { | ||
448 | .name = "da9052-onkey", | ||
449 | .resources = &da9052_onkey_resource, | ||
450 | .num_resources = 1, | ||
451 | }, | ||
452 | { | ||
453 | .name = "da9052-rtc", | ||
454 | .resources = &da9052_rtc_resource, | ||
455 | .num_resources = 1, | ||
456 | }, | ||
457 | { | ||
458 | .name = "da9052-gpio", | ||
459 | }, | ||
460 | { | ||
461 | .name = "da9052-hwmon", | ||
462 | }, | ||
463 | { | ||
464 | .name = "da9052-leds", | ||
465 | }, | ||
466 | { | ||
467 | .name = "da9052-wled1", | ||
468 | }, | ||
469 | { | ||
470 | .name = "da9052-wled2", | ||
471 | }, | ||
472 | { | ||
473 | .name = "da9052-wled3", | ||
474 | }, | ||
475 | { | ||
476 | .name = "da9052-tsi", | ||
477 | .resources = da9052_tsi_resources, | ||
478 | .num_resources = ARRAY_SIZE(da9052_tsi_resources), | ||
479 | }, | ||
480 | { | ||
481 | .name = "da9052-bat", | ||
482 | .resources = da9052_bat_resources, | ||
483 | .num_resources = ARRAY_SIZE(da9052_bat_resources), | ||
484 | }, | ||
485 | { | ||
486 | .name = "da9052-watchdog", | ||
487 | }, | ||
488 | }; | ||
489 | |||
490 | static struct regmap_irq da9052_irqs[] = { | ||
491 | [DA9052_IRQ_DCIN] = { | ||
492 | .reg_offset = 0, | ||
493 | .mask = DA9052_IRQ_MASK_POS_1, | ||
494 | }, | ||
495 | [DA9052_IRQ_VBUS] = { | ||
496 | .reg_offset = 0, | ||
497 | .mask = DA9052_IRQ_MASK_POS_2, | ||
498 | }, | ||
499 | [DA9052_IRQ_DCINREM] = { | ||
500 | .reg_offset = 0, | ||
501 | .mask = DA9052_IRQ_MASK_POS_3, | ||
502 | }, | ||
503 | [DA9052_IRQ_VBUSREM] = { | ||
504 | .reg_offset = 0, | ||
505 | .mask = DA9052_IRQ_MASK_POS_4, | ||
506 | }, | ||
507 | [DA9052_IRQ_VDDLOW] = { | ||
508 | .reg_offset = 0, | ||
509 | .mask = DA9052_IRQ_MASK_POS_5, | ||
510 | }, | ||
511 | [DA9052_IRQ_ALARM] = { | ||
512 | .reg_offset = 0, | ||
513 | .mask = DA9052_IRQ_MASK_POS_6, | ||
514 | }, | ||
515 | [DA9052_IRQ_SEQRDY] = { | ||
516 | .reg_offset = 0, | ||
517 | .mask = DA9052_IRQ_MASK_POS_7, | ||
518 | }, | ||
519 | [DA9052_IRQ_COMP1V2] = { | ||
520 | .reg_offset = 0, | ||
521 | .mask = DA9052_IRQ_MASK_POS_8, | ||
522 | }, | ||
523 | [DA9052_IRQ_NONKEY] = { | ||
524 | .reg_offset = 1, | ||
525 | .mask = DA9052_IRQ_MASK_POS_1, | ||
526 | }, | ||
527 | [DA9052_IRQ_IDFLOAT] = { | ||
528 | .reg_offset = 1, | ||
529 | .mask = DA9052_IRQ_MASK_POS_2, | ||
530 | }, | ||
531 | [DA9052_IRQ_IDGND] = { | ||
532 | .reg_offset = 1, | ||
533 | .mask = DA9052_IRQ_MASK_POS_3, | ||
534 | }, | ||
535 | [DA9052_IRQ_CHGEND] = { | ||
536 | .reg_offset = 1, | ||
537 | .mask = DA9052_IRQ_MASK_POS_4, | ||
538 | }, | ||
539 | [DA9052_IRQ_TBAT] = { | ||
540 | .reg_offset = 1, | ||
541 | .mask = DA9052_IRQ_MASK_POS_5, | ||
542 | }, | ||
543 | [DA9052_IRQ_ADC_EOM] = { | ||
544 | .reg_offset = 1, | ||
545 | .mask = DA9052_IRQ_MASK_POS_6, | ||
546 | }, | ||
547 | [DA9052_IRQ_PENDOWN] = { | ||
548 | .reg_offset = 1, | ||
549 | .mask = DA9052_IRQ_MASK_POS_7, | ||
550 | }, | ||
551 | [DA9052_IRQ_TSIREADY] = { | ||
552 | .reg_offset = 1, | ||
553 | .mask = DA9052_IRQ_MASK_POS_8, | ||
554 | }, | ||
555 | [DA9052_IRQ_GPI0] = { | ||
556 | .reg_offset = 2, | ||
557 | .mask = DA9052_IRQ_MASK_POS_1, | ||
558 | }, | ||
559 | [DA9052_IRQ_GPI1] = { | ||
560 | .reg_offset = 2, | ||
561 | .mask = DA9052_IRQ_MASK_POS_2, | ||
562 | }, | ||
563 | [DA9052_IRQ_GPI2] = { | ||
564 | .reg_offset = 2, | ||
565 | .mask = DA9052_IRQ_MASK_POS_3, | ||
566 | }, | ||
567 | [DA9052_IRQ_GPI3] = { | ||
568 | .reg_offset = 2, | ||
569 | .mask = DA9052_IRQ_MASK_POS_4, | ||
570 | }, | ||
571 | [DA9052_IRQ_GPI4] = { | ||
572 | .reg_offset = 2, | ||
573 | .mask = DA9052_IRQ_MASK_POS_5, | ||
574 | }, | ||
575 | [DA9052_IRQ_GPI5] = { | ||
576 | .reg_offset = 2, | ||
577 | .mask = DA9052_IRQ_MASK_POS_6, | ||
578 | }, | ||
579 | [DA9052_IRQ_GPI6] = { | ||
580 | .reg_offset = 2, | ||
581 | .mask = DA9052_IRQ_MASK_POS_7, | ||
582 | }, | ||
583 | [DA9052_IRQ_GPI7] = { | ||
584 | .reg_offset = 2, | ||
585 | .mask = DA9052_IRQ_MASK_POS_8, | ||
586 | }, | ||
587 | [DA9052_IRQ_GPI8] = { | ||
588 | .reg_offset = 3, | ||
589 | .mask = DA9052_IRQ_MASK_POS_1, | ||
590 | }, | ||
591 | [DA9052_IRQ_GPI9] = { | ||
592 | .reg_offset = 3, | ||
593 | .mask = DA9052_IRQ_MASK_POS_2, | ||
594 | }, | ||
595 | [DA9052_IRQ_GPI10] = { | ||
596 | .reg_offset = 3, | ||
597 | .mask = DA9052_IRQ_MASK_POS_3, | ||
598 | }, | ||
599 | [DA9052_IRQ_GPI11] = { | ||
600 | .reg_offset = 3, | ||
601 | .mask = DA9052_IRQ_MASK_POS_4, | ||
602 | }, | ||
603 | [DA9052_IRQ_GPI12] = { | ||
604 | .reg_offset = 3, | ||
605 | .mask = DA9052_IRQ_MASK_POS_5, | ||
606 | }, | ||
607 | [DA9052_IRQ_GPI13] = { | ||
608 | .reg_offset = 3, | ||
609 | .mask = DA9052_IRQ_MASK_POS_6, | ||
610 | }, | ||
611 | [DA9052_IRQ_GPI14] = { | ||
612 | .reg_offset = 3, | ||
613 | .mask = DA9052_IRQ_MASK_POS_7, | ||
614 | }, | ||
615 | [DA9052_IRQ_GPI15] = { | ||
616 | .reg_offset = 3, | ||
617 | .mask = DA9052_IRQ_MASK_POS_8, | ||
618 | }, | ||
619 | }; | ||
620 | |||
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, | ||
627 | .irqs = da9052_irqs, | ||
628 | .num_irqs = ARRAY_SIZE(da9052_irqs), | ||
629 | }; | ||
630 | |||
631 | struct regmap_config da9052_regmap_config = { | ||
632 | .reg_bits = 8, | ||
633 | .val_bits = 8, | ||
634 | |||
635 | .cache_type = REGCACHE_RBTREE, | ||
636 | |||
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, | ||
641 | }; | ||
642 | EXPORT_SYMBOL_GPL(da9052_regmap_config); | ||
643 | |||
644 | int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) | ||
645 | { | ||
646 | struct da9052_pdata *pdata = da9052->dev->platform_data; | ||
647 | struct irq_desc *desc; | ||
648 | int ret; | ||
649 | |||
650 | mutex_init(&da9052->io_lock); | ||
651 | |||
652 | if (pdata && pdata->init != NULL) | ||
653 | pdata->init(da9052); | ||
654 | |||
655 | da9052->chip_id = chip_id; | ||
656 | |||
657 | if (!pdata || !pdata->irq_base) | ||
658 | da9052->irq_base = -1; | ||
659 | else | ||
660 | da9052->irq_base = pdata->irq_base; | ||
661 | |||
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, | ||
665 | NULL); | ||
666 | if (ret < 0) | ||
667 | goto regmap_err; | ||
668 | |||
669 | desc = irq_to_desc(da9052->chip_irq); | ||
670 | da9052->irq_base = regmap_irq_chip_get_base(desc->action->dev_id); | ||
671 | |||
672 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, | ||
673 | ARRAY_SIZE(da9052_subdev_info), NULL, 0); | ||
674 | if (ret) | ||
675 | goto err; | ||
676 | |||
677 | return 0; | ||
678 | |||
679 | err: | ||
680 | mfd_remove_devices(da9052->dev); | ||
681 | regmap_err: | ||
682 | return ret; | ||
683 | } | ||
684 | |||
685 | void da9052_device_exit(struct da9052 *da9052) | ||
686 | { | ||
687 | regmap_del_irq_chip(da9052->chip_irq, | ||
688 | irq_get_irq_data(da9052->irq_base)->chip_data); | ||
689 | mfd_remove_devices(da9052->dev); | ||
690 | } | ||
691 | |||
692 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
693 | MODULE_DESCRIPTION("DA9052 MFD Core"); | ||
694 | MODULE_LICENSE("GPL"); | ||