Commit 4599cac8 authored by Jean-Baptiste Maneyrol's avatar Jean-Baptiste Maneyrol Committed by Jonathan Cameron

iio: imu: inv_mpu6050: use runtime pm with autosuspend

Use runtime power management for handling chip power and
sensor engines on/off. Simplifies things a lot since pm
runtime already has reference counter.
Usage of autosuspend reduces the number of power on/off. This
makes polling interface now usable to get data at low
frequency.
Signed-off-by: default avatarJean-Baptiste Maneyrol <jmaneyrol@invensense.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 5e95ca36
This diff is collapsed.
...@@ -164,6 +164,7 @@ struct inv_mpu6050_hw { ...@@ -164,6 +164,7 @@ struct inv_mpu6050_hw {
* @magn_disabled: magnetometer disabled for backward compatibility reason. * @magn_disabled: magnetometer disabled for backward compatibility reason.
* @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss. * @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss.
* @magn_orient: magnetometer sensor chip orientation if available. * @magn_orient: magnetometer sensor chip orientation if available.
* @suspended_sensors: sensors mask of sensors turned off for suspend
*/ */
struct inv_mpu6050_state { struct inv_mpu6050_state {
struct mutex lock; struct mutex lock;
...@@ -174,7 +175,6 @@ struct inv_mpu6050_state { ...@@ -174,7 +175,6 @@ struct inv_mpu6050_state {
enum inv_devices chip_type; enum inv_devices chip_type;
struct i2c_mux_core *muxc; struct i2c_mux_core *muxc;
struct i2c_client *mux_client; struct i2c_client *mux_client;
unsigned int powerup_count;
struct inv_mpu6050_platform_data plat_data; struct inv_mpu6050_platform_data plat_data;
struct iio_mount_matrix orientation; struct iio_mount_matrix orientation;
struct regmap *map; struct regmap *map;
...@@ -189,6 +189,7 @@ struct inv_mpu6050_state { ...@@ -189,6 +189,7 @@ struct inv_mpu6050_state {
bool magn_disabled; bool magn_disabled;
s32 magn_raw_to_gauss[3]; s32 magn_raw_to_gauss[3];
struct iio_mount_matrix magn_orient; struct iio_mount_matrix magn_orient;
unsigned int suspended_sensors;
}; };
/*register and associated bit definition*/ /*register and associated bit definition*/
...@@ -312,6 +313,7 @@ struct inv_mpu6050_state { ...@@ -312,6 +313,7 @@ struct inv_mpu6050_state {
#define INV_MPU6050_ACCEL_UP_TIME 20 #define INV_MPU6050_ACCEL_UP_TIME 20
#define INV_MPU6050_GYRO_UP_TIME 35 #define INV_MPU6050_GYRO_UP_TIME 35
#define INV_MPU6050_GYRO_DOWN_TIME 150 #define INV_MPU6050_GYRO_DOWN_TIME 150
#define INV_MPU6050_SUSPEND_DELAY_MS 2000
/* delay time in microseconds */ /* delay time in microseconds */
#define INV_MPU6050_REG_UP_TIME_MIN 5000 #define INV_MPU6050_REG_UP_TIME_MIN 5000
...@@ -439,7 +441,6 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable); ...@@ -439,7 +441,6 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable);
int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en,
unsigned int mask); unsigned int mask);
int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val); int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val);
int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on);
int inv_mpu_acpi_create_mux_client(struct i2c_client *client); int inv_mpu_acpi_create_mux_client(struct i2c_client *client);
void inv_mpu_acpi_delete_mux_client(struct i2c_client *client); void inv_mpu_acpi_delete_mux_client(struct i2c_client *client);
int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* Copyright (C) 2012 Invensense, Inc. * Copyright (C) 2012 Invensense, Inc.
*/ */
#include <linux/pm_runtime.h>
#include "inv_mpu_iio.h" #include "inv_mpu_iio.h"
static unsigned int inv_scan_query_mpu6050(struct iio_dev *indio_dev) static unsigned int inv_scan_query_mpu6050(struct iio_dev *indio_dev)
...@@ -156,41 +157,43 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable) ...@@ -156,41 +157,43 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable)
static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable) static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
{ {
struct inv_mpu6050_state *st = iio_priv(indio_dev); struct inv_mpu6050_state *st = iio_priv(indio_dev);
struct device *pdev = regmap_get_device(st->map);
unsigned int scan; unsigned int scan;
int result; int result;
scan = inv_scan_query(indio_dev);
if (enable) { if (enable) {
result = inv_mpu6050_set_power_itg(st, true); scan = inv_scan_query(indio_dev);
if (result) result = pm_runtime_get_sync(pdev);
if (result < 0) {
pm_runtime_put_noidle(pdev);
return result; return result;
}
/*
* In case autosuspend didn't trigger, turn off first not
* required sensors.
*/
result = inv_mpu6050_switch_engine(st, false, ~scan);
if (result)
goto error_power_off;
result = inv_mpu6050_switch_engine(st, true, scan); result = inv_mpu6050_switch_engine(st, true, scan);
if (result) if (result)
goto error_power_off; goto error_power_off;
st->skip_samples = inv_compute_skip_samples(st); st->skip_samples = inv_compute_skip_samples(st);
result = inv_mpu6050_prepare_fifo(st, true); result = inv_mpu6050_prepare_fifo(st, true);
if (result) if (result)
goto error_sensors_off; goto error_power_off;
} else { } else {
result = inv_mpu6050_prepare_fifo(st, false); result = inv_mpu6050_prepare_fifo(st, false);
if (result)
goto error_sensors_off;
result = inv_mpu6050_switch_engine(st, false, scan);
if (result)
goto error_power_off;
result = inv_mpu6050_set_power_itg(st, false);
if (result) if (result)
goto error_power_off; goto error_power_off;
pm_runtime_mark_last_busy(pdev);
pm_runtime_put_autosuspend(pdev);
} }
return 0; return 0;
error_sensors_off:
inv_mpu6050_switch_engine(st, false, scan);
error_power_off: error_power_off:
inv_mpu6050_set_power_itg(st, false); pm_runtime_put_autosuspend(pdev);
return result; return result;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment