2 * max8997-irq.c - Interrupt controller support for MAX8997
4 * Copyright (C) 2011 Samsung Electronics Co.Ltd
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
7 * This program is not provided / owned by Maxim Integrated Products.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * This driver is based on max8998-irq.c
26 #include <linux/err.h>
27 #include <linux/irq.h>
28 #include <linux/interrupt.h>
29 #include <linux/mfd/max8997.h>
30 #include <linux/mfd/max8997-private.h>
32 #include <linux/pm_wakeup.h>
34 #define WAKEUP_TIMEOUT (3000) //ms
36 static u8 max8997_mask_reg[] = {
37 [PMIC_INT1] = MAX8997_REG_INT1MSK,
38 [PMIC_INT2] = MAX8997_REG_INT2MSK,
39 [PMIC_INT3] = MAX8997_REG_INT3MSK,
40 [PMIC_INT4] = MAX8997_REG_INT4MSK,
41 [FUEL_GAUGE] = MAX8997_REG_INVALID,
42 [MUIC_INT1] = MAX8997_MUIC_REG_INTMASK1,
43 [MUIC_INT2] = MAX8997_MUIC_REG_INTMASK2,
44 [MUIC_INT3] = MAX8997_MUIC_REG_INTMASK3,
45 [GPIO_LOW] = MAX8997_REG_INVALID,
46 [GPIO_HI] = MAX8997_REG_INVALID,
47 [FLASH_STATUS] = MAX8997_REG_INVALID,
50 static struct i2c_client *get_i2c(struct max8997_dev *max8997,
51 enum max8997_irq_source src)
54 case PMIC_INT1 ... PMIC_INT4:
58 case MUIC_INT1 ... MUIC_INT3:
60 case GPIO_LOW ... GPIO_HI:
65 return ERR_PTR(-EINVAL);
68 return ERR_PTR(-EINVAL);
71 struct max8997_irq_data {
73 enum max8997_irq_source group;
76 static struct max8997_irq_data max8997_irqs[] = {
77 [MAX8997_PMICIRQ_PWRONR] = {
81 [MAX8997_PMICIRQ_PWRONF] = {
85 [MAX8997_PMICIRQ_PWRON1SEC] = {
89 [MAX8997_PMICIRQ_JIGONR] = {
93 [MAX8997_PMICIRQ_JIGONF] = {
97 [MAX8997_PMICIRQ_LOWBAT2] = {
101 [MAX8997_PMICIRQ_LOWBAT1] = {
106 [MAX8997_PMICIRQ_JIGR] = {
110 [MAX8997_PMICIRQ_JIGF] = {
114 [MAX8997_PMICIRQ_MR] = {
118 [MAX8997_PMICIRQ_DVS1OK] = {
122 [MAX8997_PMICIRQ_DVS2OK] = {
126 [MAX8997_PMICIRQ_DVS3OK] = {
130 [MAX8997_PMICIRQ_DVS4OK] = {
135 [MAX8997_PMICIRQ_CHGINS] = {
139 [MAX8997_PMICIRQ_CHGRM] = {
143 [MAX8997_PMICIRQ_DCINOVP] = {
147 [MAX8997_PMICIRQ_TOPOFFR] = {
151 [MAX8997_PMICIRQ_CHGRSTF] = {
155 [MAX8997_PMICIRQ_MBCHGTMEXPD] = {
160 [MAX8997_PMICIRQ_RTC60S] = {
164 [MAX8997_PMICIRQ_RTCA1] = {
168 [MAX8997_PMICIRQ_RTCA2] = {
172 [MAX8997_PMICIRQ_SMPL_INT] = {
176 [MAX8997_PMICIRQ_RTC1S] = {
180 [MAX8997_PMICIRQ_WTSR] = {
185 [MAX8997_MUICIRQ_ADCError] = {
189 [MAX8997_MUICIRQ_ADCLow] = {
193 [MAX8997_MUICIRQ_ADC] = {
198 [MAX8997_MUICIRQ_VBVolt] = {
202 [MAX8997_MUICIRQ_DBChg] = {
206 [MAX8997_MUICIRQ_DCDTmr] = {
210 [MAX8997_MUICIRQ_ChgDetRun] = {
214 [MAX8997_MUICIRQ_ChgTyp] = {
219 [MAX8997_MUICIRQ_OVP] = {
225 static inline struct max8997_irq_data *
226 irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
228 return &max8997_irqs[irq - max8997->irq_base];
231 static void max8997_irq_lock(unsigned int irq)
233 struct max8997_dev *max8997 = get_irq_chip_data(irq);
235 mutex_lock(&max8997->irqlock);
238 static void max8997_irq_sync_unlock(unsigned int irq)
240 struct max8997_dev *max8997 = get_irq_chip_data(irq);
243 for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) {
244 u8 mask_reg = max8997_mask_reg[i];
245 struct i2c_client *i2c = get_i2c(max8997, i);
247 if (mask_reg == MAX8997_REG_INVALID ||
250 max8997->irq_masks_cache[i] = max8997->irq_masks_cur[i];
252 max8997_write_reg(i2c, max8997_mask_reg[i],
253 max8997->irq_masks_cur[i]);
256 mutex_unlock(&max8997->irqlock);
259 static void max8997_irq_mask(unsigned int irq)
261 struct max8997_dev *max8997 = get_irq_chip_data(irq);
262 struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, irq);
264 max8997->irq_masks_cur[irq_data->group] |= irq_data->mask;
267 static void max8997_irq_unmask(unsigned int irq)
269 struct max8997_dev *max8997 = get_irq_chip_data(irq);
270 struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997, irq);
272 max8997->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
275 static struct irq_chip max8997_irq_chip = {
277 .bus_lock = max8997_irq_lock,
278 .bus_sync_unlock = max8997_irq_sync_unlock,
279 .mask = max8997_irq_mask,
280 .unmask = max8997_irq_unmask,
283 static irqreturn_t max8997_irq_thread(int irq, void *data)
285 struct max8997_dev *max8997 = data;
286 u8 irq_reg[MAX8997_IRQ_GROUP_NR];
291 ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
293 dev_err(max8997->dev, "Failed to read interrupt source: %d\n",
298 for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++)
301 if (irq_src & (1 << 1)) {
302 /* PMIC INT1 ~ INT4 */
303 max8997_bulk_read(max8997->i2c, MAX8997_REG_INT1, 4, &irq_reg[PMIC_INT1]);
305 if (irq_src & (1 << 2)) {
306 /* FUEL GAUGE Interrupt */
308 irq_reg[FUEL_GAUGE] = 0;
310 if (irq_src & (1 << 3)) {
311 /* MUIC INT1 ~ INT3 */
312 max8997_bulk_read(max8997->muic, MAX8997_MUIC_REG_INT1, 3,
313 &irq_reg[MUIC_INT1]);
315 if (irq_src & (1 << 4)) {
320 irq_reg[GPIO_LOW] = 0;
321 irq_reg[GPIO_HI] = 0;
323 max8997_bulk_read(max8997->i2c, MAX8997_REG_GPIOCNTL1, 12,
325 for (gpio = 0; gpio < 8; gpio++) {
326 u8 val = gpio_info[gpio] & 0x34;
327 if (((val & 0x30) == 0x30) ||
330 irq_reg[GPIO_LOW] |= (1 << gpio);
332 for (gpio = 8; gpio < 12; gpio++) {
333 u8 val = gpio_info[gpio] & 0x34;
334 if (((val & 0x30) == 0x30) ||
337 irq_reg[GPIO_HI] |= (1 << (gpio - 8));
340 if (irq_src & (1 << 5)) {
341 /* Flash Status Interrupt */
342 ret = max8997_read_reg(max8997->i2c, MAX8997_REG_FLASHSTATUS,
343 &irq_reg[FLASH_STATUS]);
347 for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++)
348 irq_reg[i] &= ~max8997->irq_masks_cur[i];
351 for (i = 0; i < MAX8997_IRQ_NR; i++) {
352 if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
353 handle_nested_irq(max8997->irq_base + i);
356 if(device_may_wakeup(max8997->dev))
357 pm_wakeup_event(max8997->dev, WAKEUP_TIMEOUT);
362 int max8997_irq_resume(struct max8997_dev *max8997)
364 if (max8997->irq && max8997->irq_base)
365 max8997_irq_thread(max8997->irq, max8997);
369 int max8997_irq_init(struct max8997_dev *max8997)
376 dev_warn(max8997->dev, "No interrupt specified.\n");
377 max8997->irq_base = 0;
381 if (!max8997->irq_base) {
382 dev_err(max8997->dev, "No interrupt base specified.\n");
386 mutex_init(&max8997->irqlock);
388 /* Mask individual interrupt sources */
389 for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) {
390 struct i2c_client *i2c;
392 max8997->irq_masks_cur[i] = 0xff;
393 max8997->irq_masks_cache[i] = 0xff;
394 i2c = get_i2c(max8997, i);
396 if (IS_ERR_OR_NULL(i2c))
398 if (max8997_mask_reg[i] == MAX8997_REG_INVALID)
401 max8997_write_reg(i2c, max8997_mask_reg[i], 0xff);
404 /* Register with genirq */
405 for (i = 0; i < MAX8997_IRQ_NR; i++) {
406 cur_irq = i + max8997->irq_base;
407 set_irq_chip_data(cur_irq, max8997);
408 set_irq_chip_and_handler(cur_irq, &max8997_irq_chip,
410 set_irq_nested_thread(cur_irq, 1);
412 set_irq_flags(cur_irq, IRQF_VALID);
414 set_irq_noprobe(cur_irq);
418 ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
419 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
420 "max8997-irq", max8997);
423 dev_err(max8997->dev, "Failed to request IRQ %d: %d\n",
428 device_init_wakeup(max8997->dev, max8997->wakeup);
433 ret = request_threaded_irq(max8997->ono, NULL, max8997_irq_thread,
434 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
435 IRQF_ONESHOT, "max8997-ono", max8997);
438 dev_err(max8997->dev, "Failed to request ono-IRQ %d: %d\n",
444 void max8997_irq_exit(struct max8997_dev *max8997)
447 free_irq(max8997->ono, max8997);
450 free_irq(max8997->irq, max8997);