diff options
author | Paul Cercueil <paul.cercueil@analog.com> | 2016-04-05 10:46:19 +0300 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2016-04-10 16:29:06 +0300 |
commit | 56ca9db862bf3d78e279d424b3434d66617c27ae (patch) | |
tree | 17bb8afecced84e47b38c468eae026d306090d95 /drivers/iio/dac/ad5593r.c | |
parent | 5ea9274b8613f87120bfa6b0c0abc384c26cefb9 (diff) | |
download | linux-56ca9db862bf3d78e279d424b3434d66617c27ae.tar.xz |
iio: dac: Add support for the AD5592R/AD5593R ADCs/DACs
This patch adds support for the AD5592R (spi) and AD5593R (i2c)
ADC/DAC/GPIO devices.
Signed-off-by: Paul Cercueil <paul.cercueil@analog.com>
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/dac/ad5593r.c')
-rw-r--r-- | drivers/iio/dac/ad5593r.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c new file mode 100644 index 000000000000..dca158a88f47 --- /dev/null +++ b/drivers/iio/dac/ad5593r.c @@ -0,0 +1,131 @@ +/* + * AD5593R Digital <-> Analog converters driver + * + * Copyright 2015-2016 Analog Devices Inc. + * Author: Paul Cercueil <paul.cercueil@analog.com> + * + * Licensed under the GPL-2. + */ + +#include "ad5592r-base.h" + +#include <linux/bitops.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> + +#define AD5593R_MODE_CONF (0 << 4) +#define AD5593R_MODE_DAC_WRITE (1 << 4) +#define AD5593R_MODE_ADC_READBACK (4 << 4) +#define AD5593R_MODE_DAC_READBACK (5 << 4) +#define AD5593R_MODE_GPIO_READBACK (6 << 4) +#define AD5593R_MODE_REG_READBACK (7 << 4) + +static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value) +{ + struct i2c_client *i2c = to_i2c_client(st->dev); + + return i2c_smbus_write_word_swapped(i2c, + AD5593R_MODE_DAC_WRITE | chan, value); +} + +static int ad5593r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value) +{ + struct i2c_client *i2c = to_i2c_client(st->dev); + s32 val; + + val = i2c_smbus_write_word_swapped(i2c, + AD5593R_MODE_CONF | AD5592R_REG_ADC_SEQ, BIT(chan)); + if (val < 0) + return (int) val; + + val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK); + if (val < 0) + return (int) val; + + *value = (u16) val; + + return 0; +} + +static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value) +{ + struct i2c_client *i2c = to_i2c_client(st->dev); + + return i2c_smbus_write_word_swapped(i2c, + AD5593R_MODE_CONF | reg, value); +} + +static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value) +{ + struct i2c_client *i2c = to_i2c_client(st->dev); + s32 val; + + val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg); + if (val < 0) + return (int) val; + + *value = (u16) val; + + return 0; +} + +static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value) +{ + struct i2c_client *i2c = to_i2c_client(st->dev); + s32 val; + + val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK); + if (val < 0) + return (int) val; + + *value = (u8) val; + + return 0; +} + +static const struct ad5592r_rw_ops ad5593r_rw_ops = { + .write_dac = ad5593r_write_dac, + .read_adc = ad5593r_read_adc, + .reg_write = ad5593r_reg_write, + .reg_read = ad5593r_reg_read, + .gpio_read = ad5593r_gpio_read, +}; + +static int ad5593r_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + return ad5592r_probe(&i2c->dev, id->name, &ad5593r_rw_ops); +} + +static int ad5593r_i2c_remove(struct i2c_client *i2c) +{ + return ad5592r_remove(&i2c->dev); +} + +static const struct i2c_device_id ad5593r_i2c_ids[] = { + { .name = "ad5593r", }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, ad5593r_i2c_ids); + +static const struct of_device_id ad5593r_of_match[] = { + { .compatible = "adi,ad5593r", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ad5593r_of_match); + +static struct i2c_driver ad5593r_driver = { + .driver = { + .name = "ad5593r", + .of_match_table = of_match_ptr(ad5593r_of_match), + }, + .probe = ad5593r_i2c_probe, + .remove = ad5593r_i2c_remove, + .id_table = ad5593r_i2c_ids, +}; +module_i2c_driver(ad5593r_driver); + +MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>"); +MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters"); +MODULE_LICENSE("GPL v2"); |