^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Common library for ADIS16XXX devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2012 Analog Devices Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Lars-Peter Clausen <lars@metafoo.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/imu/adis.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ADIS_GLOB_CMD_SW_RESET BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * __adis_write_reg() - write N bytes to register (unlocked version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @reg: The address of the lower of the two registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @value: The value to write to device (up to 4 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @size: The size of the @value (in bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int __adis_write_reg(struct adis *adis, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned int value, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned int page = reg / ADIS_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct spi_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct spi_transfer xfers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .tx_buf = adis->tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .delay.value = adis->data->write_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .cs_change_delay.value = adis->data->cs_change_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .tx_buf = adis->tx + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .delay.value = adis->data->write_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .cs_change_delay.value = adis->data->cs_change_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .tx_buf = adis->tx + 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .delay.value = adis->data->write_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .cs_change_delay.value = adis->data->cs_change_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .tx_buf = adis->tx + 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .delay.value = adis->data->write_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .tx_buf = adis->tx + 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .delay.value = adis->data->write_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) spi_message_init(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (adis->current_page != page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) adis->tx[1] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) spi_message_add_tail(&xfers[0], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) adis->tx[8] = ADIS_WRITE_REG(reg + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) adis->tx[9] = (value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) adis->tx[6] = ADIS_WRITE_REG(reg + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) adis->tx[7] = (value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) adis->tx[4] = ADIS_WRITE_REG(reg + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) adis->tx[5] = (value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) adis->tx[2] = ADIS_WRITE_REG(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) adis->tx[3] = value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) xfers[size].cs_change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) for (i = 1; i <= size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spi_message_add_tail(&xfers[i], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ret = spi_sync(adis->spi, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) adis->current_page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) EXPORT_SYMBOL_GPL(__adis_write_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * __adis_read_reg() - read N bytes from register (unlocked version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @reg: The address of the lower of the two registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @val: The value read back from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @size: The size of the @val buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int __adis_read_reg(struct adis *adis, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int *val, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned int page = reg / ADIS_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct spi_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct spi_transfer xfers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .tx_buf = adis->tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .delay.value = adis->data->write_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .cs_change_delay.value = adis->data->cs_change_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .tx_buf = adis->tx + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .delay.value = adis->data->read_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .cs_change_delay.value = adis->data->cs_change_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .tx_buf = adis->tx + 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .rx_buf = adis->rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .delay.value = adis->data->read_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .cs_change_delay.value = adis->data->cs_change_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .rx_buf = adis->rx + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .bits_per_word = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .delay.value = adis->data->read_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .delay.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) spi_message_init(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (adis->current_page != page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) adis->tx[1] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) spi_message_add_tail(&xfers[0], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) adis->tx[2] = ADIS_READ_REG(reg + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) adis->tx[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) spi_message_add_tail(&xfers[1], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) adis->tx[4] = ADIS_READ_REG(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) adis->tx[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) spi_message_add_tail(&xfers[2], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) spi_message_add_tail(&xfers[3], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = spi_sync(adis->spi, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) adis->current_page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) *val = get_unaligned_be32(adis->rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *val = get_unaligned_be16(adis->rx + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) EXPORT_SYMBOL_GPL(__adis_read_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * __adis_update_bits_base() - ADIS Update bits function - Unlocked version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @reg: The address of the lower of the two registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @mask: Bitmask to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * @val: Value to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @size: Size of the register to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Updates the desired bits of @reg in accordance with @mask and @val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) const u32 val, u8 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 __val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ret = __adis_read_reg(adis, reg, &__val, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) __val = (__val & ~mask) | (val & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return __adis_write_reg(adis, reg, __val, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) EXPORT_SYMBOL_GPL(__adis_update_bits_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int adis_debugfs_reg_access(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) unsigned int reg, unsigned int writeval, unsigned int *readval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct adis *adis = iio_device_get_drvdata(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (readval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) uint16_t val16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = adis_read_reg_16(adis, reg, &val16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *readval = val16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return adis_write_reg_16(adis, reg, writeval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) EXPORT_SYMBOL(adis_debugfs_reg_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * adis_enable_irq() - Enable or disable data ready IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @enable: Whether to enable the IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * Returns 0 on success, negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int adis_enable_irq(struct adis *adis, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) uint16_t msc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) mutex_lock(&adis->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (adis->data->enable_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ret = adis->data->enable_irq(adis, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) mutex_unlock(&adis->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) EXPORT_SYMBOL(adis_enable_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * __adis_check_status() - Check the device for error conditions (unlocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * Returns 0 on success, a negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int __adis_check_status(struct adis *adis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) uint16_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ret = __adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) status &= adis->data->status_error_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) for (i = 0; i < 16; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (status & BIT(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) dev_err(&adis->spi->dev, "%s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) adis->data->status_error_msgs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) EXPORT_SYMBOL_GPL(__adis_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * __adis_reset() - Reset the device (unlocked version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * Returns 0 on success, a negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int __adis_reset(struct adis *adis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) const struct adis_timeout *timeouts = adis->data->timeouts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = __adis_write_reg_8(adis, adis->data->glob_cmd_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ADIS_GLOB_CMD_SW_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) msleep(timeouts->sw_reset_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) EXPORT_SYMBOL_GPL(__adis_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int adis_self_test(struct adis *adis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) const struct adis_timeout *timeouts = adis->data->timeouts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = __adis_write_reg_16(adis, adis->data->self_test_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) adis->data->self_test_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) msleep(timeouts->self_test_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = __adis_check_status(adis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (adis->data->self_test_no_autoclear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) __adis_write_reg_16(adis, adis->data->self_test_reg, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * __adis_initial_startup() - Device initial setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * The function performs a HW reset via a reset pin that should be specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * via GPIOLIB. If no pin is configured a SW reset will be performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * The RST pin for the ADIS devices should be configured as ACTIVE_LOW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * After the self-test operation is performed, the function will also check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * that the product ID is as expected. This assumes that drivers providing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * 'prod_id_reg' will also provide the 'prod_id'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Returns 0 if the device is operational, a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * This function should be called early on in the device initialization sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * to ensure that the device is in a sane and known state and that it is usable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) int __adis_initial_startup(struct adis *adis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) const struct adis_timeout *timeouts = adis->data->timeouts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct gpio_desc *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) uint16_t prod_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* check if the device has rst pin low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (IS_ERR(gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return PTR_ERR(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* bring device out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) gpiod_set_value_cansleep(gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) msleep(timeouts->reset_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = __adis_reset(adis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ret = adis_self_test(adis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) adis_enable_irq(adis, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!adis->data->prod_id_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = adis_read_reg_16(adis, adis->data->prod_id_reg, &prod_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (prod_id != adis->data->prod_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dev_warn(&adis->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) "Device ID(%u) and product ID(%u) do not match.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) adis->data->prod_id, prod_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) EXPORT_SYMBOL_GPL(__adis_initial_startup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * adis_single_conversion() - Performs a single sample conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @indio_dev: The IIO device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * @chan: The IIO channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * @error_mask: Mask for the error bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * @val: Result of the conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Returns IIO_VAL_INT on success, a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * The function performs a single conversion on a given channel and post
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * processes the value accordingly to the channel spec. If a error_mask is given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * the function will check if the mask is set in the returned raw value. If it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * is set the function will perform a self-check. If the device does not report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * a error bit in the channels raw value set error_mask to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int adis_single_conversion(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct adis *adis = iio_device_get_drvdata(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unsigned int uval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mutex_lock(&adis->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ret = __adis_read_reg(adis, chan->address, &uval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) chan->scan_type.storagebits / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (uval & error_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = __adis_check_status(adis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (chan->scan_type.sign == 's')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) *val = sign_extend32(uval, chan->scan_type.realbits - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) *val = uval & ((1 << chan->scan_type.realbits) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) mutex_unlock(&adis->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) EXPORT_SYMBOL_GPL(adis_single_conversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * adis_init() - Initialize adis device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * @adis: The adis device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * @indio_dev: The iio device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * @spi: The spi device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * @data: Chip specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * Returns 0 on success, a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * This function must be called, before any other adis helper function may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int adis_init(struct adis *adis, struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct spi_device *spi, const struct adis_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!data || !data->timeouts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) dev_err(&spi->dev, "No config data or timeouts not defined!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) mutex_init(&adis->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) adis->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) adis->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) iio_device_set_drvdata(indio_dev, adis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (data->has_paging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* Need to set the page before first read/write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) adis->current_page = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* Page will always be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) adis->current_page = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) EXPORT_SYMBOL_GPL(adis_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");