mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
iio: chemical: bme680: add power management
Add runtime power management to the device. Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> Link: https://patch.msgid.link/20241202192341.33187-4-vassilisamir@gmail.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
601f7269fc
commit
1e60a6545c
@ -2,6 +2,7 @@
|
||||
#ifndef BME680_H_
|
||||
#define BME680_H_
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define BME680_REG_CHIP_ID 0xD0
|
||||
@ -80,6 +81,7 @@
|
||||
#define BME680_CALIB_RANGE_3_LEN 5
|
||||
|
||||
extern const struct regmap_config bme680_regmap_config;
|
||||
extern const struct dev_pm_ops bme680_dev_pm_ops;
|
||||
|
||||
int bme680_core_probe(struct device *dev, struct regmap *regmap,
|
||||
const char *name);
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
@ -820,9 +822,9 @@ static int bme680_read_gas(struct bme680_data *data, int *comp_gas_res)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bme680_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val, int *val2, long mask)
|
||||
static int __bme680_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
int chan_val, ret;
|
||||
@ -935,14 +937,33 @@ static int bme680_read_raw(struct iio_dev *indio_dev,
|
||||
}
|
||||
}
|
||||
|
||||
static int bme680_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
struct device *dev = regmap_get_device(data->regmap);
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __bme680_read_raw(indio_dev, chan, val, val2, mask);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool bme680_is_valid_oversampling(int rate)
|
||||
{
|
||||
return (rate > 0 && rate <= 16 && is_power_of_2(rate));
|
||||
}
|
||||
|
||||
static int bme680_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int val, int val2, long mask)
|
||||
static int __bme680_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int val, int val2, long mask)
|
||||
{
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
|
||||
@ -987,6 +1008,25 @@ static int bme680_write_raw(struct iio_dev *indio_dev,
|
||||
}
|
||||
}
|
||||
|
||||
static int bme680_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int val, int val2, long mask)
|
||||
{
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
struct device *dev = regmap_get_device(data->regmap);
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __bme680_write_raw(indio_dev, chan, val, val2, mask);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char bme680_oversampling_ratio_show[] = "1 2 4 8 16";
|
||||
|
||||
static IIO_CONST_ATTR(oversampling_ratio_available,
|
||||
@ -1087,6 +1127,29 @@ static irqreturn_t bme680_trigger_handler(int irq, void *p)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int bme680_buffer_preenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
struct device *dev = regmap_get_device(data->regmap);
|
||||
|
||||
return pm_runtime_resume_and_get(dev);
|
||||
}
|
||||
|
||||
static int bme680_buffer_postdisable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
struct device *dev = regmap_get_device(data->regmap);
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct iio_buffer_setup_ops bme680_buffer_setup_ops = {
|
||||
.preenable = bme680_buffer_preenable,
|
||||
.postdisable = bme680_buffer_postdisable,
|
||||
};
|
||||
|
||||
int bme680_core_probe(struct device *dev, struct regmap *regmap,
|
||||
const char *name)
|
||||
{
|
||||
@ -1160,15 +1223,47 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
|
||||
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
|
||||
iio_pollfunc_store_time,
|
||||
bme680_trigger_handler,
|
||||
NULL);
|
||||
&bme680_buffer_setup_ops);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"iio triggered buffer setup failed\n");
|
||||
|
||||
/* Enable runtime PM */
|
||||
pm_runtime_set_autosuspend_delay(dev, BME680_STARTUP_TIME_US);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_iio_device_register(dev, indio_dev);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(bme680_core_probe, "IIO_BME680");
|
||||
|
||||
static int bme680_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
|
||||
return bme680_set_mode(data, BME680_MODE_SLEEP);
|
||||
}
|
||||
|
||||
static int bme680_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct bme680_data *data = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
ret = bme680_chip_config(data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return bme680_gas_config(data);
|
||||
}
|
||||
|
||||
EXPORT_RUNTIME_DEV_PM_OPS(bme680_dev_pm_ops, bme680_runtime_suspend,
|
||||
bme680_runtime_resume, NULL);
|
||||
|
||||
MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>");
|
||||
MODULE_DESCRIPTION("Bosch BME680 Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -51,6 +51,7 @@ static struct i2c_driver bme680_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "bme680_i2c",
|
||||
.of_match_table = bme680_of_i2c_match,
|
||||
.pm = pm_ptr(&bme680_dev_pm_ops),
|
||||
},
|
||||
.probe = bme680_i2c_probe,
|
||||
.id_table = bme680_i2c_id,
|
||||
|
@ -154,6 +154,7 @@ static struct spi_driver bme680_spi_driver = {
|
||||
.driver = {
|
||||
.name = "bme680_spi",
|
||||
.of_match_table = bme680_of_spi_match,
|
||||
.pm = pm_ptr(&bme680_dev_pm_ops),
|
||||
},
|
||||
.probe = bme680_spi_probe,
|
||||
.id_table = bme680_spi_id,
|
||||
|
Loading…
Reference in New Issue
Block a user