diff options
Diffstat (limited to 'drivers/staging/iio/imu/adis16400_core.c')
-rw-r--r-- | drivers/staging/iio/imu/adis16400_core.c | 653 |
1 files changed, 443 insertions, 210 deletions
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index a2c3b67dcbd..d082a37c4fb 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -16,7 +16,6 @@ #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/gpio.h> #include <linux/delay.h> #include <linux/mutex.h> #include <linux/device.h> @@ -25,21 +24,16 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "../ring_generic.h" -#include "../accel/accel.h" -#include "../adc/adc.h" -#include "../gyro/gyro.h" -#include "../magnetometer/magnet.h" - +#include "../buffer_generic.h" #include "adis16400.h" -#define DRIVER_NAME "adis16400" - enum adis16400_chip_variant { ADIS16300, + ADIS16334, ADIS16350, ADIS16360, ADIS16362, @@ -48,19 +42,12 @@ enum adis16400_chip_variant { ADIS16400, }; -static int adis16400_check_status(struct iio_dev *indio_dev); - -/* At the moment the spi framework doesn't allow global setting of cs_change. - * It's in the likely to be added comment at the top of spi.h. - * This means that use cannot be made of spi_write etc. - */ - /** * adis16400_spi_write_reg_8() - write single byte to a register * @dev: device associated with child of actual device (iio_dev or iio_trig) * @reg_address: the address of the register to be written * @val: the value to write - **/ + */ static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev, u8 reg_address, u8 val) @@ -84,7 +71,10 @@ static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev, * @reg_address: the address of the lower of the two registers. Second register * is assumed to have address one greater. * @val: value to be written - **/ + * + * At the moment the spi framework doesn't allow global setting of cs_change. + * This means that use cannot be made of spi_write. + */ static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev, u8 lower_reg_address, u16 value) @@ -126,6 +116,9 @@ static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev, * @reg_address: the address of the lower of the two registers. Second register * is assumed to have address one greater. * @val: somewhere to pass back the value read + * + * At the moment the spi framework doesn't allow global setting of cs_change. + * This means that use cannot be made of spi_read. **/ static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev, u8 lower_reg_address, @@ -150,8 +143,6 @@ static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev, mutex_lock(&st->buf_lock); st->tx[0] = ADIS16400_READ_REG(lower_reg_address); st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); @@ -240,23 +231,26 @@ static ssize_t adis16400_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool val; + int ret; - if (len < 1) - return -1; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16400_reset(indio_dev); + ret = strtobool(buf, &val); + if (ret < 0) + return ret; + if (val) { + ret = adis16400_reset(dev_get_drvdata(dev)); + if (ret < 0) + return ret; } - return -1; + + return len; } int adis16400_set_irq(struct iio_dev *indio_dev, bool enable) { int ret; u16 msc; + ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_MSC_CTRL, &msc); if (ret) goto error_ret; @@ -289,24 +283,6 @@ static int adis16400_stop_device(struct iio_dev *indio_dev) return ret; } -static int adis16400_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16400_spi_write_reg_16(indio_dev, - ADIS16400_MSC_CTRL, - ADIS16400_MSC_CTRL_MEM_TEST); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - msleep(ADIS16400_MTEST_DELAY); - adis16400_check_status(indio_dev); - -err_ret: - return ret; -} - static int adis16400_check_status(struct iio_dev *indio_dev) { u16 status; @@ -356,11 +332,28 @@ error_ret: return ret; } +static int adis16400_self_test(struct iio_dev *indio_dev) +{ + int ret; + ret = adis16400_spi_write_reg_16(indio_dev, + ADIS16400_MSC_CTRL, + ADIS16400_MSC_CTRL_MEM_TEST); + if (ret) { + dev_err(&indio_dev->dev, "problem starting self test"); + goto err_ret; + } + + msleep(ADIS16400_MTEST_DELAY); + adis16400_check_status(indio_dev); + +err_ret: + return ret; +} + static int adis16400_initial_setup(struct iio_dev *indio_dev) { int ret; u16 prod_id, smp_prd; - struct device *dev = &indio_dev->dev; struct adis16400_state *st = iio_priv(indio_dev); /* use low spi speed for init */ @@ -368,29 +361,26 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) st->us->mode = SPI_MODE_3; spi_setup(st->us); - /* Disable IRQ */ ret = adis16400_set_irq(indio_dev, false); if (ret) { - dev_err(dev, "disable irq failed"); + dev_err(&indio_dev->dev, "disable irq failed"); goto err_ret; } - /* Do self test */ ret = adis16400_self_test(indio_dev); if (ret) { - dev_err(dev, "self test failure"); + dev_err(&indio_dev->dev, "self test failure"); goto err_ret; } - /* Read status register to check the result */ ret = adis16400_check_status(indio_dev); if (ret) { adis16400_reset(indio_dev); - dev_err(dev, "device not playing ball -> reset"); + dev_err(&indio_dev->dev, "device not playing ball -> reset"); msleep(ADIS16400_STARTUP_DELAY); ret = adis16400_check_status(indio_dev); if (ret) { - dev_err(dev, "giving up"); + dev_err(&indio_dev->dev, "giving up"); goto err_ret; } } @@ -401,10 +391,11 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) goto err_ret; if ((prod_id & 0xF000) != st->variant->product_id) - dev_warn(dev, "incorrect id"); + dev_warn(&indio_dev->dev, "incorrect id"); - printk(KERN_INFO DRIVER_NAME ": prod_id 0x%04x at CS%d (irq %d)\n", - prod_id, st->us->chip_select, st->us->irq); + dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n", + indio_dev->name, prod_id, + st->us->chip_select, st->us->irq); } /* use high spi speed if possible */ ret = adis16400_spi_read_reg_16(indio_dev, @@ -414,15 +405,13 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) spi_setup(st->us); } - err_ret: - return ret; } static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, - adis16400_read_frequency, - adis16400_write_frequency); + adis16400_read_frequency, + adis16400_write_frequency); static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0); @@ -447,23 +436,23 @@ enum adis16400_chan { }; static u8 adis16400_addresses[17][2] = { - [in_supply] = { ADIS16400_SUPPLY_OUT, 0 }, + [in_supply] = { ADIS16400_SUPPLY_OUT }, [gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF }, [gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF }, [gyro_z] = { ADIS16400_ZGYRO_OUT, ADIS16400_ZGYRO_OFF }, [accel_x] = { ADIS16400_XACCL_OUT, ADIS16400_XACCL_OFF }, [accel_y] = { ADIS16400_YACCL_OUT, ADIS16400_YACCL_OFF }, [accel_z] = { ADIS16400_ZACCL_OUT, ADIS16400_ZACCL_OFF }, - [magn_x] = { ADIS16400_XMAGN_OUT, 0 }, - [magn_y] = { ADIS16400_YMAGN_OUT, 0 }, - [magn_z] = { ADIS16400_ZMAGN_OUT, 0 }, - [temp] = { ADIS16400_TEMP_OUT, 0 }, + [magn_x] = { ADIS16400_XMAGN_OUT }, + [magn_y] = { ADIS16400_YMAGN_OUT }, + [magn_z] = { ADIS16400_ZMAGN_OUT }, + [temp] = { ADIS16400_TEMP_OUT }, [temp0] = { ADIS16350_XTEMP_OUT }, [temp1] = { ADIS16350_YTEMP_OUT }, [temp2] = { ADIS16350_ZTEMP_OUT }, - [in1] = { ADIS16400_AUX_ADC, 0 }, - [incli_x] = { ADIS16300_PITCH_OUT, 0 }, - [incli_y] = { ADIS16300_ROLL_OUT, 0 } + [in1] = { ADIS16400_AUX_ADC }, + [incli_x] = { ADIS16300_PITCH_OUT }, + [incli_y] = { ADIS16300_ROLL_OUT } }; static int adis16400_write_raw(struct iio_dev *indio_dev, @@ -473,6 +462,7 @@ static int adis16400_write_raw(struct iio_dev *indio_dev, long mask) { int ret; + switch (mask) { case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE): mutex_lock(&indio_dev->mlock); @@ -493,9 +483,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, long mask) { struct adis16400_state *st = iio_priv(indio_dev); - int ret; + int ret, shift; s16 val16; - int shift; switch (mask) { case 0: @@ -518,11 +507,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, case (1 << IIO_CHAN_INFO_SCALE_SHARED): case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): switch (chan->type) { - case IIO_GYRO: + case IIO_ANGL_VEL: *val = 0; *val2 = st->variant->gyro_scale_micro; return IIO_VAL_INT_PLUS_MICRO; - case IIO_IN: + case IIO_VOLTAGE: *val = 0; if (chan->channel == 0) *val2 = 2418; @@ -566,135 +555,371 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16400_channels[] = { - IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - in_supply, ADIS16400_SCAN_SUPPLY, - IIO_ST('u', 14, 16, 0), 0), - IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - magn_x, ADIS16400_SCAN_MAGN_X, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Y, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - magn_y, ADIS16400_SCAN_MAGN_Y, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Z, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - magn_z, ADIS16400_SCAN_MAGN_Z, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - temp, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0), - IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - in1, ADIS16400_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in_supply, + .scan_index = ADIS16400_SCAN_SUPPLY, + .scan_type = IIO_ST('u', 14, 16, 0) + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_x, + .scan_index = ADIS16400_SCAN_GYRO_X, + .scan_type = IIO_ST('s', 14, 16, 0) + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_y, + .scan_index = ADIS16400_SCAN_GYRO_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_z, + .scan_index = ADIS16400_SCAN_GYRO_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_x, + .scan_index = ADIS16400_SCAN_ACC_X, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_y, + .scan_index = ADIS16400_SCAN_ACC_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_z, + .scan_index = ADIS16400_SCAN_ACC_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_MAGN, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = magn_x, + .scan_index = ADIS16400_SCAN_MAGN_X, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_MAGN, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = magn_y, + .scan_index = ADIS16400_SCAN_MAGN_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_MAGN, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = magn_z, + .scan_index = ADIS16400_SCAN_MAGN_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = temp, + .scan_index = ADIS16400_SCAN_TEMP, + .scan_type = IIO_ST('s', 12, 16, 0), + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in1, + .scan_index = ADIS16400_SCAN_ADC_0, + .scan_type = IIO_ST('s', 12, 16, 0), + }, IIO_CHAN_SOFT_TIMESTAMP(12) }; static struct iio_chan_spec adis16350_channels[] = { - IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - in_supply, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, "x", 0, 0, - (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - temp0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, "y", 1, 0, - (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - temp1, ADIS16350_SCAN_TEMP_Y, IIO_ST('s', 12, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, "z", 2, 0, - (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - temp2, ADIS16350_SCAN_TEMP_Z, IIO_ST('s', 12, 16, 0), 0), - IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - in1, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in_supply, + .scan_index = ADIS16400_SCAN_SUPPLY, + .scan_type = IIO_ST('u', 12, 16, 0) + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_x, + .scan_index = ADIS16400_SCAN_GYRO_X, + .scan_type = IIO_ST('s', 14, 16, 0) + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_y, + .scan_index = ADIS16400_SCAN_GYRO_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_z, + .scan_index = ADIS16400_SCAN_GYRO_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_x, + .scan_index = ADIS16400_SCAN_ACC_X, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_y, + .scan_index = ADIS16400_SCAN_ACC_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_z, + .scan_index = ADIS16400_SCAN_ACC_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .extend_name = "x", + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = temp0, + .scan_index = ADIS16350_SCAN_TEMP_X, + .scan_type = IIO_ST('s', 12, 16, 0), + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 1, + .extend_name = "y", + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = temp1, + .scan_index = ADIS16350_SCAN_TEMP_Y, + .scan_type = IIO_ST('s', 12, 16, 0), + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 2, + .extend_name = "z", + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = temp2, + .scan_index = ADIS16350_SCAN_TEMP_Z, + .scan_type = IIO_ST('s', 12, 16, 0), + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in1, + .scan_index = ADIS16350_SCAN_ADC_0, + .scan_type = IIO_ST('s', 12, 16, 0), + }, IIO_CHAN_SOFT_TIMESTAMP(11) }; static struct iio_chan_spec adis16300_channels[] = { - IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - in_supply, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SHARED), - accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - temp, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0), - IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - in1, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - incli_x, ADIS16300_SCAN_INCLI_X, IIO_ST('s', 13, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - incli_y, ADIS16300_SCAN_INCLI_Y, IIO_ST('s', 13, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in_supply, + .scan_index = ADIS16400_SCAN_SUPPLY, + .scan_type = IIO_ST('u', 12, 16, 0) + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_x, + .scan_index = ADIS16400_SCAN_GYRO_X, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_x, + .scan_index = ADIS16400_SCAN_ACC_X, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_y, + .scan_index = ADIS16400_SCAN_ACC_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_z, + .scan_index = ADIS16400_SCAN_ACC_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = temp, + .scan_index = ADIS16400_SCAN_TEMP, + .scan_type = IIO_ST('s', 12, 16, 0), + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in1, + .scan_index = ADIS16350_SCAN_ADC_0, + .scan_type = IIO_ST('s', 12, 16, 0), + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = incli_x, + .scan_index = ADIS16300_SCAN_INCLI_X, + .scan_type = IIO_ST('s', 13, 16, 0), + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = incli_y, + .scan_index = ADIS16300_SCAN_INCLI_Y, + .scan_type = IIO_ST('s', 13, 16, 0), + }, IIO_CHAN_SOFT_TIMESTAMP(14) }; +static const struct iio_chan_spec adis16334_channels[] = { + { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_x, + .scan_index = ADIS16400_SCAN_GYRO_X, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_y, + .scan_index = ADIS16400_SCAN_GYRO_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = gyro_z, + .scan_index = ADIS16400_SCAN_GYRO_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_x, + .scan_index = ADIS16400_SCAN_ACC_X, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_y, + .scan_index = ADIS16400_SCAN_ACC_Y, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_z, + .scan_index = ADIS16400_SCAN_ACC_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + .address = accel_z, + .scan_index = ADIS16400_SCAN_ACC_Z, + .scan_type = IIO_ST('s', 14, 16, 0), + }, + IIO_CHAN_SOFT_TIMESTAMP(12) +}; + static struct attribute *adis16400_attributes[] = { &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr, @@ -719,6 +944,16 @@ static struct adis16400_chip_info adis16400_chips[] = { (1 << ADIS16300_SCAN_INCLI_X) | (1 << ADIS16300_SCAN_INCLI_Y) | (1 << 14), }, + [ADIS16334] = { + .channels = adis16334_channels, + .num_channels = ARRAY_SIZE(adis16334_channels), + .gyro_scale_micro = 873, + .accel_scale_micro = 981, + .default_scan_mask = (1 << ADIS16400_SCAN_GYRO_X) | + (1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) | + (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) | + (1 << ADIS16400_SCAN_ACC_Z), + }, [ADIS16350] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), @@ -783,7 +1018,7 @@ static const struct iio_info adis16400_info = { static int __devinit adis16400_probe(struct spi_device *spi) { - int ret, regdone = 0; + int ret; struct adis16400_state *st; struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); if (indio_dev == NULL) { @@ -810,20 +1045,15 @@ static int __devinit adis16400_probe(struct spi_device *spi) if (ret) goto error_free_dev; - ret = iio_device_register(indio_dev); - if (ret) - goto error_unreg_ring_funcs; - regdone = 1; - - ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, - st->variant->channels, - st->variant->num_channels); + ret = iio_buffer_register(indio_dev, + st->variant->channels, + st->variant->num_channels); if (ret) { dev_err(&spi->dev, "failed to initialize the ring\n"); goto error_unreg_ring_funcs; } - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { + if (spi->irq) { ret = adis16400_probe_trigger(indio_dev); if (ret) goto error_uninitialize_ring; @@ -833,20 +1063,21 @@ static int __devinit adis16400_probe(struct spi_device *spi) ret = adis16400_initial_setup(indio_dev); if (ret) goto error_remove_trigger; + ret = iio_device_register(indio_dev); + if (ret) + goto error_remove_trigger; + return 0; error_remove_trigger: - if (indio_dev->modes & INDIO_RING_TRIGGERED) + if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) adis16400_remove_trigger(indio_dev); error_uninitialize_ring: - iio_ring_buffer_unregister(indio_dev->ring); + iio_buffer_unregister(indio_dev); error_unreg_ring_funcs: adis16400_unconfigure_ring(indio_dev); error_free_dev: - if (regdone) - iio_device_unregister(indio_dev); - else - iio_free_device(indio_dev); + iio_free_device(indio_dev); error_ret: return ret; } @@ -857,14 +1088,15 @@ static int adis16400_remove(struct spi_device *spi) int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); + iio_device_unregister(indio_dev); ret = adis16400_stop_device(indio_dev); if (ret) goto err_ret; adis16400_remove_trigger(indio_dev); - iio_ring_buffer_unregister(indio_dev->ring); + iio_buffer_unregister(indio_dev); adis16400_unconfigure_ring(indio_dev); - iio_device_unregister(indio_dev); + iio_free_device(indio_dev); return 0; @@ -874,6 +1106,7 @@ err_ret: static const struct spi_device_id adis16400_id[] = { {"adis16300", ADIS16300}, + {"adis16334", ADIS16334}, {"adis16350", ADIS16350}, {"adis16354", ADIS16350}, {"adis16355", ADIS16350}, |