File Index
Files and directories
Sign in
FILE

sun4i-gpadc-iio.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/adc/sun4i-gpadc-iio.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
  3 *
  4 * Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
  5 *
  6 * The Allwinner SoCs all have an ADC that can also act as a touchscreen
  7 * controller and a thermal sensor.
  8 * The thermal sensor works only when the ADC acts as a touchscreen controller
  9 * and is configured to throw an interrupt every fixed periods of time (let say
 10 * every X seconds).
 11 * One would be tempted to disable the IP on the hardware side rather than
 12 * disabling interrupts to save some power but that resets the internal clock of
 13 * the IP, resulting in having to wait X seconds every time we want to read the
 14 * value of the thermal sensor.
 15 * This is also the reason of using autosuspend in pm_runtime. If there was no
 16 * autosuspend, the thermal sensor would need X seconds after every
 17 * pm_runtime_get_sync to get a value from the ADC. The autosuspend allows the
 18 * thermal sensor to be requested again in a certain time span before it gets
 19 * shutdown for not being used.
 20 */
 21
 22#include <linux/completion.h>
 23#include <linux/interrupt.h>
 24#include <linux/io.h>
 25#include <linux/module.h>
 26#include <linux/of.h>
 27#include <linux/platform_device.h>
 28#include <linux/pm_runtime.h>
 29#include <linux/regmap.h>
 30#include <linux/thermal.h>
 31#include <linux/delay.h>
 32
 33#include <linux/iio/iio.h>
 34#include <linux/iio/driver.h>
 35#include <linux/iio/machine.h>
 36#include <linux/mfd/sun4i-gpadc.h>
 37
 38static unsigned int sun4i_gpadc_chan_select(unsigned int chan)
 39{
 40	return SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
 41}
 42
 43static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
 44{
 45	return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
 46}
 47
 48struct gpadc_data {
 49	int		temp_offset;
 50	int		temp_scale;
 51	unsigned int	tp_mode_en;
 52	unsigned int	tp_adc_select;
 53	unsigned int	(*adc_chan_select)(unsigned int chan);
 54	unsigned int	adc_chan_mask;
 55};
 56
 57static const struct gpadc_data sun4i_gpadc_data = {
 58	.temp_offset = -1932,
 59	.temp_scale = 133,
 60	.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
 61	.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
 62	.adc_chan_select = &sun4i_gpadc_chan_select,
 63	.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
 64};
 65
 66static const struct gpadc_data sun5i_gpadc_data = {
 67	.temp_offset = -1447,
 68	.temp_scale = 100,
 69	.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
 70	.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
 71	.adc_chan_select = &sun4i_gpadc_chan_select,
 72	.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
 73};
 74
 75static const struct gpadc_data sun6i_gpadc_data = {
 76	.temp_offset = -1623,
 77	.temp_scale = 167,
 78	.tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
 79	.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
 80	.adc_chan_select = &sun6i_gpadc_chan_select,
 81	.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
 82};
 83
 84static const struct gpadc_data sun8i_a33_gpadc_data = {
 85	.temp_offset = -1662,
 86	.temp_scale = 162,
 87	.tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
 88};
 89
 90struct sun4i_gpadc_iio {
 91	struct iio_dev			*indio_dev;
 92	struct completion		completion;
 93	int				temp_data;
 94	u32				adc_data;
 95	struct regmap			*regmap;
 96	unsigned int			fifo_data_irq;
 97	atomic_t			ignore_fifo_data_irq;
 98	unsigned int			temp_data_irq;
 99	atomic_t			ignore_temp_data_irq;
100	const struct gpadc_data		*data;
101	bool				no_irq;
102	/* prevents concurrent reads of temperature and ADC */
103	struct mutex			mutex;
104	struct thermal_zone_device	*tzd;
105	struct device			*sensor_device;
106};
107
108#define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) {		\
109	.type = IIO_VOLTAGE,					\
110	.indexed = 1,						\
111	.channel = _channel,					\
112	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
113	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
114	.datasheet_name = _name,				\
115}
116
117static const struct iio_map sun4i_gpadc_hwmon_maps[] = {
118	IIO_MAP("temp_adc", "iio_hwmon.0", NULL),
119	{ }
120};
121
122static const struct iio_chan_spec sun4i_gpadc_channels[] = {
123	SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
124	SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
125	SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
126	SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
127	{
128		.type = IIO_TEMP,
129		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
130				      BIT(IIO_CHAN_INFO_SCALE) |
131				      BIT(IIO_CHAN_INFO_OFFSET),
132		.datasheet_name = "temp_adc",
133	},
134};
135
136static const struct iio_chan_spec sun4i_gpadc_channels_no_temp[] = {
137	SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
138	SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
139	SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
140	SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
141};
142
143static const struct iio_chan_spec sun8i_a33_gpadc_channels[] = {
144	{
145		.type = IIO_TEMP,
146		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
147				      BIT(IIO_CHAN_INFO_SCALE) |
148				      BIT(IIO_CHAN_INFO_OFFSET),
149		.datasheet_name = "temp_adc",
150	},
151};
152
153static const struct regmap_config sun4i_gpadc_regmap_config = {
154	.reg_bits = 32,
155	.val_bits = 32,
156	.reg_stride = 4,
157};
158
159static int sun4i_prepare_for_irq(struct iio_dev *indio_dev, int channel,
160				 unsigned int irq)
161{
162	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
163	int ret;
164	u32 reg;
165
166	pm_runtime_get_sync(indio_dev->dev.parent);
167
168	reinit_completion(&info->completion);
169
170	ret = regmap_write(info->regmap, SUN4I_GPADC_INT_FIFOC,
171			   SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) |
172			   SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH);
173	if (ret)
174		return ret;
175
176	ret = regmap_read(info->regmap, SUN4I_GPADC_CTRL1, &reg);
177	if (ret)
178		return ret;
179
180	if (irq == info->fifo_data_irq) {
181		ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
182				   info->data->tp_mode_en |
183				   info->data->tp_adc_select |
184				   info->data->adc_chan_select(channel));
185		/*
186		 * When the IP changes channel, it needs a bit of time to get
187		 * correct values.
188		 */
189		if ((reg & info->data->adc_chan_mask) !=
190			 info->data->adc_chan_select(channel))
191			mdelay(10);
192
193	} else {
194		/*
195		 * The temperature sensor returns valid data only when the ADC
196		 * operates in touchscreen mode.
197		 */
198		ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
199				   info->data->tp_mode_en);
200	}
201
202	if (ret)
203		return ret;
204
205	/*
206	 * When the IP changes mode between ADC or touchscreen, it
207	 * needs a bit of time to get correct values.
208	 */
209	if ((reg & info->data->tp_adc_select) != info->data->tp_adc_select)
210		mdelay(100);
211
212	return 0;
213}
214
215static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
216			    unsigned int irq)
217{
218	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
219	int ret;
220
221	mutex_lock(&info->mutex);
222
223	ret = sun4i_prepare_for_irq(indio_dev, channel, irq);
224	if (ret)
225		goto err;
226
227	enable_irq(irq);
228
229	/*
230	 * The temperature sensor throws an interruption periodically (currently
231	 * set at periods of ~0.6s in sun4i_gpadc_runtime_resume). A 1s delay
232	 * makes sure an interruption occurs in normal conditions. If it doesn't
233	 * occur, then there is a timeout.
234	 */
235	if (!wait_for_completion_timeout(&info->completion,
236					 msecs_to_jiffies(1000))) {
237		ret = -ETIMEDOUT;
238		goto err;
239	}
240
241	if (irq == info->fifo_data_irq)
242		*val = info->adc_data;
243	else
244		*val = info->temp_data;
245
246	ret = 0;
247
248err:
249	pm_runtime_put_autosuspend(indio_dev->dev.parent);
250	disable_irq(irq);
251	mutex_unlock(&info->mutex);
252
253	return ret;
254}
255
256static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
257				int *val)
258{
259	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
260
261	return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
262}
263
264static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
265{
266	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
267
268	if (info->no_irq) {
269		pm_runtime_get_sync(indio_dev->dev.parent);
270
271		regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val);
272
273		pm_runtime_put_autosuspend(indio_dev->dev.parent);
274
275		return 0;
276	}
277
278	return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
279}
280
281static int sun4i_gpadc_temp_offset(struct iio_dev *indio_dev, int *val)
282{
283	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
284
285	*val = info->data->temp_offset;
286
287	return 0;
288}
289
290static int sun4i_gpadc_temp_scale(struct iio_dev *indio_dev, int *val)
291{
292	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
293
294	*val = info->data->temp_scale;
295
296	return 0;
297}
298
299static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
300				struct iio_chan_spec const *chan, int *val,
301				int *val2, long mask)
302{
303	int ret;
304
305	switch (mask) {
306	case IIO_CHAN_INFO_OFFSET:
307		ret = sun4i_gpadc_temp_offset(indio_dev, val);
308		if (ret)
309			return ret;
310
311		return IIO_VAL_INT;
312	case IIO_CHAN_INFO_RAW:
313		if (chan->type == IIO_VOLTAGE)
314			ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
315						   val);
316		else
317			ret = sun4i_gpadc_temp_read(indio_dev, val);
318
319		if (ret)
320			return ret;
321
322		return IIO_VAL_INT;
323	case IIO_CHAN_INFO_SCALE:
324		if (chan->type == IIO_VOLTAGE) {
325			/* 3000mV / 4096 * raw */
326			*val = 0;
327			*val2 = 732421875;
328			return IIO_VAL_INT_PLUS_NANO;
329		}
330
331		ret = sun4i_gpadc_temp_scale(indio_dev, val);
332		if (ret)
333			return ret;
334
335		return IIO_VAL_INT;
336	default:
337		return -EINVAL;
338	}
339
340	return -EINVAL;
341}
342
343static const struct iio_info sun4i_gpadc_iio_info = {
344	.read_raw = sun4i_gpadc_read_raw,
345};
346
347static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
348{
349	struct sun4i_gpadc_iio *info = dev_id;
350
351	if (atomic_read(&info->ignore_temp_data_irq))
352		goto out;
353
354	if (!regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, &info->temp_data))
355		complete(&info->completion);
356
357out:
358	return IRQ_HANDLED;
359}
360
361static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
362{
363	struct sun4i_gpadc_iio *info = dev_id;
364
365	if (atomic_read(&info->ignore_fifo_data_irq))
366		goto out;
367
368	if (!regmap_read(info->regmap, SUN4I_GPADC_DATA, &info->adc_data))
369		complete(&info->completion);
370
371out:
372	return IRQ_HANDLED;
373}
374
375static int sun4i_gpadc_runtime_suspend(struct device *dev)
376{
377	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
378
379	/* Disable the ADC on IP */
380	regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
381	/* Disable temperature sensor on IP */
382	regmap_write(info->regmap, SUN4I_GPADC_TPR, 0);
383
384	return 0;
385}
386
387static int sun4i_gpadc_runtime_resume(struct device *dev)
388{
389	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
390
391	/* clkin = 6MHz */
392	regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
393		     SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
394		     SUN4I_GPADC_CTRL0_FS_DIV(7) |
395		     SUN4I_GPADC_CTRL0_T_ACQ(63));
396	regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en);
397	regmap_write(info->regmap, SUN4I_GPADC_CTRL3,
398		     SUN4I_GPADC_CTRL3_FILTER_EN |
399		     SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
400	/* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */
401	regmap_write(info->regmap, SUN4I_GPADC_TPR,
402		     SUN4I_GPADC_TPR_TEMP_ENABLE |
403		     SUN4I_GPADC_TPR_TEMP_PERIOD(800));
404
405	return 0;
406}
407
408static int sun4i_gpadc_get_temp(struct thermal_zone_device *tz, int *temp)
409{
410	struct sun4i_gpadc_iio *info = thermal_zone_device_priv(tz);
411	int val, scale, offset;
412
413	if (sun4i_gpadc_temp_read(info->indio_dev, &val))
414		return -ETIMEDOUT;
415
416	sun4i_gpadc_temp_scale(info->indio_dev, &scale);
417	sun4i_gpadc_temp_offset(info->indio_dev, &offset);
418
419	*temp = (val + offset) * scale;
420
421	return 0;
422}
423
424static const struct thermal_zone_device_ops sun4i_ts_tz_ops = {
425	.get_temp = &sun4i_gpadc_get_temp,
426};
427
428static const struct dev_pm_ops sun4i_gpadc_pm_ops = {
429	.runtime_suspend = &sun4i_gpadc_runtime_suspend,
430	.runtime_resume = &sun4i_gpadc_runtime_resume,
431};
432
433static int sun4i_irq_init(struct platform_device *pdev, const char *name,
434			  irq_handler_t handler, const char *devname,
435			  unsigned int *irq, atomic_t *atomic)
436{
437	int ret;
438	struct sun4i_gpadc_dev *mfd_dev = dev_get_drvdata(pdev->dev.parent);
439	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(&pdev->dev));
440
441	/*
442	 * Once the interrupt is activated, the IP continuously performs
443	 * conversions thus throws interrupts. The interrupt is activated right
444	 * after being requested but we want to control when these interrupts
445	 * occur thus we disable it right after being requested. However, an
446	 * interrupt might occur between these two instructions and we have to
447	 * make sure that does not happen, by using atomic flags. We set the
448	 * flag before requesting the interrupt and unset it right after
449	 * disabling the interrupt. When an interrupt occurs between these two
450	 * instructions, reading the atomic flag will tell us to ignore the
451	 * interrupt.
452	 */
453	atomic_set(atomic, 1);
454
455	ret = platform_get_irq_byname(pdev, name);
456	if (ret < 0)
457		return ret;
458
459	ret = regmap_irq_get_virq(mfd_dev->regmap_irqc, ret);
460	if (ret < 0) {
461		dev_err(&pdev->dev, "failed to get virq for irq %s\n", name);
462		return ret;
463	}
464
465	*irq = ret;
466	ret = devm_request_any_context_irq(&pdev->dev, *irq, handler,
467					   IRQF_NO_AUTOEN,
468					   devname, info);
469	if (ret < 0) {
470		dev_err(&pdev->dev, "could not request %s interrupt: %d\n",
471			name, ret);
472		return ret;
473	}
474
475	atomic_set(atomic, 0);
476
477	return 0;
478}
479
480static const struct of_device_id sun4i_gpadc_of_id[] = {
481	{
482		.compatible = "allwinner,sun8i-a33-ths",
483		.data = &sun8i_a33_gpadc_data,
484	},
485	{ }
486};
487
488static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
489				struct iio_dev *indio_dev)
490{
491	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
492	void __iomem *base;
493	int ret;
494
495	info->data = of_device_get_match_data(&pdev->dev);
496	if (!info->data)
497		return -ENODEV;
498
499	info->no_irq = true;
500	indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels);
501	indio_dev->channels = sun8i_a33_gpadc_channels;
502
503	base = devm_platform_ioremap_resource(pdev, 0);
504	if (IS_ERR(base))
505		return PTR_ERR(base);
506
507	info->regmap = devm_regmap_init_mmio(&pdev->dev, base,
508					     &sun4i_gpadc_regmap_config);
509	if (IS_ERR(info->regmap)) {
510		ret = PTR_ERR(info->regmap);
511		dev_err(&pdev->dev, "failed to init regmap: %d\n", ret);
512		return ret;
513	}
514
515	if (IS_ENABLED(CONFIG_THERMAL_OF))
516		info->sensor_device = &pdev->dev;
517
518	return 0;
519}
520
521static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,
522				 struct iio_dev *indio_dev)
523{
524	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
525	struct sun4i_gpadc_dev *sun4i_gpadc_dev =
526		dev_get_drvdata(pdev->dev.parent);
527	int ret;
528
529	info->no_irq = false;
530	info->regmap = sun4i_gpadc_dev->regmap;
531
532	indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels);
533	indio_dev->channels = sun4i_gpadc_channels;
534
535	info->data = (struct gpadc_data *)platform_get_device_id(pdev)->driver_data;
536
537	/*
538	 * Since the controller needs to be in touchscreen mode for its thermal
539	 * sensor to operate properly, and that switching between the two modes
540	 * needs a delay, always registering in the thermal framework will
541	 * significantly slow down the conversion rate of the ADCs.
542	 *
543	 * Therefore, instead of depending on THERMAL_OF in Kconfig, we only
544	 * register the sensor if that option is enabled, eventually leaving
545	 * that choice to the user.
546	 */
547
548	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
549		/*
550		 * This driver is a child of an MFD which has a node in the DT
551		 * but not its children, because of DT backward compatibility
552		 * for A10, A13 and A31 SoCs. Therefore, the resulting devices
553		 * of this driver do not have an of_node variable.
554		 * However, its parent (the MFD driver) has an of_node variable
555		 * and since devm_thermal_zone_of_sensor_register uses its first
556		 * argument to match the phandle defined in the node of the
557		 * thermal driver with the of_node of the device passed as first
558		 * argument and the third argument to call ops from
559		 * thermal_zone_of_device_ops, the solution is to use the parent
560		 * device as first argument to match the phandle with its
561		 * of_node, and the device from this driver as third argument to
562		 * return the temperature.
563		 */
564		info->sensor_device = pdev->dev.parent;
565	} else {
566		indio_dev->num_channels =
567			ARRAY_SIZE(sun4i_gpadc_channels_no_temp);
568		indio_dev->channels = sun4i_gpadc_channels_no_temp;
569	}
570
571	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
572		ret = sun4i_irq_init(pdev, "TEMP_DATA_PENDING",
573				     sun4i_gpadc_temp_data_irq_handler,
574				     "temp_data", &info->temp_data_irq,
575				     &info->ignore_temp_data_irq);
576		if (ret < 0)
577			return ret;
578	}
579
580	ret = sun4i_irq_init(pdev, "FIFO_DATA_PENDING",
581			     sun4i_gpadc_fifo_data_irq_handler, "fifo_data",
582			     &info->fifo_data_irq, &info->ignore_fifo_data_irq);
583	if (ret < 0)
584		return ret;
585
586	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
587		ret = iio_map_array_register(indio_dev, sun4i_gpadc_hwmon_maps);
588		if (ret < 0) {
589			dev_err(&pdev->dev,
590				"failed to register iio map array\n");
591			return ret;
592		}
593	}
594
595	return 0;
596}
597
598static int sun4i_gpadc_probe(struct platform_device *pdev)
599{
600	struct sun4i_gpadc_iio *info;
601	struct iio_dev *indio_dev;
602	int ret;
603
604	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
605	if (!indio_dev)
606		return -ENOMEM;
607
608	info = iio_priv(indio_dev);
609	platform_set_drvdata(pdev, indio_dev);
610
611	mutex_init(&info->mutex);
612	info->indio_dev = indio_dev;
613	init_completion(&info->completion);
614	indio_dev->name = dev_name(&pdev->dev);
615	indio_dev->info = &sun4i_gpadc_iio_info;
616	indio_dev->modes = INDIO_DIRECT_MODE;
617
618	if (pdev->dev.of_node)
619		ret = sun4i_gpadc_probe_dt(pdev, indio_dev);
620	else
621		ret = sun4i_gpadc_probe_mfd(pdev, indio_dev);
622
623	if (ret)
624		return ret;
625
626	pm_runtime_set_autosuspend_delay(&pdev->dev,
627					 SUN4I_GPADC_AUTOSUSPEND_DELAY);
628	pm_runtime_use_autosuspend(&pdev->dev);
629	pm_runtime_set_suspended(&pdev->dev);
630	pm_runtime_enable(&pdev->dev);
631
632	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
633		info->tzd = devm_thermal_of_zone_register(info->sensor_device,
634							  0, info,
635							  &sun4i_ts_tz_ops);
636		/*
637		 * Do not fail driver probing when failing to register in
638		 * thermal because no thermal DT node is found.
639		 */
640		if (IS_ERR(info->tzd) && PTR_ERR(info->tzd) != -ENODEV) {
641			dev_err(&pdev->dev,
642				"could not register thermal sensor: %ld\n",
643				PTR_ERR(info->tzd));
644			return PTR_ERR(info->tzd);
645		}
646	}
647
648	ret = devm_iio_device_register(&pdev->dev, indio_dev);
649	if (ret < 0) {
650		dev_err(&pdev->dev, "could not register the device\n");
651		goto err_map;
652	}
653
654	return 0;
655
656err_map:
657	if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF))
658		iio_map_array_unregister(indio_dev);
659
660	pm_runtime_put(&pdev->dev);
661	pm_runtime_disable(&pdev->dev);
662
663	return ret;
664}
665
666static void sun4i_gpadc_remove(struct platform_device *pdev)
667{
668	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
669	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
670
671	pm_runtime_put(&pdev->dev);
672	pm_runtime_disable(&pdev->dev);
673
674	if (!IS_ENABLED(CONFIG_THERMAL_OF))
675		return;
676
677	if (!info->no_irq)
678		iio_map_array_unregister(indio_dev);
679}
680
681static const struct platform_device_id sun4i_gpadc_id[] = {
682	{ "sun4i-a10-gpadc-iio", (kernel_ulong_t)&sun4i_gpadc_data },
683	{ "sun5i-a13-gpadc-iio", (kernel_ulong_t)&sun5i_gpadc_data },
684	{ "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data },
685	{ }
686};
687MODULE_DEVICE_TABLE(platform, sun4i_gpadc_id);
688
689static struct platform_driver sun4i_gpadc_driver = {
690	.driver = {
691		.name = "sun4i-gpadc-iio",
692		.of_match_table = sun4i_gpadc_of_id,
693		.pm = &sun4i_gpadc_pm_ops,
694	},
695	.id_table = sun4i_gpadc_id,
696	.probe = sun4i_gpadc_probe,
697	.remove = sun4i_gpadc_remove,
698};
699MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_id);
700
701module_platform_driver(sun4i_gpadc_driver);
702
703MODULE_DESCRIPTION("ADC driver for sunxi platforms");
704MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
705MODULE_LICENSE("GPL v2");
~/ Read-only file preview.