diff options
Diffstat (limited to 'drivers/iio/dac/ad5686.c')
| -rw-r--r-- | drivers/iio/dac/ad5686.c | 115 |
1 files changed, 56 insertions, 59 deletions
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 8dd67da0a7da..d9cae9555e5d 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -57,7 +57,7 @@ static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev, { struct ad5686_state *st = iio_priv(indio_dev); - return sprintf(buf, "%d\n", !!(st->pwr_down_mask & + return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3 << (chan->channel * 2)))); } @@ -73,7 +73,7 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, unsigned int val, ref_bit_msk; u8 shift, address = 0; - ret = strtobool(buf, &readin); + ret = kstrtobool(buf, &readin); if (ret) return ret; @@ -184,8 +184,8 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { .shared = IIO_SEPARATE, }, IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum), - IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum), - { }, + IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ad5686_powerdown_mode_enum), + { } }; #define AD5868_CHANNEL(chan, addr, bits, _shift) { \ @@ -206,12 +206,18 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { } #define DECLARE_AD5693_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ } +#define DECLARE_AD5338_CHANNELS(name, bits, _shift) \ +static const struct iio_chan_spec name[] = { \ + AD5868_CHANNEL(0, 1, bits, _shift), \ + AD5868_CHANNEL(1, 8, bits, _shift), \ +} + #define DECLARE_AD5686_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 1, bits, _shift), \ AD5868_CHANNEL(1, 2, bits, _shift), \ AD5868_CHANNEL(2, 4, bits, _shift), \ @@ -219,7 +225,7 @@ static struct iio_chan_spec name[] = { \ } #define DECLARE_AD5676_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ AD5868_CHANNEL(1, 1, bits, _shift), \ AD5868_CHANNEL(2, 2, bits, _shift), \ @@ -231,7 +237,7 @@ static struct iio_chan_spec name[] = { \ } #define DECLARE_AD5679_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ AD5868_CHANNEL(1, 1, bits, _shift), \ AD5868_CHANNEL(2, 2, bits, _shift), \ @@ -252,6 +258,8 @@ static struct iio_chan_spec name[] = { \ DECLARE_AD5693_CHANNELS(ad5310r_channels, 10, 2); DECLARE_AD5693_CHANNELS(ad5311r_channels, 10, 6); +DECLARE_AD5338_CHANNELS(ad5337r_channels, 8, 8); +DECLARE_AD5338_CHANNELS(ad5338r_channels, 10, 6); DECLARE_AD5676_CHANNELS(ad5672_channels, 12, 4); DECLARE_AD5679_CHANNELS(ad5674r_channels, 12, 4); DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0); @@ -276,6 +284,18 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { .num_channels = 1, .regmap_type = AD5693_REGMAP, }, + [ID_AD5337R] = { + .channels = ad5337r_channels, + .int_vref_mv = 2500, + .num_channels = 2, + .regmap_type = AD5686_REGMAP, + }, + [ID_AD5338R] = { + .channels = ad5338r_channels, + .int_vref_mv = 2500, + .num_channels = 2, + .regmap_type = AD5686_REGMAP, + }, [ID_AD5671R] = { .channels = ad5672_channels, .int_vref_mv = 2500, @@ -288,6 +308,12 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { .num_channels = 8, .regmap_type = AD5686_REGMAP, }, + [ID_AD5673R] = { + .channels = ad5674r_channels, + .int_vref_mv = 2500, + .num_channels = 16, + .regmap_type = AD5686_REGMAP, + }, [ID_AD5674R] = { .channels = ad5674r_channels, .int_vref_mv = 2500, @@ -311,6 +337,12 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { .num_channels = 8, .regmap_type = AD5686_REGMAP, }, + [ID_AD5677R] = { + .channels = ad5679r_channels, + .int_vref_mv = 2500, + .num_channels = 16, + .regmap_type = AD5686_REGMAP, + }, [ID_AD5679R] = { .channels = ad5679r_channels, .int_vref_mv = 2500, @@ -423,45 +455,33 @@ int ad5686_probe(struct device *dev, struct ad5686_state *st; struct iio_dev *indio_dev; unsigned int val, ref_bit_msk; + bool has_external_vref; u8 cmd; - int ret, i, voltage_uv = 0; + int ret, i; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); - dev_set_drvdata(dev, indio_dev); st->dev = dev; st->write = write; st->read = read; - st->reg = devm_regulator_get_optional(dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); - if (ret) - return ret; - - ret = regulator_get_voltage(st->reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; - } - st->chip_info = &ad5686_chip_info_tbl[chip_type]; - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - st->vref_mv = st->chip_info->int_vref_mv; + ret = devm_regulator_get_enable_read_voltage(dev, "vcc"); + if (ret < 0 && ret != -ENODEV) + return ret; + + has_external_vref = ret != -ENODEV; + st->vref_mv = has_external_vref ? ret / 1000 : st->chip_info->int_vref_mv; /* Set all the power down mode for all channels to 1K pulldown */ for (i = 0; i < st->chip_info->num_channels; i++) st->pwr_down_mode |= (0x01 << (i * 2)); - indio_dev->dev.parent = dev; indio_dev->name = name; indio_dev->info = &ad5686_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -474,12 +494,12 @@ int ad5686_probe(struct device *dev, case AD5310_REGMAP: cmd = AD5686_CMD_CONTROL_REG; ref_bit_msk = AD5310_REF_BIT_MSK; - st->use_internal_vref = !voltage_uv; + st->use_internal_vref = !has_external_vref; break; case AD5683_REGMAP: cmd = AD5686_CMD_CONTROL_REG; ref_bit_msk = AD5683_REF_BIT_MSK; - st->use_internal_vref = !voltage_uv; + st->use_internal_vref = !has_external_vref; break; case AD5686_REGMAP: cmd = AD5686_CMD_INTERNAL_REFER_SETUP; @@ -488,44 +508,21 @@ int ad5686_probe(struct device *dev, case AD5693_REGMAP: cmd = AD5686_CMD_CONTROL_REG; ref_bit_msk = AD5693_REF_BIT_MSK; - st->use_internal_vref = !voltage_uv; + st->use_internal_vref = !has_external_vref; break; default: - ret = -EINVAL; - goto error_disable_reg; + return -EINVAL; } - val = (voltage_uv | ref_bit_msk); + val = (has_external_vref | ref_bit_msk); ret = st->write(st, cmd, 0, !!val); if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_disable_reg; - - return 0; - -error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); - return ret; -} -EXPORT_SYMBOL_GPL(ad5686_probe); - -int ad5686_remove(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5686_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + return ret; - return 0; + return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_GPL(ad5686_remove); +EXPORT_SYMBOL_NS_GPL(ad5686_probe, "IIO_AD5686"); MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC"); |
