From cd62322a9767f9a0bcf855123c478187e38a10f4 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Mon, 13 Apr 2015 18:40:48 +0300 Subject: iio: accel: mma9553: fix endianness issue when reading status Refactor code for simplicity and clarity. This also fixes an endianness issue with the original code. When reading multiple registers, the received buffer of 16-bytes words is little endian (status, step count). On big endian machines, casting them to u32 would result in reversed order in the buffer (step count, status) leading to incorrect values for step count and activity. Signed-off-by: Irina Tirdea Reported-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9553.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/iio/accel/mma9553.c') diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 2df1af7d43fc..607dbfcb49ab 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -316,22 +316,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; } -- cgit v1.2.1 From ae2ec9597c9329fdf503af264966bc7e421daa58 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Mon, 13 Apr 2015 18:40:51 +0300 Subject: iio: accel: mma9553: add enable channel for activity Add an enable channel for activity, so it can also be polled independently of events or other channels. Signed-off-by: Irina Tirdea Reported-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9553.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/iio/accel/mma9553.c') diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 607dbfcb49ab..1a256055a6f7 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -968,7 +968,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, \ -- cgit v1.2.1 From 1d93353da536d3403ac291dc96070f434f6cf285 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Mon, 13 Apr 2015 18:40:49 +0300 Subject: iio: accel: mma9553: check input value for activity period When setting the activity period, the value introduced by the user in sysfs is not checked for validity. Add a boundary check so that only allowed values are reported as successfully written to device. Signed-off-by: Irina Tirdea Reported-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9553.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/iio/accel/mma9553.c') diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 1a256055a6f7..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 @@ -869,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, -- cgit v1.2.1