Commit 3ffdea3f authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-3.13a' of...

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

Jonathan writes:

First round of new drivers, functionality and cleanups for IIO in the 3.13 cycle

A number of new drivers and some new functionality + a lot of cleanups
all over IIO.

New Core Elements

1) New INT_TIME info_mask element for integration time, which may have
   different effects on measurement noise and similar, than an amplifier
   and hence is different from existing SCALE.  Already existed in some
   drivers as a custom attribute.

2) Introduce a iio_push_buffers_with_timestamp helper to cover the common
   case of filling the last 64 bits of data to be passed to the buffer with
   a timestamp.  Applied to lots of drivers. Cuts down on repeated code and
   moves a slightly fiddly bit of logic into a single location.

3) Introduce info_mask_[shared_by_dir/shared_by_all] elements to allow support
   of elements such as sampling_frequency which is typically shared by all
   input channels on a device.  This reduces code and makes these controls
   available from in kernel consumers of IIO devices.

New drivers

1) MCP3422/3/4 ADC

2) TSL4531 ambient light sensor

3) TCS3472/5 color light sensor

4) GP2AP020A00F ambient light / proximity sensor

5) LPS001WP support added to ST pressure sensor driver.

New driver functionality

1) ti_am335x_adc Add buffered sampling support.
   This device has a hardware fifo that is fed directly into an IIO kfifo
   buffer based on a watershed interrupt.  Note this will act as an example
   of how to handle this increasingly common type of device.
   The only previous example - sca3000 - take a less than optimal approach
   which is largely why it is still in staging.
   A couple of little cleanups for that new functionality followed later.

Core cleanups:

1) MAINTAINERS - Sachin actually brought my email address up to date because
   I said I'd do it and never got around to it :)

2) Assign buffer list elements as single element lists to simplify the
   iio_buffer_is_active logic.

3) wake_up_interruptible_poll instead of wake_up_interruptible to only wake
   up threads waiting for poll notifications.

4) Add O_CLOEXEC flag to anon_inode_get_fd call for IIO event interface.

5) Change iio_push_to_buffers to take a void * pointer so as to avoid some
   annoying and unnecessary type casts.

6) iio_compute_scan_bytes incorrectly took a long rather than unsigned long.

7) Various minor tidy ups.

Driver cleanups (in no particular order)

1) Another set of devm_ allocations patches from Sachin Kamat.

2) tsl2x7x - 0 to NULL cleanup.

3) hmc5843 - fix missing > in MODULE_AUTHOR

4) Set of strict_strto* to kstrto* conversions.

5) mxs-lradc - fix ordering of resource removal to match creation

6) mxs-lradc - add MODULE_ALIAS

7) adc7606 - drop a work pending test duplicated in core functions.

8) hmc5843 - devm_ allocation patch

9) Series of redundant breaks removed.

10) ad2s1200 - pr_err -> dev_err

11) adjd_s311 - use INT_TIME

12)  ST sensors - large set of cleanups from Lee Jones and removed restriction
    to using only triggers provided by the st_sensors themselves from
    Dennis Ciocca.

13) dummy and tmp006 provide sampling_frequency via info_mask_shared_by_all.

14) tcs3472 - fix incorrect buffer size and wrong device pointer used in
    suspend / resume functions.

15) max1363 - use defaults for buffer setup ops as provided by the triggered
    buffer helpers as they are the same as were specified in max1363 driver.

16) Trivial tidy ups in a number of other drivers.
parents 9076b09e 074b6a8d
......@@ -811,3 +811,14 @@ Description:
Writing '1' stores the current device configuration into
on-chip EEPROM. After power-up or chip reset the device will
automatically load the saved configuration.
What: /sys/.../iio:deviceX/in_intensity_red_integration_time
What: /sys/.../iio:deviceX/in_intensity_green_integration_time
What: /sys/.../iio:deviceX/in_intensity_blue_integration_time
What: /sys/.../iio:deviceX/in_intensity_clear_integration_time
What: /sys/.../iio:deviceX/in_illuminance_integration_time
KernelVersion: 3.12
Contact: linux-iio@vger.kernel.org
Description:
This attribute is used to get/set the integration time in
seconds.
* Sharp GP2AP020A00F I2C Proximity/ALS sensor
The proximity detector sensor requires power supply
for its built-in led. It is also defined by this binding.
Required properties:
- compatible : should be "sharp,gp2ap020a00f"
- reg : the I2C slave address of the light sensor
- interrupts : interrupt specifier for the sole interrupt generated
by the device
- vled-supply : VLED power supply, as covered in ../regulator/regulator.txt
Example:
gp2ap020a00f@39 {
compatible = "sharp,gp2ap020a00f";
reg = <0x39>;
interrupts = <2 0>;
vled-supply = <...>;
};
......@@ -4195,7 +4195,7 @@ S: Maintained
F: drivers/media/rc/iguanair.c
IIO SUBSYSTEM AND DRIVERS
M: Jonathan Cameron <jic23@cam.ac.uk>
M: Jonathan Cameron <jic23@kernel.org>
L: linux-iio@vger.kernel.org
S: Maintained
F: drivers/iio/
......@@ -7947,7 +7947,7 @@ S: Maintained
F: drivers/staging/media/go7007/
STAGING - INDUSTRIAL IO
M: Jonathan Cameron <jic23@cam.ac.uk>
M: Jonathan Cameron <jic23@kernel.org>
L: linux-iio@vger.kernel.org
S: Odd Fixes
F: drivers/staging/iio/
......
......@@ -471,13 +471,10 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct bma180_data *data = iio_priv(indio_dev);
int64_t time_ns = iio_get_time_ns();
int bit, ret, i = 0;
mutex_lock(&data->mutex);
if (indio_dev->scan_timestamp) {
ret = indio_dev->scan_bytes / sizeof(s64) - 1;
((s64 *)data->buff)[ret] = iio_get_time_ns();
}
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
indio_dev->masklength) {
......@@ -490,7 +487,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
}
mutex_unlock(&data->mutex);
iio_push_to_buffers(indio_dev, (u8 *)data->buff);
iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
err:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -182,10 +182,11 @@ static const struct iio_info accel_3d_info = {
};
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
int len)
{
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
iio_push_to_buffers(indio_dev, (u8 *)data);
iio_push_to_buffers(indio_dev, data);
}
/* Callback handler to send event after all samples are received and captured */
......@@ -200,7 +201,7 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
accel_state->common_attributes.data_ready);
if (accel_state->common_attributes.data_ready)
hid_sensor_push_data(indio_dev,
(u8 *)accel_state->accel_val,
accel_state->accel_val,
sizeof(accel_state->accel_val));
return 0;
......
......@@ -452,8 +452,9 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
int st_accel_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *plat_data)
{
int err;
struct st_sensor_data *adata = iio_priv(indio_dev);
int irq = adata->get_irq_data_ready(indio_dev);
int err;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &accel_info;
......@@ -461,7 +462,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
if (err < 0)
goto st_accel_common_probe_error;
return err;
adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
adata->multiread_bit = adata->sensor->multi_read_bit;
......@@ -478,13 +479,13 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
err = st_sensors_init_sensor(indio_dev, plat_data);
if (err < 0)
goto st_accel_common_probe_error;
return err;
if (adata->get_irq_data_ready(indio_dev) > 0) {
err = st_accel_allocate_ring(indio_dev);
if (err < 0)
goto st_accel_common_probe_error;
return err;
if (irq > 0) {
err = st_sensors_allocate_trigger(indio_dev,
ST_ACCEL_TRIGGER_OPS);
if (err < 0)
......@@ -495,15 +496,14 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
if (err)
goto st_accel_device_register_error;
return err;
return 0;
st_accel_device_register_error:
if (adata->get_irq_data_ready(indio_dev) > 0)
if (irq > 0)
st_sensors_deallocate_trigger(indio_dev);
st_accel_probe_trigger_error:
if (adata->get_irq_data_ready(indio_dev) > 0)
st_accel_deallocate_ring(indio_dev);
st_accel_common_probe_error:
return err;
}
EXPORT_SYMBOL(st_accel_common_probe);
......@@ -513,10 +513,10 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
struct st_sensor_data *adata = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (adata->get_irq_data_ready(indio_dev) > 0) {
if (adata->get_irq_data_ready(indio_dev) > 0)
st_sensors_deallocate_trigger(indio_dev);
st_accel_deallocate_ring(indio_dev);
}
}
EXPORT_SYMBOL(st_accel_common_remove);
......
......@@ -145,6 +145,16 @@ config MCP320X
This driver can also be built as a module. If so, the module will be
called mcp320x.
config MCP3422
tristate "Microchip Technology MCP3422/3/4 driver"
depends on I2C
help
Say yes here to build support for Microchip Technology's MCP3422,
MCP3423 or MCP3424 analog to digital converters.
This driver can also be built as a module. If so, the module will be
called mcp3422.
config NAU7802
tristate "Nuvoton NAU7802 ADC driver"
depends on I2C
......@@ -167,6 +177,7 @@ config TI_ADC081C
config TI_AM335X_ADC
tristate "TI's AM335X ADC driver"
depends on MFD_TI_AM335X_TSCADC
select IIO_KFIFO_BUF
help
Say yes here to build support for Texas Instruments ADC
driver which is also a MFD client.
......
......@@ -16,6 +16,7 @@ obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
......
......@@ -96,9 +96,8 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
ret = spi_read(st->spi, st->data, 4);
if (ret == 0) {
if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = pf->timestamp;
iio_push_to_buffers(indio_dev, (u8 *)st->data);
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
pf->timestamp);
}
iio_trigger_notify_done(indio_dev->trig);
......@@ -293,7 +292,7 @@ static const struct iio_info ad7266_info = {
.driver_module = THIS_MODULE,
};
static unsigned long ad7266_available_scan_masks[] = {
static const unsigned long ad7266_available_scan_masks[] = {
0x003,
0x00c,
0x030,
......@@ -303,14 +302,14 @@ static unsigned long ad7266_available_scan_masks[] = {
0x000,
};
static unsigned long ad7266_available_scan_masks_diff[] = {
static const unsigned long ad7266_available_scan_masks_diff[] = {
0x003,
0x00c,
0x030,
0x000,
};
static unsigned long ad7266_available_scan_masks_fixed[] = {
static const unsigned long ad7266_available_scan_masks_fixed[] = {
0x003,
0x000,
};
......@@ -318,7 +317,7 @@ static unsigned long ad7266_available_scan_masks_fixed[] = {
struct ad7266_chan_info {
const struct iio_chan_spec *channels;
unsigned int num_channels;
unsigned long *scan_masks;
const unsigned long *scan_masks;
};
#define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \
......
......@@ -159,20 +159,14 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7298_state *st = iio_priv(indio_dev);
s64 time_ns = 0;
int b_sent;
b_sent = spi_sync(st->spi, &st->ring_msg);
if (b_sent)
goto done;
if (indio_dev->scan_timestamp) {
time_ns = iio_get_time_ns();
memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
}
iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
iio_get_time_ns());
done:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -64,19 +64,14 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7476_state *st = iio_priv(indio_dev);
s64 time_ns;
int b_sent;
b_sent = spi_sync(st->spi, &st->msg);
if (b_sent < 0)
goto done;
time_ns = iio_get_time_ns();
if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = time_ns;
iio_push_to_buffers(indio_dev, st->data);
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
iio_get_time_ns());
done:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -121,20 +121,14 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7887_state *st = iio_priv(indio_dev);
s64 time_ns;
int b_sent;
b_sent = spi_sync(st->spi, st->ring_msg);
if (b_sent)
goto done;
time_ns = iio_get_time_ns();
if (indio_dev->scan_timestamp)
memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
iio_push_to_buffers(indio_dev, st->data);
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
iio_get_time_ns());
done:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -174,20 +174,14 @@ static irqreturn_t ad7923_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7923_state *st = iio_priv(indio_dev);
s64 time_ns = 0;
int b_sent;
b_sent = spi_sync(st->spi, &st->ring_msg);
if (b_sent)
goto done;
if (indio_dev->scan_timestamp) {
time_ns = iio_get_time_ns();
memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
}
iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
iio_get_time_ns());
done:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -368,10 +368,6 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
memset(data, 0x00, 16);
/* Guaranteed to be aligned with 8 byte boundary */
if (indio_dev->scan_timestamp)
((s64 *)data)[1] = pf->timestamp;
reg_size = indio_dev->channels[0].scan_type.realbits +
indio_dev->channels[0].scan_type.shift;
reg_size = DIV_ROUND_UP(reg_size, 8);
......@@ -391,7 +387,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
break;
}
iio_push_to_buffers(indio_dev, (uint8_t *)data);
iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
sigma_delta->irq_dis = false;
......
......@@ -83,13 +83,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
j++;
}
if (idev->scan_timestamp) {
s64 *timestamp = (s64 *)((u8 *)st->buffer +
ALIGN(j, sizeof(s64)));
*timestamp = pf->timestamp;
}
iio_push_to_buffers(idev, (u8 *)st->buffer);
iio_push_to_buffers_with_timestamp(idev, st->buffer, pf->timestamp);
iio_trigger_notify_done(idev->trig);
......@@ -279,7 +273,7 @@ static int at91_adc_trigger_init(struct iio_dev *idev)
int i, ret;
st->trig = devm_kzalloc(&idev->dev,
st->trigger_number * sizeof(st->trig),
st->trigger_number * sizeof(*st->trig),
GFP_KERNEL);
if (st->trig == NULL) {
......
......@@ -1436,7 +1436,6 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct max1363_state *st = iio_priv(indio_dev);
s64 time_ns;
__u8 *rxbuf;
int b_sent;
size_t d_size;
......@@ -1470,11 +1469,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
if (b_sent < 0)
goto done_free;
time_ns = iio_get_time_ns();
if (indio_dev->scan_timestamp)
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
iio_push_to_buffers(indio_dev, rxbuf);
iio_push_to_buffers_with_timestamp(indio_dev, rxbuf, iio_get_time_ns());
done_free:
kfree(rxbuf);
......@@ -1484,12 +1479,6 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
return IRQ_HANDLED;
}
static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = {
.postenable = &iio_triggered_buffer_postenable,
.preenable = &iio_sw_buffer_preenable,
.predisable = &iio_triggered_buffer_predisable,
};
static int max1363_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -1559,7 +1548,7 @@ static int max1363_probe(struct i2c_client *client,
goto error_disable_reg;
ret = iio_triggered_buffer_setup(indio_dev, NULL,
&max1363_trigger_handler, &max1363_buffered_setup_ops);
&max1363_trigger_handler, NULL);
if (ret)
goto error_disable_reg;
......
This diff is collapsed.
......@@ -28,12 +28,16 @@
#include <linux/iio/driver.h>
#include <linux/mfd/ti_am335x_tscadc.h>
#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
struct tiadc_device {
struct ti_tscadc_dev *mfd_tscadc;
int channels;
u8 channel_line[8];
u8 channel_step[8];
int buffer_en_ch_steps;
u16 data[8];
};
static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
......@@ -56,8 +60,14 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
return step_en;
}
static void tiadc_step_config(struct tiadc_device *adc_dev)
static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
{
return 1 << adc_dev->channel_step[chan];
}
static void tiadc_step_config(struct iio_dev *indio_dev)
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
unsigned int stepconfig;
int i, steps;
......@@ -72,6 +82,10 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
*/
steps = TOTAL_STEPS - adc_dev->channels;
if (iio_buffer_enabled(indio_dev))
stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
| STEPCONFIG_MODE_SWCNT;
else
stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
for (i = 0; i < adc_dev->channels; i++) {
......@@ -85,9 +99,175 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
adc_dev->channel_step[i] = steps;
steps++;
}
}
static irqreturn_t tiadc_irq_h(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct tiadc_device *adc_dev = iio_priv(indio_dev);
unsigned int status, config;
status = tiadc_readl(adc_dev, REG_IRQSTATUS);
/*
* ADC and touchscreen share the IRQ line.
* FIFO0 interrupts are used by TSC. Handle FIFO1 IRQs here only
*/
if (status & IRQENB_FIFO1OVRRUN) {
/* FIFO Overrun. Clear flag. Disable/Enable ADC to recover */
config = tiadc_readl(adc_dev, REG_CTRL);
config &= ~(CNTRLREG_TSCSSENB);
tiadc_writel(adc_dev, REG_CTRL, config);
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN
| IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES);
tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB));
return IRQ_HANDLED;
} else if (status & IRQENB_FIFO1THRES) {
/* Disable irq and wake worker thread */
tiadc_writel(adc_dev, REG_IRQCLR, IRQENB_FIFO1THRES);
return IRQ_WAKE_THREAD;
}
return IRQ_NONE;
}
static irqreturn_t tiadc_worker_h(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct tiadc_device *adc_dev = iio_priv(indio_dev);
int i, k, fifo1count, read;
u16 *data = adc_dev->data;
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
for (k = 0; k < fifo1count; k = k + i) {
for (i = 0; i < (indio_dev->scan_bytes)/2; i++) {
read = tiadc_readl(adc_dev, REG_FIFO1);
data[i] = read & FIFOREAD_DATA_MASK;
}
iio_push_to_buffers(indio_dev, (u8 *) data);
}
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES);
tiadc_writel(adc_dev, REG_IRQENABLE, IRQENB_FIFO1THRES);
return IRQ_HANDLED;
}
static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
int i, fifo1count, read;
tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
IRQENB_FIFO1OVRRUN |
IRQENB_FIFO1UNDRFLW));
/* Flush FIFO. Needed in corner cases in simultaneous tsc/adc use */
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
for (i = 0; i < fifo1count; i++)
read = tiadc_readl(adc_dev, REG_FIFO1);
return iio_sw_buffer_preenable(indio_dev);
}
static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
struct iio_buffer *buffer = indio_dev->buffer;
unsigned int enb = 0;
u8 bit;
tiadc_step_config(indio_dev);
for_each_set_bit(bit, buffer->scan_mask, adc_dev->channels)
enb |= (get_adc_step_bit(adc_dev, bit) << 1);
adc_dev->buffer_en_ch_steps = enb;
am335x_tsc_se_set(adc_dev->mfd_tscadc, enb);
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES
| IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
tiadc_writel(adc_dev, REG_IRQENABLE, IRQENB_FIFO1THRES
| IRQENB_FIFO1OVRRUN);
return 0;
}
static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
int fifo1count, i, read;
tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
/* Flush FIFO of leftover data in the time it takes to disable adc */
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
for (i = 0; i < fifo1count; i++)
read = tiadc_readl(adc_dev, REG_FIFO1);
return 0;
}
static int tiadc_buffer_postdisable(struct iio_dev *indio_dev)
{
tiadc_step_config(indio_dev);
return 0;
}
static const struct iio_buffer_setup_ops tiadc_buffer_setup_ops = {
.preenable = &tiadc_buffer_preenable,
.postenable = &tiadc_buffer_postenable,
.predisable = &tiadc_buffer_predisable,
.postdisable = &tiadc_buffer_postdisable,
};
static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
irqreturn_t (*pollfunc_bh)(int irq, void *p),
irqreturn_t (*pollfunc_th)(int irq, void *p),
int irq,
unsigned long flags,
const struct iio_buffer_setup_ops *setup_ops)
{
int ret;
indio_dev->buffer = iio_kfifo_allocate(indio_dev);
if (!indio_dev->buffer)
return -ENOMEM;
ret = request_threaded_irq(irq, pollfunc_th, pollfunc_bh,
flags, indio_dev->name, indio_dev);
if (ret)
goto error_kfifo_free;
indio_dev->setup_ops = setup_ops;
indio_dev->modes |= INDIO_BUFFER_HARDWARE;
ret = iio_buffer_register(indio_dev,
indio_dev->channels,
indio_dev->num_channels);
if (ret)
goto error_free_irq;
return 0;
error_free_irq:
free_irq(irq, indio_dev);
error_kfifo_free:
iio_kfifo_free(indio_dev->buffer);
return ret;
}
static void tiadc_iio_buffered_hardware_remove(struct iio_dev *indio_dev)
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
free_irq(adc_dev->mfd_tscadc->irq, indio_dev);
iio_kfifo_free(indio_dev->buffer);
iio_buffer_unregister(indio_dev);
}
static const char * const chan_name_ain[] = {
"AIN0",
"AIN1",
......@@ -120,9 +300,10 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
chan->channel = adc_dev->channel_line[i];
chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
chan->datasheet_name = chan_name_ain[chan->channel];
chan->scan_index = i;
chan->scan_type.sign = 'u';
chan->scan_type.realbits = 12;
chan->scan_type.storagebits = 32;
chan->scan_type.storagebits = 16;
}
indio_dev->channels = chan_array;
......@@ -142,11 +323,14 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
struct tiadc_device *adc_dev = iio_priv(indio_dev);
int i, map_val;
unsigned int fifo1count, read, stepid;
u32 step = UINT_MAX;
bool found = false;
u32 step_en;
unsigned long timeout = jiffies + usecs_to_jiffies
(IDLE_TIMEOUT * adc_dev->channels);
if (iio_buffer_enabled(indio_dev))
return -EBUSY;
step_en = get_adc_step_mask(adc_dev);
am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
......@@ -168,15 +352,6 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
* Hence we need to flush out this data.
*/
for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
if (chan->channel == adc_dev->channel_line[i]) {
step = adc_dev->channel_step[i];
break;
}
}
if (WARN_ON_ONCE(step == UINT_MAX))
return -EINVAL;
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
for (i = 0; i < fifo1count; i++) {
read = tiadc_readl(adc_dev, REG_FIFO1);
......@@ -186,7 +361,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
if (stepid == map_val) {
read = read & FIFOREAD_DATA_MASK;
found = true;
*val = read;
*val = (u16) read;
}
}
......@@ -237,20 +412,33 @@ static int tiadc_probe(struct platform_device *pdev)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &tiadc_info;
tiadc_step_config(adc_dev);
tiadc_step_config(indio_dev);
tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD);
err = tiadc_channel_init(indio_dev, adc_dev->channels);
if (err < 0)
return err;
err = iio_device_register(indio_dev);
err = tiadc_iio_buffered_hardware_setup(indio_dev,
&tiadc_worker_h,
&tiadc_irq_h,
adc_dev->mfd_tscadc->irq,
IRQF_SHARED,
&tiadc_buffer_setup_ops);
if (err)
goto err_free_channels;
err = iio_device_register(indio_dev);
if (err)
goto err_buffer_unregister;
platform_set_drvdata(pdev, indio_dev);
return 0;
err_buffer_unregister:
tiadc_iio_buffered_hardware_remove(indio_dev);
err_free_channels:
tiadc_channels_remove(indio_dev);
return err;
......@@ -263,6 +451,7 @@ static int tiadc_remove(struct platform_device *pdev)
u32 step_en;
iio_device_unregister(indio_dev);
tiadc_iio_buffered_hardware_remove(indio_dev);
tiadc_channels_remove(indio_dev);
step_en = get_adc_step_mask(adc_dev);
......@@ -301,7 +490,7 @@ static int tiadc_resume(struct device *dev)
restore &= ~(CNTRLREG_POWERDOWN);
tiadc_writel(adc_dev, REG_CTRL, restore);
tiadc_step_config(adc_dev);
tiadc_step_config(indio_dev);
return 0;
}
......
......@@ -7,12 +7,12 @@
struct iio_cb_buffer {
struct iio_buffer buffer;
int (*cb)(u8 *data, void *private);
int (*cb)(const void *data, void *private);
void *private;
struct iio_channel *channels;
};
static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data)
{
struct iio_cb_buffer *cb_buff = container_of(buffer,
struct iio_cb_buffer,
......@@ -21,12 +21,12 @@ static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
return cb_buff->cb(data, cb_buff->private);
}
static struct iio_buffer_access_funcs iio_cb_access = {
static const struct iio_buffer_access_funcs iio_cb_access = {
.store_to = &iio_buffer_cb_store_to,
};
struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
int (*cb)(u8 *data,
int (*cb)(const void *data,
void *private),
void *private)
{
......
......@@ -113,11 +113,8 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p)
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);
iio_push_to_buffers_with_timestamp(indio_dev, sdata->buffer_data,
pf->timestamp);
st_sensors_get_buffer_element_error:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -198,21 +198,17 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
}
EXPORT_SYMBOL(st_sensors_set_axis_enable);
int st_sensors_init_sensor(struct iio_dev *indio_dev,
static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *sdata = iio_priv(indio_dev);
mutex_init(&sdata->tb.buf_lock);
switch (pdata->drdy_int_pin) {
case 1:
if (sdata->sensor->drdy_irq.mask_int1 == 0) {
dev_err(&indio_dev->dev,
"DRDY on INT1 not available.\n");
err = -EINVAL;
goto init_error;
return -EINVAL;
}
sdata->drdy_int_pin = 1;
break;
......@@ -220,39 +216,53 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
if (sdata->sensor->drdy_irq.mask_int2 == 0) {
dev_err(&indio_dev->dev,
"DRDY on INT2 not available.\n");
err = -EINVAL;
goto init_error;
return -EINVAL;
}
sdata->drdy_int_pin = 2;
break;
default:
dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
err = -EINVAL;
goto init_error;
return -EINVAL;
}
return 0;
}
int st_sensors_init_sensor(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
struct st_sensor_data *sdata = iio_priv(indio_dev);
int err = 0;
mutex_init(&sdata->tb.buf_lock);
if (pdata)
err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
err = st_sensors_set_enable(indio_dev, false);
if (err < 0)
goto init_error;
return err;
if (sdata->current_fullscale) {
err = st_sensors_set_fullscale(indio_dev,
sdata->current_fullscale->num);
if (err < 0)
goto init_error;
return err;
} else
dev_info(&indio_dev->dev, "Full-scale not possible\n");
err = st_sensors_set_odr(indio_dev, sdata->odr);
if (err < 0)
goto init_error;
return err;
/* set BDU */
err = st_sensors_write_data_with_mask(indio_dev,
sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true);
if (err < 0)
goto init_error;
return err;
err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
init_error:
return err;
}
EXPORT_SYMBOL(st_sensors_init_sensor);
......@@ -263,6 +273,9 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
u8 drdy_mask;
struct st_sensor_data *sdata = iio_priv(indio_dev);
if (!sdata->sensor->drdy_irq.addr)
return 0;
/* Enable/Disable the interrupt generator 1. */
if (sdata->sensor->drdy_irq.ig1.en_addr > 0) {
err = st_sensors_write_data_with_mask(indio_dev,
......@@ -318,10 +331,8 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;
outdata = kmalloc(byte_for_channel, GFP_KERNEL);
if (!outdata) {
err = -EINVAL;
goto st_sensors_read_axis_data_error;
}
if (!outdata)
return -ENOMEM;
err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
ch->address, byte_for_channel,
......@@ -336,7 +347,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
st_sensors_free_memory:
kfree(outdata);
st_sensors_read_axis_data_error:
return err;
}
......@@ -349,28 +360,25 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
err = -EBUSY;
goto read_error;
goto out;
} else {
err = st_sensors_set_enable(indio_dev, true);
if (err < 0)
goto read_error;
goto out;
msleep((sdata->sensor->bootime * 1000) / sdata->odr);
err = st_sensors_read_axis_data(indio_dev, ch, val);
if (err < 0)
goto read_error;
goto out;
*val = *val >> ch->scan_type.shift;
err = st_sensors_set_enable(indio_dev, false);
}
out:
mutex_unlock(&indio_dev->mlock);
return err;
read_error:
mutex_unlock(&indio_dev->mlock);
return err;
}
EXPORT_SYMBOL(st_sensors_read_info_raw);
......
......@@ -285,8 +285,9 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
.name = "powerdown",
.read = ad5064_read_dac_powerdown,
.write = ad5064_write_dac_powerdown,
.shared = IIO_SEPARATE,
},
IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5064_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
{ },
};
......
......@@ -247,8 +247,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
.name = "powerdown",
.read = ad5380_read_dac_powerdown,
.write = ad5380_write_dac_powerdown,
.shared = IIO_SEPARATE,
},
IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
&ad5380_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
{ },
};
......
......@@ -132,8 +132,9 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
.name = "powerdown",
.read = ad5446_read_dac_powerdown,
.write = ad5446_write_dac_powerdown,
.shared = IIO_SEPARATE,
},
IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5446_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
{ },
};
......
......@@ -248,8 +248,10 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
.name = "powerdown",
.read = ad5504_read_dac_powerdown,
.write = ad5504_write_dac_powerdown,
.shared = IIO_SEPARATE,
},
IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
&ad5504_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
{ },
};
......
......@@ -163,8 +163,10 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
.name = "powerdown",
.read = ad5624r_read_dac_powerdown,
.write = ad5624r_write_dac_powerdown,
.shared = IIO_SEPARATE,
},
IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
&ad5624r_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
{ },
};
......
......@@ -213,7 +213,6 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
return ret;
*val = ret;
return IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
scale_uv = (st->vref_mv * 100000)
>> (chan->scan_type.realbits);
......@@ -265,8 +264,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
.name = "powerdown",
.read = ad5686_read_dac_powerdown,
.write = ad5686_write_dac_powerdown,
.shared = IIO_SEPARATE,
},
IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
{ },
};
......
......@@ -386,6 +386,7 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
.name = "powerdown",
.read = ad5755_read_powerdown,
.write = ad5755_write_powerdown,
.shared = IIO_SEPARATE,
},
{ },
};
......
......@@ -287,11 +287,12 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
{
.name = "powerdown",
.shared = true,
.shared = IIO_SHARED_BY_TYPE,
.read = ad5791_read_dac_powerdown,
.write = ad5791_write_dac_powerdown,
},
IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
&ad5791_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
{ },
};
......
......@@ -169,6 +169,7 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
.name = "powerdown",
.read = ad7303_read_dac_powerdown,
.write = ad7303_write_dac_powerdown,
.shared = IIO_SEPARATE,
},
{ },
};
......
......@@ -195,8 +195,9 @@ static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
.name = "powerdown",
.read = mcp4725_read_powerdown,
.write = mcp4725_write_powerdown,
.shared = IIO_SEPARATE,
},
IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4725_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
{ },
};
......
......@@ -351,6 +351,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
.read = adf4350_read, \
.write = adf4350_write, \
.private = _ident, \
.shared = IIO_SEPARATE, \
}
static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
......
......@@ -103,7 +103,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
default:
return -EINVAL;
}
break;
case IIO_CHAN_INFO_OFFSET:
switch (chan->type) {
case IIO_ANGL_VEL:
......@@ -115,7 +114,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
default:
return -EINVAL;
}
break;
}
return -EINVAL;
......
......@@ -239,7 +239,6 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
default:
return -EINVAL;
}
break;
case IIO_CHAN_INFO_OFFSET:
*val = 250000 / 1453; /* 25 C = 0x00 */
return IIO_VAL_INT;
......
......@@ -354,7 +354,6 @@ static int adxrs450_read_raw(struct iio_dev *indio_dev,
default:
return -EINVAL;
}
break;
case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW:
ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t);
if (ret)
......
......@@ -182,10 +182,11 @@ static const struct iio_info gyro_3d_info = {
};
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
int len)
{
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
iio_push_to_buffers(indio_dev, (u8 *)data);
iio_push_to_buffers(indio_dev, data);
}
/* Callback handler to send event after all samples are received and captured */
......@@ -200,7 +201,7 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
gyro_state->common_attributes.data_ready);
if (gyro_state->common_attributes.data_ready)
hid_sensor_push_data(indio_dev,
(u8 *)gyro_state->gyro_val,
gyro_state->gyro_val,
sizeof(gyro_state->gyro_val));
return 0;
......
......@@ -55,11 +55,8 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
if (ret < 0)
goto error_ret;
if (indio_dev->scan_timestamp)
memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
&pf->timestamp, sizeof(pf->timestamp));
iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
iio_push_to_buffers(indio_dev, (u8 *)buf);
iio_trigger_notify_done(indio_dev->trig);
error_ret:
......
......@@ -305,8 +305,9 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
int st_gyro_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *gdata = iio_priv(indio_dev);
int irq = gdata->get_irq_data_ready(indio_dev);
int err;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &gyro_info;
......@@ -314,7 +315,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
if (err < 0)
goto st_gyro_common_probe_error;
return err;
gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
gdata->multiread_bit = gdata->sensor->multi_read_bit;
......@@ -327,13 +328,13 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
err = st_sensors_init_sensor(indio_dev, pdata);
if (err < 0)
goto st_gyro_common_probe_error;
return err;
if (gdata->get_irq_data_ready(indio_dev) > 0) {
err = st_gyro_allocate_ring(indio_dev);
if (err < 0)
goto st_gyro_common_probe_error;
return err;
if (irq > 0) {
err = st_sensors_allocate_trigger(indio_dev,
ST_GYRO_TRIGGER_OPS);
if (err < 0)
......@@ -344,15 +345,14 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
if (err)
goto st_gyro_device_register_error;
return err;
return 0;
st_gyro_device_register_error:
if (gdata->get_irq_data_ready(indio_dev) > 0)
if (irq > 0)
st_sensors_deallocate_trigger(indio_dev);
st_gyro_probe_trigger_error:
if (gdata->get_irq_data_ready(indio_dev) > 0)
st_gyro_deallocate_ring(indio_dev);
st_gyro_common_probe_error:
return err;
}
EXPORT_SYMBOL(st_gyro_common_probe);
......@@ -362,10 +362,10 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
struct st_sensor_data *gdata = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (gdata->get_irq_data_ready(indio_dev) > 0) {
if (gdata->get_irq_data_ready(indio_dev) > 0)
st_sensors_deallocate_trigger(indio_dev);
st_gyro_deallocate_ring(indio_dev);
}
}
EXPORT_SYMBOL(st_gyro_common_remove);
......
......@@ -30,7 +30,7 @@ int __iio_add_chan_devattr(const char *postfix,
const char *buf,
size_t len),
u64 mask,
bool generic,
enum iio_shared_by shared_by,
struct device *dev,
struct list_head *attr_list);
......
......@@ -82,13 +82,8 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
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_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -102,13 +102,8 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
mutex_unlock(&adis->txrx_lock);
}
/* 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_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -124,7 +124,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
u16 fifo_count;
s64 timestamp;
u64 *tmp;
mutex_lock(&indio_dev->mlock);
if (!(st->chip_config.accl_fifo_enable |
......@@ -170,9 +169,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
if (0 == result)
timestamp = 0;
tmp = (u64 *)data;
tmp[DIV_ROUND_UP(bytes_per_datum, 8)] = timestamp;
result = iio_push_to_buffers(indio_dev, data);
result = iio_push_to_buffers_with_timestamp(indio_dev, data,
timestamp);
if (result)
goto flush_fifo;
fifo_count -= bytes_per_datum;
......
......@@ -31,16 +31,9 @@ static const char * const iio_endian_prefix[] = {
[IIO_LE] = "le",
};
static bool iio_buffer_is_active(struct iio_dev *indio_dev,
struct iio_buffer *buf)
static bool iio_buffer_is_active(struct iio_buffer *buf)
{
struct list_head *p;
list_for_each(p, &indio_dev->buffer_list)
if (p == &buf->buffer_list)
return true;
return false;
return !list_empty(&buf->buffer_list);
}
/**
......@@ -79,6 +72,7 @@ unsigned int iio_buffer_poll(struct file *filp,
void iio_buffer_init(struct iio_buffer *buffer)
{
INIT_LIST_HEAD(&buffer->demux_list);
INIT_LIST_HEAD(&buffer->buffer_list);
init_waitqueue_head(&buffer->pollq);
}
EXPORT_SYMBOL(iio_buffer_init);
......@@ -146,7 +140,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
if (ret < 0)
return ret;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
if (iio_buffer_is_active(indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
......@@ -192,7 +186,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
return ret;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
if (iio_buffer_is_active(indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
......@@ -214,7 +208,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
&iio_show_scan_index,
NULL,
0,
0,
IIO_SEPARATE,
&indio_dev->dev,
&buffer->scan_el_dev_attr_list);
if (ret)
......@@ -249,6 +243,8 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
0,
&indio_dev->dev,
&buffer->scan_el_dev_attr_list);
if (ret)
goto error_ret;
attrcount++;
ret = attrcount;
error_ret:
......@@ -396,7 +392,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
return len;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
if (iio_buffer_is_active(indio_dev->buffer)) {
ret = -EBUSY;
} else {
if (buffer->access->set_length)
......@@ -414,13 +410,11 @@ ssize_t iio_buffer_show_enable(struct device *dev,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
return sprintf(buf, "%d\n",
iio_buffer_is_active(indio_dev,
indio_dev->buffer));
return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer));
}
EXPORT_SYMBOL(iio_buffer_show_enable);
/* note NULL used as error indicator as it doesn't make sense. */
/* Note NULL used as error indicator as it doesn't make sense. */
static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
unsigned int masklength,
const unsigned long *mask)
......@@ -435,8 +429,8 @@ static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
return NULL;
}
static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
bool timestamp)
static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
const unsigned long *mask, bool timestamp)
{
const struct iio_chan_spec *ch;
unsigned bytes = 0;
......@@ -490,7 +484,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
indio_dev->active_scan_mask = NULL;
if (remove_buffer)
list_del(&remove_buffer->buffer_list);
list_del_init(&remove_buffer->buffer_list);
if (insert_buffer)
list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
......@@ -502,7 +496,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
return 0;
}
/* What scan mask do we actually have ?*/
/* What scan mask do we actually have? */
compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
sizeof(long), GFP_KERNEL);
if (compound_mask == NULL) {
......@@ -527,7 +521,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
* Roll back.
* Note can only occur when adding a buffer.
*/
list_del(&insert_buffer->buffer_list);
list_del_init(&insert_buffer->buffer_list);
indio_dev->active_scan_mask = old_mask;
success = -EINVAL;
}
......@@ -568,7 +562,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
goto error_run_postdisable;
}
}
/* Definitely possible for devices to support both of these.*/
/* Definitely possible for devices to support both of these. */
if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
if (!indio_dev->trig) {
printk(KERN_INFO "Buffer not started: no trigger\n");
......@@ -579,7 +573,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
} else { /* should never be reached */
} else { /* Should never be reached */
ret = -EINVAL;
goto error_run_postdisable;
}
......@@ -611,7 +605,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
error_remove_inserted:
if (insert_buffer)
list_del(&insert_buffer->buffer_list);
list_del_init(&insert_buffer->buffer_list);
indio_dev->active_scan_mask = old_mask;
kfree(compound_mask);
error_ret:
......@@ -628,7 +622,6 @@ ssize_t iio_buffer_store_enable(struct device *dev,
int ret;
bool requested_state;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_buffer *pbuf = indio_dev->buffer;
bool inlist;
ret = strtobool(buf, &requested_state);
......@@ -638,7 +631,7 @@ ssize_t iio_buffer_store_enable(struct device *dev,
mutex_lock(&indio_dev->mlock);
/* Find out if it is in the list */
inlist = iio_buffer_is_active(indio_dev, pbuf);
inlist = iio_buffer_is_active(indio_dev->buffer);
/* Already in desired state */
if (inlist == requested_state)
goto done;
......@@ -703,6 +696,7 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
/**
* iio_scan_mask_set() - set particular bit in the scan mask
* @indio_dev: the iio device
* @buffer: the buffer whose scan mask we are interested in
* @bit: the bit to be set.
*
......@@ -723,7 +717,7 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
if (trialmask == NULL)
return -ENOMEM;
if (!indio_dev->masklength) {
WARN_ON("trying to set scanmask prior to registering buffer\n");
WARN_ON("Trying to set scanmask prior to registering buffer\n");
goto err_invalid_mask;
}
bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
......@@ -778,8 +772,8 @@ struct iio_demux_table {
struct list_head l;
};
static unsigned char *iio_demux(struct iio_buffer *buffer,
unsigned char *datain)
static const void *iio_demux(struct iio_buffer *buffer,
const void *datain)
{
struct iio_demux_table *t;
......@@ -792,9 +786,9 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
return buffer->demux_bounce;
}
static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
static int iio_push_to_buffer(struct iio_buffer *buffer, const void *data)
{
unsigned char *dataout = iio_demux(buffer, data);
const void *dataout = iio_demux(buffer, data);
return buffer->access->store_to(buffer, dataout);
}
......@@ -809,7 +803,7 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer)
}
int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data)
int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data)
{
int ret;
struct iio_buffer *buf;
......
......@@ -101,6 +101,7 @@ static const char * const iio_chan_info_postfix[] = {
[IIO_CHAN_INFO_PHASE] = "phase",
[IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
[IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
[IIO_CHAN_INFO_INT_TIME] = "integration_time",
};
const struct iio_chan_spec
......@@ -516,14 +517,15 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
struct device_attribute *attr,
const char *buf,
size_t len),
bool generic)
enum iio_shared_by shared_by)
{
int ret;
char *name_format, *full_postfix;
int ret = 0;
char *name_format = NULL;
char *full_postfix;
sysfs_attr_init(&dev_attr->attr);
/* Build up postfix of <extend_name>_<modifier>_postfix */
if (chan->modified && !generic) {
if (chan->modified && (shared_by == IIO_SEPARATE)) {
if (chan->extend_name)
full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
iio_modifier_names[chan
......@@ -544,41 +546,64 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
chan->extend_name,
postfix);
}
if (full_postfix == NULL) {
ret = -ENOMEM;
goto error_ret;
}
if (full_postfix == NULL)
return -ENOMEM;
if (chan->differential) { /* Differential can not have modifier */
if (generic)
switch (shared_by) {
case IIO_SHARED_BY_ALL:
name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
break;
case IIO_SHARED_BY_DIR:
name_format = kasprintf(GFP_KERNEL, "%s_%s",
iio_direction[chan->output],
full_postfix);
break;
case IIO_SHARED_BY_TYPE:
name_format
= kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
iio_direction[chan->output],
iio_chan_type_name_spec[chan->type],
iio_chan_type_name_spec[chan->type],
full_postfix);
else if (chan->indexed)
break;
case IIO_SEPARATE:
if (!chan->indexed) {
WARN_ON("Differential channels must be indexed\n");
ret = -EINVAL;
goto error_free_full_postfix;
}
name_format
= kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
= kasprintf(GFP_KERNEL,
"%s_%s%d-%s%d_%s",
iio_direction[chan->output],
iio_chan_type_name_spec[chan->type],
chan->channel,
iio_chan_type_name_spec[chan->type],
chan->channel2,
full_postfix);
else {
WARN_ON("Differential channels must be indexed\n");
ret = -EINVAL;
goto error_free_full_postfix;
break;
}
} else { /* Single ended */
if (generic)
switch (shared_by) {
case IIO_SHARED_BY_ALL:
name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
break;
case IIO_SHARED_BY_DIR:
name_format = kasprintf(GFP_KERNEL, "%s_%s",
iio_direction[chan->output],
full_postfix);
break;
case IIO_SHARED_BY_TYPE:
name_format
= kasprintf(GFP_KERNEL, "%s_%s_%s",
iio_direction[chan->output],
iio_chan_type_name_spec[chan->type],
full_postfix);
else if (chan->indexed)
break;
case IIO_SEPARATE:
if (chan->indexed)
name_format
= kasprintf(GFP_KERNEL, "%s_%s%d_%s",
iio_direction[chan->output],
......@@ -591,6 +616,8 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
iio_direction[chan->output],
iio_chan_type_name_spec[chan->type],
full_postfix);
break;
}
}
if (name_format == NULL) {
ret = -ENOMEM;
......@@ -614,16 +641,11 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
dev_attr->attr.mode |= S_IWUSR;
dev_attr->store = writefunc;
}
kfree(name_format);
kfree(full_postfix);
return 0;
error_free_name_format:
kfree(name_format);
error_free_full_postfix:
kfree(full_postfix);
error_ret:
return ret;
}
......@@ -642,7 +664,7 @@ int __iio_add_chan_devattr(const char *postfix,
const char *buf,
size_t len),
u64 mask,
bool generic,
enum iio_shared_by shared_by,
struct device *dev,
struct list_head *attr_list)
{
......@@ -656,7 +678,7 @@ int __iio_add_chan_devattr(const char *postfix,
}
ret = __iio_device_attr_init(&iio_attr->dev_attr,
postfix, chan,
readfunc, writefunc, generic);
readfunc, writefunc, shared_by);
if (ret)
goto error_iio_dev_attr_free;
iio_attr->c = chan;
......@@ -664,7 +686,7 @@ int __iio_add_chan_devattr(const char *postfix,
list_for_each_entry(t, attr_list, l)
if (strcmp(t->dev_attr.attr.name,
iio_attr->dev_attr.attr.name) == 0) {
if (!generic)
if (shared_by == IIO_SEPARATE)
dev_err(dev, "tried to double register : %s\n",
t->dev_attr.attr.name);
ret = -EBUSY;
......@@ -682,46 +704,68 @@ int __iio_add_chan_devattr(const char *postfix,
return ret;
}
static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan)
static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
enum iio_shared_by shared_by,
const long *infomask)
{
int ret, attrcount = 0;
int i;
const struct iio_chan_spec_ext_info *ext_info;
int i, ret, attrcount = 0;
if (chan->channel < 0)
return 0;
for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) {
for_each_set_bit(i, infomask, sizeof(infomask)*8) {
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
chan,
&iio_read_channel_info,
&iio_write_channel_info,
i,
0,
shared_by,
&indio_dev->dev,
&indio_dev->channel_attr_list);
if (ret < 0)
goto error_ret;
attrcount++;
}
for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) {
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
chan,
&iio_read_channel_info,
&iio_write_channel_info,
i,
1,
&indio_dev->dev,
&indio_dev->channel_attr_list);
if (ret == -EBUSY) {
ret = 0;
if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
continue;
} else if (ret < 0) {
goto error_ret;
}
else if (ret < 0)
return ret;
attrcount++;
}
return attrcount;
}
static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan)
{
int ret, attrcount = 0;
const struct iio_chan_spec_ext_info *ext_info;
if (chan->channel < 0)
return 0;
ret = iio_device_add_info_mask_type(indio_dev, chan,
IIO_SEPARATE,
&chan->info_mask_separate);
if (ret < 0)
return ret;
attrcount += ret;
ret = iio_device_add_info_mask_type(indio_dev, chan,
IIO_SHARED_BY_TYPE,
&chan->info_mask_shared_by_type);
if (ret < 0)
return ret;
attrcount += ret;
ret = iio_device_add_info_mask_type(indio_dev, chan,
IIO_SHARED_BY_DIR,
&chan->info_mask_shared_by_dir);
if (ret < 0)
return ret;
attrcount += ret;
ret = iio_device_add_info_mask_type(indio_dev, chan,
IIO_SHARED_BY_ALL,
&chan->info_mask_shared_by_all);
if (ret < 0)
return ret;
attrcount += ret;
if (chan->ext_info) {
unsigned int i = 0;
for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
......@@ -740,15 +784,13 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
continue;
if (ret)
goto error_ret;
return ret;
attrcount++;
}
}
ret = attrcount;
error_ret:
return ret;
return attrcount;
}
static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
......
......@@ -159,7 +159,7 @@ int iio_event_getfd(struct iio_dev *indio_dev)
}
spin_unlock_irq(&ev_int->wait.lock);
fd = anon_inode_getfd("iio:event",
&iio_event_chrdev_fileops, ev_int, O_RDONLY);
&iio_event_chrdev_fileops, ev_int, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
spin_lock_irq(&ev_int->wait.lock);
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
......
......@@ -7,6 +7,7 @@
#include <linux/mutex.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/sched.h>
#include <linux/poll.h>
struct iio_kfifo {
struct iio_buffer buffer;
......@@ -94,7 +95,7 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length)
}
static int iio_store_to_kfifo(struct iio_buffer *r,
u8 *data)
const void *data)
{
int ret;
struct iio_kfifo *kf = iio_to_kfifo(r);
......@@ -102,7 +103,7 @@ static int iio_store_to_kfifo(struct iio_buffer *r,
if (ret != 1)
return -EBUSY;
r->stufftoread = true;
wake_up_interruptible(&r->pollq);
wake_up_interruptible_poll(&r->pollq, POLLIN | POLLRDNORM);
return 0;
}
......
......@@ -27,6 +27,18 @@ config APDS9300
To compile this driver as a module, choose M here: the
module will be called apds9300.
config GP2AP020A00F
tristate "Sharp GP2AP020A00F Proximity/ALS sensor"
depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say Y here if you have a Sharp GP2AP020A00F proximity/ALS combo-chip
hooked to an I2C bus.
To compile this driver as a module, choose M here: the
module will be called gp2ap020a00f.
config HID_SENSOR_ALS
depends on HID_SENSOR_HUB
select IIO_BUFFER
......@@ -55,6 +67,16 @@ config SENSORS_LM3533
changes. The ALS-control output values can be set per zone for the
three current output channels.
config TCS3472
tristate "TAOS TCS3472 color light-to-digital converter"
depends on I2C
help
If you say yes here you get support for the TAOS TCS3472
family of color light-to-digital converters with IR filter.
This driver can also be built as a module. If so, the module
will be called tcs3472.
config SENSORS_TSL2563
tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
depends on I2C
......@@ -65,6 +87,16 @@ config SENSORS_TSL2563
This driver can also be built as a module. If so, the module
will be called tsl2563.
config TSL4531
tristate "TAOS TSL4531 ambient light sensors"
depends on I2C
help
Say Y here if you want to build a driver for the TAOS TSL4531 family
of ambient light sensors with direct lux output.
To compile this driver as a module, choose M here: the
module will be called tsl4531.
config VCNL4000
tristate "VCNL4000 combined ALS and proximity sensor"
depends on I2C
......
......@@ -5,7 +5,10 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ADJD_S311) += adjd_s311.o
obj-$(CONFIG_APDS9300) += apds9300.o
obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
obj-$(CONFIG_TCS3472) += tcs3472.o
obj-$(CONFIG_TSL4531) += tsl4531.o
obj-$(CONFIG_VCNL4000) += vcnl4000.o
......@@ -114,43 +114,6 @@ static int adjd_s311_read_data(struct iio_dev *indio_dev, u8 reg, int *val)
return 0;
}
static ssize_t adjd_s311_read_int_time(struct iio_dev *indio_dev,
uintptr_t private, const struct iio_chan_spec *chan, char *buf)
{
struct adjd_s311_data *data = iio_priv(indio_dev);
s32 ret;
ret = i2c_smbus_read_word_data(data->client,
ADJD_S311_INT_REG(chan->address));
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", ret & ADJD_S311_INT_MASK);
}
static ssize_t adjd_s311_write_int_time(struct iio_dev *indio_dev,
uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
size_t len)
{
struct adjd_s311_data *data = iio_priv(indio_dev);
unsigned long int_time;
int ret;
ret = kstrtoul(buf, 10, &int_time);
if (ret)
return ret;
if (int_time > ADJD_S311_INT_MASK)
return -EINVAL;
ret = i2c_smbus_write_word_data(data->client,
ADJD_S311_INT_REG(chan->address), int_time);
if (ret < 0)
return ret;
return len;
}
static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
......@@ -175,10 +138,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
len += 2;
}
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
= time_ns;
iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, time_ns);
done:
iio_trigger_notify_done(indio_dev->trig);
......@@ -186,25 +146,16 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
return IRQ_HANDLED;
}
static const struct iio_chan_spec_ext_info adjd_s311_ext_info[] = {
{
.name = "integration_time",
.read = adjd_s311_read_int_time,
.write = adjd_s311_write_int_time,
},
{ }
};
#define ADJD_S311_CHANNEL(_color, _scan_idx) { \
.type = IIO_INTENSITY, \
.modified = 1, \
.address = (IDX_##_color), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
BIT(IIO_CHAN_INFO_INT_TIME), \
.channel2 = (IIO_MOD_LIGHT_##_color), \
.scan_index = (_scan_idx), \
.scan_type = IIO_ST('u', 10, 16, 0), \
.ext_info = adjd_s311_ext_info, \
}
static const struct iio_chan_spec adjd_s311_channels[] = {
......@@ -236,6 +187,18 @@ static int adjd_s311_read_raw(struct iio_dev *indio_dev,
return ret;
*val = ret & ADJD_S311_CAP_MASK;
return IIO_VAL_INT;
case IIO_CHAN_INFO_INT_TIME:
ret = i2c_smbus_read_word_data(data->client,
ADJD_S311_INT_REG(chan->address));
if (ret < 0)
return ret;
*val = 0;
/*
* not documented, based on measurement:
* 4095 LSBs correspond to roughly 4 ms
*/
*val2 = ret & ADJD_S311_INT_MASK;
return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
......@@ -245,16 +208,20 @@ static int adjd_s311_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask)
{
struct adjd_s311_data *data = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_HARDWAREGAIN:
if (val < 0 || val > ADJD_S311_CAP_MASK)
return -EINVAL;
ret = i2c_smbus_write_byte_data(data->client,
return i2c_smbus_write_byte_data(data->client,
ADJD_S311_CAP_REG(chan->address), val);
return ret;
case IIO_CHAN_INFO_INT_TIME:
if (val != 0 || val2 < 0 || val2 > ADJD_S311_INT_MASK)
return -EINVAL;
return i2c_smbus_write_word_data(data->client,
ADJD_S311_INT_REG(chan->address), val2);
}
return -EINVAL;
}
......
This diff is collapsed.
......@@ -161,10 +161,11 @@ static const struct iio_info als_info = {
};
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
int len)
{
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
iio_push_to_buffers(indio_dev, (u8 *)data);
iio_push_to_buffers(indio_dev, data);
}
/* Callback handler to send event after all samples are received and captured */
......@@ -179,7 +180,7 @@ static int als_proc_event(struct hid_sensor_hub_device *hsdev,
als_state->common_attributes.data_ready);
if (als_state->common_attributes.data_ready)
hid_sensor_push_data(indio_dev,
(u8 *)&als_state->illum,
&als_state->illum,
sizeof(als_state->illum));
return 0;
......
/*
* tcs3472.c - Support for TAOS TCS3472 color light-to-digital converter
*
* Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
*
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*
* Color light sensor with 16-bit channels for red, green, blue, clear);
* 7-bit I2C slave address 0x39 (TCS34721, TCS34723) or 0x29 (TCS34725,
* TCS34727)
*
* TODO: interrupt support, thresholds, wait time
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/buffer.h>
#include <linux/iio/triggered_buffer.h>
#define TCS3472_DRV_NAME "tcs3472"
#define TCS3472_COMMAND BIT(7)
#define TCS3472_AUTO_INCR BIT(5)
#define TCS3472_ENABLE (TCS3472_COMMAND | 0x00)
#define TCS3472_ATIME (TCS3472_COMMAND | 0x01)
#define TCS3472_WTIME (TCS3472_COMMAND | 0x03)
#define TCS3472_AILT (TCS3472_COMMAND | 0x04)
#define TCS3472_AIHT (TCS3472_COMMAND | 0x06)
#define TCS3472_PERS (TCS3472_COMMAND | 0x0c)
#define TCS3472_CONFIG (TCS3472_COMMAND | 0x0d)
#define TCS3472_CONTROL (TCS3472_COMMAND | 0x0f)
#define TCS3472_ID (TCS3472_COMMAND | 0x12)
#define TCS3472_STATUS (TCS3472_COMMAND | 0x13)
#define TCS3472_CDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x14)
#define TCS3472_RDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x16)
#define TCS3472_GDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x18)
#define TCS3472_BDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x1a)
#define TCS3472_STATUS_AVALID BIT(0)
#define TCS3472_ENABLE_AEN BIT(1)
#define TCS3472_ENABLE_PON BIT(0)
#define TCS3472_CONTROL_AGAIN_MASK (BIT(0) | BIT(1))
struct tcs3472_data {
struct i2c_client *client;
u8 enable;
u8 control;
u8 atime;
u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */
};
#define TCS3472_CHANNEL(_color, _si, _addr) { \
.type = IIO_INTENSITY, \
.modified = 1, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBSCALE) | \
BIT(IIO_CHAN_INFO_INT_TIME), \
.channel2 = IIO_MOD_LIGHT_##_color, \
.address = _addr, \
.scan_index = _si, \
.scan_type = IIO_ST('u', 16, 16, 0), \
}
static const int tcs3472_agains[] = { 1, 4, 16, 60 };
static const struct iio_chan_spec tcs3472_channels[] = {
TCS3472_CHANNEL(CLEAR, 0, TCS3472_CDATA),
TCS3472_CHANNEL(RED, 1, TCS3472_RDATA),
TCS3472_CHANNEL(GREEN, 2, TCS3472_GDATA),
TCS3472_CHANNEL(BLUE, 3, TCS3472_BDATA),
IIO_CHAN_SOFT_TIMESTAMP(4),
};
static int tcs3472_req_data(struct tcs3472_data *data)
{
int tries = 50;
int ret;
while (tries--) {
ret = i2c_smbus_read_byte_data(data->client, TCS3472_STATUS);
if (ret < 0)
return ret;
if (ret & TCS3472_STATUS_AVALID)
break;
msleep(20);
}
if (tries < 0) {
dev_err(&data->client->dev, "data not ready\n");
return -EIO;
}
return 0;
}
static int tcs3472_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct tcs3472_data *data = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = tcs3472_req_data(data);
if (ret < 0)
return ret;
ret = i2c_smbus_read_word_data(data->client, chan->address);
if (ret < 0)
return ret;
*val = ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBSCALE:
*val = tcs3472_agains[data->control &
TCS3472_CONTROL_AGAIN_MASK];
return IIO_VAL_INT;
case IIO_CHAN_INFO_INT_TIME:
*val = 0;
*val2 = (256 - data->atime) * 2400;
return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
static int tcs3472_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct tcs3472_data *data = iio_priv(indio_dev);
int i;
switch (mask) {
case IIO_CHAN_INFO_CALIBSCALE:
if (val2 != 0)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(tcs3472_agains); i++) {
if (val == tcs3472_agains[i]) {
data->control &= ~TCS3472_CONTROL_AGAIN_MASK;
data->control |= i;
return i2c_smbus_write_byte_data(
data->client, TCS3472_CONTROL,
data->control);
}
}
return -EINVAL;
case IIO_CHAN_INFO_INT_TIME:
if (val != 0)
return -EINVAL;
for (i = 0; i < 256; i++) {
if (val2 == (256 - i) * 2400) {
data->atime = i;
return i2c_smbus_write_word_data(
data->client, TCS3472_ATIME,
data->atime);
}
}
return -EINVAL;
}
return -EINVAL;
}
static irqreturn_t tcs3472_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct tcs3472_data *data = iio_priv(indio_dev);
int len = 0;
int i, j = 0;
int ret = tcs3472_req_data(data);
if (ret < 0)
goto done;
for_each_set_bit(i, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = i2c_smbus_read_word_data(data->client,
TCS3472_CDATA + 2*i);
if (ret < 0)
goto done;
data->buffer[j++] = ret;
len += 2;
}
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
iio_get_time_ns());
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static ssize_t tcs3472_show_int_time_available(struct device *dev,
struct device_attribute *attr,
char *buf)
{
size_t len = 0;
int i;
for (i = 1; i <= 256; i++)
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
2400 * i);
/* replace trailing space by newline */
buf[len - 1] = '\n';
return len;
}
static IIO_CONST_ATTR(calibscale_available, "1 4 16 60");
static IIO_DEV_ATTR_INT_TIME_AVAIL(tcs3472_show_int_time_available);
static struct attribute *tcs3472_attributes[] = {
&iio_const_attr_calibscale_available.dev_attr.attr,
&iio_dev_attr_integration_time_available.dev_attr.attr,
NULL
};
static const struct attribute_group tcs3472_attribute_group = {
.attrs = tcs3472_attributes,
};
static const struct iio_info tcs3472_info = {
.read_raw = tcs3472_read_raw,
.write_raw = tcs3472_write_raw,
.attrs = &tcs3472_attribute_group,
.driver_module = THIS_MODULE,
};
static int tcs3472_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tcs3472_data *data;
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (indio_dev == NULL)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
indio_dev->dev.parent = &client->dev;
indio_dev->info = &tcs3472_info;
indio_dev->name = TCS3472_DRV_NAME;
indio_dev->channels = tcs3472_channels;
indio_dev->num_channels = ARRAY_SIZE(tcs3472_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
ret = i2c_smbus_read_byte_data(data->client, TCS3472_ID);
if (ret < 0)
return ret;
if (ret == 0x44)
dev_info(&client->dev, "TCS34721/34725 found\n");
else if (ret == 0x4d)
dev_info(&client->dev, "TCS34723/34727 found\n");
else
return -ENODEV;
ret = i2c_smbus_read_byte_data(data->client, TCS3472_CONTROL);
if (ret < 0)
return ret;
data->control = ret;
ret = i2c_smbus_read_byte_data(data->client, TCS3472_ATIME);
if (ret < 0)
return ret;
data->atime = ret;
ret = i2c_smbus_read_byte_data(data->client, TCS3472_ENABLE);
if (ret < 0)
return ret;
/* enable device */
data->enable = ret | TCS3472_ENABLE_PON | TCS3472_ENABLE_AEN;
ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
data->enable);
if (ret < 0)
return ret;
ret = iio_triggered_buffer_setup(indio_dev, NULL,
tcs3472_trigger_handler, NULL);
if (ret < 0)
return ret;
ret = iio_device_register(indio_dev);
if (ret < 0)
goto buffer_cleanup;
return 0;
buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
static int tcs3472_powerdown(struct tcs3472_data *data)
{
return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
data->enable & ~(TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
}
static int tcs3472_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
tcs3472_powerdown(iio_priv(indio_dev));
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tcs3472_suspend(struct device *dev)
{
struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
to_i2c_client(dev)));
return tcs3472_powerdown(data);
}
static int tcs3472_resume(struct device *dev)
{
struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
to_i2c_client(dev)));
return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
data->enable | (TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
}
#endif
static SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, tcs3472_resume);
static const struct i2c_device_id tcs3472_id[] = {
{ "tcs3472", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tcs3472_id);
static struct i2c_driver tcs3472_driver = {
.driver = {
.name = TCS3472_DRV_NAME,
.pm = &tcs3472_pm_ops,
.owner = THIS_MODULE,
},
.probe = tcs3472_probe,
.remove = tcs3472_remove,
.id_table = tcs3472_id,
};
module_i2c_driver(tcs3472_driver);
MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
MODULE_DESCRIPTION("TCS3472 color light sensors driver");
MODULE_LICENSE("GPL");
/*
* tsl4531.c - Support for TAOS TSL4531 ambient light sensor
*
* Copyright 2013 Peter Meerwald <pmeerw@pmeerw.net>
*
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*
* IIO driver for the TSL4531x family
* TSL45311/TSL45313: 7-bit I2C slave address 0x39
* TSL45315/TSL45317: 7-bit I2C slave address 0x29
*
* TODO: single cycle measurement
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#define TSL4531_DRV_NAME "tsl4531"
#define TCS3472_COMMAND BIT(7)
#define TSL4531_CONTROL (TCS3472_COMMAND | 0x00)
#define TSL4531_CONFIG (TCS3472_COMMAND | 0x01)
#define TSL4531_DATA (TCS3472_COMMAND | 0x04)
#define TSL4531_ID (TCS3472_COMMAND | 0x0a)
/* operating modes in control register */
#define TSL4531_MODE_POWERDOWN 0x00
#define TSL4531_MODE_SINGLE_ADC 0x02
#define TSL4531_MODE_NORMAL 0x03
/* integration time control in config register */
#define TSL4531_TCNTRL_400MS 0x00
#define TSL4531_TCNTRL_200MS 0x01
#define TSL4531_TCNTRL_100MS 0x02
/* part number in id register */
#define TSL45311_ID 0x8
#define TSL45313_ID 0x9
#define TSL45315_ID 0xa
#define TSL45317_ID 0xb
#define TSL4531_ID_SHIFT 4
struct tsl4531_data {
struct i2c_client *client;
struct mutex lock;
int int_time;
};
static IIO_CONST_ATTR_INT_TIME_AVAIL("0.1 0.2 0.4");
static struct attribute *tsl4531_attributes[] = {
&iio_const_attr_integration_time_available.dev_attr.attr,
NULL
};
static const struct attribute_group tsl4531_attribute_group = {
.attrs = tsl4531_attributes,
};
static const struct iio_chan_spec tsl4531_channels[] = {
{
.type = IIO_LIGHT,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_INT_TIME)
}
};
static int tsl4531_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct tsl4531_data *data = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = i2c_smbus_read_word_data(data->client,
TSL4531_DATA);
if (ret < 0)
return ret;
*val = ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
/* 0.. 1x, 1 .. 2x, 2 .. 4x */
*val = 1 << data->int_time;
return IIO_VAL_INT;
case IIO_CHAN_INFO_INT_TIME:
if (data->int_time == 0)
*val2 = 400000;
else if (data->int_time == 1)
*val2 = 200000;
else if (data->int_time == 2)
*val2 = 100000;
else
return -EINVAL;
*val = 0;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
}
static int tsl4531_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct tsl4531_data *data = iio_priv(indio_dev);
int int_time, ret;
switch (mask) {
case IIO_CHAN_INFO_INT_TIME:
if (val != 0)
return -EINVAL;
if (val2 == 400000)
int_time = 0;
else if (val2 == 200000)
int_time = 1;
else if (val2 == 100000)
int_time = 2;
else
return -EINVAL;
mutex_lock(&data->lock);
ret = i2c_smbus_write_byte_data(data->client,
TSL4531_CONFIG, int_time);
if (ret >= 0)
data->int_time = int_time;
mutex_unlock(&data->lock);
return ret;
default:
return -EINVAL;
}
}
static const struct iio_info tsl4531_info = {
.read_raw = tsl4531_read_raw,
.write_raw = tsl4531_write_raw,
.attrs = &tsl4531_attribute_group,
.driver_module = THIS_MODULE,
};
static int tsl4531_check_id(struct i2c_client *client)
{
int ret = i2c_smbus_read_byte_data(client, TSL4531_ID);
if (ret < 0)
return ret;
switch (ret >> TSL4531_ID_SHIFT) {
case TSL45311_ID:
case TSL45313_ID:
case TSL45315_ID:
case TSL45317_ID:
return 1;
default:
return 0;
}
}
static int tsl4531_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tsl4531_data *data;
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
mutex_init(&data->lock);
if (!tsl4531_check_id(client)) {
dev_err(&client->dev, "no TSL4531 sensor\n");
return -ENODEV;
}
ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONTROL,
TSL4531_MODE_NORMAL);
if (ret < 0)
return ret;
ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONFIG,
TSL4531_TCNTRL_400MS);
if (ret < 0)
return ret;
indio_dev->dev.parent = &client->dev;
indio_dev->info = &tsl4531_info;
indio_dev->channels = tsl4531_channels;
indio_dev->num_channels = ARRAY_SIZE(tsl4531_channels);
indio_dev->name = TSL4531_DRV_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
return iio_device_register(indio_dev);
}
static int tsl4531_powerdown(struct i2c_client *client)
{
return i2c_smbus_write_byte_data(client, TSL4531_CONTROL,
TSL4531_MODE_POWERDOWN);
}
static int tsl4531_remove(struct i2c_client *client)
{
iio_device_unregister(i2c_get_clientdata(client));
tsl4531_powerdown(client);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tsl4531_suspend(struct device *dev)
{
return tsl4531_powerdown(to_i2c_client(dev));
}
static int tsl4531_resume(struct device *dev)
{
return i2c_smbus_write_byte_data(to_i2c_client(dev), TSL4531_CONTROL,
TSL4531_MODE_NORMAL);
}
#endif
static SIMPLE_DEV_PM_OPS(tsl4531_pm_ops, tsl4531_suspend, tsl4531_resume);
static const struct i2c_device_id tsl4531_id[] = {
{ "tsl4531", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tsl4531_id);
static struct i2c_driver tsl4531_driver = {
.driver = {
.name = TSL4531_DRV_NAME,
.pm = &tsl4531_pm_ops,
.owner = THIS_MODULE,
},
.probe = tsl4531_probe,
.remove = tsl4531_remove,
.id_table = tsl4531_id,
};
module_i2c_driver(tsl4531_driver);
MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
MODULE_DESCRIPTION("TAOS TSL4531 ambient light sensors driver");
MODULE_LICENSE("GPL");
......@@ -183,10 +183,11 @@ static const struct iio_info magn_3d_info = {
};
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
int len)
{
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
iio_push_to_buffers(indio_dev, (u8 *)data);
iio_push_to_buffers(indio_dev, data);
}
/* Callback handler to send event after all samples are received and captured */
......@@ -201,7 +202,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
magn_state->common_attributes.data_ready);
if (magn_state->common_attributes.data_ready)
hid_sensor_push_data(indio_dev,
(u8 *)magn_state->magn_val,
magn_state->magn_val,
sizeof(magn_state->magn_val));
return 0;
......
......@@ -348,8 +348,9 @@ static const struct iio_info magn_info = {
int st_magn_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *mdata = iio_priv(indio_dev);
int irq = mdata->get_irq_data_ready(indio_dev);
int err;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &magn_info;
......@@ -357,7 +358,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
if (err < 0)
goto st_magn_common_probe_error;
return err;
mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
mdata->multiread_bit = mdata->sensor->multi_read_bit;
......@@ -370,12 +371,13 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
err = st_sensors_init_sensor(indio_dev, pdata);
if (err < 0)
goto st_magn_common_probe_error;
return err;
if (mdata->get_irq_data_ready(indio_dev) > 0) {
err = st_magn_allocate_ring(indio_dev);
if (err < 0)
goto st_magn_common_probe_error;
return err;
if (irq > 0) {
err = st_sensors_allocate_trigger(indio_dev, NULL);
if (err < 0)
goto st_magn_probe_trigger_error;
......@@ -385,15 +387,14 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
if (err)
goto st_magn_device_register_error;
return err;
return 0;
st_magn_device_register_error:
if (mdata->get_irq_data_ready(indio_dev) > 0)
if (irq > 0)
st_sensors_deallocate_trigger(indio_dev);
st_magn_probe_trigger_error:
if (mdata->get_irq_data_ready(indio_dev) > 0)
st_magn_deallocate_ring(indio_dev);
st_magn_common_probe_error:
return err;
}
EXPORT_SYMBOL(st_magn_common_probe);
......@@ -403,10 +404,10 @@ void st_magn_common_remove(struct iio_dev *indio_dev)
struct st_sensor_data *mdata = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (mdata->get_irq_data_ready(indio_dev) > 0) {
if (mdata->get_irq_data_ready(indio_dev) > 0)
st_sensors_deallocate_trigger(indio_dev);
st_magn_deallocate_ring(indio_dev);
}
}
EXPORT_SYMBOL(st_magn_common_remove);
......
......@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/iio/common/st_sensors.h>
#define LPS001WP_PRESS_DEV_NAME "lps001wp"
#define LPS331AP_PRESS_DEV_NAME "lps331ap"
/**
......
This diff is collapsed.
......@@ -49,6 +49,7 @@ static int st_press_i2c_remove(struct i2c_client *client)
}
static const struct i2c_device_id st_press_id_table[] = {
{ LPS001WP_PRESS_DEV_NAME },
{ LPS331AP_PRESS_DEV_NAME },
{},
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -146,11 +146,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
len = lis3l02dq_get_buffer_element(indio_dev, data);
/* Guaranteed to be aligned with 8 byte boundary */
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= pf->timestamp;
iio_push_to_buffers(indio_dev, (u8 *)data);
iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
kfree(data);
done:
......
This diff is collapsed.
......@@ -177,11 +177,11 @@ static ssize_t sca3000_set_ring_int(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct sca3000_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
long val;
u8 val;
int ret;
mutex_lock(&st->lock);
ret = strict_strtol(buf, 10, &val);
ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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