aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2016-02-08 12:01:50 -0500
committerJonathan Cameron <jic23@kernel.org>2016-02-08 13:51:26 -0500
commitf47732c0daf5d1607ba0775edad3460d18ee1f83 (patch)
treeaeaee25b709681fa776f0676bfdecc4fa38459e6 /drivers/iio
parent4946ff5858392012ed17a079c5b3dd4bc4b15cf9 (diff)
iio:ad5064: Add AD5625/AD5627/AD5645/AD5647/AD4665/AD5657 support
The AD5625/AD5645/AD5665 are a family of 4 channel DACs with 12-bit, 14-bit and 16-bit precision respectively. The devices come in 3 flavors in terms of built-in reference, either no built-in reference, built-in 1.25V reference or built-in 2.5V reference. The AD5627/AD5647/AD5667 are similar to the AD5625/AD5645/AD5665 except that they have 2 instead of 4 channels. While these new devices are mostly register map compatible with the existing devices support by the driver some offsets and register addresses have been shuffled around. To accommodate this introduce a new register map layout. For the lack of a better name we will just call it version 2. Datasheets: http://www.analog.com/media/en/technical-documentation/data-sheets/AD5625R_5645R_5665R_5625_5665.pdf http://www.analog.com/media/en/technical-documentation/data-sheets/AD5627R_5647R_5667R_5627_5667.pdf Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/dac/Kconfig7
-rw-r--r--drivers/iio/dac/ad5064.c192
2 files changed, 188 insertions, 11 deletions
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index a56b52dbefa0..3c809e2baecb 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -10,9 +10,10 @@ config AD5064
10 depends on (SPI_MASTER && I2C!=m) || I2C 10 depends on (SPI_MASTER && I2C!=m) || I2C
11 help 11 help
12 Say yes here to build support for Analog Devices AD5024, AD5025, AD5044, 12 Say yes here to build support for Analog Devices AD5024, AD5025, AD5044,
13 AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, AD5648, AD5666, AD5668, 13 AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R, AD5627, AD5627R,
14 AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, LTC2617, LTC2619, LTC2626, 14 AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R, AD5666,
15 LTC2627, LTC2629 Digital to Analog Converter. 15 AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616,
16 LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to Analog Converter.
16 17
17 To compile this driver as a module, choose M here: the 18 To compile this driver as a module, choose M here: the
18 module will be called ad5064. 19 module will be called ad5064.
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
index b7f717cadd0b..6803e4a137cd 100644
--- a/drivers/iio/dac/ad5064.c
+++ b/drivers/iio/dac/ad5064.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, 2 * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R,
3 * AD5648, AD5666, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, 3 * AD5627, AD5627R, AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R,
4 * AD5666, AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616,
4 * LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to analog converters 5 * LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to analog converters
5 * driver 6 * driver
6 * 7 *
@@ -41,6 +42,9 @@
41#define AD5064_CMD_RESET 0x7 42#define AD5064_CMD_RESET 0x7
42#define AD5064_CMD_CONFIG 0x8 43#define AD5064_CMD_CONFIG 0x8
43 44
45#define AD5064_CMD_RESET_V2 0x5
46#define AD5064_CMD_CONFIG_V2 0x7
47
44#define AD5064_CONFIG_DAISY_CHAIN_ENABLE BIT(1) 48#define AD5064_CONFIG_DAISY_CHAIN_ENABLE BIT(1)
45#define AD5064_CONFIG_INT_VREF_ENABLE BIT(0) 49#define AD5064_CONFIG_INT_VREF_ENABLE BIT(0)
46 50
@@ -51,11 +55,13 @@
51 55
52/** 56/**
53 * enum ad5064_regmap_type - Register layout variant 57 * enum ad5064_regmap_type - Register layout variant
54 * @AD5064_REGMAP_ADI: Analog Devices register map layout 58 * @AD5064_REGMAP_ADI: Old Analog Devices register map layout
59 * @AD5064_REGMAP_ADI2: New Analog Devices register map layout
55 * @AD5064_REGMAP_LTC: LTC register map layout 60 * @AD5064_REGMAP_LTC: LTC register map layout
56 */ 61 */
57enum ad5064_regmap_type { 62enum ad5064_regmap_type {
58 AD5064_REGMAP_ADI, 63 AD5064_REGMAP_ADI,
64 AD5064_REGMAP_ADI2,
59 AD5064_REGMAP_LTC, 65 AD5064_REGMAP_LTC,
60}; 66};
61 67
@@ -125,14 +131,30 @@ enum ad5064_type {
125 ID_AD5064, 131 ID_AD5064,
126 ID_AD5064_1, 132 ID_AD5064_1,
127 ID_AD5065, 133 ID_AD5065,
134 ID_AD5625,
135 ID_AD5625R_1V25,
136 ID_AD5625R_2V5,
137 ID_AD5627,
138 ID_AD5627R_1V25,
139 ID_AD5627R_2V5,
128 ID_AD5628_1, 140 ID_AD5628_1,
129 ID_AD5628_2, 141 ID_AD5628_2,
130 ID_AD5629_1, 142 ID_AD5629_1,
131 ID_AD5629_2, 143 ID_AD5629_2,
144 ID_AD5645R_1V25,
145 ID_AD5645R_2V5,
146 ID_AD5647R_1V25,
147 ID_AD5647R_2V5,
132 ID_AD5648_1, 148 ID_AD5648_1,
133 ID_AD5648_2, 149 ID_AD5648_2,
150 ID_AD5665,
151 ID_AD5665R_1V25,
152 ID_AD5665R_2V5,
134 ID_AD5666_1, 153 ID_AD5666_1,
135 ID_AD5666_2, 154 ID_AD5666_2,
155 ID_AD5667,
156 ID_AD5667R_1V25,
157 ID_AD5667R_2V5,
136 ID_AD5668_1, 158 ID_AD5668_1,
137 ID_AD5668_2, 159 ID_AD5668_2,
138 ID_AD5669_1, 160 ID_AD5669_1,
@@ -160,17 +182,23 @@ static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
160 const struct iio_chan_spec *chan) 182 const struct iio_chan_spec *chan)
161{ 183{
162 unsigned int val, address; 184 unsigned int val, address;
185 unsigned int shift;
163 int ret; 186 int ret;
164 187
165 if (st->chip_info->regmap_type == AD5064_REGMAP_LTC) { 188 if (st->chip_info->regmap_type == AD5064_REGMAP_LTC) {
166 val = 0; 189 val = 0;
167 address = chan->address; 190 address = chan->address;
168 } else { 191 } else {
169 address = 0; 192 if (st->chip_info->regmap_type == AD5064_REGMAP_ADI2)
193 shift = 4;
194 else
195 shift = 8;
196
170 val = (0x1 << chan->address); 197 val = (0x1 << chan->address);
198 address = 0;
171 199
172 if (st->pwr_down[chan->channel]) 200 if (st->pwr_down[chan->channel])
173 val |= st->pwr_down_mode[chan->channel] << 8; 201 val |= st->pwr_down_mode[chan->channel] << shift;
174 } 202 }
175 203
176 ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, address, val, 0); 204 ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, address, val, 0);
@@ -391,6 +419,7 @@ static DECLARE_AD5065_CHANNELS(ad5045_channels, 14, 6, ad5064_ext_info);
391static DECLARE_AD5065_CHANNELS(ad5065_channels, 16, 4, ad5064_ext_info); 419static DECLARE_AD5065_CHANNELS(ad5065_channels, 16, 4, ad5064_ext_info);
392 420
393static DECLARE_AD5064_CHANNELS(ad5629_channels, 12, 4, ad5064_ext_info); 421static DECLARE_AD5064_CHANNELS(ad5629_channels, 12, 4, ad5064_ext_info);
422static DECLARE_AD5064_CHANNELS(ad5645_channels, 14, 2, ad5064_ext_info);
394static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0, ad5064_ext_info); 423static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0, ad5064_ext_info);
395 424
396static DECLARE_AD5064_CHANNELS(ltc2607_channels, 16, 0, ltc2617_ext_info); 425static DECLARE_AD5064_CHANNELS(ltc2607_channels, 16, 0, ltc2617_ext_info);
@@ -440,6 +469,46 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
440 .num_channels = 2, 469 .num_channels = 2,
441 .regmap_type = AD5064_REGMAP_ADI, 470 .regmap_type = AD5064_REGMAP_ADI,
442 }, 471 },
472 [ID_AD5625] = {
473 .shared_vref = true,
474 .channels = ad5629_channels,
475 .num_channels = 4,
476 .regmap_type = AD5064_REGMAP_ADI2
477 },
478 [ID_AD5625R_1V25] = {
479 .shared_vref = true,
480 .internal_vref = 1250000,
481 .channels = ad5629_channels,
482 .num_channels = 4,
483 .regmap_type = AD5064_REGMAP_ADI2
484 },
485 [ID_AD5625R_2V5] = {
486 .shared_vref = true,
487 .internal_vref = 2500000,
488 .channels = ad5629_channels,
489 .num_channels = 4,
490 .regmap_type = AD5064_REGMAP_ADI2
491 },
492 [ID_AD5627] = {
493 .shared_vref = true,
494 .channels = ad5629_channels,
495 .num_channels = 2,
496 .regmap_type = AD5064_REGMAP_ADI2
497 },
498 [ID_AD5627R_1V25] = {
499 .shared_vref = true,
500 .internal_vref = 1250000,
501 .channels = ad5629_channels,
502 .num_channels = 2,
503 .regmap_type = AD5064_REGMAP_ADI2
504 },
505 [ID_AD5627R_2V5] = {
506 .shared_vref = true,
507 .internal_vref = 2500000,
508 .channels = ad5629_channels,
509 .num_channels = 2,
510 .regmap_type = AD5064_REGMAP_ADI2
511 },
443 [ID_AD5628_1] = { 512 [ID_AD5628_1] = {
444 .shared_vref = true, 513 .shared_vref = true,
445 .internal_vref = 2500000, 514 .internal_vref = 2500000,
@@ -468,6 +537,34 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
468 .num_channels = 8, 537 .num_channels = 8,
469 .regmap_type = AD5064_REGMAP_ADI, 538 .regmap_type = AD5064_REGMAP_ADI,
470 }, 539 },
540 [ID_AD5645R_1V25] = {
541 .shared_vref = true,
542 .internal_vref = 1250000,
543 .channels = ad5645_channels,
544 .num_channels = 4,
545 .regmap_type = AD5064_REGMAP_ADI2
546 },
547 [ID_AD5645R_2V5] = {
548 .shared_vref = true,
549 .internal_vref = 2500000,
550 .channels = ad5645_channels,
551 .num_channels = 4,
552 .regmap_type = AD5064_REGMAP_ADI2
553 },
554 [ID_AD5647R_1V25] = {
555 .shared_vref = true,
556 .internal_vref = 1250000,
557 .channels = ad5645_channels,
558 .num_channels = 2,
559 .regmap_type = AD5064_REGMAP_ADI2
560 },
561 [ID_AD5647R_2V5] = {
562 .shared_vref = true,
563 .internal_vref = 2500000,
564 .channels = ad5645_channels,
565 .num_channels = 2,
566 .regmap_type = AD5064_REGMAP_ADI2
567 },
471 [ID_AD5648_1] = { 568 [ID_AD5648_1] = {
472 .shared_vref = true, 569 .shared_vref = true,
473 .internal_vref = 2500000, 570 .internal_vref = 2500000,
@@ -482,6 +579,26 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
482 .num_channels = 8, 579 .num_channels = 8,
483 .regmap_type = AD5064_REGMAP_ADI, 580 .regmap_type = AD5064_REGMAP_ADI,
484 }, 581 },
582 [ID_AD5665] = {
583 .shared_vref = true,
584 .channels = ad5669_channels,
585 .num_channels = 4,
586 .regmap_type = AD5064_REGMAP_ADI2
587 },
588 [ID_AD5665R_1V25] = {
589 .shared_vref = true,
590 .internal_vref = 1250000,
591 .channels = ad5669_channels,
592 .num_channels = 4,
593 .regmap_type = AD5064_REGMAP_ADI2
594 },
595 [ID_AD5665R_2V5] = {
596 .shared_vref = true,
597 .internal_vref = 2500000,
598 .channels = ad5669_channels,
599 .num_channels = 4,
600 .regmap_type = AD5064_REGMAP_ADI2
601 },
485 [ID_AD5666_1] = { 602 [ID_AD5666_1] = {
486 .shared_vref = true, 603 .shared_vref = true,
487 .internal_vref = 2500000, 604 .internal_vref = 2500000,
@@ -496,6 +613,26 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
496 .num_channels = 4, 613 .num_channels = 4,
497 .regmap_type = AD5064_REGMAP_ADI, 614 .regmap_type = AD5064_REGMAP_ADI,
498 }, 615 },
616 [ID_AD5667] = {
617 .shared_vref = true,
618 .channels = ad5669_channels,
619 .num_channels = 2,
620 .regmap_type = AD5064_REGMAP_ADI2
621 },
622 [ID_AD5667R_1V25] = {
623 .shared_vref = true,
624 .internal_vref = 1250000,
625 .channels = ad5669_channels,
626 .num_channels = 2,
627 .regmap_type = AD5064_REGMAP_ADI2
628 },
629 [ID_AD5667R_2V5] = {
630 .shared_vref = true,
631 .internal_vref = 2500000,
632 .channels = ad5669_channels,
633 .num_channels = 2,
634 .regmap_type = AD5064_REGMAP_ADI2
635 },
499 [ID_AD5668_1] = { 636 [ID_AD5668_1] = {
500 .shared_vref = true, 637 .shared_vref = true,
501 .internal_vref = 2500000, 638 .internal_vref = 2500000,
@@ -607,6 +744,22 @@ static const char * const ad5064_vref_name(struct ad5064_state *st,
607 return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref]; 744 return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref];
608} 745}
609 746
747static int ad5064_set_config(struct ad5064_state *st, unsigned int val)
748{
749 unsigned int cmd;
750
751 switch (st->chip_info->regmap_type) {
752 case AD5064_REGMAP_ADI2:
753 cmd = AD5064_CMD_CONFIG_V2;
754 break;
755 default:
756 cmd = AD5064_CMD_CONFIG;
757 break;
758 }
759
760 return ad5064_write(st, cmd, 0, val, 0);
761}
762
610static int ad5064_probe(struct device *dev, enum ad5064_type type, 763static int ad5064_probe(struct device *dev, enum ad5064_type type,
611 const char *name, ad5064_write_func write) 764 const char *name, ad5064_write_func write)
612{ 765{
@@ -636,8 +789,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
636 if (!st->chip_info->internal_vref) 789 if (!st->chip_info->internal_vref)
637 return ret; 790 return ret;
638 st->use_internal_vref = true; 791 st->use_internal_vref = true;
639 ret = ad5064_write(st, AD5064_CMD_CONFIG, 0, 792 ret = ad5064_set_config(st, AD5064_CONFIG_INT_VREF_ENABLE);
640 AD5064_CONFIG_INT_VREF_ENABLE, 0);
641 if (ret) { 793 if (ret) {
642 dev_err(dev, "Failed to enable internal vref: %d\n", 794 dev_err(dev, "Failed to enable internal vref: %d\n",
643 ret); 795 ret);
@@ -766,9 +918,19 @@ static int ad5064_i2c_write(struct ad5064_state *st, unsigned int cmd,
766 unsigned int addr, unsigned int val) 918 unsigned int addr, unsigned int val)
767{ 919{
768 struct i2c_client *i2c = to_i2c_client(st->dev); 920 struct i2c_client *i2c = to_i2c_client(st->dev);
921 unsigned int cmd_shift;
769 int ret; 922 int ret;
770 923
771 st->data.i2c[0] = (cmd << 4) | addr; 924 switch (st->chip_info->regmap_type) {
925 case AD5064_REGMAP_ADI2:
926 cmd_shift = 3;
927 break;
928 default:
929 cmd_shift = 4;
930 break;
931 }
932
933 st->data.i2c[0] = (cmd << cmd_shift) | addr;
772 put_unaligned_be16(val, &st->data.i2c[1]); 934 put_unaligned_be16(val, &st->data.i2c[1]);
773 935
774 ret = i2c_master_send(i2c, st->data.i2c, 3); 936 ret = i2c_master_send(i2c, st->data.i2c, 3);
@@ -791,9 +953,23 @@ static int ad5064_i2c_remove(struct i2c_client *i2c)
791} 953}
792 954
793static const struct i2c_device_id ad5064_i2c_ids[] = { 955static const struct i2c_device_id ad5064_i2c_ids[] = {
956 {"ad5625", ID_AD5625 },
957 {"ad5625r-1v25", ID_AD5625R_1V25 },
958 {"ad5625r-2v5", ID_AD5625R_2V5 },
959 {"ad5627", ID_AD5627 },
960 {"ad5627r-1v25", ID_AD5627R_1V25 },
961 {"ad5627r-2v5", ID_AD5627R_2V5 },
794 {"ad5629-1", ID_AD5629_1}, 962 {"ad5629-1", ID_AD5629_1},
795 {"ad5629-2", ID_AD5629_2}, 963 {"ad5629-2", ID_AD5629_2},
796 {"ad5629-3", ID_AD5629_2}, /* similar enough to ad5629-2 */ 964 {"ad5629-3", ID_AD5629_2}, /* similar enough to ad5629-2 */
965 {"ad5645r-1v25", ID_AD5645R_1V25 },
966 {"ad5645r-2v5", ID_AD5645R_2V5 },
967 {"ad5665", ID_AD5665 },
968 {"ad5665r-1v25", ID_AD5665R_1V25 },
969 {"ad5665r-2v5", ID_AD5665R_2V5 },
970 {"ad5667", ID_AD5667 },
971 {"ad5667r-1v25", ID_AD5667R_1V25 },
972 {"ad5667r-2v5", ID_AD5667R_2V5 },
797 {"ad5669-1", ID_AD5669_1}, 973 {"ad5669-1", ID_AD5669_1},
798 {"ad5669-2", ID_AD5669_2}, 974 {"ad5669-2", ID_AD5669_2},
799 {"ad5669-3", ID_AD5669_2}, /* similar enough to ad5669-2 */ 975 {"ad5669-3", ID_AD5669_2}, /* similar enough to ad5669-2 */