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


  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 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.