aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-02-21 12:38:16 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-24 15:12:26 -0500
commitbb92ff3e54530f8a1a5e0c85eaeee350c9ee0f1a (patch)
tree215506722a56bfe69e6752b25d1fea4d676052c2 /drivers/staging/iio
parentf8be4af1f272d992decdd7389dc37c49b935d216 (diff)
staging:iio:dac:ad5064: Add AD5628/AD5648/AD5668 support
The AD5628/AD5648/AD5668 are similar to the AD5024/AD5044/AD5064. The difference being that they have an internal reference voltage and 8 instead of 4 DAC channels. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/dac/Kconfig5
-rw-r--r--drivers/staging/iio/dac/ad5064.c122
2 files changed, 107 insertions, 20 deletions
diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig
index 66b2504a1ed..ab8516d76bc 100644
--- a/drivers/staging/iio/dac/Kconfig
+++ b/drivers/staging/iio/dac/Kconfig
@@ -4,11 +4,12 @@
4menu "Digital to analog converters" 4menu "Digital to analog converters"
5 5
6config AD5064 6config AD5064
7 tristate "Analog Devices AD5064/64-1/65/44/45/24/25 DAC driver" 7 tristate "Analog Devices AD5064/64-1/65/44/45/24/25, AD5628/48/68 DAC driver"
8 depends on SPI 8 depends on SPI
9 help 9 help
10 Say yes here to build support for Analog Devices AD5024, AD5025, AD5044, 10 Say yes here to build support for Analog Devices AD5024, AD5025, AD5044,
11 AD5045, AD5064, AD5064-1, AD5065 Digital to Analog Converter. 11 AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648, AD5668 Digital to Analog
12 Converter.
12 13
13 To compile this driver as a module, choose M here: the 14 To compile this driver as a module, choose M here: the
14 module will be called ad5064. 15 module will be called ad5064.
diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c
index 865e81fc2da..6dab0645aa6 100644
--- a/drivers/staging/iio/dac/ad5064.c
+++ b/drivers/staging/iio/dac/ad5064.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1 Digital to analog converters 2 * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648,
3 * driver 3 * AD5668 Digital to analog converters driver
4 * 4 *
5 * Copyright 2011 Analog Devices Inc. 5 * Copyright 2011 Analog Devices Inc.
6 * 6 *
@@ -20,7 +20,7 @@
20#include "../sysfs.h" 20#include "../sysfs.h"
21#include "dac.h" 21#include "dac.h"
22 22
23#define AD5064_MAX_DAC_CHANNELS 4 23#define AD5064_MAX_DAC_CHANNELS 8
24#define AD5064_MAX_VREFS 4 24#define AD5064_MAX_VREFS 4
25 25
26#define AD5064_ADDR(x) ((x) << 20) 26#define AD5064_ADDR(x) ((x) << 20)
@@ -37,7 +37,10 @@
37#define AD5064_CMD_CLEAR 0x5 37#define AD5064_CMD_CLEAR 0x5
38#define AD5064_CMD_LDAC_MASK 0x6 38#define AD5064_CMD_LDAC_MASK 0x6
39#define AD5064_CMD_RESET 0x7 39#define AD5064_CMD_RESET 0x7
40#define AD5064_CMD_DAISY_CHAIN_ENABLE 0x8 40#define AD5064_CMD_CONFIG 0x8
41
42#define AD5064_CONFIG_DAISY_CHAIN_ENABLE BIT(1)
43#define AD5064_CONFIG_INT_VREF_ENABLE BIT(0)
41 44
42#define AD5064_LDAC_PWRDN_NONE 0x0 45#define AD5064_LDAC_PWRDN_NONE 0x0
43#define AD5064_LDAC_PWRDN_1K 0x1 46#define AD5064_LDAC_PWRDN_1K 0x1
@@ -47,12 +50,15 @@
47/** 50/**
48 * struct ad5064_chip_info - chip specific information 51 * struct ad5064_chip_info - chip specific information
49 * @shared_vref: whether the vref supply is shared between channels 52 * @shared_vref: whether the vref supply is shared between channels
53 * @internal_vref: internal reference voltage. 0 if the chip has no internal
54 * vref.
50 * @channel: channel specification 55 * @channel: channel specification
51 * @num_channels: number of channels 56 * @num_channels: number of channels
52 */ 57 */
53 58
54struct ad5064_chip_info { 59struct ad5064_chip_info {
55 bool shared_vref; 60 bool shared_vref;
61 unsigned long internal_vref;
56 const struct iio_chan_spec *channels; 62 const struct iio_chan_spec *channels;
57 unsigned int num_channels; 63 unsigned int num_channels;
58}; 64};
@@ -65,6 +71,8 @@ struct ad5064_chip_info {
65 * @pwr_down: whether channel is powered down 71 * @pwr_down: whether channel is powered down
66 * @pwr_down_mode: channel's current power down mode 72 * @pwr_down_mode: channel's current power down mode
67 * @dac_cache: current DAC raw value (chip does not support readback) 73 * @dac_cache: current DAC raw value (chip does not support readback)
74 * @use_internal_vref: set to true if the internal reference voltage should be
75 * used.
68 * @data: spi transfer buffers 76 * @data: spi transfer buffers
69 */ 77 */
70 78
@@ -75,6 +83,7 @@ struct ad5064_state {
75 bool pwr_down[AD5064_MAX_DAC_CHANNELS]; 83 bool pwr_down[AD5064_MAX_DAC_CHANNELS];
76 u8 pwr_down_mode[AD5064_MAX_DAC_CHANNELS]; 84 u8 pwr_down_mode[AD5064_MAX_DAC_CHANNELS];
77 unsigned int dac_cache[AD5064_MAX_DAC_CHANNELS]; 85 unsigned int dac_cache[AD5064_MAX_DAC_CHANNELS];
86 bool use_internal_vref;
78 87
79 /* 88 /*
80 * DMA (thus cache coherency maintenance) requires the 89 * DMA (thus cache coherency maintenance) requires the
@@ -91,6 +100,12 @@ enum ad5064_type {
91 ID_AD5064, 100 ID_AD5064,
92 ID_AD5064_1, 101 ID_AD5064_1,
93 ID_AD5065, 102 ID_AD5065,
103 ID_AD5628_1,
104 ID_AD5628_2,
105 ID_AD5648_1,
106 ID_AD5648_2,
107 ID_AD5668_1,
108 ID_AD5668_2,
94}; 109};
95 110
96static int ad5064_spi_write(struct ad5064_state *st, unsigned int cmd, 111static int ad5064_spi_write(struct ad5064_state *st, unsigned int cmd,
@@ -196,6 +211,18 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev,
196 return ret ? ret : len; 211 return ret ? ret : len;
197} 212}
198 213
214static int ad5064_get_vref(struct ad5064_state *st,
215 struct iio_chan_spec const *chan)
216{
217 unsigned int i;
218
219 if (st->use_internal_vref)
220 return st->chip_info->internal_vref;
221
222 i = st->chip_info->shared_vref ? 0 : chan->channel;
223 return regulator_get_voltage(st->vref_reg[i].consumer);
224}
225
199static int ad5064_read_raw(struct iio_dev *indio_dev, 226static int ad5064_read_raw(struct iio_dev *indio_dev,
200 struct iio_chan_spec const *chan, 227 struct iio_chan_spec const *chan,
201 int *val, 228 int *val,
@@ -203,7 +230,6 @@ static int ad5064_read_raw(struct iio_dev *indio_dev,
203 long m) 230 long m)
204{ 231{
205 struct ad5064_state *st = iio_priv(indio_dev); 232 struct ad5064_state *st = iio_priv(indio_dev);
206 unsigned int vref;
207 int scale_uv; 233 int scale_uv;
208 234
209 switch (m) { 235 switch (m) {
@@ -211,8 +237,7 @@ static int ad5064_read_raw(struct iio_dev *indio_dev,
211 *val = st->dac_cache[chan->channel]; 237 *val = st->dac_cache[chan->channel];
212 return IIO_VAL_INT; 238 return IIO_VAL_INT;
213 case IIO_CHAN_INFO_SCALE: 239 case IIO_CHAN_INFO_SCALE:
214 vref = st->chip_info->shared_vref ? 0 : chan->channel; 240 scale_uv = ad5064_get_vref(st, chan);
215 scale_uv = regulator_get_voltage(st->vref_reg[vref].consumer);
216 if (scale_uv < 0) 241 if (scale_uv < 0)
217 return scale_uv; 242 return scale_uv;
218 243
@@ -293,6 +318,10 @@ const struct iio_chan_spec name[] = { \
293 AD5064_CHANNEL(1, bits), \ 318 AD5064_CHANNEL(1, bits), \
294 AD5064_CHANNEL(2, bits), \ 319 AD5064_CHANNEL(2, bits), \
295 AD5064_CHANNEL(3, bits), \ 320 AD5064_CHANNEL(3, bits), \
321 AD5064_CHANNEL(4, bits), \
322 AD5064_CHANNEL(5, bits), \
323 AD5064_CHANNEL(6, bits), \
324 AD5064_CHANNEL(7, bits), \
296} 325}
297 326
298static DECLARE_AD5064_CHANNELS(ad5024_channels, 12); 327static DECLARE_AD5064_CHANNELS(ad5024_channels, 12);
@@ -335,6 +364,42 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
335 .channels = ad5064_channels, 364 .channels = ad5064_channels,
336 .num_channels = 2, 365 .num_channels = 2,
337 }, 366 },
367 [ID_AD5628_1] = {
368 .shared_vref = true,
369 .internal_vref = 2500000,
370 .channels = ad5024_channels,
371 .num_channels = 8,
372 },
373 [ID_AD5628_2] = {
374 .shared_vref = true,
375 .internal_vref = 5000000,
376 .channels = ad5024_channels,
377 .num_channels = 8,
378 },
379 [ID_AD5648_1] = {
380 .shared_vref = true,
381 .internal_vref = 2500000,
382 .channels = ad5044_channels,
383 .num_channels = 8,
384 },
385 [ID_AD5648_2] = {
386 .shared_vref = true,
387 .internal_vref = 5000000,
388 .channels = ad5044_channels,
389 .num_channels = 8,
390 },
391 [ID_AD5668_1] = {
392 .shared_vref = true,
393 .internal_vref = 2500000,
394 .channels = ad5064_channels,
395 .num_channels = 8,
396 },
397 [ID_AD5668_2] = {
398 .shared_vref = true,
399 .internal_vref = 5000000,
400 .channels = ad5064_channels,
401 .num_channels = 8,
402 },
338}; 403};
339 404
340static inline unsigned int ad5064_num_vref(struct ad5064_state *st) 405static inline unsigned int ad5064_num_vref(struct ad5064_state *st)
@@ -378,12 +443,22 @@ static int __devinit ad5064_probe(struct spi_device *spi)
378 443
379 ret = regulator_bulk_get(&st->spi->dev, ad5064_num_vref(st), 444 ret = regulator_bulk_get(&st->spi->dev, ad5064_num_vref(st),
380 st->vref_reg); 445 st->vref_reg);
381 if (ret) 446 if (ret) {
382 goto error_free; 447 if (!st->chip_info->internal_vref)
383 448 goto error_free;
384 ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg); 449 st->use_internal_vref = true;
385 if (ret) 450 ret = ad5064_spi_write(st, AD5064_CMD_CONFIG, 0,
386 goto error_free_reg; 451 AD5064_CONFIG_INT_VREF_ENABLE, 0);
452 if (ret) {
453 dev_err(&spi->dev, "Failed to enable internal vref: %d\n",
454 ret);
455 goto error_free;
456 }
457 } else {
458 ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
459 if (ret)
460 goto error_free_reg;
461 }
387 462
388 for (i = 0; i < st->chip_info->num_channels; ++i) { 463 for (i = 0; i < st->chip_info->num_channels; ++i) {
389 st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K; 464 st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
@@ -404,9 +479,11 @@ static int __devinit ad5064_probe(struct spi_device *spi)
404 return 0; 479 return 0;
405 480
406error_disable_reg: 481error_disable_reg:
407 regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg); 482 if (!st->use_internal_vref)
483 regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
408error_free_reg: 484error_free_reg:
409 regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); 485 if (!st->use_internal_vref)
486 regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
410error_free: 487error_free:
411 iio_free_device(indio_dev); 488 iio_free_device(indio_dev);
412 489
@@ -421,8 +498,10 @@ static int __devexit ad5064_remove(struct spi_device *spi)
421 498
422 iio_device_unregister(indio_dev); 499 iio_device_unregister(indio_dev);
423 500
424 regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg); 501 if (!st->use_internal_vref) {
425 regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); 502 regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
503 regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
504 }
426 505
427 iio_free_device(indio_dev); 506 iio_free_device(indio_dev);
428 507
@@ -437,6 +516,13 @@ static const struct spi_device_id ad5064_id[] = {
437 {"ad5064", ID_AD5064}, 516 {"ad5064", ID_AD5064},
438 {"ad5064-1", ID_AD5064_1}, 517 {"ad5064-1", ID_AD5064_1},
439 {"ad5065", ID_AD5065}, 518 {"ad5065", ID_AD5065},
519 {"ad5628-1", ID_AD5628_1},
520 {"ad5628-2", ID_AD5628_2},
521 {"ad5648-1", ID_AD5648_1},
522 {"ad5648-2", ID_AD5648_2},
523 {"ad5668-1", ID_AD5668_1},
524 {"ad5668-2", ID_AD5668_2},
525 {"ad5668-3", ID_AD5668_2}, /* similar enough to ad5668-2 */
440 {} 526 {}
441}; 527};
442MODULE_DEVICE_TABLE(spi, ad5064_id); 528MODULE_DEVICE_TABLE(spi, ad5064_id);
@@ -453,5 +539,5 @@ static struct spi_driver ad5064_driver = {
453module_spi_driver(ad5064_driver); 539module_spi_driver(ad5064_driver);
454 540
455MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 541MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
456MODULE_DESCRIPTION("Analog Devices AD5024/25/44/45/64/64-1/65 DAC"); 542MODULE_DESCRIPTION("Analog Devices AD5024/25/44/45/64/64-1/65, AD5628/48/68 DAC");
457MODULE_LICENSE("GPL v2"); 543MODULE_LICENSE("GPL v2");