Linux 6.7-rc7
[linux-modified.git] / drivers / iio / potentiometer / ad5110.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Analog Devices AD5110 digital potentiometer driver
4  *
5  * Copyright (C) 2021 Mugilraj Dhavachelvan <dmugil2000@gmail.com>
6  *
7  * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/AD5110_5112_5114.pdf
8  */
9
10 #include <linux/bitfield.h>
11 #include <linux/delay.h>
12 #include <linux/device.h>
13 #include <linux/i2c.h>
14 #include <linux/module.h>
15
16 #include <linux/iio/iio.h>
17 #include <linux/iio/sysfs.h>
18
19 /* AD5110 commands */
20 #define AD5110_EEPROM_WR        1
21 #define AD5110_RDAC_WR          2
22 #define AD5110_SHUTDOWN 3
23 #define AD5110_RESET            4
24 #define AD5110_RDAC_RD          5
25 #define AD5110_EEPROM_RD        6
26
27 /* AD5110_EEPROM_RD data */
28 #define AD5110_WIPER_POS        0
29 #define AD5110_RESISTOR_TOL     1
30
31 #define AD5110_WIPER_RESISTANCE 70
32
33 struct ad5110_cfg {
34         int max_pos;
35         int kohms;
36         int shift;
37 };
38
39 enum ad5110_type {
40         AD5110_10,
41         AD5110_80,
42         AD5112_05,
43         AD5112_10,
44         AD5112_80,
45         AD5114_10,
46         AD5114_80,
47 };
48
49 static const struct ad5110_cfg ad5110_cfg[] = {
50         [AD5110_10] = { .max_pos = 128, .kohms = 10 },
51         [AD5110_80] = { .max_pos = 128, .kohms = 80 },
52         [AD5112_05] = { .max_pos = 64, .kohms = 5, .shift = 1 },
53         [AD5112_10] = { .max_pos = 64, .kohms = 10, .shift = 1 },
54         [AD5112_80] = { .max_pos = 64, .kohms = 80, .shift = 1 },
55         [AD5114_10] = { .max_pos = 32, .kohms = 10, .shift = 2 },
56         [AD5114_80] = { .max_pos = 32, .kohms = 80, .shift = 2 },
57 };
58
59 struct ad5110_data {
60         struct i2c_client       *client;
61         s16                     tol;            /* resistor tolerance */
62         bool                    enable;
63         struct mutex            lock;
64         const struct ad5110_cfg *cfg;
65         /*
66          * DMA (thus cache coherency maintenance) may require the
67          * transfer buffers to live in their own cache lines.
68          */
69         u8                      buf[2] __aligned(IIO_DMA_MINALIGN);
70 };
71
72 static const struct iio_chan_spec ad5110_channels[] = {
73         {
74                 .type = IIO_RESISTANCE,
75                 .output = 1,
76                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_OFFSET) |
77                                         BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_ENABLE),
78         },
79 };
80
81 static int ad5110_read(struct ad5110_data *data, u8 cmd, int *val)
82 {
83         int ret;
84
85         mutex_lock(&data->lock);
86         data->buf[0] = cmd;
87         data->buf[1] = *val;
88
89         ret = i2c_master_send_dmasafe(data->client, data->buf, sizeof(data->buf));
90         if (ret < 0) {
91                 goto error;
92         } else if (ret != sizeof(data->buf)) {
93                 ret = -EIO;
94                 goto error;
95         }
96
97         ret = i2c_master_recv_dmasafe(data->client, data->buf, 1);
98         if (ret < 0) {
99                 goto error;
100         } else if (ret != 1) {
101                 ret = -EIO;
102                 goto error;
103         }
104
105         *val = data->buf[0];
106         ret = 0;
107
108 error:
109         mutex_unlock(&data->lock);
110         return ret;
111 }
112
113 static int ad5110_write(struct ad5110_data *data, u8 cmd, u8 val)
114 {
115         int ret;
116
117         mutex_lock(&data->lock);
118         data->buf[0] = cmd;
119         data->buf[1] = val;
120
121         ret = i2c_master_send_dmasafe(data->client, data->buf, sizeof(data->buf));
122         if (ret < 0) {
123                 goto error;
124         } else if (ret != sizeof(data->buf)) {
125                 ret = -EIO;
126                 goto error;
127         }
128
129         ret = 0;
130
131 error:
132         mutex_unlock(&data->lock);
133         return ret;
134 }
135
136 static int ad5110_resistor_tol(struct ad5110_data *data, u8 cmd, int val)
137 {
138         int ret;
139
140         ret = ad5110_read(data, cmd, &val);
141         if (ret)
142                 return ret;
143
144         data->tol = data->cfg->kohms * (val & GENMASK(6, 0)) * 10 / 8;
145         if (!(val & BIT(7)))
146                 data->tol *= -1;
147
148         return 0;
149 }
150
151 static ssize_t store_eeprom_show(struct device *dev,
152                                   struct device_attribute *attr,
153                                   char *buf)
154 {
155         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
156         struct ad5110_data *data = iio_priv(indio_dev);
157         int val = AD5110_WIPER_POS;
158         int ret;
159
160         ret = ad5110_read(data, AD5110_EEPROM_RD, &val);
161         if (ret)
162                 return ret;
163
164         val = val >> data->cfg->shift;
165         return iio_format_value(buf, IIO_VAL_INT, 1, &val);
166 }
167
168 static ssize_t store_eeprom_store(struct device *dev,
169                                    struct device_attribute *attr,
170                                    const char *buf, size_t len)
171 {
172         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
173         struct ad5110_data *data = iio_priv(indio_dev);
174         int ret;
175
176         ret = ad5110_write(data, AD5110_EEPROM_WR, 0);
177         if (ret) {
178                 dev_err(&data->client->dev, "RDAC to EEPROM write failed\n");
179                 return ret;
180         }
181
182         /* The storing of EEPROM data takes approximately 18 ms. */
183         msleep(20);
184
185         return len;
186 }
187
188 static IIO_DEVICE_ATTR_RW(store_eeprom, 0);
189
190 static struct attribute *ad5110_attributes[] = {
191         &iio_dev_attr_store_eeprom.dev_attr.attr,
192         NULL
193 };
194
195 static const struct attribute_group ad5110_attribute_group = {
196         .attrs = ad5110_attributes,
197 };
198
199 static int ad5110_read_raw(struct iio_dev *indio_dev,
200                            struct iio_chan_spec const *chan,
201                            int *val, int *val2, long mask)
202 {
203         struct ad5110_data *data = iio_priv(indio_dev);
204         int ret;
205
206         switch (mask) {
207         case IIO_CHAN_INFO_RAW:
208                 ret = ad5110_read(data, AD5110_RDAC_RD, val);
209                 if (ret)
210                         return ret;
211
212                 *val = *val >> data->cfg->shift;
213                 return IIO_VAL_INT;
214         case IIO_CHAN_INFO_OFFSET:
215                 *val = AD5110_WIPER_RESISTANCE * data->cfg->max_pos;
216                 *val2 = 1000 * data->cfg->kohms + data->tol;
217                 return IIO_VAL_FRACTIONAL;
218         case IIO_CHAN_INFO_SCALE:
219                 *val = 1000 * data->cfg->kohms + data->tol;
220                 *val2 = data->cfg->max_pos;
221                 return IIO_VAL_FRACTIONAL;
222         case IIO_CHAN_INFO_ENABLE:
223                 *val = data->enable;
224                 return IIO_VAL_INT;
225         default:
226                 return -EINVAL;
227         }
228 }
229
230 static int ad5110_write_raw(struct iio_dev *indio_dev,
231                             struct iio_chan_spec const *chan,
232                             int val, int val2, long mask)
233 {
234         struct ad5110_data *data = iio_priv(indio_dev);
235         int ret;
236
237         switch (mask) {
238         case IIO_CHAN_INFO_RAW:
239                 if (val > data->cfg->max_pos || val < 0)
240                         return -EINVAL;
241
242                 return ad5110_write(data, AD5110_RDAC_WR, val << data->cfg->shift);
243         case IIO_CHAN_INFO_ENABLE:
244                 if (val < 0 || val > 1)
245                         return -EINVAL;
246                 if (data->enable == val)
247                         return 0;
248                 ret = ad5110_write(data, AD5110_SHUTDOWN, val ? 0 : 1);
249                 if (ret)
250                         return ret;
251                 data->enable = val;
252                 return 0;
253         default:
254                 return -EINVAL;
255         }
256 }
257
258 static const struct iio_info ad5110_info = {
259         .read_raw = ad5110_read_raw,
260         .write_raw = ad5110_write_raw,
261         .attrs = &ad5110_attribute_group,
262 };
263
264 #define AD5110_COMPATIBLE(of_compatible, cfg) { \
265                         .compatible = of_compatible,    \
266                         .data = &ad5110_cfg[cfg],       \
267 }
268
269 static const struct of_device_id ad5110_of_match[] = {
270         AD5110_COMPATIBLE("adi,ad5110-10", AD5110_10),
271         AD5110_COMPATIBLE("adi,ad5110-80", AD5110_80),
272         AD5110_COMPATIBLE("adi,ad5112-05", AD5112_05),
273         AD5110_COMPATIBLE("adi,ad5112-10", AD5112_10),
274         AD5110_COMPATIBLE("adi,ad5112-80", AD5112_80),
275         AD5110_COMPATIBLE("adi,ad5114-10", AD5114_10),
276         AD5110_COMPATIBLE("adi,ad5114-80", AD5114_80),
277         { }
278 };
279 MODULE_DEVICE_TABLE(of, ad5110_of_match);
280
281 #define AD5110_ID_TABLE(_name, cfg) {                           \
282         .name = _name,                                          \
283         .driver_data = (kernel_ulong_t)&ad5110_cfg[cfg],        \
284 }
285
286 static const struct i2c_device_id ad5110_id[] = {
287         AD5110_ID_TABLE("ad5110-10", AD5110_10),
288         AD5110_ID_TABLE("ad5110-80", AD5110_80),
289         AD5110_ID_TABLE("ad5112-05", AD5112_05),
290         AD5110_ID_TABLE("ad5112-10", AD5112_10),
291         AD5110_ID_TABLE("ad5112-80", AD5112_80),
292         AD5110_ID_TABLE("ad5114-10", AD5114_10),
293         AD5110_ID_TABLE("ad5114-80", AD5114_80),
294         { }
295 };
296 MODULE_DEVICE_TABLE(i2c, ad5110_id);
297
298 static int ad5110_probe(struct i2c_client *client)
299 {
300         struct device *dev = &client->dev;
301         struct iio_dev *indio_dev;
302         struct ad5110_data *data;
303         int ret;
304
305         indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
306         if (!indio_dev)
307                 return -ENOMEM;
308
309         data = iio_priv(indio_dev);
310         data->client = client;
311         mutex_init(&data->lock);
312         data->enable = 1;
313         data->cfg = i2c_get_match_data(client);
314
315         /* refresh RDAC register with EEPROM */
316         ret = ad5110_write(data, AD5110_RESET, 0);
317         if (ret) {
318                 dev_err(dev, "Refresh RDAC with EEPROM failed\n");
319                 return ret;
320         }
321
322         ret = ad5110_resistor_tol(data, AD5110_EEPROM_RD, AD5110_RESISTOR_TOL);
323         if (ret) {
324                 dev_err(dev, "Read resistor tolerance failed\n");
325                 return ret;
326         }
327
328         indio_dev->modes = INDIO_DIRECT_MODE;
329         indio_dev->info = &ad5110_info;
330         indio_dev->channels = ad5110_channels;
331         indio_dev->num_channels = ARRAY_SIZE(ad5110_channels);
332         indio_dev->name = client->name;
333
334         return devm_iio_device_register(dev, indio_dev);
335 }
336
337 static struct i2c_driver ad5110_driver = {
338         .driver = {
339                 .name   = "ad5110",
340                 .of_match_table = ad5110_of_match,
341         },
342         .probe          = ad5110_probe,
343         .id_table       = ad5110_id,
344 };
345 module_i2c_driver(ad5110_driver);
346
347 MODULE_AUTHOR("Mugilraj Dhavachelvan <dmugil2000@gmail.com>");
348 MODULE_DESCRIPTION("AD5110 digital potentiometer");
349 MODULE_LICENSE("GPL v2");