Commit 83eaeec5 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-3.9b-v2' of...

Merge tag 'iio-for-3.9b-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

	Second set of IIO new drivers, cleanups and fixes for the 3.9 cycle.

	This second version is due to a little fixup for an include
	path being added to the tsl2563 move out of staging after
	a report from Fengguang Wu and the 0-day kernel build testing
	backend.

	Minor bits:
	1) A Kconfig dependency fix for the max1363 driver that
	has been causing some autobuilder fails in Linux Next.
	2) Removal of a stale makefile entry
	3) Fix an incorrect arguement for a sizeof call
	4) Duplicate code removal in tsl2x7x driver
	5) A missing spin lock init in hid-sensor-time

	New features:
	1) mxs adc driver gains support for touchscreen special functions
	2) mxs driver gainst supprot for the MX23 and dt entries added
	3) adis16400 gains adis16448 support and some additional bells and whistles

	Moves out of staging.
	1) adis16400 - a venerable driver gets a make over and moves
	   out of staging.
	2) Kxsd9 moved out fo staging
	3) adis16080 gets cleaned up and moved out of staging
	4) tsl2563 gets a little cleaned up and move out of staging

	Removals
	1) sw_ring is killed off with all remaining drivers converted to kfifo.
	   This has been scheduled for a long time since we switched to kfifo.
	   There is demand for a high performance alternative, but this was
	   never it and I'm glad to see this vestage of IIOs youth gone once
	   and for all!
parents 8f5f90a8 9c2251dd
......@@ -5,6 +5,12 @@ Required properties:
- reg: Address and length of the register set for the device
- interrupts: Should contain the LRADC interrupts
Optional properties:
- fsl,lradc-touchscreen-wires: Number of wires used to connect the touchscreen
to LRADC. Valid value is either 4 or 5. If this
property is not present, then the touchscreen is
disabled.
Examples:
lradc@80050000 {
......
......@@ -391,7 +391,9 @@ audio-in@8004c000 {
};
lradc@80050000 {
compatible = "fsl,imx23-lradc";
reg = <0x80050000 0x2000>;
interrupts = <36 37 38 39 40 41 42 43 44>;
status = "disabled";
};
......
......@@ -42,7 +42,7 @@
#include <media/si4713.h>
#include <linux/leds-lp5523.h>
#include <../drivers/staging/iio/light/tsl2563.h>
#include <linux/platform_data/tsl2563.h>
#include <linux/lis3lv02d.h>
#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
......
......@@ -14,4 +14,11 @@ config HID_SENSOR_ACCEL_3D
Say yes here to build support for the HID SENSOR
accelerometers 3D.
config KXSD9
tristate "Kionix KXSD9 Accelerometer Driver"
depends on SPI
help
Say yes here to build support for the Kionix KXSD9 accelerometer.
Currently this only supports the device via an SPI interface.
endmenu
......@@ -3,3 +3,4 @@
#
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXSD9) += kxsd9.o
......@@ -226,7 +226,7 @@ static int kxsd9_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct kxsd9_state *st;
int ret = 0;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
......@@ -245,14 +245,14 @@ static int kxsd9_probe(struct spi_device *spi)
indio_dev->info = &kxsd9_info;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_dev;
spi->mode = SPI_MODE_0;
spi_setup(spi);
kxsd9_power_up(st);
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_dev;
return 0;
error_free_dev:
......
......@@ -100,10 +100,8 @@ config LP8788_ADC
config MAX1363
tristate "Maxim max1363 ADC driver"
depends on I2C
select IIO_TRIGGER
select MAX1363_RING_BUFFER
select IIO_BUFFER
select IIO_KFIFO_BUF
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for many Maxim i2c analog to digital
converters (ADC). (max1361, max1362, max1363, max1364, max1036,
......
......@@ -3,6 +3,13 @@
#
menu "Digital gyroscope sensors"
config ADIS16080
tristate "Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver"
depends on SPI
help
Say yes here to build support for Analog Devices ADIS16080, ADIS16100 Yaw
Rate Gyroscope with SPI.
config ADIS16136
tristate "Analog devices ADIS16136 and similar gyroscopes driver"
depends on SPI_MASTER
......
......@@ -2,5 +2,6 @@
# Makefile for industrial I/O gyroscope sensor drivers
#
obj-$(CONFIG_ADIS16080) += adis16080.o
obj-$(CONFIG_ADIS16136) += adis16136.o
obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
......@@ -29,48 +29,50 @@
#define ADIS16080_DIN_WRITE (1 << 15)
struct adis16080_chip_info {
int scale_val;
int scale_val2;
};
/**
* struct adis16080_state - device instance specific data
* @us: actual spi_device to write data
* @info: chip specific parameters
* @buf: transmit or receive buffer
* @buf_lock: mutex to protect tx and rx
**/
struct adis16080_state {
struct spi_device *us;
struct mutex buf_lock;
const struct adis16080_chip_info *info;
u8 buf[2] ____cacheline_aligned;
__be16 buf ____cacheline_aligned;
};
static int adis16080_spi_write(struct iio_dev *indio_dev,
u16 val)
static int adis16080_read_sample(struct iio_dev *indio_dev,
u16 addr, int *val)
{
int ret;
struct adis16080_state *st = iio_priv(indio_dev);
mutex_lock(&st->buf_lock);
st->buf[0] = val >> 8;
st->buf[1] = val;
ret = spi_write(st->us, st->buf, 2);
mutex_unlock(&st->buf_lock);
return ret;
}
static int adis16080_spi_read(struct iio_dev *indio_dev,
u16 *val)
{
struct spi_message m;
int ret;
struct adis16080_state *st = iio_priv(indio_dev);
struct spi_transfer t[] = {
{
.tx_buf = &st->buf,
.len = 2,
.cs_change = 1,
}, {
.rx_buf = &st->buf,
.len = 2,
},
};
mutex_lock(&st->buf_lock);
st->buf = cpu_to_be16(addr | ADIS16080_DIN_WRITE);
ret = spi_read(st->us, st->buf, 2);
spi_message_init(&m);
spi_message_add_tail(&t[0], &m);
spi_message_add_tail(&t[1], &m);
ret = spi_sync(st->us, &m);
if (ret == 0)
*val = sign_extend32(((st->buf[0] & 0xF) << 8) | st->buf[1], 11);
mutex_unlock(&st->buf_lock);
*val = sign_extend32(be16_to_cpu(st->buf), 11);
return ret;
}
......@@ -81,28 +83,52 @@ static int adis16080_read_raw(struct iio_dev *indio_dev,
int *val2,
long mask)
{
int ret = -EINVAL;
u16 ut = 0;
/* Take the iio_dev status lock */
struct adis16080_state *st = iio_priv(indio_dev);
int ret;
mutex_lock(&indio_dev->mlock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = adis16080_spi_write(indio_dev,
chan->address |
ADIS16080_DIN_WRITE);
if (ret < 0)
break;
ret = adis16080_spi_read(indio_dev, &ut);
if (ret < 0)
break;
*val = ut;
ret = IIO_VAL_INT;
mutex_lock(&indio_dev->mlock);
ret = adis16080_read_sample(indio_dev, chan->address, val);
mutex_unlock(&indio_dev->mlock);
return ret ? ret : IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
*val = st->info->scale_val;
*val2 = st->info->scale_val2;
return IIO_VAL_FRACTIONAL;
case IIO_VOLTAGE:
/* VREF = 5V, 12 bits */
*val = 5000;
*val2 = 12;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_TEMP:
/* 85 C = 585, 25 C = 0 */
*val = 85000 - 25000;
*val2 = 585;
return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_OFFSET:
switch (chan->type) {
case IIO_VOLTAGE:
/* 2.5 V = 0 */
*val = 2048;
return IIO_VAL_INT;
case IIO_TEMP:
/* 85 C = 585, 25 C = 0 */
*val = DIV_ROUND_CLOSEST(25 * 585, 85 - 25);
return IIO_VAL_INT;
default:
return -EINVAL;
}
default:
break;
}
mutex_unlock(&indio_dev->mlock);
return ret;
return -EINVAL;
}
static const struct iio_chan_spec adis16080_channels[] = {
......@@ -110,25 +136,32 @@ static const struct iio_chan_spec adis16080_channels[] = {
.type = IIO_ANGL_VEL,
.modified = 1,
.channel2 = IIO_MOD_Z,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
.address = ADIS16080_DIN_GYRO,
}, {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 0,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
.address = ADIS16080_DIN_AIN1,
}, {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 1,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
.address = ADIS16080_DIN_AIN2,
}, {
.type = IIO_TEMP,
.indexed = 1,
.channel = 0,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
.address = ADIS16080_DIN_TEMP,
}
};
......@@ -138,8 +171,27 @@ static const struct iio_info adis16080_info = {
.driver_module = THIS_MODULE,
};
enum {
ID_ADIS16080,
ID_ADIS16100,
};
static const struct adis16080_chip_info adis16080_chip_info[] = {
[ID_ADIS16080] = {
/* 80 degree = 819, 819 rad = 46925 degree */
.scale_val = 80,
.scale_val2 = 46925,
},
[ID_ADIS16100] = {
/* 300 degree = 1230, 1230 rad = 70474 degree */
.scale_val = 300,
.scale_val2 = 70474,
},
};
static int adis16080_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
int ret;
struct adis16080_state *st;
struct iio_dev *indio_dev;
......@@ -156,7 +208,7 @@ static int adis16080_probe(struct spi_device *spi)
/* Allocate the comms buffers */
st->us = spi;
mutex_init(&st->buf_lock);
st->info = &adis16080_chip_info[id->driver_data];
indio_dev->name = spi->dev.driver->name;
indio_dev->channels = adis16080_channels;
......@@ -176,7 +228,6 @@ static int adis16080_probe(struct spi_device *spi)
return ret;
}
/* fixme, confirm ordering in this function */
static int adis16080_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
......@@ -185,6 +236,13 @@ static int adis16080_remove(struct spi_device *spi)
return 0;
}
static const struct spi_device_id adis16080_ids[] = {
{ "adis16080", ID_ADIS16080 },
{ "adis16100", ID_ADIS16100 },
{},
};
MODULE_DEVICE_TABLE(spi, adis16080_ids);
static struct spi_driver adis16080_driver = {
.driver = {
.name = "adis16080",
......@@ -192,10 +250,10 @@ static struct spi_driver adis16080_driver = {
},
.probe = adis16080_probe,
.remove = adis16080_remove,
.id_table = adis16080_ids,
};
module_spi_driver(adis16080_driver);
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:adis16080");
......@@ -3,6 +3,17 @@
#
menu "Inertial measurement units"
config ADIS16400
tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
depends on SPI
select IIO_ADIS_LIB
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices adis16300, adis16344,
adis16350, adis16354, adis16355, adis16360, adis16362, adis16364,
adis16365, adis16400 and adis16405 triaxial inertial sensors
(adis16400 series also have magnetometers).
config ADIS16480
tristate "Analog Devices ADIS16480 and similar IMU driver"
depends on SPI
......
......@@ -2,6 +2,9 @@
# Makefile for Inertial Measurement Units
#
adis16400-y := adis16400_core.o
adis16400-$(CONFIG_IIO_BUFFER) += adis16400_buffer.o
obj-$(CONFIG_ADIS16400) += adis16400.o
obj-$(CONFIG_ADIS16480) += adis16480.o
adis_lib-y += adis.o
......
......@@ -17,12 +17,11 @@
#ifndef SPI_ADIS16400_H_
#define SPI_ADIS16400_H_
#include <linux/iio/imu/adis.h>
#define ADIS16400_STARTUP_DELAY 290 /* ms */
#define ADIS16400_MTEST_DELAY 90 /* ms */
#define ADIS16400_READ_REG(a) a
#define ADIS16400_WRITE_REG(a) ((a) | 0x80)
#define ADIS16400_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16400_SUPPLY_OUT 0x02 /* Power supply measurement */
#define ADIS16400_XGYRO_OUT 0x04 /* X-axis gyroscope output */
......@@ -45,6 +44,9 @@
#define ADIS16300_ROLL_OUT 0x14 /* Y axis inclinometer output measurement */
#define ADIS16300_AUX_ADC 0x16 /* Auxiliary ADC measurement */
#define ADIS16448_BARO_OUT 0x16 /* Barometric pressure output */
#define ADIS16448_TEMP_OUT 0x18 /* Temperature output */
/* Calibration parameters */
#define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
#define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
......@@ -75,7 +77,10 @@
#define ADIS16400_ALM_CTRL 0x48 /* Alarm control */
#define ADIS16400_AUX_DAC 0x4A /* Auxiliary DAC data */
#define ADIS16334_LOT_ID1 0x52 /* Lot identification code 1 */
#define ADIS16334_LOT_ID2 0x54 /* Lot identification code 2 */
#define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */
#define ADIS16334_SERIAL_NUMBER 0x58 /* Serial number, lot specific */
#define ADIS16400_ERROR_ACTIVE (1<<14)
#define ADIS16400_NEW_DATA (1<<14)
......@@ -96,21 +101,21 @@
#define ADIS16400_SMPL_PRD_DIV_MASK 0x7F
/* DIAG_STAT */
#define ADIS16400_DIAG_STAT_ZACCL_FAIL (1<<15)
#define ADIS16400_DIAG_STAT_YACCL_FAIL (1<<14)
#define ADIS16400_DIAG_STAT_XACCL_FAIL (1<<13)
#define ADIS16400_DIAG_STAT_XGYRO_FAIL (1<<12)
#define ADIS16400_DIAG_STAT_YGYRO_FAIL (1<<11)
#define ADIS16400_DIAG_STAT_ZGYRO_FAIL (1<<10)
#define ADIS16400_DIAG_STAT_ALARM2 (1<<9)
#define ADIS16400_DIAG_STAT_ALARM1 (1<<8)
#define ADIS16400_DIAG_STAT_FLASH_CHK (1<<6)
#define ADIS16400_DIAG_STAT_SELF_TEST (1<<5)
#define ADIS16400_DIAG_STAT_OVERFLOW (1<<4)
#define ADIS16400_DIAG_STAT_SPI_FAIL (1<<3)
#define ADIS16400_DIAG_STAT_FLASH_UPT (1<<2)
#define ADIS16400_DIAG_STAT_POWER_HIGH (1<<1)
#define ADIS16400_DIAG_STAT_POWER_LOW (1<<0)
#define ADIS16400_DIAG_STAT_ZACCL_FAIL 15
#define ADIS16400_DIAG_STAT_YACCL_FAIL 14
#define ADIS16400_DIAG_STAT_XACCL_FAIL 13
#define ADIS16400_DIAG_STAT_XGYRO_FAIL 12
#define ADIS16400_DIAG_STAT_YGYRO_FAIL 11
#define ADIS16400_DIAG_STAT_ZGYRO_FAIL 10
#define ADIS16400_DIAG_STAT_ALARM2 9
#define ADIS16400_DIAG_STAT_ALARM1 8
#define ADIS16400_DIAG_STAT_FLASH_CHK 6
#define ADIS16400_DIAG_STAT_SELF_TEST 5
#define ADIS16400_DIAG_STAT_OVERFLOW 4
#define ADIS16400_DIAG_STAT_SPI_FAIL 3
#define ADIS16400_DIAG_STAT_FLASH_UPT 2
#define ADIS16400_DIAG_STAT_POWER_HIGH 1
#define ADIS16400_DIAG_STAT_POWER_LOW 0
/* GLOB_CMD */
#define ADIS16400_GLOB_CMD_SW_RESET (1<<7)
......@@ -126,9 +131,6 @@
#define ADIS16334_RATE_DIV_SHIFT 8
#define ADIS16334_RATE_INT_CLK BIT(0)
#define ADIS16400_MAX_TX 24
#define ADIS16400_MAX_RX 24
#define ADIS16400_SPI_SLOW (u32)(300 * 1000)
#define ADIS16400_SPI_BURST (u32)(1000 * 1000)
#define ADIS16400_SPI_FAST (u32)(2000 * 1000)
......@@ -136,6 +138,9 @@
#define ADIS16400_HAS_PROD_ID BIT(0)
#define ADIS16400_NO_BURST BIT(1)
#define ADIS16400_HAS_SLOW_MODE BIT(2)
#define ADIS16400_HAS_SERIAL_NUMBER BIT(3)
struct adis16400_state;
struct adis16400_chip_info {
const struct iio_chan_spec *channels;
......@@ -145,95 +150,63 @@ struct adis16400_chip_info {
unsigned int accel_scale_micro;
int temp_scale_nano;
int temp_offset;
unsigned long default_scan_mask;
int (*set_freq)(struct iio_dev *indio_dev, unsigned int freq);
int (*get_freq)(struct iio_dev *indio_dev);
int (*set_freq)(struct adis16400_state *st, unsigned int freq);
int (*get_freq)(struct adis16400_state *st);
};
/**
* struct adis16400_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
* @filt_int: integer part of requested filter frequency
* @variant: chip variant info
* @filt_int: integer part of requested filter frequency
* @adis: adis device
**/
struct adis16400_state {
struct spi_device *us;
struct iio_trigger *trig;
struct mutex buf_lock;
struct adis16400_chip_info *variant;
int filt_int;
u8 tx[ADIS16400_MAX_TX] ____cacheline_aligned;
u8 rx[ADIS16400_MAX_RX] ____cacheline_aligned;
struct adis adis;
};
int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
/* At the moment triggers are only used for ring buffer
* filling. This may change!
*/
#define ADIS16400_SCAN_SUPPLY 0
#define ADIS16400_SCAN_GYRO_X 1
#define ADIS16400_SCAN_GYRO_Y 2
#define ADIS16400_SCAN_GYRO_Z 3
#define ADIS16400_SCAN_ACC_X 4
#define ADIS16400_SCAN_ACC_Y 5
#define ADIS16400_SCAN_ACC_Z 6
#define ADIS16400_SCAN_MAGN_X 7
#define ADIS16350_SCAN_TEMP_X 7
#define ADIS16400_SCAN_MAGN_Y 8
#define ADIS16350_SCAN_TEMP_Y 8
#define ADIS16400_SCAN_MAGN_Z 9
#define ADIS16350_SCAN_TEMP_Z 9
#define ADIS16400_SCAN_TEMP 10
#define ADIS16350_SCAN_ADC_0 10
#define ADIS16400_SCAN_ADC_0 11
#define ADIS16300_SCAN_INCLI_X 12
#define ADIS16300_SCAN_INCLI_Y 13
enum {
ADIS16400_SCAN_SUPPLY,
ADIS16400_SCAN_GYRO_X,
ADIS16400_SCAN_GYRO_Y,
ADIS16400_SCAN_GYRO_Z,
ADIS16400_SCAN_ACC_X,
ADIS16400_SCAN_ACC_Y,
ADIS16400_SCAN_ACC_Z,
ADIS16400_SCAN_MAGN_X,
ADIS16400_SCAN_MAGN_Y,
ADIS16400_SCAN_MAGN_Z,
ADIS16400_SCAN_BARO,
ADIS16350_SCAN_TEMP_X,
ADIS16350_SCAN_TEMP_Y,
ADIS16350_SCAN_TEMP_Z,
ADIS16300_SCAN_INCLI_X,
ADIS16300_SCAN_INCLI_Y,
ADIS16400_SCAN_ADC,
};
#ifdef CONFIG_IIO_BUFFER
void adis16400_remove_trigger(struct iio_dev *indio_dev);
int adis16400_probe_trigger(struct iio_dev *indio_dev);
ssize_t adis16400_read_data_from_ring(struct device *dev,
struct device_attribute *attr,
char *buf);
int adis16400_configure_ring(struct iio_dev *indio_dev);
void adis16400_unconfigure_ring(struct iio_dev *indio_dev);
int adis16400_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask);
irqreturn_t adis16400_trigger_handler(int irq, void *p);
#else /* CONFIG_IIO_BUFFER */
static inline void adis16400_remove_trigger(struct iio_dev *indio_dev)
{
}
static inline int adis16400_probe_trigger(struct iio_dev *indio_dev)
{
return 0;
}
static inline ssize_t
adis16400_read_data_from_ring(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return 0;
}
static int adis16400_configure_ring(struct iio_dev *indio_dev)
{
return 0;
}
static inline void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
{
}
#define adis16400_update_scan_mode NULL
#define adis16400_trigger_handler NULL
#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16400_H_ */
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include "adis16400.h"
int adis16400_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct adis16400_state *st = iio_priv(indio_dev);
struct adis *adis = &st->adis;
uint16_t *tx, *rx;
if (st->variant->flags & ADIS16400_NO_BURST)
return adis_update_scan_mode(indio_dev, scan_mask);
kfree(adis->xfer);
kfree(adis->buffer);
adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL);
if (!adis->xfer)
return -ENOMEM;
adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16),
GFP_KERNEL);
if (!adis->buffer)
return -ENOMEM;
rx = adis->buffer;
tx = adis->buffer + indio_dev->scan_bytes;
tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
tx[1] = 0;
adis->xfer[0].tx_buf = tx;
adis->xfer[0].bits_per_word = 8;
adis->xfer[0].len = 2;
adis->xfer[1].tx_buf = tx;
adis->xfer[1].bits_per_word = 8;
adis->xfer[1].len = indio_dev->scan_bytes;
spi_message_init(&adis->msg);
spi_message_add_tail(&adis->xfer[0], &adis->msg);
spi_message_add_tail(&adis->xfer[1], &adis->msg);
return 0;
}
irqreturn_t adis16400_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16400_state *st = iio_priv(indio_dev);
struct adis *adis = &st->adis;
u32 old_speed_hz = st->adis.spi->max_speed_hz;
int ret;
if (!adis->buffer)
return -ENOMEM;
if (!(st->variant->flags & ADIS16400_NO_BURST) &&
st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) {
st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST;
spi_setup(st->adis.spi);
}
ret = spi_sync(adis->spi, &adis->msg);
if (ret)
dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret);
if (!(st->variant->flags & ADIS16400_NO_BURST)) {
st->adis.spi->max_speed_hz = old_speed_hz;
spi_setup(st->adis.spi);
}
/* Guaranteed to be aligned with 8 byte boundary */
if (indio_dev->scan_timestamp) {
void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
*(s64 *)b = pf->timestamp;
}
iio_push_to_buffers(indio_dev, adis->buffer);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
......@@ -32,6 +32,16 @@ config SENSORS_LM3533
changes. The ALS-control output values can be set per zone for the
three current output channels.
config SENSORS_TSL2563
tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
depends on I2C
help
If you say yes here you get support for the Taos TSL2560,
TSL2561, TSL2562 and TSL2563 ambient light sensors.
This driver can also be built as a module. If so, the module
will be called tsl2563.
config VCNL4000
tristate "VCNL4000 combined ALS and proximity sensor"
depends on I2C
......
......@@ -4,5 +4,6 @@
obj-$(CONFIG_ADJD_S311) += adjd_s311.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
obj-$(CONFIG_VCNL4000) += vcnl4000.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
/*
* drivers/i2c/chips/tsl2563.c
* drivers/iio/light/tsl2563.c
*
* Copyright (C) 2008 Nokia Corporation
*
......@@ -38,52 +38,52 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#include "tsl2563.h"
#include <linux/platform_data/tsl2563.h>
/* Use this many bits for fraction part. */
#define ADC_FRAC_BITS (14)
#define ADC_FRAC_BITS 14
/* Given number of 1/10000's in ADC_FRAC_BITS precision. */
#define FRAC10K(f) (((f) * (1L << (ADC_FRAC_BITS))) / (10000))
/* Bits used for fraction in calibration coefficients.*/
#define CALIB_FRAC_BITS (10)
#define CALIB_FRAC_BITS 10
/* 0.5 in CALIB_FRAC_BITS precision */
#define CALIB_FRAC_HALF (1 << (CALIB_FRAC_BITS - 1))
/* Make a fraction from a number n that was multiplied with b. */
#define CALIB_FRAC(n, b) (((n) << CALIB_FRAC_BITS) / (b))
/* Decimal 10^(digits in sysfs presentation) */
#define CALIB_BASE_SYSFS (1000)
#define TSL2563_CMD (0x80)
#define TSL2563_CLEARINT (0x40)
#define TSL2563_REG_CTRL (0x00)
#define TSL2563_REG_TIMING (0x01)
#define TSL2563_REG_LOWLOW (0x02) /* data0 low threshold, 2 bytes */
#define TSL2563_REG_LOWHIGH (0x03)
#define TSL2563_REG_HIGHLOW (0x04) /* data0 high threshold, 2 bytes */
#define TSL2563_REG_HIGHHIGH (0x05)
#define TSL2563_REG_INT (0x06)
#define TSL2563_REG_ID (0x0a)
#define TSL2563_REG_DATA0LOW (0x0c) /* broadband sensor value, 2 bytes */
#define TSL2563_REG_DATA0HIGH (0x0d)
#define TSL2563_REG_DATA1LOW (0x0e) /* infrared sensor value, 2 bytes */
#define TSL2563_REG_DATA1HIGH (0x0f)
#define TSL2563_CMD_POWER_ON (0x03)
#define TSL2563_CMD_POWER_OFF (0x00)
#define TSL2563_CTRL_POWER_MASK (0x03)
#define TSL2563_TIMING_13MS (0x00)
#define TSL2563_TIMING_100MS (0x01)
#define TSL2563_TIMING_400MS (0x02)
#define TSL2563_TIMING_MASK (0x03)
#define TSL2563_TIMING_GAIN16 (0x10)
#define TSL2563_TIMING_GAIN1 (0x00)
#define TSL2563_INT_DISBLED (0x00)
#define TSL2563_INT_LEVEL (0x10)
#define CALIB_BASE_SYSFS 1000
#define TSL2563_CMD 0x80
#define TSL2563_CLEARINT 0x40
#define TSL2563_REG_CTRL 0x00
#define TSL2563_REG_TIMING 0x01
#define TSL2563_REG_LOWLOW 0x02 /* data0 low threshold, 2 bytes */
#define TSL2563_REG_LOWHIGH 0x03
#define TSL2563_REG_HIGHLOW 0x04 /* data0 high threshold, 2 bytes */
#define TSL2563_REG_HIGHHIGH 0x05
#define TSL2563_REG_INT 0x06
#define TSL2563_REG_ID 0x0a
#define TSL2563_REG_DATA0LOW 0x0c /* broadband sensor value, 2 bytes */
#define TSL2563_REG_DATA0HIGH 0x0d
#define TSL2563_REG_DATA1LOW 0x0e /* infrared sensor value, 2 bytes */
#define TSL2563_REG_DATA1HIGH 0x0f
#define TSL2563_CMD_POWER_ON 0x03
#define TSL2563_CMD_POWER_OFF 0x00
#define TSL2563_CTRL_POWER_MASK 0x03
#define TSL2563_TIMING_13MS 0x00
#define TSL2563_TIMING_100MS 0x01
#define TSL2563_TIMING_400MS 0x02
#define TSL2563_TIMING_MASK 0x03
#define TSL2563_TIMING_GAIN16 0x10
#define TSL2563_TIMING_GAIN1 0x00
#define TSL2563_INT_DISBLED 0x00
#define TSL2563_INT_LEVEL 0x10
#define TSL2563_INT_PERSIST(n) ((n) & 0x0F)
struct tsl2563_gainlevel_coeff {
......@@ -190,8 +190,10 @@ static int tsl2563_configure(struct tsl2563_chip *chip)
ret = i2c_smbus_write_byte_data(chip->client,
TSL2563_CMD | TSL2563_REG_LOWHIGH,
(chip->low_thres >> 8) & 0xFF);
/* Interrupt register is automatically written anyway if it is relevant
so is not here */
/*
* Interrupt register is automatically written anyway if it is relevant
* so is not here.
*/
error_ret:
return ret;
}
......@@ -423,9 +425,7 @@ static const struct tsl2563_lux_coeff lux_table[] = {
},
};
/*
* Convert normalized, scaled ADC values to lux.
*/
/* Convert normalized, scaled ADC values to lux. */
static unsigned int adc_to_lux(u32 adc0, u32 adc1)
{
const struct tsl2563_lux_coeff *lp = lux_table;
......@@ -441,11 +441,6 @@ static unsigned int adc_to_lux(u32 adc0, u32 adc1)
return (unsigned int) (lux >> ADC_FRAC_BITS);
}
/*--------------------------------------------------------------*/
/* Sysfs interface */
/*--------------------------------------------------------------*/
/* Apply calibration coefficient to ADC count. */
static u32 calib_adc(u32 adc, u32 calib)
{
......@@ -677,18 +672,11 @@ static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
TSL2563_CMD | TSL2563_REG_INT);
mutex_unlock(&chip->lock);
if (ret < 0)
goto error_ret;
ret = !!(ret & 0x30);
error_ret:
return ret;
return ret;
return !!(ret & 0x30);
}
/*--------------------------------------------------------------*/
/* Probe, Attach, Remove */
/*--------------------------------------------------------------*/
static struct i2c_driver tsl2563_i2c_driver;
static const struct iio_info tsl2563_info_no_irq = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2563_read_raw,
......
......@@ -225,6 +225,7 @@ static int hid_time_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, time_state);
spin_lock_init(&time_state->lock_last_time);
init_completion(&time_state->comp_last_time);
time_state->common_attributes.hsdev = hsdev;
time_state->common_attributes.pdev = pdev;
......
......@@ -12,19 +12,6 @@ config IIO_ST_HWMON
map allows IIO devices to provide basic hwmon functionality
for those channels specified in the map.
if IIO_BUFFER
config IIO_SW_RING
select IIO_TRIGGER
tristate "Industrial I/O lock free software ring"
help
Example software ring buffer implementation. The design aim
of this particular realization was to minimize write locking
with the intention that some devices would be able to write
in interrupt context.
endif # IIO_BUFFER
source "drivers/staging/iio/accel/Kconfig"
source "drivers/staging/iio/adc/Kconfig"
source "drivers/staging/iio/addac/Kconfig"
......@@ -32,7 +19,6 @@ source "drivers/staging/iio/cdc/Kconfig"
source "drivers/staging/iio/frequency/Kconfig"
source "drivers/staging/iio/gyro/Kconfig"
source "drivers/staging/iio/impedance-analyzer/Kconfig"
source "drivers/staging/iio/imu/Kconfig"
source "drivers/staging/iio/light/Kconfig"
source "drivers/staging/iio/magnetometer/Kconfig"
source "drivers/staging/iio/meter/Kconfig"
......
......@@ -2,8 +2,6 @@
# Makefile for the industrial I/O core.
#
obj-$(CONFIG_IIO_SW_RING) += ring_sw.o
obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o
iio_dummy-y := iio_simple_dummy.o
iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o
......@@ -20,7 +18,6 @@ obj-y += cdc/
obj-y += frequency/
obj-y += gyro/
obj-y += impedance-analyzer/
obj-y += imu/
obj-y += light/
obj-y += magnetometer/
obj-y += meter/
......
......@@ -56,45 +56,17 @@ config ADIS16240
Say yes here to build support for Analog Devices adis16240 programmable
impact Sensor and recorder.
config KXSD9
tristate "Kionix KXSD9 Accelerometer Driver"
depends on SPI
help
Say yes here to build support for the Kionix KXSD9 accelerometer.
Currently this only supports the device via an SPI interface.
config LIS3L02DQ
tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver"
depends on SPI
select IIO_TRIGGER if IIO_BUFFER
depends on !IIO_BUFFER || IIO_KFIFO_BUF || IIO_SW_RING
depends on !IIO_BUFFER || IIO_KFIFO_BUF
depends on GENERIC_GPIO
help
Say yes here to build SPI support for the ST microelectronics
accelerometer. The driver supplies direct access via sysfs files
and an event interface via a character device.
choice
prompt "Buffer type"
depends on LIS3L02DQ && IIO_BUFFER
config LIS3L02DQ_BUF_KFIFO
depends on IIO_KFIFO_BUF
bool "Simple FIFO"
help
Kfifo based FIFO. Does not provide any events so it is up
to userspace to ensure it reads often enough that data is not
lost.
config LIS3L02DQ_BUF_RING_SW
depends on IIO_SW_RING
bool "IIO Software Ring"
help
Original IIO ring buffer implementation. Provides simple
buffer events, half full etc.
endchoice
config SCA3000
depends on IIO_BUFFER
depends on SPI
......
......@@ -20,8 +20,6 @@ obj-$(CONFIG_ADIS16220) += adis16220.o
adis16240-y := adis16240_core.o
obj-$(CONFIG_ADIS16240) += adis16240.o
obj-$(CONFIG_KXSD9) += kxsd9.o
lis3l02dq-y := lis3l02dq_core.o
lis3l02dq-$(CONFIG_IIO_BUFFER) += lis3l02dq_ring.o
obj-$(CONFIG_LIS3L02DQ) += lis3l02dq.o
......
......@@ -185,14 +185,6 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
int lis3l02dq_configure_buffer(struct iio_dev *indio_dev);
void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev);
#ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
#define lis3l02dq_free_buf iio_sw_rb_free
#define lis3l02dq_alloc_buf iio_sw_rb_allocate
#endif
#ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
#define lis3l02dq_free_buf iio_kfifo_free
#define lis3l02dq_alloc_buf iio_kfifo_allocate
#endif
irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
......
......@@ -7,7 +7,6 @@
#include <linux/export.h>
#include <linux/iio/iio.h>
#include "../ring_sw.h"
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
......@@ -318,7 +317,7 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev)
{
iio_dealloc_pollfunc(indio_dev->pollfunc);
lis3l02dq_free_buf(indio_dev->buffer);
iio_kfifo_free(indio_dev->buffer);
}
static int lis3l02dq_buffer_postenable(struct iio_dev *indio_dev)
......@@ -401,7 +400,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
int ret;
struct iio_buffer *buffer;
buffer = lis3l02dq_alloc_buf(indio_dev);
buffer = iio_kfifo_allocate(indio_dev);
if (!buffer)
return -ENOMEM;
......@@ -427,6 +426,6 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
return 0;
error_iio_sw_rb_free:
lis3l02dq_free_buf(indio_dev->buffer);
iio_kfifo_free(indio_dev->buffer);
return ret;
}
......@@ -119,12 +119,12 @@ config LPC32XX_ADC
via sysfs.
config MXS_LRADC
tristate "Freescale i.MX28 LRADC"
tristate "Freescale i.MX23/i.MX28 LRADC"
depends on ARCH_MXS
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for i.MX28 LRADC convertor
Say yes here to build support for i.MX23/i.MX28 LRADC convertor
built into these chips.
To compile this driver as a module, choose M here: the
......
This diff is collapsed.
......@@ -10,13 +10,6 @@ config ADIS16060
Say yes here to build support for Analog Devices adis16060 wide bandwidth
yaw rate gyroscope with SPI.
config ADIS16080
tristate "Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver"
depends on SPI
help
Say yes here to build support for Analog Devices adis16080/100 Yaw Rate
Gyroscope with SPI.
config ADIS16130
tristate "Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"
depends on SPI
......
......@@ -5,17 +5,11 @@
adis16060-y := adis16060_core.o
obj-$(CONFIG_ADIS16060) += adis16060.o
adis16080-y := adis16080_core.o
obj-$(CONFIG_ADIS16080) += adis16080.o
adis16130-y := adis16130_core.o
obj-$(CONFIG_ADIS16130) += adis16130.o
adis16260-y := adis16260_core.o
obj-$(CONFIG_ADIS16260) += adis16260.o
adis16251-y := adis16251_core.o
obj-$(CONFIG_ADIS16251) += adis16251.o
adxrs450-y := adxrs450_core.o
obj-$(CONFIG_ADXRS450) += adxrs450.o
......@@ -93,7 +93,7 @@ static int iio_hwmon_probe(struct platform_device *pdev)
while (st->channels[st->num_channels].indio_dev)
st->num_channels++;
st->attrs = kzalloc(sizeof(st->attrs) * (st->num_channels + 1),
st->attrs = kzalloc(sizeof(*st->attrs) * (st->num_channels + 1),
GFP_KERNEL);
if (st->attrs == NULL) {
ret = -ENOMEM;
......
......@@ -7,7 +7,7 @@ config AD5933
tristate "Analog Devices AD5933, AD5934 driver"
depends on I2C
select IIO_BUFFER
select IIO_SW_RING
select IIO_KFIFO_BUF
help
Say yes here to build support for Analog Devices Impedance Converter,
Network Analyzer, AD5933/4, provides direct access via sysfs.
......
......@@ -22,7 +22,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include "../ring_sw.h"
#include <linux/iio/kfifo_buf.h>
#include "ad5933.h"
......@@ -630,7 +630,7 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = {
static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
indio_dev->buffer = iio_kfifo_allocate(indio_dev);
if (!indio_dev->buffer)
return -ENOMEM;
......@@ -774,7 +774,7 @@ static int ad5933_probe(struct i2c_client *client,
error_uninitialize_ring:
iio_buffer_unregister(indio_dev);
error_unreg_ring:
iio_sw_rb_free(indio_dev->buffer);
iio_kfifo_free(indio_dev->buffer);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
......@@ -794,7 +794,7 @@ static int ad5933_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_buffer_unregister(indio_dev);
iio_sw_rb_free(indio_dev->buffer);
iio_kfifo_free(indio_dev->buffer);
if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
regulator_put(st->reg);
......
#
# IIO imu drivers configuration
#
menu "Inertial measurement units"
config ADIS16400
tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
depends on SPI
select IIO_SW_RING if IIO_BUFFER
select IIO_TRIGGER if IIO_BUFFER
help
Say yes here to build support for Analog Devices adis16300, adis16344,
adis16350, adis16354, adis16355, adis16360, adis16362, adis16364,
adis16365, adis16400 and adis16405 triaxial inertial sensors
(adis16400 series also have magnetometers).
endmenu
#
# Makefile for Inertial Measurement Units
#
adis16400-y := adis16400_core.o
adis16400-$(CONFIG_IIO_BUFFER) += adis16400_ring.o adis16400_trigger.o
obj-$(CONFIG_ADIS16400) += adis16400.o
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/iio/iio.h>
#include "../ring_sw.h"
#include <linux/iio/trigger_consumer.h>
#include "adis16400.h"
/**
* adis16400_spi_read_burst() - read all data registers
* @indio_dev: the IIO device
* @rx: somewhere to pass back the value read (min size is 24 bytes)
**/
static int adis16400_spi_read_burst(struct iio_dev *indio_dev, u8 *rx)
{
struct spi_message msg;
struct adis16400_state *st = iio_priv(indio_dev);
u32 old_speed_hz = st->us->max_speed_hz;
int ret;
struct spi_transfer xfers[] = {
{
.tx_buf = st->tx,
.bits_per_word = 8,
.len = 2,
}, {
.rx_buf = rx,
.bits_per_word = 8,
.len = 24,
},
};
mutex_lock(&st->buf_lock);
st->tx[0] = ADIS16400_READ_REG(ADIS16400_GLOB_CMD);
st->tx[1] = 0;
spi_message_init(&msg);
spi_message_add_tail(&xfers[0], &msg);
spi_message_add_tail(&xfers[1], &msg);
st->us->max_speed_hz = min(ADIS16400_SPI_BURST, old_speed_hz);
spi_setup(st->us);
ret = spi_sync(st->us, &msg);
if (ret)
dev_err(&st->us->dev, "problem when burst reading");
st->us->max_speed_hz = old_speed_hz;
spi_setup(st->us);
mutex_unlock(&st->buf_lock);
return ret;
}
static const u16 read_all_tx_array[] = {
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_SUPPLY_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XGYRO_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YGYRO_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZGYRO_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XACCL_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YACCL_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZACCL_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16350_XTEMP_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16350_YTEMP_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16350_ZTEMP_OUT)),
cpu_to_be16(ADIS16400_READ_REG(ADIS16400_AUX_ADC)),
};
static int adis16350_spi_read_all(struct iio_dev *indio_dev, u8 *rx)
{
struct adis16400_state *st = iio_priv(indio_dev);
struct spi_message msg;
int i, j = 0, ret;
struct spi_transfer *xfers;
int scan_count = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength);
xfers = kzalloc(sizeof(*xfers)*(scan_count + 1),
GFP_KERNEL);
if (xfers == NULL)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
if (test_bit(i, indio_dev->active_scan_mask)) {
xfers[j].tx_buf = &read_all_tx_array[i];
xfers[j].bits_per_word = 16;
xfers[j].len = 2;
xfers[j + 1].rx_buf = rx + j*2;
j++;
}
xfers[j].bits_per_word = 16;
xfers[j].len = 2;
spi_message_init(&msg);
for (j = 0; j < scan_count + 1; j++)
spi_message_add_tail(&xfers[j], &msg);
ret = spi_sync(st->us, &msg);
kfree(xfers);
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 adis16400_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16400_state *st = iio_priv(indio_dev);
int i = 0, j, ret = 0;
s16 *data;
/* Asumption that long is enough for maximum channels */
unsigned long mask = *indio_dev->active_scan_mask;
int scan_count = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength);
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 (scan_count) {
if (st->variant->flags & ADIS16400_NO_BURST) {
ret = adis16350_spi_read_all(indio_dev, st->rx);
if (ret < 0)
goto done;
for (; i < scan_count; i++)
data[i] = *(s16 *)(st->rx + i*2);
} else {
ret = adis16400_spi_read_burst(indio_dev, st->rx);
if (ret < 0)
goto done;
for (; i < scan_count; i++) {
j = __ffs(mask);
mask &= ~(1 << j);
data[i] = be16_to_cpup(
(__be16 *)&(st->rx[j*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);
done:
kfree(data);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
void adis16400_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 adis16400_ring_setup_ops = {
.preenable = &iio_sw_buffer_preenable,
.postenable = &iio_triggered_buffer_postenable,
.predisable = &iio_triggered_buffer_predisable,
};
int adis16400_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 = &adis16400_ring_setup_ops;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
&adis16400_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 "adis16400.h"
/**
* adis16400_data_rdy_trigger_set_state() set datardy interrupt state
**/
static int adis16400_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 adis16400_set_irq(indio_dev, state);
}
static const struct iio_trigger_ops adis16400_trigger_ops = {
.owner = THIS_MODULE,
.set_trigger_state = &adis16400_data_rdy_trigger_set_state,
};
int adis16400_probe_trigger(struct iio_dev *indio_dev)
{
int ret;
struct adis16400_state *st = iio_priv(indio_dev);
st->trig = iio_trigger_alloc("%s-dev%d",
indio_dev->name,
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,
"adis16400",
st->trig);
if (ret)
goto error_free_trig;
st->trig->dev.parent = &st->us->dev;
st->trig->private_data = indio_dev;
st->trig->ops = &adis16400_trigger_ops;
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 adis16400_remove_trigger(struct iio_dev *indio_dev)
{
struct adis16400_state *st = iio_priv(indio_dev);
iio_trigger_unregister(st->trig);
free_irq(st->us->irq, st->trig);
iio_trigger_free(st->trig);
}
......@@ -25,16 +25,6 @@ config SENSORS_ISL29028
Proximity value via iio. The ISL29028 provides the concurrent sensing
of ambient light and proximity.
config SENSORS_TSL2563
tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
depends on I2C
help
If you say yes here you get support for the Taos TSL2560,
TSL2561, TSL2562 and TSL2563 ambient light sensors.
This driver can also be built as a module. If so, the module
will be called tsl2563.
config TSL2583
tristate "TAOS TSL2580, TSL2581 and TSL2583 light-to-digital converters"
depends on I2C
......
......@@ -2,7 +2,6 @@
# Makefile for industrial I/O Light sensors
#
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o
obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
obj-$(CONFIG_TSL2583) += tsl2583.o
......
......@@ -291,59 +291,6 @@ static const u8 device_channel_config[] = {
ALSPRX2
};
/**
* tsl2x7x_parse_buffer() - parse a decimal result from a buffer.
* @*buf: pointer to char buffer to parse
* @*result: pointer to buffer to contain
* resulting interger / decimal as ints.
*
*/
static int
tsl2x7x_parse_buffer(const char *buf, struct tsl2x7x_parse_result *result)
{
int integer = 0, fract = 0, fract_mult = 100000;
bool integer_part = true, negative = false;
if (buf[0] == '-') {
negative = true;
buf++;
}
while (*buf) {
if ('0' <= *buf && *buf <= '9') {
if (integer_part)
integer = integer*10 + *buf - '0';
else {
fract += fract_mult*(*buf - '0');
if (fract_mult == 1)
break;
fract_mult /= 10;
}
} else if (*buf == '\n') {
if (*(buf + 1) == '\0')
break;
else
return -EINVAL;
} else if (*buf == '.') {
integer_part = false;
} else {
return -EINVAL;
}
buf++;
}
if (negative) {
if (integer)
integer = -integer;
else
fract = -fract;
}
result->integer = integer;
result->fract = fract;
return 0;
}
/**
* tsl2x7x_i2c_read() - Read a byte from a register.
* @client: i2c client
......@@ -1036,13 +983,12 @@ static ssize_t tsl2x7x_als_time_store(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
struct tsl2x7x_parse_result result;
int ret;
result.integer = 0;
result.fract = 0;
tsl2x7x_parse_buffer(buf, &result);
ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
if (ret)
return ret;
result.fract /= 1000;
result.fract /= 3;
chip->tsl2x7x_settings.als_time =
(TSL2X7X_MAX_TIMER_CNT - (u8)result.fract);
......@@ -1109,12 +1055,12 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev,
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
struct tsl2x7x_parse_result result;
int y, z, filter_delay;
int ret;
result.integer = 0;
result.fract = 0;
tsl2x7x_parse_buffer(buf, &result);
ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
if (ret)
return ret;
result.fract /= 1000;
y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
z = y * TSL2X7X_MIN_ITIME;
......@@ -1155,12 +1101,12 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev,
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
struct tsl2x7x_parse_result result;
int y, z, filter_delay;
int ret;
result.integer = 0;
result.fract = 0;
tsl2x7x_parse_buffer(buf, &result);
ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
if (ret)
return ret;
result.fract /= 1000;
y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
z = y * TSL2X7X_MIN_ITIME;
......
......@@ -21,7 +21,7 @@ config ADE7758
tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver"
depends on SPI
select IIO_TRIGGER if IIO_BUFFER
select IIO_SW_RING if IIO_BUFFER
select IIO_KFIFO_BUF if IIO_BUFFER
help
Say yes here to build support for Analog Devices ADE7758 Polyphase
Multifunction Energy Metering IC with Per Phase Information Driver.
......
......@@ -13,7 +13,7 @@
#include <asm/unaligned.h>
#include <linux/iio/iio.h>
#include "../ring_sw.h"
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger_consumer.h>
#include "ade7758.h"
......@@ -119,7 +119,7 @@ static const struct iio_buffer_setup_ops ade7758_ring_setup_ops = {
void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
{
iio_dealloc_pollfunc(indio_dev->pollfunc);
iio_sw_rb_free(indio_dev->buffer);
iio_kfifo_free(indio_dev->buffer);
}
int ade7758_configure_ring(struct iio_dev *indio_dev)
......@@ -127,7 +127,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
struct ade7758_state *st = iio_priv(indio_dev);
int ret = 0;
indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
indio_dev->buffer = iio_kfifo_allocate(indio_dev);
if (!indio_dev->buffer) {
ret = -ENOMEM;
return ret;
......@@ -143,7 +143,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
indio_dev->id);
if (indio_dev->pollfunc == NULL) {
ret = -ENOMEM;
goto error_iio_sw_rb_free;
goto error_iio_kfifo_free;
}
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
......@@ -183,8 +183,8 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
return 0;
error_iio_sw_rb_free:
iio_sw_rb_free(indio_dev->buffer);
error_iio_kfifo_free:
iio_kfifo_free(indio_dev->buffer);
return ret;
}
......
This diff is collapsed.
/* The industrial I/O simple minimally locked ring buffer.
*
* Copyright (c) 2008 Jonathan Cameron
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This code is deliberately kept separate from the main industrialio I/O core
* as it is intended that in the future a number of different software ring
* buffer implementations will exist with different characteristics to suit
* different applications.
*
* This particular one was designed for a data capture application where it was
* particularly important that no userspace reads would interrupt the capture
* process. To this end the ring is not locked during a read.
*
* Comments on this buffer design welcomed. It's far from efficient and some of
* my understanding of the effects of scheduling on this are somewhat limited.
* Frankly, to my mind, this is the current weak point in the industrial I/O
* patch set.
*/
#ifndef _IIO_RING_SW_H_
#define _IIO_RING_SW_H_
#include <linux/iio/buffer.h>
struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
void iio_sw_rb_free(struct iio_buffer *ring);
#endif /* _IIO_RING_SW_H_ */
......@@ -6,4 +6,3 @@ struct tsl2563_platform_data {
};
#endif /* __LINUX_TSL2563_H */
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