From: Eva Rachel Retuya <eraretuya@gmail.com>
To: jic23@kernel.org, linux-iio@vger.kernel.org
Cc: knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net,
dmitry.torokhov@gmail.com, michael.hennerich@analog.com,
daniel.baluta@gmail.com, amsfield22@gmail.com,
florian.vaussard@heig-vd.ch, linux-kernel@vger.kernel.org,
Eva Rachel Retuya <eraretuya@gmail.com>
Subject: [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions
Date: Sat, 29 Apr 2017 15:48:59 +0800 [thread overview]
Message-ID: <96d20633a6ff9792f7be642a590669fc07d9ad63.1493450577.git.eraretuya@gmail.com> (raw)
In-Reply-To: <cover.1493450577.git.eraretuya@gmail.com>
In-Reply-To: <cover.1493450577.git.eraretuya@gmail.com>
Move code that enables measurement/standby mode into its own function
and call that function when appropriate. Previously, we set the sensor
to measurement in probe and back to standby during remove. Change it
here to only enter measurement mode when request for data is initiated.
The DATA_READY bit is always set if the corresponding event occurs.
Introduce the data_ready function that monitors the INT_SOURCE register
of this bit. This is done to ensure consistent readings.
Signed-off-by: Eva Rachel Retuya <eraretuya@gmail.com>
---
Changes in v2:
* Make function naming more clear: drdy -> data_ready
* Switch from while to do..while
* Rename regval to val
* Switch to usleep_range() for shorter delay
* Add comment to justify delay
* Change error code -EIO to -EAGAIN
* Endianness issue: scrap the get_triple function entirely, make no
changes in terms of reading registers in read_raw
* Introduce mutex here rather than in succeeding patch
* Probe:
* Fix random whitespace omission
* Remove configuring to standby mode, the device powers on in standby
mode so this is not needed
drivers/iio/accel/adxl345_core.c | 84 +++++++++++++++++++++++++++++++++-------
1 file changed, 69 insertions(+), 15 deletions(-)
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 9ccb582..b8a212c 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -8,6 +8,7 @@
* directory of this archive for more details.
*/
+#include <linux/delay.h>
#include <linux/module.h>
#include <linux/regmap.h>
@@ -17,6 +18,7 @@
#define ADXL345_REG_DEVID 0x00
#define ADXL345_REG_POWER_CTL 0x2D
+#define ADXL345_REG_INT_SOURCE 0x30
#define ADXL345_REG_DATA_FORMAT 0x31
#define ADXL345_REG_DATAX0 0x32
#define ADXL345_REG_DATAY0 0x34
@@ -25,6 +27,10 @@
#define ADXL345_POWER_CTL_MEASURE BIT(3)
#define ADXL345_POWER_CTL_STANDBY 0x00
+/* INT_ENABLE/INT_MAP/INT_SOURCE bits */
+#define ADXL345_INT_DATA_READY BIT(7)
+#define ADXL345_INT_OVERRUN 0
+
#define ADXL345_DATA_FORMAT_FULL_RES BIT(3) /* Up to 13-bits resolution */
#define ADXL345_DATA_FORMAT_2G 0
#define ADXL345_DATA_FORMAT_4G 1
@@ -44,9 +50,49 @@ static const int adxl345_uscale = 38300;
struct adxl345_data {
struct regmap *regmap;
+ struct mutex lock; /* protect this data structure */
u8 data_range;
};
+static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
+{
+ struct device *dev = regmap_get_device(data->regmap);
+ int ret;
+
+ ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set power mode, %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int adxl345_data_ready(struct adxl345_data *data)
+{
+ struct device *dev = regmap_get_device(data->regmap);
+ int tries = 5;
+ u32 val;
+ int ret;
+
+ do {
+ /*
+ * 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
+ * Sensor currently operates at default ODR of 100 Hz
+ */
+ usleep_range(1100, 11100);
+
+ ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, &val);
+ if (ret < 0)
+ return ret;
+ if ((val & ADXL345_INT_DATA_READY) == ADXL345_INT_DATA_READY)
+ return 0;
+ } while (--tries);
+ dev_err(dev, "Data is not yet ready, try again.\n");
+
+ return -EAGAIN;
+}
+
#define ADXL345_CHANNEL(reg, axis) { \
.type = IIO_ACCEL, \
.modified = 1, \
@@ -72,6 +118,19 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
+ mutex_lock(&data->lock);
+ ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ ret = adxl345_data_ready(data);
+ if (ret < 0) {
+ adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
+ mutex_unlock(&data->lock);
+ return ret;
+ }
/*
* Data is stored in adjacent registers:
* ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
@@ -79,10 +138,15 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
*/
ret = regmap_bulk_read(data->regmap, chan->address, ®val,
sizeof(regval));
- if (ret < 0)
+ mutex_unlock(&data->lock);
+ if (ret < 0) {
+ adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
return ret;
+ }
*val = sign_extend32(le16_to_cpu(regval), 12);
+ adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
+
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -136,6 +200,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
return ret;
}
+ mutex_init(&data->lock);
+
indio_dev->dev.parent = dev;
indio_dev->name = name;
indio_dev->info = &adxl345_info;
@@ -143,20 +209,9 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
indio_dev->channels = adxl345_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
- /* Enable measurement mode */
- ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
- ADXL345_POWER_CTL_MEASURE);
- if (ret < 0) {
- dev_err(dev, "Failed to enable measurement mode: %d\n", ret);
- return ret;
- }
-
ret = iio_device_register(indio_dev);
- if (ret < 0) {
+ if (ret < 0)
dev_err(dev, "iio_device_register failed: %d\n", ret);
- regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
- ADXL345_POWER_CTL_STANDBY);
- }
return ret;
}
@@ -169,8 +224,7 @@ int adxl345_core_remove(struct device *dev)
iio_device_unregister(indio_dev);
- return regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
- ADXL345_POWER_CTL_STANDBY);
+ return adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
}
EXPORT_SYMBOL_GPL(adxl345_core_remove);
--
2.7.4
next prev parent reply other threads:[~2017-04-29 7:51 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-29 7:48 [PATCH v2 0/4] iio: accel: adxl345: Add support for buffered readings Eva Rachel Retuya
2017-04-29 7:48 ` [PATCH v2 1/4] dt-bindings: iio: accel: adxl345: Add optional interrupt-names support Eva Rachel Retuya
2017-04-29 7:48 ` Eva Rachel Retuya [this message]
2017-05-01 0:22 ` [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions Jonathan Cameron
2017-05-01 19:42 ` Andy Shevchenko
2017-05-01 19:48 ` Jonathan Cameron
2017-05-01 20:07 ` Andy Shevchenko
2017-05-01 20:18 ` Jonathan Cameron
2017-05-02 11:39 ` Eva Rachel Retuya
2017-05-02 16:32 ` Jonathan Cameron
2017-05-10 13:07 ` Eva Rachel Retuya
2017-05-01 11:21 ` Andy Shevchenko
2017-05-02 11:46 ` Eva Rachel Retuya
2017-04-29 7:49 ` [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger Eva Rachel Retuya
2017-05-01 0:32 ` Jonathan Cameron
2017-05-02 3:01 ` Rob Herring
2017-05-02 15:59 ` Jonathan Cameron
2017-05-10 14:33 ` Eva Rachel Retuya
2017-05-02 11:59 ` Eva Rachel Retuya
2017-05-01 11:31 ` Andy Shevchenko
2017-05-02 12:15 ` Eva Rachel Retuya
2017-05-02 21:05 ` Andy Shevchenko
2017-05-10 13:24 ` Eva Rachel Retuya
2017-05-14 15:15 ` Jonathan Cameron
2017-05-14 16:08 ` Dmitry Torokhov
2017-05-05 18:26 ` Jonathan Cameron
2017-05-10 13:31 ` Eva Rachel Retuya
2017-04-29 7:49 ` [PATCH v2 4/4] iio: accel: adxl345: Add support for triggered buffer Eva Rachel Retuya
2017-05-01 0:42 ` Jonathan Cameron
2017-05-02 12:23 ` Eva Rachel Retuya
2017-05-02 16:08 ` Jonathan Cameron
2017-05-01 11:24 ` Andy Shevchenko
2017-05-02 12:24 ` Eva Rachel Retuya
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=96d20633a6ff9792f7be642a590669fc07d9ad63.1493450577.git.eraretuya@gmail.com \
--to=eraretuya@gmail.com \
--cc=amsfield22@gmail.com \
--cc=daniel.baluta@gmail.com \
--cc=dmitry.torokhov@gmail.com \
--cc=florian.vaussard@heig-vd.ch \
--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=michael.hennerich@analog.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).