summaryrefslogtreecommitdiff
path: root/drivers/iio/accel
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-13 21:51:14 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-13 21:51:14 +0300
commitec94efcdadab69f41d257a1054260f8295ab77ef (patch)
tree6287158245d80fa79b6017787d0bd762bad89c96 /drivers/iio/accel
parent892c89d5d7ffd1bb794fe54d86c0eef18d215fab (diff)
parentf0828ba96d02d4d4b197c531b34c662ee3c928df (diff)
downloadlinux-ec94efcdadab69f41d257a1054260f8295ab77ef.tar.xz
Merge tag 'iio-fixes-for-4.1a-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus
Jonathan writes: The usual mixed bag of fixes for IIO in the 4.1 cycle. Second version of this pull request as a small fix to a fix turned up before Greg pulled it for a cc10001 patch near the top of the tree. One core fix * Set updated for a iio kfifo was incorrectly set to false during a failed update, resulting in atttempts to repeat the failed operation appearing to succeed. This time I've decided to list the driver fixes in alphabetical order rather than 'randomly'. * axp288_adc - a recent change added a check for valid info masks when reading channels from consumer drivers. * bmp280 - temperature compensation was failing to read the tfine value, hence causing a temperature of 0 to always be returned and incorrect presure measurements. * cc10001 - Fix channel number mapping when some channels are reserved for remote CPUs. Fix an issue with the use of the power-up/power-down register (basically wrong polarity). Fix an issue due to the missinterpretting the return value from regulator_get_voltage. Add a delay before the start bit as recommended for the hardware to avoid data corruption. * hid pressure - fix channel spec of modfiied, but no modifier (which makes no sense!) * hid proximity - fix channel spec of modified, but no modifier (which makes no sense!). Fix a memory leak in the probe function. * mcp320x - occasional incorrect readings on dma using spi busses due to cacheline corruption. Fixed by forcing ___cacheline_aligned for the buffers. * mma9551 - buffer overrun fix (miss specified maximum length of buffers) * mma9553 - endian fix on status message. Add an enable element for activity channel. Input checking for activity period to avoid rather unpredictable results. * spmi-vadc - fix an overflow in the output value normalization seen on some boards. * st-snesors - oops due to use of a mutex that is not yet initialized during probe. * xilinx adc - Some wrong register addresses, a wrong address for vccaux channel, incorrect scale on VREFP and incorrect sign on VREFN.
Diffstat (limited to 'drivers/iio/accel')
-rw-r--r--drivers/iio/accel/mma9551_core.c21
-rw-r--r--drivers/iio/accel/mma9553.c18
-rw-r--r--drivers/iio/accel/st_accel_core.c1
3 files changed, 29 insertions, 11 deletions
diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c
index 7f55a6d7cd03..c6d5a3a40b60 100644
--- a/drivers/iio/accel/mma9551_core.c
+++ b/drivers/iio/accel/mma9551_core.c
@@ -389,7 +389,12 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
{
int ret, i;
int len_words = len / sizeof(u16);
- __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+ __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
+
+ if (len_words > ARRAY_SIZE(be_buf)) {
+ dev_err(&client->dev, "Invalid buffer size %d\n", len);
+ return -EINVAL;
+ }
ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
reg, NULL, 0, (u8 *) be_buf, len);
@@ -424,7 +429,12 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
{
int ret, i;
int len_words = len / sizeof(u16);
- __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+ __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
+
+ if (len_words > ARRAY_SIZE(be_buf)) {
+ dev_err(&client->dev, "Invalid buffer size %d\n", len);
+ return -EINVAL;
+ }
ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
reg, NULL, 0, (u8 *) be_buf, len);
@@ -459,7 +469,12 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
{
int i;
int len_words = len / sizeof(u16);
- __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+ __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
+
+ if (len_words > ARRAY_SIZE(be_buf)) {
+ dev_err(&client->dev, "Invalid buffer size %d\n", len);
+ return -EINVAL;
+ }
for (i = 0; i < len_words; i++)
be_buf[i] = cpu_to_be16(buf[i]);
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c
index 2df1af7d43fc..365a109aaaef 100644
--- a/drivers/iio/accel/mma9553.c
+++ b/drivers/iio/accel/mma9553.c
@@ -54,6 +54,7 @@
#define MMA9553_MASK_CONF_STEPCOALESCE GENMASK(7, 0)
#define MMA9553_REG_CONF_ACTTHD 0x0E
+#define MMA9553_MAX_ACTTHD GENMASK(15, 0)
/* Pedometer status registers (R-only) */
#define MMA9553_REG_STATUS 0x00
@@ -316,22 +317,19 @@ static int mma9553_set_config(struct mma9553_data *data, u16 reg,
static int mma9553_read_activity_stepcnt(struct mma9553_data *data,
u8 *activity, u16 *stepcnt)
{
- u32 status_stepcnt;
- u16 status;
+ u16 buf[2];
int ret;
ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,
- MMA9553_REG_STATUS, sizeof(u32),
- (u16 *) &status_stepcnt);
+ MMA9553_REG_STATUS, sizeof(u32), buf);
if (ret < 0) {
dev_err(&data->client->dev,
"error reading status and stepcnt\n");
return ret;
}
- status = status_stepcnt & MMA9553_MASK_CONF_WORD;
- *activity = mma9553_get_bits(status, MMA9553_MASK_STATUS_ACTIVITY);
- *stepcnt = status_stepcnt >> 16;
+ *activity = mma9553_get_bits(buf[0], MMA9553_MASK_STATUS_ACTIVITY);
+ *stepcnt = buf[1];
return 0;
}
@@ -872,6 +870,9 @@ static int mma9553_write_event_value(struct iio_dev *indio_dev,
case IIO_EV_INFO_PERIOD:
switch (chan->type) {
case IIO_ACTIVITY:
+ if (val < 0 || val > MMA9553_ACTIVITY_THD_TO_SEC(
+ MMA9553_MAX_ACTTHD))
+ return -EINVAL;
mutex_lock(&data->mutex);
ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD,
&data->conf.actthd,
@@ -971,7 +972,8 @@ static const struct iio_chan_spec_ext_info mma9553_ext_info[] = {
.modified = 1, \
.channel2 = _chan2, \
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT) | \
+ BIT(IIO_CHAN_INFO_ENABLE), \
.event_spec = mma9553_activity_events, \
.num_event_specs = ARRAY_SIZE(mma9553_activity_events), \
.ext_info = mma9553_ext_info, \
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 58d1d13d552a..211b13271c61 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -546,6 +546,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &accel_info;
+ mutex_init(&adata->tb.buf_lock);
st_sensors_power_enable(indio_dev);