wl1251: improve PS report handling
[pandora-kernel.git] / drivers / mfd / pcf50633-irq.c
1 /* NXP PCF50633 Power Management Unit (PMU) driver
2  *
3  * (C) 2006-2008 by Openmoko, Inc.
4  * Author: Harald Welte <laforge@openmoko.org>
5  *         Balaji Rao <balajirrao@openmoko.org>
6  * All rights reserved.
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/interrupt.h>
16 #include <linux/kernel.h>
17 #include <linux/mutex.h>
18 #include <linux/export.h>
19 #include <linux/slab.h>
20
21 #include <linux/mfd/pcf50633/core.h>
22
23 /* Two MBCS registers used during cold start */
24 #define PCF50633_REG_MBCS1              0x4b
25 #define PCF50633_REG_MBCS2              0x4c
26 #define PCF50633_MBCS1_USBPRES          0x01
27 #define PCF50633_MBCS1_ADAPTPRES        0x01
28
29 int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
30                         void (*handler) (int, void *), void *data)
31 {
32         if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler)
33                 return -EINVAL;
34
35         if (WARN_ON(pcf->irq_handler[irq].handler))
36                 return -EBUSY;
37
38         mutex_lock(&pcf->lock);
39         pcf->irq_handler[irq].handler = handler;
40         pcf->irq_handler[irq].data = data;
41         mutex_unlock(&pcf->lock);
42
43         return 0;
44 }
45 EXPORT_SYMBOL_GPL(pcf50633_register_irq);
46
47 int pcf50633_free_irq(struct pcf50633 *pcf, int irq)
48 {
49         if (irq < 0 || irq >= PCF50633_NUM_IRQ)
50                 return -EINVAL;
51
52         mutex_lock(&pcf->lock);
53         pcf->irq_handler[irq].handler = NULL;
54         mutex_unlock(&pcf->lock);
55
56         return 0;
57 }
58 EXPORT_SYMBOL_GPL(pcf50633_free_irq);
59
60 static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
61 {
62         u8 reg, bit;
63         int ret = 0, idx;
64
65         idx = irq >> 3;
66         reg = PCF50633_REG_INT1M + idx;
67         bit = 1 << (irq & 0x07);
68
69         pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0);
70
71         mutex_lock(&pcf->lock);
72
73         if (mask)
74                 pcf->mask_regs[idx] |= bit;
75         else
76                 pcf->mask_regs[idx] &= ~bit;
77
78         mutex_unlock(&pcf->lock);
79
80         return ret;
81 }
82
83 int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
84 {
85         dev_dbg(pcf->dev, "Masking IRQ %d\n", irq);
86
87         return __pcf50633_irq_mask_set(pcf, irq, 1);
88 }
89 EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
90
91 int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
92 {
93         dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq);
94
95         return __pcf50633_irq_mask_set(pcf, irq, 0);
96 }
97 EXPORT_SYMBOL_GPL(pcf50633_irq_unmask);
98
99 int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq)
100 {
101         u8 reg, bits;
102
103         reg =  irq >> 3;
104         bits = 1 << (irq & 0x07);
105
106         return pcf->mask_regs[reg] & bits;
107 }
108 EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get);
109
110 static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq)
111 {
112         if (pcf->irq_handler[irq].handler)
113                 pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data);
114 }
115
116 /* Maximum amount of time ONKEY is held before emergency action is taken */
117 #define PCF50633_ONKEY1S_TIMEOUT 8
118
119 static irqreturn_t pcf50633_irq(int irq, void *data)
120 {
121         struct pcf50633 *pcf = data;
122         int ret, i, j;
123         u8 pcf_int[5], chgstat;
124
125         /* Read the 5 INT regs in one transaction */
126         ret = pcf50633_read_block(pcf, PCF50633_REG_INT1,
127                                                 ARRAY_SIZE(pcf_int), pcf_int);
128         if (ret != ARRAY_SIZE(pcf_int)) {
129                 dev_err(pcf->dev, "Error reading INT registers\n");
130
131                 /*
132                  * If this doesn't ACK the interrupt to the chip, we'll be
133                  * called once again as we're level triggered.
134                  */
135                 goto out;
136         }
137
138         /* defeat 8s death from lowsys on A5 */
139         pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN,  0x04);
140
141         /* We immediately read the usb and adapter status. We thus make sure
142          * only of USBINS/USBREM IRQ handlers are called */
143         if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
144                 chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
145                 if (chgstat & (0x3 << 4))
146                         pcf_int[0] &= ~PCF50633_INT1_USBREM;
147                 else
148                         pcf_int[0] &= ~PCF50633_INT1_USBINS;
149         }
150
151         /* Make sure only one of ADPINS or ADPREM is set */
152         if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
153                 chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
154                 if (chgstat & (0x3 << 4))
155                         pcf_int[0] &= ~PCF50633_INT1_ADPREM;
156                 else
157                         pcf_int[0] &= ~PCF50633_INT1_ADPINS;
158         }
159
160         dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
161                         "INT4=0x%02x INT5=0x%02x\n", pcf_int[0],
162                         pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]);
163
164         /* Some revisions of the chip don't have a 8s standby mode on
165          * ONKEY1S press. We try to manually do it in such cases. */
166         if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) {
167                 dev_info(pcf->dev, "ONKEY1S held for %d secs\n",
168                                                         pcf->onkey1s_held);
169                 if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT)
170                         if (pcf->pdata->force_shutdown)
171                                 pcf->pdata->force_shutdown(pcf);
172         }
173
174         if (pcf_int[2] & PCF50633_INT3_ONKEY1S) {
175                 dev_info(pcf->dev, "ONKEY1S held\n");
176                 pcf->onkey1s_held = 1 ;
177
178                 /* Unmask IRQ_SECOND */
179                 pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M,
180                                                 PCF50633_INT1_SECOND);
181
182                 /* Unmask IRQ_ONKEYR */
183                 pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M,
184                                                 PCF50633_INT2_ONKEYR);
185         }
186
187         if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) {
188                 pcf->onkey1s_held = 0;
189
190                 /* Mask SECOND and ONKEYR interrupts */
191                 if (pcf->mask_regs[0] & PCF50633_INT1_SECOND)
192                         pcf50633_reg_set_bit_mask(pcf,
193                                         PCF50633_REG_INT1M,
194                                         PCF50633_INT1_SECOND,
195                                         PCF50633_INT1_SECOND);
196
197                 if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR)
198                         pcf50633_reg_set_bit_mask(pcf,
199                                         PCF50633_REG_INT2M,
200                                         PCF50633_INT2_ONKEYR,
201                                         PCF50633_INT2_ONKEYR);
202         }
203
204         /* Have we just resumed ? */
205         if (pcf->is_suspended) {
206                 pcf->is_suspended = 0;
207
208                 /* Set the resume reason filtering out non resumers */
209                 for (i = 0; i < ARRAY_SIZE(pcf_int); i++)
210                         pcf->resume_reason[i] = pcf_int[i] &
211                                                 pcf->pdata->resumers[i];
212
213                 /* Make sure we don't pass on any ONKEY events to
214                  * userspace now */
215                 pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF);
216         }
217
218         for (i = 0; i < ARRAY_SIZE(pcf_int); i++) {
219                 /* Unset masked interrupts */
220                 pcf_int[i] &= ~pcf->mask_regs[i];
221
222                 for (j = 0; j < 8 ; j++)
223                         if (pcf_int[i] & (1 << j))
224                                 pcf50633_irq_call_handler(pcf, (i * 8) + j);
225         }
226
227 out:
228         return IRQ_HANDLED;
229 }
230
231 #ifdef CONFIG_PM
232
233 int pcf50633_irq_suspend(struct pcf50633 *pcf)
234 {
235         int ret;
236         int i;
237         u8 res[5];
238
239
240         /* Make sure our interrupt handlers are not called
241          * henceforth */
242         disable_irq(pcf->irq);
243
244         /* Save the masks */
245         ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
246                                 ARRAY_SIZE(pcf->suspend_irq_masks),
247                                         pcf->suspend_irq_masks);
248         if (ret < 0) {
249                 dev_err(pcf->dev, "error saving irq masks\n");
250                 goto out;
251         }
252
253         /* Write wakeup irq masks */
254         for (i = 0; i < ARRAY_SIZE(res); i++)
255                 res[i] = ~pcf->pdata->resumers[i];
256
257         ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
258                                         ARRAY_SIZE(res), &res[0]);
259         if (ret < 0) {
260                 dev_err(pcf->dev, "error writing wakeup irq masks\n");
261                 goto out;
262         }
263
264         pcf->is_suspended = 1;
265
266 out:
267         return ret;
268 }
269
270 int pcf50633_irq_resume(struct pcf50633 *pcf)
271 {
272         int ret;
273
274         /* Write the saved mask registers */
275         ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
276                                 ARRAY_SIZE(pcf->suspend_irq_masks),
277                                         pcf->suspend_irq_masks);
278         if (ret < 0)
279                 dev_err(pcf->dev, "Error restoring saved suspend masks\n");
280
281         enable_irq(pcf->irq);
282
283         return ret;
284 }
285
286 #endif
287
288 int pcf50633_irq_init(struct pcf50633 *pcf, int irq)
289 {
290         int ret;
291
292         pcf->irq = irq;
293
294         /* Enable all interrupts except RTC SECOND */
295         pcf->mask_regs[0] = 0x80;
296         pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]);
297         pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00);
298         pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00);
299         pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
300         pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
301
302         ret = request_threaded_irq(irq, NULL, pcf50633_irq,
303                                         IRQF_TRIGGER_LOW | IRQF_ONESHOT,
304                                         "pcf50633", pcf);
305
306         if (ret)
307                 dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
308
309         if (enable_irq_wake(irq) < 0)
310                 dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
311                         "in this hardware revision", irq);
312
313         return ret;
314 }
315
316 void pcf50633_irq_free(struct pcf50633 *pcf)
317 {
318         free_irq(pcf->irq, pcf);
319 }