aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/extcon/extcon-max77693.c3
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/max77693-irq.c346
-rw-r--r--drivers/mfd/max77693.c158
-rw-r--r--include/linux/mfd/max77693-private.h46
6 files changed, 195 insertions, 361 deletions
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index ba84a6e77e03..c7278b1649da 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -1154,7 +1154,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
1154 struct max77693_muic_irq *muic_irq = &muic_irqs[i]; 1154 struct max77693_muic_irq *muic_irq = &muic_irqs[i];
1155 unsigned int virq = 0; 1155 unsigned int virq = 0;
1156 1156
1157 virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq); 1157 virq = regmap_irq_get_virq(max77693->irq_data_muic,
1158 muic_irq->irq);
1158 if (!virq) { 1159 if (!virq) {
1159 ret = -EINVAL; 1160 ret = -EINVAL;
1160 goto err_irq; 1161 goto err_irq;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ee8204cc31e9..2feac14d1085 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -384,6 +384,7 @@ config MFD_MAX77693
384 depends on I2C=y 384 depends on I2C=y
385 select MFD_CORE 385 select MFD_CORE
386 select REGMAP_I2C 386 select REGMAP_I2C
387 select REGMAP_IRQ
387 help 388 help
388 Say yes here to add support for Maxim Semiconductor MAX77693. 389 Say yes here to add support for Maxim Semiconductor MAX77693.
389 This is a companion Power Management IC with Flash, Haptic, Charger, 390 This is a companion Power Management IC with Flash, Haptic, Charger,
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8afedba535c7..8c6e7bba4660 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -116,7 +116,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o
116 116
117obj-$(CONFIG_MFD_MAX14577) += max14577.o 117obj-$(CONFIG_MFD_MAX14577) += max14577.o
118obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o 118obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
119obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o 119obj-$(CONFIG_MFD_MAX77693) += max77693.o
120obj-$(CONFIG_MFD_MAX8907) += max8907.o 120obj-$(CONFIG_MFD_MAX8907) += max8907.o
121max8925-objs := max8925-core.o max8925-i2c.o 121max8925-objs := max8925-core.o max8925-i2c.o
122obj-$(CONFIG_MFD_MAX8925) += max8925.o 122obj-$(CONFIG_MFD_MAX8925) += max8925.o
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c
deleted file mode 100644
index 7d8f99f94f27..000000000000
--- a/drivers/mfd/max77693-irq.c
+++ /dev/null
@@ -1,346 +0,0 @@
1/*
2 * max77693-irq.c - Interrupt controller support for MAX77693
3 *
4 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 * SangYoung Son <hello.son@samsung.com>
6 *
7 * This program is not provided / owned by Maxim Integrated Products.
8 *
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.
13 *
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.
18 *
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
22 *
23 * This driver is based on max8997-irq.c
24 */
25
26#include <linux/err.h>
27#include <linux/irq.h>
28#include <linux/interrupt.h>
29#include <linux/module.h>
30#include <linux/irqdomain.h>
31#include <linux/mfd/max77693.h>
32#include <linux/mfd/max77693-private.h>
33#include <linux/regmap.h>
34
35static const unsigned int max77693_mask_reg[] = {
36 [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK,
37 [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
38 [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK,
39 [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1,
40 [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2,
41 [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3,
42};
43
44static struct regmap *max77693_get_regmap(struct max77693_dev *max77693,
45 enum max77693_irq_source src)
46{
47 switch (src) {
48 case LED_INT ... CHG_INT:
49 return max77693->regmap;
50 case MUIC_INT1 ... MUIC_INT3:
51 return max77693->regmap_muic;
52 default:
53 return ERR_PTR(-EINVAL);
54 }
55}
56
57struct max77693_irq_data {
58 int mask;
59 enum max77693_irq_source group;
60};
61
62#define DECLARE_IRQ(idx, _group, _mask) \
63 [(idx)] = { .group = (_group), .mask = (_mask) }
64static const struct max77693_irq_data max77693_irqs[] = {
65 DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN, LED_INT, 1 << 0),
66 DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT, LED_INT, 1 << 1),
67 DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN, LED_INT, 1 << 2),
68 DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT, LED_INT, 1 << 3),
69 DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH, LED_INT, 1 << 4),
70
71 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT, TOPSYS_INT, 1 << 0),
72 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT, TOPSYS_INT, 1 << 1),
73 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT, TOPSYS_INT, 1 << 3),
74
75 DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I, CHG_INT, 1 << 0),
76 DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I, CHG_INT, 1 << 2),
77 DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I, CHG_INT, 1 << 3),
78 DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I, CHG_INT, 1 << 4),
79 DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I, CHG_INT, 1 << 6),
80
81 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC, MUIC_INT1, 1 << 0),
82 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW, MUIC_INT1, 1 << 1),
83 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR, MUIC_INT1, 1 << 2),
84 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K, MUIC_INT1, 1 << 3),
85
86 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP, MUIC_INT2, 1 << 0),
87 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN, MUIC_INT2, 1 << 1),
88 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR, MUIC_INT2, 1 << 2),
89 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP, MUIC_INT2, 1 << 3),
90 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT, MUIC_INT2, 1 << 4),
91 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM, MUIC_INT2, 1 << 5),
92
93 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC, MUIC_INT3, 1 << 0),
94 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC, MUIC_INT3, 1 << 1),
95 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP, MUIC_INT3, 1 << 2),
96 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, MUIC_INT3, 1 << 3),
97 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4),
98 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET, MUIC_INT3, 1 << 5),
99};
100
101static void max77693_irq_lock(struct irq_data *data)
102{
103 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
104
105 mutex_lock(&max77693->irqlock);
106}
107
108static void max77693_irq_sync_unlock(struct irq_data *data)
109{
110 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
111 int i;
112
113 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
114 u8 mask_reg = max77693_mask_reg[i];
115 struct regmap *map = max77693_get_regmap(max77693, i);
116
117 if (mask_reg == MAX77693_REG_INVALID ||
118 IS_ERR_OR_NULL(map))
119 continue;
120 max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i];
121
122 regmap_write(map, max77693_mask_reg[i],
123 max77693->irq_masks_cur[i]);
124 }
125
126 mutex_unlock(&max77693->irqlock);
127}
128
129static const inline struct max77693_irq_data *
130irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
131{
132 struct irq_data *data = irq_get_irq_data(irq);
133 return &max77693_irqs[data->hwirq];
134}
135
136static void max77693_irq_mask(struct irq_data *data)
137{
138 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
139 const struct max77693_irq_data *irq_data =
140 irq_to_max77693_irq(max77693, data->irq);
141
142 if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
143 return;
144
145 if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
146 max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
147 else
148 max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
149}
150
151static void max77693_irq_unmask(struct irq_data *data)
152{
153 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
154 const struct max77693_irq_data *irq_data =
155 irq_to_max77693_irq(max77693, data->irq);
156
157 if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
158 return;
159
160 if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
161 max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
162 else
163 max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
164}
165
166static struct irq_chip max77693_irq_chip = {
167 .name = "max77693",
168 .irq_bus_lock = max77693_irq_lock,
169 .irq_bus_sync_unlock = max77693_irq_sync_unlock,
170 .irq_mask = max77693_irq_mask,
171 .irq_unmask = max77693_irq_unmask,
172};
173
174#define MAX77693_IRQSRC_CHG (1 << 0)
175#define MAX77693_IRQSRC_TOP (1 << 1)
176#define MAX77693_IRQSRC_FLASH (1 << 2)
177#define MAX77693_IRQSRC_MUIC (1 << 3)
178static irqreturn_t max77693_irq_thread(int irq, void *data)
179{
180 struct max77693_dev *max77693 = data;
181 u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {};
182 unsigned int irq_src;
183 int ret;
184 int i, cur_irq;
185
186 ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC,
187 &irq_src);
188 if (ret < 0) {
189 dev_err(max77693->dev, "Failed to read interrupt source: %d\n",
190 ret);
191 return IRQ_NONE;
192 }
193
194 if (irq_src & MAX77693_IRQSRC_CHG) {
195 /* CHG_INT */
196 unsigned int data;
197 ret = regmap_read(max77693->regmap,
198 MAX77693_CHG_REG_CHG_INT, &data);
199 irq_reg[CHG_INT] = data;
200 }
201
202 if (irq_src & MAX77693_IRQSRC_TOP) {
203 /* TOPSYS_INT */
204 unsigned int data;
205 ret = regmap_read(max77693->regmap,
206 MAX77693_PMIC_REG_TOPSYS_INT, &data);
207 irq_reg[TOPSYS_INT] = data;
208 }
209
210 if (irq_src & MAX77693_IRQSRC_FLASH) {
211 /* LED_INT */
212 unsigned int data;
213 ret = regmap_read(max77693->regmap,
214 MAX77693_LED_REG_FLASH_INT, &data);
215 irq_reg[LED_INT] = data;
216 }
217
218 if (irq_src & MAX77693_IRQSRC_MUIC)
219 /* MUIC INT1 ~ INT3 */
220 regmap_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,
221 &irq_reg[MUIC_INT1], MAX77693_NUM_IRQ_MUIC_REGS);
222
223 /* Apply masking */
224 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
225 if (i >= MUIC_INT1 && i <= MUIC_INT3)
226 irq_reg[i] &= max77693->irq_masks_cur[i];
227 else
228 irq_reg[i] &= ~max77693->irq_masks_cur[i];
229 }
230
231 /* Report */
232 for (i = 0; i < MAX77693_IRQ_NR; i++) {
233 if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) {
234 cur_irq = irq_find_mapping(max77693->irq_domain, i);
235 if (cur_irq)
236 handle_nested_irq(cur_irq);
237 }
238 }
239
240 return IRQ_HANDLED;
241}
242
243int max77693_irq_resume(struct max77693_dev *max77693)
244{
245 if (max77693->irq)
246 max77693_irq_thread(0, max77693);
247
248 return 0;
249}
250
251static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq,
252 irq_hw_number_t hw)
253{
254 struct max77693_dev *max77693 = d->host_data;
255
256 irq_set_chip_data(irq, max77693);
257 irq_set_chip_and_handler(irq, &max77693_irq_chip, handle_edge_irq);
258 irq_set_nested_thread(irq, 1);
259#ifdef CONFIG_ARM
260 set_irq_flags(irq, IRQF_VALID);
261#else
262 irq_set_noprobe(irq);
263#endif
264 return 0;
265}
266
267static struct irq_domain_ops max77693_irq_domain_ops = {
268 .map = max77693_irq_domain_map,
269};
270
271int max77693_irq_init(struct max77693_dev *max77693)
272{
273 struct irq_domain *domain;
274 int i;
275 int ret = 0;
276 unsigned int intsrc_mask;
277
278 mutex_init(&max77693->irqlock);
279
280 /* Mask individual interrupt sources */
281 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
282 struct regmap *map;
283 /* MUIC IRQ 0:MASK 1:NOT MASK */
284 /* Other IRQ 1:MASK 0:NOT MASK */
285 if (i >= MUIC_INT1 && i <= MUIC_INT3) {
286 max77693->irq_masks_cur[i] = 0x00;
287 max77693->irq_masks_cache[i] = 0x00;
288 } else {
289 max77693->irq_masks_cur[i] = 0xff;
290 max77693->irq_masks_cache[i] = 0xff;
291 }
292 map = max77693_get_regmap(max77693, i);
293
294 if (IS_ERR_OR_NULL(map))
295 continue;
296 if (max77693_mask_reg[i] == MAX77693_REG_INVALID)
297 continue;
298 if (i >= MUIC_INT1 && i <= MUIC_INT3)
299 regmap_write(map, max77693_mask_reg[i], 0x00);
300 else
301 regmap_write(map, max77693_mask_reg[i], 0xff);
302 }
303
304 domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR,
305 &max77693_irq_domain_ops, max77693);
306 if (!domain) {
307 dev_err(max77693->dev, "could not create irq domain\n");
308 ret = -ENODEV;
309 goto err_irq;
310 }
311 max77693->irq_domain = domain;
312
313 /* Unmask max77693 interrupt */
314 ret = regmap_read(max77693->regmap,
315 MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask);
316 if (ret < 0) {
317 dev_err(max77693->dev, "fail to read PMIC register\n");
318 goto err_irq;
319 }
320
321 intsrc_mask &= ~(MAX77693_IRQSRC_CHG);
322 intsrc_mask &= ~(MAX77693_IRQSRC_FLASH);
323 intsrc_mask &= ~(MAX77693_IRQSRC_MUIC);
324 ret = regmap_write(max77693->regmap,
325 MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask);
326 if (ret < 0) {
327 dev_err(max77693->dev, "fail to write PMIC register\n");
328 goto err_irq;
329 }
330
331 ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,
332 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
333 "max77693-irq", max77693);
334 if (ret)
335 dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",
336 max77693->irq, ret);
337
338err_irq:
339 return ret;
340}
341
342void max77693_irq_exit(struct max77693_dev *max77693)
343{
344 if (max77693->irq)
345 free_irq(max77693->irq, max77693);
346}
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
index a0308336adaf..249c139ef04a 100644
--- a/drivers/mfd/max77693.c
+++ b/drivers/mfd/max77693.c
@@ -55,12 +55,95 @@ static const struct regmap_config max77693_regmap_config = {
55 .max_register = MAX77693_PMIC_REG_END, 55 .max_register = MAX77693_PMIC_REG_END,
56}; 56};
57 57
58static const struct regmap_irq max77693_led_irqs[] = {
59 { .mask = LED_IRQ_FLED2_OPEN, },
60 { .mask = LED_IRQ_FLED2_SHORT, },
61 { .mask = LED_IRQ_FLED1_OPEN, },
62 { .mask = LED_IRQ_FLED1_SHORT, },
63 { .mask = LED_IRQ_MAX_FLASH, },
64};
65
66static const struct regmap_irq_chip max77693_led_irq_chip = {
67 .name = "max77693-led",
68 .status_base = MAX77693_LED_REG_FLASH_INT,
69 .mask_base = MAX77693_LED_REG_FLASH_INT_MASK,
70 .mask_invert = false,
71 .num_regs = 1,
72 .irqs = max77693_led_irqs,
73 .num_irqs = ARRAY_SIZE(max77693_led_irqs),
74};
75
76static const struct regmap_irq max77693_topsys_irqs[] = {
77 { .mask = TOPSYS_IRQ_T120C_INT, },
78 { .mask = TOPSYS_IRQ_T140C_INT, },
79 { .mask = TOPSYS_IRQ_LOWSYS_INT, },
80};
81
82static const struct regmap_irq_chip max77693_topsys_irq_chip = {
83 .name = "max77693-topsys",
84 .status_base = MAX77693_PMIC_REG_TOPSYS_INT,
85 .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
86 .mask_invert = false,
87 .num_regs = 1,
88 .irqs = max77693_topsys_irqs,
89 .num_irqs = ARRAY_SIZE(max77693_topsys_irqs),
90};
91
92static const struct regmap_irq max77693_charger_irqs[] = {
93 { .mask = CHG_IRQ_BYP_I, },
94 { .mask = CHG_IRQ_THM_I, },
95 { .mask = CHG_IRQ_BAT_I, },
96 { .mask = CHG_IRQ_CHG_I, },
97 { .mask = CHG_IRQ_CHGIN_I, },
98};
99
100static const struct regmap_irq_chip max77693_charger_irq_chip = {
101 .name = "max77693-charger",
102 .status_base = MAX77693_CHG_REG_CHG_INT,
103 .mask_base = MAX77693_CHG_REG_CHG_INT_MASK,
104 .mask_invert = false,
105 .num_regs = 1,
106 .irqs = max77693_charger_irqs,
107 .num_irqs = ARRAY_SIZE(max77693_charger_irqs),
108};
109
58static const struct regmap_config max77693_regmap_muic_config = { 110static const struct regmap_config max77693_regmap_muic_config = {
59 .reg_bits = 8, 111 .reg_bits = 8,
60 .val_bits = 8, 112 .val_bits = 8,
61 .max_register = MAX77693_MUIC_REG_END, 113 .max_register = MAX77693_MUIC_REG_END,
62}; 114};
63 115
116static const struct regmap_irq max77693_muic_irqs[] = {
117 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, },
118 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, },
119 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, },
120 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, },
121
122 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, },
123 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, },
124 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, },
125 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, },
126 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, },
127 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, },
128
129 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, },
130 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, },
131 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, },
132 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, },
133 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, },
134 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, },
135};
136
137static const struct regmap_irq_chip max77693_muic_irq_chip = {
138 .name = "max77693-muic",
139 .status_base = MAX77693_MUIC_REG_INT1,
140 .mask_base = MAX77693_MUIC_REG_INTMASK1,
141 .mask_invert = true,
142 .num_regs = 3,
143 .irqs = max77693_muic_irqs,
144 .num_irqs = ARRAY_SIZE(max77693_muic_irqs),
145};
146
64static int max77693_i2c_probe(struct i2c_client *i2c, 147static int max77693_i2c_probe(struct i2c_client *i2c,
65 const struct i2c_device_id *id) 148 const struct i2c_device_id *id)
66{ 149{
@@ -124,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
124 goto err_regmap_muic; 207 goto err_regmap_muic;
125 } 208 }
126 209
127 ret = max77693_irq_init(max77693); 210 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
128 if (ret < 0) 211 IRQF_ONESHOT | IRQF_SHARED |
129 goto err_irq; 212 IRQF_TRIGGER_FALLING, 0,
213 &max77693_led_irq_chip,
214 &max77693->irq_data_led);
215 if (ret) {
216 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
217 goto err_regmap_muic;
218 }
219
220 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
221 IRQF_ONESHOT | IRQF_SHARED |
222 IRQF_TRIGGER_FALLING, 0,
223 &max77693_topsys_irq_chip,
224 &max77693->irq_data_topsys);
225 if (ret) {
226 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
227 goto err_irq_topsys;
228 }
229
230 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
231 IRQF_ONESHOT | IRQF_SHARED |
232 IRQF_TRIGGER_FALLING, 0,
233 &max77693_charger_irq_chip,
234 &max77693->irq_data_charger);
235 if (ret) {
236 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
237 goto err_irq_charger;
238 }
239
240 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
241 IRQF_ONESHOT | IRQF_SHARED |
242 IRQF_TRIGGER_FALLING, 0,
243 &max77693_muic_irq_chip,
244 &max77693->irq_data_muic);
245 if (ret) {
246 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
247 goto err_irq_muic;
248 }
130 249
131 pm_runtime_set_active(max77693->dev); 250 pm_runtime_set_active(max77693->dev);
132 251
@@ -138,8 +257,14 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
138 return ret; 257 return ret;
139 258
140err_mfd: 259err_mfd:
141 max77693_irq_exit(max77693); 260 mfd_remove_devices(max77693->dev);
142err_irq: 261 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
262err_irq_muic:
263 regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
264err_irq_charger:
265 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
266err_irq_topsys:
267 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
143err_regmap_muic: 268err_regmap_muic:
144 i2c_unregister_device(max77693->haptic); 269 i2c_unregister_device(max77693->haptic);
145err_i2c_haptic: 270err_i2c_haptic:
@@ -152,7 +277,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c)
152 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 277 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
153 278
154 mfd_remove_devices(max77693->dev); 279 mfd_remove_devices(max77693->dev);
155 max77693_irq_exit(max77693); 280
281 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
282 regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
283 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
284 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
285
156 i2c_unregister_device(max77693->muic); 286 i2c_unregister_device(max77693->muic);
157 i2c_unregister_device(max77693->haptic); 287 i2c_unregister_device(max77693->haptic);
158 288
@@ -170,8 +300,11 @@ static int max77693_suspend(struct device *dev)
170 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 300 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
171 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 301 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
172 302
173 if (device_may_wakeup(dev)) 303 if (device_may_wakeup(dev)) {
174 irq_set_irq_wake(max77693->irq, 1); 304 enable_irq_wake(max77693->irq);
305 disable_irq(max77693->irq);
306 }
307
175 return 0; 308 return 0;
176} 309}
177 310
@@ -180,9 +313,12 @@ static int max77693_resume(struct device *dev)
180 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 313 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
181 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 314 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
182 315
183 if (device_may_wakeup(dev)) 316 if (device_may_wakeup(dev)) {
184 irq_set_irq_wake(max77693->irq, 0); 317 disable_irq_wake(max77693->irq);
185 return max77693_irq_resume(max77693); 318 enable_irq(max77693->irq);
319 }
320
321 return 0;
186} 322}
187 323
188static const struct dev_pm_ops max77693_pm = { 324static const struct dev_pm_ops max77693_pm = {
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 80ec31d561c4..c466ff3e16b8 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -262,6 +262,41 @@ enum max77693_irq_source {
262 MAX77693_IRQ_GROUP_NR, 262 MAX77693_IRQ_GROUP_NR,
263}; 263};
264 264
265#define LED_IRQ_FLED2_OPEN BIT(0)
266#define LED_IRQ_FLED2_SHORT BIT(1)
267#define LED_IRQ_FLED1_OPEN BIT(2)
268#define LED_IRQ_FLED1_SHORT BIT(3)
269#define LED_IRQ_MAX_FLASH BIT(4)
270
271#define TOPSYS_IRQ_T120C_INT BIT(0)
272#define TOPSYS_IRQ_T140C_INT BIT(1)
273#define TOPSYS_IRQ_LOWSYS_INT BIT(3)
274
275#define CHG_IRQ_BYP_I BIT(0)
276#define CHG_IRQ_THM_I BIT(2)
277#define CHG_IRQ_BAT_I BIT(3)
278#define CHG_IRQ_CHG_I BIT(4)
279#define CHG_IRQ_CHGIN_I BIT(6)
280
281#define MUIC_IRQ_INT1_ADC BIT(0)
282#define MUIC_IRQ_INT1_ADC_LOW BIT(1)
283#define MUIC_IRQ_INT1_ADC_ERR BIT(2)
284#define MUIC_IRQ_INT1_ADC1K BIT(3)
285
286#define MUIC_IRQ_INT2_CHGTYP BIT(0)
287#define MUIC_IRQ_INT2_CHGDETREUN BIT(1)
288#define MUIC_IRQ_INT2_DCDTMR BIT(2)
289#define MUIC_IRQ_INT2_DXOVP BIT(3)
290#define MUIC_IRQ_INT2_VBVOLT BIT(4)
291#define MUIC_IRQ_INT2_VIDRM BIT(5)
292
293#define MUIC_IRQ_INT3_EOC BIT(0)
294#define MUIC_IRQ_INT3_CGMBC BIT(1)
295#define MUIC_IRQ_INT3_OVP BIT(2)
296#define MUIC_IRQ_INT3_MBCCHG_ERR BIT(3)
297#define MUIC_IRQ_INT3_CHG_ENABLED BIT(4)
298#define MUIC_IRQ_INT3_BAT_DET BIT(5)
299
265enum max77693_irq { 300enum max77693_irq {
266 /* PMIC - FLASH */ 301 /* PMIC - FLASH */
267 MAX77693_LED_IRQ_FLED2_OPEN, 302 MAX77693_LED_IRQ_FLED2_OPEN,
@@ -282,6 +317,10 @@ enum max77693_irq {
282 MAX77693_CHG_IRQ_CHG_I, 317 MAX77693_CHG_IRQ_CHG_I,
283 MAX77693_CHG_IRQ_CHGIN_I, 318 MAX77693_CHG_IRQ_CHGIN_I,
284 319
320 MAX77693_IRQ_NR,
321};
322
323enum max77693_irq_muic {
285 /* MUIC INT1 */ 324 /* MUIC INT1 */
286 MAX77693_MUIC_IRQ_INT1_ADC, 325 MAX77693_MUIC_IRQ_INT1_ADC,
287 MAX77693_MUIC_IRQ_INT1_ADC_LOW, 326 MAX77693_MUIC_IRQ_INT1_ADC_LOW,
@@ -304,7 +343,7 @@ enum max77693_irq {
304 MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, 343 MAX77693_MUIC_IRQ_INT3_CHG_ENABLED,
305 MAX77693_MUIC_IRQ_INT3_BAT_DET, 344 MAX77693_MUIC_IRQ_INT3_BAT_DET,
306 345
307 MAX77693_IRQ_NR, 346 MAX77693_MUIC_IRQ_NR,
308}; 347};
309 348
310struct max77693_dev { 349struct max77693_dev {
@@ -319,7 +358,10 @@ struct max77693_dev {
319 struct regmap *regmap_muic; 358 struct regmap *regmap_muic;
320 struct regmap *regmap_haptic; 359 struct regmap *regmap_haptic;
321 360
322 struct irq_domain *irq_domain; 361 struct regmap_irq_chip_data *irq_data_led;
362 struct regmap_irq_chip_data *irq_data_topsys;
363 struct regmap_irq_chip_data *irq_data_charger;
364 struct regmap_irq_chip_data *irq_data_muic;
323 365
324 int irq; 366 int irq;
325 int irq_gpio; 367 int irq_gpio;