2 * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs.
4 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
5 * Copyright (C) 2009 Sascha Hauer, Pengutronix
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.
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
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>
31 #define DRIVER_NAME "mc13783-adc"
33 /* platform device id driver data */
34 #define MC13783_ADC_16CHANS 1
35 #define MC13783_ADC_BPDIV2 2
37 struct mc13783_adc_priv
{
38 struct mc13xxx
*mc13xxx
;
39 struct device
*hwmon_dev
;
40 char name
[PLATFORM_NAME_SIZE
];
43 static ssize_t
name_show(struct device
*dev
, struct device_attribute
*devattr
,
46 struct mc13783_adc_priv
*priv
= dev_get_drvdata(dev
);
48 return sprintf(buf
, "%s\n", priv
->name
);
51 static int mc13783_adc_read(struct device
*dev
,
52 struct device_attribute
*devattr
, unsigned int *val
)
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];
60 ret
= mc13xxx_adc_do_conversion(priv
->mc13xxx
,
61 MC13XXX_ADC_MODE_MULT_CHAN
,
62 channel
, 0, 0, sample
);
66 /* ADIN7 subchannels */
72 *val
= (sample
[channel
% 4] >> (channel
> 3 ? 14 : 2)) & 0x3ff;
77 static ssize_t
mc13783_adc_read_bp(struct device
*dev
,
78 struct device_attribute
*devattr
, char *buf
)
81 struct platform_device
*pdev
= to_platform_device(dev
);
82 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
83 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
88 if (driver_data
& MC13783_ADC_BPDIV2
)
89 val
= DIV_ROUND_CLOSEST(val
* 9, 2);
92 * BP (channel 2) reports with offset 2.4V to the actual value
93 * to fit the input range of the ADC. unit = 2.25mV = 9/4 mV.
95 val
= DIV_ROUND_CLOSEST(val
* 9, 4) + 2400;
97 return sprintf(buf
, "%u\n", val
);
100 static ssize_t
mc13783_adc_read_gp(struct device
*dev
,
101 struct device_attribute
*devattr
, char *buf
)
104 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
110 * input range is [0, 2.3V], val has 10 bits, so each bit
113 val
= DIV_ROUND_CLOSEST(val
* 9, 4);
115 return sprintf(buf
, "%u\n", val
);
118 static ssize_t
mc13783_adc_read_uid(struct device
*dev
,
119 struct device_attribute
*devattr
, char *buf
)
122 struct platform_device
*pdev
= to_platform_device(dev
);
123 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
124 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
129 if (driver_data
& MC13783_ADC_BPDIV2
)
130 /* MC13892 have 1/2 divider, input range is [0, 4.800V] */
131 val
= DIV_ROUND_CLOSEST(val
* 4800, 1024);
133 /* MC13783 have 0.9 divider, input range is [0, 2.555V] */
134 val
= DIV_ROUND_CLOSEST(val
* 2555, 1024);
136 return sprintf(buf
, "%u\n", val
);
139 static ssize_t
mc13783_adc_read_temp(struct device
*dev
,
140 struct device_attribute
*devattr
, char *buf
)
143 struct platform_device
*pdev
= to_platform_device(dev
);
144 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
145 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
150 if (driver_data
& MC13783_ADC_BPDIV2
) {
153 * Die Temperature Read Out Code at 25C 680
154 * Temperature change per LSB +0.4244C
156 ret
= DIV_ROUND_CLOSEST(-2635920 + val
* 4244, 10);
160 * Die Temperature Read Out Code at 25C 282
161 * Temperature change per LSB -1.14C
163 ret
= 346480 - 1140 * val
;
166 return sprintf(buf
, "%d\n", ret
);
169 static DEVICE_ATTR_RO(name
);
170 static SENSOR_DEVICE_ATTR(in2_input
, S_IRUGO
, mc13783_adc_read_bp
, NULL
, 2);
171 static SENSOR_DEVICE_ATTR(in5_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 5);
172 static SENSOR_DEVICE_ATTR(in6_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 6);
173 static SENSOR_DEVICE_ATTR(in7_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 7);
174 static SENSOR_DEVICE_ATTR(in8_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 8);
175 static SENSOR_DEVICE_ATTR(in9_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 9);
176 static SENSOR_DEVICE_ATTR(in10_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 10);
177 static SENSOR_DEVICE_ATTR(in11_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 11);
178 static SENSOR_DEVICE_ATTR(in12_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 12);
179 static SENSOR_DEVICE_ATTR(in13_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 13);
180 static SENSOR_DEVICE_ATTR(in14_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 14);
181 static SENSOR_DEVICE_ATTR(in15_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 15);
182 static SENSOR_DEVICE_ATTR(in16_input
, S_IRUGO
, mc13783_adc_read_uid
, NULL
, 16);
183 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
,
184 mc13783_adc_read_temp
, NULL
, 17);
186 static struct attribute
*mc13783_attr_base
[] = {
188 &sensor_dev_attr_in2_input
.dev_attr
.attr
,
189 &sensor_dev_attr_in5_input
.dev_attr
.attr
,
190 &sensor_dev_attr_in6_input
.dev_attr
.attr
,
191 &sensor_dev_attr_in7_input
.dev_attr
.attr
,
192 &sensor_dev_attr_in16_input
.dev_attr
.attr
,
193 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
197 static const struct attribute_group mc13783_group_base
= {
198 .attrs
= mc13783_attr_base
,
201 /* these are only used if MC13783_ADC_16CHANS is provided in driver data */
202 static struct attribute
*mc13783_attr_16chans
[] = {
203 &sensor_dev_attr_in8_input
.dev_attr
.attr
,
204 &sensor_dev_attr_in9_input
.dev_attr
.attr
,
205 &sensor_dev_attr_in10_input
.dev_attr
.attr
,
206 &sensor_dev_attr_in11_input
.dev_attr
.attr
,
210 static const struct attribute_group mc13783_group_16chans
= {
211 .attrs
= mc13783_attr_16chans
,
214 /* last four channels may be occupied by the touchscreen */
215 static struct attribute
*mc13783_attr_ts
[] = {
216 &sensor_dev_attr_in12_input
.dev_attr
.attr
,
217 &sensor_dev_attr_in13_input
.dev_attr
.attr
,
218 &sensor_dev_attr_in14_input
.dev_attr
.attr
,
219 &sensor_dev_attr_in15_input
.dev_attr
.attr
,
223 static const struct attribute_group mc13783_group_ts
= {
224 .attrs
= mc13783_attr_ts
,
227 static int mc13783_adc_use_touchscreen(struct platform_device
*pdev
)
229 struct mc13783_adc_priv
*priv
= platform_get_drvdata(pdev
);
230 unsigned flags
= mc13xxx_get_flags(priv
->mc13xxx
);
232 return flags
& MC13XXX_USE_TOUCHSCREEN
;
235 static int __init
mc13783_adc_probe(struct platform_device
*pdev
)
237 struct mc13783_adc_priv
*priv
;
239 const struct platform_device_id
*id
= platform_get_device_id(pdev
);
242 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
246 priv
->mc13xxx
= dev_get_drvdata(pdev
->dev
.parent
);
247 snprintf(priv
->name
, ARRAY_SIZE(priv
->name
), "%s", id
->name
);
248 dash
= strchr(priv
->name
, '-');
252 platform_set_drvdata(pdev
, priv
);
254 /* Register sysfs hooks */
255 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
259 if (id
->driver_data
& MC13783_ADC_16CHANS
) {
260 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
261 &mc13783_group_16chans
);
263 goto out_err_create_16chans
;
266 if (!mc13783_adc_use_touchscreen(pdev
)) {
267 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
269 goto out_err_create_ts
;
272 priv
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
273 if (IS_ERR(priv
->hwmon_dev
)) {
274 ret
= PTR_ERR(priv
->hwmon_dev
);
276 "hwmon_device_register failed with %d.\n", ret
);
277 goto out_err_register
;
284 if (!mc13783_adc_use_touchscreen(pdev
))
285 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
288 if (id
->driver_data
& MC13783_ADC_16CHANS
)
289 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_16chans
);
290 out_err_create_16chans
:
292 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
296 static int mc13783_adc_remove(struct platform_device
*pdev
)
298 struct mc13783_adc_priv
*priv
= platform_get_drvdata(pdev
);
299 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
301 hwmon_device_unregister(priv
->hwmon_dev
);
303 if (!mc13783_adc_use_touchscreen(pdev
))
304 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
306 if (driver_data
& MC13783_ADC_16CHANS
)
307 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_16chans
);
309 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
314 static const struct platform_device_id mc13783_adc_idtable
[] = {
316 .name
= "mc13783-adc",
317 .driver_data
= MC13783_ADC_16CHANS
,
319 .name
= "mc13892-adc",
320 .driver_data
= MC13783_ADC_BPDIV2
,
325 MODULE_DEVICE_TABLE(platform
, mc13783_adc_idtable
);
327 static struct platform_driver mc13783_adc_driver
= {
328 .remove
= mc13783_adc_remove
,
332 .id_table
= mc13783_adc_idtable
,
335 module_platform_driver_probe(mc13783_adc_driver
, mc13783_adc_probe
);
337 MODULE_DESCRIPTION("MC13783 ADC driver");
338 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
339 MODULE_LICENSE("GPL");