Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs.
  4 *
  5 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  6 * Copyright (C) 2009 Sascha Hauer, Pengutronix
 
 
 
 
 
 
 
 
 
 
 
 
 
  7 */
  8
  9#include <linux/mfd/mc13xxx.h>
 10#include <linux/platform_device.h>
 11#include <linux/hwmon-sysfs.h>
 12#include <linux/kernel.h>
 13#include <linux/module.h>
 14#include <linux/mod_devicetable.h>
 15#include <linux/hwmon.h>
 16#include <linux/slab.h>
 17#include <linux/init.h>
 18#include <linux/err.h>
 19
 20#define DRIVER_NAME	"mc13783-adc"
 21
 22/* platform device id driver data */
 23#define MC13783_ADC_16CHANS	1
 24#define MC13783_ADC_BPDIV2	2
 25
 26struct mc13783_adc_priv {
 27	struct mc13xxx *mc13xxx;
 28	struct device *hwmon_dev;
 29	char name[PLATFORM_NAME_SIZE];
 30};
 31
 32static ssize_t name_show(struct device *dev, struct device_attribute *devattr,
 33			 char *buf)
 34{
 35	struct mc13783_adc_priv *priv = dev_get_drvdata(dev);
 36
 37	return sprintf(buf, "%s\n", priv->name);
 38}
 39
 40static int mc13783_adc_read(struct device *dev,
 41		struct device_attribute *devattr, unsigned int *val)
 42{
 43	struct mc13783_adc_priv *priv = dev_get_drvdata(dev);
 44	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 45	unsigned int channel = attr->index;
 46	unsigned int sample[4];
 47	int ret;
 48
 49	ret = mc13xxx_adc_do_conversion(priv->mc13xxx,
 50			MC13XXX_ADC_MODE_MULT_CHAN,
 51			channel, 0, 0, sample);
 52	if (ret)
 53		return ret;
 54
 55	/* ADIN7 subchannels */
 56	if (channel >= 16)
 57		channel = 7;
 58
 59	channel &= 0x7;
 60
 61	*val = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
 62
 63	return 0;
 64}
 65
 66static ssize_t mc13783_adc_bp_show(struct device *dev,
 67				   struct device_attribute *devattr,
 68				   char *buf)
 69{
 70	unsigned val;
 71	struct platform_device *pdev = to_platform_device(dev);
 72	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
 73	int ret = mc13783_adc_read(dev, devattr, &val);
 74
 75	if (ret)
 76		return ret;
 77
 78	if (driver_data & MC13783_ADC_BPDIV2)
 79		val = DIV_ROUND_CLOSEST(val * 9, 2);
 80	else
 81		/*
 82		 * BP (channel 2) reports with offset 2.4V to the actual value
 83		 * to fit the input range of the ADC.  unit = 2.25mV = 9/4 mV.
 84		 */
 85		val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400;
 86
 87	return sprintf(buf, "%u\n", val);
 88}
 89
 90static ssize_t mc13783_adc_gp_show(struct device *dev,
 91				   struct device_attribute *devattr,
 92				   char *buf)
 93{
 94	unsigned val;
 95	int ret = mc13783_adc_read(dev, devattr, &val);
 96
 97	if (ret)
 98		return ret;
 99
100	/*
101	 * input range is [0, 2.3V], val has 10 bits, so each bit
102	 * is worth 9/4 mV.
103	 */
104	val = DIV_ROUND_CLOSEST(val * 9, 4);
105
106	return sprintf(buf, "%u\n", val);
107}
108
109static ssize_t mc13783_adc_uid_show(struct device *dev,
110				    struct device_attribute *devattr,
111				    char *buf)
112{
113	unsigned int val;
114	struct platform_device *pdev = to_platform_device(dev);
115	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
116	int ret = mc13783_adc_read(dev, devattr, &val);
117
118	if (ret)
119		return ret;
120
121	if (driver_data & MC13783_ADC_BPDIV2)
122		/* MC13892 have 1/2 divider, input range is [0, 4.800V] */
123		val = DIV_ROUND_CLOSEST(val * 4800, 1024);
124	else
125		/* MC13783 have 0.9 divider, input range is [0, 2.555V] */
126		val = DIV_ROUND_CLOSEST(val * 2555, 1024);
127
128	return sprintf(buf, "%u\n", val);
129}
130
131static ssize_t mc13783_adc_temp_show(struct device *dev,
132				     struct device_attribute *devattr,
133				     char *buf)
134{
135	unsigned int val;
136	struct platform_device *pdev = to_platform_device(dev);
137	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
138	int ret = mc13783_adc_read(dev, devattr, &val);
139
140	if (ret)
141		return ret;
142
143	if (driver_data & MC13783_ADC_BPDIV2) {
144		/*
145		 * MC13892:
146		 * Die Temperature Read Out Code at 25C 680
147		 * Temperature change per LSB +0.4244C
148		 */
149		ret = DIV_ROUND_CLOSEST(-2635920 + val * 4244, 10);
150	} else {
151		/*
152		 * MC13783:
153		 * Die Temperature Read Out Code at 25C 282
154		 * Temperature change per LSB -1.14C
155		 */
156		ret = 346480 - 1140 * val;
157	}
158
159	return sprintf(buf, "%d\n", ret);
160}
161
162static DEVICE_ATTR_RO(name);
163static SENSOR_DEVICE_ATTR_RO(in2_input, mc13783_adc_bp, 2);
164static SENSOR_DEVICE_ATTR_RO(in5_input, mc13783_adc_gp, 5);
165static SENSOR_DEVICE_ATTR_RO(in6_input, mc13783_adc_gp, 6);
166static SENSOR_DEVICE_ATTR_RO(in7_input, mc13783_adc_gp, 7);
167static SENSOR_DEVICE_ATTR_RO(in8_input, mc13783_adc_gp, 8);
168static SENSOR_DEVICE_ATTR_RO(in9_input, mc13783_adc_gp, 9);
169static SENSOR_DEVICE_ATTR_RO(in10_input, mc13783_adc_gp, 10);
170static SENSOR_DEVICE_ATTR_RO(in11_input, mc13783_adc_gp, 11);
171static SENSOR_DEVICE_ATTR_RO(in12_input, mc13783_adc_gp, 12);
172static SENSOR_DEVICE_ATTR_RO(in13_input, mc13783_adc_gp, 13);
173static SENSOR_DEVICE_ATTR_RO(in14_input, mc13783_adc_gp, 14);
174static SENSOR_DEVICE_ATTR_RO(in15_input, mc13783_adc_gp, 15);
175static SENSOR_DEVICE_ATTR_RO(in16_input, mc13783_adc_uid, 16);
176static SENSOR_DEVICE_ATTR_RO(temp1_input, mc13783_adc_temp, 17);
177
178static struct attribute *mc13783_attr_base[] = {
179	&dev_attr_name.attr,
180	&sensor_dev_attr_in2_input.dev_attr.attr,
181	&sensor_dev_attr_in5_input.dev_attr.attr,
182	&sensor_dev_attr_in6_input.dev_attr.attr,
183	&sensor_dev_attr_in7_input.dev_attr.attr,
184	&sensor_dev_attr_in16_input.dev_attr.attr,
185	&sensor_dev_attr_temp1_input.dev_attr.attr,
186	NULL
187};
188
189static const struct attribute_group mc13783_group_base = {
190	.attrs = mc13783_attr_base,
191};
192
193/* these are only used if MC13783_ADC_16CHANS is provided in driver data */
194static struct attribute *mc13783_attr_16chans[] = {
195	&sensor_dev_attr_in8_input.dev_attr.attr,
196	&sensor_dev_attr_in9_input.dev_attr.attr,
197	&sensor_dev_attr_in10_input.dev_attr.attr,
198	&sensor_dev_attr_in11_input.dev_attr.attr,
199	NULL
200};
201
202static const struct attribute_group mc13783_group_16chans = {
203	.attrs = mc13783_attr_16chans,
204};
205
206/* last four channels may be occupied by the touchscreen */
207static struct attribute *mc13783_attr_ts[] = {
208	&sensor_dev_attr_in12_input.dev_attr.attr,
209	&sensor_dev_attr_in13_input.dev_attr.attr,
210	&sensor_dev_attr_in14_input.dev_attr.attr,
211	&sensor_dev_attr_in15_input.dev_attr.attr,
212	NULL
213};
214
215static const struct attribute_group mc13783_group_ts = {
216	.attrs = mc13783_attr_ts,
217};
218
219static int mc13783_adc_use_touchscreen(struct platform_device *pdev)
220{
221	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
222	unsigned flags = mc13xxx_get_flags(priv->mc13xxx);
223
224	return flags & MC13XXX_USE_TOUCHSCREEN;
225}
226
227static int __init mc13783_adc_probe(struct platform_device *pdev)
228{
229	struct mc13783_adc_priv *priv;
230	int ret;
231	const struct platform_device_id *id = platform_get_device_id(pdev);
232	char *dash;
233
234	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
235	if (!priv)
236		return -ENOMEM;
237
238	priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
239	snprintf(priv->name, ARRAY_SIZE(priv->name), "%s", id->name);
240	dash = strchr(priv->name, '-');
241	if (dash)
242		*dash = '\0';
243
244	platform_set_drvdata(pdev, priv);
245
246	/* Register sysfs hooks */
247	ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base);
248	if (ret)
249		return ret;
250
251	if (id->driver_data & MC13783_ADC_16CHANS) {
252		ret = sysfs_create_group(&pdev->dev.kobj,
253				&mc13783_group_16chans);
254		if (ret)
255			goto out_err_create_16chans;
256	}
257
258	if (!mc13783_adc_use_touchscreen(pdev)) {
259		ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts);
260		if (ret)
261			goto out_err_create_ts;
262	}
263
264	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
265	if (IS_ERR(priv->hwmon_dev)) {
266		ret = PTR_ERR(priv->hwmon_dev);
267		dev_err(&pdev->dev,
268				"hwmon_device_register failed with %d.\n", ret);
269		goto out_err_register;
270	}
271
272	return 0;
273
274out_err_register:
275
276	if (!mc13783_adc_use_touchscreen(pdev))
277		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
278out_err_create_ts:
279
280	if (id->driver_data & MC13783_ADC_16CHANS)
281		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans);
282out_err_create_16chans:
283
284	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base);
285	return ret;
286}
287
288static int mc13783_adc_remove(struct platform_device *pdev)
289{
290	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
291	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
292
293	hwmon_device_unregister(priv->hwmon_dev);
294
295	if (!mc13783_adc_use_touchscreen(pdev))
296		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
297
298	if (driver_data & MC13783_ADC_16CHANS)
299		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans);
300
301	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base);
302
303	return 0;
304}
305
306static const struct platform_device_id mc13783_adc_idtable[] = {
307	{
308		.name = "mc13783-adc",
309		.driver_data = MC13783_ADC_16CHANS,
310	}, {
311		.name = "mc13892-adc",
312		.driver_data = MC13783_ADC_BPDIV2,
313	}, {
314		/* sentinel */
315	}
316};
317MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable);
318
319static struct platform_driver mc13783_adc_driver = {
320	.remove		= mc13783_adc_remove,
321	.driver		= {
322		.name	= DRIVER_NAME,
323	},
324	.id_table	= mc13783_adc_idtable,
325};
326
327module_platform_driver_probe(mc13783_adc_driver, mc13783_adc_probe);
328
329MODULE_DESCRIPTION("MC13783 ADC driver");
330MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
331MODULE_LICENSE("GPL");
v4.10.11
 
  1/*
  2 * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs.
  3 *
  4 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  5 * Copyright (C) 2009 Sascha Hauer, Pengutronix
  6 *
  7 * This program is free software; you can redistribute it and/or
  8 * modify it under the terms of the GNU General Public License
  9 * as published by the Free Software Foundation; either version 2
 10 * of the License, or (at your option) any later version.
 11 * This program is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 * GNU General Public License for more details.
 15 *
 16 * You should have received a copy of the GNU General Public License along with
 17 * this program; if not, write to the Free Software Foundation, Inc., 51
 18 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 19 */
 20
 21#include <linux/mfd/mc13xxx.h>
 22#include <linux/platform_device.h>
 23#include <linux/hwmon-sysfs.h>
 24#include <linux/kernel.h>
 25#include <linux/module.h>
 
 26#include <linux/hwmon.h>
 27#include <linux/slab.h>
 28#include <linux/init.h>
 29#include <linux/err.h>
 30
 31#define DRIVER_NAME	"mc13783-adc"
 32
 33/* platform device id driver data */
 34#define MC13783_ADC_16CHANS	1
 35#define MC13783_ADC_BPDIV2	2
 36
 37struct mc13783_adc_priv {
 38	struct mc13xxx *mc13xxx;
 39	struct device *hwmon_dev;
 40	char name[PLATFORM_NAME_SIZE];
 41};
 42
 43static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
 44			      *devattr, char *buf)
 45{
 46	struct mc13783_adc_priv *priv = dev_get_drvdata(dev);
 47
 48	return sprintf(buf, "%s\n", priv->name);
 49}
 50
 51static int mc13783_adc_read(struct device *dev,
 52		struct device_attribute *devattr, unsigned int *val)
 53{
 54	struct mc13783_adc_priv *priv = dev_get_drvdata(dev);
 55	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 56	unsigned int channel = attr->index;
 57	unsigned int sample[4];
 58	int ret;
 59
 60	ret = mc13xxx_adc_do_conversion(priv->mc13xxx,
 61			MC13XXX_ADC_MODE_MULT_CHAN,
 62			channel, 0, 0, sample);
 63	if (ret)
 64		return ret;
 65
 
 
 
 
 66	channel &= 0x7;
 67
 68	*val = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
 69
 70	return 0;
 71}
 72
 73static ssize_t mc13783_adc_read_bp(struct device *dev,
 74		struct device_attribute *devattr, char *buf)
 
 75{
 76	unsigned val;
 77	struct platform_device *pdev = to_platform_device(dev);
 78	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
 79	int ret = mc13783_adc_read(dev, devattr, &val);
 80
 81	if (ret)
 82		return ret;
 83
 84	if (driver_data & MC13783_ADC_BPDIV2)
 85		val = DIV_ROUND_CLOSEST(val * 9, 2);
 86	else
 87		/*
 88		 * BP (channel 2) reports with offset 2.4V to the actual value
 89		 * to fit the input range of the ADC.  unit = 2.25mV = 9/4 mV.
 90		 */
 91		val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400;
 92
 93	return sprintf(buf, "%u\n", val);
 94}
 95
 96static ssize_t mc13783_adc_read_gp(struct device *dev,
 97		struct device_attribute *devattr, char *buf)
 
 98{
 99	unsigned val;
100	int ret = mc13783_adc_read(dev, devattr, &val);
101
102	if (ret)
103		return ret;
104
105	/*
106	 * input range is [0, 2.3V], val has 10 bits, so each bit
107	 * is worth 9/4 mV.
108	 */
109	val = DIV_ROUND_CLOSEST(val * 9, 4);
110
111	return sprintf(buf, "%u\n", val);
112}
113
114static DEVICE_ATTR(name, S_IRUGO, mc13783_adc_show_name, NULL);
115static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, mc13783_adc_read_bp, NULL, 2);
116static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, mc13783_adc_read_gp, NULL, 5);
117static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, mc13783_adc_read_gp, NULL, 6);
118static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, mc13783_adc_read_gp, NULL, 7);
119static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, mc13783_adc_read_gp, NULL, 8);
120static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, mc13783_adc_read_gp, NULL, 9);
121static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, mc13783_adc_read_gp, NULL, 10);
122static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, mc13783_adc_read_gp, NULL, 11);
123static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, mc13783_adc_read_gp, NULL, 12);
124static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13);
125static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14);
126static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
128static struct attribute *mc13783_attr_base[] = {
129	&dev_attr_name.attr,
130	&sensor_dev_attr_in2_input.dev_attr.attr,
131	&sensor_dev_attr_in5_input.dev_attr.attr,
132	&sensor_dev_attr_in6_input.dev_attr.attr,
133	&sensor_dev_attr_in7_input.dev_attr.attr,
 
 
134	NULL
135};
136
137static const struct attribute_group mc13783_group_base = {
138	.attrs = mc13783_attr_base,
139};
140
141/* these are only used if MC13783_ADC_16CHANS is provided in driver data */
142static struct attribute *mc13783_attr_16chans[] = {
143	&sensor_dev_attr_in8_input.dev_attr.attr,
144	&sensor_dev_attr_in9_input.dev_attr.attr,
145	&sensor_dev_attr_in10_input.dev_attr.attr,
146	&sensor_dev_attr_in11_input.dev_attr.attr,
147	NULL
148};
149
150static const struct attribute_group mc13783_group_16chans = {
151	.attrs = mc13783_attr_16chans,
152};
153
154/* last four channels may be occupied by the touchscreen */
155static struct attribute *mc13783_attr_ts[] = {
156	&sensor_dev_attr_in12_input.dev_attr.attr,
157	&sensor_dev_attr_in13_input.dev_attr.attr,
158	&sensor_dev_attr_in14_input.dev_attr.attr,
159	&sensor_dev_attr_in15_input.dev_attr.attr,
160	NULL
161};
162
163static const struct attribute_group mc13783_group_ts = {
164	.attrs = mc13783_attr_ts,
165};
166
167static int mc13783_adc_use_touchscreen(struct platform_device *pdev)
168{
169	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
170	unsigned flags = mc13xxx_get_flags(priv->mc13xxx);
171
172	return flags & MC13XXX_USE_TOUCHSCREEN;
173}
174
175static int __init mc13783_adc_probe(struct platform_device *pdev)
176{
177	struct mc13783_adc_priv *priv;
178	int ret;
179	const struct platform_device_id *id = platform_get_device_id(pdev);
180	char *dash;
181
182	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
183	if (!priv)
184		return -ENOMEM;
185
186	priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
187	snprintf(priv->name, ARRAY_SIZE(priv->name), "%s", id->name);
188	dash = strchr(priv->name, '-');
189	if (dash)
190		*dash = '\0';
191
192	platform_set_drvdata(pdev, priv);
193
194	/* Register sysfs hooks */
195	ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base);
196	if (ret)
197		return ret;
198
199	if (id->driver_data & MC13783_ADC_16CHANS) {
200		ret = sysfs_create_group(&pdev->dev.kobj,
201				&mc13783_group_16chans);
202		if (ret)
203			goto out_err_create_16chans;
204	}
205
206	if (!mc13783_adc_use_touchscreen(pdev)) {
207		ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts);
208		if (ret)
209			goto out_err_create_ts;
210	}
211
212	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
213	if (IS_ERR(priv->hwmon_dev)) {
214		ret = PTR_ERR(priv->hwmon_dev);
215		dev_err(&pdev->dev,
216				"hwmon_device_register failed with %d.\n", ret);
217		goto out_err_register;
218	}
219
220	return 0;
221
222out_err_register:
223
224	if (!mc13783_adc_use_touchscreen(pdev))
225		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
226out_err_create_ts:
227
228	if (id->driver_data & MC13783_ADC_16CHANS)
229		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans);
230out_err_create_16chans:
231
232	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base);
233	return ret;
234}
235
236static int mc13783_adc_remove(struct platform_device *pdev)
237{
238	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
239	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
240
241	hwmon_device_unregister(priv->hwmon_dev);
242
243	if (!mc13783_adc_use_touchscreen(pdev))
244		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
245
246	if (driver_data & MC13783_ADC_16CHANS)
247		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans);
248
249	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base);
250
251	return 0;
252}
253
254static const struct platform_device_id mc13783_adc_idtable[] = {
255	{
256		.name = "mc13783-adc",
257		.driver_data = MC13783_ADC_16CHANS,
258	}, {
259		.name = "mc13892-adc",
260		.driver_data = MC13783_ADC_BPDIV2,
261	}, {
262		/* sentinel */
263	}
264};
265MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable);
266
267static struct platform_driver mc13783_adc_driver = {
268	.remove		= mc13783_adc_remove,
269	.driver		= {
270		.name	= DRIVER_NAME,
271	},
272	.id_table	= mc13783_adc_idtable,
273};
274
275module_platform_driver_probe(mc13783_adc_driver, mc13783_adc_probe);
276
277MODULE_DESCRIPTION("MC13783 ADC driver");
278MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
279MODULE_LICENSE("GPL");