1 /* da9063-irq.c: Interrupts support for Dialog DA9063
3 * Copyright 2012 Dialog Semiconductor Ltd.
4 * Copyright 2013 Philipp Zabel, Pengutronix
6 * Author: Michal Hajduk <michal.hajduk@diasemi.com>
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.
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>
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
29 static const struct regmap_irq da9063_irqs
[] = {
30 /* DA9063 event A register */
31 [DA9063_IRQ_ONKEY
] = {
32 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
33 .mask
= DA9063_M_ONKEY
,
35 [DA9063_IRQ_ALARM
] = {
36 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
37 .mask
= DA9063_M_ALARM
,
40 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
41 .mask
= DA9063_M_TICK
,
43 [DA9063_IRQ_ADC_RDY
] = {
44 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
45 .mask
= DA9063_M_ADC_RDY
,
47 [DA9063_IRQ_SEQ_RDY
] = {
48 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
49 .mask
= DA9063_M_SEQ_RDY
,
51 /* DA9063 event B register */
53 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
54 .mask
= DA9063_M_WAKE
,
57 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
58 .mask
= DA9063_M_TEMP
,
60 [DA9063_IRQ_COMP_1V2
] = {
61 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
62 .mask
= DA9063_M_COMP_1V2
,
64 [DA9063_IRQ_LDO_LIM
] = {
65 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
66 .mask
= DA9063_M_LDO_LIM
,
68 [DA9063_IRQ_REG_UVOV
] = {
69 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
70 .mask
= DA9063_M_UVOV
,
72 [DA9063_IRQ_DVC_RDY
] = {
73 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
74 .mask
= DA9063_M_DVC_RDY
,
76 [DA9063_IRQ_VDD_MON
] = {
77 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
78 .mask
= DA9063_M_VDD_MON
,
81 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
82 .mask
= DA9063_M_VDD_WARN
,
84 /* DA9063 event C register */
86 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
87 .mask
= DA9063_M_GPI0
,
90 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
91 .mask
= DA9063_M_GPI1
,
94 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
95 .mask
= DA9063_M_GPI2
,
98 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
99 .mask
= DA9063_M_GPI3
,
101 [DA9063_IRQ_GPI4
] = {
102 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
103 .mask
= DA9063_M_GPI4
,
105 [DA9063_IRQ_GPI5
] = {
106 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
107 .mask
= DA9063_M_GPI5
,
109 [DA9063_IRQ_GPI6
] = {
110 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
111 .mask
= DA9063_M_GPI6
,
113 [DA9063_IRQ_GPI7
] = {
114 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
115 .mask
= DA9063_M_GPI7
,
117 /* DA9063 event D register */
118 [DA9063_IRQ_GPI8
] = {
119 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
120 .mask
= DA9063_M_GPI8
,
122 [DA9063_IRQ_GPI9
] = {
123 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
124 .mask
= DA9063_M_GPI9
,
126 [DA9063_IRQ_GPI10
] = {
127 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
128 .mask
= DA9063_M_GPI10
,
130 [DA9063_IRQ_GPI11
] = {
131 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
132 .mask
= DA9063_M_GPI11
,
134 [DA9063_IRQ_GPI12
] = {
135 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
136 .mask
= DA9063_M_GPI12
,
138 [DA9063_IRQ_GPI13
] = {
139 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
140 .mask
= DA9063_M_GPI13
,
142 [DA9063_IRQ_GPI14
] = {
143 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
144 .mask
= DA9063_M_GPI14
,
146 [DA9063_IRQ_GPI15
] = {
147 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
148 .mask
= DA9063_M_GPI15
,
152 static const struct regmap_irq_chip da9063_irq_chip
= {
153 .name
= "da9063-irq",
155 .num_irqs
= DA9063_NUM_IRQ
,
158 .status_base
= DA9063_REG_EVENT_A
,
159 .mask_base
= DA9063_REG_IRQ_MASK_A
,
160 .ack_base
= DA9063_REG_EVENT_A
,
161 .init_ack_masked
= true,
164 int da9063_irq_init(struct da9063
*da9063
)
168 if (!da9063
->chip_irq
) {
169 dev_err(da9063
->dev
, "No IRQ configured\n");
173 ret
= regmap_add_irq_chip(da9063
->regmap
, da9063
->chip_irq
,
174 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
| IRQF_SHARED
,
175 da9063
->irq_base
, &da9063_irq_chip
,
176 &da9063
->regmap_irq
);
178 dev_err(da9063
->dev
, "Failed to reguest IRQ %d: %d\n",
179 da9063
->chip_irq
, ret
);
186 void da9063_irq_exit(struct da9063
*da9063
)
188 regmap_del_irq_chip(da9063
->chip_irq
, da9063
->regmap_irq
);