Commit 5dbbd19f authored by Martin Fuzzey's avatar Martin Fuzzey Committed by Jonathan Cameron

iio: mma8452: Add support for transient event debouncing

Allow the debouce counter for transient events to be configured
using the sysfs attribute events/in_accel_thresh_rising_period
Signed-off-by: default avatarMartin Fuzzey <mfuzzey@parkeon.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 28e34278
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#define MMA8452_TRANSIENT_SRC_ZTRANSE BIT(5) #define MMA8452_TRANSIENT_SRC_ZTRANSE BIT(5)
#define MMA8452_TRANSIENT_THS 0x1f #define MMA8452_TRANSIENT_THS 0x1f
#define MMA8452_TRANSIENT_THS_MASK 0x7f #define MMA8452_TRANSIENT_THS_MASK 0x7f
#define MMA8452_TRANSIENT_COUNT 0x20
#define MMA8452_OFF_X 0x2f #define MMA8452_OFF_X 0x2f
#define MMA8452_OFF_Y 0x30 #define MMA8452_OFF_Y 0x30
#define MMA8452_OFF_Z 0x31 #define MMA8452_OFF_Z 0x31
...@@ -124,6 +125,12 @@ static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n, ...@@ -124,6 +125,12 @@ static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
return -EINVAL; return -EINVAL;
} }
static int mma8452_get_odr_index(struct mma8452_data *data)
{
return (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >>
MMA8452_CTRL_DR_SHIFT;
}
static const int mma8452_samp_freq[8][2] = { static const int mma8452_samp_freq[8][2] = {
{800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000}, {800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000},
{6, 250000}, {1, 560000} {6, 250000}, {1, 560000}
...@@ -139,6 +146,18 @@ static const int mma8452_scales[3][2] = { ...@@ -139,6 +146,18 @@ static const int mma8452_scales[3][2] = {
{0, 9577}, {0, 19154}, {0, 38307} {0, 9577}, {0, 19154}, {0, 38307}
}; };
/* Datasheet table 35 (step time vs sample frequency) */
static const int mma8452_transient_time_step_us[8] = {
1250,
2500,
5000,
10000,
20000,
20000,
20000,
20000
};
static ssize_t mma8452_show_samp_freq_avail(struct device *dev, static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -198,8 +217,7 @@ static int mma8452_read_raw(struct iio_dev *indio_dev, ...@@ -198,8 +217,7 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
*val2 = mma8452_scales[i][1]; *val2 = mma8452_scales[i][1];
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SAMP_FREQ: case IIO_CHAN_INFO_SAMP_FREQ:
i = (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >> i = mma8452_get_odr_index(data);
MMA8452_CTRL_DR_SHIFT;
*val = mma8452_samp_freq[i][0]; *val = mma8452_samp_freq[i][0];
*val2 = mma8452_samp_freq[i][1]; *val2 = mma8452_samp_freq[i][1];
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
...@@ -297,15 +315,33 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev, ...@@ -297,15 +315,33 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
int *val, int *val2) int *val, int *val2)
{ {
struct mma8452_data *data = iio_priv(indio_dev); struct mma8452_data *data = iio_priv(indio_dev);
int ret; int ret, us;
ret = i2c_smbus_read_byte_data(data->client, MMA8452_TRANSIENT_THS); switch (info) {
if (ret < 0) case IIO_EV_INFO_VALUE:
return ret; ret = i2c_smbus_read_byte_data(data->client,
MMA8452_TRANSIENT_THS);
if (ret < 0)
return ret;
*val = ret & MMA8452_TRANSIENT_THS_MASK;
return IIO_VAL_INT;
*val = ret & MMA8452_TRANSIENT_THS_MASK; case IIO_EV_INFO_PERIOD:
ret = i2c_smbus_read_byte_data(data->client,
MMA8452_TRANSIENT_COUNT);
if (ret < 0)
return ret;
us = ret * mma8452_transient_time_step_us[
mma8452_get_odr_index(data)];
*val = us / USEC_PER_SEC;
*val2 = us % USEC_PER_SEC;
return IIO_VAL_INT_PLUS_MICRO;
return IIO_VAL_INT; default:
return -EINVAL;
}
} }
static int mma8452_write_thresh(struct iio_dev *indio_dev, static int mma8452_write_thresh(struct iio_dev *indio_dev,
...@@ -316,9 +352,26 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev, ...@@ -316,9 +352,26 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev,
int val, int val2) int val, int val2)
{ {
struct mma8452_data *data = iio_priv(indio_dev); struct mma8452_data *data = iio_priv(indio_dev);
int steps;
return mma8452_change_config(data, MMA8452_TRANSIENT_THS, switch (info) {
val & MMA8452_TRANSIENT_THS_MASK); case IIO_EV_INFO_VALUE:
return mma8452_change_config(data, MMA8452_TRANSIENT_THS,
val & MMA8452_TRANSIENT_THS_MASK);
case IIO_EV_INFO_PERIOD:
steps = (val * USEC_PER_SEC + val2) /
mma8452_transient_time_step_us[
mma8452_get_odr_index(data)];
if (steps > 0xff)
return -EINVAL;
return mma8452_change_config(data, MMA8452_TRANSIENT_COUNT,
steps);
default:
return -EINVAL;
}
} }
static int mma8452_read_event_config(struct iio_dev *indio_dev, static int mma8452_read_event_config(struct iio_dev *indio_dev,
...@@ -456,7 +509,8 @@ static const struct iio_event_spec mma8452_transient_event[] = { ...@@ -456,7 +509,8 @@ static const struct iio_event_spec mma8452_transient_event[] = {
.type = IIO_EV_TYPE_THRESH, .type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_RISING, .dir = IIO_EV_DIR_RISING,
.mask_separate = BIT(IIO_EV_INFO_ENABLE), .mask_separate = BIT(IIO_EV_INFO_ENABLE),
.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
BIT(IIO_EV_INFO_PERIOD)
}, },
}; };
......
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