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
28 #define EVENTS_BUF_LEN 4
30 static const u8 mask_events_buf
[] = { [0 ... (EVENTS_BUF_LEN
- 1)] = ~0 };
32 struct da9063_irq_data
{
37 static struct regmap_irq da9063_irqs
[] = {
38 /* DA9063 event A register */
39 [DA9063_IRQ_ONKEY
] = {
40 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
41 .mask
= DA9063_M_ONKEY
,
43 [DA9063_IRQ_ALARM
] = {
44 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
45 .mask
= DA9063_M_ALARM
,
48 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
49 .mask
= DA9063_M_TICK
,
51 [DA9063_IRQ_ADC_RDY
] = {
52 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
53 .mask
= DA9063_M_ADC_RDY
,
55 [DA9063_IRQ_SEQ_RDY
] = {
56 .reg_offset
= DA9063_REG_EVENT_A_OFFSET
,
57 .mask
= DA9063_M_SEQ_RDY
,
59 /* DA9063 event B register */
61 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
62 .mask
= DA9063_M_WAKE
,
65 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
66 .mask
= DA9063_M_TEMP
,
68 [DA9063_IRQ_COMP_1V2
] = {
69 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
70 .mask
= DA9063_M_COMP_1V2
,
72 [DA9063_IRQ_LDO_LIM
] = {
73 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
74 .mask
= DA9063_M_LDO_LIM
,
76 [DA9063_IRQ_REG_UVOV
] = {
77 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
78 .mask
= DA9063_M_UVOV
,
80 [DA9063_IRQ_VDD_MON
] = {
81 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
82 .mask
= DA9063_M_VDD_MON
,
85 .reg_offset
= DA9063_REG_EVENT_B_OFFSET
,
86 .mask
= DA9063_M_VDD_WARN
,
88 /* DA9063 event C register */
90 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
91 .mask
= DA9063_M_GPI0
,
94 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
95 .mask
= DA9063_M_GPI1
,
98 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
99 .mask
= DA9063_M_GPI2
,
101 [DA9063_IRQ_GPI3
] = {
102 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
103 .mask
= DA9063_M_GPI3
,
105 [DA9063_IRQ_GPI4
] = {
106 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
107 .mask
= DA9063_M_GPI4
,
109 [DA9063_IRQ_GPI5
] = {
110 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
111 .mask
= DA9063_M_GPI5
,
113 [DA9063_IRQ_GPI6
] = {
114 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
115 .mask
= DA9063_M_GPI6
,
117 [DA9063_IRQ_GPI7
] = {
118 .reg_offset
= DA9063_REG_EVENT_C_OFFSET
,
119 .mask
= DA9063_M_GPI7
,
121 /* DA9063 event D register */
122 [DA9063_IRQ_GPI8
] = {
123 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
124 .mask
= DA9063_M_GPI8
,
126 [DA9063_IRQ_GPI9
] = {
127 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
128 .mask
= DA9063_M_GPI9
,
130 [DA9063_IRQ_GPI10
] = {
131 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
132 .mask
= DA9063_M_GPI10
,
134 [DA9063_IRQ_GPI11
] = {
135 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
136 .mask
= DA9063_M_GPI11
,
138 [DA9063_IRQ_GPI12
] = {
139 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
140 .mask
= DA9063_M_GPI12
,
142 [DA9063_IRQ_GPI13
] = {
143 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
144 .mask
= DA9063_M_GPI13
,
146 [DA9063_IRQ_GPI14
] = {
147 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
148 .mask
= DA9063_M_GPI14
,
150 [DA9063_IRQ_GPI15
] = {
151 .reg_offset
= DA9063_REG_EVENT_D_OFFSET
,
152 .mask
= DA9063_M_GPI15
,
156 static struct regmap_irq_chip da9063_irq_chip
= {
157 .name
= "da9063-irq",
159 .num_irqs
= DA9063_NUM_IRQ
,
162 .status_base
= DA9063_REG_EVENT_A
,
163 .mask_base
= DA9063_REG_IRQ_MASK_A
,
164 .ack_base
= DA9063_REG_EVENT_A
,
165 .init_ack_masked
= true,
168 int da9063_irq_init(struct da9063
*da9063
)
172 if (!da9063
->chip_irq
) {
173 dev_err(da9063
->dev
, "No IRQ configured\n");
177 ret
= regmap_add_irq_chip(da9063
->regmap
, da9063
->chip_irq
,
178 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
| IRQF_SHARED
,
179 da9063
->irq_base
, &da9063_irq_chip
,
180 &da9063
->regmap_irq
);
182 dev_err(da9063
->dev
, "Failed to reguest IRQ %d: %d\n",
183 da9063
->chip_irq
, ret
);
190 void da9063_irq_exit(struct da9063
*da9063
)
192 regmap_del_irq_chip(da9063
->chip_irq
, da9063
->regmap_irq
);