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