drm/tests: hdmi: Fix memory leaks in drm_display_mode_from_cea_vic()
[drm/drm-misc.git] / drivers / iio / adc / mt6359-auxadc.c
bloba4970cfb49a5d4e14e6d8e6dd2f0013327e6687e
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * MediaTek MT6359 PMIC AUXADC IIO driver
5 * Copyright (c) 2021 MediaTek Inc.
6 * Copyright (c) 2024 Collabora Ltd
7 * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
8 */
10 #include <linux/bits.h>
11 #include <linux/cleanup.h>
12 #include <linux/delay.h>
13 #include <linux/module.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/platform_device.h>
16 #include <linux/property.h>
17 #include <linux/regmap.h>
18 #include <linux/types.h>
20 #include <linux/iio/iio.h>
22 #include <linux/mfd/mt6397/core.h>
24 #include <dt-bindings/iio/adc/mediatek,mt6357-auxadc.h>
25 #include <dt-bindings/iio/adc/mediatek,mt6358-auxadc.h>
26 #include <dt-bindings/iio/adc/mediatek,mt6359-auxadc.h>
28 #define AUXADC_AVG_TIME_US 10
29 #define AUXADC_POLL_DELAY_US 100
30 #define AUXADC_TIMEOUT_US 32000
31 #define AUXADC_VOLT_FULL 1800
32 #define IMP_STOP_DELAY_US 150
33 #define IMP_POLL_DELAY_US 1000
35 /* For PMIC_RG_RESET_VAL and MT6358_IMP0_CLEAR, the bits specific purpose is unknown. */
36 #define PMIC_RG_RESET_VAL (BIT(0) | BIT(3))
37 #define PMIC_AUXADC_RDY_BIT BIT(15)
38 #define MT6357_IMP_ADC_NUM 30
39 #define MT6358_IMP_ADC_NUM 28
41 #define MT6358_DCM_CK_SW_EN GENMASK(1, 0)
42 #define MT6358_IMP0_CLEAR (BIT(14) | BIT(7))
43 #define MT6358_IMP0_IRQ_RDY BIT(8)
44 #define MT6358_IMP1_AUTOREPEAT_EN BIT(15)
46 #define MT6359_IMP0_CONV_EN BIT(0)
47 #define MT6359_IMP1_IRQ_RDY BIT(15)
49 enum mtk_pmic_auxadc_regs {
50 PMIC_AUXADC_ADC0,
51 PMIC_AUXADC_DCM_CON,
52 PMIC_AUXADC_IMP0,
53 PMIC_AUXADC_IMP1,
54 PMIC_AUXADC_IMP3,
55 PMIC_AUXADC_RQST0,
56 PMIC_AUXADC_RQST1,
57 PMIC_HK_TOP_WKEY,
58 PMIC_HK_TOP_RST_CON0,
59 PMIC_FGADC_R_CON0,
60 PMIC_AUXADC_REGS_MAX
63 enum mtk_pmic_auxadc_channels {
64 PMIC_AUXADC_CHAN_BATADC,
65 PMIC_AUXADC_CHAN_ISENSE,
66 PMIC_AUXADC_CHAN_VCDT,
67 PMIC_AUXADC_CHAN_BAT_TEMP,
68 PMIC_AUXADC_CHAN_BATID,
69 PMIC_AUXADC_CHAN_CHIP_TEMP,
70 PMIC_AUXADC_CHAN_VCORE_TEMP,
71 PMIC_AUXADC_CHAN_VPROC_TEMP,
72 PMIC_AUXADC_CHAN_VGPU_TEMP,
73 PMIC_AUXADC_CHAN_ACCDET,
74 PMIC_AUXADC_CHAN_VDCXO,
75 PMIC_AUXADC_CHAN_TSX_TEMP,
76 PMIC_AUXADC_CHAN_HPOFS_CAL,
77 PMIC_AUXADC_CHAN_DCXO_TEMP,
78 PMIC_AUXADC_CHAN_VBIF,
79 PMIC_AUXADC_CHAN_IBAT,
80 PMIC_AUXADC_CHAN_VBAT,
81 PMIC_AUXADC_CHAN_MAX
84 /**
85 * struct mt6359_auxadc - Main driver structure
86 * @dev: Device pointer
87 * @regmap: Regmap from SoC PMIC Wrapper
88 * @chip_info: PMIC specific chip info
89 * @lock: Mutex to serialize AUXADC reading vs configuration
90 * @timed_out: Signals whether the last read timed out
92 struct mt6359_auxadc {
93 struct device *dev;
94 struct regmap *regmap;
95 const struct mtk_pmic_auxadc_info *chip_info;
96 struct mutex lock;
97 bool timed_out;
101 * struct mtk_pmic_auxadc_chan - PMIC AUXADC channel data
102 * @req_idx: Request register number
103 * @req_mask: Bitmask to activate a channel
104 * @num_samples: Number of AUXADC samples for averaging
105 * @r_ratio: Resistance ratio fractional
107 struct mtk_pmic_auxadc_chan {
108 u8 req_idx;
109 u16 req_mask;
110 u16 num_samples;
111 struct u8_fract r_ratio;
115 * struct mtk_pmic_auxadc_info - PMIC specific chip info
116 * @model_name: PMIC model name
117 * @channels: IIO specification of ADC channels
118 * @num_channels: Number of ADC channels
119 * @desc: PMIC AUXADC channel data
120 * @regs: List of PMIC specific registers
121 * @sec_unlock_key: Security unlock key for HK_TOP writes
122 * @imp_adc_num: ADC channel for battery impedance readings
123 * @read_imp: Callback to read impedance channels
125 struct mtk_pmic_auxadc_info {
126 const char *model_name;
127 const struct iio_chan_spec *channels;
128 u8 num_channels;
129 const struct mtk_pmic_auxadc_chan *desc;
130 const u16 *regs;
131 u16 sec_unlock_key;
132 u8 imp_adc_num;
133 int (*read_imp)(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat);
136 #define MTK_PMIC_ADC_CHAN(_ch_idx, _req_idx, _req_bit, _samples, _rnum, _rdiv) \
137 [PMIC_AUXADC_CHAN_##_ch_idx] = { \
138 .req_idx = _req_idx, \
139 .req_mask = BIT(_req_bit), \
140 .num_samples = _samples, \
141 .r_ratio = { _rnum, _rdiv } \
144 #define MTK_PMIC_IIO_CHAN(_model, _name, _ch_idx, _adc_idx, _nbits, _ch_type) \
146 .type = _ch_type, \
147 .channel = _model##_AUXADC_##_ch_idx, \
148 .address = _adc_idx, \
149 .scan_index = PMIC_AUXADC_CHAN_##_ch_idx, \
150 .datasheet_name = __stringify(_name), \
151 .scan_type = { \
152 .sign = 'u', \
153 .realbits = _nbits, \
154 .storagebits = 16, \
155 .endianness = IIO_CPU \
156 }, \
157 .indexed = 1, \
158 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) \
161 static const struct iio_chan_spec mt6357_auxadc_channels[] = {
162 MTK_PMIC_IIO_CHAN(MT6357, bat_adc, BATADC, 0, 15, IIO_RESISTANCE),
163 MTK_PMIC_IIO_CHAN(MT6357, isense, ISENSE, 1, 12, IIO_CURRENT),
164 MTK_PMIC_IIO_CHAN(MT6357, cdt_v, VCDT, 2, 12, IIO_TEMP),
165 MTK_PMIC_IIO_CHAN(MT6357, batt_temp, BAT_TEMP, 3, 12, IIO_TEMP),
166 MTK_PMIC_IIO_CHAN(MT6357, chip_temp, CHIP_TEMP, 4, 12, IIO_TEMP),
167 MTK_PMIC_IIO_CHAN(MT6357, acc_det, ACCDET, 5, 12, IIO_RESISTANCE),
168 MTK_PMIC_IIO_CHAN(MT6357, dcxo_v, VDCXO, 6, 12, IIO_VOLTAGE),
169 MTK_PMIC_IIO_CHAN(MT6357, tsx_temp, TSX_TEMP, 7, 15, IIO_TEMP),
170 MTK_PMIC_IIO_CHAN(MT6357, hp_ofs_cal, HPOFS_CAL, 9, 15, IIO_RESISTANCE),
171 MTK_PMIC_IIO_CHAN(MT6357, dcxo_temp, DCXO_TEMP, 36, 15, IIO_TEMP),
172 MTK_PMIC_IIO_CHAN(MT6357, vcore_temp, VCORE_TEMP, 40, 12, IIO_TEMP),
173 MTK_PMIC_IIO_CHAN(MT6357, vproc_temp, VPROC_TEMP, 41, 12, IIO_TEMP),
175 /* Battery impedance channels */
176 MTK_PMIC_IIO_CHAN(MT6357, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
179 static const struct mtk_pmic_auxadc_chan mt6357_auxadc_ch_desc[] = {
180 MTK_PMIC_ADC_CHAN(BATADC, PMIC_AUXADC_RQST0, 0, 128, 3, 1),
181 MTK_PMIC_ADC_CHAN(ISENSE, PMIC_AUXADC_RQST0, 0, 128, 3, 1),
182 MTK_PMIC_ADC_CHAN(VCDT, PMIC_AUXADC_RQST0, 0, 8, 1, 1),
183 MTK_PMIC_ADC_CHAN(BAT_TEMP, PMIC_AUXADC_RQST0, 3, 8, 1, 1),
184 MTK_PMIC_ADC_CHAN(CHIP_TEMP, PMIC_AUXADC_RQST0, 4, 8, 1, 1),
185 MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, 8, 1, 1),
186 MTK_PMIC_ADC_CHAN(TSX_TEMP, PMIC_AUXADC_RQST0, 7, 128, 1, 1),
187 MTK_PMIC_ADC_CHAN(HPOFS_CAL, PMIC_AUXADC_RQST0, 9, 256, 1, 1),
188 MTK_PMIC_ADC_CHAN(DCXO_TEMP, PMIC_AUXADC_RQST0, 10, 16, 1, 1),
189 MTK_PMIC_ADC_CHAN(VBIF, PMIC_AUXADC_RQST0, 11, 8, 1, 1),
190 MTK_PMIC_ADC_CHAN(VCORE_TEMP, PMIC_AUXADC_RQST1, 5, 8, 1, 1),
191 MTK_PMIC_ADC_CHAN(VPROC_TEMP, PMIC_AUXADC_RQST1, 6, 8, 1, 1),
193 /* Battery impedance channels */
194 MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 3, 1),
197 static const u16 mt6357_auxadc_regs[] = {
198 [PMIC_HK_TOP_RST_CON0] = 0x0f90,
199 [PMIC_AUXADC_DCM_CON] = 0x122e,
200 [PMIC_AUXADC_ADC0] = 0x1088,
201 [PMIC_AUXADC_IMP0] = 0x119c,
202 [PMIC_AUXADC_IMP1] = 0x119e,
203 [PMIC_AUXADC_RQST0] = 0x110e,
204 [PMIC_AUXADC_RQST1] = 0x1114,
207 static const struct iio_chan_spec mt6358_auxadc_channels[] = {
208 MTK_PMIC_IIO_CHAN(MT6358, bat_adc, BATADC, 0, 15, IIO_RESISTANCE),
209 MTK_PMIC_IIO_CHAN(MT6358, cdt_v, VCDT, 2, 12, IIO_TEMP),
210 MTK_PMIC_IIO_CHAN(MT6358, batt_temp, BAT_TEMP, 3, 12, IIO_TEMP),
211 MTK_PMIC_IIO_CHAN(MT6358, chip_temp, CHIP_TEMP, 4, 12, IIO_TEMP),
212 MTK_PMIC_IIO_CHAN(MT6358, acc_det, ACCDET, 5, 12, IIO_RESISTANCE),
213 MTK_PMIC_IIO_CHAN(MT6358, dcxo_v, VDCXO, 6, 12, IIO_VOLTAGE),
214 MTK_PMIC_IIO_CHAN(MT6358, tsx_temp, TSX_TEMP, 7, 15, IIO_TEMP),
215 MTK_PMIC_IIO_CHAN(MT6358, hp_ofs_cal, HPOFS_CAL, 9, 15, IIO_RESISTANCE),
216 MTK_PMIC_IIO_CHAN(MT6358, dcxo_temp, DCXO_TEMP, 10, 15, IIO_TEMP),
217 MTK_PMIC_IIO_CHAN(MT6358, bif_v, VBIF, 11, 12, IIO_VOLTAGE),
218 MTK_PMIC_IIO_CHAN(MT6358, vcore_temp, VCORE_TEMP, 38, 12, IIO_TEMP),
219 MTK_PMIC_IIO_CHAN(MT6358, vproc_temp, VPROC_TEMP, 39, 12, IIO_TEMP),
220 MTK_PMIC_IIO_CHAN(MT6358, vgpu_temp, VGPU_TEMP, 40, 12, IIO_TEMP),
222 /* Battery impedance channels */
223 MTK_PMIC_IIO_CHAN(MT6358, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
226 static const struct mtk_pmic_auxadc_chan mt6358_auxadc_ch_desc[] = {
227 MTK_PMIC_ADC_CHAN(BATADC, PMIC_AUXADC_RQST0, 0, 128, 3, 1),
228 MTK_PMIC_ADC_CHAN(VCDT, PMIC_AUXADC_RQST0, 0, 8, 1, 1),
229 MTK_PMIC_ADC_CHAN(BAT_TEMP, PMIC_AUXADC_RQST0, 3, 8, 2, 1),
230 MTK_PMIC_ADC_CHAN(CHIP_TEMP, PMIC_AUXADC_RQST0, 4, 8, 1, 1),
231 MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, 8, 1, 1),
232 MTK_PMIC_ADC_CHAN(VDCXO, PMIC_AUXADC_RQST0, 6, 8, 3, 2),
233 MTK_PMIC_ADC_CHAN(TSX_TEMP, PMIC_AUXADC_RQST0, 7, 128, 1, 1),
234 MTK_PMIC_ADC_CHAN(HPOFS_CAL, PMIC_AUXADC_RQST0, 9, 256, 1, 1),
235 MTK_PMIC_ADC_CHAN(DCXO_TEMP, PMIC_AUXADC_RQST0, 10, 16, 1, 1),
236 MTK_PMIC_ADC_CHAN(VBIF, PMIC_AUXADC_RQST0, 11, 8, 2, 1),
237 MTK_PMIC_ADC_CHAN(VCORE_TEMP, PMIC_AUXADC_RQST1, 8, 8, 1, 1),
238 MTK_PMIC_ADC_CHAN(VPROC_TEMP, PMIC_AUXADC_RQST1, 9, 8, 1, 1),
239 MTK_PMIC_ADC_CHAN(VGPU_TEMP, PMIC_AUXADC_RQST1, 10, 8, 1, 1),
241 /* Battery impedance channels */
242 MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 7, 2),
245 static const u16 mt6358_auxadc_regs[] = {
246 [PMIC_HK_TOP_RST_CON0] = 0x0f90,
247 [PMIC_AUXADC_DCM_CON] = 0x1260,
248 [PMIC_AUXADC_ADC0] = 0x1088,
249 [PMIC_AUXADC_IMP0] = 0x1208,
250 [PMIC_AUXADC_IMP1] = 0x120a,
251 [PMIC_AUXADC_RQST0] = 0x1108,
252 [PMIC_AUXADC_RQST1] = 0x110a,
255 static const struct iio_chan_spec mt6359_auxadc_channels[] = {
256 MTK_PMIC_IIO_CHAN(MT6359, bat_adc, BATADC, 0, 15, IIO_RESISTANCE),
257 MTK_PMIC_IIO_CHAN(MT6359, batt_temp, BAT_TEMP, 3, 12, IIO_TEMP),
258 MTK_PMIC_IIO_CHAN(MT6359, chip_temp, CHIP_TEMP, 4, 12, IIO_TEMP),
259 MTK_PMIC_IIO_CHAN(MT6359, acc_det, ACCDET, 5, 12, IIO_RESISTANCE),
260 MTK_PMIC_IIO_CHAN(MT6359, dcxo_v, VDCXO, 6, 12, IIO_VOLTAGE),
261 MTK_PMIC_IIO_CHAN(MT6359, tsx_temp, TSX_TEMP, 7, 15, IIO_TEMP),
262 MTK_PMIC_IIO_CHAN(MT6359, hp_ofs_cal, HPOFS_CAL, 9, 15, IIO_RESISTANCE),
263 MTK_PMIC_IIO_CHAN(MT6359, dcxo_temp, DCXO_TEMP, 10, 15, IIO_TEMP),
264 MTK_PMIC_IIO_CHAN(MT6359, bif_v, VBIF, 11, 12, IIO_VOLTAGE),
265 MTK_PMIC_IIO_CHAN(MT6359, vcore_temp, VCORE_TEMP, 30, 12, IIO_TEMP),
266 MTK_PMIC_IIO_CHAN(MT6359, vproc_temp, VPROC_TEMP, 31, 12, IIO_TEMP),
267 MTK_PMIC_IIO_CHAN(MT6359, vgpu_temp, VGPU_TEMP, 32, 12, IIO_TEMP),
269 /* Battery impedance channels */
270 MTK_PMIC_IIO_CHAN(MT6359, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
271 MTK_PMIC_IIO_CHAN(MT6359, batt_i, IBAT, 0, 15, IIO_CURRENT),
274 static const struct mtk_pmic_auxadc_chan mt6359_auxadc_ch_desc[] = {
275 MTK_PMIC_ADC_CHAN(BATADC, PMIC_AUXADC_RQST0, 0, 128, 7, 2),
276 MTK_PMIC_ADC_CHAN(BAT_TEMP, PMIC_AUXADC_RQST0, 3, 8, 5, 2),
277 MTK_PMIC_ADC_CHAN(CHIP_TEMP, PMIC_AUXADC_RQST0, 4, 8, 1, 1),
278 MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, 8, 1, 1),
279 MTK_PMIC_ADC_CHAN(VDCXO, PMIC_AUXADC_RQST0, 6, 8, 3, 2),
280 MTK_PMIC_ADC_CHAN(TSX_TEMP, PMIC_AUXADC_RQST0, 7, 128, 1, 1),
281 MTK_PMIC_ADC_CHAN(HPOFS_CAL, PMIC_AUXADC_RQST0, 9, 256, 1, 1),
282 MTK_PMIC_ADC_CHAN(DCXO_TEMP, PMIC_AUXADC_RQST0, 10, 16, 1, 1),
283 MTK_PMIC_ADC_CHAN(VBIF, PMIC_AUXADC_RQST0, 11, 8, 5, 2),
284 MTK_PMIC_ADC_CHAN(VCORE_TEMP, PMIC_AUXADC_RQST1, 8, 8, 1, 1),
285 MTK_PMIC_ADC_CHAN(VPROC_TEMP, PMIC_AUXADC_RQST1, 9, 8, 1, 1),
286 MTK_PMIC_ADC_CHAN(VGPU_TEMP, PMIC_AUXADC_RQST1, 10, 8, 1, 1),
288 /* Battery impedance channels */
289 MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 7, 2),
290 MTK_PMIC_ADC_CHAN(IBAT, 0, 0, 128, 7, 2),
293 static const u16 mt6359_auxadc_regs[] = {
294 [PMIC_FGADC_R_CON0] = 0x0d88,
295 [PMIC_HK_TOP_WKEY] = 0x0fb4,
296 [PMIC_HK_TOP_RST_CON0] = 0x0f90,
297 [PMIC_AUXADC_RQST0] = 0x1108,
298 [PMIC_AUXADC_RQST1] = 0x110a,
299 [PMIC_AUXADC_ADC0] = 0x1088,
300 [PMIC_AUXADC_IMP0] = 0x1208,
301 [PMIC_AUXADC_IMP1] = 0x120a,
302 [PMIC_AUXADC_IMP3] = 0x120e,
305 static void mt6358_stop_imp_conv(struct mt6359_auxadc *adc_dev)
307 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
308 struct regmap *regmap = adc_dev->regmap;
310 regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6358_IMP0_CLEAR);
311 regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6358_IMP0_CLEAR);
312 regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP1], MT6358_IMP1_AUTOREPEAT_EN);
313 regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_DCM_CON], MT6358_DCM_CK_SW_EN);
316 static int mt6358_start_imp_conv(struct mt6359_auxadc *adc_dev)
318 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
319 struct regmap *regmap = adc_dev->regmap;
320 u32 val;
321 int ret;
323 regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_DCM_CON], MT6358_DCM_CK_SW_EN);
324 regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP1], MT6358_IMP1_AUTOREPEAT_EN);
326 ret = regmap_read_poll_timeout(adc_dev->regmap, cinfo->regs[PMIC_AUXADC_IMP0],
327 val, val & MT6358_IMP0_IRQ_RDY,
328 IMP_POLL_DELAY_US, AUXADC_TIMEOUT_US);
329 if (ret) {
330 mt6358_stop_imp_conv(adc_dev);
331 return ret;
334 return 0;
337 static int mt6358_read_imp(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat)
339 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
340 struct regmap *regmap = adc_dev->regmap;
341 u16 reg_adc0 = cinfo->regs[PMIC_AUXADC_ADC0];
342 u32 val_v;
343 int ret;
345 ret = mt6358_start_imp_conv(adc_dev);
346 if (ret)
347 return ret;
349 /* Read the params before stopping */
350 regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v);
352 mt6358_stop_imp_conv(adc_dev);
354 if (vbat)
355 *vbat = val_v;
356 if (ibat)
357 *ibat = 0;
359 return 0;
362 static int mt6359_read_imp(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat)
364 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
365 struct regmap *regmap = adc_dev->regmap;
366 u32 val, val_v, val_i;
367 int ret;
369 /* Start conversion */
370 regmap_write(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6359_IMP0_CONV_EN);
371 ret = regmap_read_poll_timeout(regmap, cinfo->regs[PMIC_AUXADC_IMP1],
372 val, val & MT6359_IMP1_IRQ_RDY,
373 IMP_POLL_DELAY_US, AUXADC_TIMEOUT_US);
375 /* Stop conversion regardless of the result */
376 regmap_write(regmap, cinfo->regs[PMIC_AUXADC_IMP0], 0);
377 if (ret)
378 return ret;
380 /* If it succeeded, wait for the registers to be populated */
381 fsleep(IMP_STOP_DELAY_US);
383 ret = regmap_read(regmap, cinfo->regs[PMIC_AUXADC_IMP3], &val_v);
384 if (ret)
385 return ret;
387 ret = regmap_read(regmap, cinfo->regs[PMIC_FGADC_R_CON0], &val_i);
388 if (ret)
389 return ret;
391 if (vbat)
392 *vbat = val_v;
393 if (ibat)
394 *ibat = val_i;
396 return 0;
399 static const struct mtk_pmic_auxadc_info mt6357_chip_info = {
400 .model_name = "MT6357",
401 .channels = mt6357_auxadc_channels,
402 .num_channels = ARRAY_SIZE(mt6357_auxadc_channels),
403 .desc = mt6357_auxadc_ch_desc,
404 .regs = mt6357_auxadc_regs,
405 .imp_adc_num = MT6357_IMP_ADC_NUM,
406 .read_imp = mt6358_read_imp,
409 static const struct mtk_pmic_auxadc_info mt6358_chip_info = {
410 .model_name = "MT6358",
411 .channels = mt6358_auxadc_channels,
412 .num_channels = ARRAY_SIZE(mt6358_auxadc_channels),
413 .desc = mt6358_auxadc_ch_desc,
414 .regs = mt6358_auxadc_regs,
415 .imp_adc_num = MT6358_IMP_ADC_NUM,
416 .read_imp = mt6358_read_imp,
419 static const struct mtk_pmic_auxadc_info mt6359_chip_info = {
420 .model_name = "MT6359",
421 .channels = mt6359_auxadc_channels,
422 .num_channels = ARRAY_SIZE(mt6359_auxadc_channels),
423 .desc = mt6359_auxadc_ch_desc,
424 .regs = mt6359_auxadc_regs,
425 .sec_unlock_key = 0x6359,
426 .read_imp = mt6359_read_imp,
429 static void mt6359_auxadc_reset(struct mt6359_auxadc *adc_dev)
431 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
432 struct regmap *regmap = adc_dev->regmap;
434 /* Unlock HK_TOP writes */
435 if (cinfo->sec_unlock_key)
436 regmap_write(regmap, cinfo->regs[PMIC_HK_TOP_WKEY], cinfo->sec_unlock_key);
438 /* Assert ADC reset */
439 regmap_set_bits(regmap, cinfo->regs[PMIC_HK_TOP_RST_CON0], PMIC_RG_RESET_VAL);
441 /* De-assert ADC reset. No wait required, as pwrap takes care of that for us. */
442 regmap_clear_bits(regmap, cinfo->regs[PMIC_HK_TOP_RST_CON0], PMIC_RG_RESET_VAL);
444 /* Lock HK_TOP writes again */
445 if (cinfo->sec_unlock_key)
446 regmap_write(regmap, cinfo->regs[PMIC_HK_TOP_WKEY], 0);
449 static int mt6359_auxadc_read_adc(struct mt6359_auxadc *adc_dev,
450 const struct iio_chan_spec *chan, int *out)
452 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
453 const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index];
454 struct regmap *regmap = adc_dev->regmap;
455 u32 val;
456 int ret;
458 /* Request to start sampling for ADC channel */
459 ret = regmap_write(regmap, cinfo->regs[desc->req_idx], desc->req_mask);
460 if (ret)
461 return ret;
463 /* Wait until all samples are averaged */
464 fsleep(desc->num_samples * AUXADC_AVG_TIME_US);
466 ret = regmap_read_poll_timeout(regmap,
467 cinfo->regs[PMIC_AUXADC_ADC0] + (chan->address << 1),
468 val, val & PMIC_AUXADC_RDY_BIT,
469 AUXADC_POLL_DELAY_US, AUXADC_TIMEOUT_US);
470 if (ret)
471 return ret;
473 /* Stop sampling */
474 regmap_write(regmap, cinfo->regs[desc->req_idx], 0);
476 *out = val & GENMASK(chan->scan_type.realbits - 1, 0);
477 return 0;
480 static int mt6359_auxadc_read_label(struct iio_dev *indio_dev,
481 const struct iio_chan_spec *chan, char *label)
483 return sysfs_emit(label, "%s\n", chan->datasheet_name);
486 static int mt6359_auxadc_read_raw(struct iio_dev *indio_dev,
487 const struct iio_chan_spec *chan,
488 int *val, int *val2, long mask)
490 struct mt6359_auxadc *adc_dev = iio_priv(indio_dev);
491 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
492 const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index];
493 int ret;
495 if (mask == IIO_CHAN_INFO_SCALE) {
496 *val = desc->r_ratio.numerator * AUXADC_VOLT_FULL;
498 if (desc->r_ratio.denominator > 1) {
499 *val2 = desc->r_ratio.denominator;
500 return IIO_VAL_FRACTIONAL;
503 return IIO_VAL_INT;
506 scoped_guard(mutex, &adc_dev->lock) {
507 switch (chan->scan_index) {
508 case PMIC_AUXADC_CHAN_IBAT:
509 ret = adc_dev->chip_info->read_imp(adc_dev, NULL, val);
510 break;
511 case PMIC_AUXADC_CHAN_VBAT:
512 ret = adc_dev->chip_info->read_imp(adc_dev, val, NULL);
513 break;
514 default:
515 ret = mt6359_auxadc_read_adc(adc_dev, chan, val);
516 break;
520 if (ret) {
522 * If we get more than one timeout, it's possible that the
523 * AUXADC is stuck: perform a full reset to recover it.
525 if (ret == -ETIMEDOUT) {
526 if (adc_dev->timed_out) {
527 dev_warn(adc_dev->dev, "Resetting stuck ADC!\r\n");
528 mt6359_auxadc_reset(adc_dev);
530 adc_dev->timed_out = true;
532 return ret;
534 adc_dev->timed_out = false;
536 return IIO_VAL_INT;
539 static const struct iio_info mt6359_auxadc_iio_info = {
540 .read_label = mt6359_auxadc_read_label,
541 .read_raw = mt6359_auxadc_read_raw,
544 static int mt6359_auxadc_probe(struct platform_device *pdev)
546 struct device *dev = &pdev->dev;
547 struct device *mt6397_mfd_dev = dev->parent;
548 struct mt6359_auxadc *adc_dev;
549 struct iio_dev *indio_dev;
550 struct regmap *regmap;
551 int ret;
553 /* Regmap is from SoC PMIC Wrapper, parent of the mt6397 MFD */
554 regmap = dev_get_regmap(mt6397_mfd_dev->parent, NULL);
555 if (!regmap)
556 return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n");
558 indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_dev));
559 if (!indio_dev)
560 return -ENOMEM;
562 adc_dev = iio_priv(indio_dev);
563 adc_dev->regmap = regmap;
564 adc_dev->dev = dev;
566 adc_dev->chip_info = device_get_match_data(dev);
567 if (!adc_dev->chip_info)
568 return -EINVAL;
570 mutex_init(&adc_dev->lock);
572 mt6359_auxadc_reset(adc_dev);
574 indio_dev->name = adc_dev->chip_info->model_name;
575 indio_dev->info = &mt6359_auxadc_iio_info;
576 indio_dev->modes = INDIO_DIRECT_MODE;
577 indio_dev->channels = adc_dev->chip_info->channels;
578 indio_dev->num_channels = adc_dev->chip_info->num_channels;
580 ret = devm_iio_device_register(dev, indio_dev);
581 if (ret)
582 return dev_err_probe(dev, ret, "failed to register iio device\n");
584 return 0;
587 static const struct of_device_id mt6359_auxadc_of_match[] = {
588 { .compatible = "mediatek,mt6357-auxadc", .data = &mt6357_chip_info },
589 { .compatible = "mediatek,mt6358-auxadc", .data = &mt6358_chip_info },
590 { .compatible = "mediatek,mt6359-auxadc", .data = &mt6359_chip_info },
591 { /* sentinel */ }
593 MODULE_DEVICE_TABLE(of, mt6359_auxadc_of_match);
595 static struct platform_driver mt6359_auxadc_driver = {
596 .driver = {
597 .name = "mt6359-auxadc",
598 .of_match_table = mt6359_auxadc_of_match,
600 .probe = mt6359_auxadc_probe,
602 module_platform_driver(mt6359_auxadc_driver);
604 MODULE_LICENSE("GPL");
605 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
606 MODULE_DESCRIPTION("MediaTek MT6359 PMIC AUXADC Driver");