Commit f641f667 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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

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

Jonathan writes:

First round of new drivers, cleanups and functionality for the 3.17 cycle.

New drivers
* t5403 barometric pressure sensor
* kxcjk1013 accelerometer (with a locking followup fix).
* ak09911 digital compass

Documentation
* ABI docs for proximity added (interface has been there a long time but
  somehow snuck through without being documented)
* Move iio-trig-sysfs documentation out of staging (got left behind when
  the driver moved some time ago).

Cleanups
 * drop the timestamp argument from iio_trigger_poll(_chained) as
   nothing has been done with it for some time.
 * ad799x kerneldoc for ad799x_chip brought up to date.
 * replace a number of reimplementations of the GENMASK macro and
   use the BIT macro to cleanup a few locations.
 * bring the iio_event_monitor example program up to date with new
   device types.
 * fix some incorrect function prototypes in iio_utils.h example code.
 * INDIO_RING_TRIGGERED to INDIO_BUFFER_TRIGGERED fix in docs. This
   got left behind after we renamed it a long time back.
 * fix error handling in the generic_buffer example program.
 * small tidy ups in the iio-trig-periodic-rtc driver.
 * Allow reseting iio-trig-periodic-rtc frequency to 0 (default) after
   it has changed.
 * Trivial tidy ups in coding style in iio_simply_dummy
parents 98e11370 88f6da77
...@@ -895,6 +895,19 @@ Description: ...@@ -895,6 +895,19 @@ Description:
on-chip EEPROM. After power-up or chip reset the device will on-chip EEPROM. After power-up or chip reset the device will
automatically load the saved configuration. automatically load the saved configuration.
What: /sys/.../iio:deviceX/in_proximity_raw
What: /sys/.../iio:deviceX/in_proximity_input
What: /sys/.../iio:deviceX/in_proximityY_raw
KernelVersion: 3.4
Contact: linux-iio@vger.kernel.org
Description:
Proximity measurement indicating that some
object is near the sensor, usually be observing
reflectivity of infrared or ultrasound emitted.
Often these sensors are unit less and as such conversion
to SI units is not possible. Where it is, the units should
be meters.
What: /sys/.../iio:deviceX/in_illuminanceY_input What: /sys/.../iio:deviceX/in_illuminanceY_input
What: /sys/.../iio:deviceX/in_illuminanceY_raw What: /sys/.../iio:deviceX/in_illuminanceY_raw
What: /sys/.../iio:deviceX/in_illuminanceY_mean_raw What: /sys/.../iio:deviceX/in_illuminanceY_mean_raw
......
...@@ -77,4 +77,16 @@ config MMA8452 ...@@ -77,4 +77,16 @@ config MMA8452
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called mma8452. will be called mma8452.
config KXCJK1013
tristate "Kionix 3-Axis Accelerometer Driver"
depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say Y here if you want to build a driver for the Kionix KXCJK-1013
triaxial acceleration sensor.
To compile this driver as a module, choose M here: the module will
be called kxcjk-1013.
endmenu endmenu
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
# When adding new entries keep the list in alphabetical order # When adding new entries keep the list in alphabetical order
obj-$(CONFIG_BMA180) += bma180.o obj-$(CONFIG_BMA180) += bma180.o
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
obj-$(CONFIG_KXSD9) += kxsd9.o obj-$(CONFIG_KXSD9) += kxsd9.o
obj-$(CONFIG_MMA8452) += mma8452.o obj-$(CONFIG_MMA8452) += mma8452.o
......
This diff is collapsed.
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -25,23 +26,19 @@ ...@@ -25,23 +26,19 @@
#include <linux/platform_data/ad7298.h> #include <linux/platform_data/ad7298.h>
#define AD7298_WRITE (1 << 15) /* write to the control register */ #define AD7298_WRITE BIT(15) /* write to the control register */
#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ #define AD7298_REPEAT BIT(14) /* repeated conversion enable */
#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ #define AD7298_CH(x) BIT(13 - (x)) /* channel select */
#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ #define AD7298_TSENSE BIT(5) /* temperature conversion enable */
#define AD7298_EXTREF (1 << 2) /* external reference enable */ #define AD7298_EXTREF BIT(2) /* external reference enable */
#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ #define AD7298_TAVG BIT(1) /* temperature sensor averaging enable */
#define AD7298_PDD (1 << 0) /* partial power down enable */ #define AD7298_PDD BIT(0) /* partial power down enable */
#define AD7298_MAX_CHAN 8 #define AD7298_MAX_CHAN 8
#define AD7298_BITS 12
#define AD7298_STORAGE_BITS 16
#define AD7298_INTREF_mV 2500 #define AD7298_INTREF_mV 2500
#define AD7298_CH_TEMP 9 #define AD7298_CH_TEMP 9
#define RES_MASK(bits) ((1 << (bits)) - 1)
struct ad7298_state { struct ad7298_state {
struct spi_device *spi; struct spi_device *spi;
struct regulator *reg; struct regulator *reg;
...@@ -257,7 +254,7 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, ...@@ -257,7 +254,7 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
return ret; return ret;
if (chan->address != AD7298_CH_TEMP) if (chan->address != AD7298_CH_TEMP)
*val = ret & RES_MASK(AD7298_BITS); *val = ret & GENMASK(chan->scan_type.realbits - 1, 0);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -21,8 +22,6 @@ ...@@ -21,8 +22,6 @@
#include <linux/iio/trigger_consumer.h> #include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h> #include <linux/iio/triggered_buffer.h>
#define RES_MASK(bits) ((1 << (bits)) - 1)
struct ad7476_state; struct ad7476_state;
struct ad7476_chip_info { struct ad7476_chip_info {
...@@ -117,7 +116,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, ...@@ -117,7 +116,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = (ret >> st->chip_info->channel[0].scan_type.shift) & *val = (ret >> st->chip_info->channel[0].scan_type.shift) &
RES_MASK(st->chip_info->channel[0].scan_type.realbits); GENMASK(st->chip_info->channel[0].scan_type.realbits - 1, 0);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
if (!st->chip_info->int_vref_uv) { if (!st->chip_info->int_vref_uv) {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -25,14 +26,14 @@ ...@@ -25,14 +26,14 @@
#include <linux/platform_data/ad7887.h> #include <linux/platform_data/ad7887.h>
#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */ #define AD7887_REF_DIS BIT(5) /* on-chip reference disable */
#define AD7887_DUAL (1 << 4) /* dual-channel mode */ #define AD7887_DUAL BIT(4) /* dual-channel mode */
#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */ #define AD7887_CH_AIN1 BIT(3) /* convert on channel 1, DUAL=1 */
#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */ #define AD7887_CH_AIN0 0 /* convert on channel 0, DUAL=0,1 */
#define AD7887_PM_MODE1 (0) /* CS based shutdown */ #define AD7887_PM_MODE1 0 /* CS based shutdown */
#define AD7887_PM_MODE2 (1) /* full on */ #define AD7887_PM_MODE2 1 /* full on */
#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */ #define AD7887_PM_MODE3 2 /* auto shutdown after conversion */
#define AD7887_PM_MODE4 (3) /* standby mode */ #define AD7887_PM_MODE4 3 /* standby mode */
enum ad7887_channels { enum ad7887_channels {
AD7887_CH0, AD7887_CH0,
...@@ -40,8 +41,6 @@ enum ad7887_channels { ...@@ -40,8 +41,6 @@ enum ad7887_channels {
AD7887_CH1, AD7887_CH1,
}; };
#define RES_MASK(bits) ((1 << (bits)) - 1)
/** /**
* struct ad7887_chip_info - chip specifc information * struct ad7887_chip_info - chip specifc information
* @int_vref_mv: the internal reference voltage * @int_vref_mv: the internal reference voltage
...@@ -167,7 +166,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, ...@@ -167,7 +166,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = ret >> chan->scan_type.shift; *val = ret >> chan->scan_type.shift;
*val &= RES_MASK(chan->scan_type.realbits); *val &= GENMASK(chan->scan_type.realbits - 1, 0);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
if (st->reg) { if (st->reg) {
......
...@@ -105,9 +105,8 @@ enum { ...@@ -105,9 +105,8 @@ enum {
* struct ad799x_chip_info - chip specific information * struct ad799x_chip_info - chip specific information
* @channel: channel specification * @channel: channel specification
* @num_channels: number of channels * @num_channels: number of channels
* @monitor_mode: whether the chip supports monitor interrupts
* @default_config: device default configuration * @default_config: device default configuration
* @event_attrs: pointer to the monitor event attribute group * @info: pointer to iio_info struct
*/ */
struct ad799x_chip_info { struct ad799x_chip_info {
struct iio_chan_spec channel[9]; struct iio_chan_spec channel[9];
......
...@@ -410,7 +410,7 @@ static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private) ...@@ -410,7 +410,7 @@ static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
complete(&sigma_delta->completion); complete(&sigma_delta->completion);
disable_irq_nosync(irq); disable_irq_nosync(irq);
sigma_delta->irq_dis = true; sigma_delta->irq_dis = true;
iio_trigger_poll(sigma_delta->trig, iio_get_time_ns()); iio_trigger_poll(sigma_delta->trig);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -272,7 +272,7 @@ void handle_adc_eoc_trigger(int irq, struct iio_dev *idev) ...@@ -272,7 +272,7 @@ void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
if (iio_buffer_enabled(idev)) { if (iio_buffer_enabled(idev)) {
disable_irq_nosync(irq); disable_irq_nosync(irq);
iio_trigger_poll(idev->trig, iio_get_time_ns()); iio_trigger_poll(idev->trig);
} else { } else {
st->last_value = at91_adc_readl(st, AT91_ADC_LCDR); st->last_value = at91_adc_readl(st, AT91_ADC_LCDR);
st->done = true; st->done = true;
......
...@@ -486,7 +486,7 @@ static irqreturn_t xadc_axi_interrupt_handler(int irq, void *devid) ...@@ -486,7 +486,7 @@ static irqreturn_t xadc_axi_interrupt_handler(int irq, void *devid)
return IRQ_NONE; return IRQ_NONE;
if ((status & XADC_AXI_INT_EOS) && xadc->trigger) if ((status & XADC_AXI_INT_EOS) && xadc->trigger)
iio_trigger_poll(xadc->trigger, 0); iio_trigger_poll(xadc->trigger);
if (status & XADC_AXI_INT_ALARM_MASK) { if (status & XADC_AXI_INT_ALARM_MASK) {
/* /*
......
...@@ -15,17 +15,16 @@ ...@@ -15,17 +15,16 @@
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/events.h> #include <linux/iio/events.h>
#include <linux/iio/dac/ad5504.h> #include <linux/iio/dac/ad5504.h>
#define AD5505_BITS 12 #define AD5504_RES_MASK GENMASK(11, 0)
#define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1) #define AD5504_CMD_READ BIT(15)
#define AD5504_CMD_WRITE 0
#define AD5504_CMD_READ (1 << 15)
#define AD5504_CMD_WRITE (0 << 15)
#define AD5504_ADDR(addr) ((addr) << 12) #define AD5504_ADDR(addr) ((addr) << 12)
/* Registers */ /* Registers */
...@@ -42,7 +41,7 @@ ...@@ -42,7 +41,7 @@
/** /**
* struct ad5446_state - driver instance specific data * struct ad5446_state - driver instance specific data
* @us: spi_device * @spi: spi_device
* @reg: supply regulator * @reg: supply regulator
* @vref_mv: actual reference voltage used * @vref_mv: actual reference voltage used
* @pwr_down_mask power down mask * @pwr_down_mask power down mask
......
...@@ -16,17 +16,16 @@ ...@@ -16,17 +16,16 @@
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/dac/ad5791.h> #include <linux/iio/dac/ad5791.h>
#define AD5791_RES_MASK(x) ((1 << (x)) - 1) #define AD5791_DAC_MASK GENMASK(19, 0)
#define AD5791_DAC_MASK AD5791_RES_MASK(20)
#define AD5791_DAC_MSB (1 << 19)
#define AD5791_CMD_READ (1 << 23) #define AD5791_CMD_READ BIT(23)
#define AD5791_CMD_WRITE (0 << 23) #define AD5791_CMD_WRITE 0
#define AD5791_ADDR(addr) ((addr) << 20) #define AD5791_ADDR(addr) ((addr) << 20)
/* Registers */ /* Registers */
...@@ -37,11 +36,11 @@ ...@@ -37,11 +36,11 @@
#define AD5791_ADDR_SW_CTRL 4 #define AD5791_ADDR_SW_CTRL 4
/* Control Register */ /* Control Register */
#define AD5791_CTRL_RBUF (1 << 1) #define AD5791_CTRL_RBUF BIT(1)
#define AD5791_CTRL_OPGND (1 << 2) #define AD5791_CTRL_OPGND BIT(2)
#define AD5791_CTRL_DACTRI (1 << 3) #define AD5791_CTRL_DACTRI BIT(3)
#define AD5791_CTRL_BIN2SC (1 << 4) #define AD5791_CTRL_BIN2SC BIT(4)
#define AD5791_CTRL_SDODIS (1 << 5) #define AD5791_CTRL_SDODIS BIT(5)
#define AD5761_CTRL_LINCOMP(x) ((x) << 6) #define AD5761_CTRL_LINCOMP(x) ((x) << 6)
#define AD5791_LINCOMP_0_10 0 #define AD5791_LINCOMP_0_10 0
...@@ -54,9 +53,9 @@ ...@@ -54,9 +53,9 @@
#define AD5780_LINCOMP_10_20 12 #define AD5780_LINCOMP_10_20 12
/* Software Control Register */ /* Software Control Register */
#define AD5791_SWCTRL_LDAC (1 << 0) #define AD5791_SWCTRL_LDAC BIT(0)
#define AD5791_SWCTRL_CLR (1 << 1) #define AD5791_SWCTRL_CLR BIT(1)
#define AD5791_SWCTRL_RESET (1 << 2) #define AD5791_SWCTRL_RESET BIT(2)
#define AD5791_DAC_PWRDN_6K 0 #define AD5791_DAC_PWRDN_6K 0
#define AD5791_DAC_PWRDN_3STATE 1 #define AD5791_DAC_PWRDN_3STATE 1
...@@ -72,7 +71,7 @@ struct ad5791_chip_info { ...@@ -72,7 +71,7 @@ struct ad5791_chip_info {
/** /**
* struct ad5791_state - driver instance specific data * struct ad5791_state - driver instance specific data
* @us: spi_device * @spi: spi_device
* @reg_vdd: positive supply regulator * @reg_vdd: positive supply regulator
* @reg_vss: negative supply regulator * @reg_vss: negative supply regulator
* @chip_info: chip model specific constants * @chip_info: chip model specific constants
...@@ -328,7 +327,7 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, ...@@ -328,7 +327,7 @@ static int ad5791_write_raw(struct iio_dev *indio_dev,
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
val &= AD5791_RES_MASK(chan->scan_type.realbits); val &= GENMASK(chan->scan_type.realbits - 1, 0);
val <<= chan->scan_type.shift; val <<= chan->scan_type.shift;
return ad5791_spi_write(st, chan->address, val); return ad5791_spi_write(st, chan->address, val);
......
...@@ -114,7 +114,7 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name, ...@@ -114,7 +114,7 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name,
return trig; return trig;
} }
void iio_trigger_poll(struct iio_trigger *trig, s64 time) void iio_trigger_poll(struct iio_trigger *trig)
{ {
int i; int i;
...@@ -133,12 +133,12 @@ EXPORT_SYMBOL(iio_trigger_poll); ...@@ -133,12 +133,12 @@ EXPORT_SYMBOL(iio_trigger_poll);
irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private) irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private)
{ {
iio_trigger_poll(private, iio_get_time_ns()); iio_trigger_poll(private);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll); EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll);
void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time) void iio_trigger_poll_chained(struct iio_trigger *trig)
{ {
int i; int i;
...@@ -161,7 +161,7 @@ void iio_trigger_notify_done(struct iio_trigger *trig) ...@@ -161,7 +161,7 @@ void iio_trigger_notify_done(struct iio_trigger *trig)
trig->ops->try_reenable) trig->ops->try_reenable)
if (trig->ops->try_reenable(trig)) if (trig->ops->try_reenable(trig))
/* Missed an interrupt so launch new poll now */ /* Missed an interrupt so launch new poll now */
iio_trigger_poll(trig, 0); iio_trigger_poll(trig);
} }
EXPORT_SYMBOL(iio_trigger_notify_done); EXPORT_SYMBOL(iio_trigger_notify_done);
......
...@@ -827,7 +827,7 @@ static void gp2ap020a00f_iio_trigger_work(struct irq_work *work) ...@@ -827,7 +827,7 @@ static void gp2ap020a00f_iio_trigger_work(struct irq_work *work)
struct gp2ap020a00f_data *data = struct gp2ap020a00f_data *data =
container_of(work, struct gp2ap020a00f_data, work); container_of(work, struct gp2ap020a00f_data, work);
iio_trigger_poll(data->trig, 0); iio_trigger_poll(data->trig);
} }
static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data) static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data)
......
...@@ -17,6 +17,16 @@ config AK8975 ...@@ -17,6 +17,16 @@ config AK8975
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called ak8975. will be called ak8975.
config AK09911
tristate "Asahi Kasei AK09911 3-axis Compass"
depends on I2C
help
Say yes here to build support for Asahi Kasei AK09911 3-Axis
Magnetometer.
To compile this driver as a module, choose M here: the module
will be called ak09911.
config MAG3110 config MAG3110
tristate "Freescale MAG3110 3-Axis Magnetometer" tristate "Freescale MAG3110 3-Axis Magnetometer"
depends on I2C depends on I2C
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# #
# When adding new entries keep the list in alphabetical order # When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AK09911) += ak09911.o
obj-$(CONFIG_AK8975) += ak8975.o obj-$(CONFIG_AK8975) += ak8975.o
obj-$(CONFIG_MAG3110) += mag3110.o obj-$(CONFIG_MAG3110) += mag3110.o
obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
......
/*
* AK09911 3-axis compass driver
* Copyright (c) 2014, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <linux/iio/iio.h>
#define AK09911_REG_WIA1 0x00
#define AK09911_REG_WIA2 0x01
#define AK09911_WIA1_VALUE 0x48
#define AK09911_WIA2_VALUE 0x05
#define AK09911_REG_ST1 0x10
#define AK09911_REG_HXL 0x11
#define AK09911_REG_HXH 0x12
#define AK09911_REG_HYL 0x13
#define AK09911_REG_HYH 0x14
#define AK09911_REG_HZL 0x15
#define AK09911_REG_HZH 0x16
#define AK09911_REG_ASAX 0x60
#define AK09911_REG_ASAY 0x61
#define AK09911_REG_ASAZ 0x62
#define AK09911_REG_CNTL1 0x30
#define AK09911_REG_CNTL2 0x31
#define AK09911_REG_CNTL3 0x32
#define AK09911_MODE_SNG_MEASURE 0x01
#define AK09911_MODE_SELF_TEST 0x10
#define AK09911_MODE_FUSE_ACCESS 0x1F
#define AK09911_MODE_POWERDOWN 0x00
#define AK09911_RESET_DATA 0x01
#define AK09911_REG_CNTL1 0x30
#define AK09911_REG_CNTL2 0x31
#define AK09911_REG_CNTL3 0x32
#define AK09911_RAW_TO_GAUSS(asa) ((((asa) + 128) * 6000) / 256)
#define AK09911_MAX_CONVERSION_TIMEOUT_MS 500
#define AK09911_CONVERSION_DONE_POLL_TIME_MS 10
struct ak09911_data {
struct i2c_client *client;
struct mutex lock;
u8 asa[3];
long raw_to_gauss[3];
};
static const int ak09911_index_to_reg[] = {
AK09911_REG_HXL, AK09911_REG_HYL, AK09911_REG_HZL,
};
static int ak09911_set_mode(struct i2c_client *client, u8 mode)
{
int ret;
switch (mode) {
case AK09911_MODE_SNG_MEASURE:
case AK09911_MODE_SELF_TEST:
case AK09911_MODE_FUSE_ACCESS:
case AK09911_MODE_POWERDOWN:
ret = i2c_smbus_write_byte_data(client,
AK09911_REG_CNTL2, mode);
if (ret < 0) {
dev_err(&client->dev, "set_mode error\n");
return ret;
}
/* After mode change wait atleast 100us */
usleep_range(100, 500);
break;
default:
dev_err(&client->dev,
"%s: Unknown mode(%d).", __func__, mode);
return -EINVAL;
}
return ret;
}
/* Get Sensitivity Adjustment value */
static int ak09911_get_asa(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ak09911_data *data = iio_priv(indio_dev);
int ret;
ret = ak09911_set_mode(client, AK09911_MODE_FUSE_ACCESS);
if (ret < 0)
return ret;
/* Get asa data and store in the device data. */
ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_ASAX,
3, data->asa);
if (ret < 0) {
dev_err(&client->dev, "Not able to read asa data\n");
return ret;
}
ret = ak09911_set_mode(client, AK09911_MODE_POWERDOWN);
if (ret < 0)
return ret;
data->raw_to_gauss[0] = AK09911_RAW_TO_GAUSS(data->asa[0]);
data->raw_to_gauss[1] = AK09911_RAW_TO_GAUSS(data->asa[1]);
data->raw_to_gauss[2] = AK09911_RAW_TO_GAUSS(data->asa[2]);
return 0;
}
static int ak09911_verify_chip_id(struct i2c_client *client)
{
u8 wia_val[2];
int ret;
ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_WIA1,
2, wia_val);
if (ret < 0) {
dev_err(&client->dev, "Error reading WIA\n");
return ret;
}
dev_dbg(&client->dev, "WIA %02x %02x\n", wia_val[0], wia_val[1]);
if (wia_val[0] != AK09911_WIA1_VALUE ||
wia_val[1] != AK09911_WIA2_VALUE) {
dev_err(&client->dev, "Device ak09911 not found\n");
return -ENODEV;
}
return 0;
}
static int wait_conversion_complete_polled(struct ak09911_data *data)
{
struct i2c_client *client = data->client;
u8 read_status;
u32 timeout_ms = AK09911_MAX_CONVERSION_TIMEOUT_MS;
int ret;
/* Wait for the conversion to complete. */
while (timeout_ms) {
msleep_interruptible(AK09911_CONVERSION_DONE_POLL_TIME_MS);
ret = i2c_smbus_read_byte_data(client, AK09911_REG_ST1);
if (ret < 0) {
dev_err(&client->dev, "Error in reading ST1\n");
return ret;
}
read_status = ret & 0x01;
if (read_status)
break;
timeout_ms -= AK09911_CONVERSION_DONE_POLL_TIME_MS;
}
if (!timeout_ms) {
dev_err(&client->dev, "Conversion timeout happened\n");
return -EIO;
}
return read_status;
}
static int ak09911_read_axis(struct iio_dev *indio_dev, int index, int *val)
{
struct ak09911_data *data = iio_priv(indio_dev);
struct i2c_client *client = data->client;
int ret;
mutex_lock(&data->lock);
ret = ak09911_set_mode(client, AK09911_MODE_SNG_MEASURE);
if (ret < 0)
goto fn_exit;
ret = wait_conversion_complete_polled(data);
if (ret < 0)
goto fn_exit;
/* Read data */
ret = i2c_smbus_read_word_data(client, ak09911_index_to_reg[index]);
if (ret < 0) {
dev_err(&client->dev, "Read axis data fails\n");
goto fn_exit;
}
mutex_unlock(&data->lock);
/* Clamp to valid range. */
*val = sign_extend32(clamp_t(s16, ret, -8192, 8191), 13);
return IIO_VAL_INT;
fn_exit:
mutex_unlock(&data->lock);
return ret;
}
static int ak09911_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2,
long mask)
{
struct ak09911_data *data = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_RAW:
return ak09911_read_axis(indio_dev, chan->address, val);
case IIO_CHAN_INFO_SCALE:
*val = 0;
*val2 = data->raw_to_gauss[chan->address];
return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
#define AK09911_CHANNEL(axis, index) \
{ \
.type = IIO_MAGN, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.address = index, \
}
static const struct iio_chan_spec ak09911_channels[] = {
AK09911_CHANNEL(X, 0), AK09911_CHANNEL(Y, 1), AK09911_CHANNEL(Z, 2),
};
static const struct iio_info ak09911_info = {
.read_raw = &ak09911_read_raw,
.driver_module = THIS_MODULE,
};
static const struct acpi_device_id ak_acpi_match[] = {
{"AK009911", 0},
{ },
};
MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
static int ak09911_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct ak09911_data *data;
const char *name;
int ret;
ret = ak09911_verify_chip_id(client);
if (ret) {
dev_err(&client->dev, "AK00911 not detected\n");
return -ENODEV;
}
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;
mutex_init(&data->lock);
ret = ak09911_get_asa(client);
if (ret)
return ret;
if (id)
name = id->name;
else if (ACPI_HANDLE(&client->dev))
name = dev_name(&client->dev);
else
return -ENODEV;
dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
indio_dev->dev.parent = &client->dev;
indio_dev->channels = ak09911_channels;
indio_dev->num_channels = ARRAY_SIZE(ak09911_channels);
indio_dev->info = &ak09911_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->name = name;
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id ak09911_id[] = {
{"ak09911", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, ak09911_id);
static struct i2c_driver ak09911_driver = {
.driver = {
.name = "ak09911",
.acpi_match_table = ACPI_PTR(ak_acpi_match),
},
.probe = ak09911_probe,
.id_table = ak09911_id,
};
module_i2c_driver(ak09911_driver);
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("AK09911 Compass driver");
...@@ -70,4 +70,14 @@ config IIO_ST_PRESS_SPI ...@@ -70,4 +70,14 @@ config IIO_ST_PRESS_SPI
depends on IIO_ST_PRESS depends on IIO_ST_PRESS
depends on IIO_ST_SENSORS_SPI depends on IIO_ST_SENSORS_SPI
config T5403
tristate "EPCOS T5403 digital barometric pressure sensor driver"
depends on I2C
help
Say yes here to build support for the EPCOS T5403 pressure sensor
connected via I2C.
To compile this driver as a module, choose M here: the module
will be called t5403.
endmenu endmenu
...@@ -9,6 +9,7 @@ obj-$(CONFIG_MPL3115) += mpl3115.o ...@@ -9,6 +9,7 @@ obj-$(CONFIG_MPL3115) += mpl3115.o
obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
st_pressure-y := st_pressure_core.o st_pressure-y := st_pressure_core.o
st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
obj-$(CONFIG_T5403) += t5403.o
obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
/*
* t5403.c - Support for EPCOS T5403 pressure/temperature sensor
*
* Copyright (c) 2014 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.
*
* (7-bit I2C slave address 0x77)
*
* TODO: end-of-conversion irq
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/delay.h>
#define T5403_DATA 0xf5 /* data, LSB first, 16 bit */
#define T5403_CALIB_DATA 0x8e /* 10 calibration coeff., LSB first, 16 bit */
#define T5403_SLAVE_ADDR 0x88 /* I2C slave address, 0x77 */
#define T5403_COMMAND 0xf1
/* command bits */
#define T5403_MODE_SHIFT 3 /* conversion time: 2, 8, 16, 66 ms */
#define T5403_PT BIT(1) /* 0 .. pressure, 1 .. temperature measurement */
#define T5403_SCO BIT(0) /* start conversion */
#define T5403_MODE_LOW 0
#define T5403_MODE_STANDARD 1
#define T5403_MODE_HIGH 2
#define T5403_MODE_ULTRA_HIGH 3
#define T5403_I2C_MASK (~BIT(7))
#define T5403_I2C_ADDR 0x77
static const int t5403_pressure_conv_ms[] = {2, 8, 16, 66};
struct t5403_data {
struct i2c_client *client;
struct mutex lock;
int mode;
__le16 c[10];
};
#define T5403_C_U16(i) le16_to_cpu(data->c[(i) - 1])
#define T5403_C(i) sign_extend32(T5403_C_U16(i), 15)
static int t5403_read(struct t5403_data *data, bool pressure)
{
int wait_time = 3; /* wakeup time in ms */
int ret = i2c_smbus_write_byte_data(data->client, T5403_COMMAND,
(pressure ? (data->mode << T5403_MODE_SHIFT) : T5403_PT) |
T5403_SCO);
if (ret < 0)
return ret;
wait_time += pressure ? t5403_pressure_conv_ms[data->mode] : 2;
msleep(wait_time);
return i2c_smbus_read_word_data(data->client, T5403_DATA);
}
static int t5403_comp_pressure(struct t5403_data *data, int *val, int *val2)
{
int ret;
s16 t_r;
u16 p_r;
s32 S, O, X;
mutex_lock(&data->lock);
ret = t5403_read(data, false);
if (ret < 0)
goto done;
t_r = ret;
ret = t5403_read(data, true);
if (ret < 0)
goto done;
p_r = ret;
/* see EPCOS application note */
S = T5403_C_U16(3) + (s32) T5403_C_U16(4) * t_r / 0x20000 +
T5403_C(5) * t_r / 0x8000 * t_r / 0x80000 +
T5403_C(9) * t_r / 0x8000 * t_r / 0x8000 * t_r / 0x10000;
O = T5403_C(6) * 0x4000 + T5403_C(7) * t_r / 8 +
T5403_C(8) * t_r / 0x8000 * t_r / 16 +
T5403_C(9) * t_r / 0x8000 * t_r / 0x10000 * t_r;
X = (S * p_r + O) / 0x4000;
X += ((X - 75000) * (X - 75000) / 0x10000 - 9537) *
T5403_C(10) / 0x10000;
*val = X / 1000;
*val2 = (X % 1000) * 1000;
done:
mutex_unlock(&data->lock);
return ret;
}
static int t5403_comp_temp(struct t5403_data *data, int *val)
{
int ret;
s16 t_r;
mutex_lock(&data->lock);
ret = t5403_read(data, false);
if (ret < 0)
goto done;
t_r = ret;
/* see EPCOS application note */
*val = ((s32) T5403_C_U16(1) * t_r / 0x100 +
(s32) T5403_C_U16(2) * 0x40) * 1000 / 0x10000;
done:
mutex_unlock(&data->lock);
return ret;
}
static int t5403_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct t5403_data *data = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
switch (chan->type) {
case IIO_PRESSURE:
ret = t5403_comp_pressure(data, val, val2);
if (ret < 0)
return ret;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_TEMP:
ret = t5403_comp_temp(data, val);
if (ret < 0)
return ret;
return IIO_VAL_INT;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_INT_TIME:
*val = 0;
*val2 = t5403_pressure_conv_ms[data->mode] * 1000;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
}
static int t5403_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct t5403_data *data = iio_priv(indio_dev);
int i;
switch (mask) {
case IIO_CHAN_INFO_INT_TIME:
if (val != 0)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(t5403_pressure_conv_ms); i++)
if (val2 == t5403_pressure_conv_ms[i] * 1000) {
mutex_lock(&data->lock);
data->mode = i;
mutex_unlock(&data->lock);
return 0;
}
return -EINVAL;
default:
return -EINVAL;
}
}
static const struct iio_chan_spec t5403_channels[] = {
{
.type = IIO_PRESSURE,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_INT_TIME),
},
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
},
};
static IIO_CONST_ATTR_INT_TIME_AVAIL("0.002 0.008 0.016 0.066");
static struct attribute *t5403_attributes[] = {
&iio_const_attr_integration_time_available.dev_attr.attr,
NULL
};
static const struct attribute_group t5403_attribute_group = {
.attrs = t5403_attributes,
};
static const struct iio_info t5403_info = {
.read_raw = &t5403_read_raw,
.write_raw = &t5403_write_raw,
.attrs = &t5403_attribute_group,
.driver_module = THIS_MODULE,
};
static int t5403_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct t5403_data *data;
struct iio_dev *indio_dev;
int ret;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK))
return -ENODEV;
ret = i2c_smbus_read_byte_data(client, T5403_SLAVE_ADDR);
if (ret < 0)
return ret;
if ((ret & T5403_I2C_MASK) != T5403_I2C_ADDR)
return -ENODEV;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
data->client = client;
mutex_init(&data->lock);
i2c_set_clientdata(client, indio_dev);
indio_dev->info = &t5403_info;
indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = t5403_channels;
indio_dev->num_channels = ARRAY_SIZE(t5403_channels);
data->mode = T5403_MODE_STANDARD;
ret = i2c_smbus_read_i2c_block_data(data->client, T5403_CALIB_DATA,
sizeof(data->c), (u8 *) data->c);
if (ret < 0)
return ret;
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id t5403_id[] = {
{ "t5403", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, t5403_id);
static struct i2c_driver t5403_driver = {
.driver = {
.name = "t5403",
},
.probe = t5403_probe,
.id_table = t5403_id,
};
module_i2c_driver(t5403_driver);
MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
MODULE_DESCRIPTION("EPCOS T5403 pressure/temperature sensor driver");
MODULE_LICENSE("GPL");
...@@ -232,7 +232,7 @@ static void as3935_event_work(struct work_struct *work) ...@@ -232,7 +232,7 @@ static void as3935_event_work(struct work_struct *work)
switch (val) { switch (val) {
case AS3935_EVENT_INT: case AS3935_EVENT_INT:
iio_trigger_poll(st->trig, iio_get_time_ns()); iio_trigger_poll(st->trig);
break; break;
case AS3935_NOISE_INT: case AS3935_NOISE_INT:
dev_warn(&st->spi->dev, "noise level is too high"); dev_warn(&st->spi->dev, "noise level is too high");
......
...@@ -24,8 +24,7 @@ struct iio_interrupt_trigger_info { ...@@ -24,8 +24,7 @@ struct iio_interrupt_trigger_info {
static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private) static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private)
{ {
/* Timestamp not currently provided */ iio_trigger_poll(private);
iio_trigger_poll(private, 0);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -96,7 +96,7 @@ static void iio_sysfs_trigger_work(struct irq_work *work) ...@@ -96,7 +96,7 @@ static void iio_sysfs_trigger_work(struct irq_work *work)
struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig, struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig,
work); work);
iio_trigger_poll(trig->trig, 0); iio_trigger_poll(trig->trig);
} }
static ssize_t iio_sysfs_trigger_poll(struct device *dev, static ssize_t iio_sysfs_trigger_poll(struct device *dev,
......
...@@ -305,9 +305,12 @@ int main(int argc, char **argv) ...@@ -305,9 +305,12 @@ int main(int argc, char **argv)
read_size = read(fp, read_size = read(fp,
data, data,
toread*scan_size); toread*scan_size);
if (read_size == -EAGAIN) { if (read_size < 0) {
printf("nothing available\n"); if (errno == -EAGAIN) {
continue; printf("nothing available\n");
continue;
} else
break;
} }
for (i = 0; i < read_size/scan_size; i++) for (i = 0; i < read_size/scan_size; i++)
process_scan(data + scan_size*i, process_scan(data + scan_size*i,
......
...@@ -46,6 +46,9 @@ static const char * const iio_chan_type_name_spec[] = { ...@@ -46,6 +46,9 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_TIMESTAMP] = "timestamp", [IIO_TIMESTAMP] = "timestamp",
[IIO_CAPACITANCE] = "capacitance", [IIO_CAPACITANCE] = "capacitance",
[IIO_ALTVOLTAGE] = "altvoltage", [IIO_ALTVOLTAGE] = "altvoltage",
[IIO_CCT] = "cct",
[IIO_PRESSURE] = "pressure",
[IIO_HUMIDITYRELATIVE] = "humidityrelative",
}; };
static const char * const iio_ev_type_text[] = { static const char * const iio_ev_type_text[] = {
...@@ -70,6 +73,8 @@ static const char * const iio_modifier_names[] = { ...@@ -70,6 +73,8 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_LIGHT_IR] = "ir", [IIO_MOD_LIGHT_IR] = "ir",
[IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
[IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2", [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
[IIO_MOD_LIGHT_BOTH] = "both",
[IIO_MOD_LIGHT_IR] = "ir",
[IIO_MOD_LIGHT_CLEAR] = "clear", [IIO_MOD_LIGHT_CLEAR] = "clear",
[IIO_MOD_LIGHT_RED] = "red", [IIO_MOD_LIGHT_RED] = "red",
[IIO_MOD_LIGHT_GREEN] = "green", [IIO_MOD_LIGHT_GREEN] = "green",
...@@ -100,6 +105,9 @@ static bool event_is_known(struct iio_event_data *event) ...@@ -100,6 +105,9 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_TIMESTAMP: case IIO_TIMESTAMP:
case IIO_CAPACITANCE: case IIO_CAPACITANCE:
case IIO_ALTVOLTAGE: case IIO_ALTVOLTAGE:
case IIO_CCT:
case IIO_PRESSURE:
case IIO_HUMIDITYRELATIVE:
break; break;
default: default:
return false; return false;
...@@ -114,6 +122,8 @@ static bool event_is_known(struct iio_event_data *event) ...@@ -114,6 +122,8 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_MOD_LIGHT_IR: case IIO_MOD_LIGHT_IR:
case IIO_MOD_ROOT_SUM_SQUARED_X_Y: case IIO_MOD_ROOT_SUM_SQUARED_X_Y:
case IIO_MOD_SUM_SQUARED_X_Y_Z: case IIO_MOD_SUM_SQUARED_X_Y_Z:
case IIO_MOD_LIGHT_BOTH:
case IIO_MOD_LIGHT_IR:
case IIO_MOD_LIGHT_CLEAR: case IIO_MOD_LIGHT_CLEAR:
case IIO_MOD_LIGHT_RED: case IIO_MOD_LIGHT_RED:
case IIO_MOD_LIGHT_GREEN: case IIO_MOD_LIGHT_GREEN:
......
...@@ -633,7 +633,7 @@ int read_sysfs_posint(char *filename, char *basedir) ...@@ -633,7 +633,7 @@ int read_sysfs_posint(char *filename, char *basedir)
int read_sysfs_float(char *filename, char *basedir, float *val) int read_sysfs_float(char *filename, char *basedir, float *val)
{ {
float ret = 0; int ret = 0;
FILE *sysfsfp; FILE *sysfsfp;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2); char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
if (temp == NULL) { if (temp == NULL) {
...@@ -653,9 +653,9 @@ int read_sysfs_float(char *filename, char *basedir, float *val) ...@@ -653,9 +653,9 @@ int read_sysfs_float(char *filename, char *basedir, float *val)
return ret; return ret;
} }
read_sysfs_string(const char *filename, const char *basedir, char *str) int read_sysfs_string(const char *filename, const char *basedir, char *str)
{ {
float ret = 0; int ret = 0;
FILE *sysfsfp; FILE *sysfsfp;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2); char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
if (temp == NULL) { if (temp == NULL) {
......
...@@ -31,5 +31,5 @@ consumers. ...@@ -31,5 +31,5 @@ consumers.
Trigger Consumers Trigger Consumers
Currently triggers are only used for the filling of software Currently triggers are only used for the filling of software
buffers and as such any device supporting INDIO_RING_TRIGGERED has the buffers and as such any device supporting INDIO_BUFFER_TRIGGERED has the
consumer interface automatically created. consumer interface automatically created.
...@@ -31,7 +31,7 @@ irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private) ...@@ -31,7 +31,7 @@ irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
struct lis3l02dq_state *st = iio_priv(indio_dev); struct lis3l02dq_state *st = iio_priv(indio_dev);
if (st->trigger_on) { if (st->trigger_on) {
iio_trigger_poll(st->trig, iio_get_time_ns()); iio_trigger_poll(st->trig);
return IRQ_HANDLED; return IRQ_HANDLED;
} else } else
return IRQ_WAKE_THREAD; return IRQ_WAKE_THREAD;
......
...@@ -1166,7 +1166,7 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data) ...@@ -1166,7 +1166,7 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
mxs_lradc_handle_touch(lradc); mxs_lradc_handle_touch(lradc);
if (iio_buffer_enabled(iio)) if (iio_buffer_enabled(iio))
iio_trigger_poll(iio->trig, iio_get_time_ns()); iio_trigger_poll(iio->trig);
else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
complete(&lradc->completion); complete(&lradc->completion);
......
...@@ -550,6 +550,7 @@ static int iio_dummy_remove(int index) ...@@ -550,6 +550,7 @@ static int iio_dummy_remove(int index)
static __init int iio_dummy_init(void) static __init int iio_dummy_init(void)
{ {
int i, ret; int i, ret;
if (instances > 10) { if (instances > 10) {
instances = 1; instances = 1;
return -EINVAL; return -EINVAL;
...@@ -577,6 +578,7 @@ module_init(iio_dummy_init); ...@@ -577,6 +578,7 @@ module_init(iio_dummy_init);
static __exit void iio_dummy_exit(void) static __exit void iio_dummy_exit(void)
{ {
int i; int i;
for (i = 0; i < instances; i++) for (i = 0; i < instances; i++)
iio_dummy_remove(i); iio_dummy_remove(i);
kfree(iio_dummy_devs); kfree(iio_dummy_devs);
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private) static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
{ {
disable_irq_nosync(irq); disable_irq_nosync(irq);
iio_trigger_poll(private, iio_get_time_ns()); iio_trigger_poll(private);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -154,7 +154,7 @@ static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid) ...@@ -154,7 +154,7 @@ static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid)
struct bfin_tmr_state *st = devid; struct bfin_tmr_state *st = devid;
clear_gptimer_intr(st->t->id); clear_gptimer_intr(st->t->id);
iio_trigger_poll(st->trig, 0); iio_trigger_poll(st->trig);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -26,16 +26,22 @@ struct iio_prtc_trigger_info { ...@@ -26,16 +26,22 @@ struct iio_prtc_trigger_info {
struct rtc_device *rtc; struct rtc_device *rtc;
int frequency; int frequency;
struct rtc_task task; struct rtc_task task;
bool state;
}; };
static int iio_trig_periodic_rtc_set_state(struct iio_trigger *trig, bool state) static int iio_trig_periodic_rtc_set_state(struct iio_trigger *trig, bool state)
{ {
struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig); struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
if (trig_info->frequency == 0) int ret;
if (trig_info->frequency == 0 && state)
return -EINVAL; return -EINVAL;
dev_info(&trig_info->rtc->dev, "trigger frequency is %d\n", dev_dbg(&trig_info->rtc->dev, "trigger frequency is %d\n",
trig_info->frequency); trig_info->frequency);
return rtc_irq_set_state(trig_info->rtc, &trig_info->task, state); ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
if (ret == 0)
trig_info->state = state;
return ret;
} }
static ssize_t iio_trig_periodic_read_freq(struct device *dev, static ssize_t iio_trig_periodic_read_freq(struct device *dev,
...@@ -61,7 +67,14 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev, ...@@ -61,7 +67,14 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev,
if (ret) if (ret)
goto error_ret; goto error_ret;
ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val); if (val > 0) {
ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val);
if (ret == 0 && trig_info->state && trig_info->frequency == 0)
ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 1);
} else if (val == 0) {
ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0);
} else
ret = -EINVAL;
if (ret) if (ret)
goto error_ret; goto error_ret;
...@@ -93,8 +106,7 @@ static const struct attribute_group *iio_trig_prtc_attr_groups[] = { ...@@ -93,8 +106,7 @@ static const struct attribute_group *iio_trig_prtc_attr_groups[] = {
static void iio_prtc_trigger_poll(void *private_data) static void iio_prtc_trigger_poll(void *private_data)
{ {
/* Timestamp is not provided currently */ iio_trigger_poll(private_data);
iio_trigger_poll(private_data, 0);
} }
static const struct iio_trigger_ops iio_prtc_trigger_ops = { static const struct iio_trigger_ops iio_prtc_trigger_ops = {
...@@ -128,8 +140,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev) ...@@ -128,8 +140,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
iio_trigger_set_drvdata(trig, trig_info); iio_trigger_set_drvdata(trig, trig_info);
trig->ops = &iio_prtc_trigger_ops; trig->ops = &iio_prtc_trigger_ops;
/* RTC access */ /* RTC access */
trig_info->rtc trig_info->rtc = rtc_class_open(pdata[i]);
= rtc_class_open(pdata[i]);
if (trig_info->rtc == NULL) { if (trig_info->rtc == NULL) {
ret = -EINVAL; ret = -EINVAL;
goto error_free_trig_info; goto error_free_trig_info;
...@@ -199,5 +210,5 @@ static struct platform_driver iio_trig_periodic_rtc_driver = { ...@@ -199,5 +210,5 @@ static struct platform_driver iio_trig_periodic_rtc_driver = {
module_platform_driver(iio_trig_periodic_rtc_driver); module_platform_driver(iio_trig_periodic_rtc_driver);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>"); MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem"); MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
/*
* KXCJK-1013 3-axis accelerometer Interface
* Copyright (c) 2014, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __IIO_KXCJK_1013_H__
#define __IIO_KXCJK_1013_H__
struct kxcjk_1013_platform_data {
bool active_high_intr;
};
#endif
...@@ -129,12 +129,11 @@ void iio_trigger_unregister(struct iio_trigger *trig_info); ...@@ -129,12 +129,11 @@ void iio_trigger_unregister(struct iio_trigger *trig_info);
/** /**
* iio_trigger_poll() - called on a trigger occurring * iio_trigger_poll() - called on a trigger occurring
* @trig: trigger which occurred * @trig: trigger which occurred
* @time: timestamp when trigger occurred
* *
* Typically called in relevant hardware interrupt handler. * Typically called in relevant hardware interrupt handler.
**/ **/
void iio_trigger_poll(struct iio_trigger *trig, s64 time); void iio_trigger_poll(struct iio_trigger *trig);
void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time); void iio_trigger_poll_chained(struct iio_trigger *trig);
irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private);
......
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