Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Mar 24-27, 2025, special US time zones
Register
Loading...
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * MediaTek MT6359 PMIC AUXADC IIO driver
  4 *
  5 * Copyright (c) 2021 MediaTek Inc.
  6 * Copyright (c) 2024 Collabora Ltd
  7 * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
  8 */
  9
 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>
 19
 20#include <linux/iio/iio.h>
 21
 22#include <linux/mfd/mt6397/core.h>
 23
 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>
 27
 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
 34
 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
 40
 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)
 45
 46#define MT6359_IMP0_CONV_EN		BIT(0)
 47#define MT6359_IMP1_IRQ_RDY		BIT(15)
 48
 49enum 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
 61};
 62
 63enum 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
 82};
 83
 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
 91 */
 92struct 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;
 98};
 99
100/**
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
106 */
107struct mtk_pmic_auxadc_chan {
108	u8 req_idx;
109	u16 req_mask;
110	u16 num_samples;
111	struct u8_fract r_ratio;
112};
113
114/**
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
124 */
125struct 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);
134};
135
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 }					\
142	}
143
144#define MTK_PMIC_IIO_CHAN(_model, _name, _ch_idx, _adc_idx, _nbits, _ch_type)	\
145{										\
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)	\
159}
160
161static 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),
174
175	/* Battery impedance channels */
176	MTK_PMIC_IIO_CHAN(MT6357, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
177};
178
179static 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),
192
193	/* Battery impedance channels */
194	MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 3, 1),
195};
196
197static 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,
205};
206
207static 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),
221
222	/* Battery impedance channels */
223	MTK_PMIC_IIO_CHAN(MT6358, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
224};
225
226static 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),
240
241	/* Battery impedance channels */
242	MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 7, 2),
243};
244
245static 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,
253};
254
255static 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),
268
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),
272};
273
274static 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),
287
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),
291};
292
293static 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,
303};
304
305static void mt6358_stop_imp_conv(struct mt6359_auxadc *adc_dev)
306{
307	const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
308	struct regmap *regmap = adc_dev->regmap;
309
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);
314}
315
316static int mt6358_start_imp_conv(struct mt6359_auxadc *adc_dev)
317{
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;
322
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);
325
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;
332	}
333
334	return 0;
335}
336
337static int mt6358_read_imp(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat)
338{
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;
344
345	ret = mt6358_start_imp_conv(adc_dev);
346	if (ret)
347		return ret;
348
349	/* Read the params before stopping */
350	regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v);
351
352	mt6358_stop_imp_conv(adc_dev);
353
354	if (vbat)
355		*vbat = val_v;
356	if (ibat)
357		*ibat = 0;
358
359	return 0;
360}
361
362static int mt6359_read_imp(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat)
363{
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;
368
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);
374
375	/* Stop conversion regardless of the result */
376	regmap_write(regmap, cinfo->regs[PMIC_AUXADC_IMP0], 0);
377	if (ret)
378		return ret;
379
380	/* If it succeeded, wait for the registers to be populated */
381	fsleep(IMP_STOP_DELAY_US);
382
383	ret = regmap_read(regmap, cinfo->regs[PMIC_AUXADC_IMP3], &val_v);
384	if (ret)
385		return ret;
386
387	ret = regmap_read(regmap, cinfo->regs[PMIC_FGADC_R_CON0], &val_i);
388	if (ret)
389		return ret;
390
391	if (vbat)
392		*vbat = val_v;
393	if (ibat)
394		*ibat = val_i;
395
396	return 0;
397}
398
399static 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,
407};
408
409static 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,
417};
418
419static 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,
427};
428
429static void mt6359_auxadc_reset(struct mt6359_auxadc *adc_dev)
430{
431	const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
432	struct regmap *regmap = adc_dev->regmap;
433
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);
437
438	/* Assert ADC reset */
439	regmap_set_bits(regmap, cinfo->regs[PMIC_HK_TOP_RST_CON0], PMIC_RG_RESET_VAL);
440
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);
443
444	/* Lock HK_TOP writes again */
445	if (cinfo->sec_unlock_key)
446		regmap_write(regmap, cinfo->regs[PMIC_HK_TOP_WKEY], 0);
447}
448
449static int mt6359_auxadc_read_adc(struct mt6359_auxadc *adc_dev,
450				  const struct iio_chan_spec *chan, int *out)
451{
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;
457
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;
462
463	/* Wait until all samples are averaged */
464	fsleep(desc->num_samples * AUXADC_AVG_TIME_US);
465
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;
472
473	/* Stop sampling */
474	regmap_write(regmap, cinfo->regs[desc->req_idx], 0);
475
476	*out = val & GENMASK(chan->scan_type.realbits - 1, 0);
477	return 0;
478}
479
480static int mt6359_auxadc_read_label(struct iio_dev *indio_dev,
481				    const struct iio_chan_spec *chan, char *label)
482{
483	return sysfs_emit(label, "%s\n", chan->datasheet_name);
484}
485
486static int mt6359_auxadc_read_raw(struct iio_dev *indio_dev,
487				  const struct iio_chan_spec *chan,
488				  int *val, int *val2, long mask)
489{
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;
494
495	if (mask == IIO_CHAN_INFO_SCALE) {
496		*val = desc->r_ratio.numerator * AUXADC_VOLT_FULL;
497
498		if (desc->r_ratio.denominator > 1) {
499			*val2 = desc->r_ratio.denominator;
500			return IIO_VAL_FRACTIONAL;
501		}
502
503		return IIO_VAL_INT;
504	}
505
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;
517		}
518	}
519
520	if (ret) {
521		/*
522		 * If we get more than one timeout, it's possible that the
523		 * AUXADC is stuck: perform a full reset to recover it.
524		 */
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);
529			}
530			adc_dev->timed_out = true;
531		}
532		return ret;
533	}
534	adc_dev->timed_out = false;
535
536	return IIO_VAL_INT;
537}
538
539static const struct iio_info mt6359_auxadc_iio_info = {
540	.read_label = mt6359_auxadc_read_label,
541	.read_raw = mt6359_auxadc_read_raw,
542};
543
544static int mt6359_auxadc_probe(struct platform_device *pdev)
545{
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;
552
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");
557
558	indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_dev));
559	if (!indio_dev)
560		return -ENOMEM;
561
562	adc_dev = iio_priv(indio_dev);
563	adc_dev->regmap = regmap;
564	adc_dev->dev = dev;
565
566	adc_dev->chip_info = device_get_match_data(dev);
567	if (!adc_dev->chip_info)
568		return -EINVAL;
569
570	mutex_init(&adc_dev->lock);
571
572	mt6359_auxadc_reset(adc_dev);
573
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;
579
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");
583
584	return 0;
585}
586
587static 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 */ }
592};
593MODULE_DEVICE_TABLE(of, mt6359_auxadc_of_match);
594
595static struct platform_driver mt6359_auxadc_driver = {
596	.driver = {
597		.name = "mt6359-auxadc",
598		.of_match_table = mt6359_auxadc_of_match,
599	},
600	.probe	= mt6359_auxadc_probe,
601};
602module_platform_driver(mt6359_auxadc_driver);
603
604MODULE_LICENSE("GPL");
605MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
606MODULE_DESCRIPTION("MediaTek MT6359 PMIC AUXADC Driver");