Third set of new stuff for IIO in the 4.5 cycle.

New driver features
 - us5182
   * Add interrupt support and rising / falling threshold events.
 
 Cleanups / fixes to new stuff / minor additions
 * Expose the IIO value formatting function for drivers to
   make use of internally.
 - ina2xx
    * Fix wrong channel order
    * Fix incorrect reporting of endianness
    * Adding documentation of ABI unique to this device
 - mma8452
   * Drop an unused register description
   * Use an enum for the channel index to aid readability
 - sca3000
   * Use standard NULL comparison style
 - us5182
   * fix an inconsistency in status of enable (a bug with no real effect until
     above patches are applied)
   * refactor the read_raw function to improve maintainability / readability.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJWeZ3IAAoJEFSFNJnE9BaIT2UP/3+VlQzBFrg1pBqLCR4xqMHB
 9gUBInzgBwmzpmAqD9pkvyG5f9fTz7hSqX2IGkAA1V6I91H2cunEROSGyhFd4VBW
 vhUhpz9WpRyx+8yLE3fQKUU/UmZJWTI7Xyladwrk3k87OOdcfn3wjtUdTuAhD5SW
 OWzW9txC5dAgSEC5yhqD8VdXN6tRL/eEOEFawHlf9f7bBr9DuyhECp6aIP79gKAS
 pynUPe3R5Uk/GuXdKX6zEWim4XZxhQR0oRmtrdCPIbauK6/ENDOWcaAvgS3mcN8i
 KJ/L27hQGc5zjR8VzysZzZw+7Edc4EqY2UvhA19+0RN93064s0qvR8hoEMp0bHP/
 MKGtwHv8MiqKfdCqIdimf6aT2GILTVWWx8WjyrM0O0+h444ba3ETRPGQ4mYNohuN
 Gt7FFv345aiFh2lQw8Rb54H2d19KV2hwUar3CTpRcl9OhOEnD3ulfDvQghzNlbXl
 nUh5dSOK+yDmXPPMEeZU4pYKG8rNaNZ1FxvVFy/yvUgytD1uqQDnWZ3b1gR0DiV9
 56ucUcrSg74LSqC8R/D6BXb+73LPBTmpu60iGvOQsUYcnmJSdnmEobWCnSXGjFXR
 I2e/H/ZOL4+dyHVpoyfQIiDpe6rGgYQHxyQ/kojWn2NxCJpgUufuR6jPTJ9GMF7k
 eckCq5cDb0nmmg45EQq0
 =aiE2
 -----END PGP SIGNATURE-----

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

Jonathan writes:

Third set of new stuff for IIO in the 4.5 cycle.

New driver features
- us5182
  * Add interrupt support and rising / falling threshold events.

Cleanups / fixes to new stuff / minor additions
* Expose the IIO value formatting function for drivers to
  make use of internally.
- ina2xx
   * Fix wrong channel order
   * Fix incorrect reporting of endianness
   * Adding documentation of ABI unique to this device
- mma8452
  * Drop an unused register description
  * Use an enum for the channel index to aid readability
- sca3000
  * Use standard NULL comparison style
- us5182
  * fix an inconsistency in status of enable (a bug with no real effect until
    above patches are applied)
  * refactor the read_raw function to improve maintainability / readability.
This commit is contained in:
Greg Kroah-Hartman 2015-12-26 17:05:25 -08:00
commit 02c34ccc1d
7 changed files with 414 additions and 103 deletions

View File

@ -0,0 +1,24 @@
What: /sys/bus/iio/devices/iio:deviceX/in_allow_async_readout
Date: December 2015
KernelVersion: 4.4
Contact: linux-iio@vger.kernel.org
Description:
By default (value '0'), the capture thread checks for the Conversion
Ready Flag to being set prior to committing a new value to the sample
buffer. This synchronizes the in-chip conversion rate with the
in-driver readout rate at the cost of an additional register read.
Writing '1' will remove the polling for the Conversion Ready Flags to
save the additional i2c transaction, which will improve the bandwidth
available for reading data. However, samples can be occasionally skipped
or repeated, depending on the beat between the capture and conversion
rates.
What: /sys/bus/iio/devices/iio:deviceX/in_shunt_resistor
Date: December 2015
KernelVersion: 4.4
Contact: linux-iio@vger.kernel.org
Description:
The value of the shunt resistor may be known only at runtime fom an
eeprom content read by a client application. This attribute allows to
set its value in ohms.

View File

@ -58,7 +58,6 @@
#define MMA8452_FF_MT_COUNT 0x18
#define MMA8452_TRANSIENT_CFG 0x1d
#define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0)
#define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1)
#define MMA8452_TRANSIENT_CFG_ELE BIT(4)
#define MMA8452_TRANSIENT_SRC 0x1e
#define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1)
@ -144,6 +143,13 @@ struct mma_chip_info {
u8 ev_count;
};
enum {
idx_x,
idx_y,
idx_z,
idx_ts,
};
static int mma8452_drdy(struct mma8452_data *data)
{
int tries = 150;
@ -817,31 +823,31 @@ static struct attribute_group mma8452_event_attribute_group = {
}
static const struct iio_chan_spec mma8452_channels[] = {
MMA8452_CHANNEL(X, 0, 12),
MMA8452_CHANNEL(Y, 1, 12),
MMA8452_CHANNEL(Z, 2, 12),
IIO_CHAN_SOFT_TIMESTAMP(3),
MMA8452_CHANNEL(X, idx_x, 12),
MMA8452_CHANNEL(Y, idx_y, 12),
MMA8452_CHANNEL(Z, idx_z, 12),
IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
};
static const struct iio_chan_spec mma8453_channels[] = {
MMA8452_CHANNEL(X, 0, 10),
MMA8452_CHANNEL(Y, 1, 10),
MMA8452_CHANNEL(Z, 2, 10),
IIO_CHAN_SOFT_TIMESTAMP(3),
MMA8452_CHANNEL(X, idx_x, 10),
MMA8452_CHANNEL(Y, idx_y, 10),
MMA8452_CHANNEL(Z, idx_z, 10),
IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
};
static const struct iio_chan_spec mma8652_channels[] = {
MMA8652_CHANNEL(X, 0, 12),
MMA8652_CHANNEL(Y, 1, 12),
MMA8652_CHANNEL(Z, 2, 12),
IIO_CHAN_SOFT_TIMESTAMP(3),
MMA8652_CHANNEL(X, idx_x, 12),
MMA8652_CHANNEL(Y, idx_y, 12),
MMA8652_CHANNEL(Z, idx_z, 12),
IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
};
static const struct iio_chan_spec mma8653_channels[] = {
MMA8652_CHANNEL(X, 0, 10),
MMA8652_CHANNEL(Y, 1, 10),
MMA8652_CHANNEL(Z, 2, 10),
IIO_CHAN_SOFT_TIMESTAMP(3),
MMA8652_CHANNEL(X, idx_x, 10),
MMA8652_CHANNEL(Y, idx_y, 10),
MMA8652_CHANNEL(Z, idx_z, 10),
IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
};
enum {

View File

@ -400,7 +400,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
.sign = 'u', \
.realbits = 16, \
.storagebits = 16, \
.endianness = IIO_LE, \
.endianness = IIO_CPU, \
} \
}
@ -428,8 +428,8 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
static const struct iio_chan_spec ina2xx_channels[] = {
INA2XX_CHAN_VOLTAGE(0, INA2XX_SHUNT_VOLTAGE),
INA2XX_CHAN_VOLTAGE(1, INA2XX_BUS_VOLTAGE),
INA2XX_CHAN(IIO_CURRENT, 2, INA2XX_CURRENT),
INA2XX_CHAN(IIO_POWER, 3, INA2XX_POWER),
INA2XX_CHAN(IIO_POWER, 2, INA2XX_POWER),
INA2XX_CHAN(IIO_CURRENT, 3, INA2XX_CURRENT),
IIO_CHAN_SOFT_TIMESTAMP(4),
};

View File

@ -470,6 +470,7 @@ ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals)
return 0;
}
}
EXPORT_SYMBOL_GPL(iio_format_value);
static ssize_t iio_read_channel_info(struct device *dev,
struct device_attribute *attr,

View File

@ -20,7 +20,10 @@
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/iio/sysfs.h>
#include <linux/mutex.h>
#include <linux/pm.h>
@ -30,6 +33,8 @@
#define US5182D_CFG0_ONESHOT_EN BIT(6)
#define US5182D_CFG0_SHUTDOWN_EN BIT(7)
#define US5182D_CFG0_WORD_ENABLE BIT(0)
#define US5182D_CFG0_PROX BIT(3)
#define US5182D_CFG0_PX_IRQ BIT(2)
#define US5182D_REG_CFG1 0x01
#define US5182D_CFG1_ALS_RES16 BIT(4)
@ -41,6 +46,7 @@
#define US5182D_REG_CFG3 0x03
#define US5182D_CFG3_LED_CURRENT100 (BIT(4) | BIT(5))
#define US5182D_CFG3_INT_SOURCE_PX BIT(3)
#define US5182D_REG_CFG4 0x10
@ -55,6 +61,13 @@
#define US5182D_REG_AUTO_LDARK_GAIN 0x29
#define US5182D_REG_AUTO_HDARK_GAIN 0x2a
/* Thresholds for events: px low (0x08-l, 0x09-h), px high (0x0a-l 0x0b-h) */
#define US5182D_REG_PXL_TH 0x08
#define US5182D_REG_PXH_TH 0x0a
#define US5182D_REG_PXL_TH_DEFAULT 1000
#define US5182D_REG_PXH_TH_DEFAULT 30000
#define US5182D_OPMODE_ALS 0x01
#define US5182D_OPMODE_PX 0x02
#define US5182D_OPMODE_SHIFT 4
@ -84,6 +97,8 @@
#define US5182D_READ_WORD 2
#define US5182D_OPSTORE_SLEEP_TIME 20 /* ms */
#define US5182D_SLEEP_MS 3000 /* ms */
#define US5182D_PXH_TH_DISABLE 0xffff
#define US5182D_PXL_TH_DISABLE 0x0000
/* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */
static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600,
@ -119,6 +134,12 @@ struct us5182d_data {
u8 upper_dark_gain;
u16 *us5182d_dark_ths;
u16 px_low_th;
u16 px_high_th;
int rising_en;
int falling_en;
u8 opmode;
u8 power_mode;
@ -148,10 +169,26 @@ static const struct {
{US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16},
{US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 |
US5182D_CFG2_PXGAIN_DEFAULT)},
{US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100},
{US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100 |
US5182D_CFG3_INT_SOURCE_PX},
{US5182D_REG_CFG4, 0x00},
};
static const struct iio_event_spec us5182d_events[] = {
{
.type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_RISING,
.mask_separate = BIT(IIO_EV_INFO_VALUE) |
BIT(IIO_EV_INFO_ENABLE),
},
{
.type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_FALLING,
.mask_separate = BIT(IIO_EV_INFO_VALUE) |
BIT(IIO_EV_INFO_ENABLE),
},
};
static const struct iio_chan_spec us5182d_channels[] = {
{
.type = IIO_LIGHT,
@ -161,26 +198,11 @@ static const struct iio_chan_spec us5182d_channels[] = {
{
.type = IIO_PROXIMITY,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.event_spec = us5182d_events,
.num_event_specs = ARRAY_SIZE(us5182d_events),
}
};
static int us5182d_get_als(struct us5182d_data *data)
{
int ret;
unsigned long result;
ret = i2c_smbus_read_word_data(data->client,
US5182D_REG_ADL);
if (ret < 0)
return ret;
result = ret * data->ga / US5182D_GA_RESOLUTION;
if (result > 0xffff)
result = 0xffff;
return result;
}
static int us5182d_oneshot_en(struct us5182d_data *data)
{
int ret;
@ -238,8 +260,12 @@ static int us5182d_als_enable(struct us5182d_data *data)
int ret;
u8 mode;
if (data->power_mode == US5182D_ONESHOT)
return us5182d_set_opmode(data, US5182D_ALS_ONLY);
if (data->power_mode == US5182D_ONESHOT) {
ret = us5182d_set_opmode(data, US5182D_ALS_ONLY);
if (ret < 0)
return ret;
data->px_enabled = false;
}
if (data->als_enabled)
return 0;
@ -260,8 +286,12 @@ static int us5182d_px_enable(struct us5182d_data *data)
int ret;
u8 mode;
if (data->power_mode == US5182D_ONESHOT)
return us5182d_set_opmode(data, US5182D_PX_ONLY);
if (data->power_mode == US5182D_ONESHOT) {
ret = us5182d_set_opmode(data, US5182D_PX_ONLY);
if (ret < 0)
return ret;
data->als_enabled = false;
}
if (data->px_enabled)
return 0;
@ -277,6 +307,39 @@ static int us5182d_px_enable(struct us5182d_data *data)
return 0;
}
static int us5182d_get_als(struct us5182d_data *data)
{
int ret;
unsigned long result;
ret = us5182d_als_enable(data);
if (ret < 0)
return ret;
ret = i2c_smbus_read_word_data(data->client,
US5182D_REG_ADL);
if (ret < 0)
return ret;
result = ret * data->ga / US5182D_GA_RESOLUTION;
if (result > 0xffff)
result = 0xffff;
return result;
}
static int us5182d_get_px(struct us5182d_data *data)
{
int ret;
ret = us5182d_px_enable(data);
if (ret < 0)
return ret;
return i2c_smbus_read_word_data(data->client,
US5182D_REG_PDL);
}
static int us5182d_shutdown_en(struct us5182d_data *data, u8 state)
{
int ret;
@ -323,6 +386,46 @@ static int us5182d_set_power_state(struct us5182d_data *data, bool on)
return ret;
}
static int us5182d_read_value(struct us5182d_data *data,
struct iio_chan_spec const *chan)
{
int ret, value;
mutex_lock(&data->lock);
if (data->power_mode == US5182D_ONESHOT) {
ret = us5182d_oneshot_en(data);
if (ret < 0)
goto out_err;
}
ret = us5182d_set_power_state(data, true);
if (ret < 0)
goto out_err;
if (chan->type == IIO_LIGHT)
ret = us5182d_get_als(data);
else
ret = us5182d_get_px(data);
if (ret < 0)
goto out_poweroff;
value = ret;
ret = us5182d_set_power_state(data, false);
if (ret < 0)
goto out_err;
mutex_unlock(&data->lock);
return value;
out_poweroff:
us5182d_set_power_state(data, false);
out_err:
mutex_unlock(&data->lock);
return ret;
}
static int us5182d_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
@ -332,76 +435,21 @@ static int us5182d_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
switch (chan->type) {
case IIO_LIGHT:
mutex_lock(&data->lock);
if (data->power_mode == US5182D_ONESHOT) {
ret = us5182d_oneshot_en(data);
if (ret < 0)
goto out_err;
}
ret = us5182d_set_power_state(data, true);
if (ret < 0)
goto out_err;
ret = us5182d_als_enable(data);
if (ret < 0)
goto out_poweroff;
ret = us5182d_get_als(data);
if (ret < 0)
goto out_poweroff;
*val = ret;
ret = us5182d_set_power_state(data, false);
if (ret < 0)
goto out_err;
mutex_unlock(&data->lock);
return IIO_VAL_INT;
case IIO_PROXIMITY:
mutex_lock(&data->lock);
if (data->power_mode == US5182D_ONESHOT) {
ret = us5182d_oneshot_en(data);
if (ret < 0)
goto out_err;
}
ret = us5182d_set_power_state(data, true);
if (ret < 0)
goto out_err;
ret = us5182d_px_enable(data);
if (ret < 0)
goto out_poweroff;
ret = i2c_smbus_read_word_data(data->client,
US5182D_REG_PDL);
if (ret < 0)
goto out_poweroff;
*val = ret;
ret = us5182d_set_power_state(data, false);
if (ret < 0)
goto out_err;
mutex_unlock(&data->lock);
return IIO_VAL_INT;
default:
return -EINVAL;
}
ret = us5182d_read_value(data, chan);
if (ret < 0)
return ret;
*val = ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
if (ret < 0)
return ret;
*val = 0;
*val2 = us5182d_scales[ret & US5182D_AGAIN_MASK];
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
return -EINVAL;
out_poweroff:
us5182d_set_power_state(data, false);
out_err:
mutex_unlock(&data->lock);
return ret;
}
/**
@ -479,11 +527,201 @@ static int us5182d_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
static int us5182d_setup_prox(struct iio_dev *indio_dev,
enum iio_event_direction dir, u16 val)
{
struct us5182d_data *data = iio_priv(indio_dev);
if (dir == IIO_EV_DIR_FALLING)
return i2c_smbus_write_word_data(data->client,
US5182D_REG_PXL_TH, val);
else if (dir == IIO_EV_DIR_RISING)
return i2c_smbus_write_word_data(data->client,
US5182D_REG_PXH_TH, val);
return 0;
}
static int us5182d_read_thresh(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, enum iio_event_type type,
enum iio_event_direction dir, enum iio_event_info info, int *val,
int *val2)
{
struct us5182d_data *data = iio_priv(indio_dev);
switch (dir) {
case IIO_EV_DIR_RISING:
mutex_lock(&data->lock);
*val = data->px_high_th;
mutex_unlock(&data->lock);
break;
case IIO_EV_DIR_FALLING:
mutex_lock(&data->lock);
*val = data->px_low_th;
mutex_unlock(&data->lock);
break;
default:
return -EINVAL;
}
return IIO_VAL_INT;
}
static int us5182d_write_thresh(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, enum iio_event_type type,
enum iio_event_direction dir, enum iio_event_info info, int val,
int val2)
{
struct us5182d_data *data = iio_priv(indio_dev);
int ret;
if (val < 0 || val > USHRT_MAX || val2 != 0)
return -EINVAL;
switch (dir) {
case IIO_EV_DIR_RISING:
mutex_lock(&data->lock);
if (data->rising_en) {
ret = us5182d_setup_prox(indio_dev, dir, val);
if (ret < 0)
goto err;
}
data->px_high_th = val;
mutex_unlock(&data->lock);
break;
case IIO_EV_DIR_FALLING:
mutex_lock(&data->lock);
if (data->falling_en) {
ret = us5182d_setup_prox(indio_dev, dir, val);
if (ret < 0)
goto err;
}
data->px_low_th = val;
mutex_unlock(&data->lock);
break;
default:
return -EINVAL;
}
return 0;
err:
mutex_unlock(&data->lock);
return ret;
}
static int us5182d_read_event_config(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, enum iio_event_type type,
enum iio_event_direction dir)
{
struct us5182d_data *data = iio_priv(indio_dev);
int ret;
switch (dir) {
case IIO_EV_DIR_RISING:
mutex_lock(&data->lock);
ret = data->rising_en;
mutex_unlock(&data->lock);
break;
case IIO_EV_DIR_FALLING:
mutex_lock(&data->lock);
ret = data->falling_en;
mutex_unlock(&data->lock);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int us5182d_write_event_config(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, enum iio_event_type type,
enum iio_event_direction dir, int state)
{
struct us5182d_data *data = iio_priv(indio_dev);
int ret;
u16 new_th;
mutex_lock(&data->lock);
switch (dir) {
case IIO_EV_DIR_RISING:
if (data->rising_en == state) {
mutex_unlock(&data->lock);
return 0;
}
new_th = US5182D_PXH_TH_DISABLE;
if (state) {
data->power_mode = US5182D_CONTINUOUS;
ret = us5182d_set_power_state(data, true);
if (ret < 0)
goto err;
ret = us5182d_px_enable(data);
if (ret < 0)
goto err_poweroff;
new_th = data->px_high_th;
}
ret = us5182d_setup_prox(indio_dev, dir, new_th);
if (ret < 0)
goto err_poweroff;
data->rising_en = state;
break;
case IIO_EV_DIR_FALLING:
if (data->falling_en == state) {
mutex_unlock(&data->lock);
return 0;
}
new_th = US5182D_PXL_TH_DISABLE;
if (state) {
data->power_mode = US5182D_CONTINUOUS;
ret = us5182d_set_power_state(data, true);
if (ret < 0)
goto err;
ret = us5182d_px_enable(data);
if (ret < 0)
goto err_poweroff;
new_th = data->px_low_th;
}
ret = us5182d_setup_prox(indio_dev, dir, new_th);
if (ret < 0)
goto err_poweroff;
data->falling_en = state;
break;
default:
ret = -EINVAL;
goto err;
}
if (!state) {
ret = us5182d_set_power_state(data, false);
if (ret < 0)
goto err;
}
if (!data->falling_en && !data->rising_en && !data->default_continuous)
data->power_mode = US5182D_ONESHOT;
mutex_unlock(&data->lock);
return 0;
err_poweroff:
if (state)
us5182d_set_power_state(data, false);
err:
mutex_unlock(&data->lock);
return ret;
}
static const struct iio_info us5182d_info = {
.driver_module = THIS_MODULE,
.read_raw = us5182d_read_raw,
.write_raw = us5182d_write_raw,
.attrs = &us5182d_attr_group,
.read_event_value = &us5182d_read_thresh,
.write_event_value = &us5182d_write_thresh,
.read_event_config = &us5182d_read_event_config,
.write_event_config = &us5182d_write_event_config,
};
static int us5182d_reset(struct iio_dev *indio_dev)
@ -505,6 +743,9 @@ static int us5182d_init(struct iio_dev *indio_dev)
data->opmode = 0;
data->power_mode = US5182D_CONTINUOUS;
data->px_low_th = US5182D_REG_PXL_TH_DEFAULT;
data->px_high_th = US5182D_REG_PXH_TH_DEFAULT;
for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) {
ret = i2c_smbus_write_byte_data(data->client,
us5182d_regvals[i].reg,
@ -575,6 +816,33 @@ static int us5182d_dark_gain_config(struct iio_dev *indio_dev)
US5182D_REG_DARK_AUTO_EN_DEFAULT);
}
static irqreturn_t us5182d_irq_thread_handler(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct us5182d_data *data = iio_priv(indio_dev);
enum iio_event_direction dir;
int ret;
u64 ev;
ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
if (ret < 0) {
dev_err(&data->client->dev, "i2c transfer error in irq\n");
return IRQ_HANDLED;
}
dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING;
ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir);
iio_push_event(indio_dev, ev, iio_get_time_ns());
ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0,
ret & ~US5182D_CFG0_PX_IRQ);
if (ret < 0)
dev_err(&data->client->dev, "i2c transfer error in irq\n");
return IRQ_HANDLED;
}
static int us5182d_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@ -606,6 +874,16 @@ static int us5182d_probe(struct i2c_client *client,
return (ret < 0) ? ret : -ENODEV;
}
if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
us5182d_irq_thread_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"us5182d-irq", indio_dev);
if (ret < 0)
return ret;
} else
dev_warn(&client->dev, "no valid irq found\n");
us5182d_get_platform_data(indio_dev);
ret = us5182d_init(indio_dev);
if (ret < 0)

View File

@ -48,7 +48,7 @@ static int sca3000_read_data(struct sca3000_state *st,
}
};
*rx_p = kmalloc(len, GFP_KERNEL);
if (*rx_p == NULL) {
if (!*rx_p) {
ret = -ENOMEM;
goto error_ret;
}

View File

@ -636,6 +636,8 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
}
#endif
ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals);
int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer,
int *fract);