]> Pileus Git - ~andy/linux/blob - drivers/staging/iio/dac/ad5791.c
staging:iio:dac:ad5791: Convert to extended channel attributes
[~andy/linux] / drivers / staging / iio / dac / ad5791.c
1 /*
2  * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog
3  * Converter
4  *
5  * Copyright 2011 Analog Devices Inc.
6  *
7  * Licensed under the GPL-2.
8  */
9
10 #include <linux/interrupt.h>
11 #include <linux/fs.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/spi/spi.h>
15 #include <linux/slab.h>
16 #include <linux/sysfs.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/module.h>
19
20 #include <linux/iio/iio.h>
21 #include <linux/iio/sysfs.h>
22 #include "dac.h"
23 #include "ad5791.h"
24
25 static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val)
26 {
27         union {
28                 u32 d32;
29                 u8 d8[4];
30         } data;
31
32         data.d32 = cpu_to_be32(AD5791_CMD_WRITE |
33                               AD5791_ADDR(addr) |
34                               (val & AD5791_DAC_MASK));
35
36         return spi_write(spi, &data.d8[1], 3);
37 }
38
39 static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
40 {
41         union {
42                 u32 d32;
43                 u8 d8[4];
44         } data[3];
45         int ret;
46         struct spi_message msg;
47         struct spi_transfer xfers[] = {
48                 {
49                         .tx_buf = &data[0].d8[1],
50                         .bits_per_word = 8,
51                         .len = 3,
52                         .cs_change = 1,
53                 }, {
54                         .tx_buf = &data[1].d8[1],
55                         .rx_buf = &data[2].d8[1],
56                         .bits_per_word = 8,
57                         .len = 3,
58                 },
59         };
60
61         data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
62                               AD5791_ADDR(addr));
63         data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
64
65         spi_message_init(&msg);
66         spi_message_add_tail(&xfers[0], &msg);
67         spi_message_add_tail(&xfers[1], &msg);
68         ret = spi_sync(spi, &msg);
69
70         *val = be32_to_cpu(data[2].d32);
71
72         return ret;
73 }
74
75 static const char * const ad5791_powerdown_modes[] = {
76         "6kohm_to_gnd",
77         "three_state",
78 };
79
80 static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev,
81         const struct iio_chan_spec *chan)
82 {
83         struct ad5791_state *st = iio_priv(indio_dev);
84
85         return st->pwr_down_mode;
86 }
87
88 static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev,
89         const struct iio_chan_spec *chan, unsigned int mode)
90 {
91         struct ad5791_state *st = iio_priv(indio_dev);
92
93         st->pwr_down_mode = mode;
94
95         return 0;
96 }
97
98 static const struct iio_enum ad5791_powerdown_mode_enum = {
99         .items = ad5791_powerdown_modes,
100         .num_items = ARRAY_SIZE(ad5791_powerdown_modes),
101         .get = ad5791_get_powerdown_mode,
102         .set = ad5791_set_powerdown_mode,
103 };
104
105 static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev,
106         uintptr_t private, const struct iio_chan_spec *chan, char *buf)
107 {
108         struct ad5791_state *st = iio_priv(indio_dev);
109
110         return sprintf(buf, "%d\n", st->pwr_down);
111 }
112
113 static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev,
114          uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
115          size_t len)
116 {
117         long readin;
118         int ret;
119         struct ad5791_state *st = iio_priv(indio_dev);
120
121         ret = strict_strtol(buf, 10, &readin);
122         if (ret)
123                 return ret;
124
125         if (readin == 0) {
126                 st->pwr_down = false;
127                 st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
128         } else if (readin == 1) {
129                 st->pwr_down = true;
130                 if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
131                         st->ctrl |= AD5791_CTRL_OPGND;
132                 else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
133                         st->ctrl |= AD5791_CTRL_DACTRI;
134         } else
135                 ret = -EINVAL;
136
137         ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl);
138
139         return ret ? ret : len;
140 }
141
142 static int ad5791_get_lin_comp(unsigned int span)
143 {
144         if (span <= 10000)
145                 return AD5791_LINCOMP_0_10;
146         else if (span <= 12000)
147                 return AD5791_LINCOMP_10_12;
148         else if (span <= 16000)
149                 return AD5791_LINCOMP_12_16;
150         else if (span <= 19000)
151                 return AD5791_LINCOMP_16_19;
152         else
153                 return AD5791_LINCOMP_19_20;
154 }
155
156 static int ad5780_get_lin_comp(unsigned int span)
157 {
158         if (span <= 10000)
159                 return AD5780_LINCOMP_0_10;
160         else
161                 return AD5780_LINCOMP_10_20;
162 }
163 static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
164         [ID_AD5760] = {
165                 .get_lin_comp = ad5780_get_lin_comp,
166         },
167         [ID_AD5780] = {
168                 .get_lin_comp = ad5780_get_lin_comp,
169         },
170         [ID_AD5781] = {
171                 .get_lin_comp = ad5791_get_lin_comp,
172         },
173         [ID_AD5791] = {
174                 .get_lin_comp = ad5791_get_lin_comp,
175         },
176 };
177
178 static int ad5791_read_raw(struct iio_dev *indio_dev,
179                            struct iio_chan_spec const *chan,
180                            int *val,
181                            int *val2,
182                            long m)
183 {
184         struct ad5791_state *st = iio_priv(indio_dev);
185         u64 val64;
186         int ret;
187
188         switch (m) {
189         case IIO_CHAN_INFO_RAW:
190                 ret = ad5791_spi_read(st->spi, chan->address, val);
191                 if (ret)
192                         return ret;
193                 *val &= AD5791_DAC_MASK;
194                 *val >>= chan->scan_type.shift;
195                 return IIO_VAL_INT;
196         case IIO_CHAN_INFO_SCALE:
197                 *val = 0;
198                 *val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits;
199                 return IIO_VAL_INT_PLUS_MICRO;
200         case IIO_CHAN_INFO_OFFSET:
201                 val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
202                 do_div(val64, st->vref_mv);
203                 *val = -val64;
204                 return IIO_VAL_INT;
205         default:
206                 return -EINVAL;
207         }
208
209 };
210
211 static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
212         {
213                 .name = "powerdown",
214                 .shared = true,
215                 .read = ad5791_read_dac_powerdown,
216                 .write = ad5791_write_dac_powerdown,
217         },
218         IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
219         IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
220         { },
221 };
222
223 #define AD5791_CHAN(bits, shift) {                      \
224         .type = IIO_VOLTAGE,                            \
225         .output = 1,                                    \
226         .indexed = 1,                                   \
227         .address = AD5791_ADDR_DAC0,                    \
228         .channel = 0,                                   \
229         .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
230                 IIO_CHAN_INFO_SCALE_SHARED_BIT |        \
231                 IIO_CHAN_INFO_OFFSET_SHARED_BIT,        \
232         .scan_type = IIO_ST('u', bits, 24, shift),      \
233         .ext_info = ad5791_ext_info,                    \
234 }
235
236 static const struct iio_chan_spec ad5791_channels[] = {
237         [ID_AD5760] = AD5791_CHAN(16, 4),
238         [ID_AD5780] = AD5791_CHAN(18, 2),
239         [ID_AD5781] = AD5791_CHAN(18, 2),
240         [ID_AD5791] = AD5791_CHAN(20, 0)
241 };
242
243 static int ad5791_write_raw(struct iio_dev *indio_dev,
244                             struct iio_chan_spec const *chan,
245                             int val,
246                             int val2,
247                             long mask)
248 {
249         struct ad5791_state *st = iio_priv(indio_dev);
250
251         switch (mask) {
252         case IIO_CHAN_INFO_RAW:
253                 val &= AD5791_RES_MASK(chan->scan_type.realbits);
254                 val <<= chan->scan_type.shift;
255
256                 return ad5791_spi_write(st->spi, chan->address, val);
257
258         default:
259                 return -EINVAL;
260         }
261 }
262
263 static const struct iio_info ad5791_info = {
264         .read_raw = &ad5791_read_raw,
265         .write_raw = &ad5791_write_raw,
266         .driver_module = THIS_MODULE,
267 };
268
269 static int __devinit ad5791_probe(struct spi_device *spi)
270 {
271         struct ad5791_platform_data *pdata = spi->dev.platform_data;
272         struct iio_dev *indio_dev;
273         struct ad5791_state *st;
274         int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
275
276         indio_dev = iio_device_alloc(sizeof(*st));
277         if (indio_dev == NULL) {
278                 ret = -ENOMEM;
279                 goto error_ret;
280         }
281         st = iio_priv(indio_dev);
282         st->reg_vdd = regulator_get(&spi->dev, "vdd");
283         if (!IS_ERR(st->reg_vdd)) {
284                 ret = regulator_enable(st->reg_vdd);
285                 if (ret)
286                         goto error_put_reg_pos;
287
288                 pos_voltage_uv = regulator_get_voltage(st->reg_vdd);
289         }
290
291         st->reg_vss = regulator_get(&spi->dev, "vss");
292         if (!IS_ERR(st->reg_vss)) {
293                 ret = regulator_enable(st->reg_vss);
294                 if (ret)
295                         goto error_put_reg_neg;
296
297                 neg_voltage_uv = regulator_get_voltage(st->reg_vss);
298         }
299
300         st->pwr_down = true;
301         st->spi = spi;
302
303         if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
304                 st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
305                 st->vref_neg_mv = neg_voltage_uv / 1000;
306         } else if (pdata) {
307                 st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
308                 st->vref_neg_mv = pdata->vref_neg_mv;
309         } else {
310                 dev_warn(&spi->dev, "reference voltage unspecified\n");
311         }
312
313         ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
314         if (ret)
315                 goto error_disable_reg_neg;
316
317         st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi)
318                                               ->driver_data];
319
320
321         st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
322                   | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
323                   AD5791_CTRL_BIN2SC;
324
325         ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl |
326                 AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
327         if (ret)
328                 goto error_disable_reg_neg;
329
330         spi_set_drvdata(spi, indio_dev);
331         indio_dev->dev.parent = &spi->dev;
332         indio_dev->info = &ad5791_info;
333         indio_dev->modes = INDIO_DIRECT_MODE;
334         indio_dev->channels
335                 = &ad5791_channels[spi_get_device_id(spi)->driver_data];
336         indio_dev->num_channels = 1;
337         indio_dev->name = spi_get_device_id(st->spi)->name;
338         ret = iio_device_register(indio_dev);
339         if (ret)
340                 goto error_disable_reg_neg;
341
342         return 0;
343
344 error_disable_reg_neg:
345         if (!IS_ERR(st->reg_vss))
346                 regulator_disable(st->reg_vss);
347 error_put_reg_neg:
348         if (!IS_ERR(st->reg_vss))
349                 regulator_put(st->reg_vss);
350
351         if (!IS_ERR(st->reg_vdd))
352                 regulator_disable(st->reg_vdd);
353 error_put_reg_pos:
354         if (!IS_ERR(st->reg_vdd))
355                 regulator_put(st->reg_vdd);
356         iio_device_free(indio_dev);
357 error_ret:
358
359         return ret;
360 }
361
362 static int __devexit ad5791_remove(struct spi_device *spi)
363 {
364         struct iio_dev *indio_dev = spi_get_drvdata(spi);
365         struct ad5791_state *st = iio_priv(indio_dev);
366
367         iio_device_unregister(indio_dev);
368         if (!IS_ERR(st->reg_vdd)) {
369                 regulator_disable(st->reg_vdd);
370                 regulator_put(st->reg_vdd);
371         }
372
373         if (!IS_ERR(st->reg_vss)) {
374                 regulator_disable(st->reg_vss);
375                 regulator_put(st->reg_vss);
376         }
377         iio_device_free(indio_dev);
378
379         return 0;
380 }
381
382 static const struct spi_device_id ad5791_id[] = {
383         {"ad5760", ID_AD5760},
384         {"ad5780", ID_AD5780},
385         {"ad5781", ID_AD5781},
386         {"ad5790", ID_AD5791},
387         {"ad5791", ID_AD5791},
388         {}
389 };
390 MODULE_DEVICE_TABLE(spi, ad5791_id);
391
392 static struct spi_driver ad5791_driver = {
393         .driver = {
394                    .name = "ad5791",
395                    .owner = THIS_MODULE,
396                    },
397         .probe = ad5791_probe,
398         .remove = __devexit_p(ad5791_remove),
399         .id_table = ad5791_id,
400 };
401 module_spi_driver(ad5791_driver);
402
403 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
404 MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
405 MODULE_LICENSE("GPL v2");