1 // SPDX-License-Identifier: GPL-2.0-only
3 * TI LP8788 MFD - ADC driver
5 * Copyright 2012 Texas Instruments
7 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
10 #include <linux/delay.h>
11 #include <linux/iio/iio.h>
12 #include <linux/iio/driver.h>
13 #include <linux/iio/machine.h>
14 #include <linux/mfd/lp8788.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
20 /* register address */
21 #define LP8788_ADC_CONF 0x60
22 #define LP8788_ADC_RAW 0x61
23 #define LP8788_ADC_DONE 0x63
25 #define ADC_CONV_START 1
29 const struct iio_map
*map
;
33 static const int lp8788_scale
[LPADC_MAX
] = {
34 [LPADC_VBATT_5P5
] = 1343101,
35 [LPADC_VIN_CHG
] = 3052503,
36 [LPADC_IBATT
] = 610500,
37 [LPADC_IC_TEMP
] = 61050,
38 [LPADC_VBATT_6P0
] = 1465201,
39 [LPADC_VBATT_5P0
] = 1221001,
40 [LPADC_ADC1
] = 610500,
41 [LPADC_ADC2
] = 610500,
42 [LPADC_VDD
] = 1025641,
43 [LPADC_VCOIN
] = 757020,
44 [LPADC_ADC3
] = 610500,
45 [LPADC_ADC4
] = 610500,
48 static int lp8788_get_adc_result(struct lp8788_adc
*adc
, enum lp8788_adc_id id
,
56 int size
= ARRAY_SIZE(rawdata
);
60 data
= (id
<< 1) | ADC_CONV_START
;
61 ret
= lp8788_write_byte(adc
->lp
, LP8788_ADC_CONF
, data
);
65 /* retry until adc conversion is done */
68 usleep_range(100, 200);
70 ret
= lp8788_read_byte(adc
->lp
, LP8788_ADC_DONE
, &data
);
79 ret
= lp8788_read_multi_bytes(adc
->lp
, LP8788_ADC_RAW
, rawdata
, size
);
83 msb
= (rawdata
[0] << 4) & 0x00000ff0;
84 lsb
= (rawdata
[1] >> 4) & 0x0000000f;
94 static int lp8788_adc_read_raw(struct iio_dev
*indio_dev
,
95 struct iio_chan_spec
const *chan
,
96 int *val
, int *val2
, long mask
)
98 struct lp8788_adc
*adc
= iio_priv(indio_dev
);
99 enum lp8788_adc_id id
= chan
->channel
;
102 mutex_lock(&adc
->lock
);
105 case IIO_CHAN_INFO_RAW
:
106 ret
= lp8788_get_adc_result(adc
, id
, val
) ? -EIO
: IIO_VAL_INT
;
108 case IIO_CHAN_INFO_SCALE
:
109 *val
= lp8788_scale
[id
] / 1000000;
110 *val2
= lp8788_scale
[id
] % 1000000;
111 ret
= IIO_VAL_INT_PLUS_MICRO
;
118 mutex_unlock(&adc
->lock
);
123 static const struct iio_info lp8788_adc_info
= {
124 .read_raw
= &lp8788_adc_read_raw
,
127 #define LP8788_CHAN(_id, _type) { \
130 .channel = LPADC_##_id, \
131 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
132 BIT(IIO_CHAN_INFO_SCALE), \
133 .datasheet_name = #_id, \
136 static const struct iio_chan_spec lp8788_adc_channels
[] = {
137 [LPADC_VBATT_5P5
] = LP8788_CHAN(VBATT_5P5
, IIO_VOLTAGE
),
138 [LPADC_VIN_CHG
] = LP8788_CHAN(VIN_CHG
, IIO_VOLTAGE
),
139 [LPADC_IBATT
] = LP8788_CHAN(IBATT
, IIO_CURRENT
),
140 [LPADC_IC_TEMP
] = LP8788_CHAN(IC_TEMP
, IIO_TEMP
),
141 [LPADC_VBATT_6P0
] = LP8788_CHAN(VBATT_6P0
, IIO_VOLTAGE
),
142 [LPADC_VBATT_5P0
] = LP8788_CHAN(VBATT_5P0
, IIO_VOLTAGE
),
143 [LPADC_ADC1
] = LP8788_CHAN(ADC1
, IIO_VOLTAGE
),
144 [LPADC_ADC2
] = LP8788_CHAN(ADC2
, IIO_VOLTAGE
),
145 [LPADC_VDD
] = LP8788_CHAN(VDD
, IIO_VOLTAGE
),
146 [LPADC_VCOIN
] = LP8788_CHAN(VCOIN
, IIO_VOLTAGE
),
147 [LPADC_ADC3
] = LP8788_CHAN(ADC3
, IIO_VOLTAGE
),
148 [LPADC_ADC4
] = LP8788_CHAN(ADC4
, IIO_VOLTAGE
),
151 /* default maps used by iio consumer (lp8788-charger driver) */
152 static const struct iio_map lp8788_default_iio_maps
[] = {
153 IIO_MAP("VBATT_5P0", "lp8788-charger", "lp8788_vbatt_5p0"),
154 IIO_MAP("ADC1", "lp8788-charger", "lp8788_adc1"),
158 static int lp8788_iio_map_register(struct device
*dev
,
159 struct iio_dev
*indio_dev
,
160 struct lp8788_platform_data
*pdata
,
161 struct lp8788_adc
*adc
)
163 const struct iio_map
*map
;
166 map
= (!pdata
|| !pdata
->adc_pdata
) ?
167 lp8788_default_iio_maps
: pdata
->adc_pdata
;
169 ret
= devm_iio_map_array_register(dev
, indio_dev
, map
);
171 dev_err(&indio_dev
->dev
, "iio map err: %d\n", ret
);
179 static int lp8788_adc_probe(struct platform_device
*pdev
)
181 struct lp8788
*lp
= dev_get_drvdata(pdev
->dev
.parent
);
182 struct iio_dev
*indio_dev
;
183 struct lp8788_adc
*adc
;
186 indio_dev
= devm_iio_device_alloc(&pdev
->dev
, sizeof(*adc
));
190 adc
= iio_priv(indio_dev
);
193 ret
= lp8788_iio_map_register(&pdev
->dev
, indio_dev
, lp
->pdata
, adc
);
197 mutex_init(&adc
->lock
);
199 indio_dev
->name
= pdev
->name
;
200 indio_dev
->modes
= INDIO_DIRECT_MODE
;
201 indio_dev
->info
= &lp8788_adc_info
;
202 indio_dev
->channels
= lp8788_adc_channels
;
203 indio_dev
->num_channels
= ARRAY_SIZE(lp8788_adc_channels
);
205 return devm_iio_device_register(&pdev
->dev
, indio_dev
);
208 static struct platform_driver lp8788_adc_driver
= {
209 .probe
= lp8788_adc_probe
,
211 .name
= LP8788_DEV_ADC
,
214 module_platform_driver(lp8788_adc_driver
);
216 MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver");
217 MODULE_AUTHOR("Milo Kim");
218 MODULE_LICENSE("GPL");
219 MODULE_ALIAS("platform:lp8788-adc");