Commit 5bd22f51 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Jonathan Cameron

staging:iio:adis16204: Use adis library

Use the new adis library for the adis16204 driver. This allows us to completely
scrap the adis16204 buffer and trigger code and more than half of the core
driver code.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 3bff7eb0
...@@ -24,8 +24,8 @@ config ADIS16203 ...@@ -24,8 +24,8 @@ config ADIS16203
config ADIS16204 config ADIS16204
tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder" tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder"
depends on SPI depends on SPI
select IIO_TRIGGER if IIO_BUFFER select IIO_ADIS_LIB
select IIO_SW_RING if IIO_BUFFER select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help help
Say yes here to build support for Analog Devices adis16204 Programmable Say yes here to build support for Analog Devices adis16204 Programmable
High-g Digital Impact Sensor and Recorder. High-g Digital Impact Sensor and Recorder.
......
...@@ -9,7 +9,6 @@ adis16203-y := adis16203_core.o ...@@ -9,7 +9,6 @@ adis16203-y := adis16203_core.o
obj-$(CONFIG_ADIS16203) += adis16203.o obj-$(CONFIG_ADIS16203) += adis16203.o
adis16204-y := adis16204_core.o adis16204-y := adis16204_core.o
adis16204-$(CONFIG_IIO_BUFFER) += adis16204_ring.o adis16204_trigger.o
obj-$(CONFIG_ADIS16204) += adis16204.o obj-$(CONFIG_ADIS16204) += adis16204.o
adis16209-y := adis16209_core.o adis16209-y := adis16209_core.o
......
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
#define ADIS16204_STARTUP_DELAY 220 /* ms */ #define ADIS16204_STARTUP_DELAY 220 /* ms */
#define ADIS16204_READ_REG(a) a
#define ADIS16204_WRITE_REG(a) ((a) | 0x80)
#define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */ #define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */
#define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ #define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */
...@@ -35,8 +32,6 @@ ...@@ -35,8 +32,6 @@
#define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */ #define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */
#define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */ #define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */
#define ADIS16204_OUTPUTS 5
/* MSC_CTRL */ /* MSC_CTRL */
#define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */
#define ADIS16204_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ #define ADIS16204_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */
...@@ -47,87 +42,27 @@ ...@@ -47,87 +42,27 @@
/* DIAG_STAT */ /* DIAG_STAT */
#define ADIS16204_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16204_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16204_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16204_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16204_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag: 1 = error condition, #define ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag: 1 = error condition,
0 = normal operation */ 0 = normal operation */
#define ADIS16204_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ #define ADIS16204_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */
#define ADIS16204_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ #define ADIS16204_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */
#define ADIS16204_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ #define ADIS16204_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */
#define ADIS16204_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 2.975 V */ #define ADIS16204_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 2.975 V */
/* GLOB_CMD */ /* GLOB_CMD */
#define ADIS16204_GLOB_CMD_SW_RESET (1<<7) #define ADIS16204_GLOB_CMD_SW_RESET (1<<7)
#define ADIS16204_GLOB_CMD_CLEAR_STAT (1<<4) #define ADIS16204_GLOB_CMD_CLEAR_STAT (1<<4)
#define ADIS16204_GLOB_CMD_FACTORY_CAL (1<<1) #define ADIS16204_GLOB_CMD_FACTORY_CAL (1<<1)
#define ADIS16204_MAX_TX 24
#define ADIS16204_MAX_RX 24
#define ADIS16204_ERROR_ACTIVE (1<<14) #define ADIS16204_ERROR_ACTIVE (1<<14)
/**
* struct adis16204_state - device instance specific data
* @us: actual spi_device
* @trig: data ready trigger registered with iio
* @tx: transmit buffer
* @rx: receive buffer
* @buf_lock: mutex to protect tx and rx
**/
struct adis16204_state {
struct spi_device *us;
struct iio_trigger *trig;
struct mutex buf_lock;
u8 tx[ADIS16204_MAX_TX] ____cacheline_aligned;
u8 rx[ADIS16204_MAX_RX];
};
int adis16204_set_irq(struct iio_dev *indio_dev, bool enable);
enum adis16204_scan { enum adis16204_scan {
ADIS16204_SCAN_SUPPLY,
ADIS16204_SCAN_ACC_X, ADIS16204_SCAN_ACC_X,
ADIS16204_SCAN_ACC_Y, ADIS16204_SCAN_ACC_Y,
ADIS16204_SCAN_ACC_XY,
ADIS16204_SCAN_SUPPLY,
ADIS16204_SCAN_AUX_ADC, ADIS16204_SCAN_AUX_ADC,
ADIS16204_SCAN_TEMP, ADIS16204_SCAN_TEMP,
}; };
#ifdef CONFIG_IIO_BUFFER
void adis16204_remove_trigger(struct iio_dev *indio_dev);
int adis16204_probe_trigger(struct iio_dev *indio_dev);
ssize_t adis16204_read_data_from_ring(struct device *dev,
struct device_attribute *attr,
char *buf);
int adis16204_configure_ring(struct iio_dev *indio_dev);
void adis16204_unconfigure_ring(struct iio_dev *indio_dev);
#else /* CONFIG_IIO_BUFFER */
static inline void adis16204_remove_trigger(struct iio_dev *indio_dev)
{
}
static inline int adis16204_probe_trigger(struct iio_dev *indio_dev)
{
return 0;
}
static inline ssize_t
adis16204_read_data_from_ring(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return 0;
}
static int adis16204_configure_ring(struct iio_dev *indio_dev)
{
return 0;
}
static inline void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
{
}
#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16204_H_ */ #endif /* SPI_ADIS16204_H_ */
This diff is collapsed.
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include "../ring_sw.h"
#include <linux/iio/trigger_consumer.h>
#include "adis16204.h"
/**
* adis16204_read_ring_data() read data registers which will be placed into ring
* @indio_dev: the IIO device
* @rx: somewhere to pass back the value read
**/
static int adis16204_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
{
struct spi_message msg;
struct adis16204_state *st = iio_priv(indio_dev);
struct spi_transfer xfers[ADIS16204_OUTPUTS + 1];
int ret;
int i;
mutex_lock(&st->buf_lock);
spi_message_init(&msg);
memset(xfers, 0, sizeof(xfers));
for (i = 0; i <= ADIS16204_OUTPUTS; i++) {
xfers[i].bits_per_word = 8;
xfers[i].cs_change = 1;
xfers[i].len = 2;
xfers[i].delay_usecs = 20;
xfers[i].tx_buf = st->tx + 2 * i;
st->tx[2 * i]
= ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i);
st->tx[2 * i + 1] = 0;
if (i >= 1)
xfers[i].rx_buf = rx + 2 * (i - 1);
spi_message_add_tail(&xfers[i], &msg);
}
ret = spi_sync(st->us, &msg);
if (ret)
dev_err(&st->us->dev, "problem when burst reading");
mutex_unlock(&st->buf_lock);
return ret;
}
/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
* specific to be rolled into the core.
*/
static irqreturn_t adis16204_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16204_state *st = iio_priv(indio_dev);
int i = 0;
s16 *data;
data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
if (data == NULL) {
dev_err(&st->us->dev, "memory alloc failed in ring bh");
goto done;
}
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
adis16204_read_ring_data(indio_dev, st->rx) >= 0)
for (; i < bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength); i++)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
{
iio_dealloc_pollfunc(indio_dev->pollfunc);
iio_sw_rb_free(indio_dev->buffer);
}
static const struct iio_buffer_setup_ops adis16204_ring_setup_ops = {
.preenable = &iio_sw_buffer_preenable,
.postenable = &iio_triggered_buffer_postenable,
.predisable = &iio_triggered_buffer_predisable,
};
int adis16204_configure_ring(struct iio_dev *indio_dev)
{
int ret = 0;
struct iio_buffer *ring;
ring = iio_sw_rb_allocate(indio_dev);
if (!ring) {
ret = -ENOMEM;
return ret;
}
indio_dev->buffer = ring;
ring->scan_timestamp = true;
indio_dev->setup_ops = &adis16204_ring_setup_ops;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
&adis16204_trigger_handler,
IRQF_ONESHOT,
indio_dev,
"%s_consumer%d",
indio_dev->name,
indio_dev->id);
if (indio_dev->pollfunc == NULL) {
ret = -ENOMEM;
goto error_iio_sw_rb_free;
}
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
return 0;
error_iio_sw_rb_free:
iio_sw_rb_free(indio_dev->buffer);
return ret;
}
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/export.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include "adis16204.h"
/**
* adis16204_data_rdy_trigger_set_state() set datardy interrupt state
**/
static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
struct iio_dev *indio_dev = trig->private_data;
dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
return adis16204_set_irq(indio_dev, state);
}
static const struct iio_trigger_ops adis16204_trigger_ops = {
.owner = THIS_MODULE,
.set_trigger_state = &adis16204_data_rdy_trigger_set_state,
};
int adis16204_probe_trigger(struct iio_dev *indio_dev)
{
int ret;
struct adis16204_state *st = iio_priv(indio_dev);
st->trig = iio_trigger_alloc("adis16204-dev%d", indio_dev->id);
if (st->trig == NULL) {
ret = -ENOMEM;
goto error_ret;
}
ret = request_irq(st->us->irq,
&iio_trigger_generic_data_rdy_poll,
IRQF_TRIGGER_RISING,
"adis16204",
st->trig);
if (ret)
goto error_free_trig;
st->trig->dev.parent = &st->us->dev;
st->trig->ops = &adis16204_trigger_ops;
st->trig->private_data = indio_dev;
ret = iio_trigger_register(st->trig);
/* select default trigger */
indio_dev->trig = st->trig;
if (ret)
goto error_free_irq;
return 0;
error_free_irq:
free_irq(st->us->irq, st->trig);
error_free_trig:
iio_trigger_free(st->trig);
error_ret:
return ret;
}
void adis16204_remove_trigger(struct iio_dev *indio_dev)
{
struct adis16204_state *state = iio_priv(indio_dev);
iio_trigger_unregister(state->trig);
free_irq(state->us->irq, state->trig);
iio_trigger_free(state->trig);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment