1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2022 Richtek Technology Corp.
5 * Author: ChiaEn Wu <chiaen_wu@richtek.com>
8 #include <linux/bits.h>
9 #include <linux/bitfield.h>
10 #include <linux/iio/iio.h>
11 #include <linux/kernel.h>
12 #include <linux/mod_devicetable.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
15 #include <linux/platform_device.h>
16 #include <linux/regmap.h>
17 #include <linux/sysfs.h>
18 #include <linux/units.h>
20 #include <dt-bindings/iio/adc/mediatek,mt6370_adc.h>
22 #define MT6370_REG_DEV_INFO 0x100
23 #define MT6370_REG_CHG_CTRL3 0x113
24 #define MT6370_REG_CHG_CTRL7 0x117
25 #define MT6370_REG_CHG_ADC 0x121
26 #define MT6370_REG_ADC_DATA_H 0x14C
28 #define MT6370_ADC_START_MASK BIT(0)
29 #define MT6370_ADC_IN_SEL_MASK GENMASK(7, 4)
30 #define MT6370_AICR_ICHG_MASK GENMASK(7, 2)
31 #define MT6370_VENID_MASK GENMASK(7, 4)
33 #define MT6370_AICR_100_mA 0x0
34 #define MT6370_AICR_150_mA 0x1
35 #define MT6370_AICR_200_mA 0x2
36 #define MT6370_AICR_250_mA 0x3
37 #define MT6370_AICR_300_mA 0x4
38 #define MT6370_AICR_350_mA 0x5
40 #define MT6370_ICHG_100_mA 0x0
41 #define MT6370_ICHG_200_mA 0x1
42 #define MT6370_ICHG_300_mA 0x2
43 #define MT6370_ICHG_400_mA 0x3
44 #define MT6370_ICHG_500_mA 0x4
45 #define MT6370_ICHG_600_mA 0x5
46 #define MT6370_ICHG_700_mA 0x6
47 #define MT6370_ICHG_800_mA 0x7
49 #define ADC_CONV_TIME_MS 35
50 #define ADC_CONV_POLLING_TIME_US 1000
52 #define MT6370_VID_RT5081 0x8
53 #define MT6370_VID_RT5081A 0xA
54 #define MT6370_VID_MT6370 0xE
56 struct mt6370_adc_data
{
58 struct regmap
*regmap
;
60 * This mutex lock is for preventing the different ADC channels
61 * from being read at the same time.
63 struct mutex adc_lock
;
67 static int mt6370_adc_read_channel(struct mt6370_adc_data
*priv
, int chan
,
68 unsigned long addr
, int *val
)
74 mutex_lock(&priv
->adc_lock
);
76 reg_val
= MT6370_ADC_START_MASK
|
77 FIELD_PREP(MT6370_ADC_IN_SEL_MASK
, addr
);
78 ret
= regmap_write(priv
->regmap
, MT6370_REG_CHG_ADC
, reg_val
);
82 msleep(ADC_CONV_TIME_MS
);
84 ret
= regmap_read_poll_timeout(priv
->regmap
,
85 MT6370_REG_CHG_ADC
, reg_val
,
86 !(reg_val
& MT6370_ADC_START_MASK
),
87 ADC_CONV_POLLING_TIME_US
,
88 ADC_CONV_TIME_MS
* MILLI
* 3);
90 dev_err(priv
->dev
, "Failed to read ADC register (%d)\n", ret
);
94 ret
= regmap_raw_read(priv
->regmap
, MT6370_REG_ADC_DATA_H
,
95 &be_val
, sizeof(be_val
));
99 *val
= be16_to_cpu(be_val
);
103 mutex_unlock(&priv
->adc_lock
);
108 static int mt6370_adc_get_ibus_scale(struct mt6370_adc_data
*priv
)
111 case MT6370_VID_RT5081
:
112 case MT6370_VID_RT5081A
:
113 case MT6370_VID_MT6370
:
120 static int mt6370_adc_get_ibat_scale(struct mt6370_adc_data
*priv
)
123 case MT6370_VID_RT5081
:
124 case MT6370_VID_RT5081A
:
125 case MT6370_VID_MT6370
:
132 static int mt6370_adc_read_scale(struct mt6370_adc_data
*priv
,
133 int chan
, int *val1
, int *val2
)
135 unsigned int reg_val
;
139 case MT6370_CHAN_VBAT
:
140 case MT6370_CHAN_VSYS
:
141 case MT6370_CHAN_CHG_VDDP
:
144 case MT6370_CHAN_IBUS
:
145 ret
= regmap_read(priv
->regmap
, MT6370_REG_CHG_CTRL3
, ®_val
);
149 reg_val
= FIELD_GET(MT6370_AICR_ICHG_MASK
, reg_val
);
151 case MT6370_AICR_100_mA
:
152 case MT6370_AICR_150_mA
:
153 case MT6370_AICR_200_mA
:
154 case MT6370_AICR_250_mA
:
155 case MT6370_AICR_300_mA
:
156 case MT6370_AICR_350_mA
:
157 *val1
= mt6370_adc_get_ibus_scale(priv
);
166 return IIO_VAL_FRACTIONAL
;
167 case MT6370_CHAN_IBAT
:
168 ret
= regmap_read(priv
->regmap
, MT6370_REG_CHG_CTRL7
, ®_val
);
172 reg_val
= FIELD_GET(MT6370_AICR_ICHG_MASK
, reg_val
);
174 case MT6370_ICHG_100_mA
:
175 case MT6370_ICHG_200_mA
:
176 case MT6370_ICHG_300_mA
:
177 case MT6370_ICHG_400_mA
:
180 case MT6370_ICHG_500_mA
:
181 case MT6370_ICHG_600_mA
:
182 case MT6370_ICHG_700_mA
:
183 case MT6370_ICHG_800_mA
:
184 *val1
= mt6370_adc_get_ibat_scale(priv
);
193 return IIO_VAL_FRACTIONAL
;
194 case MT6370_CHAN_VBUSDIV5
:
197 case MT6370_CHAN_VBUSDIV2
:
200 case MT6370_CHAN_TS_BAT
:
203 return IIO_VAL_FRACTIONAL
;
204 case MT6370_CHAN_TEMP_JC
:
212 static int mt6370_adc_read_offset(struct mt6370_adc_data
*priv
,
220 static int mt6370_adc_read_raw(struct iio_dev
*iio_dev
,
221 const struct iio_chan_spec
*chan
,
222 int *val
, int *val2
, long mask
)
224 struct mt6370_adc_data
*priv
= iio_priv(iio_dev
);
227 case IIO_CHAN_INFO_RAW
:
228 return mt6370_adc_read_channel(priv
, chan
->channel
,
230 case IIO_CHAN_INFO_SCALE
:
231 return mt6370_adc_read_scale(priv
, chan
->channel
, val
, val2
);
232 case IIO_CHAN_INFO_OFFSET
:
233 return mt6370_adc_read_offset(priv
, chan
->channel
, val
);
239 static const char * const mt6370_channel_labels
[MT6370_CHAN_MAX
] = {
240 [MT6370_CHAN_VBUSDIV5
] = "vbusdiv5",
241 [MT6370_CHAN_VBUSDIV2
] = "vbusdiv2",
242 [MT6370_CHAN_VSYS
] = "vsys",
243 [MT6370_CHAN_VBAT
] = "vbat",
244 [MT6370_CHAN_TS_BAT
] = "ts_bat",
245 [MT6370_CHAN_IBUS
] = "ibus",
246 [MT6370_CHAN_IBAT
] = "ibat",
247 [MT6370_CHAN_CHG_VDDP
] = "chg_vddp",
248 [MT6370_CHAN_TEMP_JC
] = "temp_jc",
251 static int mt6370_adc_read_label(struct iio_dev
*iio_dev
,
252 struct iio_chan_spec
const *chan
, char *label
)
254 return sysfs_emit(label
, "%s\n", mt6370_channel_labels
[chan
->channel
]);
257 static const struct iio_info mt6370_adc_iio_info
= {
258 .read_raw
= mt6370_adc_read_raw
,
259 .read_label
= mt6370_adc_read_label
,
262 #define MT6370_ADC_CHAN(_idx, _type, _addr, _extra_info) { \
264 .channel = MT6370_CHAN_##_idx, \
266 .scan_index = MT6370_CHAN_##_idx, \
268 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
269 BIT(IIO_CHAN_INFO_SCALE) | \
273 static const struct iio_chan_spec mt6370_adc_channels
[] = {
274 MT6370_ADC_CHAN(VBUSDIV5
, IIO_VOLTAGE
, 1, 0),
275 MT6370_ADC_CHAN(VBUSDIV2
, IIO_VOLTAGE
, 2, 0),
276 MT6370_ADC_CHAN(VSYS
, IIO_VOLTAGE
, 3, 0),
277 MT6370_ADC_CHAN(VBAT
, IIO_VOLTAGE
, 4, 0),
278 MT6370_ADC_CHAN(TS_BAT
, IIO_VOLTAGE
, 6, 0),
279 MT6370_ADC_CHAN(IBUS
, IIO_CURRENT
, 8, 0),
280 MT6370_ADC_CHAN(IBAT
, IIO_CURRENT
, 9, 0),
281 MT6370_ADC_CHAN(CHG_VDDP
, IIO_VOLTAGE
, 11, 0),
282 MT6370_ADC_CHAN(TEMP_JC
, IIO_TEMP
, 12, BIT(IIO_CHAN_INFO_OFFSET
)),
285 static int mt6370_get_vendor_info(struct mt6370_adc_data
*priv
)
287 unsigned int dev_info
;
290 ret
= regmap_read(priv
->regmap
, MT6370_REG_DEV_INFO
, &dev_info
);
294 priv
->vid
= FIELD_GET(MT6370_VENID_MASK
, dev_info
);
299 static int mt6370_adc_probe(struct platform_device
*pdev
)
301 struct device
*dev
= &pdev
->dev
;
302 struct mt6370_adc_data
*priv
;
303 struct iio_dev
*indio_dev
;
304 struct regmap
*regmap
;
307 regmap
= dev_get_regmap(pdev
->dev
.parent
, NULL
);
309 return dev_err_probe(dev
, -ENODEV
, "Failed to get regmap\n");
311 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*priv
));
315 priv
= iio_priv(indio_dev
);
317 priv
->regmap
= regmap
;
318 mutex_init(&priv
->adc_lock
);
320 ret
= mt6370_get_vendor_info(priv
);
322 return dev_err_probe(dev
, ret
, "Failed to get vid\n");
324 ret
= regmap_write(priv
->regmap
, MT6370_REG_CHG_ADC
, 0);
326 return dev_err_probe(dev
, ret
, "Failed to reset ADC\n");
328 indio_dev
->name
= "mt6370-adc";
329 indio_dev
->info
= &mt6370_adc_iio_info
;
330 indio_dev
->modes
= INDIO_DIRECT_MODE
;
331 indio_dev
->channels
= mt6370_adc_channels
;
332 indio_dev
->num_channels
= ARRAY_SIZE(mt6370_adc_channels
);
334 return devm_iio_device_register(dev
, indio_dev
);
337 static const struct of_device_id mt6370_adc_of_id
[] = {
338 { .compatible
= "mediatek,mt6370-adc", },
341 MODULE_DEVICE_TABLE(of
, mt6370_adc_of_id
);
343 static struct platform_driver mt6370_adc_driver
= {
345 .name
= "mt6370-adc",
346 .of_match_table
= mt6370_adc_of_id
,
348 .probe
= mt6370_adc_probe
,
350 module_platform_driver(mt6370_adc_driver
);
352 MODULE_AUTHOR("ChiaEn Wu <chiaen_wu@richtek.com>");
353 MODULE_DESCRIPTION("MT6370 ADC Driver");
354 MODULE_LICENSE("GPL v2");