diff options
Diffstat (limited to 'drivers/iio/dac')
-rw-r--r-- | drivers/iio/dac/Kconfig | 44 | ||||
-rw-r--r-- | drivers/iio/dac/Makefile | 1 | ||||
-rw-r--r-- | drivers/iio/dac/ad5064.c | 21 | ||||
-rw-r--r-- | drivers/iio/dac/ad5360.c | 15 | ||||
-rw-r--r-- | drivers/iio/dac/ad5380.c | 18 | ||||
-rw-r--r-- | drivers/iio/dac/ad5421.c | 19 | ||||
-rw-r--r-- | drivers/iio/dac/ad5446.c | 19 | ||||
-rw-r--r-- | drivers/iio/dac/ad5449.c | 15 | ||||
-rw-r--r-- | drivers/iio/dac/ad5504.c | 31 | ||||
-rw-r--r-- | drivers/iio/dac/ad5624r_spi.c | 22 | ||||
-rw-r--r-- | drivers/iio/dac/ad5686.c | 17 | ||||
-rw-r--r-- | drivers/iio/dac/ad5755.c | 14 | ||||
-rw-r--r-- | drivers/iio/dac/ad5764.c | 20 | ||||
-rw-r--r-- | drivers/iio/dac/ad5791.c | 35 | ||||
-rw-r--r-- | drivers/iio/dac/ad7303.c | 31 | ||||
-rw-r--r-- | drivers/iio/dac/max517.c | 17 | ||||
-rw-r--r-- | drivers/iio/dac/mcp4725.c | 185 |
17 files changed, 257 insertions, 267 deletions
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index c9c33ce32d3..3c6a78a75b7 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -1,6 +1,8 @@ # # DAC drivers # +# When adding new entries keep the list in alphabetical order + menu "Digital to analog converters" config AD5064 @@ -15,7 +17,7 @@ config AD5064 module will be called ad5064. config AD5360 - tristate "Analog Devices Analog Devices AD5360/61/62/63/70/71/73 DAC driver" + tristate "Analog Devices AD5360/61/62/63/70/71/73 DAC driver" depends on SPI help Say yes here to build support for Analog Devices AD5360, AD5361, @@ -48,13 +50,6 @@ config AD5421 To compile this driver as module choose M here: the module will be called ad5421. -config AD5624R_SPI - tristate "Analog Devices AD5624/44/64R DAC spi driver" - depends on SPI - help - Say yes here to build support for Analog Devices AD5624R, AD5644R and - AD5664R converters (DAC). This driver uses the common SPI interface. - config AD5446 tristate "Analog Devices AD5446 and similar single channel DACs driver" depends on (SPI_MASTER && I2C!=m) || I2C @@ -68,7 +63,7 @@ config AD5446 module will be called ad5446. config AD5449 - tristate "Analog Device AD5449 and similar DACs driver" + tristate "Analog Devices AD5449 and similar DACs driver" depends on SPI_MASTER help Say yes here to build support for Analog Devices AD5415, AD5426, AD5429, @@ -87,6 +82,24 @@ config AD5504 To compile this driver as a module, choose M here: the module will be called ad5504. +config AD5624R_SPI + tristate "Analog Devices AD5624/44/64R DAC spi driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD5624R, AD5644R and + AD5664R converters (DAC). This driver uses the common SPI interface. + +config AD5686 + tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD5686R, AD5685R, + AD5684R, AD5791 Voltage Output Digital to + Analog Converter. + + To compile this driver as a module, choose M here: the + module will be called ad5686. + config AD5755 tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver" depends on SPI_MASTER @@ -119,19 +132,8 @@ config AD5791 To compile this driver as a module, choose M here: the module will be called ad5791. -config AD5686 - tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver" - depends on SPI - help - Say yes here to build support for Analog Devices AD5686R, AD5685R, - AD5684R, AD5791 Voltage Output Digital to - Analog Converter. - - To compile this driver as a module, choose M here: the - module will be called ad5686. - config AD7303 - tristate "Analog Devices Analog Devices AD7303 DAC driver" + tristate "Analog Devices AD7303 DAC driver" depends on SPI help Say yes here to build support for Analog Devices AD7303 Digital to Analog diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index c8d7ab6bff0..bb84ad64463 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -2,6 +2,7 @@ # Makefile for industrial I/O DAC drivers # +# When adding new entries keep the list in alphabetical order obj-$(CONFIG_AD5360) += ad5360.o obj-$(CONFIG_AD5380) += ad5380.o obj-$(CONFIG_AD5421) += ad5421.o diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index aa26d50ab63..a3a52be4852 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -442,7 +442,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, unsigned int i; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -456,23 +456,23 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, for (i = 0; i < ad5064_num_vref(st); ++i) st->vref_reg[i].supply = ad5064_vref_name(st, i); - ret = regulator_bulk_get(dev, ad5064_num_vref(st), + ret = devm_regulator_bulk_get(dev, ad5064_num_vref(st), st->vref_reg); if (ret) { if (!st->chip_info->internal_vref) - goto error_free; + return ret; st->use_internal_vref = true; ret = ad5064_write(st, AD5064_CMD_CONFIG, 0, AD5064_CONFIG_INT_VREF_ENABLE, 0); if (ret) { dev_err(dev, "Failed to enable internal vref: %d\n", ret); - goto error_free; + return ret; } } else { ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg); if (ret) - goto error_free_reg; + return ret; } indio_dev->dev.parent = dev; @@ -498,11 +498,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, error_disable_reg: if (!st->use_internal_vref) regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg); -error_free_reg: - if (!st->use_internal_vref) - regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); -error_free: - iio_device_free(indio_dev); return ret; } @@ -514,12 +509,8 @@ static int ad5064_remove(struct device *dev) iio_device_unregister(indio_dev); - if (!st->use_internal_vref) { + if (!st->use_internal_vref) regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg); - regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); - } - - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index 80923af424f..d2da71ece74 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -459,7 +459,7 @@ static int ad5360_probe(struct spi_device *spi) unsigned int i; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -480,13 +480,13 @@ static int ad5360_probe(struct spi_device *spi) ret = ad5360_alloc_channels(indio_dev); if (ret) { dev_err(&spi->dev, "Failed to allocate channel spec: %d\n", ret); - goto error_free; + return ret; } for (i = 0; i < st->chip_info->num_vrefs; ++i) st->vref_reg[i].supply = ad5360_vref_name[i]; - ret = regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs, + ret = devm_regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs, st->vref_reg); if (ret) { dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret); @@ -496,7 +496,7 @@ static int ad5360_probe(struct spi_device *spi) ret = regulator_bulk_enable(st->chip_info->num_vrefs, st->vref_reg); if (ret) { dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret); - goto error_free_reg; + goto error_free_channels; } ret = iio_device_register(indio_dev); @@ -509,12 +509,8 @@ static int ad5360_probe(struct spi_device *spi) error_disable_reg: regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg); -error_free_reg: - regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg); error_free_channels: kfree(indio_dev->channels); -error_free: - iio_device_free(indio_dev); return ret; } @@ -529,9 +525,6 @@ static int ad5360_remove(struct spi_device *spi) kfree(indio_dev->channels); regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg); - regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg); - - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index bf2db02215c..1c44ae3920e 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -369,11 +369,10 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap, unsigned int ctrl = 0; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (indio_dev == NULL) { dev_err(dev, "Failed to allocate iio device\n"); - ret = -ENOMEM; - goto error_out; + return -ENOMEM; } st = iio_priv(indio_dev); @@ -391,13 +390,13 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap, ret = ad5380_alloc_channels(indio_dev); if (ret) { dev_err(dev, "Failed to allocate channel spec: %d\n", ret); - goto error_free; + return ret; } if (st->chip_info->int_vref == 2500000) ctrl |= AD5380_CTRL_INT_VREF_2V5; - st->vref_reg = regulator_get(dev, "vref"); + st->vref_reg = devm_regulator_get(dev, "vref"); if (!IS_ERR(st->vref_reg)) { ret = regulator_enable(st->vref_reg); if (ret) { @@ -434,13 +433,7 @@ error_disable_reg: if (!IS_ERR(st->vref_reg)) regulator_disable(st->vref_reg); error_free_reg: - if (!IS_ERR(st->vref_reg)) - regulator_put(st->vref_reg); - kfree(indio_dev->channels); -error_free: - iio_device_free(indio_dev); -error_out: return ret; } @@ -456,11 +449,8 @@ static int ad5380_remove(struct device *dev) if (!IS_ERR(st->vref_reg)) { regulator_disable(st->vref_reg); - regulator_put(st->vref_reg); } - iio_device_free(indio_dev); - return 0; } diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 98f24407c3c..1f78b14abb7 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -451,7 +451,7 @@ static int ad5421_probe(struct spi_device *spi) struct ad5421_state *st; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -484,31 +484,23 @@ static int ad5421_probe(struct spi_device *spi) ad5421_update_ctrl(indio_dev, 0, 0); if (spi->irq) { - ret = request_threaded_irq(spi->irq, + ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, ad5421_fault_handler, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "ad5421 fault", indio_dev); if (ret) - goto error_free; + return ret; } ret = iio_device_register(indio_dev); if (ret) { dev_err(&spi->dev, "Failed to register iio device: %d\n", ret); - goto error_free_irq; + return ret; } return 0; - -error_free_irq: - if (spi->irq) - free_irq(spi->irq, indio_dev); -error_free: - iio_device_free(indio_dev); - - return ret; } static int ad5421_remove(struct spi_device *spi) @@ -516,9 +508,6 @@ static int ad5421_remove(struct spi_device *spi) struct iio_dev *indio_dev = spi_get_drvdata(spi); iio_device_unregister(indio_dev); - if (spi->irq) - free_irq(spi->irq, indio_dev); - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index cae8f6056ac..96e9ed4c2d0 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -220,11 +220,11 @@ static int ad5446_probe(struct device *dev, const char *name, struct regulator *reg; int ret, voltage_uv = 0; - reg = regulator_get(dev, "vcc"); + reg = devm_regulator_get(dev, "vcc"); if (!IS_ERR(reg)) { ret = regulator_enable(reg); if (ret) - goto error_put_reg; + return ret; ret = regulator_get_voltage(reg); if (ret < 0) @@ -233,7 +233,7 @@ static int ad5446_probe(struct device *dev, const char *name, voltage_uv = ret; } - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -264,19 +264,13 @@ static int ad5446_probe(struct device *dev, const char *name, ret = iio_device_register(indio_dev); if (ret) - goto error_free_device; + goto error_disable_reg; return 0; -error_free_device: - iio_device_free(indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); -error_put_reg: - if (!IS_ERR(reg)) - regulator_put(reg); - return ret; } @@ -286,11 +280,8 @@ static int ad5446_remove(struct device *dev) struct ad5446_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { + if (!IS_ERR(st->reg)) regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index ba1c914b039..fff7d0762c0 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -275,7 +275,7 @@ static int ad5449_spi_probe(struct spi_device *spi) unsigned int i; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -288,14 +288,14 @@ static int ad5449_spi_probe(struct spi_device *spi) for (i = 0; i < st->chip_info->num_channels; ++i) st->vref_reg[i].supply = ad5449_vref_name(st, i); - ret = regulator_bulk_get(&spi->dev, st->chip_info->num_channels, + ret = devm_regulator_bulk_get(&spi->dev, st->chip_info->num_channels, st->vref_reg); if (ret) - goto error_free; + return ret; ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg); if (ret) - goto error_free_reg; + return ret; indio_dev->dev.parent = &spi->dev; indio_dev->name = id->name; @@ -325,10 +325,6 @@ static int ad5449_spi_probe(struct spi_device *spi) error_disable_reg: regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg); -error_free_reg: - regulator_bulk_free(st->chip_info->num_channels, st->vref_reg); -error_free: - iio_device_free(indio_dev); return ret; } @@ -341,9 +337,6 @@ static int ad5449_spi_remove(struct spi_device *spi) iio_device_unregister(indio_dev); regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg); - regulator_bulk_free(st->chip_info->num_channels, st->vref_reg); - - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index 139206e84cb..caffb16bc05 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -281,16 +281,14 @@ static int ad5504_probe(struct spi_device *spi) struct regulator *reg; int ret, voltage_uv = 0; - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - reg = regulator_get(&spi->dev, "vcc"); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + reg = devm_regulator_get(&spi->dev, "vcc"); if (!IS_ERR(reg)) { ret = regulator_enable(reg); if (ret) - goto error_put_reg; + return ret; ret = regulator_get_voltage(reg); if (ret < 0) @@ -321,7 +319,7 @@ static int ad5504_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; if (spi->irq) { - ret = request_threaded_irq(spi->irq, + ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, &ad5504_event_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, @@ -333,22 +331,14 @@ static int ad5504_probe(struct spi_device *spi) ret = iio_device_register(indio_dev); if (ret) - goto error_free_irq; + goto error_disable_reg; return 0; -error_free_irq: - if (spi->irq) - free_irq(spi->irq, indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); -error_put_reg: - if (!IS_ERR(reg)) - regulator_put(reg); - iio_device_free(indio_dev); -error_ret: return ret; } @@ -358,14 +348,9 @@ static int ad5504_remove(struct spi_device *spi) struct ad5504_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - if (spi->irq) - free_irq(spi->irq, indio_dev); - if (!IS_ERR(st->reg)) { + if (!IS_ERR(st->reg)) regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index bb298aaff32..714af757cd5 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -226,17 +226,15 @@ static int ad5624r_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, voltage_uv = 0; - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; st = iio_priv(indio_dev); - st->reg = regulator_get(&spi->dev, "vcc"); + st->reg = devm_regulator_get(&spi->dev, "vcc"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); if (ret) - goto error_put_reg; + return ret; ret = regulator_get_voltage(st->reg); if (ret < 0) @@ -277,11 +275,6 @@ static int ad5624r_probe(struct spi_device *spi) error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); -error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); - iio_device_free(indio_dev); -error_ret: return ret; } @@ -292,11 +285,8 @@ static int ad5624r_remove(struct spi_device *spi) struct ad5624r_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { + if (!IS_ERR(st->reg)) regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 06439b1af9b..57825ead7db 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -314,18 +314,18 @@ static int ad5686_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, regdone = 0, voltage_uv = 0; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); - st->reg = regulator_get(&spi->dev, "vcc"); + st->reg = devm_regulator_get(&spi->dev, "vcc"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); if (ret) - goto error_put_reg; + return ret; ret = regulator_get_voltage(st->reg); if (ret < 0) @@ -369,12 +369,6 @@ static int ad5686_probe(struct spi_device *spi) error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); -error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); - - iio_device_free(indio_dev); - return ret; } @@ -384,11 +378,8 @@ static int ad5686_remove(struct spi_device *spi) struct ad5686_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { + if (!IS_ERR(st->reg)) regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 12bb315e55f..36a4361aece 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -565,7 +565,7 @@ static int ad5755_probe(struct spi_device *spi) struct ad5755_state *st; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -589,24 +589,19 @@ static int ad5755_probe(struct spi_device *spi) ret = ad5755_init_channels(indio_dev, pdata); if (ret) - goto error_free; + return ret; ret = ad5755_setup_pdata(indio_dev, pdata); if (ret) - goto error_free; + return ret; ret = iio_device_register(indio_dev); if (ret) { dev_err(&spi->dev, "Failed to register iio device: %d\n", ret); - goto error_free; + return ret; } return 0; - -error_free: - iio_device_free(indio_dev); - - return ret; } static int ad5755_remove(struct spi_device *spi) @@ -614,7 +609,6 @@ static int ad5755_remove(struct spi_device *spi) struct iio_dev *indio_dev = spi_get_drvdata(spi); iio_device_unregister(indio_dev); - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c index 7a53f7d70da..df7e028d9db 100644 --- a/drivers/iio/dac/ad5764.c +++ b/drivers/iio/dac/ad5764.c @@ -275,7 +275,7 @@ static int ad5764_probe(struct spi_device *spi) struct ad5764_state *st; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -298,12 +298,12 @@ static int ad5764_probe(struct spi_device *spi) st->vref_reg[0].supply = "vrefAB"; st->vref_reg[1].supply = "vrefCD"; - ret = regulator_bulk_get(&st->spi->dev, + ret = devm_regulator_bulk_get(&st->spi->dev, ARRAY_SIZE(st->vref_reg), st->vref_reg); if (ret) { dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret); - goto error_free; + return ret; } ret = regulator_bulk_enable(ARRAY_SIZE(st->vref_reg), @@ -311,7 +311,7 @@ static int ad5764_probe(struct spi_device *spi) if (ret) { dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret); - goto error_free_reg; + return ret; } } @@ -326,12 +326,6 @@ static int ad5764_probe(struct spi_device *spi) error_disable_reg: if (st->chip_info->int_vref == 0) regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg); -error_free_reg: - if (st->chip_info->int_vref == 0) - regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg); -error_free: - iio_device_free(indio_dev); - return ret; } @@ -342,12 +336,8 @@ static int ad5764_remove(struct spi_device *spi) iio_device_unregister(indio_dev); - if (st->chip_info->int_vref == 0) { + if (st->chip_info->int_vref == 0) regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg); - regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg); - } - - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 97c1e5d780d..ce745896330 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -349,17 +349,15 @@ static int ad5791_probe(struct spi_device *spi) struct ad5791_state *st; int ret, pos_voltage_uv = 0, neg_voltage_uv = 0; - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; st = iio_priv(indio_dev); - st->reg_vdd = regulator_get(&spi->dev, "vdd"); + st->reg_vdd = devm_regulator_get(&spi->dev, "vdd"); if (!IS_ERR(st->reg_vdd)) { ret = regulator_enable(st->reg_vdd); if (ret) - goto error_put_reg_pos; + return ret; ret = regulator_get_voltage(st->reg_vdd); if (ret < 0) @@ -368,11 +366,11 @@ static int ad5791_probe(struct spi_device *spi) pos_voltage_uv = ret; } - st->reg_vss = regulator_get(&spi->dev, "vss"); + st->reg_vss = devm_regulator_get(&spi->dev, "vss"); if (!IS_ERR(st->reg_vss)) { ret = regulator_enable(st->reg_vss); if (ret) - goto error_put_reg_neg; + goto error_disable_reg_pos; ret = regulator_get_voltage(st->reg_vss); if (ret < 0) @@ -428,19 +426,9 @@ static int ad5791_probe(struct spi_device *spi) error_disable_reg_neg: if (!IS_ERR(st->reg_vss)) regulator_disable(st->reg_vss); -error_put_reg_neg: - if (!IS_ERR(st->reg_vss)) - regulator_put(st->reg_vss); - error_disable_reg_pos: if (!IS_ERR(st->reg_vdd)) regulator_disable(st->reg_vdd); -error_put_reg_pos: - if (!IS_ERR(st->reg_vdd)) - regulator_put(st->reg_vdd); - iio_device_free(indio_dev); -error_ret: - return ret; } @@ -450,16 +438,11 @@ static int ad5791_remove(struct spi_device *spi) struct ad5791_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg_vdd)) { + if (!IS_ERR(st->reg_vdd)) regulator_disable(st->reg_vdd); - regulator_put(st->reg_vdd); - } - if (!IS_ERR(st->reg_vss)) { + if (!IS_ERR(st->reg_vss)) regulator_disable(st->reg_vss); - regulator_put(st->reg_vss); - } - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c index d546f50f925..ed2d276477b 100644 --- a/drivers/iio/dac/ad7303.c +++ b/drivers/iio/dac/ad7303.c @@ -203,7 +203,7 @@ static int ad7303_probe(struct spi_device *spi) bool ext_ref; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -212,15 +212,13 @@ static int ad7303_probe(struct spi_device *spi) st->spi = spi; - st->vdd_reg = regulator_get(&spi->dev, "Vdd"); - if (IS_ERR(st->vdd_reg)) { - ret = PTR_ERR(st->vdd_reg); - goto err_free; - } + st->vdd_reg = devm_regulator_get(&spi->dev, "Vdd"); + if (IS_ERR(st->vdd_reg)) + return PTR_ERR(st->vdd_reg); ret = regulator_enable(st->vdd_reg); if (ret) - goto err_put_vdd_reg; + return ret; if (spi->dev.of_node) { ext_ref = of_property_read_bool(spi->dev.of_node, @@ -234,7 +232,7 @@ static int ad7303_probe(struct spi_device *spi) } if (ext_ref) { - st->vref_reg = regulator_get(&spi->dev, "REF"); + st->vref_reg = devm_regulator_get(&spi->dev, "REF"); if (IS_ERR(st->vref_reg)) { ret = PTR_ERR(st->vref_reg); goto err_disable_vdd_reg; @@ -242,7 +240,7 @@ static int ad7303_probe(struct spi_device *spi) ret = regulator_enable(st->vref_reg); if (ret) - goto err_put_vref_reg; + goto err_disable_vdd_reg; st->config |= AD7303_CFG_EXTERNAL_VREF; } @@ -263,16 +261,8 @@ static int ad7303_probe(struct spi_device *spi) err_disable_vref_reg: if (st->vref_reg) regulator_disable(st->vref_reg); -err_put_vref_reg: - if (st->vref_reg) - regulator_put(st->vref_reg); err_disable_vdd_reg: regulator_disable(st->vdd_reg); -err_put_vdd_reg: - regulator_put(st->vdd_reg); -err_free: - iio_device_free(indio_dev); - return ret; } @@ -283,14 +273,9 @@ static int ad7303_remove(struct spi_device *spi) iio_device_unregister(indio_dev); - if (st->vref_reg) { + if (st->vref_reg) regulator_disable(st->vref_reg); - regulator_put(st->vref_reg); - } regulator_disable(st->vdd_reg); - regulator_put(st->vdd_reg); - - iio_device_free(indio_dev); return 0; } diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index ebfaa415624..83adcbf1a20 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -164,11 +164,9 @@ static int max517_probe(struct i2c_client *client, struct max517_platform_data *platform_data = client->dev.platform_data; int err; - indio_dev = iio_device_alloc(sizeof(*data)); - if (indio_dev == NULL) { - err = -ENOMEM; - goto exit; - } + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; @@ -198,23 +196,16 @@ static int max517_probe(struct i2c_client *client, err = iio_device_register(indio_dev); if (err) - goto exit_free_device; + return err; dev_info(&client->dev, "DAC registered\n"); return 0; - -exit_free_device: - iio_device_free(indio_dev); -exit: - return err; } static int max517_remove(struct i2c_client *client) { iio_device_unregister(i2c_get_clientdata(client)); - iio_device_free(i2c_get_clientdata(client)); - return 0; } diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index a612ec766d9..1397b6e0e41 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -12,14 +12,13 @@ * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC) * (7-bit I2C slave address 0x60, the three LSBs can be configured in * hardware) - * - * writing the DAC value to EEPROM is not supported */ #include <linux/module.h> #include <linux/init.h> #include <linux/i2c.h> #include <linux/err.h> +#include <linux/delay.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -32,38 +31,176 @@ struct mcp4725_data { struct i2c_client *client; u16 vref_mv; u16 dac_value; + bool powerdown; + unsigned powerdown_mode; }; -#ifdef CONFIG_PM_SLEEP static int mcp4725_suspend(struct device *dev) { + struct mcp4725_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); u8 outbuf[2]; - outbuf[0] = 0x3 << 4; /* power-down bits, 500 kOhm resistor */ + outbuf[0] = (data->powerdown_mode + 1) << 4; outbuf[1] = 0; + data->powerdown = true; - return i2c_master_send(to_i2c_client(dev), outbuf, 2); + return i2c_master_send(data->client, outbuf, 2); } static int mcp4725_resume(struct device *dev) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct mcp4725_data *data = iio_priv(indio_dev); + struct mcp4725_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); u8 outbuf[2]; /* restore previous DAC value */ outbuf[0] = (data->dac_value >> 8) & 0xf; outbuf[1] = data->dac_value & 0xff; + data->powerdown = false; - return i2c_master_send(to_i2c_client(dev), outbuf, 2); + return i2c_master_send(data->client, outbuf, 2); } +#ifdef CONFIG_PM_SLEEP static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume); #define MCP4725_PM_OPS (&mcp4725_pm_ops) #else #define MCP4725_PM_OPS NULL #endif +static ssize_t mcp4725_store_eeprom(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct mcp4725_data *data = iio_priv(indio_dev); + int tries = 20; + u8 inoutbuf[3]; + bool state; + int ret; + + ret = strtobool(buf, &state); + if (ret < 0) + return ret; + + if (!state) + return 0; + + inoutbuf[0] = 0x60; /* write EEPROM */ + inoutbuf[1] = data->dac_value >> 4; + inoutbuf[2] = (data->dac_value & 0xf) << 4; + + ret = i2c_master_send(data->client, inoutbuf, 3); + if (ret < 0) + return ret; + else if (ret != 3) + return -EIO; + + /* wait for write complete, takes up to 50ms */ + while (tries--) { + msleep(20); + ret = i2c_master_recv(data->client, inoutbuf, 3); + if (ret < 0) + return ret; + else if (ret != 3) + return -EIO; + + if (inoutbuf[0] & 0x80) + break; + } + + if (tries < 0) { + dev_err(&data->client->dev, + "mcp4725_store_eeprom() failed, incomplete\n"); + return -EIO; + } + + return len; +} + +static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, NULL, mcp4725_store_eeprom, 0); + +static struct attribute *mcp4725_attributes[] = { + &iio_dev_attr_store_eeprom.dev_attr.attr, + NULL, +}; + +static const struct attribute_group mcp4725_attribute_group = { + .attrs = mcp4725_attributes, +}; + +static const char * const mcp4725_powerdown_modes[] = { + "1kohm_to_gnd", + "100kohm_to_gnd", + "500kohm_to_gnd" +}; + +static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct mcp4725_data *data = iio_priv(indio_dev); + + return data->powerdown_mode; +} + +static int mcp4725_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned mode) +{ + struct mcp4725_data *data = iio_priv(indio_dev); + + data->powerdown_mode = mode; + + return 0; +} + +static ssize_t mcp4725_read_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) +{ + struct mcp4725_data *data = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", data->powerdown); +} + +static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct mcp4725_data *data = iio_priv(indio_dev); + bool state; + int ret; + + ret = strtobool(buf, &state); + if (ret) + return ret; + + if (state) + ret = mcp4725_suspend(&data->client->dev); + else + ret = mcp4725_resume(&data->client->dev); + if (ret < 0) + return ret; + + return len; +} + +static const struct iio_enum mcp4725_powerdown_mode_enum = { + .items = mcp4725_powerdown_modes, + .num_items = ARRAY_SIZE(mcp4725_powerdown_modes), + .get = mcp4725_get_powerdown_mode, + .set = mcp4725_set_powerdown_mode, +}; + +static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = { + { + .name = "powerdown", + .read = mcp4725_read_powerdown, + .write = mcp4725_write_powerdown, + }, + IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum), + { }, +}; + static const struct iio_chan_spec mcp4725_channel = { .type = IIO_VOLTAGE, .indexed = 1, @@ -72,6 +209,7 @@ static const struct iio_chan_spec mcp4725_channel = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .scan_type = IIO_ST('u', 12, 16, 0), + .ext_info = mcp4725_ext_info, }; static int mcp4725_set_value(struct iio_dev *indio_dev, int val) @@ -138,6 +276,7 @@ static int mcp4725_write_raw(struct iio_dev *indio_dev, static const struct iio_info mcp4725_info = { .read_raw = mcp4725_read_raw, .write_raw = mcp4725_write_raw, + .attrs = &mcp4725_attribute_group, .driver_module = THIS_MODULE, }; @@ -148,19 +287,17 @@ static int mcp4725_probe(struct i2c_client *client, struct iio_dev *indio_dev; struct mcp4725_platform_data *platform_data = client->dev.platform_data; u8 inbuf[3]; + u8 pd; int err; if (!platform_data || !platform_data->vref_mv) { dev_err(&client->dev, "invalid platform data"); - err = -EINVAL; - goto exit; + return -EINVAL; } - indio_dev = iio_device_alloc(sizeof(*data)); - if (indio_dev == NULL) { - err = -ENOMEM; - goto exit; - } + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (indio_dev == NULL) + return -ENOMEM; data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; @@ -177,31 +314,25 @@ static int mcp4725_probe(struct i2c_client *client, err = i2c_master_recv(client, inbuf, 3); if (err < 0) { dev_err(&client->dev, "failed to read DAC value"); - goto exit_free_device; + return err; } + pd = (inbuf[0] >> 1) & 0x3; + data->powerdown = pd > 0 ? true : false; + data->powerdown_mode = pd ? pd-1 : 2; /* 500kohm_to_gnd */ data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4); err = iio_device_register(indio_dev); if (err) - goto exit_free_device; + return err; dev_info(&client->dev, "MCP4725 DAC registered\n"); return 0; - -exit_free_device: - iio_device_free(indio_dev); -exit: - return err; } static int mcp4725_remove(struct i2c_client *client) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - - iio_device_unregister(indio_dev); - iio_device_free(indio_dev); - + iio_device_unregister(i2c_get_clientdata(client)); return 0; } |