Skip to content

Commit

Permalink
iio:common: Add STMicroelectronics common library
Browse files Browse the repository at this point in the history
This patch add a generic library for STMicroelectronics 3-axis sensors.

Signed-off-by: Denis Ciocca <denis.ciocca@st.com>
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
  • Loading branch information
Denis Ciocca authored and Jonathan Cameron committed Jan 31, 2013
1 parent 085494a commit 23491b5
Show file tree
Hide file tree
Showing 12 changed files with 1,202 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/iio/common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
#

source "drivers/iio/common/hid-sensors/Kconfig"
source "drivers/iio/common/st_sensors/Kconfig"
1 change: 1 addition & 0 deletions drivers/iio/common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
#

obj-y += hid-sensors/
obj-y += st_sensors/
14 changes: 14 additions & 0 deletions drivers/iio/common/st_sensors/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# STMicroelectronics sensors common library
#

config IIO_ST_SENSORS_I2C
tristate

config IIO_ST_SENSORS_SPI
tristate

config IIO_ST_SENSORS_CORE
tristate
select IIO_ST_SENSORS_I2C if I2C
select IIO_ST_SENSORS_SPI if SPI_MASTER
10 changes: 10 additions & 0 deletions drivers/iio/common/st_sensors/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Makefile for the STMicroelectronics sensor common modules.
#

obj-$(CONFIG_IIO_ST_SENSORS_I2C) += st_sensors_i2c.o
obj-$(CONFIG_IIO_ST_SENSORS_SPI) += st_sensors_spi.o
obj-$(CONFIG_IIO_ST_SENSORS_CORE) += st_sensors.o
st_sensors-y := st_sensors_core.o
st_sensors-$(CONFIG_IIO_BUFFER) += st_sensors_buffer.o
st_sensors-$(CONFIG_IIO_TRIGGER) += st_sensors_trigger.o
116 changes: 116 additions & 0 deletions drivers/iio/common/st_sensors/st_sensors_buffer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* STMicroelectronics sensors buffer library driver
*
* Copyright 2012-2013 STMicroelectronics Inc.
*
* Denis Ciocca <denis.ciocca@st.com>
*
* Licensed under the GPL-2.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/interrupt.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/irqreturn.h>

#include <linux/iio/common/st_sensors.h>


int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf)
{
int i, n = 0, len;
u8 addr[ST_SENSORS_NUMBER_DATA_CHANNELS];
struct st_sensor_data *sdata = iio_priv(indio_dev);

for (i = 0; i < ST_SENSORS_NUMBER_DATA_CHANNELS; i++) {
if (test_bit(i, indio_dev->active_scan_mask)) {
addr[n] = indio_dev->channels[i].address;
n++;
}
}
switch (n) {
case 1:
len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
addr[0], ST_SENSORS_BYTE_FOR_CHANNEL, buf,
sdata->multiread_bit);
break;
case 2:
if ((addr[1] - addr[0]) == ST_SENSORS_BYTE_FOR_CHANNEL) {
len = sdata->tf->read_multiple_byte(&sdata->tb,
sdata->dev, addr[0],
ST_SENSORS_BYTE_FOR_CHANNEL*n,
buf, sdata->multiread_bit);
} else {
u8 rx_array[ST_SENSORS_BYTE_FOR_CHANNEL*
ST_SENSORS_NUMBER_DATA_CHANNELS];
len = sdata->tf->read_multiple_byte(&sdata->tb,
sdata->dev, addr[0],
ST_SENSORS_BYTE_FOR_CHANNEL*
ST_SENSORS_NUMBER_DATA_CHANNELS,
rx_array, sdata->multiread_bit);
if (len < 0)
goto read_data_channels_error;

for (i = 0; i < n * ST_SENSORS_NUMBER_DATA_CHANNELS;
i++) {
if (i < n)
buf[i] = rx_array[i];
else
buf[i] = rx_array[n + i];
}
len = ST_SENSORS_BYTE_FOR_CHANNEL*n;
}
break;
case 3:
len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
addr[0], ST_SENSORS_BYTE_FOR_CHANNEL*
ST_SENSORS_NUMBER_DATA_CHANNELS,
buf, sdata->multiread_bit);
break;
default:
len = -EINVAL;
goto read_data_channels_error;
}
if (len != ST_SENSORS_BYTE_FOR_CHANNEL*n) {
len = -EIO;
goto read_data_channels_error;
}

read_data_channels_error:
return len;
}
EXPORT_SYMBOL(st_sensors_get_buffer_element);

irqreturn_t st_sensors_trigger_handler(int irq, void *p)
{
int len;
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct st_sensor_data *sdata = iio_priv(indio_dev);

len = st_sensors_get_buffer_element(indio_dev, sdata->buffer_data);
if (len < 0)
goto st_sensors_get_buffer_element_error;

if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)sdata->buffer_data +
ALIGN(len, sizeof(s64))) = pf->timestamp;

iio_push_to_buffers(indio_dev, sdata->buffer_data);

st_sensors_get_buffer_element_error:
iio_trigger_notify_done(indio_dev->trig);

return IRQ_HANDLED;
}
EXPORT_SYMBOL(st_sensors_trigger_handler);

MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics ST-sensors buffer");
MODULE_LICENSE("GPL v2");
Loading

0 comments on commit 23491b5

Please sign in to comment.