diff options
Diffstat (limited to 'drivers/staging')
| -rw-r--r-- | drivers/staging/iio/gyro/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/staging/iio/gyro/Makefile | 3 | ||||
| -rw-r--r-- | drivers/staging/iio/gyro/adxrs450.h | 62 | ||||
| -rw-r--r-- | drivers/staging/iio/gyro/adxrs450_core.c | 440 | ||||
| -rw-r--r-- | drivers/staging/iio/iio_hwmon.c | 83 |
5 files changed, 37 insertions, 561 deletions
diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index 658b3673d05..83606628719 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -29,14 +29,4 @@ config ADIS16260 This driver can also be built as a module. If so, the module will be called adis16260. -config ADXRS450 - tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver" - depends on SPI - help - Say yes here to build support for Analog Devices ADXRS450 and ADXRS453 - programmable digital output gyroscope. - - This driver can also be built as a module. If so, the module - will be called adxrs450. - endmenu diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile index ef331617129..98e650061a3 100644 --- a/drivers/staging/iio/gyro/Makefile +++ b/drivers/staging/iio/gyro/Makefile @@ -10,6 +10,3 @@ obj-$(CONFIG_ADIS16130) += adis16130.o adis16260-y := adis16260_core.o obj-$(CONFIG_ADIS16260) += adis16260.o - -adxrs450-y := adxrs450_core.o -obj-$(CONFIG_ADXRS450) += adxrs450.o diff --git a/drivers/staging/iio/gyro/adxrs450.h b/drivers/staging/iio/gyro/adxrs450.h deleted file mode 100644 index f8cf21f0294..00000000000 --- a/drivers/staging/iio/gyro/adxrs450.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef SPI_ADXRS450_H_ -#define SPI_ADXRS450_H_ - -#define ADXRS450_STARTUP_DELAY 50 /* ms */ - -/* The MSB for the spi commands */ -#define ADXRS450_SENSOR_DATA 0x20 -#define ADXRS450_WRITE_DATA 0x40 -#define ADXRS450_READ_DATA 0x80 - -#define ADXRS450_RATE1 0x00 /* Rate Registers */ -#define ADXRS450_TEMP1 0x02 /* Temperature Registers */ -#define ADXRS450_LOCST1 0x04 /* Low CST Memory Registers */ -#define ADXRS450_HICST1 0x06 /* High CST Memory Registers */ -#define ADXRS450_QUAD1 0x08 /* Quad Memory Registers */ -#define ADXRS450_FAULT1 0x0A /* Fault Registers */ -#define ADXRS450_PID1 0x0C /* Part ID Register 1 */ -#define ADXRS450_SNH 0x0E /* Serial Number Registers, 4 bytes */ -#define ADXRS450_SNL 0x10 -#define ADXRS450_DNC1 0x12 /* Dynamic Null Correction Registers */ -/* Check bits */ -#define ADXRS450_P 0x01 -#define ADXRS450_CHK 0x02 -#define ADXRS450_CST 0x04 -#define ADXRS450_PWR 0x08 -#define ADXRS450_POR 0x10 -#define ADXRS450_NVM 0x20 -#define ADXRS450_Q 0x40 -#define ADXRS450_PLL 0x80 -#define ADXRS450_UV 0x100 -#define ADXRS450_OV 0x200 -#define ADXRS450_AMP 0x400 -#define ADXRS450_FAIL 0x800 - -#define ADXRS450_WRERR_MASK (0x7 << 29) - -#define ADXRS450_MAX_RX 4 -#define ADXRS450_MAX_TX 4 - -#define ADXRS450_GET_ST(a) ((a >> 26) & 0x3) - -enum { - ID_ADXRS450, - ID_ADXRS453, -}; - -/** - * struct adxrs450_state - device instance specific data - * @us: actual spi_device - * @buf_lock: mutex to protect tx and rx - * @tx: transmit buffer - * @rx: receive buffer - **/ -struct adxrs450_state { - struct spi_device *us; - struct mutex buf_lock; - u8 tx[ADXRS450_MAX_RX] ____cacheline_aligned; - u8 rx[ADXRS450_MAX_TX]; - -}; - -#endif /* SPI_ADXRS450_H_ */ diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c deleted file mode 100644 index f0ce81da8ac..00000000000 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * ADXRS450/ADXRS453 Digital Output Gyroscope Driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <linux/mutex.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> -#include <linux/module.h> - -#include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> - -#include "adxrs450.h" - -/** - * adxrs450_spi_read_reg_16() - read 2 bytes from a register pair - * @dev: device associated with child of actual iio_dev - * @reg_address: the address of the lower of the two registers,which should be an even address, - * Second register's address is reg_address + 1. - * @val: somewhere to pass back the value read - **/ -static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev, - u8 reg_address, - u16 *val) -{ - struct adxrs450_state *st = iio_priv(indio_dev); - int ret; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADXRS450_READ_DATA | (reg_address >> 7); - st->tx[1] = reg_address << 1; - st->tx[2] = 0; - st->tx[3] = 0; - - if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1)) - st->tx[3] |= ADXRS450_P; - - ret = spi_write(st->us, st->tx, 4); - if (ret) { - dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n", - reg_address); - goto error_ret; - } - ret = spi_read(st->us, st->rx, 4); - if (ret) { - dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n", - reg_address); - goto error_ret; - } - - *val = (be32_to_cpu(*(u32 *)st->rx) >> 5) & 0xFFFF; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -/** - * adxrs450_spi_write_reg_16() - write 2 bytes data to a register pair - * @dev: device associated with child of actual actual iio_dev - * @reg_address: the address of the lower of the two registers,which should be an even address, - * Second register's address is reg_address + 1. - * @val: value to be written. - **/ -static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev, - u8 reg_address, - u16 val) -{ - struct adxrs450_state *st = iio_priv(indio_dev); - int ret; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADXRS450_WRITE_DATA | reg_address >> 7; - st->tx[1] = reg_address << 1 | val >> 15; - st->tx[2] = val >> 7; - st->tx[3] = val << 1; - - if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1)) - st->tx[3] |= ADXRS450_P; - - ret = spi_write(st->us, st->tx, 4); - if (ret) - dev_err(&st->us->dev, "problem while writing 16 bit register 0x%02x\n", - reg_address); - msleep(1); /* enforce sequential transfer delay 0.1ms */ - mutex_unlock(&st->buf_lock); - return ret; -} - -/** - * adxrs450_spi_sensor_data() - read 2 bytes sensor data - * @dev: device associated with child of actual iio_dev - * @val: somewhere to pass back the value read - **/ -static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val) -{ - struct adxrs450_state *st = iio_priv(indio_dev); - int ret; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADXRS450_SENSOR_DATA; - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; - - ret = spi_write(st->us, st->tx, 4); - if (ret) { - dev_err(&st->us->dev, "Problem while reading sensor data\n"); - goto error_ret; - } - - ret = spi_read(st->us, st->rx, 4); - if (ret) { - dev_err(&st->us->dev, "Problem while reading sensor data\n"); - goto error_ret; - } - - *val = (be32_to_cpu(*(u32 *)st->rx) >> 10) & 0xFFFF; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -/** - * adxrs450_spi_initial() - use for initializing procedure. - * @st: device instance specific data - * @val: somewhere to pass back the value read - **/ -static int adxrs450_spi_initial(struct adxrs450_state *st, - u32 *val, char chk) -{ - struct spi_message msg; - int ret; - struct spi_transfer xfers = { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 4, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADXRS450_SENSOR_DATA; - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; - if (chk) - st->tx[3] |= (ADXRS450_CHK | ADXRS450_P); - spi_message_init(&msg); - spi_message_add_tail(&xfers, &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "Problem while reading initializing data\n"); - goto error_ret; - } - - *val = be32_to_cpu(*(u32 *)st->rx); - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -/* Recommended Startup Sequence by spec */ -static int adxrs450_initial_setup(struct iio_dev *indio_dev) -{ - u32 t; - u16 data; - int ret; - struct adxrs450_state *st = iio_priv(indio_dev); - - msleep(ADXRS450_STARTUP_DELAY*2); - ret = adxrs450_spi_initial(st, &t, 1); - if (ret) - return ret; - if (t != 0x01) - dev_warn(&st->us->dev, "The initial power on response " - "is not correct! Restart without reset?\n"); - - msleep(ADXRS450_STARTUP_DELAY); - ret = adxrs450_spi_initial(st, &t, 0); - if (ret) - return ret; - - msleep(ADXRS450_STARTUP_DELAY); - ret = adxrs450_spi_initial(st, &t, 0); - if (ret) - return ret; - if (((t & 0xff) | 0x01) != 0xff || ADXRS450_GET_ST(t) != 2) { - dev_err(&st->us->dev, "The second response is not correct!\n"); - return -EIO; - - } - ret = adxrs450_spi_initial(st, &t, 0); - if (ret) - return ret; - if (((t & 0xff) | 0x01) != 0xff || ADXRS450_GET_ST(t) != 2) { - dev_err(&st->us->dev, "The third response is not correct!\n"); - return -EIO; - - } - ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_FAULT1, &data); - if (ret) - return ret; - if (data & 0x0fff) { - dev_err(&st->us->dev, "The device is not in normal status!\n"); - return -EINVAL; - } - ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_PID1, &data); - if (ret) - return ret; - dev_info(&st->us->dev, "The Part ID is 0x%x\n", data); - - ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNL, &data); - if (ret) - return ret; - t = data; - ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNH, &data); - if (ret) - return ret; - t |= data << 16; - dev_info(&st->us->dev, "The Serial Number is 0x%x\n", t); - - return 0; -} - -static int adxrs450_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) -{ - int ret; - switch (mask) { - case IIO_CHAN_INFO_CALIBBIAS: - ret = adxrs450_spi_write_reg_16(indio_dev, - ADXRS450_DNC1, - val & 0x3FF); - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -static int adxrs450_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long mask) -{ - int ret; - s16 t; - - switch (mask) { - case IIO_CHAN_INFO_RAW: - switch (chan->type) { - case IIO_ANGL_VEL: - ret = adxrs450_spi_sensor_data(indio_dev, &t); - if (ret) - break; - *val = t; - ret = IIO_VAL_INT; - break; - case IIO_TEMP: - ret = adxrs450_spi_read_reg_16(indio_dev, - ADXRS450_TEMP1, &t); - if (ret) - break; - *val = (t >> 6) + 225; - ret = IIO_VAL_INT; - break; - default: - ret = -EINVAL; - break; - } - break; - case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_ANGL_VEL: - *val = 0; - *val2 = 218166; - return IIO_VAL_INT_PLUS_NANO; - case IIO_TEMP: - *val = 200; - *val2 = 0; - return IIO_VAL_INT; - default: - return -EINVAL; - } - break; - case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW: - ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t); - if (ret) - break; - *val = t; - ret = IIO_VAL_INT; - break; - case IIO_CHAN_INFO_CALIBBIAS: - ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_DNC1, &t); - if (ret) - break; - *val = t; - ret = IIO_VAL_INT; - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static const struct iio_chan_spec adxrs450_channels[2][2] = { - [ID_ADXRS450] = { - { - .type = IIO_ANGL_VEL, - .modified = 1, - .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - } - }, - [ID_ADXRS453] = { - { - .type = IIO_ANGL_VEL, - .modified = 1, - .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - } - }, -}; - -static const struct iio_info adxrs450_info = { - .driver_module = THIS_MODULE, - .read_raw = &adxrs450_read_raw, - .write_raw = &adxrs450_write_raw, -}; - -static int adxrs450_probe(struct spi_device *spi) -{ - int ret; - struct adxrs450_state *st; - struct iio_dev *indio_dev; - - /* setup the industrialio driver allocated elements */ - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st = iio_priv(indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - /* This is only used for removal purposes */ - spi_set_drvdata(spi, indio_dev); - - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &adxrs450_info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = - adxrs450_channels[spi_get_device_id(spi)->driver_data]; - indio_dev->num_channels = ARRAY_SIZE(adxrs450_channels); - indio_dev->name = spi->dev.driver->name; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_free_dev; - - /* Get the device into a sane initial state */ - ret = adxrs450_initial_setup(indio_dev); - if (ret) - goto error_initial; - return 0; -error_initial: - iio_device_unregister(indio_dev); -error_free_dev: - iio_device_free(indio_dev); - -error_ret: - return ret; -} - -static int adxrs450_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - - return 0; -} - -static const struct spi_device_id adxrs450_id[] = { - {"adxrs450", ID_ADXRS450}, - {"adxrs453", ID_ADXRS453}, - {} -}; -MODULE_DEVICE_TABLE(spi, adxrs450_id); - -static struct spi_driver adxrs450_driver = { - .driver = { - .name = "adxrs450", - .owner = THIS_MODULE, - }, - .probe = adxrs450_probe, - .remove = adxrs450_remove, - .id_table = adxrs450_id, -}; -module_spi_driver(adxrs450_driver); - -MODULE_AUTHOR("Cliff Cai <cliff.cai@xxxxxxxxxx>"); -MODULE_DESCRIPTION("Analog Devices ADXRS450/ADXRS453 Gyroscope SPI driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index 97ad645bb15..93af756ba48 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -55,63 +55,58 @@ static ssize_t iio_hwmon_read_val(struct device *dev, return sprintf(buf, "%d\n", result); } -static void iio_hwmon_free_attrs(struct iio_hwmon_state *st) +static ssize_t show_name(struct device *dev, struct device_attribute *attr, + char *buf) { - int i; - struct sensor_device_attribute *a; - for (i = 0; i < st->num_channels; i++) - if (st->attrs[i]) { - a = to_sensor_dev_attr( - container_of(st->attrs[i], - struct device_attribute, - attr)); - kfree(a); - } + return sprintf(buf, "iio_hwmon\n"); } +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + static int iio_hwmon_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct iio_hwmon_state *st; struct sensor_device_attribute *a; int ret, i; int in_i = 1, temp_i = 1, curr_i = 1; enum iio_chan_type type; + struct iio_channel *channels; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_ret; - } + channels = iio_channel_get_all(dev); + if (IS_ERR(channels)) + return PTR_ERR(channels); - st->channels = iio_channel_get_all(dev_name(&pdev->dev)); - if (IS_ERR(st->channels)) { - ret = PTR_ERR(st->channels); - goto error_free_state; - } + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); + if (st == NULL) + return -ENOMEM; + + st->channels = channels; /* count how many attributes we have */ while (st->channels[st->num_channels].indio_dev) st->num_channels++; - st->attrs = kzalloc(sizeof(*st->attrs) * (st->num_channels + 1), - GFP_KERNEL); + st->attrs = devm_kzalloc(dev, + sizeof(*st->attrs) * (st->num_channels + 2), + GFP_KERNEL); if (st->attrs == NULL) { ret = -ENOMEM; goto error_release_channels; } + for (i = 0; i < st->num_channels; i++) { - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = devm_kzalloc(dev, sizeof(*a), GFP_KERNEL); if (a == NULL) { ret = -ENOMEM; - goto error_free_attrs; + goto error_release_channels; } sysfs_attr_init(&a->dev_attr.attr); ret = iio_get_channel_type(&st->channels[i], &type); - if (ret < 0) { - kfree(a); - goto error_free_attrs; - } + if (ret < 0) + goto error_release_channels; + switch (type) { case IIO_VOLTAGE: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, @@ -130,27 +125,25 @@ static int iio_hwmon_probe(struct platform_device *pdev) break; default: ret = -EINVAL; - kfree(a); - goto error_free_attrs; + goto error_release_channels; } if (a->dev_attr.attr.name == NULL) { - kfree(a); ret = -ENOMEM; - goto error_free_attrs; + goto error_release_channels; } a->dev_attr.show = iio_hwmon_read_val; a->dev_attr.attr.mode = S_IRUGO; a->index = i; st->attrs[i] = &a->dev_attr.attr; } - + st->attrs[st->num_channels] = &dev_attr_name.attr; st->attr_group.attrs = st->attrs; platform_set_drvdata(pdev, st); - ret = sysfs_create_group(&pdev->dev.kobj, &st->attr_group); + ret = sysfs_create_group(&dev->kobj, &st->attr_group); if (ret < 0) - goto error_free_attrs; + goto error_release_channels; - st->hwmon_dev = hwmon_device_register(&pdev->dev); + st->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(st->hwmon_dev)) { ret = PTR_ERR(st->hwmon_dev); goto error_remove_group; @@ -158,15 +151,9 @@ static int iio_hwmon_probe(struct platform_device *pdev) return 0; error_remove_group: - sysfs_remove_group(&pdev->dev.kobj, &st->attr_group); -error_free_attrs: - iio_hwmon_free_attrs(st); - kfree(st->attrs); + sysfs_remove_group(&dev->kobj, &st->attr_group); error_release_channels: iio_channel_release_all(st->channels); -error_free_state: - kfree(st); -error_ret: return ret; } @@ -176,17 +163,21 @@ static int iio_hwmon_remove(struct platform_device *pdev) hwmon_device_unregister(st->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &st->attr_group); - iio_hwmon_free_attrs(st); - kfree(st->attrs); iio_channel_release_all(st->channels); return 0; } +static struct of_device_id iio_hwmon_of_match[] = { + { .compatible = "iio-hwmon", }, + { } +}; + static struct platform_driver __refdata iio_hwmon_driver = { .driver = { .name = "iio_hwmon", .owner = THIS_MODULE, + .of_match_table = iio_hwmon_of_match, }, .probe = iio_hwmon_probe, .remove = iio_hwmon_remove, |
