iio: accel: adxl345: add sampling frequency support
Subsystems (2)
PATCH v6 1/1 iio: accel: adxl345: add sampling frequency support
The ADXL345 provides selectable output data rate. This adds the iio channel information for the sampling frequency with that feature.
---
This was part of a patchset titled "add calibration offset and sampling frequency support". All other patches have already been picked up.
* v6 (Suggested by Andy Shevchenko)
- Simplify calculation of sampling frequency setting by using clamp_val()
drivers/iio/accel/adxl345_core.c | 57 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-)
drivers/iio/accel/adxl345_core.c +56 -1
@@ -14,6 +14,7 @@#include <linux/regmap.h> #include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "adxl345.h"
@@ -22,6 +23,7 @@#define ADXL345_REG_OFSY 0x1f#define ADXL345_REG_OFSZ 0x20#define ADXL345_REG_OFS_AXIS (index) (ADXL345_REG_OFSX + (index)) +#define ADXL345_REG_BW_RATE 0x2C#define ADXL345_REG_POWER_CTL 0x2D#define ADXL345_REG_DATA_FORMAT 0x31#define ADXL345_REG_DATAX0 0x32
@@ -30,6 +32,10 @@#define ADXL345_REG_DATA_AXIS (index) \ (ADXL345_REG_DATAX0 + (index) * sizeof(__le16)) +#define ADXL345_BW_RATE GENMASK(3, 0) +#define ADXL345_BASE_RATE_NANO_HZ 97656250LL +#define NHZ_PER_HZ 1000000000LL +#define ADXL345_POWER_CTL_MEASURE BIT(3)#define ADXL345_POWER_CTL_STANDBY 0x00
@@ -62,7 +68,8 @@ struct adxl345_data { .address = index, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_CALIBBIAS), \ - .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), \ }static const struct iio_chan_spec adxl345_channels[] = {
@@ -77,6 +84,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, {struct adxl345_data *data =iio_priv (indio_dev);__le16 accel; +long long samp_freq_nhz;unsigned int regval;int ret;
@@ -112,6 +120,16 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, *val =sign_extend32 (regval,7 ) *4 ;return IIO_VAL_INT ; +case IIO_CHAN_INFO_SAMP_FREQ : + ret =regmap_read (data->regmap,ADXL345_REG_BW_RATE , ®val); +if (ret <0 ) +return ret; + + samp_freq_nhz =ADXL345_BASE_RATE_NANO_HZ << + (regval &ADXL345_BW_RATE ); + *val =div_s64_rem (samp_freq_nhz,NHZ_PER_HZ , val2); + +return IIO_VAL_INT_PLUS_NANO ; }return -EINVAL ;
@@ -122,6 +140,7 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct adxl345_data *data = iio_priv(indio_dev); +s64 n;switch (mask) {case IIO_CHAN_INFO_CALIBBIAS :
@@ -132,14 +151,50 @@ static int adxl345_write_raw(struct iio_dev *indio_dev,return regmap_write (data->regmap,ADXL345_REG_OFS_AXIS (chan->address), val /4 ); +case IIO_CHAN_INFO_SAMP_FREQ : + n =div_s64 (val *NHZ_PER_HZ + val2,ADXL345_BASE_RATE_NANO_HZ ); + +return regmap_update_bits (data->regmap,ADXL345_REG_BW_RATE , +ADXL345_BW_RATE , +clamp_val (ilog2 (n),0 , +ADXL345_BW_RATE )); }return -EINVAL ; } +static int adxl345_write_raw_get_fmt (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +long mask) +{ +switch (mask) { +case IIO_CHAN_INFO_CALIBBIAS : +return IIO_VAL_INT ; +case IIO_CHAN_INFO_SAMP_FREQ : +return IIO_VAL_INT_PLUS_NANO ; +default : +return -EINVAL ; + } +} + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( +"0.09765625 0.1953125 0.390625 0.78125 1.5625 3.125 6.25 12.5 25 50 100 200 400 800 1600 3200" +); + +static struct attribute *adxl345_attrs[] = { + &iio_const_attr_sampling_frequency_available.dev_attr.attr, +NULL , +}; + +static const struct attribute_group adxl345_attrs_group = { + .attrs = adxl345_attrs, +}; +static const struct iio_info adxl345_info = { + .attrs = &adxl345_attrs_group, .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, + .write_raw_get_fmt = adxl345_write_raw_get_fmt, }; int adxl345_core_probe(struct device *dev, struct regmap *regmap,
Signature · 1 line
2.7.4
Jonathan Cameron
maintainerQuoted 7 lines · On Tue, 10 Jul 2018 00:10:08 +0900 Akinobu Mita <[email protected]> wrote:
The ADXL345 provides selectable output data rate. This adds the iio channel information for the sampling frequency with that feature.
Cc Eva Rachel Retuya <[email protected]>Cc Andy Shevchenko <[email protected]>Cc Jonathan Cameron <[email protected]>Signed-off-by Akinobu Mita <[email protected]>
Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 135 lines
---
This was part of a patchset titled "add calibration offset and sampling frequency support". All other patches have already been picked up.* v6 (Suggested by Andy Shevchenko)
- Simplify calculation of sampling frequency setting by usingclamp_val()drivers/iio/accel/adxl345_core.c | 57 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-)drivers/iio/accel/adxl345_core.c +56
-1@@ -14,6 +14,7 @@#include <linux/regmap.h> #include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "adxl345.h" @@ -22,6 +23,7 @@#define ADXL345_REG_OFSY 0x1f#define ADXL345_REG_OFSZ 0x20#define ADXL345_REG_OFS_AXIS (index) (ADXL345_REG_OFSX + (index)) +#define ADXL345_REG_BW_RATE 0x2C#define ADXL345_REG_POWER_CTL 0x2D#define ADXL345_REG_DATA_FORMAT 0x31#define ADXL345_REG_DATAX0 0x32@@ -30,6 +32,10 @@#define ADXL345_REG_DATA_AXIS (index) \ (ADXL345_REG_DATAX0 + (index) * sizeof(__le16)) +#define ADXL345_BW_RATE GENMASK(3, 0) +#define ADXL345_BASE_RATE_NANO_HZ 97656250LL +#define NHZ_PER_HZ 1000000000LL +#define ADXL345_POWER_CTL_MEASURE BIT(3)#define ADXL345_POWER_CTL_STANDBY 0x00@@ -62,7 +68,8 @@ struct adxl345_data { .address = index, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_CALIBBIAS), \ - .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), \ }static const struct iio_chan_spec adxl345_channels[] = {@@ -77,6 +84,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, {struct adxl345_data *data =iio_priv (indio_dev);__le16 accel; +long long samp_freq_nhz;unsigned int regval;int ret;@@ -112,6 +120,16 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, *val =sign_extend32 (regval,7 ) *4 ;return IIO_VAL_INT ; +case IIO_CHAN_INFO_SAMP_FREQ : + ret =regmap_read (data->regmap,ADXL345_REG_BW_RATE , ®val); +if (ret <0 ) +return ret; + + samp_freq_nhz =ADXL345_BASE_RATE_NANO_HZ << + (regval &ADXL345_BW_RATE ); + *val =div_s64_rem (samp_freq_nhz,NHZ_PER_HZ , val2); + +return IIO_VAL_INT_PLUS_NANO ; }return -EINVAL ;@@ -122,6 +140,7 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct adxl345_data *data = iio_priv(indio_dev); +s64 n;switch (mask) {case IIO_CHAN_INFO_CALIBBIAS :@@ -132,14 +151,50 @@ static int adxl345_write_raw(struct iio_dev *indio_dev,return regmap_write (data->regmap,ADXL345_REG_OFS_AXIS (chan->address), val /4 ); +case IIO_CHAN_INFO_SAMP_FREQ : + n =div_s64 (val *NHZ_PER_HZ + val2,ADXL345_BASE_RATE_NANO_HZ ); + +return regmap_update_bits (data->regmap,ADXL345_REG_BW_RATE , +ADXL345_BW_RATE , +clamp_val (ilog2 (n),0 , +ADXL345_BW_RATE )); }return -EINVAL ; } +static int adxl345_write_raw_get_fmt (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +long mask) +{ +switch (mask) { +case IIO_CHAN_INFO_CALIBBIAS : +return IIO_VAL_INT ; +case IIO_CHAN_INFO_SAMP_FREQ : +return IIO_VAL_INT_PLUS_NANO ; +default : +return -EINVAL ; + } +} + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( +"0.09765625 0.1953125 0.390625 0.78125 1.5625 3.125 6.25 12.5 25 50 100 200 400 800 1600 3200" +); + +static struct attribute *adxl345_attrs[] = { + &iio_const_attr_sampling_frequency_available.dev_attr.attr, +NULL , +}; + +static const struct attribute_group adxl345_attrs_group = { + .attrs = adxl345_attrs, +}; +static const struct iio_info adxl345_info = { + .attrs = &adxl345_attrs_group, .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, + .write_raw_get_fmt = adxl345_write_raw_get_fmt, }; int adxl345_core_probe(struct device *dev, struct regmap *regmap,