All of lore.kernel.org
 help / color / mirror / Atom feed
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



  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.