Skip to content

Commit 6a17a07

Browse files
larsclausenjic23
authored andcommitted
iio:dac:ad5064: Add support for the ad5629r and ad5669r
The ad5629r and ad5669r are the I2C variants of the ad5628 and ad5668. Since the ad5064 driver currently only supports SPI based devices the major part of this patch focuses on adding support for I2C based devices. Adding support for the actual parts boils down to adding entries for them to the device id table. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
1 parent 8ec4cf5 commit 6a17a07

File tree

2 files changed

+173
-35
lines changed

2 files changed

+173
-35
lines changed

drivers/iio/dac/Kconfig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
menu "Digital to analog converters"
55

66
config AD5064
7-
tristate "Analog Devices AD5064/64-1/65/44/45/24/25, AD5628/48/66/68 DAC driver"
8-
depends on SPI
7+
tristate "Analog Devices AD5064 and similar multi-channel DAC driver"
8+
depends on (SPI_MASTER || I2C)
99
help
1010
Say yes here to build support for Analog Devices AD5024, AD5025, AD5044,
11-
AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648, AD5666, AD5668 Digital
12-
to Analog Converter.
11+
AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, AD5648, AD5666, AD5668,
12+
AD5669R Digital to Analog Converter.
1313

1414
To compile this driver as a module, choose M here: the
1515
module will be called ad5064.

drivers/iio/dac/ad5064.c

Lines changed: 169 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648,
3-
* AD5666, AD5668 Digital to analog converters driver
2+
* AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R,
3+
* AD5648, AD5666, AD5668, AD5669R Digital to analog converters driver
44
*
55
* Copyright 2011 Analog Devices Inc.
66
*
@@ -12,9 +12,11 @@
1212
#include <linux/module.h>
1313
#include <linux/kernel.h>
1414
#include <linux/spi/spi.h>
15+
#include <linux/i2c.h>
1516
#include <linux/slab.h>
1617
#include <linux/sysfs.h>
1718
#include <linux/regulator/consumer.h>
19+
#include <asm/unaligned.h>
1820

1921
#include <linux/iio/iio.h>
2022
#include <linux/iio/sysfs.h>
@@ -62,33 +64,44 @@ struct ad5064_chip_info {
6264
unsigned int num_channels;
6365
};
6466

67+
struct ad5064_state;
68+
69+
typedef int (*ad5064_write_func)(struct ad5064_state *st, unsigned int cmd,
70+
unsigned int addr, unsigned int val);
71+
6572
/**
6673
* struct ad5064_state - driver instance specific data
67-
* @spi: spi_device
74+
* @dev: the device for this driver instance
6875
* @chip_info: chip model specific constants, available modes etc
6976
* @vref_reg: vref supply regulators
7077
* @pwr_down: whether channel is powered down
7178
* @pwr_down_mode: channel's current power down mode
7279
* @dac_cache: current DAC raw value (chip does not support readback)
7380
* @use_internal_vref: set to true if the internal reference voltage should be
7481
* used.
75-
* @data: spi transfer buffers
82+
* @write: register write callback
83+
* @data: i2c/spi transfer buffers
7684
*/
7785

7886
struct ad5064_state {
79-
struct spi_device *spi;
87+
struct device *dev;
8088
const struct ad5064_chip_info *chip_info;
8189
struct regulator_bulk_data vref_reg[AD5064_MAX_VREFS];
8290
bool pwr_down[AD5064_MAX_DAC_CHANNELS];
8391
u8 pwr_down_mode[AD5064_MAX_DAC_CHANNELS];
8492
unsigned int dac_cache[AD5064_MAX_DAC_CHANNELS];
8593
bool use_internal_vref;
8694

95+
ad5064_write_func write;
96+
8797
/*
8898
* DMA (thus cache coherency maintenance) requires the
8999
* transfer buffers to live in their own cache lines.
90100
*/
91-
__be32 data ____cacheline_aligned;
101+
union {
102+
u8 i2c[3];
103+
__be32 spi;
104+
} data ____cacheline_aligned;
92105
};
93106

94107
enum ad5064_type {
@@ -109,14 +122,31 @@ enum ad5064_type {
109122
ID_AD5668_2,
110123
};
111124

125+
static int ad5064_i2c_write(struct ad5064_state *st, unsigned int cmd,
126+
unsigned int addr, unsigned int val)
127+
{
128+
struct i2c_client *i2c = to_i2c_client(st->dev);
129+
130+
st->data.i2c[0] = (cmd << 4) | addr;
131+
put_unaligned_be16(val, &st->data.i2c[1]);
132+
return i2c_master_send(i2c, st->data.i2c, 3);
133+
}
134+
112135
static int ad5064_spi_write(struct ad5064_state *st, unsigned int cmd,
136+
unsigned int addr, unsigned int val)
137+
{
138+
struct spi_device *spi = to_spi_device(st->dev);
139+
140+
st->data.spi = cpu_to_be32(AD5064_CMD(cmd) | AD5064_ADDR(addr) | val);
141+
return spi_write(spi, &st->data.spi, sizeof(st->data.spi));
142+
}
143+
144+
static int ad5064_write(struct ad5064_state *st, unsigned int cmd,
113145
unsigned int addr, unsigned int val, unsigned int shift)
114146
{
115147
val <<= shift;
116148

117-
st->data = cpu_to_be32(AD5064_CMD(cmd) | AD5064_ADDR(addr) | val);
118-
119-
return spi_write(st->spi, &st->data, sizeof(st->data));
149+
return st->write(st, cmd, addr, val);
120150
}
121151

122152
static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
@@ -130,7 +160,7 @@ static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
130160
if (st->pwr_down[channel])
131161
val |= st->pwr_down_mode[channel] << 8;
132162

133-
ret = ad5064_spi_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0);
163+
ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0);
134164

135165
return ret;
136166
}
@@ -251,7 +281,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev,
251281
return -EINVAL;
252282

253283
mutex_lock(&indio_dev->mlock);
254-
ret = ad5064_spi_write(st, AD5064_CMD_WRITE_INPUT_N_UPDATE_N,
284+
ret = ad5064_write(st, AD5064_CMD_WRITE_INPUT_N_UPDATE_N,
255285
chan->address, val, chan->scan_type.shift);
256286
if (ret == 0)
257287
st->dac_cache[chan->channel] = val;
@@ -413,9 +443,9 @@ static const char * const ad5064_vref_name(struct ad5064_state *st,
413443
return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref];
414444
}
415445

416-
static int __devinit ad5064_probe(struct spi_device *spi)
446+
static int __devinit ad5064_probe(struct device *dev, enum ad5064_type type,
447+
const char *name, ad5064_write_func write)
417448
{
418-
enum ad5064_type type = spi_get_device_id(spi)->driver_data;
419449
struct iio_dev *indio_dev;
420450
struct ad5064_state *st;
421451
unsigned int i;
@@ -426,24 +456,25 @@ static int __devinit ad5064_probe(struct spi_device *spi)
426456
return -ENOMEM;
427457

428458
st = iio_priv(indio_dev);
429-
spi_set_drvdata(spi, indio_dev);
459+
dev_set_drvdata(dev, indio_dev);
430460

431461
st->chip_info = &ad5064_chip_info_tbl[type];
432-
st->spi = spi;
462+
st->dev = dev;
463+
st->write = write;
433464

434465
for (i = 0; i < ad5064_num_vref(st); ++i)
435466
st->vref_reg[i].supply = ad5064_vref_name(st, i);
436467

437-
ret = regulator_bulk_get(&st->spi->dev, ad5064_num_vref(st),
468+
ret = regulator_bulk_get(dev, ad5064_num_vref(st),
438469
st->vref_reg);
439470
if (ret) {
440471
if (!st->chip_info->internal_vref)
441472
goto error_free;
442473
st->use_internal_vref = true;
443-
ret = ad5064_spi_write(st, AD5064_CMD_CONFIG, 0,
474+
ret = ad5064_write(st, AD5064_CMD_CONFIG, 0,
444475
AD5064_CONFIG_INT_VREF_ENABLE, 0);
445476
if (ret) {
446-
dev_err(&spi->dev, "Failed to enable internal vref: %d\n",
477+
dev_err(dev, "Failed to enable internal vref: %d\n",
447478
ret);
448479
goto error_free;
449480
}
@@ -458,8 +489,8 @@ static int __devinit ad5064_probe(struct spi_device *spi)
458489
st->dac_cache[i] = 0x8000;
459490
}
460491

461-
indio_dev->dev.parent = &spi->dev;
462-
indio_dev->name = spi_get_device_id(spi)->name;
492+
indio_dev->dev.parent = dev;
493+
indio_dev->name = name;
463494
indio_dev->info = &ad5064_info;
464495
indio_dev->modes = INDIO_DIRECT_MODE;
465496
indio_dev->channels = st->chip_info->channels;
@@ -483,10 +514,9 @@ static int __devinit ad5064_probe(struct spi_device *spi)
483514
return ret;
484515
}
485516

486-
487-
static int __devexit ad5064_remove(struct spi_device *spi)
517+
static int __devexit ad5064_remove(struct device *dev)
488518
{
489-
struct iio_dev *indio_dev = spi_get_drvdata(spi);
519+
struct iio_dev *indio_dev = dev_get_drvdata(dev);
490520
struct ad5064_state *st = iio_priv(indio_dev);
491521

492522
iio_device_unregister(indio_dev);
@@ -501,7 +531,22 @@ static int __devexit ad5064_remove(struct spi_device *spi)
501531
return 0;
502532
}
503533

504-
static const struct spi_device_id ad5064_id[] = {
534+
#if IS_ENABLED(CONFIG_SPI_MASTER)
535+
536+
static int __devinit ad5064_spi_probe(struct spi_device *spi)
537+
{
538+
const struct spi_device_id *id = spi_get_device_id(spi);
539+
540+
return ad5064_probe(&spi->dev, id->driver_data, id->name,
541+
ad5064_spi_write);
542+
}
543+
544+
static int __devexit ad5064_spi_remove(struct spi_device *spi)
545+
{
546+
return ad5064_remove(&spi->dev);
547+
}
548+
549+
static const struct spi_device_id ad5064_spi_ids[] = {
505550
{"ad5024", ID_AD5024},
506551
{"ad5025", ID_AD5025},
507552
{"ad5044", ID_AD5044},
@@ -520,19 +565,112 @@ static const struct spi_device_id ad5064_id[] = {
520565
{"ad5668-3", ID_AD5668_2}, /* similar enough to ad5668-2 */
521566
{}
522567
};
523-
MODULE_DEVICE_TABLE(spi, ad5064_id);
568+
MODULE_DEVICE_TABLE(spi, ad5064_spi_ids);
524569

525-
static struct spi_driver ad5064_driver = {
570+
static struct spi_driver ad5064_spi_driver = {
526571
.driver = {
527572
.name = "ad5064",
528573
.owner = THIS_MODULE,
529574
},
530-
.probe = ad5064_probe,
531-
.remove = __devexit_p(ad5064_remove),
532-
.id_table = ad5064_id,
575+
.probe = ad5064_spi_probe,
576+
.remove = __devexit_p(ad5064_spi_remove),
577+
.id_table = ad5064_spi_ids,
533578
};
534-
module_spi_driver(ad5064_driver);
579+
580+
static int __init ad5064_spi_register_driver(void)
581+
{
582+
return spi_register_driver(&ad5064_spi_driver);
583+
}
584+
585+
static void __exit ad5064_spi_unregister_driver(void)
586+
{
587+
spi_unregister_driver(&ad5064_spi_driver);
588+
}
589+
590+
#else
591+
592+
static inline int ad5064_spi_register_driver(void) { return 0; }
593+
static inline void ad5064_spi_unregister_driver(void) { }
594+
595+
#endif
596+
597+
#if IS_ENABLED(CONFIG_I2C)
598+
599+
static int __devinit ad5064_i2c_probe(struct i2c_client *i2c,
600+
const struct i2c_device_id *id)
601+
{
602+
return ad5064_probe(&i2c->dev, id->driver_data, id->name,
603+
ad5064_i2c_write);
604+
}
605+
606+
static int __devexit ad5064_i2c_remove(struct i2c_client *i2c)
607+
{
608+
return ad5064_remove(&i2c->dev);
609+
}
610+
611+
static const struct i2c_device_id ad5064_i2c_ids[] = {
612+
{"ad5629-1", ID_AD5628_1},
613+
{"ad5629-2", ID_AD5628_2},
614+
{"ad5629-3", ID_AD5628_2}, /* similar enough to ad5629-2 */
615+
{"ad5669-1", ID_AD5668_1},
616+
{"ad5669-2", ID_AD5668_2},
617+
{"ad5669-3", ID_AD5668_2}, /* similar enough to ad5669-2 */
618+
{}
619+
};
620+
MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids);
621+
622+
static struct i2c_driver ad5064_i2c_driver = {
623+
.driver = {
624+
.name = "ad5064",
625+
.owner = THIS_MODULE,
626+
},
627+
.probe = ad5064_i2c_probe,
628+
.remove = __devexit_p(ad5064_i2c_remove),
629+
.id_table = ad5064_i2c_ids,
630+
};
631+
632+
static int __init ad5064_i2c_register_driver(void)
633+
{
634+
return i2c_add_driver(&ad5064_i2c_driver);
635+
}
636+
637+
static void __exit ad5064_i2c_unregister_driver(void)
638+
{
639+
i2c_del_driver(&ad5064_i2c_driver);
640+
}
641+
642+
#else
643+
644+
static inline int ad5064_i2c_register_driver(void) { return 0; }
645+
static inline void ad5064_i2c_unregister_driver(void) { }
646+
647+
#endif
648+
649+
static int __init ad5064_init(void)
650+
{
651+
int ret;
652+
653+
ret = ad5064_spi_register_driver();
654+
if (ret)
655+
return ret;
656+
657+
ret = ad5064_i2c_register_driver();
658+
if (ret) {
659+
ad5064_spi_unregister_driver();
660+
return ret;
661+
}
662+
663+
return 0;
664+
}
665+
module_init(ad5064_init);
666+
667+
static void __exit ad5064_exit(void)
668+
{
669+
ad5064_i2c_unregister_driver();
670+
ad5064_spi_unregister_driver();
671+
}
672+
module_exit(ad5064_exit);
535673

536674
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
537-
MODULE_DESCRIPTION("Analog Devices AD5024/25/44/45/64/64-1/65, AD5628/48/66/68 DAC");
675+
MODULE_DESCRIPTION("Analog Devices AD5024 and similar multi-channel DACs");
538676
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)