From: Dan Robertson <dan@dlrobertson.com>
To: Jonathan Cameron <jic23@kernel.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>,
Peter Meerwald-Stadler <pmeerw@pmeerw.net>,
Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andy.shevchenko@gmail.com>,
linux-iio@vger.kernel.org, Dan Robertson <dan@dlrobertson.com>
Subject: [PATCH 1/1] iio: accel: bma400: add PM_SLEEP support
Date: Wed, 15 Jul 2020 01:02:26 -0400 [thread overview]
Message-ID: <20200715050226.9751-2-dan@dlrobertson.com> (raw)
In-Reply-To: <20200715050226.9751-1-dan@dlrobertson.com>
- Add system sleep ops if CONFIG_PM_SLEEP is set.
- Add attribute for setting the power mode of the
device.
Signed-off-by: Dan Robertson <dan@dlrobertson.com>
---
drivers/iio/accel/bma400.h | 3 +
drivers/iio/accel/bma400_core.c | 132 ++++++++++++++++++++++++--------
drivers/iio/accel/bma400_i2c.c | 1 +
drivers/iio/accel/bma400_spi.c | 1 +
4 files changed, 107 insertions(+), 30 deletions(-)
diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h
index 5ad10db9819f..e9dd9e918aac 100644
--- a/drivers/iio/accel/bma400.h
+++ b/drivers/iio/accel/bma400.h
@@ -10,6 +10,7 @@
#define _BMA400_H_
#include <linux/bits.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
/*
@@ -96,4 +97,6 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name);
int bma400_remove(struct device *dev);
+extern const struct dev_pm_ops bma400_pm_ops;
+
#endif
diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
index cc77f89c048b..5af57b8e1fd7 100644
--- a/drivers/iio/accel/bma400_core.c
+++ b/drivers/iio/accel/bma400_core.c
@@ -147,36 +147,6 @@ bma400_accel_get_mount_matrix(const struct iio_dev *indio_dev,
return &data->orientation;
}
-static const struct iio_chan_spec_ext_info bma400_ext_info[] = {
- IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma400_accel_get_mount_matrix),
- { }
-};
-
-#define BMA400_ACC_CHANNEL(_axis) { \
- .type = IIO_ACCEL, \
- .modified = 1, \
- .channel2 = IIO_MOD_##_axis, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
- BIT(IIO_CHAN_INFO_SCALE) | \
- BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
- .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
- BIT(IIO_CHAN_INFO_SCALE) | \
- BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
- .ext_info = bma400_ext_info, \
-}
-
-static const struct iio_chan_spec bma400_channels[] = {
- BMA400_ACC_CHANNEL(X),
- BMA400_ACC_CHANNEL(Y),
- BMA400_ACC_CHANNEL(Z),
- {
- .type = IIO_TEMP,
- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
- },
-};
-
static int bma400_get_temp_reg(struct bma400_data *data, int *val, int *val2)
{
unsigned int raw_temp;
@@ -542,6 +512,73 @@ static int bma400_set_power_mode(struct bma400_data *data,
return 0;
}
+static const char * const bma400_power_modes[] = {
+ "sleep",
+ "low-power",
+ "normal"
+};
+
+int bma400_power_mode_enum_get(struct iio_dev *dev,
+ const struct iio_chan_spec *chan)
+{
+ struct bma400_data *data = iio_priv(dev);
+
+ return data->power_mode;
+}
+
+int bma400_power_mode_enum_set(struct iio_dev *dev,
+ const struct iio_chan_spec *chan,
+ unsigned int mode)
+{
+ struct bma400_data *data = iio_priv(dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = bma400_set_power_mode(data, mode);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static const struct iio_enum bma400_power_mode_enum = {
+ .items = bma400_power_modes,
+ .num_items = ARRAY_SIZE(bma400_power_modes),
+ .get = bma400_power_mode_enum_get,
+ .set = bma400_power_mode_enum_set,
+};
+
+static const struct iio_chan_spec_ext_info bma400_ext_info[] = {
+ IIO_ENUM("power_mode", true, &bma400_power_mode_enum),
+ IIO_ENUM_AVAILABLE("power_mode", &bma400_power_mode_enum),
+ IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma400_accel_get_mount_matrix),
+ { }
+};
+
+#define BMA400_ACC_CHANNEL(_axis) { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##_axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ .ext_info = bma400_ext_info, \
+}
+
+static const struct iio_chan_spec bma400_channels[] = {
+ BMA400_ACC_CHANNEL(X),
+ BMA400_ACC_CHANNEL(Y),
+ BMA400_ACC_CHANNEL(Z),
+ {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ },
+};
+
static void bma400_init_tables(void)
{
int raw;
@@ -848,6 +885,41 @@ int bma400_remove(struct device *dev)
}
EXPORT_SYMBOL(bma400_remove);
+#ifdef CONFIG_PM_SLEEP
+static int bma400_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct bma400_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = bma400_set_power_mode(data, POWER_MODE_SLEEP);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static int bma400_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct bma400_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = bma400_set_power_mode(data, POWER_MODE_NORMAL);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+#endif
+
+const struct dev_pm_ops bma400_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+ SET_SYSTEM_SLEEP_PM_OPS(bma400_suspend, bma400_resume)
+#endif
+};
+EXPORT_SYMBOL(bma400_pm_ops);
+
MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core");
MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c
index 9dcb7cc9996e..52a779d53629 100644
--- a/drivers/iio/accel/bma400_i2c.c
+++ b/drivers/iio/accel/bma400_i2c.c
@@ -48,6 +48,7 @@ static struct i2c_driver bma400_i2c_driver = {
.driver = {
.name = "bma400",
.of_match_table = bma400_of_i2c_match,
+ .pm = &bma400_pm_ops
},
.probe = bma400_i2c_probe,
.remove = bma400_i2c_remove,
diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c
index 7c2825904e08..358bd26ac4cd 100644
--- a/drivers/iio/accel/bma400_spi.c
+++ b/drivers/iio/accel/bma400_spi.c
@@ -108,6 +108,7 @@ static struct spi_driver bma400_spi_driver = {
.driver = {
.name = "bma400",
.of_match_table = bma400_of_spi_match,
+ .pm = &bma400_pm_ops
},
.probe = bma400_spi_probe,
.remove = bma400_spi_remove,
next prev parent reply other threads:[~2020-07-15 5:20 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-15 5:02 [PATCH 0/1] iio: accel: bma400: add PM_SLEEP support Dan Robertson
2020-07-15 5:02 ` Dan Robertson [this message]
2020-07-15 5:44 ` [PATCH 1/1] " Andy Shevchenko
2020-07-20 23:50 ` Dan Robertson
2020-07-20 11:23 ` Jonathan Cameron
2020-07-20 23:53 ` Dan Robertson
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=20200715050226.9751-2-dan@dlrobertson.com \
--to=dan@dlrobertson.com \
--cc=andy.shevchenko@gmail.com \
--cc=jic23@kernel.org \
--cc=lars@metafoo.de \
--cc=linus.walleij@linaro.org \
--cc=linux-iio@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox