aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/dac/ad5064.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/dac/ad5064.c')
-rw-r--r--drivers/iio/dac/ad5064.c192
1 files changed, 184 insertions, 8 deletions
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 */