Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Gwendal Grignou <gwendal@chromium.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Gwendal Grignou and committed by
Jonathan Cameron
e7e3b9d2 79846e33

+47 -4
+5
drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
··· 200 200 st->core.param.sensor_range.roundup = 1; 201 201 202 202 ret = cros_ec_motion_send_host_cmd(&st->core, 0); 203 + if (ret == 0) { 204 + st->core.range_updated = true; 205 + st->core.curr_range = val; 206 + } 203 207 break; 204 208 default: 205 209 ret = cros_ec_sensors_core_write( ··· 319 315 static struct platform_driver cros_ec_sensors_platform_driver = { 320 316 .driver = { 321 317 .name = "cros-ec-sensors", 318 + .pm = &cros_ec_sensors_pm_ops, 322 319 }, 323 320 .probe = cros_ec_sensors_probe, 324 321 .id_table = cros_ec_sensors_ids,
+21
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
··· 824 824 } 825 825 EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write); 826 826 827 + static int __maybe_unused cros_ec_sensors_resume(struct device *dev) 828 + { 829 + struct platform_device *pdev = to_platform_device(dev); 830 + struct iio_dev *indio_dev = platform_get_drvdata(pdev); 831 + struct cros_ec_sensors_core_state *st = iio_priv(indio_dev); 832 + int ret = 0; 833 + 834 + if (st->range_updated) { 835 + mutex_lock(&st->cmd_lock); 836 + st->param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE; 837 + st->param.sensor_range.data = st->curr_range; 838 + st->param.sensor_range.roundup = 1; 839 + ret = cros_ec_motion_send_host_cmd(st, 0); 840 + mutex_unlock(&st->cmd_lock); 841 + } 842 + return ret; 843 + } 844 + 845 + SIMPLE_DEV_PM_OPS(cros_ec_sensors_pm_ops, NULL, cros_ec_sensors_resume); 846 + EXPORT_SYMBOL_GPL(cros_ec_sensors_pm_ops); 847 + 827 848 MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions"); 828 849 MODULE_LICENSE("GPL v2");
+5 -1
drivers/iio/light/cros_ec_light_prox.c
··· 145 145 break; 146 146 case IIO_CHAN_INFO_CALIBSCALE: 147 147 st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE; 148 - st->core.param.sensor_range.data = (val << 16) | (val2 / 100); 148 + st->core.curr_range = (val << 16) | (val2 / 100); 149 + st->core.param.sensor_range.data = st->core.curr_range; 149 150 ret = cros_ec_motion_send_host_cmd(&st->core, 0); 151 + if (ret == 0) 152 + st->core.range_updated = true; 150 153 break; 151 154 default: 152 155 ret = cros_ec_sensors_core_write(&st->core, chan, val, val2, ··· 259 256 static struct platform_driver cros_ec_light_prox_platform_driver = { 260 257 .driver = { 261 258 .name = "cros-ec-light-prox", 259 + .pm = &cros_ec_sensors_pm_ops, 262 260 }, 263 261 .probe = cros_ec_light_prox_probe, 264 262 .id_table = cros_ec_light_prox_ids,
+6 -2
drivers/iio/pressure/cros_ec_baro.c
··· 96 96 /* Always roundup, so caller gets at least what it asks for. */ 97 97 st->core.param.sensor_range.roundup = 1; 98 98 99 - if (cros_ec_motion_send_host_cmd(&st->core, 0)) 100 - ret = -EIO; 99 + ret = cros_ec_motion_send_host_cmd(&st->core, 0); 100 + if (ret == 0) { 101 + st->core.range_updated = true; 102 + st->core.curr_range = val; 103 + } 101 104 break; 102 105 default: 103 106 ret = cros_ec_sensors_core_write(&st->core, chan, val, val2, ··· 202 199 static struct platform_driver cros_ec_baro_platform_driver = { 203 200 .driver = { 204 201 .name = "cros-ec-baro", 202 + .pm = &cros_ec_sensors_pm_ops, 205 203 }, 206 204 .probe = cros_ec_baro_probe, 207 205 .id_table = cros_ec_baro_ids,
+10 -1
include/linux/iio/common/cros_ec_sensors_core.h
··· 42 42 * @resp: motion sensor response structure 43 43 * @type: type of motion sensor 44 44 * @loc: location where the motion sensor is placed 45 + * @range_updated: True if the range of the sensor has been 46 + * updated. 47 + * @curr_range: If updated, the current range value. 48 + * It will be reapplied at every resume. 45 49 * @calib: calibration parameters. Note that trigger 46 50 * captured data will always provide the calibrated 47 51 * data ··· 68 64 69 65 enum motionsensor_type type; 70 66 enum motionsensor_location loc; 67 + 68 + bool range_updated; 69 + int curr_range; 71 70 72 71 struct calib_data { 73 72 s16 offset; ··· 121 114 struct iio_chan_spec const *chan, 122 115 int val, int val2, long mask); 123 116 124 - /* List of extended channel specification for all sensors */ 117 + extern const struct dev_pm_ops cros_ec_sensors_pm_ops; 118 + 119 + /* List of extended channel specification for all sensors. */ 125 120 extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[]; 126 121 extern const struct attribute *cros_ec_sensor_fifo_attributes[]; 127 122