xref: /openbmc/linux/drivers/iio/adc/stmpe-adc.c (revision 9f3d084965a5544f096d4f769e274d4c2892079b)
1*9f3d0849SStefan Agner // SPDX-License-Identifier: GPL-2.0
2*9f3d0849SStefan Agner /*
3*9f3d0849SStefan Agner  *  STMicroelectronics STMPE811 IIO ADC Driver
4*9f3d0849SStefan Agner  *
5*9f3d0849SStefan Agner  *  4 channel, 10/12-bit ADC
6*9f3d0849SStefan Agner  *
7*9f3d0849SStefan Agner  *  Copyright (C) 2013-2018 Toradex AG <stefan.agner@toradex.com>
8*9f3d0849SStefan Agner  */
9*9f3d0849SStefan Agner 
10*9f3d0849SStefan Agner #include <linux/completion.h>
11*9f3d0849SStefan Agner #include <linux/err.h>
12*9f3d0849SStefan Agner #include <linux/iio/iio.h>
13*9f3d0849SStefan Agner #include <linux/interrupt.h>
14*9f3d0849SStefan Agner #include <linux/kernel.h>
15*9f3d0849SStefan Agner #include <linux/mfd/stmpe.h>
16*9f3d0849SStefan Agner #include <linux/module.h>
17*9f3d0849SStefan Agner #include <linux/of_platform.h>
18*9f3d0849SStefan Agner #include <linux/platform_device.h>
19*9f3d0849SStefan Agner #include <linux/device.h>
20*9f3d0849SStefan Agner 
21*9f3d0849SStefan Agner #define STMPE_REG_INT_STA		0x0B
22*9f3d0849SStefan Agner #define STMPE_REG_ADC_INT_EN		0x0E
23*9f3d0849SStefan Agner #define STMPE_REG_ADC_INT_STA		0x0F
24*9f3d0849SStefan Agner 
25*9f3d0849SStefan Agner #define STMPE_REG_ADC_CTRL1		0x20
26*9f3d0849SStefan Agner #define STMPE_REG_ADC_CTRL2		0x21
27*9f3d0849SStefan Agner #define STMPE_REG_ADC_CAPT		0x22
28*9f3d0849SStefan Agner #define STMPE_REG_ADC_DATA_CH(channel)	(0x30 + 2 * (channel))
29*9f3d0849SStefan Agner 
30*9f3d0849SStefan Agner #define STMPE_REG_TEMP_CTRL		0x60
31*9f3d0849SStefan Agner #define STMPE_TEMP_CTRL_ENABLE		BIT(0)
32*9f3d0849SStefan Agner #define STMPE_TEMP_CTRL_ACQ		BIT(1)
33*9f3d0849SStefan Agner #define STMPE_TEMP_CTRL_THRES_EN	BIT(3)
34*9f3d0849SStefan Agner #define STMPE_START_ONE_TEMP_CONV	(STMPE_TEMP_CTRL_ENABLE | \
35*9f3d0849SStefan Agner 					STMPE_TEMP_CTRL_ACQ | \
36*9f3d0849SStefan Agner 					STMPE_TEMP_CTRL_THRES_EN)
37*9f3d0849SStefan Agner #define STMPE_REG_TEMP_DATA		0x61
38*9f3d0849SStefan Agner #define STMPE_REG_TEMP_TH		0x63
39*9f3d0849SStefan Agner #define STMPE_ADC_LAST_NR		7
40*9f3d0849SStefan Agner #define STMPE_TEMP_CHANNEL		(STMPE_ADC_LAST_NR + 1)
41*9f3d0849SStefan Agner 
42*9f3d0849SStefan Agner #define STMPE_ADC_CH(channel)		((1 << (channel)) & 0xff)
43*9f3d0849SStefan Agner 
44*9f3d0849SStefan Agner #define STMPE_ADC_TIMEOUT		msecs_to_jiffies(1000)
45*9f3d0849SStefan Agner 
46*9f3d0849SStefan Agner struct stmpe_adc {
47*9f3d0849SStefan Agner 	struct stmpe *stmpe;
48*9f3d0849SStefan Agner 	struct clk *clk;
49*9f3d0849SStefan Agner 	struct device *dev;
50*9f3d0849SStefan Agner 	struct mutex lock;
51*9f3d0849SStefan Agner 
52*9f3d0849SStefan Agner 	/* We are allocating plus one for the temperature channel */
53*9f3d0849SStefan Agner 	struct iio_chan_spec stmpe_adc_iio_channels[STMPE_ADC_LAST_NR + 2];
54*9f3d0849SStefan Agner 
55*9f3d0849SStefan Agner 	struct completion completion;
56*9f3d0849SStefan Agner 
57*9f3d0849SStefan Agner 	u8 channel;
58*9f3d0849SStefan Agner 	u32 value;
59*9f3d0849SStefan Agner };
60*9f3d0849SStefan Agner 
61*9f3d0849SStefan Agner static int stmpe_read_voltage(struct stmpe_adc *info,
62*9f3d0849SStefan Agner 		struct iio_chan_spec const *chan, int *val)
63*9f3d0849SStefan Agner {
64*9f3d0849SStefan Agner 	long ret;
65*9f3d0849SStefan Agner 
66*9f3d0849SStefan Agner 	mutex_lock(&info->lock);
67*9f3d0849SStefan Agner 
68*9f3d0849SStefan Agner 	info->channel = (u8)chan->channel;
69*9f3d0849SStefan Agner 
70*9f3d0849SStefan Agner 	if (info->channel > STMPE_ADC_LAST_NR) {
71*9f3d0849SStefan Agner 		mutex_unlock(&info->lock);
72*9f3d0849SStefan Agner 		return -EINVAL;
73*9f3d0849SStefan Agner 	}
74*9f3d0849SStefan Agner 
75*9f3d0849SStefan Agner 	stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_EN,
76*9f3d0849SStefan Agner 			STMPE_ADC_CH(info->channel));
77*9f3d0849SStefan Agner 
78*9f3d0849SStefan Agner 	stmpe_reg_write(info->stmpe, STMPE_REG_ADC_CAPT,
79*9f3d0849SStefan Agner 			STMPE_ADC_CH(info->channel));
80*9f3d0849SStefan Agner 
81*9f3d0849SStefan Agner 	*val = info->value;
82*9f3d0849SStefan Agner 
83*9f3d0849SStefan Agner 	ret = wait_for_completion_interruptible_timeout
84*9f3d0849SStefan Agner 		(&info->completion, STMPE_ADC_TIMEOUT);
85*9f3d0849SStefan Agner 
86*9f3d0849SStefan Agner 	if (ret <= 0) {
87*9f3d0849SStefan Agner 		mutex_unlock(&info->lock);
88*9f3d0849SStefan Agner 		if (ret == 0)
89*9f3d0849SStefan Agner 			return -ETIMEDOUT;
90*9f3d0849SStefan Agner 		else
91*9f3d0849SStefan Agner 			return ret;
92*9f3d0849SStefan Agner 	}
93*9f3d0849SStefan Agner 
94*9f3d0849SStefan Agner 	*val = info->value;
95*9f3d0849SStefan Agner 
96*9f3d0849SStefan Agner 	mutex_unlock(&info->lock);
97*9f3d0849SStefan Agner 
98*9f3d0849SStefan Agner 	return 0;
99*9f3d0849SStefan Agner }
100*9f3d0849SStefan Agner 
101*9f3d0849SStefan Agner static int stmpe_read_temp(struct stmpe_adc *info,
102*9f3d0849SStefan Agner 		struct iio_chan_spec const *chan, int *val)
103*9f3d0849SStefan Agner {
104*9f3d0849SStefan Agner 	long ret;
105*9f3d0849SStefan Agner 
106*9f3d0849SStefan Agner 	mutex_lock(&info->lock);
107*9f3d0849SStefan Agner 
108*9f3d0849SStefan Agner 	info->channel = (u8)chan->channel;
109*9f3d0849SStefan Agner 
110*9f3d0849SStefan Agner 	if (info->channel != STMPE_TEMP_CHANNEL) {
111*9f3d0849SStefan Agner 		mutex_unlock(&info->lock);
112*9f3d0849SStefan Agner 		return -EINVAL;
113*9f3d0849SStefan Agner 	}
114*9f3d0849SStefan Agner 
115*9f3d0849SStefan Agner 	stmpe_reg_write(info->stmpe, STMPE_REG_TEMP_CTRL,
116*9f3d0849SStefan Agner 			STMPE_START_ONE_TEMP_CONV);
117*9f3d0849SStefan Agner 
118*9f3d0849SStefan Agner 	ret = wait_for_completion_interruptible_timeout
119*9f3d0849SStefan Agner 		(&info->completion, STMPE_ADC_TIMEOUT);
120*9f3d0849SStefan Agner 
121*9f3d0849SStefan Agner 	if (ret <= 0) {
122*9f3d0849SStefan Agner 		mutex_unlock(&info->lock);
123*9f3d0849SStefan Agner 		if (ret == 0)
124*9f3d0849SStefan Agner 			return -ETIMEDOUT;
125*9f3d0849SStefan Agner 		else
126*9f3d0849SStefan Agner 			return ret;
127*9f3d0849SStefan Agner 	}
128*9f3d0849SStefan Agner 
129*9f3d0849SStefan Agner 	/*
130*9f3d0849SStefan Agner 	 * absolute temp = +V3.3 * value /7.51 [K]
131*9f3d0849SStefan Agner 	 * scale to [milli °C]
132*9f3d0849SStefan Agner 	 */
133*9f3d0849SStefan Agner 	*val = ((449960l * info->value) / 1024l) - 273150;
134*9f3d0849SStefan Agner 
135*9f3d0849SStefan Agner 	mutex_unlock(&info->lock);
136*9f3d0849SStefan Agner 
137*9f3d0849SStefan Agner 	return 0;
138*9f3d0849SStefan Agner }
139*9f3d0849SStefan Agner 
140*9f3d0849SStefan Agner static int stmpe_read_raw(struct iio_dev *indio_dev,
141*9f3d0849SStefan Agner 			  struct iio_chan_spec const *chan,
142*9f3d0849SStefan Agner 			  int *val,
143*9f3d0849SStefan Agner 			  int *val2,
144*9f3d0849SStefan Agner 			  long mask)
145*9f3d0849SStefan Agner {
146*9f3d0849SStefan Agner 	struct stmpe_adc *info = iio_priv(indio_dev);
147*9f3d0849SStefan Agner 	long ret;
148*9f3d0849SStefan Agner 
149*9f3d0849SStefan Agner 	switch (mask) {
150*9f3d0849SStefan Agner 	case IIO_CHAN_INFO_RAW:
151*9f3d0849SStefan Agner 	case IIO_CHAN_INFO_PROCESSED:
152*9f3d0849SStefan Agner 
153*9f3d0849SStefan Agner 		switch (chan->type) {
154*9f3d0849SStefan Agner 		case IIO_VOLTAGE:
155*9f3d0849SStefan Agner 			ret = stmpe_read_voltage(info, chan, val);
156*9f3d0849SStefan Agner 			break;
157*9f3d0849SStefan Agner 
158*9f3d0849SStefan Agner 		case IIO_TEMP:
159*9f3d0849SStefan Agner 			ret = stmpe_read_temp(info, chan, val);
160*9f3d0849SStefan Agner 			break;
161*9f3d0849SStefan Agner 		default:
162*9f3d0849SStefan Agner 			return -EINVAL;
163*9f3d0849SStefan Agner 		}
164*9f3d0849SStefan Agner 
165*9f3d0849SStefan Agner 		if (ret < 0)
166*9f3d0849SStefan Agner 			return ret;
167*9f3d0849SStefan Agner 
168*9f3d0849SStefan Agner 		return IIO_VAL_INT;
169*9f3d0849SStefan Agner 
170*9f3d0849SStefan Agner 	case IIO_CHAN_INFO_SCALE:
171*9f3d0849SStefan Agner 		*val = 3300;
172*9f3d0849SStefan Agner 		*val2 = info->stmpe->mod_12b ? 12 : 10;
173*9f3d0849SStefan Agner 		return IIO_VAL_FRACTIONAL_LOG2;
174*9f3d0849SStefan Agner 
175*9f3d0849SStefan Agner 	default:
176*9f3d0849SStefan Agner 		break;
177*9f3d0849SStefan Agner 	}
178*9f3d0849SStefan Agner 
179*9f3d0849SStefan Agner 	return -EINVAL;
180*9f3d0849SStefan Agner }
181*9f3d0849SStefan Agner 
182*9f3d0849SStefan Agner static irqreturn_t stmpe_adc_isr(int irq, void *dev_id)
183*9f3d0849SStefan Agner {
184*9f3d0849SStefan Agner 	struct stmpe_adc *info = (struct stmpe_adc *)dev_id;
185*9f3d0849SStefan Agner 	u16 data;
186*9f3d0849SStefan Agner 
187*9f3d0849SStefan Agner 	if (info->channel > STMPE_TEMP_CHANNEL)
188*9f3d0849SStefan Agner 		return IRQ_NONE;
189*9f3d0849SStefan Agner 
190*9f3d0849SStefan Agner 	if (info->channel <= STMPE_ADC_LAST_NR) {
191*9f3d0849SStefan Agner 		int int_sta;
192*9f3d0849SStefan Agner 
193*9f3d0849SStefan Agner 		int_sta = stmpe_reg_read(info->stmpe, STMPE_REG_ADC_INT_STA);
194*9f3d0849SStefan Agner 
195*9f3d0849SStefan Agner 		/* Is the interrupt relevant */
196*9f3d0849SStefan Agner 		if (!(int_sta & STMPE_ADC_CH(info->channel)))
197*9f3d0849SStefan Agner 			return IRQ_NONE;
198*9f3d0849SStefan Agner 
199*9f3d0849SStefan Agner 		/* Read value */
200*9f3d0849SStefan Agner 		stmpe_block_read(info->stmpe,
201*9f3d0849SStefan Agner 			STMPE_REG_ADC_DATA_CH(info->channel), 2, (u8 *) &data);
202*9f3d0849SStefan Agner 
203*9f3d0849SStefan Agner 		stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_STA, int_sta);
204*9f3d0849SStefan Agner 	} else if (info->channel == STMPE_TEMP_CHANNEL) {
205*9f3d0849SStefan Agner 		/* Read value */
206*9f3d0849SStefan Agner 		stmpe_block_read(info->stmpe, STMPE_REG_TEMP_DATA, 2,
207*9f3d0849SStefan Agner 				(u8 *) &data);
208*9f3d0849SStefan Agner 	}
209*9f3d0849SStefan Agner 
210*9f3d0849SStefan Agner 	info->value = (u32) be16_to_cpu(data);
211*9f3d0849SStefan Agner 	complete(&info->completion);
212*9f3d0849SStefan Agner 
213*9f3d0849SStefan Agner 	return IRQ_HANDLED;
214*9f3d0849SStefan Agner }
215*9f3d0849SStefan Agner 
216*9f3d0849SStefan Agner static const struct iio_info stmpe_adc_iio_info = {
217*9f3d0849SStefan Agner 	.read_raw = &stmpe_read_raw,
218*9f3d0849SStefan Agner };
219*9f3d0849SStefan Agner 
220*9f3d0849SStefan Agner static void stmpe_adc_voltage_chan(struct iio_chan_spec *ics, int chan)
221*9f3d0849SStefan Agner {
222*9f3d0849SStefan Agner 	ics->type = IIO_VOLTAGE;
223*9f3d0849SStefan Agner 	ics->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
224*9f3d0849SStefan Agner 	ics->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
225*9f3d0849SStefan Agner 	ics->indexed = 1;
226*9f3d0849SStefan Agner 	ics->channel = chan;
227*9f3d0849SStefan Agner }
228*9f3d0849SStefan Agner 
229*9f3d0849SStefan Agner static void stmpe_adc_temp_chan(struct iio_chan_spec *ics, int chan)
230*9f3d0849SStefan Agner {
231*9f3d0849SStefan Agner 	ics->type = IIO_TEMP;
232*9f3d0849SStefan Agner 	ics->info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED);
233*9f3d0849SStefan Agner 	ics->indexed = 1;
234*9f3d0849SStefan Agner 	ics->channel = chan;
235*9f3d0849SStefan Agner }
236*9f3d0849SStefan Agner 
237*9f3d0849SStefan Agner static int stmpe_adc_init_hw(struct stmpe_adc *adc)
238*9f3d0849SStefan Agner {
239*9f3d0849SStefan Agner 	int ret;
240*9f3d0849SStefan Agner 	struct stmpe *stmpe = adc->stmpe;
241*9f3d0849SStefan Agner 
242*9f3d0849SStefan Agner 	ret = stmpe_enable(stmpe, STMPE_BLOCK_ADC);
243*9f3d0849SStefan Agner 	if (ret) {
244*9f3d0849SStefan Agner 		dev_err(stmpe->dev, "Could not enable clock for ADC\n");
245*9f3d0849SStefan Agner 		return ret;
246*9f3d0849SStefan Agner 	}
247*9f3d0849SStefan Agner 
248*9f3d0849SStefan Agner 	ret = stmpe811_adc_common_init(stmpe);
249*9f3d0849SStefan Agner 	if (ret) {
250*9f3d0849SStefan Agner 		stmpe_disable(stmpe, STMPE_BLOCK_ADC);
251*9f3d0849SStefan Agner 		return ret;
252*9f3d0849SStefan Agner 	}
253*9f3d0849SStefan Agner 
254*9f3d0849SStefan Agner 	/* use temp irq for each conversion completion */
255*9f3d0849SStefan Agner 	stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH, 0);
256*9f3d0849SStefan Agner 	stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH + 1, 0);
257*9f3d0849SStefan Agner 
258*9f3d0849SStefan Agner 	return 0;
259*9f3d0849SStefan Agner }
260*9f3d0849SStefan Agner 
261*9f3d0849SStefan Agner static int stmpe_adc_probe(struct platform_device *pdev)
262*9f3d0849SStefan Agner {
263*9f3d0849SStefan Agner 	struct iio_dev *indio_dev;
264*9f3d0849SStefan Agner 	struct stmpe_adc *info;
265*9f3d0849SStefan Agner 	struct device_node *np;
266*9f3d0849SStefan Agner 	u32 norequest_mask = 0;
267*9f3d0849SStefan Agner 	int irq_temp, irq_adc;
268*9f3d0849SStefan Agner 	int num_chan = 0;
269*9f3d0849SStefan Agner 	int i = 0;
270*9f3d0849SStefan Agner 	int ret;
271*9f3d0849SStefan Agner 
272*9f3d0849SStefan Agner 	irq_adc = platform_get_irq_byname(pdev, "STMPE_ADC");
273*9f3d0849SStefan Agner 	if (irq_adc < 0)
274*9f3d0849SStefan Agner 		return irq_adc;
275*9f3d0849SStefan Agner 
276*9f3d0849SStefan Agner 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct stmpe_adc));
277*9f3d0849SStefan Agner 	if (!indio_dev) {
278*9f3d0849SStefan Agner 		dev_err(&pdev->dev, "failed allocating iio device\n");
279*9f3d0849SStefan Agner 		return -ENOMEM;
280*9f3d0849SStefan Agner 	}
281*9f3d0849SStefan Agner 
282*9f3d0849SStefan Agner 	info = iio_priv(indio_dev);
283*9f3d0849SStefan Agner 	mutex_init(&info->lock);
284*9f3d0849SStefan Agner 
285*9f3d0849SStefan Agner 	init_completion(&info->completion);
286*9f3d0849SStefan Agner 	ret = devm_request_threaded_irq(&pdev->dev, irq_adc, NULL,
287*9f3d0849SStefan Agner 					stmpe_adc_isr, IRQF_ONESHOT,
288*9f3d0849SStefan Agner 					"stmpe-adc", info);
289*9f3d0849SStefan Agner 	if (ret < 0) {
290*9f3d0849SStefan Agner 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
291*9f3d0849SStefan Agner 				irq_adc);
292*9f3d0849SStefan Agner 		return ret;
293*9f3d0849SStefan Agner 	}
294*9f3d0849SStefan Agner 
295*9f3d0849SStefan Agner 	irq_temp = platform_get_irq_byname(pdev, "STMPE_TEMP_SENS");
296*9f3d0849SStefan Agner 	if (irq_temp >= 0) {
297*9f3d0849SStefan Agner 		ret = devm_request_threaded_irq(&pdev->dev, irq_temp, NULL,
298*9f3d0849SStefan Agner 						stmpe_adc_isr, IRQF_ONESHOT,
299*9f3d0849SStefan Agner 						"stmpe-adc", info);
300*9f3d0849SStefan Agner 		if (ret < 0)
301*9f3d0849SStefan Agner 			dev_warn(&pdev->dev, "failed requesting irq for"
302*9f3d0849SStefan Agner 				 " temp sensor, irq = %d\n", irq_temp);
303*9f3d0849SStefan Agner 	}
304*9f3d0849SStefan Agner 
305*9f3d0849SStefan Agner 	platform_set_drvdata(pdev, indio_dev);
306*9f3d0849SStefan Agner 
307*9f3d0849SStefan Agner 	indio_dev->name		= dev_name(&pdev->dev);
308*9f3d0849SStefan Agner 	indio_dev->dev.parent	= &pdev->dev;
309*9f3d0849SStefan Agner 	indio_dev->info		= &stmpe_adc_iio_info;
310*9f3d0849SStefan Agner 	indio_dev->modes	= INDIO_DIRECT_MODE;
311*9f3d0849SStefan Agner 
312*9f3d0849SStefan Agner 	info->stmpe = dev_get_drvdata(pdev->dev.parent);
313*9f3d0849SStefan Agner 
314*9f3d0849SStefan Agner 	np = pdev->dev.of_node;
315*9f3d0849SStefan Agner 
316*9f3d0849SStefan Agner 	if (!np)
317*9f3d0849SStefan Agner 		dev_err(&pdev->dev, "no device tree node found\n");
318*9f3d0849SStefan Agner 
319*9f3d0849SStefan Agner 	of_property_read_u32(np, "st,norequest-mask", &norequest_mask);
320*9f3d0849SStefan Agner 
321*9f3d0849SStefan Agner 	for_each_clear_bit(i, (unsigned long *) &norequest_mask,
322*9f3d0849SStefan Agner 			   (STMPE_ADC_LAST_NR + 1)) {
323*9f3d0849SStefan Agner 		stmpe_adc_voltage_chan(&info->stmpe_adc_iio_channels[num_chan], i);
324*9f3d0849SStefan Agner 		num_chan++;
325*9f3d0849SStefan Agner 	}
326*9f3d0849SStefan Agner 	stmpe_adc_temp_chan(&info->stmpe_adc_iio_channels[num_chan], i);
327*9f3d0849SStefan Agner 	num_chan++;
328*9f3d0849SStefan Agner 	indio_dev->channels = info->stmpe_adc_iio_channels;
329*9f3d0849SStefan Agner 	indio_dev->num_channels = num_chan;
330*9f3d0849SStefan Agner 
331*9f3d0849SStefan Agner 	ret = stmpe_adc_init_hw(info);
332*9f3d0849SStefan Agner 	if (ret)
333*9f3d0849SStefan Agner 		return ret;
334*9f3d0849SStefan Agner 
335*9f3d0849SStefan Agner 	return devm_iio_device_register(&pdev->dev, indio_dev);
336*9f3d0849SStefan Agner }
337*9f3d0849SStefan Agner 
338*9f3d0849SStefan Agner static int __maybe_unused stmpe_adc_resume(struct device *dev)
339*9f3d0849SStefan Agner {
340*9f3d0849SStefan Agner 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
341*9f3d0849SStefan Agner 	struct stmpe_adc *info = iio_priv(indio_dev);
342*9f3d0849SStefan Agner 
343*9f3d0849SStefan Agner 	stmpe_adc_init_hw(info);
344*9f3d0849SStefan Agner 
345*9f3d0849SStefan Agner 	return 0;
346*9f3d0849SStefan Agner }
347*9f3d0849SStefan Agner 
348*9f3d0849SStefan Agner static SIMPLE_DEV_PM_OPS(stmpe_adc_pm_ops, NULL, stmpe_adc_resume);
349*9f3d0849SStefan Agner 
350*9f3d0849SStefan Agner static struct platform_driver stmpe_adc_driver = {
351*9f3d0849SStefan Agner 	.probe		= stmpe_adc_probe,
352*9f3d0849SStefan Agner 	.driver		= {
353*9f3d0849SStefan Agner 		.name	= "stmpe-adc",
354*9f3d0849SStefan Agner 		.pm	= &stmpe_adc_pm_ops,
355*9f3d0849SStefan Agner 	},
356*9f3d0849SStefan Agner };
357*9f3d0849SStefan Agner 
358*9f3d0849SStefan Agner module_platform_driver(stmpe_adc_driver);
359*9f3d0849SStefan Agner 
360*9f3d0849SStefan Agner MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>");
361*9f3d0849SStefan Agner MODULE_DESCRIPTION("STMPEXXX ADC driver");
362*9f3d0849SStefan Agner MODULE_LICENSE("GPL v2");
363*9f3d0849SStefan Agner MODULE_ALIAS("platform:stmpe-adc");
364