1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs.
5 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
6 * Copyright (C) 2009 Sascha Hauer, Pengutronix
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>
20 #define DRIVER_NAME "mc13783-adc"
22 /* platform device id driver data */
23 #define MC13783_ADC_16CHANS 1
24 #define MC13783_ADC_BPDIV2 2
26 struct mc13783_adc_priv
{
27 struct mc13xxx
*mc13xxx
;
28 struct device
*hwmon_dev
;
29 char name
[PLATFORM_NAME_SIZE
];
32 static ssize_t
name_show(struct device
*dev
, struct device_attribute
*devattr
,
35 struct mc13783_adc_priv
*priv
= dev_get_drvdata(dev
);
37 return sprintf(buf
, "%s\n", priv
->name
);
40 static int mc13783_adc_read(struct device
*dev
,
41 struct device_attribute
*devattr
, unsigned int *val
)
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];
49 ret
= mc13xxx_adc_do_conversion(priv
->mc13xxx
,
50 MC13XXX_ADC_MODE_MULT_CHAN
,
51 channel
, 0, 0, sample
);
55 /* ADIN7 subchannels */
61 *val
= (sample
[channel
% 4] >> (channel
> 3 ? 14 : 2)) & 0x3ff;
66 static ssize_t
mc13783_adc_read_bp(struct device
*dev
,
67 struct device_attribute
*devattr
, char *buf
)
70 struct platform_device
*pdev
= to_platform_device(dev
);
71 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
72 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
77 if (driver_data
& MC13783_ADC_BPDIV2
)
78 val
= DIV_ROUND_CLOSEST(val
* 9, 2);
81 * BP (channel 2) reports with offset 2.4V to the actual value
82 * to fit the input range of the ADC. unit = 2.25mV = 9/4 mV.
84 val
= DIV_ROUND_CLOSEST(val
* 9, 4) + 2400;
86 return sprintf(buf
, "%u\n", val
);
89 static ssize_t
mc13783_adc_read_gp(struct device
*dev
,
90 struct device_attribute
*devattr
, char *buf
)
93 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
99 * input range is [0, 2.3V], val has 10 bits, so each bit
102 val
= DIV_ROUND_CLOSEST(val
* 9, 4);
104 return sprintf(buf
, "%u\n", val
);
107 static ssize_t
mc13783_adc_read_uid(struct device
*dev
,
108 struct device_attribute
*devattr
, char *buf
)
111 struct platform_device
*pdev
= to_platform_device(dev
);
112 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
113 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
118 if (driver_data
& MC13783_ADC_BPDIV2
)
119 /* MC13892 have 1/2 divider, input range is [0, 4.800V] */
120 val
= DIV_ROUND_CLOSEST(val
* 4800, 1024);
122 /* MC13783 have 0.9 divider, input range is [0, 2.555V] */
123 val
= DIV_ROUND_CLOSEST(val
* 2555, 1024);
125 return sprintf(buf
, "%u\n", val
);
128 static ssize_t
mc13783_adc_read_temp(struct device
*dev
,
129 struct device_attribute
*devattr
, char *buf
)
132 struct platform_device
*pdev
= to_platform_device(dev
);
133 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
134 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
139 if (driver_data
& MC13783_ADC_BPDIV2
) {
142 * Die Temperature Read Out Code at 25C 680
143 * Temperature change per LSB +0.4244C
145 ret
= DIV_ROUND_CLOSEST(-2635920 + val
* 4244, 10);
149 * Die Temperature Read Out Code at 25C 282
150 * Temperature change per LSB -1.14C
152 ret
= 346480 - 1140 * val
;
155 return sprintf(buf
, "%d\n", ret
);
158 static DEVICE_ATTR_RO(name
);
159 static SENSOR_DEVICE_ATTR(in2_input
, S_IRUGO
, mc13783_adc_read_bp
, NULL
, 2);
160 static SENSOR_DEVICE_ATTR(in5_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 5);
161 static SENSOR_DEVICE_ATTR(in6_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 6);
162 static SENSOR_DEVICE_ATTR(in7_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 7);
163 static SENSOR_DEVICE_ATTR(in8_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 8);
164 static SENSOR_DEVICE_ATTR(in9_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 9);
165 static SENSOR_DEVICE_ATTR(in10_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 10);
166 static SENSOR_DEVICE_ATTR(in11_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 11);
167 static SENSOR_DEVICE_ATTR(in12_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 12);
168 static SENSOR_DEVICE_ATTR(in13_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 13);
169 static SENSOR_DEVICE_ATTR(in14_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 14);
170 static SENSOR_DEVICE_ATTR(in15_input
, S_IRUGO
, mc13783_adc_read_gp
, NULL
, 15);
171 static SENSOR_DEVICE_ATTR(in16_input
, S_IRUGO
, mc13783_adc_read_uid
, NULL
, 16);
172 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
,
173 mc13783_adc_read_temp
, NULL
, 17);
175 static struct attribute
*mc13783_attr_base
[] = {
177 &sensor_dev_attr_in2_input
.dev_attr
.attr
,
178 &sensor_dev_attr_in5_input
.dev_attr
.attr
,
179 &sensor_dev_attr_in6_input
.dev_attr
.attr
,
180 &sensor_dev_attr_in7_input
.dev_attr
.attr
,
181 &sensor_dev_attr_in16_input
.dev_attr
.attr
,
182 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
186 static const struct attribute_group mc13783_group_base
= {
187 .attrs
= mc13783_attr_base
,
190 /* these are only used if MC13783_ADC_16CHANS is provided in driver data */
191 static struct attribute
*mc13783_attr_16chans
[] = {
192 &sensor_dev_attr_in8_input
.dev_attr
.attr
,
193 &sensor_dev_attr_in9_input
.dev_attr
.attr
,
194 &sensor_dev_attr_in10_input
.dev_attr
.attr
,
195 &sensor_dev_attr_in11_input
.dev_attr
.attr
,
199 static const struct attribute_group mc13783_group_16chans
= {
200 .attrs
= mc13783_attr_16chans
,
203 /* last four channels may be occupied by the touchscreen */
204 static struct attribute
*mc13783_attr_ts
[] = {
205 &sensor_dev_attr_in12_input
.dev_attr
.attr
,
206 &sensor_dev_attr_in13_input
.dev_attr
.attr
,
207 &sensor_dev_attr_in14_input
.dev_attr
.attr
,
208 &sensor_dev_attr_in15_input
.dev_attr
.attr
,
212 static const struct attribute_group mc13783_group_ts
= {
213 .attrs
= mc13783_attr_ts
,
216 static int mc13783_adc_use_touchscreen(struct platform_device
*pdev
)
218 struct mc13783_adc_priv
*priv
= platform_get_drvdata(pdev
);
219 unsigned flags
= mc13xxx_get_flags(priv
->mc13xxx
);
221 return flags
& MC13XXX_USE_TOUCHSCREEN
;
224 static int __init
mc13783_adc_probe(struct platform_device
*pdev
)
226 struct mc13783_adc_priv
*priv
;
228 const struct platform_device_id
*id
= platform_get_device_id(pdev
);
231 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
235 priv
->mc13xxx
= dev_get_drvdata(pdev
->dev
.parent
);
236 snprintf(priv
->name
, ARRAY_SIZE(priv
->name
), "%s", id
->name
);
237 dash
= strchr(priv
->name
, '-');
241 platform_set_drvdata(pdev
, priv
);
243 /* Register sysfs hooks */
244 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
248 if (id
->driver_data
& MC13783_ADC_16CHANS
) {
249 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
250 &mc13783_group_16chans
);
252 goto out_err_create_16chans
;
255 if (!mc13783_adc_use_touchscreen(pdev
)) {
256 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
258 goto out_err_create_ts
;
261 priv
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
262 if (IS_ERR(priv
->hwmon_dev
)) {
263 ret
= PTR_ERR(priv
->hwmon_dev
);
265 "hwmon_device_register failed with %d.\n", ret
);
266 goto out_err_register
;
273 if (!mc13783_adc_use_touchscreen(pdev
))
274 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
277 if (id
->driver_data
& MC13783_ADC_16CHANS
)
278 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_16chans
);
279 out_err_create_16chans
:
281 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
285 static int mc13783_adc_remove(struct platform_device
*pdev
)
287 struct mc13783_adc_priv
*priv
= platform_get_drvdata(pdev
);
288 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
290 hwmon_device_unregister(priv
->hwmon_dev
);
292 if (!mc13783_adc_use_touchscreen(pdev
))
293 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
295 if (driver_data
& MC13783_ADC_16CHANS
)
296 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_16chans
);
298 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
303 static const struct platform_device_id mc13783_adc_idtable
[] = {
305 .name
= "mc13783-adc",
306 .driver_data
= MC13783_ADC_16CHANS
,
308 .name
= "mc13892-adc",
309 .driver_data
= MC13783_ADC_BPDIV2
,
314 MODULE_DEVICE_TABLE(platform
, mc13783_adc_idtable
);
316 static struct platform_driver mc13783_adc_driver
= {
317 .remove
= mc13783_adc_remove
,
321 .id_table
= mc13783_adc_idtable
,
324 module_platform_driver_probe(mc13783_adc_driver
, mc13783_adc_probe
);
326 MODULE_DESCRIPTION("MC13783 ADC driver");
327 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
328 MODULE_LICENSE("GPL");