Commit 5e913d27 authored by Tiberiu Breana's avatar Tiberiu Breana Committed by Jonathan Cameron
Browse files

iio: accel: Add sampling rate support for STK8312



Added support for setting the STK8312 accelerometer's
sampling rate.

Signed-off-by: default avatarTiberiu Breana <tiberiu.a.breana@intel.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 95c12bba
Loading
Loading
Loading
Loading
+82 −14
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#define STK8312_REG_ZOUT		0x02
#define STK8312_REG_INTSU		0x06
#define STK8312_REG_MODE		0x07
#define STK8312_REG_SR			0x08
#define STK8312_REG_STH			0x13
#define STK8312_REG_RESET		0x20
#define STK8312_REG_AFECTRL		0x24
@@ -41,6 +42,8 @@
#define STK8312_DREADY_BIT		0x10
#define STK8312_INT_MODE		0xC0
#define STK8312_RNG_MASK		0xC0
#define STK8312_SR_MASK			0x07
#define STK8312_SR_400HZ_IDX		0
#define STK8312_RNG_SHIFT		6
#define STK8312_READ_RETRIES		16
#define STK8312_ALL_CHANNEL_MASK	7
@@ -65,13 +68,22 @@ static const int stk8312_scale_table[][2] = {
	{0, 461600}, {1, 231100}
};

static const struct {
	u16 val;
	u32 val2;
} stk8312_samp_freq_table[] = {
	{400, 0}, {200, 0}, {100, 0}, {50, 0}, {25, 0},
	{12, 500000}, {6, 250000}, {3, 125000}
};

#define STK8312_ACCEL_CHANNEL(index, reg, axis) {			\
	.type = IIO_ACCEL,						\
	.address = reg,							\
	.modified = 1,							\
	.channel2 = IIO_MOD_##axis,					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
				    BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
	.scan_index = index,						\
	.scan_type = {							\
		.sign = 's',						\
@@ -92,6 +104,7 @@ struct stk8312_data {
	struct i2c_client *client;
	struct mutex lock;
	int range;
	u8 sample_rate_idx;
	u8 mode;
	struct iio_trigger *dready_trig;
	bool dready_trigger_on;
@@ -100,8 +113,11 @@ struct stk8312_data {

static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL);

static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("3.125 6.25 12.5 25 50 100 200 400");

static struct attribute *stk8312_attributes[] = {
	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
	NULL,
};

@@ -220,6 +236,39 @@ static const struct iio_trigger_ops stk8312_trigger_ops = {
	.owner = THIS_MODULE,
};

static int stk8312_set_sample_rate(struct stk8312_data *data, int rate)
{
	int ret;
	u8 masked_reg;
	u8 mode;
	struct i2c_client *client = data->client;

	if (rate == data->sample_rate_idx)
		return 0;

	mode = data->mode;
	/* We need to go in standby mode to modify registers */
	ret = stk8312_set_mode(data, STK8312_MODE_STANDBY);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_read_byte_data(client, STK8312_REG_SR);
	if (ret < 0) {
		dev_err(&client->dev, "failed to set sampling rate\n");
		return ret;
	}

	masked_reg = (ret & (~STK8312_SR_MASK)) | rate;

	ret = i2c_smbus_write_byte_data(client, STK8312_REG_SR, masked_reg);
	if (ret < 0)
		dev_err(&client->dev, "failed to set sampling rate\n");
	else
		data->sample_rate_idx = rate;

	return stk8312_set_mode(data, mode);
}

static int stk8312_set_range(struct stk8312_data *data, u8 range)
{
	int ret;
@@ -303,6 +352,10 @@ static int stk8312_read_raw(struct iio_dev *indio_dev,
		*val = stk8312_scale_table[data->range - 1][0];
		*val2 = stk8312_scale_table[data->range - 1][1];
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*val = stk8312_samp_freq_table[data->sample_rate_idx].val;
		*val2 = stk8312_samp_freq_table[data->sample_rate_idx].val2;
		return IIO_VAL_INT_PLUS_MICRO;
	}

	return -EINVAL;
@@ -332,6 +385,20 @@ static int stk8312_write_raw(struct iio_dev *indio_dev,
		ret = stk8312_set_range(data, index);
		mutex_unlock(&data->lock);

		return ret;
	case IIO_CHAN_INFO_SAMP_FREQ:
		for (i = 0; i < ARRAY_SIZE(stk8312_samp_freq_table); i++)
			if (val == stk8312_samp_freq_table[i].val &&
			    val2 == stk8312_samp_freq_table[i].val2) {
				index = i;
				break;
			}
		if (index < 0)
			return -EINVAL;
		mutex_lock(&data->lock);
		ret = stk8312_set_sample_rate(data, index);
		mutex_unlock(&data->lock);

		return ret;
	}

@@ -479,6 +546,7 @@ static int stk8312_probe(struct i2c_client *client,
		dev_err(&client->dev, "failed to reset sensor\n");
		return ret;
	}
	data->sample_rate_idx = STK8312_SR_400HZ_IDX;
	ret = stk8312_set_range(data, 1);
	if (ret < 0)
		return ret;