-enum adis16201_chan {
- in_supply,
- temp,
- accel_x,
- accel_y,
- incli_x,
- incli_y,
- in_aux,
-};
-
-/**
- * adis16201_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 adis16201_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16201_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16201_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio device associated with child of actual device
- * @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
- **/
-static int adis16201_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16201_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16201_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16201_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio device associated with child of actual device
- * @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
- **/
-static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16201_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 20,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 20,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16201_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static int adis16201_reset(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16201_state *st = iio_priv(indio_dev);
-
- ret = adis16201_spi_write_reg_8(indio_dev,
- ADIS16201_GLOB_CMD,
- ADIS16201_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&st->us->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16201_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret = 0;
- u16 msc;
-
- ret = adis16201_spi_read_reg_16(indio_dev, ADIS16201_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16201_MSC_CTRL_ACTIVE_HIGH;
- msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_DIO1;
- if (enable)
- msc |= ADIS16201_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16201_spi_write_reg_16(indio_dev, ADIS16201_MSC_CTRL, msc);
-
-error_ret:
- return ret;
-}
-
-static int adis16201_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
-
- ret = adis16201_spi_read_reg_16(indio_dev,
- ADIS16201_DIAG_STAT, &status);
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status & 0xF;
- if (ret)
- ret = -EFAULT;
-
- if (status & ADIS16201_DIAG_STAT_SPI_FAIL)
- dev_err(&indio_dev->dev, "SPI failure\n");
- if (status & ADIS16201_DIAG_STAT_FLASH_UPT)
- dev_err(&indio_dev->dev, "Flash update failed\n");
- if (status & ADIS16201_DIAG_STAT_POWER_HIGH)
- dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
- if (status & ADIS16201_DIAG_STAT_POWER_LOW)
- dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16201_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16201_spi_write_reg_16(indio_dev,
- ADIS16201_MSC_CTRL,
- ADIS16201_MSC_CTRL_SELF_TEST_EN);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- ret = adis16201_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16201_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
- struct device *dev = &indio_dev->dev;
-
- /* Disable IRQ */
- ret = adis16201_set_irq(indio_dev, false);
- if (ret) {
- dev_err(dev, "disable irq failed");
- goto err_ret;
- }
-
- /* Do self test */
- ret = adis16201_self_test(indio_dev);
- if (ret) {
- dev_err(dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16201_check_status(indio_dev);
- if (ret) {
- adis16201_reset(indio_dev);
- dev_err(dev, "device not playing ball -> reset");
- msleep(ADIS16201_STARTUP_DELAY);
- ret = adis16201_check_status(indio_dev);
- if (ret) {
- dev_err(dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
-static u8 adis16201_addresses[7][2] = {
- [in_supply] = { ADIS16201_SUPPLY_OUT, },
- [temp] = { ADIS16201_TEMP_OUT },
- [accel_x] = { ADIS16201_XACCL_OUT, ADIS16201_XACCL_OFFS },
- [accel_y] = { ADIS16201_YACCL_OUT, ADIS16201_YACCL_OFFS },
- [in_aux] = { ADIS16201_AUX_ADC },
- [incli_x] = { ADIS16201_XINCL_OUT },
- [incli_y] = { ADIS16201_YINCL_OUT },