config: tegra3: enable /dev mount with ACL
[linux-2.6.git] / drivers / mfd / max8907c-irq.c
1 /*
2  * Battery driver for Maxim MAX8907C
3  *
4  * Copyright (c) 2011, NVIDIA Corporation.
5  * Based on driver/mfd/max8925-core.c, Copyright (C) 2009-2010 Marvell International Ltd.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/slab.h>
15 #include <linux/i2c.h>
16 #include <linux/irq.h>
17 #include <linux/interrupt.h>
18 #include <linux/mfd/core.h>
19 #include <linux/mfd/max8907c.h>
20
21 struct max8907c_irq_data {
22         int     reg;
23         int     mask_reg;
24         int     enable;         /* enable or not */
25         int     offs;           /* bit offset in mask register */
26         bool    is_rtc;
27         int     wake;
28 };
29
30 static struct max8907c_irq_data max8907c_irqs[] = {
31         [MAX8907C_IRQ_VCHG_DC_OVP] = {
32                 .reg            = MAX8907C_REG_CHG_IRQ1,
33                 .mask_reg       = MAX8907C_REG_CHG_IRQ1_MASK,
34                 .offs           = 1 << 0,
35         },
36         [MAX8907C_IRQ_VCHG_DC_F] = {
37                 .reg            = MAX8907C_REG_CHG_IRQ1,
38                 .mask_reg       = MAX8907C_REG_CHG_IRQ1_MASK,
39                 .offs           = 1 << 1,
40         },
41         [MAX8907C_IRQ_VCHG_DC_R] = {
42                 .reg            = MAX8907C_REG_CHG_IRQ1,
43                 .mask_reg       = MAX8907C_REG_CHG_IRQ1_MASK,
44                 .offs           = 1 << 2,
45         },
46         [MAX8907C_IRQ_VCHG_THM_OK_R] = {
47                 .reg            = MAX8907C_REG_CHG_IRQ2,
48                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
49                 .offs           = 1 << 0,
50         },
51         [MAX8907C_IRQ_VCHG_THM_OK_F] = {
52                 .reg            = MAX8907C_REG_CHG_IRQ2,
53                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
54                 .offs           = 1 << 1,
55         },
56         [MAX8907C_IRQ_VCHG_MBATTLOW_F] = {
57                 .reg            = MAX8907C_REG_CHG_IRQ2,
58                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
59                 .offs           = 1 << 2,
60         },
61         [MAX8907C_IRQ_VCHG_MBATTLOW_R] = {
62                 .reg            = MAX8907C_REG_CHG_IRQ2,
63                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
64                 .offs           = 1 << 3,
65         },
66         [MAX8907C_IRQ_VCHG_RST] = {
67                 .reg            = MAX8907C_REG_CHG_IRQ2,
68                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
69                 .offs           = 1 << 4,
70         },
71         [MAX8907C_IRQ_VCHG_DONE] = {
72                 .reg            = MAX8907C_REG_CHG_IRQ2,
73                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
74                 .offs           = 1 << 5,
75         },
76         [MAX8907C_IRQ_VCHG_TOPOFF] = {
77                 .reg            = MAX8907C_REG_CHG_IRQ2,
78                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
79                 .offs           = 1 << 6,
80         },
81         [MAX8907C_IRQ_VCHG_TMR_FAULT] = {
82                 .reg            = MAX8907C_REG_CHG_IRQ2,
83                 .mask_reg       = MAX8907C_REG_CHG_IRQ2_MASK,
84                 .offs           = 1 << 7,
85         },
86         [MAX8907C_IRQ_GPM_RSTIN] = {
87                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
88                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
89                 .offs           = 1 << 0,
90         },
91         [MAX8907C_IRQ_GPM_MPL] = {
92                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
93                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
94                 .offs           = 1 << 1,
95         },
96         [MAX8907C_IRQ_GPM_SW_3SEC] = {
97                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
98                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
99                 .offs           = 1 << 2,
100         },
101         [MAX8907C_IRQ_GPM_EXTON_F] = {
102                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
103                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
104                 .offs           = 1 << 3,
105         },
106         [MAX8907C_IRQ_GPM_EXTON_R] = {
107                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
108                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
109                 .offs           = 1 << 4,
110         },
111         [MAX8907C_IRQ_GPM_SW_1SEC] = {
112                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
113                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
114                 .offs           = 1 << 5,
115         },
116         [MAX8907C_IRQ_GPM_SW_F] = {
117                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
118                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
119                 .offs           = 1 << 6,
120         },
121         [MAX8907C_IRQ_GPM_SW_R] = {
122                 .reg            = MAX8907C_REG_ON_OFF_IRQ1,
123                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ1_MASK,
124                 .offs           = 1 << 7,
125         },
126         [MAX8907C_IRQ_GPM_SYSCKEN_F] = {
127                 .reg            = MAX8907C_REG_ON_OFF_IRQ2,
128                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ2_MASK,
129                 .offs           = 1 << 0,
130         },
131         [MAX8907C_IRQ_GPM_SYSCKEN_R] = {
132                 .reg            = MAX8907C_REG_ON_OFF_IRQ2,
133                 .mask_reg       = MAX8907C_REG_ON_OFF_IRQ2_MASK,
134                 .offs           = 1 << 1,
135         },
136         [MAX8907C_IRQ_RTC_ALARM1] = {
137                 .reg            = MAX8907C_REG_RTC_IRQ,
138                 .mask_reg       = MAX8907C_REG_RTC_IRQ_MASK,
139                 .offs           = 1 << 2,
140                 .is_rtc         = true,
141         },
142         [MAX8907C_IRQ_RTC_ALARM0] = {
143                 .reg            = MAX8907C_REG_RTC_IRQ,
144                 .mask_reg       = MAX8907C_REG_RTC_IRQ_MASK,
145                 .offs           = 1 << 3,
146                 .is_rtc         = true,
147         },
148 };
149
150 static inline struct max8907c_irq_data *irq_to_max8907c(struct max8907c *chip,
151                                                       int irq)
152 {
153         return &max8907c_irqs[irq - chip->irq_base];
154 }
155
156 static irqreturn_t max8907c_irq(int irq, void *data)
157 {
158         struct max8907c *chip = data;
159         struct max8907c_irq_data *irq_data;
160         struct i2c_client *i2c;
161         int read_reg = -1, value = 0;
162         int i;
163
164         for (i = 0; i < ARRAY_SIZE(max8907c_irqs); i++) {
165                 irq_data = &max8907c_irqs[i];
166
167                 if (irq_data->is_rtc)
168                         i2c = chip->i2c_rtc;
169                 else
170                         i2c = chip->i2c_power;
171
172                 if (read_reg != irq_data->reg) {
173                         read_reg = irq_data->reg;
174                         value = max8907c_reg_read(i2c, irq_data->reg);
175                 }
176
177                 if (value & irq_data->enable)
178                         handle_nested_irq(chip->irq_base + i);
179         }
180         return IRQ_HANDLED;
181 }
182
183 static void max8907c_irq_lock(struct irq_data *data)
184 {
185         struct max8907c *chip = irq_data_get_irq_chip_data(data);
186
187         mutex_lock(&chip->irq_lock);
188 }
189
190 static void max8907c_irq_sync_unlock(struct irq_data *data)
191 {
192         struct max8907c *chip = irq_data_get_irq_chip_data(data);
193         struct max8907c_irq_data *irq_data;
194         unsigned char irq_chg[2], irq_on[2];
195         unsigned char irq_rtc;
196         int i;
197
198         irq_chg[0] = irq_chg[1] = irq_on[0] = irq_on[1] = irq_rtc = 0xFF;
199
200         for (i = 0; i < ARRAY_SIZE(max8907c_irqs); i++) {
201                 irq_data = &max8907c_irqs[i];
202                 /* 1 -- disable, 0 -- enable */
203                 switch (irq_data->mask_reg) {
204                 case MAX8907C_REG_CHG_IRQ1_MASK:
205                         irq_chg[0] &= ~irq_data->enable;
206                         break;
207                 case MAX8907C_REG_CHG_IRQ2_MASK:
208                         irq_chg[1] &= ~irq_data->enable;
209                         break;
210                 case MAX8907C_REG_ON_OFF_IRQ1_MASK:
211                         irq_on[0] &= ~irq_data->enable;
212                         break;
213                 case MAX8907C_REG_ON_OFF_IRQ2_MASK:
214                         irq_on[1] &= ~irq_data->enable;
215                         break;
216                 case MAX8907C_REG_RTC_IRQ_MASK:
217                         irq_rtc &= ~irq_data->enable;
218                         break;
219                 default:
220                         dev_err(chip->dev, "wrong IRQ\n");
221                         break;
222                 }
223         }
224         /* update mask into registers */
225         if (chip->cache_chg[0] != irq_chg[0]) {
226                 chip->cache_chg[0] = irq_chg[0];
227                 max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ1_MASK,
228                         irq_chg[0]);
229         }
230         if (chip->cache_chg[1] != irq_chg[1]) {
231                 chip->cache_chg[1] = irq_chg[1];
232                 max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ2_MASK,
233                         irq_chg[1]);
234         }
235         if (chip->cache_on[0] != irq_on[0]) {
236                 chip->cache_on[0] = irq_on[0];
237                 max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ1_MASK,
238                                 irq_on[0]);
239         }
240         if (chip->cache_on[1] != irq_on[1]) {
241                 chip->cache_on[1] = irq_on[1];
242                 max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ2_MASK,
243                                 irq_on[1]);
244         }
245         if (chip->cache_rtc != irq_rtc) {
246                 chip->cache_rtc = irq_rtc;
247                 max8907c_reg_write(chip->i2c_rtc, MAX8907C_REG_RTC_IRQ_MASK,
248                                    irq_rtc);
249         }
250
251         mutex_unlock(&chip->irq_lock);
252 }
253
254 static void max8907c_irq_enable(struct irq_data *data)
255 {
256         struct max8907c *chip = irq_data_get_irq_chip_data(data);
257         max8907c_irqs[data->irq - chip->irq_base].enable
258                 = max8907c_irqs[data->irq - chip->irq_base].offs;
259 }
260
261 static void max8907c_irq_disable(struct irq_data *data)
262 {
263         struct max8907c *chip = irq_data_get_irq_chip_data(data);
264         max8907c_irqs[data->irq - chip->irq_base].enable = 0;
265 }
266
267 static int max8907c_irq_set_wake(struct irq_data *data, unsigned int on)
268 {
269         struct max8907c *chip = irq_data_get_irq_chip_data(data);
270         if (on) {
271                 max8907c_irqs[data->irq - chip->irq_base].wake
272                         = max8907c_irqs[data->irq - chip->irq_base].enable;
273         } else {
274                 max8907c_irqs[data->irq - chip->irq_base].wake = 0;
275         }
276         return 0;
277 }
278
279 static struct irq_chip max8907c_irq_chip = {
280         .name                   = "max8907c",
281         .irq_bus_lock           = max8907c_irq_lock,
282         .irq_bus_sync_unlock    = max8907c_irq_sync_unlock,
283         .irq_enable             = max8907c_irq_enable,
284         .irq_disable            = max8907c_irq_disable,
285         .irq_set_wake           = max8907c_irq_set_wake,
286 };
287
288 int max8907c_irq_init(struct max8907c *chip, int irq, int irq_base)
289 {
290         unsigned long flags = IRQF_ONESHOT;
291         struct irq_desc *desc;
292         int i, ret;
293         int __irq;
294
295         if (!irq_base || !irq) {
296                 dev_warn(chip->dev, "No interrupt support\n");
297                 return -EINVAL;
298         }
299         /* clear all interrupts */
300         max8907c_reg_read(chip->i2c_power, MAX8907C_REG_CHG_IRQ1);
301         max8907c_reg_read(chip->i2c_power, MAX8907C_REG_CHG_IRQ2);
302         max8907c_reg_read(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ1);
303         max8907c_reg_read(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ2);
304         max8907c_reg_read(chip->i2c_rtc, MAX8907C_REG_RTC_IRQ);
305         /* mask all interrupts */
306         max8907c_reg_write(chip->i2c_rtc, MAX8907C_REG_ALARM0_CNTL, 0);
307         max8907c_reg_write(chip->i2c_rtc, MAX8907C_REG_ALARM1_CNTL, 0);
308         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ1_MASK, 0xff);
309         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ2_MASK, 0xff);
310         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ1_MASK, 0xff);
311         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ2_MASK, 0xff);
312         max8907c_reg_write(chip->i2c_rtc, MAX8907C_REG_RTC_IRQ_MASK, 0xff);
313
314         chip->cache_chg[0] = chip->cache_chg[1] =
315                 chip->cache_on[0] = chip->cache_on[1] =
316                 chip->cache_rtc = 0xFF;
317
318         mutex_init(&chip->irq_lock);
319         chip->core_irq = irq;
320         chip->irq_base = irq_base;
321         desc = irq_to_desc(chip->core_irq);
322
323         /* register with genirq */
324         for (i = 0; i < ARRAY_SIZE(max8907c_irqs); i++) {
325                 __irq = i + chip->irq_base;
326                 irq_set_chip_data(__irq, chip);
327                 irq_set_chip_and_handler(__irq, &max8907c_irq_chip,
328                                          handle_edge_irq);
329                 irq_set_nested_thread(__irq, 1);
330 #ifdef CONFIG_ARM
331                 /* ARM requires an extra step to clear IRQ_NOREQUEST, which it
332                  * sets on behalf of every irq_chip.
333                  */
334                 set_irq_flags(__irq, IRQF_VALID);
335 #else
336                 irq_set_noprobe(__irq);
337 #endif
338         }
339
340         ret = request_threaded_irq(irq, NULL, max8907c_irq, flags,
341                                    "max8907c", chip);
342         if (ret) {
343                 dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
344                 chip->core_irq = 0;
345         }
346
347         device_init_wakeup(chip->dev, 1);
348
349         return ret;
350 }
351
352 int max8907c_suspend(struct i2c_client *i2c, pm_message_t state)
353 {
354         struct max8907c *chip = i2c_get_clientdata(i2c);
355
356         struct max8907c_irq_data *irq_data;
357         unsigned char irq_chg[2], irq_on[2];
358         unsigned char irq_rtc;
359         int i;
360
361         irq_chg[0] = irq_chg[1] = irq_on[0] = irq_on[1] = irq_rtc = 0xFF;
362
363         for (i = 0; i < ARRAY_SIZE(max8907c_irqs); i++) {
364                 irq_data = &max8907c_irqs[i];
365                 /* 1 -- disable, 0 -- enable */
366                 switch (irq_data->mask_reg) {
367                 case MAX8907C_REG_CHG_IRQ1_MASK:
368                         irq_chg[0] &= ~irq_data->wake;
369                         break;
370                 case MAX8907C_REG_CHG_IRQ2_MASK:
371                         irq_chg[1] &= ~irq_data->wake;
372                         break;
373                 case MAX8907C_REG_ON_OFF_IRQ1_MASK:
374                         irq_on[0] &= ~irq_data->wake;
375                         break;
376                 case MAX8907C_REG_ON_OFF_IRQ2_MASK:
377                         irq_on[1] &= ~irq_data->wake;
378                         break;
379                 case MAX8907C_REG_RTC_IRQ_MASK:
380                         irq_rtc &= ~irq_data->wake;
381                         break;
382                 default:
383                         dev_err(chip->dev, "wrong IRQ\n");
384                         break;
385                 }
386         }
387
388         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ1_MASK, irq_chg[0]);
389         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ2_MASK, irq_chg[1]);
390         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ1_MASK, irq_on[0]);
391         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ2_MASK, irq_on[1]);
392         max8907c_reg_write(chip->i2c_rtc, MAX8907C_REG_RTC_IRQ_MASK, irq_rtc);
393
394         if (device_may_wakeup(chip->dev))
395                 enable_irq_wake(chip->core_irq);
396         else
397                 disable_irq(chip->core_irq);
398
399         return 0;
400 }
401
402 int max8907c_resume(struct i2c_client *i2c)
403 {
404         struct max8907c *chip = i2c_get_clientdata(i2c);
405
406         if (device_may_wakeup(chip->dev))
407                 disable_irq_wake(chip->core_irq);
408         else
409                 enable_irq(chip->core_irq);
410
411         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ1_MASK, chip->cache_chg[0]);
412         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_CHG_IRQ2_MASK, chip->cache_chg[1]);
413         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ1_MASK, chip->cache_on[0]);
414         max8907c_reg_write(chip->i2c_power, MAX8907C_REG_ON_OFF_IRQ2_MASK, chip->cache_on[1]);
415         max8907c_reg_write(chip->i2c_rtc, MAX8907C_REG_RTC_IRQ_MASK, chip->cache_rtc);
416
417         return 0;
418 }
419
420 void max8907c_irq_free(struct max8907c *chip)
421 {
422         if (chip->core_irq)
423                 free_irq(chip->core_irq, chip);
424 }
425