2 * TI LP8788 MFD - ADC driver
4 * Copyright 2012 Texas Instruments
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/delay.h>
14 #include <linux/iio/iio.h>
15 #include <linux/iio/driver.h>
16 #include <linux/iio/machine.h>
17 #include <linux/mfd/lp8788.h>
18 #include <linux/module.h>
19 #include <linux/mutex.h>
20 #include <linux/platform_device.h>
21 #include <linux/slab.h>
23 /* register address */
24 #define LP8788_ADC_CONF 0x60
25 #define LP8788_ADC_RAW 0x61
26 #define LP8788_ADC_DONE 0x63
28 #define ADC_CONV_START 1
36 static const int lp8788_scale
[LPADC_MAX
] = {
37 [LPADC_VBATT_5P5
] = 1343101,
38 [LPADC_VIN_CHG
] = 3052503,
39 [LPADC_IBATT
] = 610500,
40 [LPADC_IC_TEMP
] = 61050,
41 [LPADC_VBATT_6P0
] = 1465201,
42 [LPADC_VBATT_5P0
] = 1221001,
43 [LPADC_ADC1
] = 610500,
44 [LPADC_ADC2
] = 610500,
45 [LPADC_VDD
] = 1025641,
46 [LPADC_VCOIN
] = 757020,
47 [LPADC_ADC3
] = 610500,
48 [LPADC_ADC4
] = 610500,
51 static int lp8788_get_adc_result(struct lp8788_adc
*adc
, enum lp8788_adc_id id
,
59 int size
= ARRAY_SIZE(rawdata
);
63 data
= (id
<< 1) | ADC_CONV_START
;
64 ret
= lp8788_write_byte(adc
->lp
, LP8788_ADC_CONF
, data
);
68 /* retry until adc conversion is done */
71 usleep_range(100, 200);
73 ret
= lp8788_read_byte(adc
->lp
, LP8788_ADC_DONE
, &data
);
82 ret
= lp8788_read_multi_bytes(adc
->lp
, LP8788_ADC_RAW
, rawdata
, size
);
86 msb
= (rawdata
[0] << 4) & 0x00000ff0;
87 lsb
= (rawdata
[1] >> 4) & 0x0000000f;
97 static int lp8788_adc_read_raw(struct iio_dev
*indio_dev
,
98 struct iio_chan_spec
const *chan
,
99 int *val
, int *val2
, long mask
)
101 struct lp8788_adc
*adc
= iio_priv(indio_dev
);
102 enum lp8788_adc_id id
= chan
->channel
;
105 mutex_lock(&adc
->lock
);
108 case IIO_CHAN_INFO_RAW
:
109 ret
= lp8788_get_adc_result(adc
, id
, val
) ? -EIO
: IIO_VAL_INT
;
111 case IIO_CHAN_INFO_SCALE
:
112 *val
= lp8788_scale
[id
] / 1000000;
113 *val2
= lp8788_scale
[id
] % 1000000;
114 ret
= IIO_VAL_INT_PLUS_MICRO
;
121 mutex_unlock(&adc
->lock
);
126 static const struct iio_info lp8788_adc_info
= {
127 .read_raw
= &lp8788_adc_read_raw
,
128 .driver_module
= THIS_MODULE
,
131 #define LP8788_CHAN(_id, _type) { \
134 .channel = LPADC_##_id, \
135 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
136 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
137 .datasheet_name = #_id, \
140 static const struct iio_chan_spec lp8788_adc_channels
[] = {
141 [LPADC_VBATT_5P5
] = LP8788_CHAN(VBATT_5P5
, IIO_VOLTAGE
),
142 [LPADC_VIN_CHG
] = LP8788_CHAN(VIN_CHG
, IIO_VOLTAGE
),
143 [LPADC_IBATT
] = LP8788_CHAN(IBATT
, IIO_CURRENT
),
144 [LPADC_IC_TEMP
] = LP8788_CHAN(IC_TEMP
, IIO_TEMP
),
145 [LPADC_VBATT_6P0
] = LP8788_CHAN(VBATT_6P0
, IIO_VOLTAGE
),
146 [LPADC_VBATT_5P0
] = LP8788_CHAN(VBATT_5P0
, IIO_VOLTAGE
),
147 [LPADC_ADC1
] = LP8788_CHAN(ADC1
, IIO_VOLTAGE
),
148 [LPADC_ADC2
] = LP8788_CHAN(ADC2
, IIO_VOLTAGE
),
149 [LPADC_VDD
] = LP8788_CHAN(VDD
, IIO_VOLTAGE
),
150 [LPADC_VCOIN
] = LP8788_CHAN(VCOIN
, IIO_VOLTAGE
),
151 [LPADC_ADC3
] = LP8788_CHAN(ADC3
, IIO_VOLTAGE
),
152 [LPADC_ADC4
] = LP8788_CHAN(ADC4
, IIO_VOLTAGE
),
155 /* default maps used by iio consumer (lp8788-charger driver) */
156 static struct iio_map lp8788_default_iio_maps
[] = {
158 .consumer_dev_name
= "lp8788-charger",
159 .consumer_channel
= "lp8788_vbatt_5p0",
160 .adc_channel_label
= "VBATT_5P0",
163 .consumer_dev_name
= "lp8788-charger",
164 .consumer_channel
= "lp8788_adc1",
165 .adc_channel_label
= "ADC1",
170 static int lp8788_iio_map_register(struct iio_dev
*indio_dev
,
171 struct lp8788_platform_data
*pdata
,
172 struct lp8788_adc
*adc
)
177 map
= (!pdata
|| !pdata
->adc_pdata
) ?
178 lp8788_default_iio_maps
: pdata
->adc_pdata
;
180 ret
= iio_map_array_register(indio_dev
, map
);
182 dev_err(&indio_dev
->dev
, "iio map err: %d\n", ret
);
190 static int lp8788_adc_probe(struct platform_device
*pdev
)
192 struct lp8788
*lp
= dev_get_drvdata(pdev
->dev
.parent
);
193 struct iio_dev
*indio_dev
;
194 struct lp8788_adc
*adc
;
197 indio_dev
= iio_device_alloc(sizeof(*adc
));
201 adc
= iio_priv(indio_dev
);
203 platform_set_drvdata(pdev
, indio_dev
);
205 indio_dev
->dev
.of_node
= pdev
->dev
.of_node
;
206 ret
= lp8788_iio_map_register(indio_dev
, lp
->pdata
, adc
);
210 mutex_init(&adc
->lock
);
212 indio_dev
->dev
.parent
= &pdev
->dev
;
213 indio_dev
->name
= pdev
->name
;
214 indio_dev
->modes
= INDIO_DIRECT_MODE
;
215 indio_dev
->info
= &lp8788_adc_info
;
216 indio_dev
->channels
= lp8788_adc_channels
;
217 indio_dev
->num_channels
= ARRAY_SIZE(lp8788_adc_channels
);
219 ret
= iio_device_register(indio_dev
);
221 dev_err(&pdev
->dev
, "iio dev register err: %d\n", ret
);
228 iio_map_array_unregister(indio_dev
);
230 iio_device_free(indio_dev
);
234 static int lp8788_adc_remove(struct platform_device
*pdev
)
236 struct iio_dev
*indio_dev
= platform_get_drvdata(pdev
);
238 iio_device_unregister(indio_dev
);
239 iio_map_array_unregister(indio_dev
);
240 iio_device_free(indio_dev
);
245 static struct platform_driver lp8788_adc_driver
= {
246 .probe
= lp8788_adc_probe
,
247 .remove
= lp8788_adc_remove
,
249 .name
= LP8788_DEV_ADC
,
250 .owner
= THIS_MODULE
,
253 module_platform_driver(lp8788_adc_driver
);
255 MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver");
256 MODULE_AUTHOR("Milo Kim");
257 MODULE_LICENSE("GPL");
258 MODULE_ALIAS("platform:lp8788-adc");