1*bb71e40dSAndré Draszik // SPDX-License-Identifier: GPL-2.0-only
2*bb71e40dSAndré Draszik /*
3*bb71e40dSAndré Draszik * Copyright 2020 Google Inc
4*bb71e40dSAndré Draszik * Copyright 2025 Linaro Ltd.
5*bb71e40dSAndré Draszik *
6*bb71e40dSAndré Draszik * Core driver for Maxim MAX77759 companion PMIC for USB Type-C
7*bb71e40dSAndré Draszik */
8*bb71e40dSAndré Draszik
9*bb71e40dSAndré Draszik #include <linux/array_size.h>
10*bb71e40dSAndré Draszik #include <linux/bitfield.h>
11*bb71e40dSAndré Draszik #include <linux/bits.h>
12*bb71e40dSAndré Draszik #include <linux/cleanup.h>
13*bb71e40dSAndré Draszik #include <linux/completion.h>
14*bb71e40dSAndré Draszik #include <linux/dev_printk.h>
15*bb71e40dSAndré Draszik #include <linux/device.h>
16*bb71e40dSAndré Draszik #include <linux/err.h>
17*bb71e40dSAndré Draszik #include <linux/i2c.h>
18*bb71e40dSAndré Draszik #include <linux/init.h>
19*bb71e40dSAndré Draszik #include <linux/interrupt.h>
20*bb71e40dSAndré Draszik #include <linux/irq.h>
21*bb71e40dSAndré Draszik #include <linux/jiffies.h>
22*bb71e40dSAndré Draszik #include <linux/mfd/core.h>
23*bb71e40dSAndré Draszik #include <linux/mfd/max77759.h>
24*bb71e40dSAndré Draszik #include <linux/mod_devicetable.h>
25*bb71e40dSAndré Draszik #include <linux/module.h>
26*bb71e40dSAndré Draszik #include <linux/mutex.h>
27*bb71e40dSAndré Draszik #include <linux/of.h>
28*bb71e40dSAndré Draszik #include <linux/overflow.h>
29*bb71e40dSAndré Draszik #include <linux/regmap.h>
30*bb71e40dSAndré Draszik
31*bb71e40dSAndré Draszik /* Chip ID as per MAX77759_PMIC_REG_PMIC_ID */
32*bb71e40dSAndré Draszik enum {
33*bb71e40dSAndré Draszik MAX77759_CHIP_ID = 59,
34*bb71e40dSAndré Draszik };
35*bb71e40dSAndré Draszik
36*bb71e40dSAndré Draszik enum max77759_i2c_subdev_id {
37*bb71e40dSAndré Draszik /*
38*bb71e40dSAndré Draszik * These are arbitrary and simply used to match struct
39*bb71e40dSAndré Draszik * max77759_i2c_subdev entries to the regmap pointers in struct
40*bb71e40dSAndré Draszik * max77759 during probe().
41*bb71e40dSAndré Draszik */
42*bb71e40dSAndré Draszik MAX77759_I2C_SUBDEV_ID_MAXQ,
43*bb71e40dSAndré Draszik MAX77759_I2C_SUBDEV_ID_CHARGER,
44*bb71e40dSAndré Draszik };
45*bb71e40dSAndré Draszik
46*bb71e40dSAndré Draszik struct max77759_i2c_subdev {
47*bb71e40dSAndré Draszik enum max77759_i2c_subdev_id id;
48*bb71e40dSAndré Draszik const struct regmap_config *cfg;
49*bb71e40dSAndré Draszik u16 i2c_address;
50*bb71e40dSAndré Draszik };
51*bb71e40dSAndré Draszik
52*bb71e40dSAndré Draszik static const struct regmap_range max77759_top_registers[] = {
53*bb71e40dSAndré Draszik regmap_reg_range(0x00, 0x02), /* PMIC_ID / PMIC_REVISION / OTP_REVISION */
54*bb71e40dSAndré Draszik regmap_reg_range(0x22, 0x24), /* INTSRC / INTSRCMASK / TOPSYS_INT */
55*bb71e40dSAndré Draszik regmap_reg_range(0x26, 0x26), /* TOPSYS_INT_MASK */
56*bb71e40dSAndré Draszik regmap_reg_range(0x40, 0x40), /* I2C_CNFG */
57*bb71e40dSAndré Draszik regmap_reg_range(0x50, 0x51), /* SWRESET / CONTROL_FG */
58*bb71e40dSAndré Draszik };
59*bb71e40dSAndré Draszik
60*bb71e40dSAndré Draszik static const struct regmap_range max77759_top_ro_registers[] = {
61*bb71e40dSAndré Draszik regmap_reg_range(0x00, 0x02),
62*bb71e40dSAndré Draszik regmap_reg_range(0x22, 0x22),
63*bb71e40dSAndré Draszik };
64*bb71e40dSAndré Draszik
65*bb71e40dSAndré Draszik static const struct regmap_range max77759_top_volatile_registers[] = {
66*bb71e40dSAndré Draszik regmap_reg_range(0x22, 0x22),
67*bb71e40dSAndré Draszik regmap_reg_range(0x24, 0x24),
68*bb71e40dSAndré Draszik };
69*bb71e40dSAndré Draszik
70*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_top_wr_table = {
71*bb71e40dSAndré Draszik .yes_ranges = max77759_top_registers,
72*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_top_registers),
73*bb71e40dSAndré Draszik .no_ranges = max77759_top_ro_registers,
74*bb71e40dSAndré Draszik .n_no_ranges = ARRAY_SIZE(max77759_top_ro_registers),
75*bb71e40dSAndré Draszik };
76*bb71e40dSAndré Draszik
77*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_top_rd_table = {
78*bb71e40dSAndré Draszik .yes_ranges = max77759_top_registers,
79*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_top_registers),
80*bb71e40dSAndré Draszik };
81*bb71e40dSAndré Draszik
82*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_top_volatile_table = {
83*bb71e40dSAndré Draszik .yes_ranges = max77759_top_volatile_registers,
84*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_top_volatile_registers),
85*bb71e40dSAndré Draszik };
86*bb71e40dSAndré Draszik
87*bb71e40dSAndré Draszik static const struct regmap_config max77759_regmap_config_top = {
88*bb71e40dSAndré Draszik .name = "top",
89*bb71e40dSAndré Draszik .reg_bits = 8,
90*bb71e40dSAndré Draszik .val_bits = 8,
91*bb71e40dSAndré Draszik .max_register = MAX77759_PMIC_REG_CONTROL_FG,
92*bb71e40dSAndré Draszik .wr_table = &max77759_top_wr_table,
93*bb71e40dSAndré Draszik .rd_table = &max77759_top_rd_table,
94*bb71e40dSAndré Draszik .volatile_table = &max77759_top_volatile_table,
95*bb71e40dSAndré Draszik .num_reg_defaults_raw = MAX77759_PMIC_REG_CONTROL_FG + 1,
96*bb71e40dSAndré Draszik .cache_type = REGCACHE_FLAT,
97*bb71e40dSAndré Draszik };
98*bb71e40dSAndré Draszik
99*bb71e40dSAndré Draszik static const struct regmap_range max77759_maxq_registers[] = {
100*bb71e40dSAndré Draszik regmap_reg_range(0x60, 0x73), /* Device ID, Rev, INTx, STATUSx, MASKx */
101*bb71e40dSAndré Draszik regmap_reg_range(0x81, 0xa1), /* AP_DATAOUTx */
102*bb71e40dSAndré Draszik regmap_reg_range(0xb1, 0xd1), /* AP_DATAINx */
103*bb71e40dSAndré Draszik regmap_reg_range(0xe0, 0xe0), /* UIC_SWRST */
104*bb71e40dSAndré Draszik };
105*bb71e40dSAndré Draszik
106*bb71e40dSAndré Draszik static const struct regmap_range max77759_maxq_ro_registers[] = {
107*bb71e40dSAndré Draszik regmap_reg_range(0x60, 0x63), /* Device ID, Rev */
108*bb71e40dSAndré Draszik regmap_reg_range(0x68, 0x6f), /* STATUSx */
109*bb71e40dSAndré Draszik regmap_reg_range(0xb1, 0xd1),
110*bb71e40dSAndré Draszik };
111*bb71e40dSAndré Draszik
112*bb71e40dSAndré Draszik static const struct regmap_range max77759_maxq_volatile_registers[] = {
113*bb71e40dSAndré Draszik regmap_reg_range(0x64, 0x6f), /* INTx, STATUSx */
114*bb71e40dSAndré Draszik regmap_reg_range(0xb1, 0xd1),
115*bb71e40dSAndré Draszik regmap_reg_range(0xe0, 0xe0),
116*bb71e40dSAndré Draszik };
117*bb71e40dSAndré Draszik
118*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_maxq_wr_table = {
119*bb71e40dSAndré Draszik .yes_ranges = max77759_maxq_registers,
120*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_maxq_registers),
121*bb71e40dSAndré Draszik .no_ranges = max77759_maxq_ro_registers,
122*bb71e40dSAndré Draszik .n_no_ranges = ARRAY_SIZE(max77759_maxq_ro_registers),
123*bb71e40dSAndré Draszik };
124*bb71e40dSAndré Draszik
125*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_maxq_rd_table = {
126*bb71e40dSAndré Draszik .yes_ranges = max77759_maxq_registers,
127*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_maxq_registers),
128*bb71e40dSAndré Draszik };
129*bb71e40dSAndré Draszik
130*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_maxq_volatile_table = {
131*bb71e40dSAndré Draszik .yes_ranges = max77759_maxq_volatile_registers,
132*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_maxq_volatile_registers),
133*bb71e40dSAndré Draszik };
134*bb71e40dSAndré Draszik
135*bb71e40dSAndré Draszik static const struct regmap_config max77759_regmap_config_maxq = {
136*bb71e40dSAndré Draszik .name = "maxq",
137*bb71e40dSAndré Draszik .reg_bits = 8,
138*bb71e40dSAndré Draszik .val_bits = 8,
139*bb71e40dSAndré Draszik .max_register = MAX77759_MAXQ_REG_UIC_SWRST,
140*bb71e40dSAndré Draszik .wr_table = &max77759_maxq_wr_table,
141*bb71e40dSAndré Draszik .rd_table = &max77759_maxq_rd_table,
142*bb71e40dSAndré Draszik .volatile_table = &max77759_maxq_volatile_table,
143*bb71e40dSAndré Draszik .num_reg_defaults_raw = MAX77759_MAXQ_REG_UIC_SWRST + 1,
144*bb71e40dSAndré Draszik .cache_type = REGCACHE_FLAT,
145*bb71e40dSAndré Draszik };
146*bb71e40dSAndré Draszik
147*bb71e40dSAndré Draszik static const struct regmap_range max77759_charger_registers[] = {
148*bb71e40dSAndré Draszik regmap_reg_range(0xb0, 0xcc),
149*bb71e40dSAndré Draszik };
150*bb71e40dSAndré Draszik
151*bb71e40dSAndré Draszik static const struct regmap_range max77759_charger_ro_registers[] = {
152*bb71e40dSAndré Draszik regmap_reg_range(0xb4, 0xb8), /* INT_OK, DETAILS_0x */
153*bb71e40dSAndré Draszik };
154*bb71e40dSAndré Draszik
155*bb71e40dSAndré Draszik static const struct regmap_range max77759_charger_volatile_registers[] = {
156*bb71e40dSAndré Draszik regmap_reg_range(0xb0, 0xb1), /* INTx */
157*bb71e40dSAndré Draszik regmap_reg_range(0xb4, 0xb8),
158*bb71e40dSAndré Draszik };
159*bb71e40dSAndré Draszik
160*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_charger_wr_table = {
161*bb71e40dSAndré Draszik .yes_ranges = max77759_charger_registers,
162*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_charger_registers),
163*bb71e40dSAndré Draszik .no_ranges = max77759_charger_ro_registers,
164*bb71e40dSAndré Draszik .n_no_ranges = ARRAY_SIZE(max77759_charger_ro_registers),
165*bb71e40dSAndré Draszik };
166*bb71e40dSAndré Draszik
167*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_charger_rd_table = {
168*bb71e40dSAndré Draszik .yes_ranges = max77759_charger_registers,
169*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_charger_registers),
170*bb71e40dSAndré Draszik };
171*bb71e40dSAndré Draszik
172*bb71e40dSAndré Draszik static const struct regmap_access_table max77759_charger_volatile_table = {
173*bb71e40dSAndré Draszik .yes_ranges = max77759_charger_volatile_registers,
174*bb71e40dSAndré Draszik .n_yes_ranges = ARRAY_SIZE(max77759_charger_volatile_registers),
175*bb71e40dSAndré Draszik };
176*bb71e40dSAndré Draszik
177*bb71e40dSAndré Draszik static const struct regmap_config max77759_regmap_config_charger = {
178*bb71e40dSAndré Draszik .name = "charger",
179*bb71e40dSAndré Draszik .reg_bits = 8,
180*bb71e40dSAndré Draszik .val_bits = 8,
181*bb71e40dSAndré Draszik .max_register = MAX77759_CHGR_REG_CHG_CNFG_19,
182*bb71e40dSAndré Draszik .wr_table = &max77759_charger_wr_table,
183*bb71e40dSAndré Draszik .rd_table = &max77759_charger_rd_table,
184*bb71e40dSAndré Draszik .volatile_table = &max77759_charger_volatile_table,
185*bb71e40dSAndré Draszik .num_reg_defaults_raw = MAX77759_CHGR_REG_CHG_CNFG_19 + 1,
186*bb71e40dSAndré Draszik .cache_type = REGCACHE_FLAT,
187*bb71e40dSAndré Draszik };
188*bb71e40dSAndré Draszik
189*bb71e40dSAndré Draszik /*
190*bb71e40dSAndré Draszik * Interrupts - with the following interrupt hierarchy:
191*bb71e40dSAndré Draszik * pmic IRQs (INTSRC)
192*bb71e40dSAndré Draszik * - MAXQ_INT: MaxQ IRQs
193*bb71e40dSAndré Draszik * - UIC_INT1
194*bb71e40dSAndré Draszik * - APCmdResI
195*bb71e40dSAndré Draszik * - SysMsgI
196*bb71e40dSAndré Draszik * - GPIOxI
197*bb71e40dSAndré Draszik * - TOPSYS_INT: topsys
198*bb71e40dSAndré Draszik * - TOPSYS_INT
199*bb71e40dSAndré Draszik * - TSHDN_INT
200*bb71e40dSAndré Draszik * - SYSOVLO_INT
201*bb71e40dSAndré Draszik * - SYSUVLO_INT
202*bb71e40dSAndré Draszik * - FSHIP_NOT_RD
203*bb71e40dSAndré Draszik * - CHGR_INT: charger
204*bb71e40dSAndré Draszik * - CHG_INT
205*bb71e40dSAndré Draszik * - CHG_INT2
206*bb71e40dSAndré Draszik */
207*bb71e40dSAndré Draszik enum {
208*bb71e40dSAndré Draszik MAX77759_INT_MAXQ,
209*bb71e40dSAndré Draszik MAX77759_INT_TOPSYS,
210*bb71e40dSAndré Draszik MAX77759_INT_CHGR,
211*bb71e40dSAndré Draszik };
212*bb71e40dSAndré Draszik
213*bb71e40dSAndré Draszik enum {
214*bb71e40dSAndré Draszik MAX77759_TOPSYS_INT_TSHDN,
215*bb71e40dSAndré Draszik MAX77759_TOPSYS_INT_SYSOVLO,
216*bb71e40dSAndré Draszik MAX77759_TOPSYS_INT_SYSUVLO,
217*bb71e40dSAndré Draszik MAX77759_TOPSYS_INT_FSHIP_NOT_RD,
218*bb71e40dSAndré Draszik };
219*bb71e40dSAndré Draszik
220*bb71e40dSAndré Draszik enum {
221*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_APCMDRESI,
222*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_SYSMSGI,
223*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_GPIO,
224*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_UIC1,
225*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_UIC2,
226*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_UIC3,
227*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_UIC4,
228*bb71e40dSAndré Draszik };
229*bb71e40dSAndré Draszik
230*bb71e40dSAndré Draszik enum {
231*bb71e40dSAndré Draszik MAX77759_CHARGER_INT_1,
232*bb71e40dSAndré Draszik MAX77759_CHARGER_INT_2,
233*bb71e40dSAndré Draszik };
234*bb71e40dSAndré Draszik
235*bb71e40dSAndré Draszik static const struct regmap_irq max77759_pmic_irqs[] = {
236*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_INT_MAXQ, 0, MAX77759_PMIC_REG_INTSRC_MAXQ),
237*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_INT_TOPSYS, 0, MAX77759_PMIC_REG_INTSRC_TOPSYS),
238*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_INT_CHGR, 0, MAX77759_PMIC_REG_INTSRC_CHGR),
239*bb71e40dSAndré Draszik };
240*bb71e40dSAndré Draszik
241*bb71e40dSAndré Draszik static const struct regmap_irq max77759_maxq_irqs[] = {
242*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_MAXQ_INT_APCMDRESI, 0, MAX77759_MAXQ_REG_UIC_INT1_APCMDRESI),
243*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_MAXQ_INT_SYSMSGI, 0, MAX77759_MAXQ_REG_UIC_INT1_SYSMSGI),
244*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_MAXQ_INT_GPIO, 0, GENMASK(1, 0)),
245*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC1, 0, GENMASK(5, 2)),
246*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC2, 1, GENMASK(7, 0)),
247*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC3, 2, GENMASK(7, 0)),
248*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC4, 3, GENMASK(7, 0)),
249*bb71e40dSAndré Draszik };
250*bb71e40dSAndré Draszik
251*bb71e40dSAndré Draszik static const struct regmap_irq max77759_topsys_irqs[] = {
252*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_TSHDN, 0, MAX77759_PMIC_REG_TOPSYS_INT_TSHDN),
253*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_SYSOVLO, 0, MAX77759_PMIC_REG_TOPSYS_INT_SYSOVLO),
254*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_SYSUVLO, 0, MAX77759_PMIC_REG_TOPSYS_INT_SYSUVLO),
255*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_FSHIP_NOT_RD, 0, MAX77759_PMIC_REG_TOPSYS_INT_FSHIP),
256*bb71e40dSAndré Draszik };
257*bb71e40dSAndré Draszik
258*bb71e40dSAndré Draszik static const struct regmap_irq max77759_chgr_irqs[] = {
259*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_CHARGER_INT_1, 0, GENMASK(7, 0)),
260*bb71e40dSAndré Draszik REGMAP_IRQ_REG(MAX77759_CHARGER_INT_2, 1, GENMASK(7, 0)),
261*bb71e40dSAndré Draszik };
262*bb71e40dSAndré Draszik
263*bb71e40dSAndré Draszik static const struct regmap_irq_chip max77759_pmic_irq_chip = {
264*bb71e40dSAndré Draszik .name = "max77759-pmic",
265*bb71e40dSAndré Draszik /* INTSRC is read-only and doesn't require clearing */
266*bb71e40dSAndré Draszik .status_base = MAX77759_PMIC_REG_INTSRC,
267*bb71e40dSAndré Draszik .mask_base = MAX77759_PMIC_REG_INTSRCMASK,
268*bb71e40dSAndré Draszik .num_regs = 1,
269*bb71e40dSAndré Draszik .irqs = max77759_pmic_irqs,
270*bb71e40dSAndré Draszik .num_irqs = ARRAY_SIZE(max77759_pmic_irqs),
271*bb71e40dSAndré Draszik };
272*bb71e40dSAndré Draszik
273*bb71e40dSAndré Draszik /*
274*bb71e40dSAndré Draszik * We can let regmap-irq auto-ack the topsys interrupt bits as required, but
275*bb71e40dSAndré Draszik * for all others the individual drivers need to know which interrupt bit
276*bb71e40dSAndré Draszik * exactly is set inside their interrupt handlers, and therefore we can not set
277*bb71e40dSAndré Draszik * .ack_base for those.
278*bb71e40dSAndré Draszik */
279*bb71e40dSAndré Draszik static const struct regmap_irq_chip max77759_maxq_irq_chip = {
280*bb71e40dSAndré Draszik .name = "max77759-maxq",
281*bb71e40dSAndré Draszik .domain_suffix = "MAXQ",
282*bb71e40dSAndré Draszik .status_base = MAX77759_MAXQ_REG_UIC_INT1,
283*bb71e40dSAndré Draszik .mask_base = MAX77759_MAXQ_REG_UIC_INT1_M,
284*bb71e40dSAndré Draszik .num_regs = 4,
285*bb71e40dSAndré Draszik .irqs = max77759_maxq_irqs,
286*bb71e40dSAndré Draszik .num_irqs = ARRAY_SIZE(max77759_maxq_irqs),
287*bb71e40dSAndré Draszik };
288*bb71e40dSAndré Draszik
289*bb71e40dSAndré Draszik static const struct regmap_irq_chip max77759_topsys_irq_chip = {
290*bb71e40dSAndré Draszik .name = "max77759-topsys",
291*bb71e40dSAndré Draszik .domain_suffix = "TOPSYS",
292*bb71e40dSAndré Draszik .status_base = MAX77759_PMIC_REG_TOPSYS_INT,
293*bb71e40dSAndré Draszik .mask_base = MAX77759_PMIC_REG_TOPSYS_INT_MASK,
294*bb71e40dSAndré Draszik .ack_base = MAX77759_PMIC_REG_TOPSYS_INT,
295*bb71e40dSAndré Draszik .num_regs = 1,
296*bb71e40dSAndré Draszik .irqs = max77759_topsys_irqs,
297*bb71e40dSAndré Draszik .num_irqs = ARRAY_SIZE(max77759_topsys_irqs),
298*bb71e40dSAndré Draszik };
299*bb71e40dSAndré Draszik
300*bb71e40dSAndré Draszik static const struct regmap_irq_chip max77759_chrg_irq_chip = {
301*bb71e40dSAndré Draszik .name = "max77759-chgr",
302*bb71e40dSAndré Draszik .domain_suffix = "CHGR",
303*bb71e40dSAndré Draszik .status_base = MAX77759_CHGR_REG_CHG_INT,
304*bb71e40dSAndré Draszik .mask_base = MAX77759_CHGR_REG_CHG_INT_MASK,
305*bb71e40dSAndré Draszik .num_regs = 2,
306*bb71e40dSAndré Draszik .irqs = max77759_chgr_irqs,
307*bb71e40dSAndré Draszik .num_irqs = ARRAY_SIZE(max77759_chgr_irqs),
308*bb71e40dSAndré Draszik };
309*bb71e40dSAndré Draszik
310*bb71e40dSAndré Draszik static const struct max77759_i2c_subdev max77759_i2c_subdevs[] = {
311*bb71e40dSAndré Draszik {
312*bb71e40dSAndré Draszik .id = MAX77759_I2C_SUBDEV_ID_MAXQ,
313*bb71e40dSAndré Draszik .cfg = &max77759_regmap_config_maxq,
314*bb71e40dSAndré Draszik /* I2C address is same as for sub-block 'top' */
315*bb71e40dSAndré Draszik },
316*bb71e40dSAndré Draszik {
317*bb71e40dSAndré Draszik .id = MAX77759_I2C_SUBDEV_ID_CHARGER,
318*bb71e40dSAndré Draszik .cfg = &max77759_regmap_config_charger,
319*bb71e40dSAndré Draszik .i2c_address = 0x69,
320*bb71e40dSAndré Draszik },
321*bb71e40dSAndré Draszik };
322*bb71e40dSAndré Draszik
323*bb71e40dSAndré Draszik static const struct resource max77759_gpio_resources[] = {
324*bb71e40dSAndré Draszik DEFINE_RES_IRQ_NAMED(MAX77759_MAXQ_INT_GPIO, "GPI"),
325*bb71e40dSAndré Draszik };
326*bb71e40dSAndré Draszik
327*bb71e40dSAndré Draszik static const struct resource max77759_charger_resources[] = {
328*bb71e40dSAndré Draszik DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_1, "INT1"),
329*bb71e40dSAndré Draszik DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_2, "INT2"),
330*bb71e40dSAndré Draszik };
331*bb71e40dSAndré Draszik
332*bb71e40dSAndré Draszik static const struct mfd_cell max77759_cells[] = {
333*bb71e40dSAndré Draszik MFD_CELL_OF("max77759-nvmem", NULL, NULL, 0, 0,
334*bb71e40dSAndré Draszik "maxim,max77759-nvmem"),
335*bb71e40dSAndré Draszik };
336*bb71e40dSAndré Draszik
337*bb71e40dSAndré Draszik static const struct mfd_cell max77759_maxq_cells[] = {
338*bb71e40dSAndré Draszik MFD_CELL_OF("max77759-gpio", max77759_gpio_resources, NULL, 0, 0,
339*bb71e40dSAndré Draszik "maxim,max77759-gpio"),
340*bb71e40dSAndré Draszik };
341*bb71e40dSAndré Draszik
342*bb71e40dSAndré Draszik static const struct mfd_cell max77759_charger_cells[] = {
343*bb71e40dSAndré Draszik MFD_CELL_RES("max77759-charger", max77759_charger_resources),
344*bb71e40dSAndré Draszik };
345*bb71e40dSAndré Draszik
max77759_maxq_command(struct max77759 * max77759,const struct max77759_maxq_command * cmd,struct max77759_maxq_response * rsp)346*bb71e40dSAndré Draszik int max77759_maxq_command(struct max77759 *max77759,
347*bb71e40dSAndré Draszik const struct max77759_maxq_command *cmd,
348*bb71e40dSAndré Draszik struct max77759_maxq_response *rsp)
349*bb71e40dSAndré Draszik {
350*bb71e40dSAndré Draszik DEFINE_FLEX(struct max77759_maxq_response, _rsp, rsp, length, 1);
351*bb71e40dSAndré Draszik struct device *dev = regmap_get_device(max77759->regmap_maxq);
352*bb71e40dSAndré Draszik static const unsigned int timeout_ms = 200;
353*bb71e40dSAndré Draszik int ret;
354*bb71e40dSAndré Draszik
355*bb71e40dSAndré Draszik if (cmd->length > MAX77759_MAXQ_OPCODE_MAXLENGTH)
356*bb71e40dSAndré Draszik return -EINVAL;
357*bb71e40dSAndré Draszik
358*bb71e40dSAndré Draszik /*
359*bb71e40dSAndré Draszik * As a convenience for API users when issuing simple commands, rsp is
360*bb71e40dSAndré Draszik * allowed to be NULL. In that case we need a temporary here to write
361*bb71e40dSAndré Draszik * the response to, as we need to verify that the command was indeed
362*bb71e40dSAndré Draszik * completed correctly.
363*bb71e40dSAndré Draszik */
364*bb71e40dSAndré Draszik if (!rsp)
365*bb71e40dSAndré Draszik rsp = _rsp;
366*bb71e40dSAndré Draszik
367*bb71e40dSAndré Draszik if (!rsp->length || rsp->length > MAX77759_MAXQ_OPCODE_MAXLENGTH)
368*bb71e40dSAndré Draszik return -EINVAL;
369*bb71e40dSAndré Draszik
370*bb71e40dSAndré Draszik guard(mutex)(&max77759->maxq_lock);
371*bb71e40dSAndré Draszik
372*bb71e40dSAndré Draszik reinit_completion(&max77759->cmd_done);
373*bb71e40dSAndré Draszik
374*bb71e40dSAndré Draszik /*
375*bb71e40dSAndré Draszik * MaxQ latches the message when the DATAOUT32 register is written. If
376*bb71e40dSAndré Draszik * cmd->length is shorter we still need to write 0 to it.
377*bb71e40dSAndré Draszik */
378*bb71e40dSAndré Draszik ret = regmap_bulk_write(max77759->regmap_maxq,
379*bb71e40dSAndré Draszik MAX77759_MAXQ_REG_AP_DATAOUT0, cmd->cmd,
380*bb71e40dSAndré Draszik cmd->length);
381*bb71e40dSAndré Draszik if (!ret && cmd->length < MAX77759_MAXQ_OPCODE_MAXLENGTH)
382*bb71e40dSAndré Draszik ret = regmap_write(max77759->regmap_maxq,
383*bb71e40dSAndré Draszik MAX77759_MAXQ_REG_AP_DATAOUT32, 0);
384*bb71e40dSAndré Draszik if (ret) {
385*bb71e40dSAndré Draszik dev_err(dev, "writing command failed: %d\n", ret);
386*bb71e40dSAndré Draszik return ret;
387*bb71e40dSAndré Draszik }
388*bb71e40dSAndré Draszik
389*bb71e40dSAndré Draszik /* Wait for response from MaxQ */
390*bb71e40dSAndré Draszik if (!wait_for_completion_timeout(&max77759->cmd_done,
391*bb71e40dSAndré Draszik msecs_to_jiffies(timeout_ms))) {
392*bb71e40dSAndré Draszik dev_err(dev, "timed out waiting for response\n");
393*bb71e40dSAndré Draszik return -ETIMEDOUT;
394*bb71e40dSAndré Draszik }
395*bb71e40dSAndré Draszik
396*bb71e40dSAndré Draszik ret = regmap_bulk_read(max77759->regmap_maxq,
397*bb71e40dSAndré Draszik MAX77759_MAXQ_REG_AP_DATAIN0,
398*bb71e40dSAndré Draszik rsp->rsp, rsp->length);
399*bb71e40dSAndré Draszik if (ret) {
400*bb71e40dSAndré Draszik dev_err(dev, "reading response failed: %d\n", ret);
401*bb71e40dSAndré Draszik return ret;
402*bb71e40dSAndré Draszik }
403*bb71e40dSAndré Draszik
404*bb71e40dSAndré Draszik /*
405*bb71e40dSAndré Draszik * As per the protocol, the first byte of the reply will match the
406*bb71e40dSAndré Draszik * request.
407*bb71e40dSAndré Draszik */
408*bb71e40dSAndré Draszik if (cmd->cmd[0] != rsp->rsp[0]) {
409*bb71e40dSAndré Draszik dev_err(dev, "unexpected opcode response for %#.2x: %*ph\n",
410*bb71e40dSAndré Draszik cmd->cmd[0], (int)rsp->length, rsp->rsp);
411*bb71e40dSAndré Draszik return -EIO;
412*bb71e40dSAndré Draszik }
413*bb71e40dSAndré Draszik
414*bb71e40dSAndré Draszik return 0;
415*bb71e40dSAndré Draszik }
416*bb71e40dSAndré Draszik EXPORT_SYMBOL_GPL(max77759_maxq_command);
417*bb71e40dSAndré Draszik
apcmdres_irq_handler(int irq,void * irq_data)418*bb71e40dSAndré Draszik static irqreturn_t apcmdres_irq_handler(int irq, void *irq_data)
419*bb71e40dSAndré Draszik {
420*bb71e40dSAndré Draszik struct max77759 *max77759 = irq_data;
421*bb71e40dSAndré Draszik
422*bb71e40dSAndré Draszik regmap_write(max77759->regmap_maxq, MAX77759_MAXQ_REG_UIC_INT1,
423*bb71e40dSAndré Draszik MAX77759_MAXQ_REG_UIC_INT1_APCMDRESI);
424*bb71e40dSAndré Draszik
425*bb71e40dSAndré Draszik complete(&max77759->cmd_done);
426*bb71e40dSAndré Draszik
427*bb71e40dSAndré Draszik return IRQ_HANDLED;
428*bb71e40dSAndré Draszik }
429*bb71e40dSAndré Draszik
max77759_create_i2c_subdev(struct i2c_client * client,struct max77759 * max77759,const struct max77759_i2c_subdev * sd)430*bb71e40dSAndré Draszik static int max77759_create_i2c_subdev(struct i2c_client *client,
431*bb71e40dSAndré Draszik struct max77759 *max77759,
432*bb71e40dSAndré Draszik const struct max77759_i2c_subdev *sd)
433*bb71e40dSAndré Draszik {
434*bb71e40dSAndré Draszik struct i2c_client *sub;
435*bb71e40dSAndré Draszik struct regmap *regmap;
436*bb71e40dSAndré Draszik int ret;
437*bb71e40dSAndré Draszik
438*bb71e40dSAndré Draszik /*
439*bb71e40dSAndré Draszik * If 'sd' has an I2C address, 'sub' will be assigned a new 'dummy'
440*bb71e40dSAndré Draszik * device, otherwise use it as-is.
441*bb71e40dSAndré Draszik */
442*bb71e40dSAndré Draszik sub = client;
443*bb71e40dSAndré Draszik if (sd->i2c_address) {
444*bb71e40dSAndré Draszik sub = devm_i2c_new_dummy_device(&client->dev,
445*bb71e40dSAndré Draszik client->adapter,
446*bb71e40dSAndré Draszik sd->i2c_address);
447*bb71e40dSAndré Draszik
448*bb71e40dSAndré Draszik if (IS_ERR(sub))
449*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, PTR_ERR(sub),
450*bb71e40dSAndré Draszik "failed to claim I2C device %s\n",
451*bb71e40dSAndré Draszik sd->cfg->name);
452*bb71e40dSAndré Draszik }
453*bb71e40dSAndré Draszik
454*bb71e40dSAndré Draszik regmap = devm_regmap_init_i2c(sub, sd->cfg);
455*bb71e40dSAndré Draszik if (IS_ERR(regmap))
456*bb71e40dSAndré Draszik return dev_err_probe(&sub->dev, PTR_ERR(regmap),
457*bb71e40dSAndré Draszik "regmap init for '%s' failed\n",
458*bb71e40dSAndré Draszik sd->cfg->name);
459*bb71e40dSAndré Draszik
460*bb71e40dSAndré Draszik ret = regmap_attach_dev(&client->dev, regmap, sd->cfg);
461*bb71e40dSAndré Draszik if (ret)
462*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, ret,
463*bb71e40dSAndré Draszik "regmap attach of '%s' failed\n",
464*bb71e40dSAndré Draszik sd->cfg->name);
465*bb71e40dSAndré Draszik
466*bb71e40dSAndré Draszik if (sd->id == MAX77759_I2C_SUBDEV_ID_MAXQ)
467*bb71e40dSAndré Draszik max77759->regmap_maxq = regmap;
468*bb71e40dSAndré Draszik else if (sd->id == MAX77759_I2C_SUBDEV_ID_CHARGER)
469*bb71e40dSAndré Draszik max77759->regmap_charger = regmap;
470*bb71e40dSAndré Draszik
471*bb71e40dSAndré Draszik return 0;
472*bb71e40dSAndré Draszik }
473*bb71e40dSAndré Draszik
max77759_add_chained_irq_chip(struct device * dev,struct regmap * regmap,int pirq,struct regmap_irq_chip_data * parent,const struct regmap_irq_chip * chip,struct regmap_irq_chip_data ** data)474*bb71e40dSAndré Draszik static int max77759_add_chained_irq_chip(struct device *dev,
475*bb71e40dSAndré Draszik struct regmap *regmap,
476*bb71e40dSAndré Draszik int pirq,
477*bb71e40dSAndré Draszik struct regmap_irq_chip_data *parent,
478*bb71e40dSAndré Draszik const struct regmap_irq_chip *chip,
479*bb71e40dSAndré Draszik struct regmap_irq_chip_data **data)
480*bb71e40dSAndré Draszik {
481*bb71e40dSAndré Draszik int irq, ret;
482*bb71e40dSAndré Draszik
483*bb71e40dSAndré Draszik irq = regmap_irq_get_virq(parent, pirq);
484*bb71e40dSAndré Draszik if (irq < 0)
485*bb71e40dSAndré Draszik return dev_err_probe(dev, irq,
486*bb71e40dSAndré Draszik "failed to get parent vIRQ(%d) for chip %s\n",
487*bb71e40dSAndré Draszik pirq, chip->name);
488*bb71e40dSAndré Draszik
489*bb71e40dSAndré Draszik ret = devm_regmap_add_irq_chip(dev, regmap, irq,
490*bb71e40dSAndré Draszik IRQF_ONESHOT | IRQF_SHARED, 0, chip,
491*bb71e40dSAndré Draszik data);
492*bb71e40dSAndré Draszik if (ret)
493*bb71e40dSAndré Draszik return dev_err_probe(dev, ret, "failed to add %s IRQ chip\n",
494*bb71e40dSAndré Draszik chip->name);
495*bb71e40dSAndré Draszik
496*bb71e40dSAndré Draszik return 0;
497*bb71e40dSAndré Draszik }
498*bb71e40dSAndré Draszik
max77759_add_chained_maxq(struct i2c_client * client,struct max77759 * max77759,struct regmap_irq_chip_data * parent)499*bb71e40dSAndré Draszik static int max77759_add_chained_maxq(struct i2c_client *client,
500*bb71e40dSAndré Draszik struct max77759 *max77759,
501*bb71e40dSAndré Draszik struct regmap_irq_chip_data *parent)
502*bb71e40dSAndré Draszik {
503*bb71e40dSAndré Draszik struct regmap_irq_chip_data *irq_chip_data;
504*bb71e40dSAndré Draszik int apcmdres_irq;
505*bb71e40dSAndré Draszik int ret;
506*bb71e40dSAndré Draszik
507*bb71e40dSAndré Draszik ret = max77759_add_chained_irq_chip(&client->dev,
508*bb71e40dSAndré Draszik max77759->regmap_maxq,
509*bb71e40dSAndré Draszik MAX77759_INT_MAXQ,
510*bb71e40dSAndré Draszik parent,
511*bb71e40dSAndré Draszik &max77759_maxq_irq_chip,
512*bb71e40dSAndré Draszik &irq_chip_data);
513*bb71e40dSAndré Draszik if (ret)
514*bb71e40dSAndré Draszik return ret;
515*bb71e40dSAndré Draszik
516*bb71e40dSAndré Draszik init_completion(&max77759->cmd_done);
517*bb71e40dSAndré Draszik apcmdres_irq = regmap_irq_get_virq(irq_chip_data,
518*bb71e40dSAndré Draszik MAX77759_MAXQ_INT_APCMDRESI);
519*bb71e40dSAndré Draszik
520*bb71e40dSAndré Draszik ret = devm_request_threaded_irq(&client->dev, apcmdres_irq,
521*bb71e40dSAndré Draszik NULL, apcmdres_irq_handler,
522*bb71e40dSAndré Draszik IRQF_ONESHOT | IRQF_SHARED,
523*bb71e40dSAndré Draszik dev_name(&client->dev), max77759);
524*bb71e40dSAndré Draszik if (ret)
525*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, ret,
526*bb71e40dSAndré Draszik "MAX77759_MAXQ_INT_APCMDRESI failed\n");
527*bb71e40dSAndré Draszik
528*bb71e40dSAndré Draszik ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO,
529*bb71e40dSAndré Draszik max77759_maxq_cells,
530*bb71e40dSAndré Draszik ARRAY_SIZE(max77759_maxq_cells),
531*bb71e40dSAndré Draszik NULL, 0,
532*bb71e40dSAndré Draszik regmap_irq_get_domain(irq_chip_data));
533*bb71e40dSAndré Draszik if (ret)
534*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, ret,
535*bb71e40dSAndré Draszik "failed to add child devices (MaxQ)\n");
536*bb71e40dSAndré Draszik
537*bb71e40dSAndré Draszik return 0;
538*bb71e40dSAndré Draszik }
539*bb71e40dSAndré Draszik
max77759_add_chained_topsys(struct i2c_client * client,struct max77759 * max77759,struct regmap_irq_chip_data * parent)540*bb71e40dSAndré Draszik static int max77759_add_chained_topsys(struct i2c_client *client,
541*bb71e40dSAndré Draszik struct max77759 *max77759,
542*bb71e40dSAndré Draszik struct regmap_irq_chip_data *parent)
543*bb71e40dSAndré Draszik {
544*bb71e40dSAndré Draszik struct regmap_irq_chip_data *irq_chip_data;
545*bb71e40dSAndré Draszik int ret;
546*bb71e40dSAndré Draszik
547*bb71e40dSAndré Draszik ret = max77759_add_chained_irq_chip(&client->dev,
548*bb71e40dSAndré Draszik max77759->regmap_top,
549*bb71e40dSAndré Draszik MAX77759_INT_TOPSYS,
550*bb71e40dSAndré Draszik parent,
551*bb71e40dSAndré Draszik &max77759_topsys_irq_chip,
552*bb71e40dSAndré Draszik &irq_chip_data);
553*bb71e40dSAndré Draszik if (ret)
554*bb71e40dSAndré Draszik return ret;
555*bb71e40dSAndré Draszik
556*bb71e40dSAndré Draszik return 0;
557*bb71e40dSAndré Draszik }
558*bb71e40dSAndré Draszik
max77759_add_chained_charger(struct i2c_client * client,struct max77759 * max77759,struct regmap_irq_chip_data * parent)559*bb71e40dSAndré Draszik static int max77759_add_chained_charger(struct i2c_client *client,
560*bb71e40dSAndré Draszik struct max77759 *max77759,
561*bb71e40dSAndré Draszik struct regmap_irq_chip_data *parent)
562*bb71e40dSAndré Draszik {
563*bb71e40dSAndré Draszik struct regmap_irq_chip_data *irq_chip_data;
564*bb71e40dSAndré Draszik int ret;
565*bb71e40dSAndré Draszik
566*bb71e40dSAndré Draszik ret = max77759_add_chained_irq_chip(&client->dev,
567*bb71e40dSAndré Draszik max77759->regmap_charger,
568*bb71e40dSAndré Draszik MAX77759_INT_CHGR,
569*bb71e40dSAndré Draszik parent,
570*bb71e40dSAndré Draszik &max77759_chrg_irq_chip,
571*bb71e40dSAndré Draszik &irq_chip_data);
572*bb71e40dSAndré Draszik if (ret)
573*bb71e40dSAndré Draszik return ret;
574*bb71e40dSAndré Draszik
575*bb71e40dSAndré Draszik ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO,
576*bb71e40dSAndré Draszik max77759_charger_cells,
577*bb71e40dSAndré Draszik ARRAY_SIZE(max77759_charger_cells),
578*bb71e40dSAndré Draszik NULL, 0,
579*bb71e40dSAndré Draszik regmap_irq_get_domain(irq_chip_data));
580*bb71e40dSAndré Draszik if (ret)
581*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, ret,
582*bb71e40dSAndré Draszik "failed to add child devices (charger)\n");
583*bb71e40dSAndré Draszik
584*bb71e40dSAndré Draszik return 0;
585*bb71e40dSAndré Draszik }
586*bb71e40dSAndré Draszik
max77759_probe(struct i2c_client * client)587*bb71e40dSAndré Draszik static int max77759_probe(struct i2c_client *client)
588*bb71e40dSAndré Draszik {
589*bb71e40dSAndré Draszik struct regmap_irq_chip_data *irq_chip_data_pmic;
590*bb71e40dSAndré Draszik struct irq_data *irq_data;
591*bb71e40dSAndré Draszik struct max77759 *max77759;
592*bb71e40dSAndré Draszik unsigned long irq_flags;
593*bb71e40dSAndré Draszik unsigned int pmic_id;
594*bb71e40dSAndré Draszik int ret;
595*bb71e40dSAndré Draszik
596*bb71e40dSAndré Draszik max77759 = devm_kzalloc(&client->dev, sizeof(*max77759), GFP_KERNEL);
597*bb71e40dSAndré Draszik if (!max77759)
598*bb71e40dSAndré Draszik return -ENOMEM;
599*bb71e40dSAndré Draszik
600*bb71e40dSAndré Draszik i2c_set_clientdata(client, max77759);
601*bb71e40dSAndré Draszik
602*bb71e40dSAndré Draszik max77759->regmap_top = devm_regmap_init_i2c(client,
603*bb71e40dSAndré Draszik &max77759_regmap_config_top);
604*bb71e40dSAndré Draszik if (IS_ERR(max77759->regmap_top))
605*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, PTR_ERR(max77759->regmap_top),
606*bb71e40dSAndré Draszik "regmap init for '%s' failed\n",
607*bb71e40dSAndré Draszik max77759_regmap_config_top.name);
608*bb71e40dSAndré Draszik
609*bb71e40dSAndré Draszik ret = regmap_read(max77759->regmap_top,
610*bb71e40dSAndré Draszik MAX77759_PMIC_REG_PMIC_ID, &pmic_id);
611*bb71e40dSAndré Draszik if (ret)
612*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, ret,
613*bb71e40dSAndré Draszik "unable to read device ID\n");
614*bb71e40dSAndré Draszik
615*bb71e40dSAndré Draszik if (pmic_id != MAX77759_CHIP_ID)
616*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, -ENODEV,
617*bb71e40dSAndré Draszik "unsupported device ID %#.2x (%d)\n",
618*bb71e40dSAndré Draszik pmic_id, pmic_id);
619*bb71e40dSAndré Draszik
620*bb71e40dSAndré Draszik ret = devm_mutex_init(&client->dev, &max77759->maxq_lock);
621*bb71e40dSAndré Draszik if (ret)
622*bb71e40dSAndré Draszik return ret;
623*bb71e40dSAndré Draszik
624*bb71e40dSAndré Draszik for (int i = 0; i < ARRAY_SIZE(max77759_i2c_subdevs); i++) {
625*bb71e40dSAndré Draszik ret = max77759_create_i2c_subdev(client, max77759,
626*bb71e40dSAndré Draszik &max77759_i2c_subdevs[i]);
627*bb71e40dSAndré Draszik if (ret)
628*bb71e40dSAndré Draszik return ret;
629*bb71e40dSAndré Draszik }
630*bb71e40dSAndré Draszik
631*bb71e40dSAndré Draszik irq_data = irq_get_irq_data(client->irq);
632*bb71e40dSAndré Draszik if (!irq_data)
633*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, -EINVAL,
634*bb71e40dSAndré Draszik "invalid IRQ: %d\n", client->irq);
635*bb71e40dSAndré Draszik
636*bb71e40dSAndré Draszik irq_flags = IRQF_ONESHOT | IRQF_SHARED;
637*bb71e40dSAndré Draszik irq_flags |= irqd_get_trigger_type(irq_data);
638*bb71e40dSAndré Draszik
639*bb71e40dSAndré Draszik ret = devm_regmap_add_irq_chip(&client->dev, max77759->regmap_top,
640*bb71e40dSAndré Draszik client->irq, irq_flags, 0,
641*bb71e40dSAndré Draszik &max77759_pmic_irq_chip,
642*bb71e40dSAndré Draszik &irq_chip_data_pmic);
643*bb71e40dSAndré Draszik if (ret)
644*bb71e40dSAndré Draszik return dev_err_probe(&client->dev, ret,
645*bb71e40dSAndré Draszik "failed to add IRQ chip '%s'\n",
646*bb71e40dSAndré Draszik max77759_pmic_irq_chip.name);
647*bb71e40dSAndré Draszik
648*bb71e40dSAndré Draszik ret = max77759_add_chained_maxq(client, max77759, irq_chip_data_pmic);
649*bb71e40dSAndré Draszik if (ret)
650*bb71e40dSAndré Draszik return ret;
651*bb71e40dSAndré Draszik
652*bb71e40dSAndré Draszik ret = max77759_add_chained_topsys(client, max77759, irq_chip_data_pmic);
653*bb71e40dSAndré Draszik if (ret)
654*bb71e40dSAndré Draszik return ret;
655*bb71e40dSAndré Draszik
656*bb71e40dSAndré Draszik ret = max77759_add_chained_charger(client, max77759, irq_chip_data_pmic);
657*bb71e40dSAndré Draszik if (ret)
658*bb71e40dSAndré Draszik return ret;
659*bb71e40dSAndré Draszik
660*bb71e40dSAndré Draszik return devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO,
661*bb71e40dSAndré Draszik max77759_cells, ARRAY_SIZE(max77759_cells),
662*bb71e40dSAndré Draszik NULL, 0,
663*bb71e40dSAndré Draszik regmap_irq_get_domain(irq_chip_data_pmic));
664*bb71e40dSAndré Draszik }
665*bb71e40dSAndré Draszik
666*bb71e40dSAndré Draszik static const struct i2c_device_id max77759_i2c_id[] = {
667*bb71e40dSAndré Draszik { "max77759" },
668*bb71e40dSAndré Draszik { }
669*bb71e40dSAndré Draszik };
670*bb71e40dSAndré Draszik MODULE_DEVICE_TABLE(i2c, max77759_i2c_id);
671*bb71e40dSAndré Draszik
672*bb71e40dSAndré Draszik static const struct of_device_id max77759_of_id[] = {
673*bb71e40dSAndré Draszik { .compatible = "maxim,max77759", },
674*bb71e40dSAndré Draszik { }
675*bb71e40dSAndré Draszik };
676*bb71e40dSAndré Draszik MODULE_DEVICE_TABLE(of, max77759_of_id);
677*bb71e40dSAndré Draszik
678*bb71e40dSAndré Draszik static struct i2c_driver max77759_i2c_driver = {
679*bb71e40dSAndré Draszik .driver = {
680*bb71e40dSAndré Draszik .name = "max77759",
681*bb71e40dSAndré Draszik .of_match_table = max77759_of_id,
682*bb71e40dSAndré Draszik },
683*bb71e40dSAndré Draszik .probe = max77759_probe,
684*bb71e40dSAndré Draszik .id_table = max77759_i2c_id,
685*bb71e40dSAndré Draszik };
686*bb71e40dSAndré Draszik module_i2c_driver(max77759_i2c_driver);
687*bb71e40dSAndré Draszik
688*bb71e40dSAndré Draszik MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>");
689*bb71e40dSAndré Draszik MODULE_DESCRIPTION("Maxim MAX77759 core driver");
690*bb71e40dSAndré Draszik MODULE_LICENSE("GPL");
691