[PATCH 06/11] staging:iio:adis16220: Use adis library

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use the new adis library for the adis16220 driver. The adis16220 driver is a bit
special and so we can only make use of the generic register access and control
functions for now.

Signed-off-by: Lars-Peter Clausen <lars@xxxxxxxxxx>
---
 drivers/staging/iio/accel/adis16220.h      |  20 +--
 drivers/staging/iio/accel/adis16220_core.c | 280 ++++++-----------------------
 2 files changed, 60 insertions(+), 240 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h
index 024313c..7cc4d2f 100644
--- a/drivers/staging/iio/accel/adis16220.h
+++ b/drivers/staging/iio/accel/adis16220.h
@@ -1,10 +1,9 @@
 #ifndef SPI_ADIS16220_H_
 #define SPI_ADIS16220_H_
 
-#define ADIS16220_STARTUP_DELAY	220 /* ms */
+#include "../imu/adis.h"
 
-#define ADIS16220_READ_REG(a)    a
-#define ADIS16220_WRITE_REG(a) ((a) | 0x80)
+#define ADIS16220_STARTUP_DELAY	220 /* ms */
 
 /* Flash memory write count */
 #define ADIS16220_FLASH_CNT     0x00
@@ -102,15 +101,15 @@
 #define ADIS16220_DIAG_STAT_FLASH_CHK	(1<<6)
 #define ADIS16220_DIAG_STAT_SELF_TEST	(1<<5)
 /* Capture period violation/interruption */
-#define ADIS16220_DIAG_STAT_VIOLATION	(1<<4)
+#define ADIS16220_DIAG_STAT_VIOLATION_BIT	4
 /* SPI communications failure */
-#define ADIS16220_DIAG_STAT_SPI_FAIL	(1<<3)
+#define ADIS16220_DIAG_STAT_SPI_FAIL_BIT	3
 /* Flash update failure */
-#define ADIS16220_DIAG_STAT_FLASH_UPT	(1<<2)
+#define ADIS16220_DIAG_STAT_FLASH_UPT_BIT	2
 /* Power supply above 3.625 V */
-#define ADIS16220_DIAG_STAT_POWER_HIGH	(1<<1)
+#define ADIS16220_DIAG_STAT_POWER_HIGH_BIT	1
 /* Power supply below 3.15 V */
-#define ADIS16220_DIAG_STAT_POWER_LOW	(1<<0)
+#define ADIS16220_DIAG_STAT_POWER_LOW_BIT	0
 
 /* GLOB_CMD */
 #define ADIS16220_GLOB_CMD_SW_RESET	(1<<7)
@@ -125,13 +124,14 @@
 
 /**
  * struct adis16220_state - device instance specific data
- * @us:			actual spi_device
+ * @adis:		adis device
  * @tx:			transmit buffer
  * @rx:			receive buffer
  * @buf_lock:		mutex to protect tx and rx
  **/
 struct adis16220_state {
-	struct spi_device	*us;
+	struct adis adis;
+
 	struct mutex		buf_lock;
 	u8			tx[ADIS16220_MAX_TX] ____cacheline_aligned;
 	u8			rx[ADIS16220_MAX_RX];
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index 22807ac..c39ce62 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -20,136 +20,19 @@
 
 #include "adis16220.h"
 
-/**
- * adis16220_spi_write_reg_8() - write single byte to a register
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16220_spi_write_reg_8(struct iio_dev *indio_dev,
-		u8 reg_address,
-		u8 val)
-{
-	int ret;
-	struct adis16220_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16220_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	ret = spi_write(st->us, st->tx, 2);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16220_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 adis16220_spi_write_reg_16(struct iio_dev *indio_dev,
-		u8 lower_reg_address,
-		u16 value)
-{
-	int ret;
-	struct spi_message msg;
-	struct adis16220_state *st = iio_priv(indio_dev);
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		}, {
-			.tx_buf = st->tx + 2,
-			.bits_per_word = 8,
-			.len = 2,
-			.delay_usecs = 35,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16220_WRITE_REG(lower_reg_address);
-	st->tx[1] = value & 0xFF;
-	st->tx[2] = ADIS16220_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;
-}
-
-/**
- * adis16220_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 adis16220_spi_read_reg_16(struct iio_dev *indio_dev,
-				     u8 lower_reg_address,
-				     u16 *val)
-{
-	struct spi_message msg;
-	struct adis16220_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 = 35,
-		}, {
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16220_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 ssize_t adis16220_read_16bit(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct adis16220_state *st = iio_priv(indio_dev);
 	ssize_t ret;
 	s16 val = 0;
 
 	/* Take the iio_dev status lock */
 	mutex_lock(&indio_dev->mlock);
-	ret = adis16220_spi_read_reg_16(indio_dev, this_attr->address,
+	ret = adis_read_reg_16(&st->adis, this_attr->address,
 					(u16 *)&val);
 	mutex_unlock(&indio_dev->mlock);
 	if (ret)
@@ -164,13 +47,14 @@ static ssize_t adis16220_write_16bit(struct device *dev,
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct adis16220_state *st = iio_priv(indio_dev);
 	int ret;
 	u16 val;
 
 	ret = kstrtou16(buf, 10, &val);
 	if (ret)
 		goto error_ret;
-	ret = adis16220_spi_write_reg_16(indio_dev, this_attr->address, val);
+	ret = adis_write_reg_16(&st->adis, this_attr->address, val);
 
 error_ret:
 	return ret ? ret : len;
@@ -178,10 +62,11 @@ error_ret:
 
 static int adis16220_capture(struct iio_dev *indio_dev)
 {
+	struct adis16220_state *st = iio_priv(indio_dev);
 	int ret;
-	ret = adis16220_spi_write_reg_16(indio_dev,
-			ADIS16220_GLOB_CMD,
-			0xBF08); /* initiates a manual data capture */
+
+	 /* initiates a manual data capture */
+	ret = adis_write_reg_16(&st->adis, ADIS16220_GLOB_CMD, 0xBF08);
 	if (ret)
 		dev_err(&indio_dev->dev, "problem beginning capture");
 
@@ -190,18 +75,6 @@ static int adis16220_capture(struct iio_dev *indio_dev)
 	return ret;
 }
 
-static int adis16220_reset(struct iio_dev *indio_dev)
-{
-	int ret;
-	ret = adis16220_spi_write_reg_8(indio_dev,
-			ADIS16220_GLOB_CMD,
-			ADIS16220_GLOB_CMD_SW_RESET);
-	if (ret)
-		dev_err(&indio_dev->dev, "problem resetting device");
-
-	return ret;
-}
-
 static ssize_t adis16220_write_capture(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf, size_t len)
@@ -222,81 +95,6 @@ static ssize_t adis16220_write_capture(struct device *dev,
 	return len;
 }
 
-static int adis16220_check_status(struct iio_dev *indio_dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16220_spi_read_reg_16(indio_dev, ADIS16220_DIAG_STAT,
-					&status);
-
-	if (ret < 0) {
-		dev_err(&indio_dev->dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status & 0x7F;
-
-	if (status & ADIS16220_DIAG_STAT_VIOLATION)
-		dev_err(&indio_dev->dev,
-			"Capture period violation/interruption\n");
-	if (status & ADIS16220_DIAG_STAT_SPI_FAIL)
-		dev_err(&indio_dev->dev, "SPI failure\n");
-	if (status & ADIS16220_DIAG_STAT_FLASH_UPT)
-		dev_err(&indio_dev->dev, "Flash update failed\n");
-	if (status & ADIS16220_DIAG_STAT_POWER_HIGH)
-		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
-	if (status & ADIS16220_DIAG_STAT_POWER_LOW)
-		dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
-
-error_ret:
-	return ret;
-}
-
-static int adis16220_self_test(struct iio_dev *indio_dev)
-{
-	int ret;
-	ret = adis16220_spi_write_reg_16(indio_dev,
-			ADIS16220_MSC_CTRL,
-			ADIS16220_MSC_CTRL_SELF_TEST_EN);
-	if (ret) {
-		dev_err(&indio_dev->dev, "problem starting self test");
-		goto err_ret;
-	}
-
-	adis16220_check_status(indio_dev);
-
-err_ret:
-	return ret;
-}
-
-static int adis16220_initial_setup(struct iio_dev *indio_dev)
-{
-	int ret;
-
-	/* Do self test */
-	ret = adis16220_self_test(indio_dev);
-	if (ret) {
-		dev_err(&indio_dev->dev, "self test failure");
-		goto err_ret;
-	}
-
-	/* Read status register to check the result */
-	ret = adis16220_check_status(indio_dev);
-	if (ret) {
-		adis16220_reset(indio_dev);
-		dev_err(&indio_dev->dev, "device not playing ball -> reset");
-		msleep(ADIS16220_STARTUP_DELAY);
-		ret = adis16220_check_status(indio_dev);
-		if (ret) {
-			dev_err(&indio_dev->dev, "giving up");
-			goto err_ret;
-		}
-	}
-
-err_ret:
-	return ret;
-}
-
 static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
 					char *buf,
 					loff_t off,
@@ -333,7 +131,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
 		count = ADIS16220_CAPTURE_SIZE - off;
 
 	/* write the begin position of capture buffer */
-	ret = adis16220_spi_write_reg_16(indio_dev,
+	ret = adis_write_reg_16(&st->adis,
 					ADIS16220_CAPT_PNTR,
 					off > 1);
 	if (ret)
@@ -342,8 +140,9 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
 	/* read count/2 values from capture buffer */
 	mutex_lock(&st->buf_lock);
 
+
 	for (i = 0; i < count; i += 2) {
-		st->tx[i] = ADIS16220_READ_REG(addr);
+		st->tx[i] = ADIS_READ_REG(addr);
 		st->tx[i + 1] = 0;
 	}
 	xfers[1].len = count;
@@ -351,7 +150,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
 	spi_message_init(&msg);
 	spi_message_add_tail(&xfers[0], &msg);
 	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
+	ret = spi_sync(st->adis.spi, &msg);
 	if (ret) {
 
 		mutex_unlock(&st->buf_lock);
@@ -472,6 +271,8 @@ static int adis16220_read_raw(struct iio_dev *indio_dev,
 			      int *val, int *val2,
 			      long mask)
 {
+	struct adis16220_state *st = iio_priv(indio_dev);
+	const struct adis16220_address_spec *addr;
 	int ret = -EINVAL;
 	int addrind = 0;
 	u16 uval;
@@ -516,28 +317,21 @@ static int adis16220_read_raw(struct iio_dev *indio_dev,
 	default:
 		return -EINVAL;
 	}
-	if (adis16220_addresses[chan->address][addrind].sign) {
-		ret = adis16220_spi_read_reg_16(indio_dev,
-						adis16220_addresses[chan
-								    ->address]
-						[addrind].addr,
-						&sval);
+	addr = &adis16220_addresses[chan->address][addrind];
+	if (addr->sign) {
+		ret = adis_read_reg_16(&st->adis, addr->addr, &sval);
 		if (ret)
 			return ret;
-		bits = adis16220_addresses[chan->address][addrind].bits;
+		bits = addr->bits;
 		sval &= (1 << bits) - 1;
 		sval = (s16)(sval << (16 - bits)) >> (16 - bits);
 		*val = sval;
 		return IIO_VAL_INT;
 	} else {
-		ret = adis16220_spi_read_reg_16(indio_dev,
-						adis16220_addresses[chan
-								    ->address]
-						[addrind].addr,
-						&uval);
+		ret = adis_read_reg_16(&st->adis, addr->addr, &uval);
 		if (ret)
 			return ret;
-		bits = adis16220_addresses[chan->address][addrind].bits;
+		bits = addr->bits;
 		uval &= (1 << bits) - 1;
 		*val = uval;
 		return IIO_VAL_INT;
@@ -601,6 +395,32 @@ static const struct iio_info adis16220_info = {
 	.read_raw = &adis16220_read_raw,
 };
 
+static const char * const adis16220_status_error_msgs[] = {
+	[ADIS16220_DIAG_STAT_VIOLATION_BIT] = "Capture period violation/interruption",
+	[ADIS16220_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+	[ADIS16220_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+	[ADIS16220_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
+	[ADIS16220_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
+};
+
+static const struct adis_data adis16220_data = {
+	.read_delay = 35,
+	.write_delay = 35,
+	.msc_ctrl_reg = ADIS16220_MSC_CTRL,
+	.glob_cmd_reg = ADIS16220_GLOB_CMD,
+	.diag_stat_reg = ADIS16220_DIAG_STAT,
+
+	.self_test_mask = ADIS16220_MSC_CTRL_SELF_TEST_EN,
+	.startup_delay = ADIS16220_STARTUP_DELAY,
+
+	.status_error_msgs = adis16220_status_error_msgs,
+	.status_error_mask = BIT(ADIS16220_DIAG_STAT_VIOLATION_BIT) |
+		BIT(ADIS16220_DIAG_STAT_SPI_FAIL_BIT) |
+		BIT(ADIS16220_DIAG_STAT_FLASH_UPT_BIT) |
+		BIT(ADIS16220_DIAG_STAT_POWER_HIGH_BIT) |
+		BIT(ADIS16220_DIAG_STAT_POWER_LOW_BIT),
+};
+
 static int __devinit adis16220_probe(struct spi_device *spi)
 {
 	int ret;
@@ -618,9 +438,6 @@ static int __devinit adis16220_probe(struct spi_device *spi)
 	/* this is only used for removal purposes */
 	spi_set_drvdata(spi, indio_dev);
 
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-
 	indio_dev->name = spi->dev.driver->name;
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->info = &adis16220_info;
@@ -644,8 +461,11 @@ static int __devinit adis16220_probe(struct spi_device *spi)
 	if (ret)
 		goto error_rm_adc1_bin;
 
+	ret = adis_init(&st->adis, indio_dev, spi, &adis16220_data);
+	if (ret)
+		goto error_rm_adc2_bin;
 	/* Get the device into a sane initial state */
-	ret = adis16220_initial_setup(indio_dev);
+	ret = adis_initial_startup(&st->adis);
 	if (ret)
 		goto error_rm_adc2_bin;
 	return 0;
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux