1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f5ce4a7aSOskar Andero /*
3f5ce4a7aSOskar Andero * Copyright (C) 2013 Oskar Andero <oskar.andero@gmail.com>
4b12206e9SSøren Andersen * Copyright (C) 2014 Rose Technology
5b12206e9SSøren Andersen * Allan Bendorff Jensen <abj@rosetechnology.dk>
6b12206e9SSøren Andersen * Soren Andersen <san@rosetechnology.dk>
7f5ce4a7aSOskar Andero *
8b12206e9SSøren Andersen * Driver for following ADC chips from Microchip Technology's:
9b12206e9SSøren Andersen * 10 Bit converter
10b12206e9SSøren Andersen * MCP3001
11b12206e9SSøren Andersen * MCP3002
12b12206e9SSøren Andersen * MCP3004
13b12206e9SSøren Andersen * MCP3008
14b12206e9SSøren Andersen * ------------
15b12206e9SSøren Andersen * 12 bit converter
16b12206e9SSøren Andersen * MCP3201
17b12206e9SSøren Andersen * MCP3202
18b12206e9SSøren Andersen * MCP3204
19b12206e9SSøren Andersen * MCP3208
20b12206e9SSøren Andersen * ------------
21e6f47943SLukas Wunner * 13 bit converter
22e6f47943SLukas Wunner * MCP3301
23c1375d67SLukas Wunner * ------------
24c1375d67SLukas Wunner * 22 bit converter
25c1375d67SLukas Wunner * MCP3550
26c1375d67SLukas Wunner * MCP3551
27c1375d67SLukas Wunner * MCP3553
28b12206e9SSøren Andersen *
29f5ce4a7aSOskar Andero * Datasheet can be found here:
303593cd53SAlexander A. Klimov * https://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001
313593cd53SAlexander A. Klimov * https://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf mcp3002
323593cd53SAlexander A. Klimov * https://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf mcp3004/08
33b12206e9SSøren Andersen * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf mcp3201
34b12206e9SSøren Andersen * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf mcp3202
35b12206e9SSøren Andersen * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf mcp3204/08
363593cd53SAlexander A. Klimov * https://ww1.microchip.com/downloads/en/DeviceDoc/21700E.pdf mcp3301
37c1375d67SLukas Wunner * http://ww1.microchip.com/downloads/en/DeviceDoc/21950D.pdf mcp3550/1/3
38f5ce4a7aSOskar Andero */
39f5ce4a7aSOskar Andero
40f5ce4a7aSOskar Andero #include <linux/err.h>
41b12206e9SSøren Andersen #include <linux/delay.h>
42f5ce4a7aSOskar Andero #include <linux/spi/spi.h>
43f5ce4a7aSOskar Andero #include <linux/module.h>
44016d271eSJonathan Cameron #include <linux/mod_devicetable.h>
45f5ce4a7aSOskar Andero #include <linux/iio/iio.h>
46f5ce4a7aSOskar Andero #include <linux/regulator/consumer.h>
47f5ce4a7aSOskar Andero
48f5ce4a7aSOskar Andero enum {
49b12206e9SSøren Andersen mcp3001,
50b12206e9SSøren Andersen mcp3002,
51b12206e9SSøren Andersen mcp3004,
52b12206e9SSøren Andersen mcp3008,
53b12206e9SSøren Andersen mcp3201,
54b12206e9SSøren Andersen mcp3202,
55f5ce4a7aSOskar Andero mcp3204,
56f5ce4a7aSOskar Andero mcp3208,
57f686a36bSAndrea Galbusera mcp3301,
58c1375d67SLukas Wunner mcp3550_50,
59c1375d67SLukas Wunner mcp3550_60,
60c1375d67SLukas Wunner mcp3551,
61c1375d67SLukas Wunner mcp3553,
62f5ce4a7aSOskar Andero };
63f5ce4a7aSOskar Andero
64b12206e9SSøren Andersen struct mcp320x_chip_info {
65b12206e9SSøren Andersen const struct iio_chan_spec *channels;
66b12206e9SSøren Andersen unsigned int num_channels;
67b12206e9SSøren Andersen unsigned int resolution;
68c1375d67SLukas Wunner unsigned int conv_time; /* usec */
69b12206e9SSøren Andersen };
70b12206e9SSøren Andersen
719c84c910SLukas Wunner /**
729c84c910SLukas Wunner * struct mcp320x - Microchip SPI ADC instance
739c84c910SLukas Wunner * @spi: SPI slave (parent of the IIO device)
749c84c910SLukas Wunner * @msg: SPI message to select a channel and receive a value from the ADC
759c84c910SLukas Wunner * @transfer: SPI transfers used by @msg
76c1375d67SLukas Wunner * @start_conv_msg: SPI message to start a conversion by briefly asserting CS
77c1375d67SLukas Wunner * @start_conv_transfer: SPI transfer used by @start_conv_msg
789c84c910SLukas Wunner * @reg: regulator generating Vref
799c84c910SLukas Wunner * @lock: protects read sequences
809c84c910SLukas Wunner * @chip_info: ADC properties
819c84c910SLukas Wunner * @tx_buf: buffer for @transfer[0] (not used on single-channel converters)
829c84c910SLukas Wunner * @rx_buf: buffer for @transfer[1]
839c84c910SLukas Wunner */
84f5ce4a7aSOskar Andero struct mcp320x {
85f5ce4a7aSOskar Andero struct spi_device *spi;
86f5ce4a7aSOskar Andero struct spi_message msg;
87f5ce4a7aSOskar Andero struct spi_transfer transfer[2];
88c1375d67SLukas Wunner struct spi_message start_conv_msg;
89c1375d67SLukas Wunner struct spi_transfer start_conv_transfer;
90f5ce4a7aSOskar Andero
91f5ce4a7aSOskar Andero struct regulator *reg;
92f5ce4a7aSOskar Andero struct mutex lock;
93b12206e9SSøren Andersen const struct mcp320x_chip_info *chip_info;
940e81bc99SMichael Welling
95*e770f780SJonathan Cameron u8 tx_buf __aligned(IIO_DMA_MINALIGN);
96c1375d67SLukas Wunner u8 rx_buf[4];
97f5ce4a7aSOskar Andero };
98f5ce4a7aSOskar Andero
mcp320x_channel_to_tx_data(int device_index,const unsigned int channel,bool differential)99b12206e9SSøren Andersen static int mcp320x_channel_to_tx_data(int device_index,
100b12206e9SSøren Andersen const unsigned int channel, bool differential)
101b12206e9SSøren Andersen {
102b12206e9SSøren Andersen int start_bit = 1;
103b12206e9SSøren Andersen
104b12206e9SSøren Andersen switch (device_index) {
105b12206e9SSøren Andersen case mcp3002:
106b12206e9SSøren Andersen case mcp3202:
107b12206e9SSøren Andersen return ((start_bit << 4) | (!differential << 3) |
108b12206e9SSøren Andersen (channel << 2));
109b12206e9SSøren Andersen case mcp3004:
110b12206e9SSøren Andersen case mcp3204:
111b12206e9SSøren Andersen case mcp3008:
112b12206e9SSøren Andersen case mcp3208:
113b12206e9SSøren Andersen return ((start_bit << 6) | (!differential << 5) |
114b12206e9SSøren Andersen (channel << 2));
115b12206e9SSøren Andersen default:
116b12206e9SSøren Andersen return -EINVAL;
117b12206e9SSøren Andersen }
118b12206e9SSøren Andersen }
119b12206e9SSøren Andersen
mcp320x_adc_conversion(struct mcp320x * adc,u8 channel,bool differential,int device_index,int * val)120b12206e9SSøren Andersen static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
121e6f47943SLukas Wunner bool differential, int device_index, int *val)
122f5ce4a7aSOskar Andero {
123f5ce4a7aSOskar Andero int ret;
124f5ce4a7aSOskar Andero
125c1375d67SLukas Wunner if (adc->chip_info->conv_time) {
126c1375d67SLukas Wunner ret = spi_sync(adc->spi, &adc->start_conv_msg);
127c1375d67SLukas Wunner if (ret < 0)
128c1375d67SLukas Wunner return ret;
129c1375d67SLukas Wunner
130c1375d67SLukas Wunner usleep_range(adc->chip_info->conv_time,
131c1375d67SLukas Wunner adc->chip_info->conv_time + 100);
132c1375d67SLukas Wunner }
133c1375d67SLukas Wunner
134ea910318SLukas Wunner memset(&adc->rx_buf, 0, sizeof(adc->rx_buf));
135ea910318SLukas Wunner if (adc->chip_info->num_channels > 1)
136ea910318SLukas Wunner adc->tx_buf = mcp320x_channel_to_tx_data(device_index, channel,
137ea910318SLukas Wunner differential);
138b12206e9SSøren Andersen
139f5ce4a7aSOskar Andero ret = spi_sync(adc->spi, &adc->msg);
140f5ce4a7aSOskar Andero if (ret < 0)
141f5ce4a7aSOskar Andero return ret;
142f5ce4a7aSOskar Andero
143b12206e9SSøren Andersen switch (device_index) {
144b12206e9SSøren Andersen case mcp3001:
145e6f47943SLukas Wunner *val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3);
146e6f47943SLukas Wunner return 0;
147b12206e9SSøren Andersen case mcp3002:
148b12206e9SSøren Andersen case mcp3004:
149b12206e9SSøren Andersen case mcp3008:
150e6f47943SLukas Wunner *val = (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6);
151e6f47943SLukas Wunner return 0;
152b12206e9SSøren Andersen case mcp3201:
153e6f47943SLukas Wunner *val = (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1);
154e6f47943SLukas Wunner return 0;
155b12206e9SSøren Andersen case mcp3202:
156b12206e9SSøren Andersen case mcp3204:
157b12206e9SSøren Andersen case mcp3208:
158e6f47943SLukas Wunner *val = (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
159e6f47943SLukas Wunner return 0;
160f686a36bSAndrea Galbusera case mcp3301:
161e6f47943SLukas Wunner *val = sign_extend32((adc->rx_buf[0] & 0x1f) << 8
162e6f47943SLukas Wunner | adc->rx_buf[1], 12);
163e6f47943SLukas Wunner return 0;
164c1375d67SLukas Wunner case mcp3550_50:
165c1375d67SLukas Wunner case mcp3550_60:
166c1375d67SLukas Wunner case mcp3551:
167c1375d67SLukas Wunner case mcp3553: {
1689299b503SJonathan Cameron u32 raw = be32_to_cpup((__be32 *)adc->rx_buf);
169c1375d67SLukas Wunner
170c1375d67SLukas Wunner if (!(adc->spi->mode & SPI_CPOL))
171c1375d67SLukas Wunner raw <<= 1; /* strip Data Ready bit in SPI mode 0,0 */
172c1375d67SLukas Wunner
173c1375d67SLukas Wunner /*
174c1375d67SLukas Wunner * If the input is within -vref and vref, bit 21 is the sign.
175c1375d67SLukas Wunner * Up to 12% overrange or underrange are allowed, in which case
176c1375d67SLukas Wunner * bit 23 is the sign and bit 0 to 21 is the value.
177c1375d67SLukas Wunner */
178c1375d67SLukas Wunner raw >>= 8;
179c1375d67SLukas Wunner if (raw & BIT(22) && raw & BIT(23))
180c1375d67SLukas Wunner return -EIO; /* cannot have overrange AND underrange */
181c1375d67SLukas Wunner else if (raw & BIT(22))
182c1375d67SLukas Wunner raw &= ~BIT(22); /* overrange */
183c1375d67SLukas Wunner else if (raw & BIT(23) || raw & BIT(21))
184c1375d67SLukas Wunner raw |= GENMASK(31, 22); /* underrange or negative */
185c1375d67SLukas Wunner
186c1375d67SLukas Wunner *val = (s32)raw;
187c1375d67SLukas Wunner return 0;
188c1375d67SLukas Wunner }
189b12206e9SSøren Andersen default:
190b12206e9SSøren Andersen return -EINVAL;
191b12206e9SSøren Andersen }
192f5ce4a7aSOskar Andero }
193f5ce4a7aSOskar Andero
mcp320x_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * channel,int * val,int * val2,long mask)194f5ce4a7aSOskar Andero static int mcp320x_read_raw(struct iio_dev *indio_dev,
195f5ce4a7aSOskar Andero struct iio_chan_spec const *channel, int *val,
196f5ce4a7aSOskar Andero int *val2, long mask)
197f5ce4a7aSOskar Andero {
198f5ce4a7aSOskar Andero struct mcp320x *adc = iio_priv(indio_dev);
199f5ce4a7aSOskar Andero int ret = -EINVAL;
200b12206e9SSøren Andersen int device_index = 0;
201f5ce4a7aSOskar Andero
202f5ce4a7aSOskar Andero mutex_lock(&adc->lock);
203f5ce4a7aSOskar Andero
204b12206e9SSøren Andersen device_index = spi_get_device_id(adc->spi)->driver_data;
205b12206e9SSøren Andersen
206f5ce4a7aSOskar Andero switch (mask) {
207f5ce4a7aSOskar Andero case IIO_CHAN_INFO_RAW:
208b12206e9SSøren Andersen ret = mcp320x_adc_conversion(adc, channel->address,
209e6f47943SLukas Wunner channel->differential, device_index, val);
210f5ce4a7aSOskar Andero if (ret < 0)
211f5ce4a7aSOskar Andero goto out;
212f5ce4a7aSOskar Andero
213f5ce4a7aSOskar Andero ret = IIO_VAL_INT;
214f5ce4a7aSOskar Andero break;
215f5ce4a7aSOskar Andero
216f5ce4a7aSOskar Andero case IIO_CHAN_INFO_SCALE:
217f5ce4a7aSOskar Andero ret = regulator_get_voltage(adc->reg);
218f5ce4a7aSOskar Andero if (ret < 0)
219f5ce4a7aSOskar Andero goto out;
220f5ce4a7aSOskar Andero
221b12206e9SSøren Andersen /* convert regulator output voltage to mV */
222f5ce4a7aSOskar Andero *val = ret / 1000;
223b12206e9SSøren Andersen *val2 = adc->chip_info->resolution;
224f5ce4a7aSOskar Andero ret = IIO_VAL_FRACTIONAL_LOG2;
225f5ce4a7aSOskar Andero break;
226f5ce4a7aSOskar Andero }
227f5ce4a7aSOskar Andero
228f5ce4a7aSOskar Andero out:
229f5ce4a7aSOskar Andero mutex_unlock(&adc->lock);
230f5ce4a7aSOskar Andero
231f5ce4a7aSOskar Andero return ret;
232f5ce4a7aSOskar Andero }
233f5ce4a7aSOskar Andero
234f5ce4a7aSOskar Andero #define MCP320X_VOLTAGE_CHANNEL(num) \
235f5ce4a7aSOskar Andero { \
236f5ce4a7aSOskar Andero .type = IIO_VOLTAGE, \
237f5ce4a7aSOskar Andero .indexed = 1, \
238f5ce4a7aSOskar Andero .channel = (num), \
239f5ce4a7aSOskar Andero .address = (num), \
240f5ce4a7aSOskar Andero .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
241f5ce4a7aSOskar Andero .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
242f5ce4a7aSOskar Andero }
243f5ce4a7aSOskar Andero
2444ea71e5cSAkinobu Mita #define MCP320X_VOLTAGE_CHANNEL_DIFF(chan1, chan2) \
245f5ce4a7aSOskar Andero { \
246f5ce4a7aSOskar Andero .type = IIO_VOLTAGE, \
247f5ce4a7aSOskar Andero .indexed = 1, \
2484ea71e5cSAkinobu Mita .channel = (chan1), \
2494ea71e5cSAkinobu Mita .channel2 = (chan2), \
2504ea71e5cSAkinobu Mita .address = (chan1), \
251f5ce4a7aSOskar Andero .differential = 1, \
252f5ce4a7aSOskar Andero .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
253f5ce4a7aSOskar Andero .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
254f5ce4a7aSOskar Andero }
255f5ce4a7aSOskar Andero
256b12206e9SSøren Andersen static const struct iio_chan_spec mcp3201_channels[] = {
2574ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
258b12206e9SSøren Andersen };
259b12206e9SSøren Andersen
260b12206e9SSøren Andersen static const struct iio_chan_spec mcp3202_channels[] = {
261b12206e9SSøren Andersen MCP320X_VOLTAGE_CHANNEL(0),
262b12206e9SSøren Andersen MCP320X_VOLTAGE_CHANNEL(1),
2634ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
2644ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0),
265b12206e9SSøren Andersen };
266b12206e9SSøren Andersen
267f5ce4a7aSOskar Andero static const struct iio_chan_spec mcp3204_channels[] = {
268f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(0),
269f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(1),
270f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(2),
271f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(3),
2724ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
2734ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0),
2744ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(2, 3),
2754ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(3, 2),
276f5ce4a7aSOskar Andero };
277f5ce4a7aSOskar Andero
278f5ce4a7aSOskar Andero static const struct iio_chan_spec mcp3208_channels[] = {
279f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(0),
280f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(1),
281f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(2),
282f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(3),
283f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(4),
284f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(5),
285f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(6),
286f5ce4a7aSOskar Andero MCP320X_VOLTAGE_CHANNEL(7),
2874ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
2884ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0),
2894ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(2, 3),
2904ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(3, 2),
2914ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(4, 5),
2924ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(5, 4),
2934ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(6, 7),
2944ea71e5cSAkinobu Mita MCP320X_VOLTAGE_CHANNEL_DIFF(7, 6),
295f5ce4a7aSOskar Andero };
296f5ce4a7aSOskar Andero
297f5ce4a7aSOskar Andero static const struct iio_info mcp320x_info = {
298f5ce4a7aSOskar Andero .read_raw = mcp320x_read_raw,
299f5ce4a7aSOskar Andero };
300f5ce4a7aSOskar Andero
301b12206e9SSøren Andersen static const struct mcp320x_chip_info mcp320x_chip_infos[] = {
302b12206e9SSøren Andersen [mcp3001] = {
303b12206e9SSøren Andersen .channels = mcp3201_channels,
304b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3201_channels),
305b12206e9SSøren Andersen .resolution = 10
306b12206e9SSøren Andersen },
307b12206e9SSøren Andersen [mcp3002] = {
308b12206e9SSøren Andersen .channels = mcp3202_channels,
309b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3202_channels),
310b12206e9SSøren Andersen .resolution = 10
311b12206e9SSøren Andersen },
312b12206e9SSøren Andersen [mcp3004] = {
313b12206e9SSøren Andersen .channels = mcp3204_channels,
314b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3204_channels),
315b12206e9SSøren Andersen .resolution = 10
316b12206e9SSøren Andersen },
317b12206e9SSøren Andersen [mcp3008] = {
318b12206e9SSøren Andersen .channels = mcp3208_channels,
319b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3208_channels),
320b12206e9SSøren Andersen .resolution = 10
321b12206e9SSøren Andersen },
322b12206e9SSøren Andersen [mcp3201] = {
323b12206e9SSøren Andersen .channels = mcp3201_channels,
324b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3201_channels),
325b12206e9SSøren Andersen .resolution = 12
326b12206e9SSøren Andersen },
327b12206e9SSøren Andersen [mcp3202] = {
328b12206e9SSøren Andersen .channels = mcp3202_channels,
329b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3202_channels),
330b12206e9SSøren Andersen .resolution = 12
331b12206e9SSøren Andersen },
332f5ce4a7aSOskar Andero [mcp3204] = {
333f5ce4a7aSOskar Andero .channels = mcp3204_channels,
334b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3204_channels),
335b12206e9SSøren Andersen .resolution = 12
336f5ce4a7aSOskar Andero },
337f5ce4a7aSOskar Andero [mcp3208] = {
338f5ce4a7aSOskar Andero .channels = mcp3208_channels,
339b12206e9SSøren Andersen .num_channels = ARRAY_SIZE(mcp3208_channels),
340b12206e9SSøren Andersen .resolution = 12
341f5ce4a7aSOskar Andero },
342f686a36bSAndrea Galbusera [mcp3301] = {
343f686a36bSAndrea Galbusera .channels = mcp3201_channels,
344f686a36bSAndrea Galbusera .num_channels = ARRAY_SIZE(mcp3201_channels),
345f686a36bSAndrea Galbusera .resolution = 13
346f686a36bSAndrea Galbusera },
347c1375d67SLukas Wunner [mcp3550_50] = {
348c1375d67SLukas Wunner .channels = mcp3201_channels,
349c1375d67SLukas Wunner .num_channels = ARRAY_SIZE(mcp3201_channels),
350c1375d67SLukas Wunner .resolution = 21,
351c1375d67SLukas Wunner /* 2% max deviation + 144 clock periods to exit shutdown */
352c1375d67SLukas Wunner .conv_time = 80000 * 1.02 + 144000 / 102.4,
353c1375d67SLukas Wunner },
354c1375d67SLukas Wunner [mcp3550_60] = {
355c1375d67SLukas Wunner .channels = mcp3201_channels,
356c1375d67SLukas Wunner .num_channels = ARRAY_SIZE(mcp3201_channels),
357c1375d67SLukas Wunner .resolution = 21,
358c1375d67SLukas Wunner .conv_time = 66670 * 1.02 + 144000 / 122.88,
359c1375d67SLukas Wunner },
360c1375d67SLukas Wunner [mcp3551] = {
361c1375d67SLukas Wunner .channels = mcp3201_channels,
362c1375d67SLukas Wunner .num_channels = ARRAY_SIZE(mcp3201_channels),
363c1375d67SLukas Wunner .resolution = 21,
364c1375d67SLukas Wunner .conv_time = 73100 * 1.02 + 144000 / 112.64,
365c1375d67SLukas Wunner },
366c1375d67SLukas Wunner [mcp3553] = {
367c1375d67SLukas Wunner .channels = mcp3201_channels,
368c1375d67SLukas Wunner .num_channels = ARRAY_SIZE(mcp3201_channels),
369c1375d67SLukas Wunner .resolution = 21,
370c1375d67SLukas Wunner .conv_time = 16670 * 1.02 + 144000 / 122.88,
371c1375d67SLukas Wunner },
372f5ce4a7aSOskar Andero };
373f5ce4a7aSOskar Andero
mcp320x_probe(struct spi_device * spi)374f5ce4a7aSOskar Andero static int mcp320x_probe(struct spi_device *spi)
375f5ce4a7aSOskar Andero {
376f5ce4a7aSOskar Andero struct iio_dev *indio_dev;
377f5ce4a7aSOskar Andero struct mcp320x *adc;
378b12206e9SSøren Andersen const struct mcp320x_chip_info *chip_info;
379c1375d67SLukas Wunner int ret, device_index;
380f5ce4a7aSOskar Andero
381a726dea5SSachin Kamat indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
382f5ce4a7aSOskar Andero if (!indio_dev)
383f5ce4a7aSOskar Andero return -ENOMEM;
384f5ce4a7aSOskar Andero
385f5ce4a7aSOskar Andero adc = iio_priv(indio_dev);
386f5ce4a7aSOskar Andero adc->spi = spi;
387f5ce4a7aSOskar Andero
388f5ce4a7aSOskar Andero indio_dev->name = spi_get_device_id(spi)->name;
389f5ce4a7aSOskar Andero indio_dev->modes = INDIO_DIRECT_MODE;
390f5ce4a7aSOskar Andero indio_dev->info = &mcp320x_info;
3910964e409SLukas Wunner spi_set_drvdata(spi, indio_dev);
392f5ce4a7aSOskar Andero
393c1375d67SLukas Wunner device_index = spi_get_device_id(spi)->driver_data;
394c1375d67SLukas Wunner chip_info = &mcp320x_chip_infos[device_index];
395f5ce4a7aSOskar Andero indio_dev->channels = chip_info->channels;
396f5ce4a7aSOskar Andero indio_dev->num_channels = chip_info->num_channels;
397f5ce4a7aSOskar Andero
39841be6a0dSManfred Schlaegl adc->chip_info = chip_info;
39941be6a0dSManfred Schlaegl
400f5ce4a7aSOskar Andero adc->transfer[0].tx_buf = &adc->tx_buf;
401f5ce4a7aSOskar Andero adc->transfer[0].len = sizeof(adc->tx_buf);
402f5ce4a7aSOskar Andero adc->transfer[1].rx_buf = adc->rx_buf;
403c1375d67SLukas Wunner adc->transfer[1].len = DIV_ROUND_UP(chip_info->resolution, 8);
404c1375d67SLukas Wunner
405ea910318SLukas Wunner if (chip_info->num_channels == 1)
406ea910318SLukas Wunner /* single-channel converters are rx only (no MOSI pin) */
407ea910318SLukas Wunner spi_message_init_with_transfers(&adc->msg,
408ea910318SLukas Wunner &adc->transfer[1], 1);
409ea910318SLukas Wunner else
410f5ce4a7aSOskar Andero spi_message_init_with_transfers(&adc->msg, adc->transfer,
411f5ce4a7aSOskar Andero ARRAY_SIZE(adc->transfer));
412f5ce4a7aSOskar Andero
413c1375d67SLukas Wunner switch (device_index) {
414c1375d67SLukas Wunner case mcp3550_50:
415c1375d67SLukas Wunner case mcp3550_60:
416c1375d67SLukas Wunner case mcp3551:
417c1375d67SLukas Wunner case mcp3553:
418c1375d67SLukas Wunner /* rx len increases from 24 to 25 bit in SPI mode 0,0 */
419c1375d67SLukas Wunner if (!(spi->mode & SPI_CPOL))
420c1375d67SLukas Wunner adc->transfer[1].len++;
421c1375d67SLukas Wunner
422c1375d67SLukas Wunner /* conversions are started by asserting CS pin for 8 usec */
423eccd0718SSergiu Cuciurean adc->start_conv_transfer.delay.value = 8;
424eccd0718SSergiu Cuciurean adc->start_conv_transfer.delay.unit = SPI_DELAY_UNIT_USECS;
425c1375d67SLukas Wunner spi_message_init_with_transfers(&adc->start_conv_msg,
426c1375d67SLukas Wunner &adc->start_conv_transfer, 1);
427c1375d67SLukas Wunner
428c1375d67SLukas Wunner /*
429c1375d67SLukas Wunner * If CS was previously kept low (continuous conversion mode)
430c1375d67SLukas Wunner * and then changed to high, the chip is in shutdown.
431c1375d67SLukas Wunner * Sometimes it fails to wake from shutdown and clocks out
432c1375d67SLukas Wunner * only 0xffffff. The magic sequence of performing two
433c1375d67SLukas Wunner * conversions without delay between them resets the chip
434c1375d67SLukas Wunner * and ensures all subsequent conversions succeed.
435c1375d67SLukas Wunner */
436c1375d67SLukas Wunner mcp320x_adc_conversion(adc, 0, 1, device_index, &ret);
437c1375d67SLukas Wunner mcp320x_adc_conversion(adc, 0, 1, device_index, &ret);
438c1375d67SLukas Wunner }
439c1375d67SLukas Wunner
440a726dea5SSachin Kamat adc->reg = devm_regulator_get(&spi->dev, "vref");
441a726dea5SSachin Kamat if (IS_ERR(adc->reg))
442a726dea5SSachin Kamat return PTR_ERR(adc->reg);
443f5ce4a7aSOskar Andero
444f5ce4a7aSOskar Andero ret = regulator_enable(adc->reg);
445f5ce4a7aSOskar Andero if (ret < 0)
446a726dea5SSachin Kamat return ret;
447f5ce4a7aSOskar Andero
448f5ce4a7aSOskar Andero mutex_init(&adc->lock);
449f5ce4a7aSOskar Andero
450f5ce4a7aSOskar Andero ret = iio_device_register(indio_dev);
451f5ce4a7aSOskar Andero if (ret < 0)
452f5ce4a7aSOskar Andero goto reg_disable;
453f5ce4a7aSOskar Andero
454f5ce4a7aSOskar Andero return 0;
455f5ce4a7aSOskar Andero
456f5ce4a7aSOskar Andero reg_disable:
457f5ce4a7aSOskar Andero regulator_disable(adc->reg);
458f5ce4a7aSOskar Andero
459f5ce4a7aSOskar Andero return ret;
460f5ce4a7aSOskar Andero }
461f5ce4a7aSOskar Andero
mcp320x_remove(struct spi_device * spi)462a0386bbaSUwe Kleine-König static void mcp320x_remove(struct spi_device *spi)
463f5ce4a7aSOskar Andero {
464f5ce4a7aSOskar Andero struct iio_dev *indio_dev = spi_get_drvdata(spi);
465f5ce4a7aSOskar Andero struct mcp320x *adc = iio_priv(indio_dev);
466f5ce4a7aSOskar Andero
467f5ce4a7aSOskar Andero iio_device_unregister(indio_dev);
468f5ce4a7aSOskar Andero regulator_disable(adc->reg);
469f5ce4a7aSOskar Andero }
470f5ce4a7aSOskar Andero
471b12206e9SSøren Andersen static const struct of_device_id mcp320x_dt_ids[] = {
4720d0e5384SJavier Martinez Canillas /* NOTE: The use of compatibles with no vendor prefix is deprecated. */
47335ed9fbfSLukas Wunner { .compatible = "mcp3001" },
47435ed9fbfSLukas Wunner { .compatible = "mcp3002" },
47535ed9fbfSLukas Wunner { .compatible = "mcp3004" },
47635ed9fbfSLukas Wunner { .compatible = "mcp3008" },
47735ed9fbfSLukas Wunner { .compatible = "mcp3201" },
47835ed9fbfSLukas Wunner { .compatible = "mcp3202" },
47935ed9fbfSLukas Wunner { .compatible = "mcp3204" },
48035ed9fbfSLukas Wunner { .compatible = "mcp3208" },
48135ed9fbfSLukas Wunner { .compatible = "mcp3301" },
48235ed9fbfSLukas Wunner { .compatible = "microchip,mcp3001" },
48335ed9fbfSLukas Wunner { .compatible = "microchip,mcp3002" },
48435ed9fbfSLukas Wunner { .compatible = "microchip,mcp3004" },
48535ed9fbfSLukas Wunner { .compatible = "microchip,mcp3008" },
48635ed9fbfSLukas Wunner { .compatible = "microchip,mcp3201" },
48735ed9fbfSLukas Wunner { .compatible = "microchip,mcp3202" },
48835ed9fbfSLukas Wunner { .compatible = "microchip,mcp3204" },
48935ed9fbfSLukas Wunner { .compatible = "microchip,mcp3208" },
49035ed9fbfSLukas Wunner { .compatible = "microchip,mcp3301" },
491c1375d67SLukas Wunner { .compatible = "microchip,mcp3550-50" },
492c1375d67SLukas Wunner { .compatible = "microchip,mcp3550-60" },
493c1375d67SLukas Wunner { .compatible = "microchip,mcp3551" },
494c1375d67SLukas Wunner { .compatible = "microchip,mcp3553" },
49535ed9fbfSLukas Wunner { }
496b12206e9SSøren Andersen };
497b12206e9SSøren Andersen MODULE_DEVICE_TABLE(of, mcp320x_dt_ids);
498b12206e9SSøren Andersen
499f5ce4a7aSOskar Andero static const struct spi_device_id mcp320x_id[] = {
500b12206e9SSøren Andersen { "mcp3001", mcp3001 },
501b12206e9SSøren Andersen { "mcp3002", mcp3002 },
502b12206e9SSøren Andersen { "mcp3004", mcp3004 },
503b12206e9SSøren Andersen { "mcp3008", mcp3008 },
504b12206e9SSøren Andersen { "mcp3201", mcp3201 },
505b12206e9SSøren Andersen { "mcp3202", mcp3202 },
506f5ce4a7aSOskar Andero { "mcp3204", mcp3204 },
507f5ce4a7aSOskar Andero { "mcp3208", mcp3208 },
508f686a36bSAndrea Galbusera { "mcp3301", mcp3301 },
509c1375d67SLukas Wunner { "mcp3550-50", mcp3550_50 },
510c1375d67SLukas Wunner { "mcp3550-60", mcp3550_60 },
511c1375d67SLukas Wunner { "mcp3551", mcp3551 },
512c1375d67SLukas Wunner { "mcp3553", mcp3553 },
513f5ce4a7aSOskar Andero { }
514f5ce4a7aSOskar Andero };
515f5ce4a7aSOskar Andero MODULE_DEVICE_TABLE(spi, mcp320x_id);
516f5ce4a7aSOskar Andero
517f5ce4a7aSOskar Andero static struct spi_driver mcp320x_driver = {
518f5ce4a7aSOskar Andero .driver = {
519f5ce4a7aSOskar Andero .name = "mcp320x",
520016d271eSJonathan Cameron .of_match_table = mcp320x_dt_ids,
521f5ce4a7aSOskar Andero },
522f5ce4a7aSOskar Andero .probe = mcp320x_probe,
523f5ce4a7aSOskar Andero .remove = mcp320x_remove,
524f5ce4a7aSOskar Andero .id_table = mcp320x_id,
525f5ce4a7aSOskar Andero };
526f5ce4a7aSOskar Andero module_spi_driver(mcp320x_driver);
527f5ce4a7aSOskar Andero
528f5ce4a7aSOskar Andero MODULE_AUTHOR("Oskar Andero <oskar.andero@gmail.com>");
529c1375d67SLukas Wunner MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08 and MCP3550/1/3");
530f5ce4a7aSOskar Andero MODULE_LICENSE("GPL v2");
531