Commit | Line | Data |
---|---|---|
7edd3634 GC |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * Copyright (c) 2020 MediaTek Inc. | |
4 | * | |
5 | * Author: Gene Chen <gene_chen@richtek.com> | |
6 | */ | |
7 | ||
8 | #include <linux/i2c.h> | |
9 | #include <linux/init.h> | |
10 | #include <linux/interrupt.h> | |
11 | #include <linux/kernel.h> | |
12 | #include <linux/mfd/core.h> | |
13 | #include <linux/module.h> | |
14 | #include <linux/of_irq.h> | |
15 | #include <linux/of_platform.h> | |
7edd3634 GC |
16 | |
17 | #include <linux/mfd/mt6360.h> | |
18 | ||
19 | /* reg 0 -> 0 ~ 7 */ | |
20 | #define MT6360_CHG_TREG_EVT (4) | |
21 | #define MT6360_CHG_AICR_EVT (5) | |
22 | #define MT6360_CHG_MIVR_EVT (6) | |
23 | #define MT6360_PWR_RDY_EVT (7) | |
24 | /* REG 1 -> 8 ~ 15 */ | |
25 | #define MT6360_CHG_BATSYSUV_EVT (9) | |
26 | #define MT6360_FLED_CHG_VINOVP_EVT (11) | |
27 | #define MT6360_CHG_VSYSUV_EVT (12) | |
28 | #define MT6360_CHG_VSYSOV_EVT (13) | |
29 | #define MT6360_CHG_VBATOV_EVT (14) | |
30 | #define MT6360_CHG_VBUSOV_EVT (15) | |
31 | /* REG 2 -> 16 ~ 23 */ | |
32 | /* REG 3 -> 24 ~ 31 */ | |
33 | #define MT6360_WD_PMU_DET (25) | |
34 | #define MT6360_WD_PMU_DONE (26) | |
35 | #define MT6360_CHG_TMRI (27) | |
36 | #define MT6360_CHG_ADPBADI (29) | |
37 | #define MT6360_CHG_RVPI (30) | |
38 | #define MT6360_OTPI (31) | |
39 | /* REG 4 -> 32 ~ 39 */ | |
40 | #define MT6360_CHG_AICCMEASL (32) | |
41 | #define MT6360_CHGDET_DONEI (34) | |
42 | #define MT6360_WDTMRI (35) | |
43 | #define MT6360_SSFINISHI (36) | |
44 | #define MT6360_CHG_RECHGI (37) | |
45 | #define MT6360_CHG_TERMI (38) | |
46 | #define MT6360_CHG_IEOCI (39) | |
47 | /* REG 5 -> 40 ~ 47 */ | |
48 | #define MT6360_PUMPX_DONEI (40) | |
49 | #define MT6360_BAT_OVP_ADC_EVT (41) | |
50 | #define MT6360_TYPEC_OTP_EVT (42) | |
51 | #define MT6360_ADC_WAKEUP_EVT (43) | |
52 | #define MT6360_ADC_DONEI (44) | |
53 | #define MT6360_BST_BATUVI (45) | |
54 | #define MT6360_BST_VBUSOVI (46) | |
55 | #define MT6360_BST_OLPI (47) | |
56 | /* REG 6 -> 48 ~ 55 */ | |
57 | #define MT6360_ATTACH_I (48) | |
58 | #define MT6360_DETACH_I (49) | |
59 | #define MT6360_QC30_STPDONE (51) | |
60 | #define MT6360_QC_VBUSDET_DONE (52) | |
61 | #define MT6360_HVDCP_DET (53) | |
62 | #define MT6360_CHGDETI (54) | |
63 | #define MT6360_DCDTI (55) | |
64 | /* REG 7 -> 56 ~ 63 */ | |
65 | #define MT6360_FOD_DONE_EVT (56) | |
66 | #define MT6360_FOD_OV_EVT (57) | |
67 | #define MT6360_CHRDET_UVP_EVT (58) | |
68 | #define MT6360_CHRDET_OVP_EVT (59) | |
69 | #define MT6360_CHRDET_EXT_EVT (60) | |
70 | #define MT6360_FOD_LR_EVT (61) | |
71 | #define MT6360_FOD_HR_EVT (62) | |
72 | #define MT6360_FOD_DISCHG_FAIL_EVT (63) | |
73 | /* REG 8 -> 64 ~ 71 */ | |
74 | #define MT6360_USBID_EVT (64) | |
75 | #define MT6360_APWDTRST_EVT (65) | |
76 | #define MT6360_EN_EVT (66) | |
77 | #define MT6360_QONB_RST_EVT (67) | |
78 | #define MT6360_MRSTB_EVT (68) | |
79 | #define MT6360_OTP_EVT (69) | |
80 | #define MT6360_VDDAOV_EVT (70) | |
81 | #define MT6360_SYSUV_EVT (71) | |
82 | /* REG 9 -> 72 ~ 79 */ | |
83 | #define MT6360_FLED_STRBPIN_EVT (72) | |
84 | #define MT6360_FLED_TORPIN_EVT (73) | |
85 | #define MT6360_FLED_TX_EVT (74) | |
86 | #define MT6360_FLED_LVF_EVT (75) | |
87 | #define MT6360_FLED2_SHORT_EVT (78) | |
88 | #define MT6360_FLED1_SHORT_EVT (79) | |
89 | /* REG 10 -> 80 ~ 87 */ | |
90 | #define MT6360_FLED2_STRB_EVT (80) | |
91 | #define MT6360_FLED1_STRB_EVT (81) | |
92 | #define MT6360_FLED2_STRB_TO_EVT (82) | |
93 | #define MT6360_FLED1_STRB_TO_EVT (83) | |
94 | #define MT6360_FLED2_TOR_EVT (84) | |
95 | #define MT6360_FLED1_TOR_EVT (85) | |
96 | /* REG 11 -> 88 ~ 95 */ | |
97 | /* REG 12 -> 96 ~ 103 */ | |
98 | #define MT6360_BUCK1_PGB_EVT (96) | |
99 | #define MT6360_BUCK1_OC_EVT (100) | |
100 | #define MT6360_BUCK1_OV_EVT (101) | |
101 | #define MT6360_BUCK1_UV_EVT (102) | |
102 | /* REG 13 -> 104 ~ 111 */ | |
103 | #define MT6360_BUCK2_PGB_EVT (104) | |
104 | #define MT6360_BUCK2_OC_EVT (108) | |
105 | #define MT6360_BUCK2_OV_EVT (109) | |
106 | #define MT6360_BUCK2_UV_EVT (110) | |
107 | /* REG 14 -> 112 ~ 119 */ | |
108 | #define MT6360_LDO1_OC_EVT (113) | |
109 | #define MT6360_LDO2_OC_EVT (114) | |
110 | #define MT6360_LDO3_OC_EVT (115) | |
111 | #define MT6360_LDO5_OC_EVT (117) | |
112 | #define MT6360_LDO6_OC_EVT (118) | |
113 | #define MT6360_LDO7_OC_EVT (119) | |
114 | /* REG 15 -> 120 ~ 127 */ | |
115 | #define MT6360_LDO1_PGB_EVT (121) | |
116 | #define MT6360_LDO2_PGB_EVT (122) | |
117 | #define MT6360_LDO3_PGB_EVT (123) | |
118 | #define MT6360_LDO5_PGB_EVT (125) | |
119 | #define MT6360_LDO6_PGB_EVT (126) | |
120 | #define MT6360_LDO7_PGB_EVT (127) | |
121 | ||
122 | static const struct regmap_irq mt6360_pmu_irqs[] = { | |
123 | REGMAP_IRQ_REG_LINE(MT6360_CHG_TREG_EVT, 8), | |
124 | REGMAP_IRQ_REG_LINE(MT6360_CHG_AICR_EVT, 8), | |
125 | REGMAP_IRQ_REG_LINE(MT6360_CHG_MIVR_EVT, 8), | |
126 | REGMAP_IRQ_REG_LINE(MT6360_PWR_RDY_EVT, 8), | |
127 | REGMAP_IRQ_REG_LINE(MT6360_CHG_BATSYSUV_EVT, 8), | |
128 | REGMAP_IRQ_REG_LINE(MT6360_FLED_CHG_VINOVP_EVT, 8), | |
129 | REGMAP_IRQ_REG_LINE(MT6360_CHG_VSYSUV_EVT, 8), | |
130 | REGMAP_IRQ_REG_LINE(MT6360_CHG_VSYSOV_EVT, 8), | |
131 | REGMAP_IRQ_REG_LINE(MT6360_CHG_VBATOV_EVT, 8), | |
132 | REGMAP_IRQ_REG_LINE(MT6360_CHG_VBUSOV_EVT, 8), | |
133 | REGMAP_IRQ_REG_LINE(MT6360_WD_PMU_DET, 8), | |
134 | REGMAP_IRQ_REG_LINE(MT6360_WD_PMU_DONE, 8), | |
135 | REGMAP_IRQ_REG_LINE(MT6360_CHG_TMRI, 8), | |
136 | REGMAP_IRQ_REG_LINE(MT6360_CHG_ADPBADI, 8), | |
137 | REGMAP_IRQ_REG_LINE(MT6360_CHG_RVPI, 8), | |
138 | REGMAP_IRQ_REG_LINE(MT6360_OTPI, 8), | |
139 | REGMAP_IRQ_REG_LINE(MT6360_CHG_AICCMEASL, 8), | |
140 | REGMAP_IRQ_REG_LINE(MT6360_CHGDET_DONEI, 8), | |
141 | REGMAP_IRQ_REG_LINE(MT6360_WDTMRI, 8), | |
142 | REGMAP_IRQ_REG_LINE(MT6360_SSFINISHI, 8), | |
143 | REGMAP_IRQ_REG_LINE(MT6360_CHG_RECHGI, 8), | |
144 | REGMAP_IRQ_REG_LINE(MT6360_CHG_TERMI, 8), | |
145 | REGMAP_IRQ_REG_LINE(MT6360_CHG_IEOCI, 8), | |
146 | REGMAP_IRQ_REG_LINE(MT6360_PUMPX_DONEI, 8), | |
7edd3634 GC |
147 | REGMAP_IRQ_REG_LINE(MT6360_BAT_OVP_ADC_EVT, 8), |
148 | REGMAP_IRQ_REG_LINE(MT6360_TYPEC_OTP_EVT, 8), | |
149 | REGMAP_IRQ_REG_LINE(MT6360_ADC_WAKEUP_EVT, 8), | |
150 | REGMAP_IRQ_REG_LINE(MT6360_ADC_DONEI, 8), | |
151 | REGMAP_IRQ_REG_LINE(MT6360_BST_BATUVI, 8), | |
152 | REGMAP_IRQ_REG_LINE(MT6360_BST_VBUSOVI, 8), | |
153 | REGMAP_IRQ_REG_LINE(MT6360_BST_OLPI, 8), | |
154 | REGMAP_IRQ_REG_LINE(MT6360_ATTACH_I, 8), | |
155 | REGMAP_IRQ_REG_LINE(MT6360_DETACH_I, 8), | |
156 | REGMAP_IRQ_REG_LINE(MT6360_QC30_STPDONE, 8), | |
157 | REGMAP_IRQ_REG_LINE(MT6360_QC_VBUSDET_DONE, 8), | |
158 | REGMAP_IRQ_REG_LINE(MT6360_HVDCP_DET, 8), | |
159 | REGMAP_IRQ_REG_LINE(MT6360_CHGDETI, 8), | |
160 | REGMAP_IRQ_REG_LINE(MT6360_DCDTI, 8), | |
161 | REGMAP_IRQ_REG_LINE(MT6360_FOD_DONE_EVT, 8), | |
162 | REGMAP_IRQ_REG_LINE(MT6360_FOD_OV_EVT, 8), | |
163 | REGMAP_IRQ_REG_LINE(MT6360_CHRDET_UVP_EVT, 8), | |
164 | REGMAP_IRQ_REG_LINE(MT6360_CHRDET_OVP_EVT, 8), | |
165 | REGMAP_IRQ_REG_LINE(MT6360_CHRDET_EXT_EVT, 8), | |
166 | REGMAP_IRQ_REG_LINE(MT6360_FOD_LR_EVT, 8), | |
167 | REGMAP_IRQ_REG_LINE(MT6360_FOD_HR_EVT, 8), | |
168 | REGMAP_IRQ_REG_LINE(MT6360_FOD_DISCHG_FAIL_EVT, 8), | |
169 | REGMAP_IRQ_REG_LINE(MT6360_USBID_EVT, 8), | |
170 | REGMAP_IRQ_REG_LINE(MT6360_APWDTRST_EVT, 8), | |
171 | REGMAP_IRQ_REG_LINE(MT6360_EN_EVT, 8), | |
172 | REGMAP_IRQ_REG_LINE(MT6360_QONB_RST_EVT, 8), | |
173 | REGMAP_IRQ_REG_LINE(MT6360_MRSTB_EVT, 8), | |
174 | REGMAP_IRQ_REG_LINE(MT6360_OTP_EVT, 8), | |
175 | REGMAP_IRQ_REG_LINE(MT6360_VDDAOV_EVT, 8), | |
176 | REGMAP_IRQ_REG_LINE(MT6360_SYSUV_EVT, 8), | |
177 | REGMAP_IRQ_REG_LINE(MT6360_FLED_STRBPIN_EVT, 8), | |
178 | REGMAP_IRQ_REG_LINE(MT6360_FLED_TORPIN_EVT, 8), | |
179 | REGMAP_IRQ_REG_LINE(MT6360_FLED_TX_EVT, 8), | |
180 | REGMAP_IRQ_REG_LINE(MT6360_FLED_LVF_EVT, 8), | |
181 | REGMAP_IRQ_REG_LINE(MT6360_FLED2_SHORT_EVT, 8), | |
182 | REGMAP_IRQ_REG_LINE(MT6360_FLED1_SHORT_EVT, 8), | |
183 | REGMAP_IRQ_REG_LINE(MT6360_FLED2_STRB_EVT, 8), | |
184 | REGMAP_IRQ_REG_LINE(MT6360_FLED1_STRB_EVT, 8), | |
185 | REGMAP_IRQ_REG_LINE(MT6360_FLED2_STRB_TO_EVT, 8), | |
186 | REGMAP_IRQ_REG_LINE(MT6360_FLED1_STRB_TO_EVT, 8), | |
187 | REGMAP_IRQ_REG_LINE(MT6360_FLED2_TOR_EVT, 8), | |
188 | REGMAP_IRQ_REG_LINE(MT6360_FLED1_TOR_EVT, 8), | |
189 | REGMAP_IRQ_REG_LINE(MT6360_BUCK1_PGB_EVT, 8), | |
190 | REGMAP_IRQ_REG_LINE(MT6360_BUCK1_OC_EVT, 8), | |
191 | REGMAP_IRQ_REG_LINE(MT6360_BUCK1_OV_EVT, 8), | |
192 | REGMAP_IRQ_REG_LINE(MT6360_BUCK1_UV_EVT, 8), | |
193 | REGMAP_IRQ_REG_LINE(MT6360_BUCK2_PGB_EVT, 8), | |
194 | REGMAP_IRQ_REG_LINE(MT6360_BUCK2_OC_EVT, 8), | |
195 | REGMAP_IRQ_REG_LINE(MT6360_BUCK2_OV_EVT, 8), | |
196 | REGMAP_IRQ_REG_LINE(MT6360_BUCK2_UV_EVT, 8), | |
197 | REGMAP_IRQ_REG_LINE(MT6360_LDO1_OC_EVT, 8), | |
198 | REGMAP_IRQ_REG_LINE(MT6360_LDO2_OC_EVT, 8), | |
199 | REGMAP_IRQ_REG_LINE(MT6360_LDO3_OC_EVT, 8), | |
200 | REGMAP_IRQ_REG_LINE(MT6360_LDO5_OC_EVT, 8), | |
201 | REGMAP_IRQ_REG_LINE(MT6360_LDO6_OC_EVT, 8), | |
202 | REGMAP_IRQ_REG_LINE(MT6360_LDO7_OC_EVT, 8), | |
203 | REGMAP_IRQ_REG_LINE(MT6360_LDO1_PGB_EVT, 8), | |
204 | REGMAP_IRQ_REG_LINE(MT6360_LDO2_PGB_EVT, 8), | |
205 | REGMAP_IRQ_REG_LINE(MT6360_LDO3_PGB_EVT, 8), | |
206 | REGMAP_IRQ_REG_LINE(MT6360_LDO5_PGB_EVT, 8), | |
207 | REGMAP_IRQ_REG_LINE(MT6360_LDO6_PGB_EVT, 8), | |
208 | REGMAP_IRQ_REG_LINE(MT6360_LDO7_PGB_EVT, 8), | |
209 | }; | |
210 | ||
211 | static int mt6360_pmu_handle_post_irq(void *irq_drv_data) | |
212 | { | |
213 | struct mt6360_pmu_data *mpd = irq_drv_data; | |
214 | ||
215 | return regmap_update_bits(mpd->regmap, | |
216 | MT6360_PMU_IRQ_SET, MT6360_IRQ_RETRIG, MT6360_IRQ_RETRIG); | |
217 | } | |
218 | ||
219 | static struct regmap_irq_chip mt6360_pmu_irq_chip = { | |
220 | .irqs = mt6360_pmu_irqs, | |
221 | .num_irqs = ARRAY_SIZE(mt6360_pmu_irqs), | |
222 | .num_regs = MT6360_PMU_IRQ_REGNUM, | |
223 | .mask_base = MT6360_PMU_CHG_MASK1, | |
224 | .status_base = MT6360_PMU_CHG_IRQ1, | |
225 | .ack_base = MT6360_PMU_CHG_IRQ1, | |
226 | .init_ack_masked = true, | |
227 | .use_ack = true, | |
228 | .handle_post_irq = mt6360_pmu_handle_post_irq, | |
229 | }; | |
230 | ||
231 | static const struct regmap_config mt6360_pmu_regmap_config = { | |
232 | .reg_bits = 8, | |
233 | .val_bits = 8, | |
234 | .max_register = MT6360_PMU_MAXREG, | |
235 | }; | |
236 | ||
237 | static const struct resource mt6360_adc_resources[] = { | |
238 | DEFINE_RES_IRQ_NAMED(MT6360_ADC_DONEI, "adc_donei"), | |
239 | }; | |
240 | ||
241 | static const struct resource mt6360_chg_resources[] = { | |
242 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_TREG_EVT, "chg_treg_evt"), | |
243 | DEFINE_RES_IRQ_NAMED(MT6360_PWR_RDY_EVT, "pwr_rdy_evt"), | |
244 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_BATSYSUV_EVT, "chg_batsysuv_evt"), | |
245 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSUV_EVT, "chg_vsysuv_evt"), | |
246 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSOV_EVT, "chg_vsysov_evt"), | |
247 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBATOV_EVT, "chg_vbatov_evt"), | |
248 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBUSOV_EVT, "chg_vbusov_evt"), | |
249 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_AICCMEASL, "chg_aiccmeasl"), | |
250 | DEFINE_RES_IRQ_NAMED(MT6360_WDTMRI, "wdtmri"), | |
251 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_RECHGI, "chg_rechgi"), | |
252 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_TERMI, "chg_termi"), | |
253 | DEFINE_RES_IRQ_NAMED(MT6360_CHG_IEOCI, "chg_ieoci"), | |
254 | DEFINE_RES_IRQ_NAMED(MT6360_PUMPX_DONEI, "pumpx_donei"), | |
255 | DEFINE_RES_IRQ_NAMED(MT6360_ATTACH_I, "attach_i"), | |
256 | DEFINE_RES_IRQ_NAMED(MT6360_CHRDET_EXT_EVT, "chrdet_ext_evt"), | |
257 | }; | |
258 | ||
259 | static const struct resource mt6360_led_resources[] = { | |
260 | DEFINE_RES_IRQ_NAMED(MT6360_FLED_CHG_VINOVP_EVT, "fled_chg_vinovp_evt"), | |
261 | DEFINE_RES_IRQ_NAMED(MT6360_FLED_LVF_EVT, "fled_lvf_evt"), | |
262 | DEFINE_RES_IRQ_NAMED(MT6360_FLED2_SHORT_EVT, "fled2_short_evt"), | |
263 | DEFINE_RES_IRQ_NAMED(MT6360_FLED1_SHORT_EVT, "fled1_short_evt"), | |
264 | DEFINE_RES_IRQ_NAMED(MT6360_FLED2_STRB_TO_EVT, "fled2_strb_to_evt"), | |
265 | DEFINE_RES_IRQ_NAMED(MT6360_FLED1_STRB_TO_EVT, "fled1_strb_to_evt"), | |
266 | }; | |
267 | ||
268 | static const struct resource mt6360_pmic_resources[] = { | |
269 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_PGB_EVT, "buck1_pgb_evt"), | |
270 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OC_EVT, "buck1_oc_evt"), | |
271 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OV_EVT, "buck1_ov_evt"), | |
272 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_UV_EVT, "buck1_uv_evt"), | |
273 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_PGB_EVT, "buck2_pgb_evt"), | |
274 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OC_EVT, "buck2_oc_evt"), | |
275 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OV_EVT, "buck2_ov_evt"), | |
276 | DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_UV_EVT, "buck2_uv_evt"), | |
277 | DEFINE_RES_IRQ_NAMED(MT6360_LDO6_OC_EVT, "ldo6_oc_evt"), | |
278 | DEFINE_RES_IRQ_NAMED(MT6360_LDO7_OC_EVT, "ldo7_oc_evt"), | |
279 | DEFINE_RES_IRQ_NAMED(MT6360_LDO6_PGB_EVT, "ldo6_pgb_evt"), | |
280 | DEFINE_RES_IRQ_NAMED(MT6360_LDO7_PGB_EVT, "ldo7_pgb_evt"), | |
281 | }; | |
282 | ||
283 | static const struct resource mt6360_ldo_resources[] = { | |
284 | DEFINE_RES_IRQ_NAMED(MT6360_LDO1_OC_EVT, "ldo1_oc_evt"), | |
285 | DEFINE_RES_IRQ_NAMED(MT6360_LDO2_OC_EVT, "ldo2_oc_evt"), | |
286 | DEFINE_RES_IRQ_NAMED(MT6360_LDO3_OC_EVT, "ldo3_oc_evt"), | |
287 | DEFINE_RES_IRQ_NAMED(MT6360_LDO5_OC_EVT, "ldo5_oc_evt"), | |
288 | DEFINE_RES_IRQ_NAMED(MT6360_LDO1_PGB_EVT, "ldo1_pgb_evt"), | |
289 | DEFINE_RES_IRQ_NAMED(MT6360_LDO2_PGB_EVT, "ldo2_pgb_evt"), | |
290 | DEFINE_RES_IRQ_NAMED(MT6360_LDO3_PGB_EVT, "ldo3_pgb_evt"), | |
291 | DEFINE_RES_IRQ_NAMED(MT6360_LDO5_PGB_EVT, "ldo5_pgb_evt"), | |
292 | }; | |
293 | ||
294 | static const struct mfd_cell mt6360_devs[] = { | |
db783e76 | 295 | MFD_CELL_OF("mt6360_adc", mt6360_adc_resources, |
7edd3634 | 296 | NULL, 0, 0, "mediatek,mt6360_adc"), |
db783e76 | 297 | MFD_CELL_OF("mt6360_chg", mt6360_chg_resources, |
7edd3634 | 298 | NULL, 0, 0, "mediatek,mt6360_chg"), |
db783e76 | 299 | MFD_CELL_OF("mt6360_led", mt6360_led_resources, |
7edd3634 | 300 | NULL, 0, 0, "mediatek,mt6360_led"), |
db783e76 | 301 | MFD_CELL_OF("mt6360_pmic", mt6360_pmic_resources, |
7edd3634 | 302 | NULL, 0, 0, "mediatek,mt6360_pmic"), |
db783e76 | 303 | MFD_CELL_OF("mt6360_ldo", mt6360_ldo_resources, |
7edd3634 | 304 | NULL, 0, 0, "mediatek,mt6360_ldo"), |
db783e76 | 305 | MFD_CELL_OF("mt6360_tcpc", NULL, |
7edd3634 GC |
306 | NULL, 0, 0, "mediatek,mt6360_tcpc"), |
307 | }; | |
308 | ||
309 | static const unsigned short mt6360_slave_addr[MT6360_SLAVE_MAX] = { | |
310 | MT6360_PMU_SLAVEID, | |
311 | MT6360_PMIC_SLAVEID, | |
312 | MT6360_LDO_SLAVEID, | |
313 | MT6360_TCPC_SLAVEID, | |
314 | }; | |
315 | ||
316 | static int mt6360_pmu_probe(struct i2c_client *client) | |
317 | { | |
318 | struct mt6360_pmu_data *mpd; | |
319 | unsigned int reg_data; | |
320 | int i, ret; | |
321 | ||
322 | mpd = devm_kzalloc(&client->dev, sizeof(*mpd), GFP_KERNEL); | |
323 | if (!mpd) | |
324 | return -ENOMEM; | |
325 | ||
326 | mpd->dev = &client->dev; | |
327 | i2c_set_clientdata(client, mpd); | |
328 | ||
329 | mpd->regmap = devm_regmap_init_i2c(client, &mt6360_pmu_regmap_config); | |
330 | if (IS_ERR(mpd->regmap)) { | |
331 | dev_err(&client->dev, "Failed to register regmap\n"); | |
332 | return PTR_ERR(mpd->regmap); | |
333 | } | |
334 | ||
335 | ret = regmap_read(mpd->regmap, MT6360_PMU_DEV_INFO, ®_data); | |
336 | if (ret) { | |
337 | dev_err(&client->dev, "Device not found\n"); | |
338 | return ret; | |
339 | } | |
340 | ||
341 | mpd->chip_rev = reg_data & CHIP_REV_MASK; | |
342 | if (mpd->chip_rev != CHIP_VEN_MT6360) { | |
343 | dev_err(&client->dev, "Device not supported\n"); | |
344 | return -ENODEV; | |
345 | } | |
346 | ||
347 | mt6360_pmu_irq_chip.irq_drv_data = mpd; | |
348 | ret = devm_regmap_add_irq_chip(&client->dev, mpd->regmap, client->irq, | |
349 | IRQF_TRIGGER_FALLING, 0, | |
350 | &mt6360_pmu_irq_chip, &mpd->irq_data); | |
351 | if (ret) { | |
352 | dev_err(&client->dev, "Failed to add Regmap IRQ Chip\n"); | |
353 | return ret; | |
354 | } | |
355 | ||
356 | mpd->i2c[0] = client; | |
357 | for (i = 1; i < MT6360_SLAVE_MAX; i++) { | |
358 | mpd->i2c[i] = devm_i2c_new_dummy_device(&client->dev, | |
359 | client->adapter, | |
360 | mt6360_slave_addr[i]); | |
361 | if (IS_ERR(mpd->i2c[i])) { | |
362 | dev_err(&client->dev, | |
363 | "Failed to get new dummy I2C device for address 0x%x", | |
364 | mt6360_slave_addr[i]); | |
365 | return PTR_ERR(mpd->i2c[i]); | |
366 | } | |
367 | i2c_set_clientdata(mpd->i2c[i], mpd); | |
368 | } | |
369 | ||
370 | ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, | |
371 | mt6360_devs, ARRAY_SIZE(mt6360_devs), NULL, | |
372 | 0, regmap_irq_get_domain(mpd->irq_data)); | |
373 | if (ret) { | |
374 | dev_err(&client->dev, | |
375 | "Failed to register subordinate devices\n"); | |
376 | return ret; | |
377 | } | |
378 | ||
379 | return 0; | |
380 | } | |
381 | ||
382 | static int __maybe_unused mt6360_pmu_suspend(struct device *dev) | |
383 | { | |
384 | struct i2c_client *i2c = to_i2c_client(dev); | |
385 | ||
386 | if (device_may_wakeup(dev)) | |
387 | enable_irq_wake(i2c->irq); | |
388 | ||
389 | return 0; | |
390 | } | |
391 | ||
392 | static int __maybe_unused mt6360_pmu_resume(struct device *dev) | |
393 | { | |
394 | ||
395 | struct i2c_client *i2c = to_i2c_client(dev); | |
396 | ||
397 | if (device_may_wakeup(dev)) | |
398 | disable_irq_wake(i2c->irq); | |
399 | ||
400 | return 0; | |
401 | } | |
402 | ||
403 | static SIMPLE_DEV_PM_OPS(mt6360_pmu_pm_ops, | |
404 | mt6360_pmu_suspend, mt6360_pmu_resume); | |
405 | ||
406 | static const struct of_device_id __maybe_unused mt6360_pmu_of_id[] = { | |
407 | { .compatible = "mediatek,mt6360_pmu", }, | |
408 | {}, | |
409 | }; | |
410 | MODULE_DEVICE_TABLE(of, mt6360_pmu_of_id); | |
411 | ||
412 | static struct i2c_driver mt6360_pmu_driver = { | |
413 | .driver = { | |
bf6b694a | 414 | .name = "mt6360_pmu", |
7edd3634 GC |
415 | .pm = &mt6360_pmu_pm_ops, |
416 | .of_match_table = of_match_ptr(mt6360_pmu_of_id), | |
417 | }, | |
418 | .probe_new = mt6360_pmu_probe, | |
419 | }; | |
420 | module_i2c_driver(mt6360_pmu_driver); | |
421 | ||
422 | MODULE_AUTHOR("Gene Chen <gene_chen@richtek.com>"); | |
423 | MODULE_DESCRIPTION("MT6360 PMU I2C Driver"); | |
424 | MODULE_LICENSE("GPL v2"); |