Commit e7e3b9d2 authored by Gwendal Grignou's avatar Gwendal Grignou Committed by Jonathan Cameron

iio: cros_ec: Reapply range at resume

EC does not currently preserve range across sensor reinit.
If sensor is powered down at suspend, it will default to the EC default
range at resume, not the range set by the host.

Save range if modified, and apply at resume.
Signed-off-by: default avatarGwendal Grignou <gwendal@chromium.org>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 79846e33
......@@ -200,6 +200,10 @@ static int cros_ec_sensors_write(struct iio_dev *indio_dev,
st->core.param.sensor_range.roundup = 1;
ret = cros_ec_motion_send_host_cmd(&st->core, 0);
if (ret == 0) {
st->core.range_updated = true;
st->core.curr_range = val;
}
break;
default:
ret = cros_ec_sensors_core_write(
......@@ -315,6 +319,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_sensors_ids);
static struct platform_driver cros_ec_sensors_platform_driver = {
.driver = {
.name = "cros-ec-sensors",
.pm = &cros_ec_sensors_pm_ops,
},
.probe = cros_ec_sensors_probe,
.id_table = cros_ec_sensors_ids,
......
......@@ -824,5 +824,26 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
}
EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write);
static int __maybe_unused cros_ec_sensors_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
int ret = 0;
if (st->range_updated) {
mutex_lock(&st->cmd_lock);
st->param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
st->param.sensor_range.data = st->curr_range;
st->param.sensor_range.roundup = 1;
ret = cros_ec_motion_send_host_cmd(st, 0);
mutex_unlock(&st->cmd_lock);
}
return ret;
}
SIMPLE_DEV_PM_OPS(cros_ec_sensors_pm_ops, NULL, cros_ec_sensors_resume);
EXPORT_SYMBOL_GPL(cros_ec_sensors_pm_ops);
MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions");
MODULE_LICENSE("GPL v2");
......@@ -145,8 +145,11 @@ static int cros_ec_light_prox_write(struct iio_dev *indio_dev,
break;
case IIO_CHAN_INFO_CALIBSCALE:
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
st->core.param.sensor_range.data = (val << 16) | (val2 / 100);
st->core.curr_range = (val << 16) | (val2 / 100);
st->core.param.sensor_range.data = st->core.curr_range;
ret = cros_ec_motion_send_host_cmd(&st->core, 0);
if (ret == 0)
st->core.range_updated = true;
break;
default:
ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
......@@ -256,6 +259,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_light_prox_ids);
static struct platform_driver cros_ec_light_prox_platform_driver = {
.driver = {
.name = "cros-ec-light-prox",
.pm = &cros_ec_sensors_pm_ops,
},
.probe = cros_ec_light_prox_probe,
.id_table = cros_ec_light_prox_ids,
......
......@@ -96,8 +96,11 @@ static int cros_ec_baro_write(struct iio_dev *indio_dev,
/* Always roundup, so caller gets at least what it asks for. */
st->core.param.sensor_range.roundup = 1;
if (cros_ec_motion_send_host_cmd(&st->core, 0))
ret = -EIO;
ret = cros_ec_motion_send_host_cmd(&st->core, 0);
if (ret == 0) {
st->core.range_updated = true;
st->core.curr_range = val;
}
break;
default:
ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
......@@ -199,6 +202,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_baro_ids);
static struct platform_driver cros_ec_baro_platform_driver = {
.driver = {
.name = "cros-ec-baro",
.pm = &cros_ec_sensors_pm_ops,
},
.probe = cros_ec_baro_probe,
.id_table = cros_ec_baro_ids,
......
......@@ -42,6 +42,10 @@ typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p);
* @resp: motion sensor response structure
* @type: type of motion sensor
* @loc: location where the motion sensor is placed
* @range_updated: True if the range of the sensor has been
* updated.
* @curr_range: If updated, the current range value.
* It will be reapplied at every resume.
* @calib: calibration parameters. Note that trigger
* captured data will always provide the calibrated
* data
......@@ -65,6 +69,9 @@ struct cros_ec_sensors_core_state {
enum motionsensor_type type;
enum motionsensor_location loc;
bool range_updated;
int curr_range;
struct calib_data {
s16 offset;
u16 scale;
......@@ -114,7 +121,9 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
struct iio_chan_spec const *chan,
int val, int val2, long mask);
/* List of extended channel specification for all sensors */
extern const struct dev_pm_ops cros_ec_sensors_pm_ops;
/* List of extended channel specification for all sensors. */
extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];
extern const struct attribute *cros_ec_sensor_fifo_attributes[];
......
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