From: Afonso Bordado <afonsobordado@az8.co>
To: jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net
Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org
Subject: [PATCH v3 3/4] iio: fxas21002c: add ODR/Scale support
Date: Tue, 4 Sep 2018 21:04:33 +0100 [thread overview]
Message-ID: <20180904200434.10442-3-afonsobordado@az8.co> (raw)
In-Reply-To: <20180904200434.10442-1-afonsobordado@az8.co>
This patch adds support for reading/writing ODR/Scale
We don't support the scale boost modes.
Signed-off-by: Afonso Bordado <afonsobordado@az8.co>
---
drivers/iio/gyro/fxas21002c.c | 161 +++++++++++++++++++++++++++++++---
1 file changed, 148 insertions(+), 13 deletions(-)
diff --git a/drivers/iio/gyro/fxas21002c.c b/drivers/iio/gyro/fxas21002c.c
index 18b1f500dd3e..7efef3156fa0 100644
--- a/drivers/iio/gyro/fxas21002c.c
+++ b/drivers/iio/gyro/fxas21002c.c
@@ -7,7 +7,7 @@
* IIO driver for FXAS21002C (7-bit I2C slave address 0x20 or 0x21).
* Datasheet: https://www.nxp.com/docs/en/data-sheet/FXAS21002.pdf
* TODO:
- * ODR / Scale Support
+ * Scale boost mode
* Power management
* GPIO Reset
* Power supplies
@@ -44,7 +44,10 @@
#define FXAS21002C_REG_F_EVENT 0x0A
#define FXAS21002C_REG_INT_SRC_FLAG 0x0B
#define FXAS21002C_REG_WHO_AM_I 0x0C
+
#define FXAS21002C_REG_CTRL_REG0 0x0D
+#define FXAS21002C_SCALE_MASK GENMASK(1, 0)
+
#define FXAS21002C_REG_RT_CFG 0x0E
#define FXAS21002C_REG_RT_SRC 0x0F
#define FXAS21002C_REG_RT_THS 0x10
@@ -56,14 +59,12 @@
#define FXAS21002C_ACTIVE_BIT BIT(1)
#define FXAS21002C_READY_BIT BIT(0)
+#define FXAS21002C_ODR_SHIFT 2
+#define FXAS21002C_ODR_MASK GENMASK(4, 2)
+
#define FXAS21002C_REG_CTRL_REG2 0x14
#define FXAS21002C_REG_CTRL_REG3 0x15
-#define FXAS21002C_DEFAULT_ODR_HZ 800
-
-/* 0.0625 deg/s */
-#define FXAS21002C_DEFAULT_SENSITIVITY IIO_DEGREE_TO_RAD(62500)
-
#define FXAS21002C_TEMP_SCALE 1000
enum {
@@ -82,6 +83,40 @@ struct fxas21002c_data {
struct regmap *regmap;
};
+enum fxas21002c_scale {
+ FXAS21002C_SCALE_62MDPS,
+ FXAS21002C_SCALE_31MDPS,
+ FXAS21002C_SCALE_15MDPS,
+ FXAS21002C_SCALE_7MDPS,
+};
+
+static const int fxas21002c_anglevel_scale_avail[4][2] = {
+ [FXAS21002C_SCALE_62MDPS] = { 0, IIO_DEGREE_TO_RAD(62500) },
+ [FXAS21002C_SCALE_31MDPS] = { 0, IIO_DEGREE_TO_RAD(31250) },
+ [FXAS21002C_SCALE_15MDPS] = { 0, IIO_DEGREE_TO_RAD(15625) },
+ [FXAS21002C_SCALE_7MDPS] = { 0, IIO_DEGREE_TO_RAD(7812) },
+};
+
+enum fxas21002c_odr {
+ FXAS21002C_ODR_800,
+ FXAS21002C_ODR_400,
+ FXAS21002C_ODR_200,
+ FXAS21002C_ODR_100,
+ FXAS21002C_ODR_50,
+ FXAS21002C_ODR_25,
+ FXAS21002C_ODR_12_5,
+};
+
+static const int fxas21002c_sample_freq_avail[7][2] = {
+ [FXAS21002C_ODR_800] = { 800, 0 },
+ [FXAS21002C_ODR_400] = { 400, 0 },
+ [FXAS21002C_ODR_200] = { 200, 0 },
+ [FXAS21002C_ODR_100] = { 100, 0 },
+ [FXAS21002C_ODR_50] = { 50, 0 },
+ [FXAS21002C_ODR_25] = { 25, 0 },
+ [FXAS21002C_ODR_12_5] = { 12, 500000 },
+};
+
static const struct regmap_range fxas21002c_writable_ranges[] = {
regmap_reg_range(FXAS21002C_REG_F_SETUP, FXAS21002C_REG_F_SETUP),
regmap_reg_range(FXAS21002C_REG_CTRL_REG0, FXAS21002C_REG_RT_CFG),
@@ -254,6 +289,49 @@ static int fxas21002c_read_oneshot(struct fxas21002c_data *data,
}
}
+static int fxas21002c_scale_read(struct fxas21002c_data *data, int *val,
+ int *val2)
+{
+ int ret;
+ unsigned int raw;
+
+ ret = regmap_read(data->regmap, FXAS21002C_REG_CTRL_REG0, &raw);
+ if (ret)
+ return ret;
+
+ raw &= FXAS21002C_SCALE_MASK;
+
+ *val = fxas21002c_anglevel_scale_avail[raw][0];
+ *val2 = fxas21002c_anglevel_scale_avail[raw][1];
+
+ return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int fxas21002c_odr_read(struct fxas21002c_data *data, int *val,
+ int *val2)
+{
+ int ret;
+ unsigned int raw;
+
+ ret = regmap_read(data->regmap, FXAS21002C_REG_CTRL_REG1, &raw);
+ if (ret)
+ return ret;
+
+ raw = (raw & FXAS21002C_ODR_MASK) >> FXAS21002C_ODR_SHIFT;
+
+ /*
+ * We don't use this mode but according to the datasheet its
+ * also a 12.5Hz
+ */
+ if (raw == 7)
+ raw = FXAS21002C_ODR_12_5;
+
+ *val = fxas21002c_sample_freq_avail[raw][0];
+ *val2 = fxas21002c_sample_freq_avail[raw][1];
+
+ return IIO_VAL_INT_PLUS_MICRO;
+}
+
static int fxas21002c_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
@@ -266,10 +344,7 @@ static int fxas21002c_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
- *val = 0;
- *val2 = FXAS21002C_DEFAULT_SENSITIVITY;
-
- return IIO_VAL_INT_PLUS_MICRO;
+ return fxas21002c_scale_read(data, val, val2);
case IIO_TEMP:
*val = FXAS21002C_TEMP_SCALE;
@@ -281,16 +356,76 @@ static int fxas21002c_read_raw(struct iio_dev *indio_dev,
if (chan->type != IIO_ANGL_VEL)
return -EINVAL;
- *val = FXAS21002C_DEFAULT_ODR_HZ;
-
- return IIO_VAL_INT;
+ return fxas21002c_odr_read(data, val, val2);
}
return -EINVAL;
}
+static int fxas21002c_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val,
+ int val2, long mask)
+{
+ struct fxas21002c_data *data = iio_priv(indio_dev);
+ int ret = -EINVAL;
+ int i;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ for (i = 0; i < ARRAY_SIZE(fxas21002c_sample_freq_avail); i++) {
+ if (fxas21002c_sample_freq_avail[i][0] == val &&
+ fxas21002c_sample_freq_avail[i][1] == val2)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(fxas21002c_sample_freq_avail))
+ break;
+
+ return regmap_update_bits(data->regmap,
+ FXAS21002C_REG_CTRL_REG1,
+ FXAS21002C_ODR_MASK,
+ i << FXAS21002C_ODR_SHIFT);
+ case IIO_CHAN_INFO_SCALE:
+ for (i = 0; i < ARRAY_SIZE(fxas21002c_anglevel_scale_avail);
+ i++) {
+ if (fxas21002c_anglevel_scale_avail[i][0] == val &&
+ fxas21002c_anglevel_scale_avail[i][1] == val2)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(fxas21002c_anglevel_scale_avail))
+ break;
+
+ return regmap_update_bits(data->regmap,
+ FXAS21002C_REG_CTRL_REG0,
+ FXAS21002C_SCALE_MASK, i);
+ }
+
+ return ret;
+}
+
+static IIO_CONST_ATTR(anglevel_scale_available,
+ "0.001090831 " /* 62.5 mdps */
+ "0.000545415 " /* 31.25 mdps */
+ "0.000272708 " /* 15.625 mdps */
+ "0.000136354"); /* 7.8125 mdps */
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("800 400 200 100 50 25 12.5");
+
+static struct attribute *fxas21002c_attributes[] = {
+ &iio_const_attr_anglevel_scale_available.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group fxas21002c_attribute_group = {
+ .attrs = fxas21002c_attributes,
+};
+
static const struct iio_info fxas21002c_info = {
.read_raw = fxas21002c_read_raw,
+ .write_raw = fxas21002c_write_raw,
+ .attrs = &fxas21002c_attribute_group,
};
static int fxas21002c_probe(struct i2c_client *client,
--
2.18.0
next prev parent reply other threads:[~2018-09-04 19:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-04 20:04 [PATCH v3 1/4] iio: gyro: add support for fxas21002c Afonso Bordado
2018-09-04 19:18 ` Andy Shevchenko
2018-09-04 20:04 ` [PATCH v3 2/4] iio: gyro: add device tree " Afonso Bordado
2018-09-04 19:13 ` Andy Shevchenko
2018-09-10 20:09 ` Rob Herring
2018-09-04 20:04 ` Afonso Bordado [this message]
2018-09-04 19:26 ` [PATCH v3 3/4] iio: fxas21002c: add ODR/Scale support Andy Shevchenko
2018-09-04 20:04 ` [PATCH v3 4/4] MAINTAINERS: add entry for fxas21002c gyro driver Afonso Bordado
2018-09-04 19:16 ` Andy Shevchenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180904200434.10442-3-afonsobordado@az8.co \
--to=afonsobordado@az8.co \
--cc=devicetree@vger.kernel.org \
--cc=jic23@kernel.org \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pmeerw@pmeerw.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.