]> Git Repo - linux.git/blob - drivers/iio/dac/ad5686.c
powerpc/64s/hash: convert SLB miss handlers to C
[linux.git] / drivers / iio / dac / ad5686.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * AD5686R, AD5685R, AD5684R Digital to analog converters  driver
4  *
5  * Copyright 2011 Analog Devices Inc.
6  */
7
8 #include <linux/interrupt.h>
9 #include <linux/fs.h>
10 #include <linux/device.h>
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15 #include <linux/regulator/consumer.h>
16
17 #include <linux/iio/iio.h>
18 #include <linux/iio/sysfs.h>
19
20 #include "ad5686.h"
21
22 static const char * const ad5686_powerdown_modes[] = {
23         "1kohm_to_gnd",
24         "100kohm_to_gnd",
25         "three_state"
26 };
27
28 static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
29                                      const struct iio_chan_spec *chan)
30 {
31         struct ad5686_state *st = iio_priv(indio_dev);
32
33         return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
34 }
35
36 static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
37                                      const struct iio_chan_spec *chan,
38                                      unsigned int mode)
39 {
40         struct ad5686_state *st = iio_priv(indio_dev);
41
42         st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
43         st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
44
45         return 0;
46 }
47
48 static const struct iio_enum ad5686_powerdown_mode_enum = {
49         .items = ad5686_powerdown_modes,
50         .num_items = ARRAY_SIZE(ad5686_powerdown_modes),
51         .get = ad5686_get_powerdown_mode,
52         .set = ad5686_set_powerdown_mode,
53 };
54
55 static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
56                 uintptr_t private, const struct iio_chan_spec *chan, char *buf)
57 {
58         struct ad5686_state *st = iio_priv(indio_dev);
59
60         return sprintf(buf, "%d\n", !!(st->pwr_down_mask &
61                                        (0x3 << (chan->channel * 2))));
62 }
63
64 static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
65                                           uintptr_t private,
66                                           const struct iio_chan_spec *chan,
67                                           const char *buf,
68                                           size_t len)
69 {
70         bool readin;
71         int ret;
72         struct ad5686_state *st = iio_priv(indio_dev);
73         unsigned int val, ref_bit_msk;
74         u8 shift;
75
76         ret = strtobool(buf, &readin);
77         if (ret)
78                 return ret;
79
80         if (readin)
81                 st->pwr_down_mask |= (0x3 << (chan->channel * 2));
82         else
83                 st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
84
85         switch (st->chip_info->regmap_type) {
86         case AD5683_REGMAP:
87                 shift = 13;
88                 ref_bit_msk = AD5683_REF_BIT_MSK;
89                 break;
90         case AD5686_REGMAP:
91                 shift = 0;
92                 ref_bit_msk = 0;
93                 break;
94         case AD5693_REGMAP:
95                 shift = 13;
96                 ref_bit_msk = AD5693_REF_BIT_MSK;
97                 break;
98         default:
99                 return -EINVAL;
100         }
101
102         val = ((st->pwr_down_mask & st->pwr_down_mode) << shift);
103         if (!st->use_internal_vref)
104                 val |= ref_bit_msk;
105
106         ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, 0, val);
107
108         return ret ? ret : len;
109 }
110
111 static int ad5686_read_raw(struct iio_dev *indio_dev,
112                            struct iio_chan_spec const *chan,
113                            int *val,
114                            int *val2,
115                            long m)
116 {
117         struct ad5686_state *st = iio_priv(indio_dev);
118         int ret;
119
120         switch (m) {
121         case IIO_CHAN_INFO_RAW:
122                 mutex_lock(&indio_dev->mlock);
123                 ret = st->read(st, chan->address);
124                 mutex_unlock(&indio_dev->mlock);
125                 if (ret < 0)
126                         return ret;
127                 *val = ret;
128                 return IIO_VAL_INT;
129         case IIO_CHAN_INFO_SCALE:
130                 *val = st->vref_mv;
131                 *val2 = chan->scan_type.realbits;
132                 return IIO_VAL_FRACTIONAL_LOG2;
133         }
134         return -EINVAL;
135 }
136
137 static int ad5686_write_raw(struct iio_dev *indio_dev,
138                             struct iio_chan_spec const *chan,
139                             int val,
140                             int val2,
141                             long mask)
142 {
143         struct ad5686_state *st = iio_priv(indio_dev);
144         int ret;
145
146         switch (mask) {
147         case IIO_CHAN_INFO_RAW:
148                 if (val > (1 << chan->scan_type.realbits) || val < 0)
149                         return -EINVAL;
150
151                 mutex_lock(&indio_dev->mlock);
152                 ret = st->write(st,
153                                 AD5686_CMD_WRITE_INPUT_N_UPDATE_N,
154                                 chan->address,
155                                 val << chan->scan_type.shift);
156                 mutex_unlock(&indio_dev->mlock);
157                 break;
158         default:
159                 ret = -EINVAL;
160         }
161
162         return ret;
163 }
164
165 static const struct iio_info ad5686_info = {
166         .read_raw = ad5686_read_raw,
167         .write_raw = ad5686_write_raw,
168 };
169
170 static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
171         {
172                 .name = "powerdown",
173                 .read = ad5686_read_dac_powerdown,
174                 .write = ad5686_write_dac_powerdown,
175                 .shared = IIO_SEPARATE,
176         },
177         IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
178         IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
179         { },
180 };
181
182 #define AD5868_CHANNEL(chan, addr, bits, _shift) {              \
183                 .type = IIO_VOLTAGE,                            \
184                 .indexed = 1,                                   \
185                 .output = 1,                                    \
186                 .channel = chan,                                \
187                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
188                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
189                 .address = addr,                                \
190                 .scan_type = {                                  \
191                         .sign = 'u',                            \
192                         .realbits = (bits),                     \
193                         .storagebits = 16,                      \
194                         .shift = (_shift),                      \
195                 },                                              \
196                 .ext_info = ad5686_ext_info,                    \
197 }
198
199 #define DECLARE_AD5693_CHANNELS(name, bits, _shift)             \
200 static struct iio_chan_spec name[] = {                          \
201                 AD5868_CHANNEL(0, 0, bits, _shift),             \
202 }
203
204 #define DECLARE_AD5686_CHANNELS(name, bits, _shift)             \
205 static struct iio_chan_spec name[] = {                          \
206                 AD5868_CHANNEL(0, 1, bits, _shift),             \
207                 AD5868_CHANNEL(1, 2, bits, _shift),             \
208                 AD5868_CHANNEL(2, 4, bits, _shift),             \
209                 AD5868_CHANNEL(3, 8, bits, _shift),             \
210 }
211
212 #define DECLARE_AD5676_CHANNELS(name, bits, _shift)             \
213 static struct iio_chan_spec name[] = {                          \
214                 AD5868_CHANNEL(0, 0, bits, _shift),             \
215                 AD5868_CHANNEL(1, 1, bits, _shift),             \
216                 AD5868_CHANNEL(2, 2, bits, _shift),             \
217                 AD5868_CHANNEL(3, 3, bits, _shift),             \
218                 AD5868_CHANNEL(4, 4, bits, _shift),             \
219                 AD5868_CHANNEL(5, 5, bits, _shift),             \
220                 AD5868_CHANNEL(6, 6, bits, _shift),             \
221                 AD5868_CHANNEL(7, 7, bits, _shift),             \
222 }
223
224 DECLARE_AD5693_CHANNELS(ad5311r_channels, 10, 6);
225 DECLARE_AD5676_CHANNELS(ad5672_channels, 12, 4);
226 DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0);
227 DECLARE_AD5686_CHANNELS(ad5684_channels, 12, 4);
228 DECLARE_AD5686_CHANNELS(ad5685r_channels, 14, 2);
229 DECLARE_AD5686_CHANNELS(ad5686_channels, 16, 0);
230 DECLARE_AD5693_CHANNELS(ad5693_channels, 16, 0);
231 DECLARE_AD5693_CHANNELS(ad5692r_channels, 14, 2);
232 DECLARE_AD5693_CHANNELS(ad5691r_channels, 12, 4);
233
234 static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
235         [ID_AD5311R] = {
236                 .channels = ad5311r_channels,
237                 .int_vref_mv = 2500,
238                 .num_channels = 1,
239                 .regmap_type = AD5693_REGMAP,
240         },
241         [ID_AD5671R] = {
242                 .channels = ad5672_channels,
243                 .int_vref_mv = 2500,
244                 .num_channels = 8,
245                 .regmap_type = AD5686_REGMAP,
246         },
247         [ID_AD5672R] = {
248                 .channels = ad5672_channels,
249                 .int_vref_mv = 2500,
250                 .num_channels = 8,
251                 .regmap_type = AD5686_REGMAP,
252         },
253         [ID_AD5675R] = {
254                 .channels = ad5676_channels,
255                 .int_vref_mv = 2500,
256                 .num_channels = 8,
257                 .regmap_type = AD5686_REGMAP,
258         },
259         [ID_AD5676] = {
260                 .channels = ad5676_channels,
261                 .num_channels = 8,
262                 .regmap_type = AD5686_REGMAP,
263         },
264         [ID_AD5676R] = {
265                 .channels = ad5676_channels,
266                 .int_vref_mv = 2500,
267                 .num_channels = 8,
268                 .regmap_type = AD5686_REGMAP,
269         },
270         [ID_AD5681R] = {
271                 .channels = ad5691r_channels,
272                 .int_vref_mv = 2500,
273                 .num_channels = 1,
274                 .regmap_type = AD5683_REGMAP,
275         },
276         [ID_AD5682R] = {
277                 .channels = ad5692r_channels,
278                 .int_vref_mv = 2500,
279                 .num_channels = 1,
280                 .regmap_type = AD5683_REGMAP,
281         },
282         [ID_AD5683] = {
283                 .channels = ad5693_channels,
284                 .num_channels = 1,
285                 .regmap_type = AD5683_REGMAP,
286         },
287         [ID_AD5683R] = {
288                 .channels = ad5693_channels,
289                 .int_vref_mv = 2500,
290                 .num_channels = 1,
291                 .regmap_type = AD5683_REGMAP,
292         },
293         [ID_AD5684] = {
294                 .channels = ad5684_channels,
295                 .num_channels = 4,
296                 .regmap_type = AD5686_REGMAP,
297         },
298         [ID_AD5684R] = {
299                 .channels = ad5684_channels,
300                 .int_vref_mv = 2500,
301                 .num_channels = 4,
302                 .regmap_type = AD5686_REGMAP,
303         },
304         [ID_AD5685R] = {
305                 .channels = ad5685r_channels,
306                 .int_vref_mv = 2500,
307                 .num_channels = 4,
308                 .regmap_type = AD5686_REGMAP,
309         },
310         [ID_AD5686] = {
311                 .channels = ad5686_channels,
312                 .num_channels = 4,
313                 .regmap_type = AD5686_REGMAP,
314         },
315         [ID_AD5686R] = {
316                 .channels = ad5686_channels,
317                 .int_vref_mv = 2500,
318                 .num_channels = 4,
319                 .regmap_type = AD5686_REGMAP,
320         },
321         [ID_AD5691R] = {
322                 .channels = ad5691r_channels,
323                 .int_vref_mv = 2500,
324                 .num_channels = 1,
325                 .regmap_type = AD5693_REGMAP,
326         },
327         [ID_AD5692R] = {
328                 .channels = ad5692r_channels,
329                 .int_vref_mv = 2500,
330                 .num_channels = 1,
331                 .regmap_type = AD5693_REGMAP,
332         },
333         [ID_AD5693] = {
334                 .channels = ad5693_channels,
335                 .num_channels = 1,
336                 .regmap_type = AD5693_REGMAP,
337         },
338         [ID_AD5693R] = {
339                 .channels = ad5693_channels,
340                 .int_vref_mv = 2500,
341                 .num_channels = 1,
342                 .regmap_type = AD5693_REGMAP,
343         },
344         [ID_AD5694] = {
345                 .channels = ad5684_channels,
346                 .num_channels = 4,
347                 .regmap_type = AD5686_REGMAP,
348         },
349         [ID_AD5694R] = {
350                 .channels = ad5684_channels,
351                 .int_vref_mv = 2500,
352                 .num_channels = 4,
353                 .regmap_type = AD5686_REGMAP,
354         },
355         [ID_AD5696] = {
356                 .channels = ad5686_channels,
357                 .num_channels = 4,
358                 .regmap_type = AD5686_REGMAP,
359         },
360         [ID_AD5696R] = {
361                 .channels = ad5686_channels,
362                 .int_vref_mv = 2500,
363                 .num_channels = 4,
364                 .regmap_type = AD5686_REGMAP,
365         },
366 };
367
368 int ad5686_probe(struct device *dev,
369                  enum ad5686_supported_device_ids chip_type,
370                  const char *name, ad5686_write_func write,
371                  ad5686_read_func read)
372 {
373         struct ad5686_state *st;
374         struct iio_dev *indio_dev;
375         unsigned int val, ref_bit_msk;
376         u8 cmd;
377         int ret, i, voltage_uv = 0;
378
379         indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
380         if (indio_dev == NULL)
381                 return  -ENOMEM;
382
383         st = iio_priv(indio_dev);
384         dev_set_drvdata(dev, indio_dev);
385
386         st->dev = dev;
387         st->write = write;
388         st->read = read;
389
390         st->reg = devm_regulator_get_optional(dev, "vcc");
391         if (!IS_ERR(st->reg)) {
392                 ret = regulator_enable(st->reg);
393                 if (ret)
394                         return ret;
395
396                 ret = regulator_get_voltage(st->reg);
397                 if (ret < 0)
398                         goto error_disable_reg;
399
400                 voltage_uv = ret;
401         }
402
403         st->chip_info = &ad5686_chip_info_tbl[chip_type];
404
405         if (voltage_uv)
406                 st->vref_mv = voltage_uv / 1000;
407         else
408                 st->vref_mv = st->chip_info->int_vref_mv;
409
410         /* Set all the power down mode for all channels to 1K pulldown */
411         for (i = 0; i < st->chip_info->num_channels; i++)
412                 st->pwr_down_mode |= (0x01 << (i * 2));
413
414         indio_dev->dev.parent = dev;
415         indio_dev->name = name;
416         indio_dev->info = &ad5686_info;
417         indio_dev->modes = INDIO_DIRECT_MODE;
418         indio_dev->channels = st->chip_info->channels;
419         indio_dev->num_channels = st->chip_info->num_channels;
420
421         switch (st->chip_info->regmap_type) {
422         case AD5683_REGMAP:
423                 cmd = AD5686_CMD_CONTROL_REG;
424                 ref_bit_msk = AD5683_REF_BIT_MSK;
425                 st->use_internal_vref = !voltage_uv;
426                 break;
427         case AD5686_REGMAP:
428                 cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
429                 ref_bit_msk = 0;
430                 break;
431         case AD5693_REGMAP:
432                 cmd = AD5686_CMD_CONTROL_REG;
433                 ref_bit_msk = AD5693_REF_BIT_MSK;
434                 st->use_internal_vref = !voltage_uv;
435                 break;
436         default:
437                 ret = -EINVAL;
438                 goto error_disable_reg;
439         }
440
441         val = (voltage_uv | ref_bit_msk);
442
443         ret = st->write(st, cmd, 0, !!val);
444         if (ret)
445                 goto error_disable_reg;
446
447         ret = iio_device_register(indio_dev);
448         if (ret)
449                 goto error_disable_reg;
450
451         return 0;
452
453 error_disable_reg:
454         if (!IS_ERR(st->reg))
455                 regulator_disable(st->reg);
456         return ret;
457 }
458 EXPORT_SYMBOL_GPL(ad5686_probe);
459
460 int ad5686_remove(struct device *dev)
461 {
462         struct iio_dev *indio_dev = dev_get_drvdata(dev);
463         struct ad5686_state *st = iio_priv(indio_dev);
464
465         iio_device_unregister(indio_dev);
466         if (!IS_ERR(st->reg))
467                 regulator_disable(st->reg);
468
469         return 0;
470 }
471 EXPORT_SYMBOL_GPL(ad5686_remove);
472
473 MODULE_AUTHOR("Michael Hennerich <[email protected]>");
474 MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
475 MODULE_LICENSE("GPL v2");
This page took 0.0600000000000001 seconds and 4 git commands to generate.