aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/wm8350-irq.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-10-12 11:15:09 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2009-12-13 13:20:55 -0500
commite0a3389ab9cb08813bf325616249abb29c4d2302 (patch)
treee7f1bd9d90a98cd23cb677d8aea6877985fed5cc /drivers/mfd/wm8350-irq.c
parentfba65fe0ededc538771e47f6d099d7c853f4776e (diff)
mfd: Split wm8350 IRQ code into a separate file
In preparation for refactoring - it's over 700 lines of well-isolated code and having it in a file by itself makes things more managable. While we're at it make sure that we clean up the IRQ if we fail after acquiring it on init. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/wm8350-irq.c')
-rw-r--r--drivers/mfd/wm8350-irq.c804
1 files changed, 804 insertions, 0 deletions
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
new file mode 100644
index 000000000000..a432e2b65c48
--- /dev/null
+++ b/drivers/mfd/wm8350-irq.c
@@ -0,0 +1,804 @@
1/*
2 * wm8350-irq.c -- IRQ support for Wolfson WM8350
3 *
4 * Copyright 2007, 2008, 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Liam Girdwood, Mark Brown
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
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/bug.h>
19#include <linux/device.h>
20#include <linux/interrupt.h>
21#include <linux/workqueue.h>
22
23#include <linux/mfd/wm8350/core.h>
24#include <linux/mfd/wm8350/audio.h>
25#include <linux/mfd/wm8350/comparator.h>
26#include <linux/mfd/wm8350/gpio.h>
27#include <linux/mfd/wm8350/pmic.h>
28#include <linux/mfd/wm8350/rtc.h>
29#include <linux/mfd/wm8350/supply.h>
30#include <linux/mfd/wm8350/wdt.h>
31
32static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
33{
34 mutex_lock(&wm8350->irq_mutex);
35
36 if (wm8350->irq[irq].handler)
37 wm8350->irq[irq].handler(wm8350, irq, wm8350->irq[irq].data);
38 else {
39 dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
40 irq);
41 wm8350_mask_irq(wm8350, irq);
42 }
43
44 mutex_unlock(&wm8350->irq_mutex);
45}
46
47/*
48 * This is a threaded IRQ handler so can access I2C/SPI. Since all
49 * interrupts are clear on read the IRQ line will be reasserted and
50 * the physical IRQ will be handled again if another interrupt is
51 * asserted while we run - in the normal course of events this is a
52 * rare occurrence so we save I2C/SPI reads.
53 */
54static irqreturn_t wm8350_irq(int irq, void *data)
55{
56 struct wm8350 *wm8350 = data;
57 u16 level_one, status1, status2, comp;
58
59 /* TODO: Use block reads to improve performance? */
60 level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
61 & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
62 status1 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_1)
63 & ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_1_MASK);
64 status2 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_2)
65 & ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_2_MASK);
66 comp = wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS)
67 & ~wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK);
68
69 /* over current */
70 if (level_one & WM8350_OC_INT) {
71 u16 oc;
72
73 oc = wm8350_reg_read(wm8350, WM8350_OVER_CURRENT_INT_STATUS);
74 oc &= ~wm8350_reg_read(wm8350,
75 WM8350_OVER_CURRENT_INT_STATUS_MASK);
76
77 if (oc & WM8350_OC_LS_EINT) /* limit switch */
78 wm8350_irq_call_handler(wm8350, WM8350_IRQ_OC_LS);
79 }
80
81 /* under voltage */
82 if (level_one & WM8350_UV_INT) {
83 u16 uv;
84
85 uv = wm8350_reg_read(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS);
86 uv &= ~wm8350_reg_read(wm8350,
87 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK);
88
89 if (uv & WM8350_UV_DC1_EINT)
90 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC1);
91 if (uv & WM8350_UV_DC2_EINT)
92 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC2);
93 if (uv & WM8350_UV_DC3_EINT)
94 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC3);
95 if (uv & WM8350_UV_DC4_EINT)
96 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC4);
97 if (uv & WM8350_UV_DC5_EINT)
98 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC5);
99 if (uv & WM8350_UV_DC6_EINT)
100 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC6);
101 if (uv & WM8350_UV_LDO1_EINT)
102 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO1);
103 if (uv & WM8350_UV_LDO2_EINT)
104 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO2);
105 if (uv & WM8350_UV_LDO3_EINT)
106 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO3);
107 if (uv & WM8350_UV_LDO4_EINT)
108 wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO4);
109 }
110
111 /* charger, RTC */
112 if (status1) {
113 if (status1 & WM8350_CHG_BAT_HOT_EINT)
114 wm8350_irq_call_handler(wm8350,
115 WM8350_IRQ_CHG_BAT_HOT);
116 if (status1 & WM8350_CHG_BAT_COLD_EINT)
117 wm8350_irq_call_handler(wm8350,
118 WM8350_IRQ_CHG_BAT_COLD);
119 if (status1 & WM8350_CHG_BAT_FAIL_EINT)
120 wm8350_irq_call_handler(wm8350,
121 WM8350_IRQ_CHG_BAT_FAIL);
122 if (status1 & WM8350_CHG_TO_EINT)
123 wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_TO);
124 if (status1 & WM8350_CHG_END_EINT)
125 wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_END);
126 if (status1 & WM8350_CHG_START_EINT)
127 wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_START);
128 if (status1 & WM8350_CHG_FAST_RDY_EINT)
129 wm8350_irq_call_handler(wm8350,
130 WM8350_IRQ_CHG_FAST_RDY);
131 if (status1 & WM8350_CHG_VBATT_LT_3P9_EINT)
132 wm8350_irq_call_handler(wm8350,
133 WM8350_IRQ_CHG_VBATT_LT_3P9);
134 if (status1 & WM8350_CHG_VBATT_LT_3P1_EINT)
135 wm8350_irq_call_handler(wm8350,
136 WM8350_IRQ_CHG_VBATT_LT_3P1);
137 if (status1 & WM8350_CHG_VBATT_LT_2P85_EINT)
138 wm8350_irq_call_handler(wm8350,
139 WM8350_IRQ_CHG_VBATT_LT_2P85);
140 if (status1 & WM8350_RTC_ALM_EINT)
141 wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_ALM);
142 if (status1 & WM8350_RTC_SEC_EINT)
143 wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_SEC);
144 if (status1 & WM8350_RTC_PER_EINT)
145 wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_PER);
146 }
147
148 /* current sink, system, aux adc */
149 if (status2) {
150 if (status2 & WM8350_CS1_EINT)
151 wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS1);
152 if (status2 & WM8350_CS2_EINT)
153 wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS2);
154
155 if (status2 & WM8350_SYS_HYST_COMP_FAIL_EINT)
156 wm8350_irq_call_handler(wm8350,
157 WM8350_IRQ_SYS_HYST_COMP_FAIL);
158 if (status2 & WM8350_SYS_CHIP_GT115_EINT)
159 wm8350_irq_call_handler(wm8350,
160 WM8350_IRQ_SYS_CHIP_GT115);
161 if (status2 & WM8350_SYS_CHIP_GT140_EINT)
162 wm8350_irq_call_handler(wm8350,
163 WM8350_IRQ_SYS_CHIP_GT140);
164 if (status2 & WM8350_SYS_WDOG_TO_EINT)
165 wm8350_irq_call_handler(wm8350,
166 WM8350_IRQ_SYS_WDOG_TO);
167
168 if (status2 & WM8350_AUXADC_DATARDY_EINT)
169 wm8350_irq_call_handler(wm8350,
170 WM8350_IRQ_AUXADC_DATARDY);
171 if (status2 & WM8350_AUXADC_DCOMP4_EINT)
172 wm8350_irq_call_handler(wm8350,
173 WM8350_IRQ_AUXADC_DCOMP4);
174 if (status2 & WM8350_AUXADC_DCOMP3_EINT)
175 wm8350_irq_call_handler(wm8350,
176 WM8350_IRQ_AUXADC_DCOMP3);
177 if (status2 & WM8350_AUXADC_DCOMP2_EINT)
178 wm8350_irq_call_handler(wm8350,
179 WM8350_IRQ_AUXADC_DCOMP2);
180 if (status2 & WM8350_AUXADC_DCOMP1_EINT)
181 wm8350_irq_call_handler(wm8350,
182 WM8350_IRQ_AUXADC_DCOMP1);
183
184 if (status2 & WM8350_USB_LIMIT_EINT)
185 wm8350_irq_call_handler(wm8350, WM8350_IRQ_USB_LIMIT);
186 }
187
188 /* wake, codec, ext */
189 if (comp) {
190 if (comp & WM8350_WKUP_OFF_STATE_EINT)
191 wm8350_irq_call_handler(wm8350,
192 WM8350_IRQ_WKUP_OFF_STATE);
193 if (comp & WM8350_WKUP_HIB_STATE_EINT)
194 wm8350_irq_call_handler(wm8350,
195 WM8350_IRQ_WKUP_HIB_STATE);
196 if (comp & WM8350_WKUP_CONV_FAULT_EINT)
197 wm8350_irq_call_handler(wm8350,
198 WM8350_IRQ_WKUP_CONV_FAULT);
199 if (comp & WM8350_WKUP_WDOG_RST_EINT)
200 wm8350_irq_call_handler(wm8350,
201 WM8350_IRQ_WKUP_WDOG_RST);
202 if (comp & WM8350_WKUP_GP_PWR_ON_EINT)
203 wm8350_irq_call_handler(wm8350,
204 WM8350_IRQ_WKUP_GP_PWR_ON);
205 if (comp & WM8350_WKUP_ONKEY_EINT)
206 wm8350_irq_call_handler(wm8350, WM8350_IRQ_WKUP_ONKEY);
207 if (comp & WM8350_WKUP_GP_WAKEUP_EINT)
208 wm8350_irq_call_handler(wm8350,
209 WM8350_IRQ_WKUP_GP_WAKEUP);
210
211 if (comp & WM8350_CODEC_JCK_DET_L_EINT)
212 wm8350_irq_call_handler(wm8350,
213 WM8350_IRQ_CODEC_JCK_DET_L);
214 if (comp & WM8350_CODEC_JCK_DET_R_EINT)
215 wm8350_irq_call_handler(wm8350,
216 WM8350_IRQ_CODEC_JCK_DET_R);
217 if (comp & WM8350_CODEC_MICSCD_EINT)
218 wm8350_irq_call_handler(wm8350,
219 WM8350_IRQ_CODEC_MICSCD);
220 if (comp & WM8350_CODEC_MICD_EINT)
221 wm8350_irq_call_handler(wm8350, WM8350_IRQ_CODEC_MICD);
222
223 if (comp & WM8350_EXT_USB_FB_EINT)
224 wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_USB_FB);
225 if (comp & WM8350_EXT_WALL_FB_EINT)
226 wm8350_irq_call_handler(wm8350,
227 WM8350_IRQ_EXT_WALL_FB);
228 if (comp & WM8350_EXT_BAT_FB_EINT)
229 wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_BAT_FB);
230 }
231
232 if (level_one & WM8350_GP_INT) {
233 int i;
234 u16 gpio;
235
236 gpio = wm8350_reg_read(wm8350, WM8350_GPIO_INT_STATUS);
237 gpio &= ~wm8350_reg_read(wm8350,
238 WM8350_GPIO_INT_STATUS_MASK);
239
240 for (i = 0; i < 12; i++) {
241 if (gpio & (1 << i))
242 wm8350_irq_call_handler(wm8350,
243 WM8350_IRQ_GPIO(i));
244 }
245 }
246
247 return IRQ_HANDLED;
248}
249
250int wm8350_register_irq(struct wm8350 *wm8350, int irq,
251 void (*handler) (struct wm8350 *, int, void *),
252 void *data)
253{
254 if (irq < 0 || irq > WM8350_NUM_IRQ || !handler)
255 return -EINVAL;
256
257 if (wm8350->irq[irq].handler)
258 return -EBUSY;
259
260 mutex_lock(&wm8350->irq_mutex);
261 wm8350->irq[irq].handler = handler;
262 wm8350->irq[irq].data = data;
263 mutex_unlock(&wm8350->irq_mutex);
264
265 return 0;
266}
267EXPORT_SYMBOL_GPL(wm8350_register_irq);
268
269int wm8350_free_irq(struct wm8350 *wm8350, int irq)
270{
271 if (irq < 0 || irq > WM8350_NUM_IRQ)
272 return -EINVAL;
273
274 mutex_lock(&wm8350->irq_mutex);
275 wm8350->irq[irq].handler = NULL;
276 mutex_unlock(&wm8350->irq_mutex);
277 return 0;
278}
279EXPORT_SYMBOL_GPL(wm8350_free_irq);
280
281int wm8350_mask_irq(struct wm8350 *wm8350, int irq)
282{
283 switch (irq) {
284 case WM8350_IRQ_CHG_BAT_HOT:
285 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
286 WM8350_IM_CHG_BAT_HOT_EINT);
287 case WM8350_IRQ_CHG_BAT_COLD:
288 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
289 WM8350_IM_CHG_BAT_COLD_EINT);
290 case WM8350_IRQ_CHG_BAT_FAIL:
291 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
292 WM8350_IM_CHG_BAT_FAIL_EINT);
293 case WM8350_IRQ_CHG_TO:
294 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
295 WM8350_IM_CHG_TO_EINT);
296 case WM8350_IRQ_CHG_END:
297 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
298 WM8350_IM_CHG_END_EINT);
299 case WM8350_IRQ_CHG_START:
300 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
301 WM8350_IM_CHG_START_EINT);
302 case WM8350_IRQ_CHG_FAST_RDY:
303 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
304 WM8350_IM_CHG_FAST_RDY_EINT);
305 case WM8350_IRQ_RTC_PER:
306 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
307 WM8350_IM_RTC_PER_EINT);
308 case WM8350_IRQ_RTC_SEC:
309 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
310 WM8350_IM_RTC_SEC_EINT);
311 case WM8350_IRQ_RTC_ALM:
312 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
313 WM8350_IM_RTC_ALM_EINT);
314 case WM8350_IRQ_CHG_VBATT_LT_3P9:
315 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
316 WM8350_IM_CHG_VBATT_LT_3P9_EINT);
317 case WM8350_IRQ_CHG_VBATT_LT_3P1:
318 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
319 WM8350_IM_CHG_VBATT_LT_3P1_EINT);
320 case WM8350_IRQ_CHG_VBATT_LT_2P85:
321 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
322 WM8350_IM_CHG_VBATT_LT_2P85_EINT);
323 case WM8350_IRQ_CS1:
324 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
325 WM8350_IM_CS1_EINT);
326 case WM8350_IRQ_CS2:
327 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
328 WM8350_IM_CS2_EINT);
329 case WM8350_IRQ_USB_LIMIT:
330 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
331 WM8350_IM_USB_LIMIT_EINT);
332 case WM8350_IRQ_AUXADC_DATARDY:
333 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
334 WM8350_IM_AUXADC_DATARDY_EINT);
335 case WM8350_IRQ_AUXADC_DCOMP4:
336 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
337 WM8350_IM_AUXADC_DCOMP4_EINT);
338 case WM8350_IRQ_AUXADC_DCOMP3:
339 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
340 WM8350_IM_AUXADC_DCOMP3_EINT);
341 case WM8350_IRQ_AUXADC_DCOMP2:
342 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
343 WM8350_IM_AUXADC_DCOMP2_EINT);
344 case WM8350_IRQ_AUXADC_DCOMP1:
345 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
346 WM8350_IM_AUXADC_DCOMP1_EINT);
347 case WM8350_IRQ_SYS_HYST_COMP_FAIL:
348 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
349 WM8350_IM_SYS_HYST_COMP_FAIL_EINT);
350 case WM8350_IRQ_SYS_CHIP_GT115:
351 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
352 WM8350_IM_SYS_CHIP_GT115_EINT);
353 case WM8350_IRQ_SYS_CHIP_GT140:
354 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
355 WM8350_IM_SYS_CHIP_GT140_EINT);
356 case WM8350_IRQ_SYS_WDOG_TO:
357 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
358 WM8350_IM_SYS_WDOG_TO_EINT);
359 case WM8350_IRQ_UV_LDO4:
360 return wm8350_set_bits(wm8350,
361 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
362 WM8350_IM_UV_LDO4_EINT);
363 case WM8350_IRQ_UV_LDO3:
364 return wm8350_set_bits(wm8350,
365 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
366 WM8350_IM_UV_LDO3_EINT);
367 case WM8350_IRQ_UV_LDO2:
368 return wm8350_set_bits(wm8350,
369 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
370 WM8350_IM_UV_LDO2_EINT);
371 case WM8350_IRQ_UV_LDO1:
372 return wm8350_set_bits(wm8350,
373 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
374 WM8350_IM_UV_LDO1_EINT);
375 case WM8350_IRQ_UV_DC6:
376 return wm8350_set_bits(wm8350,
377 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
378 WM8350_IM_UV_DC6_EINT);
379 case WM8350_IRQ_UV_DC5:
380 return wm8350_set_bits(wm8350,
381 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
382 WM8350_IM_UV_DC5_EINT);
383 case WM8350_IRQ_UV_DC4:
384 return wm8350_set_bits(wm8350,
385 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
386 WM8350_IM_UV_DC4_EINT);
387 case WM8350_IRQ_UV_DC3:
388 return wm8350_set_bits(wm8350,
389 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
390 WM8350_IM_UV_DC3_EINT);
391 case WM8350_IRQ_UV_DC2:
392 return wm8350_set_bits(wm8350,
393 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
394 WM8350_IM_UV_DC2_EINT);
395 case WM8350_IRQ_UV_DC1:
396 return wm8350_set_bits(wm8350,
397 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
398 WM8350_IM_UV_DC1_EINT);
399 case WM8350_IRQ_OC_LS:
400 return wm8350_set_bits(wm8350,
401 WM8350_OVER_CURRENT_INT_STATUS_MASK,
402 WM8350_IM_OC_LS_EINT);
403 case WM8350_IRQ_EXT_USB_FB:
404 return wm8350_set_bits(wm8350,
405 WM8350_COMPARATOR_INT_STATUS_MASK,
406 WM8350_IM_EXT_USB_FB_EINT);
407 case WM8350_IRQ_EXT_WALL_FB:
408 return wm8350_set_bits(wm8350,
409 WM8350_COMPARATOR_INT_STATUS_MASK,
410 WM8350_IM_EXT_WALL_FB_EINT);
411 case WM8350_IRQ_EXT_BAT_FB:
412 return wm8350_set_bits(wm8350,
413 WM8350_COMPARATOR_INT_STATUS_MASK,
414 WM8350_IM_EXT_BAT_FB_EINT);
415 case WM8350_IRQ_CODEC_JCK_DET_L:
416 return wm8350_set_bits(wm8350,
417 WM8350_COMPARATOR_INT_STATUS_MASK,
418 WM8350_IM_CODEC_JCK_DET_L_EINT);
419 case WM8350_IRQ_CODEC_JCK_DET_R:
420 return wm8350_set_bits(wm8350,
421 WM8350_COMPARATOR_INT_STATUS_MASK,
422 WM8350_IM_CODEC_JCK_DET_R_EINT);
423 case WM8350_IRQ_CODEC_MICSCD:
424 return wm8350_set_bits(wm8350,
425 WM8350_COMPARATOR_INT_STATUS_MASK,
426 WM8350_IM_CODEC_MICSCD_EINT);
427 case WM8350_IRQ_CODEC_MICD:
428 return wm8350_set_bits(wm8350,
429 WM8350_COMPARATOR_INT_STATUS_MASK,
430 WM8350_IM_CODEC_MICD_EINT);
431 case WM8350_IRQ_WKUP_OFF_STATE:
432 return wm8350_set_bits(wm8350,
433 WM8350_COMPARATOR_INT_STATUS_MASK,
434 WM8350_IM_WKUP_OFF_STATE_EINT);
435 case WM8350_IRQ_WKUP_HIB_STATE:
436 return wm8350_set_bits(wm8350,
437 WM8350_COMPARATOR_INT_STATUS_MASK,
438 WM8350_IM_WKUP_HIB_STATE_EINT);
439 case WM8350_IRQ_WKUP_CONV_FAULT:
440 return wm8350_set_bits(wm8350,
441 WM8350_COMPARATOR_INT_STATUS_MASK,
442 WM8350_IM_WKUP_CONV_FAULT_EINT);
443 case WM8350_IRQ_WKUP_WDOG_RST:
444 return wm8350_set_bits(wm8350,
445 WM8350_COMPARATOR_INT_STATUS_MASK,
446 WM8350_IM_WKUP_OFF_STATE_EINT);
447 case WM8350_IRQ_WKUP_GP_PWR_ON:
448 return wm8350_set_bits(wm8350,
449 WM8350_COMPARATOR_INT_STATUS_MASK,
450 WM8350_IM_WKUP_GP_PWR_ON_EINT);
451 case WM8350_IRQ_WKUP_ONKEY:
452 return wm8350_set_bits(wm8350,
453 WM8350_COMPARATOR_INT_STATUS_MASK,
454 WM8350_IM_WKUP_ONKEY_EINT);
455 case WM8350_IRQ_WKUP_GP_WAKEUP:
456 return wm8350_set_bits(wm8350,
457 WM8350_COMPARATOR_INT_STATUS_MASK,
458 WM8350_IM_WKUP_GP_WAKEUP_EINT);
459 case WM8350_IRQ_GPIO(0):
460 return wm8350_set_bits(wm8350,
461 WM8350_GPIO_INT_STATUS_MASK,
462 WM8350_IM_GP0_EINT);
463 case WM8350_IRQ_GPIO(1):
464 return wm8350_set_bits(wm8350,
465 WM8350_GPIO_INT_STATUS_MASK,
466 WM8350_IM_GP1_EINT);
467 case WM8350_IRQ_GPIO(2):
468 return wm8350_set_bits(wm8350,
469 WM8350_GPIO_INT_STATUS_MASK,
470 WM8350_IM_GP2_EINT);
471 case WM8350_IRQ_GPIO(3):
472 return wm8350_set_bits(wm8350,
473 WM8350_GPIO_INT_STATUS_MASK,
474 WM8350_IM_GP3_EINT);
475 case WM8350_IRQ_GPIO(4):
476 return wm8350_set_bits(wm8350,
477 WM8350_GPIO_INT_STATUS_MASK,
478 WM8350_IM_GP4_EINT);
479 case WM8350_IRQ_GPIO(5):
480 return wm8350_set_bits(wm8350,
481 WM8350_GPIO_INT_STATUS_MASK,
482 WM8350_IM_GP5_EINT);
483 case WM8350_IRQ_GPIO(6):
484 return wm8350_set_bits(wm8350,
485 WM8350_GPIO_INT_STATUS_MASK,
486 WM8350_IM_GP6_EINT);
487 case WM8350_IRQ_GPIO(7):
488 return wm8350_set_bits(wm8350,
489 WM8350_GPIO_INT_STATUS_MASK,
490 WM8350_IM_GP7_EINT);
491 case WM8350_IRQ_GPIO(8):
492 return wm8350_set_bits(wm8350,
493 WM8350_GPIO_INT_STATUS_MASK,
494 WM8350_IM_GP8_EINT);
495 case WM8350_IRQ_GPIO(9):
496 return wm8350_set_bits(wm8350,
497 WM8350_GPIO_INT_STATUS_MASK,
498 WM8350_IM_GP9_EINT);
499 case WM8350_IRQ_GPIO(10):
500 return wm8350_set_bits(wm8350,
501 WM8350_GPIO_INT_STATUS_MASK,
502 WM8350_IM_GP10_EINT);
503 case WM8350_IRQ_GPIO(11):
504 return wm8350_set_bits(wm8350,
505 WM8350_GPIO_INT_STATUS_MASK,
506 WM8350_IM_GP11_EINT);
507 case WM8350_IRQ_GPIO(12):
508 return wm8350_set_bits(wm8350,
509 WM8350_GPIO_INT_STATUS_MASK,
510 WM8350_IM_GP12_EINT);
511 default:
512 dev_warn(wm8350->dev, "Attempting to mask unknown IRQ %d\n",
513 irq);
514 return -EINVAL;
515 }
516 return 0;
517}
518EXPORT_SYMBOL_GPL(wm8350_mask_irq);
519
520int wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
521{
522 switch (irq) {
523 case WM8350_IRQ_CHG_BAT_HOT:
524 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
525 WM8350_IM_CHG_BAT_HOT_EINT);
526 case WM8350_IRQ_CHG_BAT_COLD:
527 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
528 WM8350_IM_CHG_BAT_COLD_EINT);
529 case WM8350_IRQ_CHG_BAT_FAIL:
530 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
531 WM8350_IM_CHG_BAT_FAIL_EINT);
532 case WM8350_IRQ_CHG_TO:
533 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
534 WM8350_IM_CHG_TO_EINT);
535 case WM8350_IRQ_CHG_END:
536 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
537 WM8350_IM_CHG_END_EINT);
538 case WM8350_IRQ_CHG_START:
539 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
540 WM8350_IM_CHG_START_EINT);
541 case WM8350_IRQ_CHG_FAST_RDY:
542 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
543 WM8350_IM_CHG_FAST_RDY_EINT);
544 case WM8350_IRQ_RTC_PER:
545 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
546 WM8350_IM_RTC_PER_EINT);
547 case WM8350_IRQ_RTC_SEC:
548 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
549 WM8350_IM_RTC_SEC_EINT);
550 case WM8350_IRQ_RTC_ALM:
551 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
552 WM8350_IM_RTC_ALM_EINT);
553 case WM8350_IRQ_CHG_VBATT_LT_3P9:
554 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
555 WM8350_IM_CHG_VBATT_LT_3P9_EINT);
556 case WM8350_IRQ_CHG_VBATT_LT_3P1:
557 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
558 WM8350_IM_CHG_VBATT_LT_3P1_EINT);
559 case WM8350_IRQ_CHG_VBATT_LT_2P85:
560 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
561 WM8350_IM_CHG_VBATT_LT_2P85_EINT);
562 case WM8350_IRQ_CS1:
563 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
564 WM8350_IM_CS1_EINT);
565 case WM8350_IRQ_CS2:
566 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
567 WM8350_IM_CS2_EINT);
568 case WM8350_IRQ_USB_LIMIT:
569 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
570 WM8350_IM_USB_LIMIT_EINT);
571 case WM8350_IRQ_AUXADC_DATARDY:
572 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
573 WM8350_IM_AUXADC_DATARDY_EINT);
574 case WM8350_IRQ_AUXADC_DCOMP4:
575 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
576 WM8350_IM_AUXADC_DCOMP4_EINT);
577 case WM8350_IRQ_AUXADC_DCOMP3:
578 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
579 WM8350_IM_AUXADC_DCOMP3_EINT);
580 case WM8350_IRQ_AUXADC_DCOMP2:
581 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
582 WM8350_IM_AUXADC_DCOMP2_EINT);
583 case WM8350_IRQ_AUXADC_DCOMP1:
584 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
585 WM8350_IM_AUXADC_DCOMP1_EINT);
586 case WM8350_IRQ_SYS_HYST_COMP_FAIL:
587 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
588 WM8350_IM_SYS_HYST_COMP_FAIL_EINT);
589 case WM8350_IRQ_SYS_CHIP_GT115:
590 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
591 WM8350_IM_SYS_CHIP_GT115_EINT);
592 case WM8350_IRQ_SYS_CHIP_GT140:
593 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
594 WM8350_IM_SYS_CHIP_GT140_EINT);
595 case WM8350_IRQ_SYS_WDOG_TO:
596 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
597 WM8350_IM_SYS_WDOG_TO_EINT);
598 case WM8350_IRQ_UV_LDO4:
599 return wm8350_clear_bits(wm8350,
600 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
601 WM8350_IM_UV_LDO4_EINT);
602 case WM8350_IRQ_UV_LDO3:
603 return wm8350_clear_bits(wm8350,
604 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
605 WM8350_IM_UV_LDO3_EINT);
606 case WM8350_IRQ_UV_LDO2:
607 return wm8350_clear_bits(wm8350,
608 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
609 WM8350_IM_UV_LDO2_EINT);
610 case WM8350_IRQ_UV_LDO1:
611 return wm8350_clear_bits(wm8350,
612 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
613 WM8350_IM_UV_LDO1_EINT);
614 case WM8350_IRQ_UV_DC6:
615 return wm8350_clear_bits(wm8350,
616 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
617 WM8350_IM_UV_DC6_EINT);
618 case WM8350_IRQ_UV_DC5:
619 return wm8350_clear_bits(wm8350,
620 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
621 WM8350_IM_UV_DC5_EINT);
622 case WM8350_IRQ_UV_DC4:
623 return wm8350_clear_bits(wm8350,
624 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
625 WM8350_IM_UV_DC4_EINT);
626 case WM8350_IRQ_UV_DC3:
627 return wm8350_clear_bits(wm8350,
628 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
629 WM8350_IM_UV_DC3_EINT);
630 case WM8350_IRQ_UV_DC2:
631 return wm8350_clear_bits(wm8350,
632 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
633 WM8350_IM_UV_DC2_EINT);
634 case WM8350_IRQ_UV_DC1:
635 return wm8350_clear_bits(wm8350,
636 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
637 WM8350_IM_UV_DC1_EINT);
638 case WM8350_IRQ_OC_LS:
639 return wm8350_clear_bits(wm8350,
640 WM8350_OVER_CURRENT_INT_STATUS_MASK,
641 WM8350_IM_OC_LS_EINT);
642 case WM8350_IRQ_EXT_USB_FB:
643 return wm8350_clear_bits(wm8350,
644 WM8350_COMPARATOR_INT_STATUS_MASK,
645 WM8350_IM_EXT_USB_FB_EINT);
646 case WM8350_IRQ_EXT_WALL_FB:
647 return wm8350_clear_bits(wm8350,
648 WM8350_COMPARATOR_INT_STATUS_MASK,
649 WM8350_IM_EXT_WALL_FB_EINT);
650 case WM8350_IRQ_EXT_BAT_FB:
651 return wm8350_clear_bits(wm8350,
652 WM8350_COMPARATOR_INT_STATUS_MASK,
653 WM8350_IM_EXT_BAT_FB_EINT);
654 case WM8350_IRQ_CODEC_JCK_DET_L:
655 return wm8350_clear_bits(wm8350,
656 WM8350_COMPARATOR_INT_STATUS_MASK,
657 WM8350_IM_CODEC_JCK_DET_L_EINT);
658 case WM8350_IRQ_CODEC_JCK_DET_R:
659 return wm8350_clear_bits(wm8350,
660 WM8350_COMPARATOR_INT_STATUS_MASK,
661 WM8350_IM_CODEC_JCK_DET_R_EINT);
662 case WM8350_IRQ_CODEC_MICSCD:
663 return wm8350_clear_bits(wm8350,
664 WM8350_COMPARATOR_INT_STATUS_MASK,
665 WM8350_IM_CODEC_MICSCD_EINT);
666 case WM8350_IRQ_CODEC_MICD:
667 return wm8350_clear_bits(wm8350,
668 WM8350_COMPARATOR_INT_STATUS_MASK,
669 WM8350_IM_CODEC_MICD_EINT);
670 case WM8350_IRQ_WKUP_OFF_STATE:
671 return wm8350_clear_bits(wm8350,
672 WM8350_COMPARATOR_INT_STATUS_MASK,
673 WM8350_IM_WKUP_OFF_STATE_EINT);
674 case WM8350_IRQ_WKUP_HIB_STATE:
675 return wm8350_clear_bits(wm8350,
676 WM8350_COMPARATOR_INT_STATUS_MASK,
677 WM8350_IM_WKUP_HIB_STATE_EINT);
678 case WM8350_IRQ_WKUP_CONV_FAULT:
679 return wm8350_clear_bits(wm8350,
680 WM8350_COMPARATOR_INT_STATUS_MASK,
681 WM8350_IM_WKUP_CONV_FAULT_EINT);
682 case WM8350_IRQ_WKUP_WDOG_RST:
683 return wm8350_clear_bits(wm8350,
684 WM8350_COMPARATOR_INT_STATUS_MASK,
685 WM8350_IM_WKUP_OFF_STATE_EINT);
686 case WM8350_IRQ_WKUP_GP_PWR_ON:
687 return wm8350_clear_bits(wm8350,
688 WM8350_COMPARATOR_INT_STATUS_MASK,
689 WM8350_IM_WKUP_GP_PWR_ON_EINT);
690 case WM8350_IRQ_WKUP_ONKEY:
691 return wm8350_clear_bits(wm8350,
692 WM8350_COMPARATOR_INT_STATUS_MASK,
693 WM8350_IM_WKUP_ONKEY_EINT);
694 case WM8350_IRQ_WKUP_GP_WAKEUP:
695 return wm8350_clear_bits(wm8350,
696 WM8350_COMPARATOR_INT_STATUS_MASK,
697 WM8350_IM_WKUP_GP_WAKEUP_EINT);
698 case WM8350_IRQ_GPIO(0):
699 return wm8350_clear_bits(wm8350,
700 WM8350_GPIO_INT_STATUS_MASK,
701 WM8350_IM_GP0_EINT);
702 case WM8350_IRQ_GPIO(1):
703 return wm8350_clear_bits(wm8350,
704 WM8350_GPIO_INT_STATUS_MASK,
705 WM8350_IM_GP1_EINT);
706 case WM8350_IRQ_GPIO(2):
707 return wm8350_clear_bits(wm8350,
708 WM8350_GPIO_INT_STATUS_MASK,
709 WM8350_IM_GP2_EINT);
710 case WM8350_IRQ_GPIO(3):
711 return wm8350_clear_bits(wm8350,
712 WM8350_GPIO_INT_STATUS_MASK,
713 WM8350_IM_GP3_EINT);
714 case WM8350_IRQ_GPIO(4):
715 return wm8350_clear_bits(wm8350,
716 WM8350_GPIO_INT_STATUS_MASK,
717 WM8350_IM_GP4_EINT);
718 case WM8350_IRQ_GPIO(5):
719 return wm8350_clear_bits(wm8350,
720 WM8350_GPIO_INT_STATUS_MASK,
721 WM8350_IM_GP5_EINT);
722 case WM8350_IRQ_GPIO(6):
723 return wm8350_clear_bits(wm8350,
724 WM8350_GPIO_INT_STATUS_MASK,
725 WM8350_IM_GP6_EINT);
726 case WM8350_IRQ_GPIO(7):
727 return wm8350_clear_bits(wm8350,
728 WM8350_GPIO_INT_STATUS_MASK,
729 WM8350_IM_GP7_EINT);
730 case WM8350_IRQ_GPIO(8):
731 return wm8350_clear_bits(wm8350,
732 WM8350_GPIO_INT_STATUS_MASK,
733 WM8350_IM_GP8_EINT);
734 case WM8350_IRQ_GPIO(9):
735 return wm8350_clear_bits(wm8350,
736 WM8350_GPIO_INT_STATUS_MASK,
737 WM8350_IM_GP9_EINT);
738 case WM8350_IRQ_GPIO(10):
739 return wm8350_clear_bits(wm8350,
740 WM8350_GPIO_INT_STATUS_MASK,
741 WM8350_IM_GP10_EINT);
742 case WM8350_IRQ_GPIO(11):
743 return wm8350_clear_bits(wm8350,
744 WM8350_GPIO_INT_STATUS_MASK,
745 WM8350_IM_GP11_EINT);
746 case WM8350_IRQ_GPIO(12):
747 return wm8350_clear_bits(wm8350,
748 WM8350_GPIO_INT_STATUS_MASK,
749 WM8350_IM_GP12_EINT);
750 default:
751 dev_warn(wm8350->dev, "Attempting to unmask unknown IRQ %d\n",
752 irq);
753 return -EINVAL;
754 }
755 return 0;
756}
757EXPORT_SYMBOL_GPL(wm8350_unmask_irq);
758
759int wm8350_irq_init(struct wm8350 *wm8350, int irq,
760 struct wm8350_platform_data *pdata)
761{
762 int ret;
763 int flags = IRQF_ONESHOT;
764
765 if (!irq) {
766 dev_err(wm8350->dev, "No IRQ configured\n");
767 return -EINVAL;
768 }
769
770 wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
771 wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
772 wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
773 wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
774 wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
775 wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
776
777 mutex_init(&wm8350->irq_mutex);
778 wm8350->chip_irq = irq;
779
780 if (pdata && pdata->irq_high) {
781 flags |= IRQF_TRIGGER_HIGH;
782
783 wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
784 WM8350_IRQ_POL);
785 } else {
786 flags |= IRQF_TRIGGER_LOW;
787
788 wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
789 WM8350_IRQ_POL);
790 }
791
792 ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
793 "wm8350", wm8350);
794 if (ret != 0)
795 dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
796
797 return ret;
798}
799
800int wm8350_irq_exit(struct wm8350 *wm8350)
801{
802 free_irq(wm8350->chip_irq, wm8350);
803 return 0;
804}