diff options
Diffstat (limited to 'drivers/iio/gyro')
-rw-r--r-- | drivers/iio/gyro/Kconfig | 18 | ||||
-rw-r--r-- | drivers/iio/gyro/Makefile | 2 | ||||
-rw-r--r-- | drivers/iio/gyro/adis16080.c | 21 | ||||
-rw-r--r-- | drivers/iio/gyro/adis16130.c | 23 | ||||
-rw-r--r-- | drivers/iio/gyro/adis16136.c | 10 | ||||
-rw-r--r-- | drivers/iio/gyro/adis16260.c | 422 | ||||
-rw-r--r-- | drivers/iio/gyro/adxrs450.c | 15 | ||||
-rw-r--r-- | drivers/iio/gyro/hid-sensor-gyro-3d.c | 41 | ||||
-rw-r--r-- | drivers/iio/gyro/itg3200_core.c | 15 | ||||
-rw-r--r-- | drivers/iio/gyro/st_gyro.h | 11 | ||||
-rw-r--r-- | drivers/iio/gyro/st_gyro_core.c | 14 | ||||
-rw-r--r-- | drivers/iio/gyro/st_gyro_i2c.c | 18 | ||||
-rw-r--r-- | drivers/iio/gyro/st_gyro_spi.c | 18 |
13 files changed, 504 insertions, 124 deletions
diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 8498e9dcda6..41c64a43bca 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig @@ -1,6 +1,8 @@ # # IIO Digital Gyroscope Sensor drivers configuration # +# When adding new entries keep the list in alphabetical order + menu "Digital gyroscope sensors" config ADIS16080 @@ -26,6 +28,18 @@ config ADIS16136 Say yes here to build support for the Analog Devices ADIS16133, ADIS16135, ADIS16136 gyroscope devices. +config ADIS16260 + tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver" + depends on SPI + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER + help + Say yes here to build support for Analog Devices ADIS16260 ADIS16265 + ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors. + + 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 @@ -58,8 +72,8 @@ config IIO_ST_GYRO_3AXIS Say yes here to build support for STMicroelectronics gyroscopes: L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330. - This driver can also be built as a module. If so, will be created - these modules: + This driver can also be built as a module. If so, these modules + will be created: - st_gyro (core functions for the driver [it is mandatory]); - st_gyro_i2c (necessary for the I2C devices [optional*]); - st_gyro_spi (necessary for the SPI devices [optional*]); diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile index e9dc034aa18..2f2752a4ea8 100644 --- a/drivers/iio/gyro/Makefile +++ b/drivers/iio/gyro/Makefile @@ -2,9 +2,11 @@ # Makefile for industrial I/O gyroscope sensor drivers # +# When adding new entries keep the list in alphabetical order obj-$(CONFIG_ADIS16080) += adis16080.o obj-$(CONFIG_ADIS16130) += adis16130.o obj-$(CONFIG_ADIS16136) += adis16136.o +obj-$(CONFIG_ADIS16260) += adis16260.o obj-$(CONFIG_ADXRS450) += adxrs450.o obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c index e1bb5f994a5..e9ec022ae22 100644 --- a/drivers/iio/gyro/adis16080.c +++ b/drivers/iio/gyro/adis16080.c @@ -192,16 +192,13 @@ static const struct adis16080_chip_info adis16080_chip_info[] = { static int adis16080_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); - int ret; struct adis16080_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; - } + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); @@ -217,22 +214,12 @@ static int adis16080_probe(struct spi_device *spi) indio_dev->info = &adis16080_info; indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(indio_dev); - if (ret) - goto error_free_dev; - return 0; - -error_free_dev: - iio_device_free(indio_dev); -error_ret: - return ret; + return iio_device_register(indio_dev); } static int adis16080_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - return 0; } diff --git a/drivers/iio/gyro/adis16130.c b/drivers/iio/gyro/adis16130.c index 129acdf801a..ac66fc18404 100644 --- a/drivers/iio/gyro/adis16130.c +++ b/drivers/iio/gyro/adis16130.c @@ -148,16 +148,13 @@ static const struct iio_info adis16130_info = { static int adis16130_probe(struct spi_device *spi) { - int ret; struct adis16130_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; - } + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); @@ -170,24 +167,12 @@ static int adis16130_probe(struct spi_device *spi) indio_dev->info = &adis16130_info; indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(indio_dev); - if (ret) - goto error_free_dev; - - return 0; - -error_free_dev: - iio_device_free(indio_dev); - -error_ret: - return ret; + return iio_device_register(indio_dev); } static int adis16130_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - return 0; } diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index 058e6d5c955..591bd555e1f 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -497,7 +497,7 @@ static int adis16136_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret; - indio_dev = iio_device_alloc(sizeof(*adis16136)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16136)); if (indio_dev == NULL) return -ENOMEM; @@ -515,11 +515,11 @@ static int adis16136_probe(struct spi_device *spi) ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data); if (ret) - goto error_free_dev; + return ret; ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); if (ret) - goto error_free_dev; + return ret; ret = adis16136_initial_setup(indio_dev); if (ret) @@ -537,8 +537,6 @@ error_stop_device: adis16136_stop_device(indio_dev); error_cleanup_buffer: adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); -error_free_dev: - iio_device_free(indio_dev); return ret; } @@ -552,8 +550,6 @@ static int adis16136_remove(struct spi_device *spi) adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); - iio_device_free(indio_dev); - return 0; } diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c new file mode 100644 index 00000000000..06541162fc0 --- /dev/null +++ b/drivers/iio/gyro/adis16260.c @@ -0,0 +1,422 @@ +/* + * ADIS16260/ADIS16265 Programmable Digital Gyroscope Sensor Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/interrupt.h> +#include <linux/mutex.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/spi/spi.h> +#include <linux/sysfs.h> +#include <linux/module.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> +#include <linux/iio/imu/adis.h> + +#define ADIS16260_STARTUP_DELAY 220 /* ms */ + +#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */ +#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */ +#define ADIS16260_AUX_ADC 0x0A /* analog input channel measurement */ +#define ADIS16260_TEMP_OUT 0x0C /* internal temperature measurement */ +#define ADIS16260_ANGL_OUT 0x0E /* angle displacement */ +#define ADIS16260_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */ +#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */ +#define ADIS16260_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */ +#define ADIS16260_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */ +#define ADIS16260_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */ +#define ADIS16260_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */ +#define ADIS16260_ALM_CTRL 0x28 /* Alarm control */ +#define ADIS16260_AUX_DAC 0x30 /* Auxiliary DAC data */ +#define ADIS16260_GPIO_CTRL 0x32 /* Control, digital I/O line */ +#define ADIS16260_MSC_CTRL 0x34 /* Control, data ready, self-test settings */ +#define ADIS16260_SMPL_PRD 0x36 /* Control, internal sample rate */ +#define ADIS16260_SENS_AVG 0x38 /* Control, dynamic range, filtering */ +#define ADIS16260_SLP_CNT 0x3A /* Control, sleep mode initiation */ +#define ADIS16260_DIAG_STAT 0x3C /* Diagnostic, error flags */ +#define ADIS16260_GLOB_CMD 0x3E /* Control, global commands */ +#define ADIS16260_LOT_ID1 0x52 /* Lot Identification Code 1 */ +#define ADIS16260_LOT_ID2 0x54 /* Lot Identification Code 2 */ +#define ADIS16260_PROD_ID 0x56 /* Product identifier; + * convert to decimal = 16,265/16,260 */ +#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */ + +#define ADIS16260_ERROR_ACTIVE (1<<14) +#define ADIS16260_NEW_DATA (1<<15) + +/* MSC_CTRL */ +#define ADIS16260_MSC_CTRL_MEM_TEST (1<<11) +/* Internal self-test enable */ +#define ADIS16260_MSC_CTRL_INT_SELF_TEST (1<<10) +#define ADIS16260_MSC_CTRL_NEG_SELF_TEST (1<<9) +#define ADIS16260_MSC_CTRL_POS_SELF_TEST (1<<8) +#define ADIS16260_MSC_CTRL_DATA_RDY_EN (1<<2) +#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1) +#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2 (1<<0) + +/* SMPL_PRD */ +/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */ +#define ADIS16260_SMPL_PRD_TIME_BASE (1<<7) +#define ADIS16260_SMPL_PRD_DIV_MASK 0x7F + +/* SLP_CNT */ +#define ADIS16260_SLP_CNT_POWER_OFF 0x80 + +/* DIAG_STAT */ +#define ADIS16260_DIAG_STAT_ALARM2 (1<<9) +#define ADIS16260_DIAG_STAT_ALARM1 (1<<8) +#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6 +#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5 +#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4 +#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3 +#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2 +#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1 +#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0 + +/* GLOB_CMD */ +#define ADIS16260_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16260_GLOB_CMD_FLASH_UPD (1<<3) +#define ADIS16260_GLOB_CMD_DAC_LATCH (1<<2) +#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1) +#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0) + +#define ADIS16260_SPI_SLOW (u32)(300 * 1000) +#define ADIS16260_SPI_BURST (u32)(1000 * 1000) +#define ADIS16260_SPI_FAST (u32)(2000 * 1000) + +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +#define ADIS16260_SCAN_GYRO 0 +#define ADIS16260_SCAN_SUPPLY 1 +#define ADIS16260_SCAN_AUX_ADC 2 +#define ADIS16260_SCAN_TEMP 3 +#define ADIS16260_SCAN_ANGL 4 + +static ssize_t adis16260_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis *adis = iio_priv(indio_dev); + int ret, len = 0; + u16 t; + int sps; + ret = adis_read_reg_16(adis, ADIS16260_SMPL_PRD, &t); + if (ret) + return ret; + + if (spi_get_device_id(adis->spi)->driver_data) /* If an adis16251 */ + sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256; + else + sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048; + sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1; + len = sprintf(buf, "%d\n", sps); + return len; +} + +static ssize_t adis16260_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis *adis = iio_priv(indio_dev); + unsigned int val; + int ret; + u8 t; + + ret = kstrtouint(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + if (spi_get_device_id(adis->spi)->driver_data) + t = 256 / val; + else + t = 2048 / val; + + if (t > ADIS16260_SMPL_PRD_DIV_MASK) + t = ADIS16260_SMPL_PRD_DIV_MASK; + else if (t > 0) + t--; + + if (t >= 0x0A) + adis->spi->max_speed_hz = ADIS16260_SPI_SLOW; + else + adis->spi->max_speed_hz = ADIS16260_SPI_FAST; + ret = adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t); + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +/* Power down the device */ +static int adis16260_stop_device(struct iio_dev *indio_dev) +{ + struct adis *adis = iio_priv(indio_dev); + int ret; + u16 val = ADIS16260_SLP_CNT_POWER_OFF; + + ret = adis_write_reg_16(adis, ADIS16260_SLP_CNT, val); + if (ret) + dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT"); + + return ret; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16260_read_frequency, + adis16260_write_frequency); + +static const struct iio_chan_spec adis16260_channels[] = { + ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_CALIBSCALE), 14), + ADIS_INCLI_CHAN(X, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), + ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), + ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), + ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12), + IIO_CHAN_SOFT_TIMESTAMP(5), +}; + +static const u8 adis16260_addresses[][2] = { + [ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE }, +}; + +static int adis16260_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct adis *adis = iio_priv(indio_dev); + int ret; + u8 addr; + s16 val16; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return adis_single_conversion(indio_dev, chan, + ADIS16260_ERROR_ACTIVE, val); + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + *val = 0; + if (spi_get_device_id(adis->spi)->driver_data) { + /* 0.01832 degree / sec */ + *val2 = IIO_DEGREE_TO_RAD(18320); + } else { + /* 0.07326 degree / sec */ + *val2 = IIO_DEGREE_TO_RAD(73260); + } + return IIO_VAL_INT_PLUS_MICRO; + case IIO_INCLI: + *val = 0; + *val2 = IIO_DEGREE_TO_RAD(36630); + return IIO_VAL_INT_PLUS_MICRO; + case IIO_VOLTAGE: + if (chan->channel == 0) { + *val = 1; + *val2 = 831500; /* 1.8315 mV */ + } else { + *val = 0; + *val2 = 610500; /* 610.5 uV */ + } + return IIO_VAL_INT_PLUS_MICRO; + case IIO_TEMP: + *val = 145; + *val2 = 300000; /* 0.1453 C */ + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + break; + case IIO_CHAN_INFO_OFFSET: + *val = 250000 / 1453; /* 25 C = 0x00 */ + return IIO_VAL_INT; + case IIO_CHAN_INFO_CALIBBIAS: + addr = adis16260_addresses[chan->scan_index][0]; + ret = adis_read_reg_16(adis, addr, &val16); + if (ret) + return ret; + + *val = sign_extend32(val16, 11); + return IIO_VAL_INT; + case IIO_CHAN_INFO_CALIBSCALE: + addr = adis16260_addresses[chan->scan_index][1]; + ret = adis_read_reg_16(adis, addr, &val16); + if (ret) + return ret; + + *val = val16; + return IIO_VAL_INT; + } + return -EINVAL; +} + +static int adis16260_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct adis *adis = iio_priv(indio_dev); + u8 addr; + + switch (mask) { + case IIO_CHAN_INFO_CALIBBIAS: + if (val < -2048 || val >= 2048) + return -EINVAL; + + addr = adis16260_addresses[chan->scan_index][0]; + return adis_write_reg_16(adis, addr, val); + case IIO_CHAN_INFO_CALIBSCALE: + if (val < 0 || val >= 4096) + return -EINVAL; + + addr = adis16260_addresses[chan->scan_index][1]; + return adis_write_reg_16(adis, addr, val); + } + return -EINVAL; +} + +static struct attribute *adis16260_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16260_attribute_group = { + .attrs = adis16260_attributes, +}; + +static const struct iio_info adis16260_info = { + .attrs = &adis16260_attribute_group, + .read_raw = &adis16260_read_raw, + .write_raw = &adis16260_write_raw, + .update_scan_mode = adis_update_scan_mode, + .driver_module = THIS_MODULE, +}; + +static const char * const adis1620_status_error_msgs[] = { + [ADIS16260_DIAG_STAT_FLASH_CHK_BIT] = "Flash checksum error", + [ADIS16260_DIAG_STAT_SELF_TEST_BIT] = "Self test error", + [ADIS16260_DIAG_STAT_OVERFLOW_BIT] = "Sensor overrange", + [ADIS16260_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16260_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16260_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 5.25", + [ADIS16260_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 4.75", +}; + +static const struct adis_data adis16260_data = { + .write_delay = 30, + .read_delay = 30, + .msc_ctrl_reg = ADIS16260_MSC_CTRL, + .glob_cmd_reg = ADIS16260_GLOB_CMD, + .diag_stat_reg = ADIS16260_DIAG_STAT, + + .self_test_mask = ADIS16260_MSC_CTRL_MEM_TEST, + .startup_delay = ADIS16260_STARTUP_DELAY, + + .status_error_msgs = adis1620_status_error_msgs, + .status_error_mask = BIT(ADIS16260_DIAG_STAT_FLASH_CHK_BIT) | + BIT(ADIS16260_DIAG_STAT_SELF_TEST_BIT) | + BIT(ADIS16260_DIAG_STAT_OVERFLOW_BIT) | + BIT(ADIS16260_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16260_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16260_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT), +}; + +static int adis16260_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct adis *adis; + int ret; + + /* setup the industrialio driver allocated elements */ + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis)); + if (!indio_dev) + return -ENOMEM; + adis = iio_priv(indio_dev); + /* this is only used for removal purposes */ + spi_set_drvdata(spi, indio_dev); + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16260_info; + indio_dev->channels = adis16260_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16260_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis_init(adis, indio_dev, spi, &adis16260_data); + if (ret) + return ret; + + ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL); + if (ret) + return ret; + + /* Get the device into a sane initial state */ + ret = adis_initial_startup(adis); + if (ret) + goto error_cleanup_buffer_trigger; + ret = iio_device_register(indio_dev); + if (ret) + goto error_cleanup_buffer_trigger; + + return 0; + +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(adis, indio_dev); + return ret; +} + +static int adis16260_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *adis = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + adis16260_stop_device(indio_dev); + adis_cleanup_buffer_and_trigger(adis, indio_dev); + + return 0; +} + +/* + * These parts do not need to be differentiated until someone adds + * support for the on chip filtering. + */ +static const struct spi_device_id adis16260_id[] = { + {"adis16260", 0}, + {"adis16265", 0}, + {"adis16250", 0}, + {"adis16255", 0}, + {"adis16251", 1}, + {} +}; +MODULE_DEVICE_TABLE(spi, adis16260_id); + +static struct spi_driver adis16260_driver = { + .driver = { + .name = "adis16260", + .owner = THIS_MODULE, + }, + .probe = adis16260_probe, + .remove = adis16260_remove, + .id_table = adis16260_id, +}; +module_spi_driver(adis16260_driver); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16260/5 Digital Gyroscope Sensor"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c index 8bd72b490b7..6dab2995f0f 100644 --- a/drivers/iio/gyro/adxrs450.c +++ b/drivers/iio/gyro/adxrs450.c @@ -426,11 +426,9 @@ static int adxrs450_probe(struct spi_device *spi) 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; - } + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; st = iio_priv(indio_dev); st->us = spi; mutex_init(&st->buf_lock); @@ -447,7 +445,7 @@ static int adxrs450_probe(struct spi_device *spi) ret = iio_device_register(indio_dev); if (ret) - goto error_free_dev; + return ret; /* Get the device into a sane initial state */ ret = adxrs450_initial_setup(indio_dev); @@ -456,17 +454,12 @@ static int adxrs450_probe(struct spi_device *spi) 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; } diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index bc943dd47da..c688d974d3e 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -30,10 +30,6 @@ #include <linux/iio/triggered_buffer.h> #include "../common/hid-sensors/hid-sensor-trigger.h" -/*Format: HID-SENSOR-usage_id_in_hex*/ -/*Usage ID from spec for Gyro-3D: 0x200076*/ -#define DRIVER_NAME "HID-SENSOR-200076" - enum gyro_3d_channel { CHANNEL_SCAN_INDEX_X, CHANNEL_SCAN_INDEX_Y, @@ -179,18 +175,10 @@ static int gyro_3d_write_raw(struct iio_dev *indio_dev, return ret; } -static int gyro_3d_write_raw_get_fmt(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - long mask) -{ - return IIO_VAL_INT_PLUS_MICRO; -} - static const struct iio_info gyro_3d_info = { .driver_module = THIS_MODULE, .read_raw = &gyro_3d_read_raw, .write_raw = &gyro_3d_write_raw, - .write_raw_get_fmt = &gyro_3d_write_raw_get_fmt, }; /* Function to push data to buffer */ @@ -286,11 +274,9 @@ static int hid_gyro_3d_probe(struct platform_device *pdev) struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; struct iio_chan_spec *channels; - indio_dev = iio_device_alloc(sizeof(struct gyro_3d_state)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*gyro_state)); + if (!indio_dev) + return -ENOMEM; platform_set_drvdata(pdev, indio_dev); gyro_state = iio_priv(indio_dev); @@ -302,15 +288,14 @@ static int hid_gyro_3d_probe(struct platform_device *pdev) &gyro_state->common_attributes); if (ret) { dev_err(&pdev->dev, "failed to setup common attributes\n"); - goto error_free_dev; + return ret; } channels = kmemdup(gyro_3d_channels, sizeof(gyro_3d_channels), GFP_KERNEL); if (!channels) { - ret = -ENOMEM; dev_err(&pdev->dev, "failed to duplicate channels\n"); - goto error_free_dev; + return -ENOMEM; } ret = gyro_3d_parse_report(pdev, hsdev, channels, @@ -367,9 +352,6 @@ error_unreg_buffer_funcs: iio_triggered_buffer_cleanup(indio_dev); error_free_dev_mem: kfree(indio_dev->channels); -error_free_dev: - iio_device_free(indio_dev); -error_ret: return ret; } @@ -384,14 +366,23 @@ static int hid_gyro_3d_remove(struct platform_device *pdev) hid_sensor_remove_trigger(indio_dev); iio_triggered_buffer_cleanup(indio_dev); kfree(indio_dev->channels); - iio_device_free(indio_dev); return 0; } +static struct platform_device_id hid_gyro_3d_ids[] = { + { + /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ + .name = "HID-SENSOR-200076", + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, hid_gyro_3d_ids); + static struct platform_driver hid_gyro_3d_platform_driver = { + .id_table = hid_gyro_3d_ids, .driver = { - .name = DRIVER_NAME, + .name = KBUILD_MODNAME, .owner = THIS_MODULE, }, .probe = hid_gyro_3d_probe, diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index d66605d2629..4d3f3b92b36 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -309,11 +309,9 @@ static int itg3200_probe(struct i2c_client *client, dev_dbg(&client->dev, "probe I2C dev with IRQ %i", client->irq); - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; st = iio_priv(indio_dev); @@ -330,7 +328,7 @@ static int itg3200_probe(struct i2c_client *client, ret = itg3200_buffer_configure(indio_dev); if (ret) - goto error_free_dev; + return ret; if (client->irq) { ret = itg3200_probe_trigger(indio_dev); @@ -353,9 +351,6 @@ error_remove_trigger: itg3200_remove_trigger(indio_dev); error_unconfigure_buffer: itg3200_buffer_unconfigure(indio_dev); -error_free_dev: - iio_device_free(indio_dev); -error_ret: return ret; } @@ -370,8 +365,6 @@ static int itg3200_remove(struct i2c_client *client) itg3200_buffer_unconfigure(indio_dev); - iio_device_free(indio_dev); - return 0; } diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h index 3ad9907bb15..f8f2bf84a5a 100644 --- a/drivers/iio/gyro/st_gyro.h +++ b/drivers/iio/gyro/st_gyro.h @@ -23,7 +23,16 @@ #define L3G4IS_GYRO_DEV_NAME "l3g4is_ui" #define LSM330_GYRO_DEV_NAME "lsm330_gyro" -int st_gyro_common_probe(struct iio_dev *indio_dev); +/** + * struct st_sensors_platform_data - gyro platform data + * @drdy_int_pin: DRDY on gyros is available only on INT2 pin. + */ +static const struct st_sensors_platform_data gyro_pdata = { + .drdy_int_pin = 2, +}; + +int st_gyro_common_probe(struct iio_dev *indio_dev, + struct st_sensors_platform_data *pdata); void st_gyro_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index f9ed3488c31..e13c2b0bf3d 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -60,7 +60,7 @@ #define ST_GYRO_1_BDU_ADDR 0x23 #define ST_GYRO_1_BDU_MASK 0x80 #define ST_GYRO_1_DRDY_IRQ_ADDR 0x22 -#define ST_GYRO_1_DRDY_IRQ_MASK 0x08 +#define ST_GYRO_1_DRDY_IRQ_INT2_MASK 0x08 #define ST_GYRO_1_MULTIREAD_BIT true /* CUSTOM VALUES FOR SENSOR 2 */ @@ -84,7 +84,7 @@ #define ST_GYRO_2_BDU_ADDR 0x23 #define ST_GYRO_2_BDU_MASK 0x80 #define ST_GYRO_2_DRDY_IRQ_ADDR 0x22 -#define ST_GYRO_2_DRDY_IRQ_MASK 0x08 +#define ST_GYRO_2_DRDY_IRQ_INT2_MASK 0x08 #define ST_GYRO_2_MULTIREAD_BIT true static const struct iio_chan_spec st_gyro_16bit_channels[] = { @@ -158,7 +158,7 @@ static const struct st_sensors st_gyro_sensors[] = { }, .drdy_irq = { .addr = ST_GYRO_1_DRDY_IRQ_ADDR, - .mask = ST_GYRO_1_DRDY_IRQ_MASK, + .mask_int2 = ST_GYRO_1_DRDY_IRQ_INT2_MASK, }, .multi_read_bit = ST_GYRO_1_MULTIREAD_BIT, .bootime = 2, @@ -221,7 +221,7 @@ static const struct st_sensors st_gyro_sensors[] = { }, .drdy_irq = { .addr = ST_GYRO_2_DRDY_IRQ_ADDR, - .mask = ST_GYRO_2_DRDY_IRQ_MASK, + .mask_int2 = ST_GYRO_2_DRDY_IRQ_INT2_MASK, }, .multi_read_bit = ST_GYRO_2_MULTIREAD_BIT, .bootime = 2, @@ -302,7 +302,8 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = { #define ST_GYRO_TRIGGER_OPS NULL #endif -int st_gyro_common_probe(struct iio_dev *indio_dev) +int st_gyro_common_probe(struct iio_dev *indio_dev, + struct st_sensors_platform_data *pdata) { int err; struct st_sensor_data *gdata = iio_priv(indio_dev); @@ -324,7 +325,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev) &gdata->sensor->fs.fs_avl[0]; gdata->odr = gdata->sensor->odr.odr_avl[0].hz; - err = st_sensors_init_sensor(indio_dev); + err = st_sensors_init_sensor(indio_dev, pdata); if (err < 0) goto st_gyro_common_probe_error; @@ -365,7 +366,6 @@ void st_gyro_common_remove(struct iio_dev *indio_dev) st_sensors_deallocate_trigger(indio_dev); st_gyro_deallocate_ring(indio_dev); } - iio_device_free(indio_dev); } EXPORT_SYMBOL(st_gyro_common_remove); diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 8a310500573..16b8b8d70bf 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -25,27 +25,21 @@ static int st_gyro_i2c_probe(struct i2c_client *client, struct st_sensor_data *gdata; int err; - indio_dev = iio_device_alloc(sizeof(*gdata)); - if (indio_dev == NULL) { - err = -ENOMEM; - goto iio_device_alloc_error; - } + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*gdata)); + if (!indio_dev) + return -ENOMEM; gdata = iio_priv(indio_dev); gdata->dev = &client->dev; st_sensors_i2c_configure(indio_dev, client, gdata); - err = st_gyro_common_probe(indio_dev); + err = st_gyro_common_probe(indio_dev, + (struct st_sensors_platform_data *)&gyro_pdata); if (err < 0) - goto st_gyro_common_probe_error; + return err; return 0; - -st_gyro_common_probe_error: - iio_device_free(indio_dev); -iio_device_alloc_error: - return err; } static int st_gyro_i2c_remove(struct i2c_client *client) diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index f3540390eb2..94763e25caf 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c @@ -24,27 +24,21 @@ static int st_gyro_spi_probe(struct spi_device *spi) struct st_sensor_data *gdata; int err; - indio_dev = iio_device_alloc(sizeof(*gdata)); - if (indio_dev == NULL) { - err = -ENOMEM; - goto iio_device_alloc_error; - } + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*gdata)); + if (!indio_dev) + return -ENOMEM; gdata = iio_priv(indio_dev); gdata->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, gdata); - err = st_gyro_common_probe(indio_dev); + err = st_gyro_common_probe(indio_dev, + (struct st_sensors_platform_data *)&gyro_pdata); if (err < 0) - goto st_gyro_common_probe_error; + return err; return 0; - -st_gyro_common_probe_error: - iio_device_free(indio_dev); -iio_device_alloc_error: - return err; } static int st_gyro_spi_remove(struct spi_device *spi) |