~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/iio/dac/ad5791.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * AD5760, AD5780, AD5781, AD5791 Voltage Output Digital to Analog Converter
 
3
 *
 
4
 * Copyright 2011 Analog Devices Inc.
 
5
 *
 
6
 * Licensed under the GPL-2.
 
7
 */
 
8
 
 
9
#include <linux/interrupt.h>
 
10
#include <linux/gpio.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
 
 
19
#include "../iio.h"
 
20
#include "../sysfs.h"
 
21
#include "dac.h"
 
22
#include "ad5791.h"
 
23
 
 
24
static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val)
 
25
{
 
26
        union {
 
27
                u32 d32;
 
28
                u8 d8[4];
 
29
        } data;
 
30
 
 
31
        data.d32 = cpu_to_be32(AD5791_CMD_WRITE |
 
32
                              AD5791_ADDR(addr) |
 
33
                              (val & AD5791_DAC_MASK));
 
34
 
 
35
        return spi_write(spi, &data.d8[1], 3);
 
36
}
 
37
 
 
38
static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
 
39
{
 
40
        union {
 
41
                u32 d32;
 
42
                u8 d8[4];
 
43
        } data[3];
 
44
        int ret;
 
45
        struct spi_message msg;
 
46
        struct spi_transfer xfers[] = {
 
47
                {
 
48
                        .tx_buf = &data[0].d8[1],
 
49
                        .bits_per_word = 8,
 
50
                        .len = 3,
 
51
                        .cs_change = 1,
 
52
                }, {
 
53
                        .tx_buf = &data[1].d8[1],
 
54
                        .rx_buf = &data[2].d8[1],
 
55
                        .bits_per_word = 8,
 
56
                        .len = 3,
 
57
                },
 
58
        };
 
59
 
 
60
        data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
 
61
                              AD5791_ADDR(addr));
 
62
        data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
 
63
 
 
64
        spi_message_init(&msg);
 
65
        spi_message_add_tail(&xfers[0], &msg);
 
66
        spi_message_add_tail(&xfers[1], &msg);
 
67
        ret = spi_sync(spi, &msg);
 
68
 
 
69
        *val = be32_to_cpu(data[2].d32);
 
70
 
 
71
        return ret;
 
72
}
 
73
 
 
74
static ssize_t ad5791_write_dac(struct device *dev,
 
75
                                 struct device_attribute *attr,
 
76
                                 const char *buf, size_t len)
 
77
{
 
78
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
79
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
80
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
81
        long readin;
 
82
        int ret;
 
83
 
 
84
        ret = strict_strtol(buf, 10, &readin);
 
85
        if (ret)
 
86
                return ret;
 
87
 
 
88
        readin += (1 << (st->chip_info->bits - 1));
 
89
        readin &= AD5791_RES_MASK(st->chip_info->bits);
 
90
        readin <<= st->chip_info->left_shift;
 
91
 
 
92
        ret = ad5791_spi_write(st->spi, this_attr->address, readin);
 
93
        return ret ? ret : len;
 
94
}
 
95
 
 
96
static ssize_t ad5791_read_dac(struct device *dev,
 
97
                                           struct device_attribute *attr,
 
98
                                           char *buf)
 
99
{
 
100
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
101
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
102
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
103
        int ret;
 
104
        int val;
 
105
 
 
106
        ret = ad5791_spi_read(st->spi, this_attr->address, &val);
 
107
        if (ret)
 
108
                return ret;
 
109
 
 
110
        val &= AD5791_DAC_MASK;
 
111
        val >>= st->chip_info->left_shift;
 
112
        val -= (1 << (st->chip_info->bits - 1));
 
113
 
 
114
        return sprintf(buf, "%d\n", val);
 
115
}
 
116
 
 
117
static ssize_t ad5791_read_powerdown_mode(struct device *dev,
 
118
                                      struct device_attribute *attr, char *buf)
 
119
{
 
120
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
121
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
122
 
 
123
        const char mode[][14] = {"6kohm_to_gnd", "three_state"};
 
124
 
 
125
        return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
 
126
}
 
127
 
 
128
static ssize_t ad5791_write_powerdown_mode(struct device *dev,
 
129
                                       struct device_attribute *attr,
 
130
                                       const char *buf, size_t len)
 
131
{
 
132
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
133
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
134
        int ret;
 
135
 
 
136
        if (sysfs_streq(buf, "6kohm_to_gnd"))
 
137
                st->pwr_down_mode = AD5791_DAC_PWRDN_6K;
 
138
        else if (sysfs_streq(buf, "three_state"))
 
139
                st->pwr_down_mode = AD5791_DAC_PWRDN_3STATE;
 
140
        else
 
141
                ret = -EINVAL;
 
142
 
 
143
        return ret ? ret : len;
 
144
}
 
145
 
 
146
static ssize_t ad5791_read_dac_powerdown(struct device *dev,
 
147
                                           struct device_attribute *attr,
 
148
                                           char *buf)
 
149
{
 
150
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
151
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
152
 
 
153
        return sprintf(buf, "%d\n", st->pwr_down);
 
154
}
 
155
 
 
156
static ssize_t ad5791_write_dac_powerdown(struct device *dev,
 
157
                                            struct device_attribute *attr,
 
158
                                            const char *buf, size_t len)
 
159
{
 
160
        long readin;
 
161
        int ret;
 
162
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
163
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
164
 
 
165
        ret = strict_strtol(buf, 10, &readin);
 
166
        if (ret)
 
167
                return ret;
 
168
 
 
169
        if (readin == 0) {
 
170
                st->pwr_down = false;
 
171
                st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
 
172
        } else if (readin == 1) {
 
173
                st->pwr_down = true;
 
174
                if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
 
175
                        st->ctrl |= AD5791_CTRL_OPGND;
 
176
                else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
 
177
                        st->ctrl |= AD5791_CTRL_DACTRI;
 
178
        } else
 
179
                ret = -EINVAL;
 
180
 
 
181
        ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl);
 
182
 
 
183
        return ret ? ret : len;
 
184
}
 
185
 
 
186
static ssize_t ad5791_show_scale(struct device *dev,
 
187
                                struct device_attribute *attr,
 
188
                                char *buf)
 
189
{
 
190
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
191
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
192
        /* Corresponds to Vref / 2^(bits) */
 
193
        unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
 
194
 
 
195
        return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
 
196
}
 
197
static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5791_show_scale, NULL, 0);
 
198
 
 
199
static ssize_t ad5791_show_name(struct device *dev,
 
200
                                 struct device_attribute *attr,
 
201
                                 char *buf)
 
202
{
 
203
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
204
        struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
 
205
 
 
206
        return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
 
207
}
 
208
static IIO_DEVICE_ATTR(name, S_IRUGO, ad5791_show_name, NULL, 0);
 
209
 
 
210
#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr)             \
 
211
        IIO_DEVICE_ATTR(out##_num##_raw,                                \
 
212
                        S_IRUGO | S_IWUSR, _show, _store, _addr)
 
213
 
 
214
static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5791_read_dac,
 
215
        ad5791_write_dac, AD5791_ADDR_DAC0);
 
216
 
 
217
static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
 
218
                        S_IWUSR, ad5791_read_powerdown_mode,
 
219
                        ad5791_write_powerdown_mode, 0);
 
220
 
 
221
static IIO_CONST_ATTR(out_powerdown_mode_available,
 
222
                        "6kohm_to_gnd three_state");
 
223
 
 
224
#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr)          \
 
225
        IIO_DEVICE_ATTR(out##_num##_powerdown,                          \
 
226
                        S_IRUGO | S_IWUSR, _show, _store, _addr)
 
227
 
 
228
static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5791_read_dac_powerdown,
 
229
                                   ad5791_write_dac_powerdown, 0);
 
230
 
 
231
static struct attribute *ad5791_attributes[] = {
 
232
        &iio_dev_attr_out0_raw.dev_attr.attr,
 
233
        &iio_dev_attr_out0_powerdown.dev_attr.attr,
 
234
        &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 
235
        &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
 
236
        &iio_dev_attr_out_scale.dev_attr.attr,
 
237
        &iio_dev_attr_name.dev_attr.attr,
 
238
        NULL,
 
239
};
 
240
 
 
241
static const struct attribute_group ad5791_attribute_group = {
 
242
        .attrs = ad5791_attributes,
 
243
};
 
244
 
 
245
static int ad5791_get_lin_comp(unsigned int span)
 
246
{
 
247
        if (span <= 10000)
 
248
                return AD5791_LINCOMP_0_10;
 
249
        else if (span <= 12000)
 
250
                return AD5791_LINCOMP_10_12;
 
251
        else if (span <= 16000)
 
252
                return AD5791_LINCOMP_12_16;
 
253
        else if (span <= 19000)
 
254
                return AD5791_LINCOMP_16_19;
 
255
        else
 
256
                return AD5791_LINCOMP_19_20;
 
257
}
 
258
 
 
259
static int ad5780_get_lin_comp(unsigned int span)
 
260
{
 
261
        if (span <= 10000)
 
262
                return AD5780_LINCOMP_0_10;
 
263
        else
 
264
                return AD5780_LINCOMP_10_20;
 
265
}
 
266
 
 
267
static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
 
268
        [ID_AD5760] = {
 
269
                .bits = 16,
 
270
                .left_shift = 4,
 
271
                .get_lin_comp = ad5780_get_lin_comp,
 
272
        },
 
273
        [ID_AD5780] = {
 
274
                .bits = 18,
 
275
                .left_shift = 2,
 
276
                .get_lin_comp = ad5780_get_lin_comp,
 
277
        },
 
278
        [ID_AD5781] = {
 
279
                .bits = 18,
 
280
                .left_shift = 2,
 
281
                .get_lin_comp = ad5791_get_lin_comp,
 
282
        },
 
283
        [ID_AD5791] = {
 
284
                .bits = 20,
 
285
                .left_shift = 0,
 
286
                .get_lin_comp = ad5791_get_lin_comp,
 
287
        },
 
288
};
 
289
 
 
290
static const struct iio_info ad5791_info = {
 
291
        .attrs = &ad5791_attribute_group,
 
292
        .driver_module = THIS_MODULE,
 
293
};
 
294
 
 
295
static int __devinit ad5791_probe(struct spi_device *spi)
 
296
{
 
297
        struct ad5791_platform_data *pdata = spi->dev.platform_data;
 
298
        struct ad5791_state *st;
 
299
        int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
 
300
 
 
301
        st = kzalloc(sizeof(*st), GFP_KERNEL);
 
302
        if (st == NULL) {
 
303
                ret = -ENOMEM;
 
304
                goto error_ret;
 
305
        }
 
306
 
 
307
        spi_set_drvdata(spi, st);
 
308
 
 
309
        st->reg_vdd = regulator_get(&spi->dev, "vdd");
 
310
        if (!IS_ERR(st->reg_vdd)) {
 
311
                ret = regulator_enable(st->reg_vdd);
 
312
                if (ret)
 
313
                        goto error_put_reg_pos;
 
314
 
 
315
                pos_voltage_uv = regulator_get_voltage(st->reg_vdd);
 
316
        }
 
317
 
 
318
        st->reg_vss = regulator_get(&spi->dev, "vss");
 
319
        if (!IS_ERR(st->reg_vss)) {
 
320
                ret = regulator_enable(st->reg_vss);
 
321
                if (ret)
 
322
                        goto error_put_reg_neg;
 
323
 
 
324
                neg_voltage_uv = regulator_get_voltage(st->reg_vss);
 
325
        }
 
326
 
 
327
        if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd))
 
328
                st->vref_mv = (pos_voltage_uv - neg_voltage_uv) / 1000;
 
329
        else if (pdata)
 
330
                st->vref_mv = pdata->vref_pos_mv - pdata->vref_neg_mv;
 
331
        else
 
332
                dev_warn(&spi->dev, "reference voltage unspecified\n");
 
333
 
 
334
        ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
 
335
        if (ret)
 
336
                goto error_disable_reg_neg;
 
337
 
 
338
        st->chip_info =
 
339
                &ad5791_chip_info_tbl[spi_get_device_id(spi)->driver_data];
 
340
 
 
341
 
 
342
        st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
 
343
                  | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
 
344
                  AD5791_CTRL_BIN2SC;
 
345
 
 
346
        ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl |
 
347
                AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
 
348
        if (ret)
 
349
                goto error_disable_reg_neg;
 
350
 
 
351
        st->pwr_down = true;
 
352
 
 
353
        st->spi = spi;
 
354
        st->indio_dev = iio_allocate_device(0);
 
355
        if (st->indio_dev == NULL) {
 
356
                ret = -ENOMEM;
 
357
                goto error_disable_reg_neg;
 
358
        }
 
359
        st->indio_dev->dev.parent = &spi->dev;
 
360
        st->indio_dev->dev_data = (void *)(st);
 
361
        st->indio_dev->info = &ad5791_info;
 
362
        st->indio_dev->modes = INDIO_DIRECT_MODE;
 
363
 
 
364
        ret = iio_device_register(st->indio_dev);
 
365
        if (ret)
 
366
                goto error_free_dev;
 
367
 
 
368
        return 0;
 
369
 
 
370
error_free_dev:
 
371
        iio_free_device(st->indio_dev);
 
372
 
 
373
error_disable_reg_neg:
 
374
        if (!IS_ERR(st->reg_vss))
 
375
                regulator_disable(st->reg_vss);
 
376
error_put_reg_neg:
 
377
        if (!IS_ERR(st->reg_vss))
 
378
                regulator_put(st->reg_vss);
 
379
 
 
380
        if (!IS_ERR(st->reg_vdd))
 
381
                regulator_disable(st->reg_vdd);
 
382
error_put_reg_pos:
 
383
        if (!IS_ERR(st->reg_vdd))
 
384
                regulator_put(st->reg_vdd);
 
385
 
 
386
        kfree(st);
 
387
error_ret:
 
388
        return ret;
 
389
}
 
390
 
 
391
static int __devexit ad5791_remove(struct spi_device *spi)
 
392
{
 
393
        struct ad5791_state *st = spi_get_drvdata(spi);
 
394
 
 
395
        iio_device_unregister(st->indio_dev);
 
396
 
 
397
        if (!IS_ERR(st->reg_vdd)) {
 
398
                regulator_disable(st->reg_vdd);
 
399
                regulator_put(st->reg_vdd);
 
400
        }
 
401
 
 
402
        if (!IS_ERR(st->reg_vss)) {
 
403
                regulator_disable(st->reg_vss);
 
404
                regulator_put(st->reg_vss);
 
405
        }
 
406
 
 
407
        kfree(st);
 
408
 
 
409
        return 0;
 
410
}
 
411
 
 
412
static const struct spi_device_id ad5791_id[] = {
 
413
        {"ad5760", ID_AD5760},
 
414
        {"ad5780", ID_AD5780},
 
415
        {"ad5781", ID_AD5781},
 
416
        {"ad5791", ID_AD5791},
 
417
        {}
 
418
};
 
419
 
 
420
static struct spi_driver ad5791_driver = {
 
421
        .driver = {
 
422
                   .name = "ad5791",
 
423
                   .owner = THIS_MODULE,
 
424
                   },
 
425
        .probe = ad5791_probe,
 
426
        .remove = __devexit_p(ad5791_remove),
 
427
        .id_table = ad5791_id,
 
428
};
 
429
 
 
430
static __init int ad5791_spi_init(void)
 
431
{
 
432
        return spi_register_driver(&ad5791_driver);
 
433
}
 
434
module_init(ad5791_spi_init);
 
435
 
 
436
static __exit void ad5791_spi_exit(void)
 
437
{
 
438
        spi_unregister_driver(&ad5791_driver);
 
439
}
 
440
module_exit(ad5791_spi_exit);
 
441
 
 
442
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 
443
MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5791 DAC");
 
444
MODULE_LICENSE("GPL v2");