diff options
Diffstat (limited to 'drivers/iio/imu/adis.c')
-rw-r--r-- | drivers/iio/imu/adis.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index 494171844812..d160147cce0b 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -39,34 +39,29 @@ int __adis_write_reg(struct adis *adis, unsigned int reg, unsigned int value, struct spi_transfer xfers[] = { { .tx_buf = adis->tx, - .bits_per_word = 8, .len = 2, .cs_change = 1, .delay.value = adis->data->write_delay, .delay.unit = SPI_DELAY_UNIT_USECS, }, { .tx_buf = adis->tx + 2, - .bits_per_word = 8, .len = 2, .cs_change = 1, .delay.value = adis->data->write_delay, .delay.unit = SPI_DELAY_UNIT_USECS, }, { .tx_buf = adis->tx + 4, - .bits_per_word = 8, .len = 2, .cs_change = 1, .delay.value = adis->data->write_delay, .delay.unit = SPI_DELAY_UNIT_USECS, }, { .tx_buf = adis->tx + 6, - .bits_per_word = 8, .len = 2, .delay.value = adis->data->write_delay, .delay.unit = SPI_DELAY_UNIT_USECS, }, { .tx_buf = adis->tx + 8, - .bits_per_word = 8, .len = 2, .delay.value = adis->data->write_delay, .delay.unit = SPI_DELAY_UNIT_USECS, @@ -133,14 +128,12 @@ int __adis_read_reg(struct adis *adis, unsigned int reg, unsigned int *val, struct spi_transfer xfers[] = { { .tx_buf = adis->tx, - .bits_per_word = 8, .len = 2, .cs_change = 1, .delay.value = adis->data->write_delay, .delay.unit = SPI_DELAY_UNIT_USECS, }, { .tx_buf = adis->tx + 2, - .bits_per_word = 8, .len = 2, .cs_change = 1, .delay.value = adis->data->read_delay, @@ -148,14 +141,12 @@ int __adis_read_reg(struct adis *adis, unsigned int reg, unsigned int *val, }, { .tx_buf = adis->tx + 4, .rx_buf = adis->rx, - .bits_per_word = 8, .len = 2, .cs_change = 1, .delay.value = adis->data->read_delay, .delay.unit = SPI_DELAY_UNIT_USECS, }, { .rx_buf = adis->rx + 2, - .bits_per_word = 8, .len = 2, .delay.value = adis->data->read_delay, .delay.unit = SPI_DELAY_UNIT_USECS, @@ -223,13 +214,13 @@ int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask, int ret; u32 __val; - ret = __adis_read_reg(adis, reg, &__val, size); + ret = adis->ops->read(adis, reg, &__val, size); if (ret) return ret; __val = (__val & ~mask) | (val & mask); - return __adis_write_reg(adis, reg, __val, size); + return adis->ops->write(adis, reg, __val, size); } EXPORT_SYMBOL_NS_GPL(__adis_update_bits_base, "IIO_ADISLIB"); @@ -304,11 +295,20 @@ EXPORT_SYMBOL_NS(__adis_enable_irq, "IIO_ADISLIB"); */ int __adis_check_status(struct adis *adis) { - u16 status; + unsigned int status; + int diag_stat_bits; + u16 status_16 = 0; int ret; int i; - ret = __adis_read_reg_16(adis, adis->data->diag_stat_reg, &status); + if (adis->data->diag_stat_size) { + ret = adis->ops->read(adis, adis->data->diag_stat_reg, &status, + adis->data->diag_stat_size); + } else { + ret = __adis_read_reg_16(adis, adis->data->diag_stat_reg, + &status_16); + status = status_16; + } if (ret) return ret; @@ -317,7 +317,10 @@ int __adis_check_status(struct adis *adis) if (status == 0) return 0; - for (i = 0; i < 16; ++i) { + diag_stat_bits = BITS_PER_BYTE * (adis->data->diag_stat_size ? + adis->data->diag_stat_size : 2); + + for (i = 0; i < diag_stat_bits; ++i) { if (status & BIT(i)) { dev_err(&adis->spi->dev, "%s.\n", adis->data->status_error_msgs[i]); @@ -468,7 +471,7 @@ int adis_single_conversion(struct iio_dev *indio_dev, guard(mutex)(&adis->state_lock); - ret = __adis_read_reg(adis, chan->address, &uval, + ret = adis->ops->read(adis, chan->address, &uval, chan->scan_type.storagebits / 8); if (ret) return ret; @@ -488,6 +491,12 @@ int adis_single_conversion(struct iio_dev *indio_dev, } EXPORT_SYMBOL_NS_GPL(adis_single_conversion, "IIO_ADISLIB"); +static const struct adis_ops adis_default_ops = { + .read = __adis_read_reg, + .write = __adis_write_reg, + .reset = __adis_reset, +}; + /** * adis_init() - Initialize adis device structure * @adis: The adis device @@ -517,6 +526,11 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev, adis->spi = spi; adis->data = data; + if (!adis->ops->write && !adis->ops->read && !adis->ops->reset) + adis->ops = &adis_default_ops; + else if (!adis->ops->write || !adis->ops->read || !adis->ops->reset) + return -EINVAL; + iio_device_set_drvdata(indio_dev, adis); if (data->has_paging) { |