diff options
Diffstat (limited to 'drivers/iio/dac')
-rw-r--r-- | drivers/iio/dac/Kconfig | 29 | ||||
-rw-r--r-- | drivers/iio/dac/Makefile | 3 | ||||
-rw-r--r-- | drivers/iio/dac/ad5755.c | 2 | ||||
-rw-r--r-- | drivers/iio/dac/ad8801.c | 239 | ||||
-rw-r--r-- | drivers/iio/dac/cio-dac.c | 144 | ||||
-rw-r--r-- | drivers/iio/dac/stx104.c | 275 |
6 files changed, 405 insertions, 287 deletions
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index ca814479fadf..120b24478469 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -181,6 +181,25 @@ config AD7303 To compile this driver as module choose M here: the module will be called ad7303. +config CIO_DAC + tristate "Measurement Computing CIO-DAC IIO driver" + depends on X86 && ISA_BUS_API + help + Say yes here to build support for the Measurement Computing CIO-DAC + analog output device family (CIO-DAC16, CIO-DAC08, PC104-DAC06). The + base port addresses for the devices may be configured via the base + array module parameter. + +config AD8801 + tristate "Analog Devices AD8801/AD8803 DAC driver" + depends on SPI_MASTER + help + Say yes here to build support for Analog Devices AD8801, AD8803 Digital to + Analog Converters (DAC). + + To compile this driver as a module choose M here: the module will be called + ad8801. + config LPC18XX_DAC tristate "NXP LPC18xx DAC driver" depends on ARCH_LPC18XX || COMPILE_TEST @@ -245,16 +264,6 @@ config MCP4922 To compile this driver as a module, choose M here: the module will be called mcp4922. -config STX104 - tristate "Apex Embedded Systems STX104 DAC driver" - depends on X86 && ISA_BUS_API - select GPIOLIB - help - Say yes here to build support for the 2-channel DAC and GPIO on the - Apex Embedded Systems STX104 integrated analog PC/104 card. The base - port addresses for the devices may be configured via the base array - module parameter. - config VF610_DAC tristate "Vybrid vf610 DAC driver" depends on OF diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 8b78d5ca9b11..27642bbf75f2 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -20,11 +20,12 @@ obj-$(CONFIG_AD5764) += ad5764.o obj-$(CONFIG_AD5791) += ad5791.o obj-$(CONFIG_AD5686) += ad5686.o obj-$(CONFIG_AD7303) += ad7303.o +obj-$(CONFIG_AD8801) += ad8801.o +obj-$(CONFIG_CIO_DAC) += cio-dac.o obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o obj-$(CONFIG_M62332) += m62332.o obj-$(CONFIG_MAX517) += max517.o obj-$(CONFIG_MAX5821) += max5821.o obj-$(CONFIG_MCP4725) += mcp4725.o obj-$(CONFIG_MCP4922) += mcp4922.o -obj-$(CONFIG_STX104) += stx104.o obj-$(CONFIG_VF610_DAC) += vf610_dac.o diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 0fde593ec0d9..5f7968232564 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -655,7 +655,7 @@ static struct ad5755_platform_data *ad5755_parse_dt(struct device *dev) devnr = 0; for_each_child_of_node(np, pp) { - if (devnr > AD5755_NUM_CHANNELS) { + if (devnr >= AD5755_NUM_CHANNELS) { dev_err(dev, "There is to many channels defined in DT\n"); goto error_out; diff --git a/drivers/iio/dac/ad8801.c b/drivers/iio/dac/ad8801.c new file mode 100644 index 000000000000..f06faa1aec09 --- /dev/null +++ b/drivers/iio/dac/ad8801.c @@ -0,0 +1,239 @@ +/* + * IIO DAC driver for Analog Devices AD8801 DAC + * + * Copyright (C) 2016 Gwenhael Goavec-Merou + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#include <linux/iio/iio.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/spi/spi.h> +#include <linux/sysfs.h> + +#define AD8801_CFG_ADDR_OFFSET 8 + +enum ad8801_device_ids { + ID_AD8801, + ID_AD8803, +}; + +struct ad8801_state { + struct spi_device *spi; + unsigned char dac_cache[8]; /* Value write on each channel */ + unsigned int vrefh_mv; + unsigned int vrefl_mv; + struct regulator *vrefh_reg; + struct regulator *vrefl_reg; + + __be16 data ____cacheline_aligned; +}; + +static int ad8801_spi_write(struct ad8801_state *state, + u8 channel, unsigned char value) +{ + state->data = cpu_to_be16((channel << AD8801_CFG_ADDR_OFFSET) | value); + return spi_write(state->spi, &state->data, sizeof(state->data)); +} + +static int ad8801_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long mask) +{ + struct ad8801_state *state = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val >= 256 || val < 0) + return -EINVAL; + + ret = ad8801_spi_write(state, chan->channel, val); + if (ret == 0) + state->dac_cache[chan->channel] = val; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int ad8801_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long info) +{ + struct ad8801_state *state = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_RAW: + *val = state->dac_cache[chan->channel]; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = state->vrefh_mv - state->vrefl_mv; + *val2 = 8; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_CHAN_INFO_OFFSET: + *val = state->vrefl_mv; + return IIO_VAL_INT; + default: + return -EINVAL; + } + + return -EINVAL; +} + +static const struct iio_info ad8801_info = { + .read_raw = ad8801_read_raw, + .write_raw = ad8801_write_raw, + .driver_module = THIS_MODULE, +}; + +#define AD8801_CHANNEL(chan) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ +} + +static const struct iio_chan_spec ad8801_channels[] = { + AD8801_CHANNEL(0), + AD8801_CHANNEL(1), + AD8801_CHANNEL(2), + AD8801_CHANNEL(3), + AD8801_CHANNEL(4), + AD8801_CHANNEL(5), + AD8801_CHANNEL(6), + AD8801_CHANNEL(7), +}; + +static int ad8801_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct ad8801_state *state; + const struct spi_device_id *id; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state)); + if (indio_dev == NULL) + return -ENOMEM; + + state = iio_priv(indio_dev); + state->spi = spi; + id = spi_get_device_id(spi); + + state->vrefh_reg = devm_regulator_get(&spi->dev, "vrefh"); + if (IS_ERR(state->vrefh_reg)) { + dev_err(&spi->dev, "Vrefh regulator not specified\n"); + return PTR_ERR(state->vrefh_reg); + } + + ret = regulator_enable(state->vrefh_reg); + if (ret) { + dev_err(&spi->dev, "Failed to enable vrefh regulator: %d\n", + ret); + return ret; + } + + ret = regulator_get_voltage(state->vrefh_reg); + if (ret < 0) { + dev_err(&spi->dev, "Failed to read vrefh regulator: %d\n", + ret); + goto error_disable_vrefh_reg; + } + state->vrefh_mv = ret / 1000; + + if (id->driver_data == ID_AD8803) { + state->vrefl_reg = devm_regulator_get(&spi->dev, "vrefl"); + if (IS_ERR(state->vrefl_reg)) { + dev_err(&spi->dev, "Vrefl regulator not specified\n"); + ret = PTR_ERR(state->vrefl_reg); + goto error_disable_vrefh_reg; + } + + ret = regulator_enable(state->vrefl_reg); + if (ret) { + dev_err(&spi->dev, "Failed to enable vrefl regulator: %d\n", + ret); + goto error_disable_vrefh_reg; + } + + ret = regulator_get_voltage(state->vrefl_reg); + if (ret < 0) { + dev_err(&spi->dev, "Failed to read vrefl regulator: %d\n", + ret); + goto error_disable_vrefl_reg; + } + state->vrefl_mv = ret / 1000; + } else { + state->vrefl_mv = 0; + state->vrefl_reg = NULL; + } + + spi_set_drvdata(spi, indio_dev); + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ad8801_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad8801_channels; + indio_dev->num_channels = ARRAY_SIZE(ad8801_channels); + indio_dev->name = id->name; + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&spi->dev, "Failed to register iio device: %d\n", + ret); + goto error_disable_vrefl_reg; + } + + return 0; + +error_disable_vrefl_reg: + if (state->vrefl_reg) + regulator_disable(state->vrefl_reg); +error_disable_vrefh_reg: + regulator_disable(state->vrefh_reg); + return ret; +} + +static int ad8801_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad8801_state *state = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + if (state->vrefl_reg) + regulator_disable(state->vrefl_reg); + regulator_disable(state->vrefh_reg); + + return 0; +} + +static const struct spi_device_id ad8801_ids[] = { + {"ad8801", ID_AD8801}, + {"ad8803", ID_AD8803}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad8801_ids); + +static struct spi_driver ad8801_driver = { + .driver = { + .name = "ad8801", + }, + .probe = ad8801_probe, + .remove = ad8801_remove, + .id_table = ad8801_ids, +}; +module_spi_driver(ad8801_driver); + +MODULE_AUTHOR("Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>"); +MODULE_DESCRIPTION("Analog Devices AD8801/AD8803 DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/cio-dac.c b/drivers/iio/dac/cio-dac.c new file mode 100644 index 000000000000..5a743e2a779d --- /dev/null +++ b/drivers/iio/dac/cio-dac.c @@ -0,0 +1,144 @@ +/* + * IIO driver for the Measurement Computing CIO-DAC + * Copyright (C) 2016 William Breathitt Gray + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * This driver supports the following Measurement Computing devices: CIO-DAC16, + * CIO-DAC06, and PC104-DAC06. + */ +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/iio/iio.h> +#include <linux/iio/types.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/isa.h> +#include <linux/module.h> +#include <linux/moduleparam.h> + +#define CIO_DAC_NUM_CHAN 16 + +#define CIO_DAC_CHAN(chan) { \ + .type = IIO_VOLTAGE, \ + .channel = chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .indexed = 1, \ + .output = 1 \ +} + +#define CIO_DAC_EXTENT 32 + +static unsigned int base[max_num_isa_dev(CIO_DAC_EXTENT)]; +static unsigned int num_cio_dac; +module_param_array(base, uint, &num_cio_dac, 0); +MODULE_PARM_DESC(base, "Measurement Computing CIO-DAC base addresses"); + +/** + * struct cio_dac_iio - IIO device private data structure + * @chan_out_states: channels' output states + * @base: base port address of the IIO device + */ +struct cio_dac_iio { + int chan_out_states[CIO_DAC_NUM_CHAN]; + unsigned int base; +}; + +static int cio_dac_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long mask) +{ + struct cio_dac_iio *const priv = iio_priv(indio_dev); + + if (mask != IIO_CHAN_INFO_RAW) + return -EINVAL; + + *val = priv->chan_out_states[chan->channel]; + + return IIO_VAL_INT; +} + +static int cio_dac_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long mask) +{ + struct cio_dac_iio *const priv = iio_priv(indio_dev); + const unsigned int chan_addr_offset = 2 * chan->channel; + + if (mask != IIO_CHAN_INFO_RAW) + return -EINVAL; + + /* DAC can only accept up to a 16-bit value */ + if ((unsigned int)val > 65535) + return -EINVAL; + + priv->chan_out_states[chan->channel] = val; + outw(val, priv->base + chan_addr_offset); + + return 0; +} + +static const struct iio_info cio_dac_info = { + .driver_module = THIS_MODULE, + .read_raw = cio_dac_read_raw, + .write_raw = cio_dac_write_raw +}; + +static const struct iio_chan_spec cio_dac_channels[CIO_DAC_NUM_CHAN] = { + CIO_DAC_CHAN(0), CIO_DAC_CHAN(1), CIO_DAC_CHAN(2), CIO_DAC_CHAN(3), + CIO_DAC_CHAN(4), CIO_DAC_CHAN(5), CIO_DAC_CHAN(6), CIO_DAC_CHAN(7), + CIO_DAC_CHAN(8), CIO_DAC_CHAN(9), CIO_DAC_CHAN(10), CIO_DAC_CHAN(11), + CIO_DAC_CHAN(12), CIO_DAC_CHAN(13), CIO_DAC_CHAN(14), CIO_DAC_CHAN(15) +}; + +static int cio_dac_probe(struct device *dev, unsigned int id) +{ + struct iio_dev *indio_dev; + struct cio_dac_iio *priv; + unsigned int i; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); + if (!indio_dev) + return -ENOMEM; + + if (!devm_request_region(dev, base[id], CIO_DAC_EXTENT, + dev_name(dev))) { + dev_err(dev, "Unable to request port addresses (0x%X-0x%X)\n", + base[id], base[id] + CIO_DAC_EXTENT); + return -EBUSY; + } + + indio_dev->info = &cio_dac_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = cio_dac_channels; + indio_dev->num_channels = CIO_DAC_NUM_CHAN; + indio_dev->name = dev_name(dev); + + priv = iio_priv(indio_dev); + priv->base = base[id]; + + /* initialize DAC outputs to 0V */ + for (i = 0; i < 32; i += 2) + outw(0, base[id] + i); + + return devm_iio_device_register(dev, indio_dev); +} + +static struct isa_driver cio_dac_driver = { + .probe = cio_dac_probe, + .driver = { + .name = "cio-dac" + } +}; + +module_isa_driver(cio_dac_driver, num_cio_dac); + +MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); +MODULE_DESCRIPTION("Measurement Computing CIO-DAC IIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/stx104.c b/drivers/iio/dac/stx104.c deleted file mode 100644 index bebbd00304ce..000000000000 --- a/drivers/iio/dac/stx104.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * DAC driver for the Apex Embedded Systems STX104 - * Copyright (C) 2016 William Breathitt Gray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/gpio/driver.h> -#include <linux/iio/iio.h> -#include <linux/iio/types.h> -#include <linux/io.h> -#include <linux/ioport.h> -#include <linux/isa.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/spinlock.h> - -#define STX104_NUM_CHAN 2 - -#define STX104_CHAN(chan) { \ - .type = IIO_VOLTAGE, \ - .channel = chan, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ - .indexed = 1, \ - .output = 1 \ -} - -#define STX104_EXTENT 16 - -static unsigned int base[max_num_isa_dev(STX104_EXTENT)]; -static unsigned int num_stx104; -module_param_array(base, uint, &num_stx104, 0); -MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses"); - -/** - * struct stx104_iio - IIO device private data structure - * @chan_out_states: channels' output states - * @base: base port address of the IIO device - */ -struct stx104_iio { - unsigned chan_out_states[STX104_NUM_CHAN]; - unsigned base; -}; - -/** - * struct stx104_gpio - GPIO device private data structure - * @chip: instance of the gpio_chip - * @lock: synchronization lock to prevent I/O race conditions - * @base: base port address of the GPIO device - * @out_state: output bits state - */ -struct stx104_gpio { - struct gpio_chip chip; - spinlock_t lock; - unsigned int base; - unsigned int out_state; -}; - -/** - * struct stx104_dev - STX104 device private data structure - * @indio_dev: IIO device - * @chip: instance of the gpio_chip - */ -struct stx104_dev { - struct iio_dev *indio_dev; - struct gpio_chip *chip; -}; - -static int stx104_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, int *val, int *val2, long mask) -{ - struct stx104_iio *const priv = iio_priv(indio_dev); - - if (mask != IIO_CHAN_INFO_RAW) - return -EINVAL; - - *val = priv->chan_out_states[chan->channel]; - - return IIO_VAL_INT; -} - -static int stx104_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, int val, int val2, long mask) -{ - struct stx104_iio *const priv = iio_priv(indio_dev); - const unsigned chan_addr_offset = 2 * chan->channel; - - if (mask != IIO_CHAN_INFO_RAW) - return -EINVAL; - - priv->chan_out_states[chan->channel] = val; - outw(val, priv->base + 4 + chan_addr_offset); - - return 0; -} - -static const struct iio_info stx104_info = { - .driver_module = THIS_MODULE, - .read_raw = stx104_read_raw, - .write_raw = stx104_write_raw -}; - -static const struct iio_chan_spec stx104_channels[STX104_NUM_CHAN] = { - STX104_CHAN(0), - STX104_CHAN(1) -}; - -static int stx104_gpio_get_direction(struct gpio_chip *chip, - unsigned int offset) -{ - /* GPIO 0-3 are input only, while the rest are output only */ - if (offset < 4) - return 1; - - return 0; -} - -static int stx104_gpio_direction_input(struct gpio_chip *chip, - unsigned int offset) -{ - if (offset >= 4) - return -EINVAL; - - return 0; -} - -static int stx104_gpio_direction_output(struct gpio_chip *chip, - unsigned int offset, int value) -{ - if (offset < 4) - return -EINVAL; - - chip->set(chip, offset, value); - return 0; -} - -static int stx104_gpio_get(struct gpio_chip *chip, unsigned int offset) -{ - struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); - - if (offset >= 4) - return -EINVAL; - - return !!(inb(stx104gpio->base) & BIT(offset)); -} - -static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset, - int value) -{ - struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); - const unsigned int mask = BIT(offset) >> 4; - unsigned long flags; - - if (offset < 4) - return; - - spin_lock_irqsave(&stx104gpio->lock, flags); - - if (value) - stx104gpio->out_state |= mask; - else - stx104gpio->out_state &= ~mask; - - outb(stx104gpio->out_state, stx104gpio->base); - - spin_unlock_irqrestore(&stx104gpio->lock, flags); -} - -static int stx104_probe(struct device *dev, unsigned int id) -{ - struct iio_dev *indio_dev; - struct stx104_iio *priv; - struct stx104_gpio *stx104gpio; - struct stx104_dev *stx104dev; - int err; - - indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); - if (!indio_dev) - return -ENOMEM; - - stx104gpio = devm_kzalloc(dev, sizeof(*stx104gpio), GFP_KERNEL); - if (!stx104gpio) - return -ENOMEM; - - stx104dev = devm_kzalloc(dev, sizeof(*stx104dev), GFP_KERNEL); - if (!stx104dev) - return -ENOMEM; - - if (!devm_request_region(dev, base[id], STX104_EXTENT, - dev_name(dev))) { - dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", - base[id], base[id] + STX104_EXTENT); - return -EBUSY; - } - - indio_dev->info = &stx104_info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = stx104_channels; - indio_dev->num_channels = STX104_NUM_CHAN; - indio_dev->name = dev_name(dev); - - priv = iio_priv(indio_dev); - priv->base = base[id]; - - /* initialize DAC output to 0V */ - outw(0, base[id] + 4); - outw(0, base[id] + 6); - - stx104gpio->chip.label = dev_name(dev); - stx104gpio->chip.parent = dev; - stx104gpio->chip.owner = THIS_MODULE; - stx104gpio->chip.base = -1; - stx104gpio->chip.ngpio = 8; - stx104gpio->chip.get_direction = stx104_gpio_get_direction; - stx104gpio->chip.direction_input = stx104_gpio_direction_input; - stx104gpio->chip.direction_output = stx104_gpio_direction_output; - stx104gpio->chip.get = stx104_gpio_get; - stx104gpio->chip.set = stx104_gpio_set; - stx104gpio->base = base[id] + 3; - stx104gpio->out_state = 0x0; - - spin_lock_init(&stx104gpio->lock); - - stx104dev->indio_dev = indio_dev; - stx104dev->chip = &stx104gpio->chip; - dev_set_drvdata(dev, stx104dev); - - err = gpiochip_add_data(&stx104gpio->chip, stx104gpio); - if (err) { - dev_err(dev, "GPIO registering failed (%d)\n", err); - return err; - } - - err = iio_device_register(indio_dev); - if (err) { - dev_err(dev, "IIO device registering failed (%d)\n", err); - gpiochip_remove(&stx104gpio->chip); - return err; - } - - return 0; -} - -static int stx104_remove(struct device *dev, unsigned int id) -{ - struct stx104_dev *const stx104dev = dev_get_drvdata(dev); - - iio_device_unregister(stx104dev->indio_dev); - gpiochip_remove(stx104dev->chip); - - return 0; -} - -static struct isa_driver stx104_driver = { - .probe = stx104_probe, - .driver = { - .name = "stx104" - }, - .remove = stx104_remove -}; - -module_isa_driver(stx104_driver, num_stx104); - -MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); -MODULE_DESCRIPTION("Apex Embedded Systems STX104 DAC driver"); -MODULE_LICENSE("GPL v2"); |