diff options
Diffstat (limited to 'drivers/staging/iio/resolver')
-rw-r--r-- | drivers/staging/iio/resolver/Kconfig | 9 | ||||
-rw-r--r-- | drivers/staging/iio/resolver/Makefile | 2 | ||||
-rw-r--r-- | drivers/staging/iio/resolver/ad2s1200.c | 188 | ||||
-rw-r--r-- | drivers/staging/iio/resolver/ad2s120x.c | 177 | ||||
-rw-r--r-- | drivers/staging/iio/resolver/ad2s1210.c | 223 | ||||
-rw-r--r-- | drivers/staging/iio/resolver/ad2s90.c | 60 |
6 files changed, 317 insertions, 342 deletions
diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig index 6ecd79e30038..49f69ef986fc 100644 --- a/drivers/staging/iio/resolver/Kconfig +++ b/drivers/staging/iio/resolver/Kconfig @@ -1,7 +1,7 @@ # # Resolver/Synchro drivers # -comment "Resolver to digital converters" +menu "Resolver to digital converters" config AD2S90 tristate "Analog Devices ad2s90 driver" @@ -10,9 +10,10 @@ config AD2S90 Say yes here to build support for Analog Devices spi resolver to digital converters, ad2s90, provides direct access via sysfs. -config AD2S120X - tristate "Analog Devices ad2s120x driver" +config AD2S1200 + tristate "Analog Devices ad2s1200/ad2s1205 driver" depends on SPI + depends on GENERIC_GPIO help Say yes here to build support for Analog Devices spi resolver to digital converters, ad2s1200 and ad2s1205, provides direct access @@ -21,7 +22,9 @@ config AD2S120X config AD2S1210 tristate "Analog Devices ad2s1210 driver" depends on SPI + depends on GENERIC_GPIO help Say yes here to build support for Analog Devices spi resolver to digital converters, ad2s1210, provides direct access via sysfs. +endmenu diff --git a/drivers/staging/iio/resolver/Makefile b/drivers/staging/iio/resolver/Makefile index 0b84a89e6cac..14375e444ebf 100644 --- a/drivers/staging/iio/resolver/Makefile +++ b/drivers/staging/iio/resolver/Makefile @@ -3,5 +3,5 @@ # obj-$(CONFIG_AD2S90) += ad2s90.o -obj-$(CONFIG_AD2S120X) += ad2s120x.o +obj-$(CONFIG_AD2S1200) += ad2s1200.o obj-$(CONFIG_AD2S1210) += ad2s1210.o diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c new file mode 100644 index 000000000000..d7ad46aed0ff --- /dev/null +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -0,0 +1,188 @@ +/* + * ad2s1200.c simple support for the ADI Resolver to Digital Converters: + * AD2S1200/1205 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * 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. + * + */ +#include <linux/types.h> +#include <linux/mutex.h> +#include <linux/device.h> +#include <linux/spi/spi.h> +#include <linux/slab.h> +#include <linux/sysfs.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/module.h> + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad2s1200" + +/* input pin sample and rdvel is controlled by driver */ +#define AD2S1200_PN 2 + +/* input clock on serial interface */ +#define AD2S1200_HZ 8192000 +/* clock period in nano second */ +#define AD2S1200_TSCLK (1000000000/AD2S1200_HZ) + +struct ad2s1200_state { + struct mutex lock; + struct spi_device *sdev; + int sample; + int rdvel; + u8 rx[2] ____cacheline_aligned; +}; + +static int ad2s1200_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret = 0; + s16 vel; + struct ad2s1200_state *st = iio_priv(indio_dev); + + mutex_lock(&st->lock); + gpio_set_value(st->sample, 0); + /* delay (6 * AD2S1200_TSCLK + 20) nano seconds */ + udelay(1); + gpio_set_value(st->sample, 1); + gpio_set_value(st->rdvel, !!(chan->type == IIO_ANGL)); + ret = spi_read(st->sdev, st->rx, 2); + if (ret < 0) { + mutex_unlock(&st->lock); + return ret; + } + + switch (chan->type) { + case IIO_ANGL: + *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + break; + case IIO_ANGL_VEL: + vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + vel = (vel << 4) >> 4; + *val = vel; + default: + mutex_unlock(&st->lock); + return -EINVAL; + } + /* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */ + udelay(1); + mutex_unlock(&st->lock); + return IIO_VAL_INT; +} + +static const struct iio_chan_spec ad2s1200_channels[] = { + { + .type = IIO_ANGL, + .indexed = 1, + .channel = 0, + }, { + .type = IIO_ANGL_VEL, + .indexed = 1, + .channel = 0, + } +}; + +static const struct iio_info ad2s1200_info = { + .read_raw = &ad2s1200_read_raw, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad2s1200_probe(struct spi_device *spi) +{ + struct ad2s1200_state *st; + struct iio_dev *indio_dev; + int pn, ret = 0; + unsigned short *pins = spi->dev.platform_data; + + for (pn = 0; pn < AD2S1200_PN; pn++) + if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) { + pr_err("%s: request gpio pin %d failed\n", + DRV_NAME, pins[pn]); + goto error_ret; + } + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); + mutex_init(&st->lock); + st->sdev = spi; + st->sample = pins[0]; + st->rdvel = pins[1]; + + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ad2s1200_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad2s1200_channels; + indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels); + indio_dev->name = spi_get_device_id(spi)->name; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_dev; + + spi->max_speed_hz = AD2S1200_HZ; + spi->mode = SPI_MODE_3; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_free_device(indio_dev); +error_ret: + for (--pn; pn >= 0; pn--) + gpio_free(pins[pn]); + return ret; +} + +static int __devexit ad2s1200_remove(struct spi_device *spi) +{ + iio_device_unregister(spi_get_drvdata(spi)); + iio_free_device(spi_get_drvdata(spi)); + + return 0; +} + +static const struct spi_device_id ad2s1200_id[] = { + { "ad2s1200" }, + { "ad2s1205" }, + {} +}; + +static struct spi_driver ad2s1200_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad2s1200_probe, + .remove = __devexit_p(ad2s1200_remove), + .id_table = ad2s1200_id, +}; + +static __init int ad2s1200_spi_init(void) +{ + return spi_register_driver(&ad2s1200_driver); +} +module_init(ad2s1200_spi_init); + +static __exit void ad2s1200_spi_exit(void) +{ + spi_unregister_driver(&ad2s1200_driver); +} +module_exit(ad2s1200_spi_exit); + +MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/resolver/ad2s120x.c b/drivers/staging/iio/resolver/ad2s120x.c deleted file mode 100644 index bed4c725f2df..000000000000 --- a/drivers/staging/iio/resolver/ad2s120x.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * ad2s120x.c simple support for the ADI Resolver to Digital Converters: AD2S1200/1205 - * - * Copyright (c) 2010-2010 Analog Devices Inc. - * - * 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. - * - */ -#include <linux/types.h> -#include <linux/mutex.h> -#include <linux/device.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/delay.h> -#include <linux/gpio.h> - -#include "../iio.h" -#include "../sysfs.h" - -#define DRV_NAME "ad2s120x" - -/* input pin sample and rdvel is controlled by driver */ -#define AD2S120X_PN 2 - -/* input clock on serial interface */ -#define AD2S120X_HZ 8192000 -/* clock period in nano second */ -#define AD2S120X_TSCLK (1000000000/AD2S120X_HZ) - -struct ad2s120x_state { - struct mutex lock; - struct spi_device *sdev; - int sample; - int rdvel; - u8 rx[2] ____cacheline_aligned; -}; - -static ssize_t ad2s120x_show_val(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret = 0; - ssize_t len = 0; - u16 pos; - s16 vel; - u8 status; - struct ad2s120x_state *st = iio_priv(dev_get_drvdata(dev)); - struct iio_dev_attr *iattr = to_iio_dev_attr(attr); - - mutex_lock(&st->lock); - - gpio_set_value(st->sample, 0); - /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */ - udelay(1); - gpio_set_value(st->sample, 1); - gpio_set_value(st->rdvel, iattr->address); - ret = spi_read(st->sdev, st->rx, 2); - if (ret < 0) - goto error_ret; - status = st->rx[1]; - if (iattr->address) - pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - else { - vel = (st->rx[0] & 0x80) ? 0xf000 : 0; - vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - } - len = sprintf(buf, "%d %c%c%c%c ", iattr->address ? pos : vel, - (status & 0x8) ? 'P' : 'V', - (status & 0x4) ? 'd' : '_', - (status & 0x2) ? 'l' : '_', - (status & 0x1) ? '1' : '0'); -error_ret: - /* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */ - udelay(1); - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s120x_show_val, NULL, 1); -static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s120x_show_val, NULL, 0); - -static struct attribute *ad2s120x_attributes[] = { - &iio_dev_attr_pos.dev_attr.attr, - &iio_dev_attr_vel.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad2s120x_attribute_group = { - .attrs = ad2s120x_attributes, -}; - -static const struct iio_info ad2s120x_info = { - .attrs = &ad2s120x_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad2s120x_probe(struct spi_device *spi) -{ - struct ad2s120x_state *st; - struct iio_dev *indio_dev; - int pn, ret = 0; - unsigned short *pins = spi->dev.platform_data; - - for (pn = 0; pn < AD2S120X_PN; pn++) - if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) { - pr_err("%s: request gpio pin %d failed\n", - DRV_NAME, pins[pn]); - goto error_ret; - } - indio_dev = iio_allocate_device(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - spi_set_drvdata(spi, indio_dev); - st = iio_priv(indio_dev); - mutex_init(&st->lock); - st->sdev = spi; - st->sample = pins[0]; - st->rdvel = pins[1]; - - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &ad2s120x_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_free_dev; - - spi->max_speed_hz = AD2S120X_HZ; - spi->mode = SPI_MODE_3; - spi_setup(spi); - - return 0; - -error_free_dev: - iio_free_device(indio_dev); -error_ret: - for (--pn; pn >= 0; pn--) - gpio_free(pins[pn]); - return ret; -} - -static int __devexit ad2s120x_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad2s120x_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad2s120x_probe, - .remove = __devexit_p(ad2s120x_remove), -}; - -static __init int ad2s120x_spi_init(void) -{ - return spi_register_driver(&ad2s120x_driver); -} -module_init(ad2s120x_spi_init); - -static __exit void ad2s120x_spi_exit(void) -{ - spi_unregister_driver(&ad2s120x_driver); -} -module_exit(ad2s120x_spi_exit); - -MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index ecaf7bb790fe..6401a6273625 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -16,6 +16,7 @@ #include <linux/sysfs.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -194,47 +195,6 @@ static inline int ad2s1210_soft_reset(struct ad2s1210_state *st) return ad2s1210_config_write(st, 0x0); } - -/* return the OLD DATA since last spi bus write */ -static ssize_t ad2s1210_show_raw(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); - int ret = 0; - - mutex_lock(&st->lock); - if (st->old_data) { - ret = sprintf(buf, "0x%x\n", st->rx[0]); - st->old_data = false; - } - mutex_unlock(&st->lock); - - return ret; -} - -static ssize_t ad2s1210_store_raw(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); - unsigned long udata; - unsigned char data; - int ret; - - ret = strict_strtoul(buf, 16, &udata); - if (ret) - return -EINVAL; - - data = udata & 0xff; - mutex_lock(&st->lock); - ret = ad2s1210_config_write(st, data); - mutex_unlock(&st->lock); - - return ret < 0 ? ret : len; -} - static ssize_t ad2s1210_store_softreset(struct device *dev, struct device_attribute *attr, const char *buf, @@ -513,75 +473,72 @@ error_ret: return ret < 0 ? ret : len; } -static ssize_t ad2s1210_show_pos(struct device *dev, - struct device_attribute *attr, - char *buf) +static int ad2s1210_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) { + struct ad2s1210_state *st = iio_priv(indio_dev); + bool negative; int ret = 0; - ssize_t len = 0; u16 pos; - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); - - mutex_lock(&st->lock); - gpio_set_value(st->pdata->sample, 0); - /* delay (6 * tck + 20) nano seconds */ - udelay(1); - - ad2s1210_set_mode(MOD_POS, st); - ret = spi_read(st->sdev, st->rx, 2); - if (ret) - goto error_ret; - pos = be16_to_cpup((u16 *)st->rx); - if (st->hysteresis) - pos >>= 16 - st->resolution; - len = sprintf(buf, "%d\n", pos); -error_ret: - gpio_set_value(st->pdata->sample, 1); - /* delay (2 * tck + 20) nano seconds */ - udelay(1); - mutex_unlock(&st->lock); - - return ret < 0 ? ret : len; -} - -static ssize_t ad2s1210_show_vel(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - unsigned short negative; - int ret = 0; - ssize_t len = 0; s16 vel; - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); mutex_lock(&st->lock); gpio_set_value(st->pdata->sample, 0); /* delay (6 * tck + 20) nano seconds */ udelay(1); - ad2s1210_set_mode(MOD_VEL, st); + switch (chan->type) { + case IIO_ANGL: + ad2s1210_set_mode(MOD_POS, st); + break; + case IIO_ANGL_VEL: + ad2s1210_set_mode(MOD_VEL, st); + break; + default: + ret = -EINVAL; + break; + } + if (ret < 0) + goto error_ret; ret = spi_read(st->sdev, st->rx, 2); - if (ret) + if (ret < 0) goto error_ret; - negative = st->rx[0] & 0x80; - vel = be16_to_cpup((s16 *)st->rx); - vel >>= 16 - st->resolution; - if (vel & 0x8000) { - negative = (0xffff >> st->resolution) << st->resolution; - vel |= negative; + + switch (chan->type) { + case IIO_ANGL: + pos = be16_to_cpup((u16 *)st->rx); + if (st->hysteresis) + pos >>= 16 - st->resolution; + *val = pos; + ret = IIO_VAL_INT; + break; + case IIO_ANGL_VEL: + negative = st->rx[0] & 0x80; + vel = be16_to_cpup((s16 *)st->rx); + vel >>= 16 - st->resolution; + if (vel & 0x8000) { + negative = (0xffff >> st->resolution) << st->resolution; + vel |= negative; + } + *val = vel; + ret = IIO_VAL_INT; + break; + default: + mutex_unlock(&st->lock); + return -EINVAL; } - len = sprintf(buf, "%d\n", vel); + error_ret: gpio_set_value(st->pdata->sample, 1); /* delay (2 * tck + 20) nano seconds */ udelay(1); mutex_unlock(&st->lock); - - return ret < 0 ? ret : len; + return ret; } -static IIO_DEVICE_ATTR(raw_io, S_IRUGO | S_IWUSR, - ad2s1210_show_raw, ad2s1210_store_raw, 0); static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, ad2s1210_store_softreset, 0); static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUSR, @@ -594,8 +551,7 @@ static IIO_DEVICE_ATTR(bits, S_IRUGO | S_IWUSR, ad2s1210_show_resolution, ad2s1210_store_resolution, 0); static IIO_DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, ad2s1210_show_fault, ad2s1210_clear_fault, 0); -static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s1210_show_pos, NULL, 0); -static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s1210_show_vel, NULL, 0); + static IIO_DEVICE_ATTR(los_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, AD2S1210_REG_LOS_THRD); @@ -618,16 +574,26 @@ static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, AD2S1210_REG_LOT_LOW_THRD); + +static struct iio_chan_spec ad2s1210_channels[] = { + { + .type = IIO_ANGL, + .indexed = 1, + .channel = 0, + }, { + .type = IIO_ANGL_VEL, + .indexed = 1, + .channel = 0, + } +}; + static struct attribute *ad2s1210_attributes[] = { - &iio_dev_attr_raw_io.dev_attr.attr, &iio_dev_attr_reset.dev_attr.attr, &iio_dev_attr_fclkin.dev_attr.attr, &iio_dev_attr_fexcit.dev_attr.attr, &iio_dev_attr_control.dev_attr.attr, &iio_dev_attr_bits.dev_attr.attr, &iio_dev_attr_fault.dev_attr.attr, - &iio_dev_attr_pos.dev_attr.attr, - &iio_dev_attr_vel.dev_attr.attr, &iio_dev_attr_los_thrd.dev_attr.attr, &iio_dev_attr_dos_ovr_thrd.dev_attr.attr, &iio_dev_attr_dos_mis_thrd.dev_attr.attr, @@ -639,7 +605,6 @@ static struct attribute *ad2s1210_attributes[] = { }; static const struct attribute_group ad2s1210_attribute_group = { - .name = DRV_NAME, .attrs = ad2s1210_attributes, }; @@ -681,51 +646,37 @@ error_ret: } static const struct iio_info ad2s1210_info = { + .read_raw = &ad2s1210_read_raw, .attrs = &ad2s1210_attribute_group, .driver_module = THIS_MODULE, }; static int ad2s1210_setup_gpios(struct ad2s1210_state *st) { - int ret; unsigned long flags = st->pdata->gpioin ? GPIOF_DIR_IN : GPIOF_DIR_OUT; + struct gpio ad2s1210_gpios[] = { + { st->pdata->sample, GPIOF_DIR_IN, "sample" }, + { st->pdata->a[0], flags, "a0" }, + { st->pdata->a[1], flags, "a1" }, + { st->pdata->res[0], flags, "res0" }, + { st->pdata->res[0], flags, "res1" }, + }; - ret = gpio_request_one(st->pdata->sample, GPIOF_DIR_IN, "sample"); - if (ret < 0) - goto error_ret; - ret = gpio_request_one(st->pdata->a[0], flags, "a0"); - if (ret < 0) - goto error_free_sample; - ret = gpio_request_one(st->pdata->a[1], flags, "a1"); - if (ret < 0) - goto error_free_a0; - ret = gpio_request_one(st->pdata->res[1], flags, "res0"); - if (ret < 0) - goto error_free_a1; - ret = gpio_request_one(st->pdata->res[1], flags, "res1"); - if (ret < 0) - goto error_free_res0; - - return 0; -error_free_res0: - gpio_free(st->pdata->res[0]); -error_free_a1: - gpio_free(st->pdata->a[1]); -error_free_a0: - gpio_free(st->pdata->a[0]); -error_free_sample: - gpio_free(st->pdata->sample); -error_ret: - return ret; + return gpio_request_array(ad2s1210_gpios, ARRAY_SIZE(ad2s1210_gpios)); } static void ad2s1210_free_gpios(struct ad2s1210_state *st) { - gpio_free(st->pdata->res[1]); - gpio_free(st->pdata->res[0]); - gpio_free(st->pdata->a[1]); - gpio_free(st->pdata->a[0]); - gpio_free(st->pdata->sample); + unsigned long flags = st->pdata->gpioin ? GPIOF_DIR_IN : GPIOF_DIR_OUT; + struct gpio ad2s1210_gpios[] = { + { st->pdata->sample, GPIOF_DIR_IN, "sample" }, + { st->pdata->a[0], flags, "a0" }, + { st->pdata->a[1], flags, "a1" }, + { st->pdata->res[0], flags, "res0" }, + { st->pdata->res[0], flags, "res1" }, + }; + + gpio_free_array(ad2s1210_gpios, ARRAY_SIZE(ad2s1210_gpios)); } static int __devinit ad2s1210_probe(struct spi_device *spi) @@ -760,6 +711,9 @@ static int __devinit ad2s1210_probe(struct spi_device *spi) indio_dev->dev.parent = &spi->dev; indio_dev->info = &ad2s1210_info; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad2s1210_channels; + indio_dev->num_channels = ARRAY_SIZE(ad2s1210_channels); + indio_dev->name = spi_get_device_id(spi)->name; ret = iio_device_register(indio_dev); if (ret) @@ -783,13 +737,19 @@ error_ret: static int __devexit ad2s1210_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad2s1210_state *st = iio_priv(indio_dev); + iio_device_unregister(indio_dev); - ad2s1210_free_gpios(st); + ad2s1210_free_gpios(iio_priv(indio_dev)); + iio_free_device(indio_dev); return 0; } +static const struct spi_device_id ad2s1210_id[] = { + { "ad2s1210" }, + {} +}; + static struct spi_driver ad2s1210_driver = { .driver = { .name = DRV_NAME, @@ -797,6 +757,7 @@ static struct spi_driver ad2s1210_driver = { }, .probe = ad2s1210_probe, .remove = __devexit_p(ad2s1210_remove), + .id_table = ad2s1210_id, }; static __init int ad2s1210_spi_init(void) diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 166e2414ac85..a9200d949dcd 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -14,59 +14,49 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#define DRV_NAME "ad2s90" - struct ad2s90_state { struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; u8 rx[2] ____cacheline_aligned; }; -static ssize_t ad2s90_show_angular(struct device *dev, - struct device_attribute *attr, char *buf) +static int ad2s90_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) { int ret; - ssize_t len = 0; - u16 val; - struct ad2s90_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s90_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); ret = spi_read(st->sdev, st->rx, 2); if (ret) goto error_ret; - val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - len = sprintf(buf, "%d\n", val); + *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + error_ret: mutex_unlock(&st->lock); - return ret ? ret : len; + return IIO_VAL_INT; } -#define IIO_DEV_ATTR_SIMPLE_RESOLVER(_show) \ - IIO_DEVICE_ATTR(angular, S_IRUGO, _show, NULL, 0) - -static IIO_DEV_ATTR_SIMPLE_RESOLVER(ad2s90_show_angular); - -static struct attribute *ad2s90_attributes[] = { - &iio_dev_attr_angular.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad2s90_attribute_group = { - .name = DRV_NAME, - .attrs = ad2s90_attributes, -}; - static const struct iio_info ad2s90_info = { - .attrs = &ad2s90_attribute_group, + .read_raw = &ad2s90_read_raw, .driver_module = THIS_MODULE, }; +static const struct iio_chan_spec ad2s90_chan = { + .type = IIO_ANGL, + .indexed = 1, + .channel = 0, +}; + static int __devinit ad2s90_probe(struct spi_device *spi) { struct iio_dev *indio_dev; @@ -86,8 +76,11 @@ static int __devinit ad2s90_probe(struct spi_device *spi) indio_dev->dev.parent = &spi->dev; indio_dev->info = &ad2s90_info; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = &ad2s90_chan; + indio_dev->num_channels = 1; + indio_dev->name = spi_get_device_id(spi)->name; - ret = iio_device_register(st->idev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -99,7 +92,7 @@ static int __devinit ad2s90_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(st->idev); + iio_free_device(indio_dev); error_ret: return ret; } @@ -107,17 +100,24 @@ error_ret: static int __devexit ad2s90_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); + iio_free_device(spi_get_drvdata(spi)); return 0; } +static const struct spi_device_id ad2s90_id[] = { + { "ad2s90" }, + {} +}; + static struct spi_driver ad2s90_driver = { .driver = { - .name = DRV_NAME, + .name = "ad2s90", .owner = THIS_MODULE, }, .probe = ad2s90_probe, .remove = __devexit_p(ad2s90_remove), + .id_table = ad2s90_id, }; static __init int ad2s90_spi_init(void) |