xref: /linux/drivers/iio/adc/88pm886-gpadc.c (revision 68a052239fc4b351e961f698b824f7654a346091)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2025, Duje Mihanović <duje@dujemihanovic.xyz>
4  */
5 
6 #include <linux/bits.h>
7 #include <linux/bug.h>
8 #include <linux/delay.h>
9 #include <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/i2c.h>
12 #include <linux/math.h>
13 #include <linux/mod_devicetable.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/types.h>
19 #include <linux/units.h>
20 
21 #include <asm/byteorder.h>
22 
23 #include <linux/iio/iio.h>
24 #include <linux/iio/types.h>
25 
26 #include <linux/mfd/88pm886.h>
27 
28 struct pm886_gpadc {
29 	struct regmap *map;
30 };
31 
32 enum pm886_gpadc_channel {
33 	VSC_CHAN,
34 	VCHG_PWR_CHAN,
35 	VCF_OUT_CHAN,
36 	VBAT_CHAN,
37 	VBAT_SLP_CHAN,
38 	VBUS_CHAN,
39 
40 	GPADC0_CHAN,
41 	GPADC1_CHAN,
42 	GPADC2_CHAN,
43 	GPADC3_CHAN,
44 
45 	GND_DET1_CHAN,
46 	GND_DET2_CHAN,
47 	MIC_DET_CHAN,
48 
49 	TINT_CHAN,
50 };
51 
52 static const int pm886_gpadc_regs[] = {
53 	[VSC_CHAN] = PM886_REG_GPADC_VSC,
54 	[VCHG_PWR_CHAN] = PM886_REG_GPADC_VCHG_PWR,
55 	[VCF_OUT_CHAN] = PM886_REG_GPADC_VCF_OUT,
56 	[VBAT_CHAN] = PM886_REG_GPADC_VBAT,
57 	[VBAT_SLP_CHAN] = PM886_REG_GPADC_VBAT_SLP,
58 	[VBUS_CHAN] = PM886_REG_GPADC_VBUS,
59 
60 	[GPADC0_CHAN] = PM886_REG_GPADC_GPADC0,
61 	[GPADC1_CHAN] = PM886_REG_GPADC_GPADC1,
62 	[GPADC2_CHAN] = PM886_REG_GPADC_GPADC2,
63 	[GPADC3_CHAN] = PM886_REG_GPADC_GPADC3,
64 
65 	[GND_DET1_CHAN] = PM886_REG_GPADC_GND_DET1,
66 	[GND_DET2_CHAN] = PM886_REG_GPADC_GND_DET2,
67 	[MIC_DET_CHAN] = PM886_REG_GPADC_MIC_DET,
68 
69 	[TINT_CHAN] = PM886_REG_GPADC_TINT,
70 };
71 
72 #define ADC_CHANNEL_VOLTAGE(index, lsb, name)		\
73 {							\
74 	.type = IIO_VOLTAGE,				\
75 	.indexed = 1,					\
76 	.channel = index,				\
77 	.address = lsb,					\
78 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
79 			      BIT(IIO_CHAN_INFO_SCALE),	\
80 	.datasheet_name = name,				\
81 }
82 
83 #define ADC_CHANNEL_RESISTANCE(index, lsb, name)		\
84 {								\
85 	.type = IIO_RESISTANCE,					\
86 	.indexed = 1,						\
87 	.channel = index,					\
88 	.address = lsb,						\
89 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
90 	.datasheet_name = name,					\
91 }
92 
93 #define ADC_CHANNEL_TEMPERATURE(index, lsb, name)		\
94 {								\
95 	.type = IIO_TEMP,					\
96 	.indexed = 1,						\
97 	.channel = index,					\
98 	.address = lsb,						\
99 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
100 			      BIT(IIO_CHAN_INFO_SCALE) |	\
101 			      BIT(IIO_CHAN_INFO_OFFSET),	\
102 	.datasheet_name = name,					\
103 }
104 
105 static const struct iio_chan_spec pm886_gpadc_channels[] = {
106 	ADC_CHANNEL_VOLTAGE(VSC_CHAN, 1367, "vsc"),
107 	ADC_CHANNEL_VOLTAGE(VCHG_PWR_CHAN, 1709, "vchg_pwr"),
108 	ADC_CHANNEL_VOLTAGE(VCF_OUT_CHAN, 1367, "vcf_out"),
109 	ADC_CHANNEL_VOLTAGE(VBAT_CHAN, 1367, "vbat"),
110 	ADC_CHANNEL_VOLTAGE(VBAT_SLP_CHAN, 1367, "vbat_slp"),
111 	ADC_CHANNEL_VOLTAGE(VBUS_CHAN, 1709, "vbus"),
112 
113 	ADC_CHANNEL_RESISTANCE(GPADC0_CHAN, 342, "gpadc0"),
114 	ADC_CHANNEL_RESISTANCE(GPADC1_CHAN, 342, "gpadc1"),
115 	ADC_CHANNEL_RESISTANCE(GPADC2_CHAN, 342, "gpadc2"),
116 	ADC_CHANNEL_RESISTANCE(GPADC3_CHAN, 342, "gpadc3"),
117 
118 	ADC_CHANNEL_VOLTAGE(GND_DET1_CHAN, 342, "gnddet1"),
119 	ADC_CHANNEL_VOLTAGE(GND_DET2_CHAN, 342, "gnddet2"),
120 	ADC_CHANNEL_VOLTAGE(MIC_DET_CHAN, 1367, "mic_det"),
121 
122 	ADC_CHANNEL_TEMPERATURE(TINT_CHAN, 104, "tint"),
123 };
124 
125 static const struct regmap_config pm886_gpadc_regmap_config = {
126 	.reg_bits = 8,
127 	.val_bits = 8,
128 	.max_register = PM886_GPADC_MAX_REGISTER,
129 };
130 
131 static int gpadc_get_raw(struct iio_dev *iio, enum pm886_gpadc_channel chan)
132 {
133 	struct pm886_gpadc *gpadc = iio_priv(iio);
134 	__be16 buf;
135 	int ret;
136 
137 	ret = regmap_bulk_read(gpadc->map, pm886_gpadc_regs[chan], &buf, sizeof(buf));
138 	if (ret)
139 		return ret;
140 
141 	return be16_to_cpu(buf) >> 4;
142 }
143 
144 static int
145 gpadc_set_bias(struct pm886_gpadc *gpadc, enum pm886_gpadc_channel chan, bool on)
146 {
147 	unsigned int gpadc_num = chan - GPADC0_CHAN;
148 	unsigned int bits = BIT(gpadc_num + 4) | BIT(gpadc_num);
149 
150 	return regmap_assign_bits(gpadc->map, PM886_REG_GPADC_CONFIG(0x14), bits, on);
151 }
152 
153 static int
154 gpadc_find_bias_current(struct iio_dev *iio, struct iio_chan_spec const *chan,
155 			unsigned int *raw_uV, unsigned int *raw_uA)
156 {
157 	struct pm886_gpadc *gpadc = iio_priv(iio);
158 	unsigned int gpadc_num = chan->channel - GPADC0_CHAN;
159 	unsigned int reg = PM886_REG_GPADC_CONFIG(0xb + gpadc_num);
160 	unsigned long lsb = chan->address;
161 	int ret;
162 
163 	for (unsigned int i = 0; i < PM886_GPADC_BIAS_LEVELS; i++) {
164 		ret = regmap_update_bits(gpadc->map, reg, GENMASK(3, 0), i);
165 		if (ret)
166 			return ret;
167 
168 		/* Wait for the new bias level to apply. */
169 		fsleep(5 * USEC_PER_MSEC);
170 
171 		*raw_uA = PM886_GPADC_INDEX_TO_BIAS_uA(i);
172 		*raw_uV = gpadc_get_raw(iio, chan->channel) * lsb;
173 
174 		/*
175 		 * Vendor kernel errors out above 1.25 V, but testing shows
176 		 * that the resistance of the battery detection channel (GPADC2
177 		 * on coreprimevelte) reaches about 1.4 MΩ when the battery is
178 		 * removed, which can't be measured with such a low upper
179 		 * limit. Therefore, to be able to detect the battery without
180 		 * ugly externs as used in the vendor fuel gauge driver,
181 		 * increase this limit a bit.
182 		 */
183 		if (WARN_ON(*raw_uV > 1500 * (MICRO / MILLI)))
184 			return -EIO;
185 
186 		/*
187 		 * Vendor kernel errors out under 300 mV, but for the same
188 		 * reason as above (except the channel hovers around 3.5 kΩ
189 		 * with battery present) reduce this limit.
190 		 */
191 		if (*raw_uV < 200 * (MICRO / MILLI)) {
192 			dev_dbg(&iio->dev, "bad bias for chan %d: %d uA @ %d uV\n",
193 				chan->channel, *raw_uA, *raw_uV);
194 			continue;
195 		}
196 
197 		dev_dbg(&iio->dev, "good bias for chan %d: %d uA @ %d uV\n",
198 			chan->channel, *raw_uA, *raw_uV);
199 		return 0;
200 	}
201 
202 	dev_err(&iio->dev, "failed to find good bias for chan %d\n", chan->channel);
203 	return -EINVAL;
204 }
205 
206 static int
207 gpadc_get_resistance_ohm(struct iio_dev *iio, struct iio_chan_spec const *chan)
208 {
209 	struct pm886_gpadc *gpadc = iio_priv(iio);
210 	unsigned int raw_uV, raw_uA;
211 	int ret;
212 
213 	ret = gpadc_set_bias(gpadc, chan->channel, true);
214 	if (ret)
215 		goto out;
216 
217 	ret = gpadc_find_bias_current(iio, chan, &raw_uV, &raw_uA);
218 	if (ret)
219 		goto out;
220 
221 	ret = DIV_ROUND_CLOSEST(raw_uV, raw_uA);
222 out:
223 	gpadc_set_bias(gpadc, chan->channel, false);
224 	return ret;
225 }
226 
227 static int
228 __pm886_gpadc_read_raw(struct iio_dev *iio, struct iio_chan_spec const *chan,
229 		       int *val, int *val2, long mask)
230 {
231 	unsigned long lsb = chan->address;
232 
233 	switch (mask) {
234 	case IIO_CHAN_INFO_RAW:
235 		*val = gpadc_get_raw(iio, chan->channel);
236 		if (*val < 0)
237 			return *val;
238 
239 		return IIO_VAL_INT;
240 	case IIO_CHAN_INFO_SCALE:
241 		*val = lsb;
242 
243 		if (chan->type == IIO_VOLTAGE) {
244 			*val2 = MILLI;
245 			return IIO_VAL_FRACTIONAL;
246 		} else {
247 			return IIO_VAL_INT;
248 		}
249 	case IIO_CHAN_INFO_OFFSET:
250 		/* Raw value is 104 millikelvin/LSB, convert it to 104 millicelsius/LSB */
251 		*val = ABSOLUTE_ZERO_MILLICELSIUS;
252 		*val2 = lsb;
253 		return IIO_VAL_FRACTIONAL;
254 	case IIO_CHAN_INFO_PROCESSED:
255 		*val = gpadc_get_resistance_ohm(iio, chan);
256 		if (*val < 0)
257 			return *val;
258 
259 		return IIO_VAL_INT;
260 	default:
261 		return -EINVAL;
262 	}
263 }
264 
265 static int pm886_gpadc_read_raw(struct iio_dev *iio, struct iio_chan_spec const *chan,
266 				int *val, int *val2, long mask)
267 {
268 	struct device *dev = iio->dev.parent;
269 	int ret;
270 
271 	ret = pm_runtime_resume_and_get(dev);
272 	if (ret)
273 		return ret;
274 
275 	ret = __pm886_gpadc_read_raw(iio, chan, val, val2, mask);
276 
277 	pm_runtime_put_autosuspend(dev);
278 	return ret;
279 }
280 
281 static int pm886_gpadc_hw_enable(struct regmap *map)
282 {
283 	const u8 config[] = {
284 		PM886_GPADC_CONFIG1_EN_ALL,
285 		PM886_GPADC_CONFIG2_EN_ALL,
286 		PM886_GPADC_GND_DET2_EN,
287 	};
288 	int ret;
289 
290 	/* Enable the ADC block. */
291 	ret = regmap_set_bits(map, PM886_REG_GPADC_CONFIG(0x6), BIT(0));
292 	if (ret)
293 		return ret;
294 
295 	/* Enable all channels. */
296 	return regmap_bulk_write(map, PM886_REG_GPADC_CONFIG(0x1), config, ARRAY_SIZE(config));
297 }
298 
299 static int pm886_gpadc_hw_disable(struct regmap *map)
300 {
301 	return regmap_clear_bits(map, PM886_REG_GPADC_CONFIG(0x6), BIT(0));
302 }
303 
304 static const struct iio_info pm886_gpadc_iio_info = {
305 	.read_raw = pm886_gpadc_read_raw,
306 };
307 
308 static int pm886_gpadc_probe(struct platform_device *pdev)
309 {
310 	struct device *dev = &pdev->dev;
311 	struct pm886_chip *chip = dev_get_drvdata(dev->parent);
312 	struct i2c_client *client = chip->client;
313 	struct pm886_gpadc *gpadc;
314 	struct i2c_client *page;
315 	struct iio_dev *iio;
316 	int ret;
317 
318 	iio = devm_iio_device_alloc(dev, sizeof(*gpadc));
319 	if (!iio)
320 		return -ENOMEM;
321 
322 	gpadc = iio_priv(iio);
323 	dev_set_drvdata(dev, iio);
324 
325 	page = devm_i2c_new_dummy_device(dev, client->adapter,
326 					 client->addr + PM886_PAGE_OFFSET_GPADC);
327 	if (IS_ERR(page))
328 		return dev_err_probe(dev, PTR_ERR(page), "Failed to initialize GPADC page\n");
329 
330 	gpadc->map = devm_regmap_init_i2c(page, &pm886_gpadc_regmap_config);
331 	if (IS_ERR(gpadc->map))
332 		return dev_err_probe(dev, PTR_ERR(gpadc->map),
333 				     "Failed to initialize GPADC regmap\n");
334 
335 	iio->name = "88pm886-gpadc";
336 	iio->modes = INDIO_DIRECT_MODE;
337 	iio->info = &pm886_gpadc_iio_info;
338 	iio->channels = pm886_gpadc_channels;
339 	iio->num_channels = ARRAY_SIZE(pm886_gpadc_channels);
340 	device_set_node(&iio->dev, dev_fwnode(dev->parent));
341 
342 	ret = devm_pm_runtime_enable(dev);
343 	if (ret)
344 		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
345 
346 	pm_runtime_set_autosuspend_delay(dev, 50);
347 	pm_runtime_use_autosuspend(dev);
348 	ret = devm_iio_device_register(dev, iio);
349 	if (ret)
350 		return dev_err_probe(dev, ret, "Failed to register ADC\n");
351 
352 	return 0;
353 }
354 
355 static int pm886_gpadc_runtime_resume(struct device *dev)
356 {
357 	struct iio_dev *iio = dev_get_drvdata(dev);
358 	struct pm886_gpadc *gpadc = iio_priv(iio);
359 
360 	return pm886_gpadc_hw_enable(gpadc->map);
361 }
362 
363 static int pm886_gpadc_runtime_suspend(struct device *dev)
364 {
365 	struct iio_dev *iio = dev_get_drvdata(dev);
366 	struct pm886_gpadc *gpadc = iio_priv(iio);
367 
368 	return pm886_gpadc_hw_disable(gpadc->map);
369 }
370 
371 static DEFINE_RUNTIME_DEV_PM_OPS(pm886_gpadc_pm_ops,
372 				 pm886_gpadc_runtime_suspend,
373 				 pm886_gpadc_runtime_resume, NULL);
374 
375 static const struct platform_device_id pm886_gpadc_id[] = {
376 	{ "88pm886-gpadc" },
377 	{ }
378 };
379 MODULE_DEVICE_TABLE(platform, pm886_gpadc_id);
380 
381 static struct platform_driver pm886_gpadc_driver = {
382 	.driver = {
383 		.name = "88pm886-gpadc",
384 		.pm = pm_ptr(&pm886_gpadc_pm_ops),
385 	},
386 	.probe = pm886_gpadc_probe,
387 	.id_table = pm886_gpadc_id,
388 };
389 module_platform_driver(pm886_gpadc_driver);
390 
391 MODULE_AUTHOR("Duje Mihanović <duje@dujemihanovic.xyz>");
392 MODULE_DESCRIPTION("Marvell 88PM886 GPADC driver");
393 MODULE_LICENSE("GPL");
394