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_bp_show(struct device
*dev
,
67 struct device_attribute
*devattr
,
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
);
78 if (driver_data
& MC13783_ADC_BPDIV2
)
79 val
= DIV_ROUND_CLOSEST(val
* 9, 2);
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.
85 val
= DIV_ROUND_CLOSEST(val
* 9, 4) + 2400;
87 return sprintf(buf
, "%u\n", val
);
90 static ssize_t
mc13783_adc_gp_show(struct device
*dev
,
91 struct device_attribute
*devattr
,
95 int ret
= mc13783_adc_read(dev
, devattr
, &val
);
101 * input range is [0, 2.3V], val has 10 bits, so each bit
104 val
= DIV_ROUND_CLOSEST(val
* 9, 4);
106 return sprintf(buf
, "%u\n", val
);
109 static ssize_t
mc13783_adc_uid_show(struct device
*dev
,
110 struct device_attribute
*devattr
,
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
);
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);
125 /* MC13783 have 0.9 divider, input range is [0, 2.555V] */
126 val
= DIV_ROUND_CLOSEST(val
* 2555, 1024);
128 return sprintf(buf
, "%u\n", val
);
131 static ssize_t
mc13783_adc_temp_show(struct device
*dev
,
132 struct device_attribute
*devattr
,
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
);
143 if (driver_data
& MC13783_ADC_BPDIV2
) {
146 * Die Temperature Read Out Code at 25C 680
147 * Temperature change per LSB +0.4244C
149 ret
= DIV_ROUND_CLOSEST(-2635920 + val
* 4244, 10);
153 * Die Temperature Read Out Code at 25C 282
154 * Temperature change per LSB -1.14C
156 ret
= 346480 - 1140 * val
;
159 return sprintf(buf
, "%d\n", ret
);
162 static DEVICE_ATTR_RO(name
);
163 static SENSOR_DEVICE_ATTR_RO(in2_input
, mc13783_adc_bp
, 2);
164 static SENSOR_DEVICE_ATTR_RO(in5_input
, mc13783_adc_gp
, 5);
165 static SENSOR_DEVICE_ATTR_RO(in6_input
, mc13783_adc_gp
, 6);
166 static SENSOR_DEVICE_ATTR_RO(in7_input
, mc13783_adc_gp
, 7);
167 static SENSOR_DEVICE_ATTR_RO(in8_input
, mc13783_adc_gp
, 8);
168 static SENSOR_DEVICE_ATTR_RO(in9_input
, mc13783_adc_gp
, 9);
169 static SENSOR_DEVICE_ATTR_RO(in10_input
, mc13783_adc_gp
, 10);
170 static SENSOR_DEVICE_ATTR_RO(in11_input
, mc13783_adc_gp
, 11);
171 static SENSOR_DEVICE_ATTR_RO(in12_input
, mc13783_adc_gp
, 12);
172 static SENSOR_DEVICE_ATTR_RO(in13_input
, mc13783_adc_gp
, 13);
173 static SENSOR_DEVICE_ATTR_RO(in14_input
, mc13783_adc_gp
, 14);
174 static SENSOR_DEVICE_ATTR_RO(in15_input
, mc13783_adc_gp
, 15);
175 static SENSOR_DEVICE_ATTR_RO(in16_input
, mc13783_adc_uid
, 16);
176 static SENSOR_DEVICE_ATTR_RO(temp1_input
, mc13783_adc_temp
, 17);
178 static struct attribute
*mc13783_attr_base
[] = {
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
,
189 static const struct attribute_group mc13783_group_base
= {
190 .attrs
= mc13783_attr_base
,
193 /* these are only used if MC13783_ADC_16CHANS is provided in driver data */
194 static 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
,
202 static const struct attribute_group mc13783_group_16chans
= {
203 .attrs
= mc13783_attr_16chans
,
206 /* last four channels may be occupied by the touchscreen */
207 static 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
,
215 static const struct attribute_group mc13783_group_ts
= {
216 .attrs
= mc13783_attr_ts
,
219 static int mc13783_adc_use_touchscreen(struct platform_device
*pdev
)
221 struct mc13783_adc_priv
*priv
= platform_get_drvdata(pdev
);
222 unsigned flags
= mc13xxx_get_flags(priv
->mc13xxx
);
224 return flags
& MC13XXX_USE_TOUCHSCREEN
;
227 static int __init
mc13783_adc_probe(struct platform_device
*pdev
)
229 struct mc13783_adc_priv
*priv
;
231 const struct platform_device_id
*id
= platform_get_device_id(pdev
);
234 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
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
, '-');
244 platform_set_drvdata(pdev
, priv
);
246 /* Register sysfs hooks */
247 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
251 if (id
->driver_data
& MC13783_ADC_16CHANS
) {
252 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
253 &mc13783_group_16chans
);
255 goto out_err_create_16chans
;
258 if (!mc13783_adc_use_touchscreen(pdev
)) {
259 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
261 goto out_err_create_ts
;
264 priv
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
265 if (IS_ERR(priv
->hwmon_dev
)) {
266 ret
= PTR_ERR(priv
->hwmon_dev
);
268 "hwmon_device_register failed with %d.\n", ret
);
269 goto out_err_register
;
276 if (!mc13783_adc_use_touchscreen(pdev
))
277 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
280 if (id
->driver_data
& MC13783_ADC_16CHANS
)
281 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_16chans
);
282 out_err_create_16chans
:
284 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
288 static int mc13783_adc_remove(struct platform_device
*pdev
)
290 struct mc13783_adc_priv
*priv
= platform_get_drvdata(pdev
);
291 kernel_ulong_t driver_data
= platform_get_device_id(pdev
)->driver_data
;
293 hwmon_device_unregister(priv
->hwmon_dev
);
295 if (!mc13783_adc_use_touchscreen(pdev
))
296 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_ts
);
298 if (driver_data
& MC13783_ADC_16CHANS
)
299 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_16chans
);
301 sysfs_remove_group(&pdev
->dev
.kobj
, &mc13783_group_base
);
306 static const struct platform_device_id mc13783_adc_idtable
[] = {
308 .name
= "mc13783-adc",
309 .driver_data
= MC13783_ADC_16CHANS
,
311 .name
= "mc13892-adc",
312 .driver_data
= MC13783_ADC_BPDIV2
,
317 MODULE_DEVICE_TABLE(platform
, mc13783_adc_idtable
);
319 static struct platform_driver mc13783_adc_driver
= {
320 .remove
= mc13783_adc_remove
,
324 .id_table
= mc13783_adc_idtable
,
327 module_platform_driver_probe(mc13783_adc_driver
, mc13783_adc_probe
);
329 MODULE_DESCRIPTION("MC13783 ADC driver");
330 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
331 MODULE_LICENSE("GPL");