1 /* da9063-irq.c: Interrupts support for Dialog DA9063 2 * 3 * Copyright 2012 Dialog Semiconductor Ltd. 4 * Copyright 2013 Philipp Zabel, Pengutronix 5 * 6 * Author: Michal Hajduk, Dialog Semiconductor 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/irq.h> 18 #include <linux/mfd/core.h> 19 #include <linux/interrupt.h> 20 #include <linux/regmap.h> 21 #include <linux/mfd/da9063/core.h> 22 #include <linux/mfd/da9063/pdata.h> 23 24 #define DA9063_REG_EVENT_A_OFFSET 0 25 #define DA9063_REG_EVENT_B_OFFSET 1 26 #define DA9063_REG_EVENT_C_OFFSET 2 27 #define DA9063_REG_EVENT_D_OFFSET 3 28 29 static const struct regmap_irq da9063_irqs[] = { 30 /* DA9063 event A register */ 31 REGMAP_IRQ_REG(DA9063_IRQ_ONKEY, 32 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ONKEY), 33 REGMAP_IRQ_REG(DA9063_IRQ_ALARM, 34 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ALARM), 35 REGMAP_IRQ_REG(DA9063_IRQ_TICK, 36 DA9063_REG_EVENT_A_OFFSET, DA9063_M_TICK), 37 REGMAP_IRQ_REG(DA9063_IRQ_ADC_RDY, 38 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ADC_RDY), 39 REGMAP_IRQ_REG(DA9063_IRQ_SEQ_RDY, 40 DA9063_REG_EVENT_A_OFFSET, DA9063_M_SEQ_RDY), 41 /* DA9063 event B register */ 42 REGMAP_IRQ_REG(DA9063_IRQ_WAKE, 43 DA9063_REG_EVENT_B_OFFSET, DA9063_M_WAKE), 44 REGMAP_IRQ_REG(DA9063_IRQ_TEMP, 45 DA9063_REG_EVENT_B_OFFSET, DA9063_M_TEMP), 46 REGMAP_IRQ_REG(DA9063_IRQ_COMP_1V2, 47 DA9063_REG_EVENT_B_OFFSET, DA9063_M_COMP_1V2), 48 REGMAP_IRQ_REG(DA9063_IRQ_LDO_LIM, 49 DA9063_REG_EVENT_B_OFFSET, DA9063_M_LDO_LIM), 50 REGMAP_IRQ_REG(DA9063_IRQ_REG_UVOV, 51 DA9063_REG_EVENT_B_OFFSET, DA9063_M_UVOV), 52 REGMAP_IRQ_REG(DA9063_IRQ_DVC_RDY, 53 DA9063_REG_EVENT_B_OFFSET, DA9063_M_DVC_RDY), 54 REGMAP_IRQ_REG(DA9063_IRQ_VDD_MON, 55 DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_MON), 56 REGMAP_IRQ_REG(DA9063_IRQ_WARN, 57 DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_WARN), 58 /* DA9063 event C register */ 59 REGMAP_IRQ_REG(DA9063_IRQ_GPI0, 60 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI0), 61 REGMAP_IRQ_REG(DA9063_IRQ_GPI1, 62 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI1), 63 REGMAP_IRQ_REG(DA9063_IRQ_GPI2, 64 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI2), 65 REGMAP_IRQ_REG(DA9063_IRQ_GPI3, 66 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI3), 67 REGMAP_IRQ_REG(DA9063_IRQ_GPI4, 68 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI4), 69 REGMAP_IRQ_REG(DA9063_IRQ_GPI5, 70 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI5), 71 REGMAP_IRQ_REG(DA9063_IRQ_GPI6, 72 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI6), 73 REGMAP_IRQ_REG(DA9063_IRQ_GPI7, 74 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI7), 75 /* DA9063 event D register */ 76 REGMAP_IRQ_REG(DA9063_IRQ_GPI8, 77 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI8), 78 REGMAP_IRQ_REG(DA9063_IRQ_GPI9, 79 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI9), 80 REGMAP_IRQ_REG(DA9063_IRQ_GPI10, 81 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI10), 82 REGMAP_IRQ_REG(DA9063_IRQ_GPI11, 83 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI11), 84 REGMAP_IRQ_REG(DA9063_IRQ_GPI12, 85 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI12), 86 REGMAP_IRQ_REG(DA9063_IRQ_GPI13, 87 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI13), 88 REGMAP_IRQ_REG(DA9063_IRQ_GPI14, 89 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI14), 90 REGMAP_IRQ_REG(DA9063_IRQ_GPI15, 91 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI15), 92 }; 93 94 static const struct regmap_irq_chip da9063_irq_chip = { 95 .name = "da9063-irq", 96 .irqs = da9063_irqs, 97 .num_irqs = ARRAY_SIZE(da9063_irqs), 98 .num_regs = 4, 99 .status_base = DA9063_REG_EVENT_A, 100 .mask_base = DA9063_REG_IRQ_MASK_A, 101 .ack_base = DA9063_REG_EVENT_A, 102 .init_ack_masked = true, 103 }; 104 105 int da9063_irq_init(struct da9063 *da9063) 106 { 107 int ret; 108 109 if (!da9063->chip_irq) { 110 dev_err(da9063->dev, "No IRQ configured\n"); 111 return -EINVAL; 112 } 113 114 ret = devm_regmap_add_irq_chip(da9063->dev, da9063->regmap, 115 da9063->chip_irq, 116 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 117 da9063->irq_base, &da9063_irq_chip, 118 &da9063->regmap_irq); 119 if (ret) { 120 dev_err(da9063->dev, "Failed to reguest IRQ %d: %d\n", 121 da9063->chip_irq, ret); 122 return ret; 123 } 124 125 return 0; 126 } 127