History

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.

Gwendal Grignou committed 6 years ago

Commit e7e3b9d1 parent 79846e35 files · +47 −4Browse files

Unified · Split

5 files
  1. drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +5 −0
  2. drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +21 −0
  3. drivers/iio/light/cros_ec_light_prox.c +5 −1
  4. drivers/iio/pressure/cros_ec_baro.c +6 −2
  5. include/linux/iio/common/cros_ec_sensors_core.h +10 −1
drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c+5−0
@@ -200,6 +200,10 @@ static int cros_ec_sensors_write(struct iio_dev *indio_dev, · 199 unmodified lines
200200 st->core.param.sensor_range.roundup = 1;
201201
202202 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+ }
203207 break;
204208 default:
205209 ret = cros_ec_sensors_core_write(
@@ -315,6 +319,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_sensors_ids); · 109 unmodified lines
315319 static struct platform_driver cros_ec_sensors_platform_driver = {
316320 .driver = {
317321 .name = "cros-ec-sensors",
322+ .pm = &cros_ec_sensors_pm_ops,
318323 },
319324 .probe = cros_ec_sensors_probe,
320325 .id_table = cros_ec_sensors_ids,
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c+21−0
@@ -824,5 +824,26 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st, · 823 unmodified lines
824824 }
825825 EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write);
826826
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+
827848 MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions");
828849 MODULE_LICENSE("GPL v2");
drivers/iio/light/cros_ec_light_prox.c+5−1
@@ -145,8 +145,11 @@ static int cros_ec_light_prox_write(struct iio_dev *indio_dev, · 144 unmodified lines
145145 break;
146146 case IIO_CHAN_INFO_CALIBSCALE:
147147 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;
149150 ret = cros_ec_motion_send_host_cmd(&st->core, 0);
151+ if (ret == 0)
152+ st->core.range_updated = true;
150153 break;
151154 default:
152155 ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
@@ -256,6 +259,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_light_prox_ids); · 103 unmodified lines
256259 static struct platform_driver cros_ec_light_prox_platform_driver = {
257260 .driver = {
258261 .name = "cros-ec-light-prox",
262+ .pm = &cros_ec_sensors_pm_ops,
259263 },
260264 .probe = cros_ec_light_prox_probe,
261265 .id_table = cros_ec_light_prox_ids,
drivers/iio/pressure/cros_ec_baro.c+6−2
@@ -96,8 +96,11 @@ static int cros_ec_baro_write(struct iio_dev *indio_dev, · 95 unmodified lines
9696 /* Always roundup, so caller gets at least what it asks for. */
9797 st->core.param.sensor_range.roundup = 1;
9898
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+ }
101104 break;
102105 default:
103106 ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
@@ -199,6 +202,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_baro_ids); · 95 unmodified lines
199202 static struct platform_driver cros_ec_baro_platform_driver = {
200203 .driver = {
201204 .name = "cros-ec-baro",
205+ .pm = &cros_ec_sensors_pm_ops,
202206 },
203207 .probe = cros_ec_baro_probe,
204208 .id_table = cros_ec_baro_ids,
include/linux/iio/common/cros_ec_sensors_core.h+10−1
@@ -42,6 +42,10 @@ typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p); · 41 unmodified lines
4242 * @resp: motion sensor response structure
4343 * @type: type of motion sensor
4444 * @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.
4549 * @calib: calibration parameters. Note that trigger
4650 * captured data will always provide the calibrated
4751 * data
@@ -65,6 +69,9 @@ struct cros_ec_sensors_core_state { · 17 unmodified lines
6569 enum motionsensor_type type;
6670 enum motionsensor_location loc;
6771
72+ bool range_updated;
73+ int curr_range;
74+
6875 struct calib_data {
6976 s16 offset;
7077 u16 scale;
@@ -114,7 +121,9 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st, · 43 unmodified lines
114121 struct iio_chan_spec const *chan,
115122 int val, int val2, long mask);
116123
117−/* List of extended channel specification for all sensors */
124+extern const struct dev_pm_ops cros_ec_sensors_pm_ops;
125+
126+/* List of extended channel specification for all sensors. */
118127 extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];
119128 extern const struct attribute *cros_ec_sensor_fifo_attributes[];
120129