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

iio: accel: fxls8962af: add wake on event

This adds ways for the SoC to wake from accelerometer wake events.

In the suspend function we skip disabling the sensor if wakeup-source
and events are activated.

If buffered reads are enabled they will be deactivated before suspend.
As the onboard buffer is only holding up to 32 12-bit X/Y/Z data
triplets.

Signed-off-by: Sean Nyekjaer <sean@geanix.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20210920114221.1595543-2-sean@geanix.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Sean Nyekjaer and committed by
Jonathan Cameron
269efcf0 131fb9f2

+44 -2
+44 -2
drivers/iio/accel/fxls8962af-core.c
··· 166 166 } scan; 167 167 int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */ 168 168 struct iio_mount_matrix orientation; 169 + int irq; 169 170 u8 watermark; 170 171 u8 enable_event; 171 172 u16 lower_thres; ··· 1157 1156 data = iio_priv(indio_dev); 1158 1157 dev_set_drvdata(dev, indio_dev); 1159 1158 data->regmap = regmap; 1159 + data->irq = irq; 1160 1160 1161 1161 ret = iio_read_mount_matrix(dev, &data->orientation); 1162 1162 if (ret) ··· 1227 1225 if (ret) 1228 1226 return ret; 1229 1227 1228 + if (device_property_read_bool(dev, "wakeup-source")) 1229 + device_init_wakeup(dev, true); 1230 + 1230 1231 return devm_iio_device_register(dev, indio_dev); 1231 1232 } 1232 1233 EXPORT_SYMBOL_GPL(fxls8962af_core_probe); ··· 1255 1250 return fxls8962af_active(data); 1256 1251 } 1257 1252 1253 + static int __maybe_unused fxls8962af_suspend(struct device *dev) 1254 + { 1255 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 1256 + struct fxls8962af_data *data = iio_priv(indio_dev); 1257 + 1258 + if (device_may_wakeup(dev) && data->enable_event) { 1259 + enable_irq_wake(data->irq); 1260 + 1261 + /* 1262 + * Disable buffer, as the buffer is so small the device will wake 1263 + * almost immediately. 1264 + */ 1265 + if (iio_buffer_enabled(indio_dev)) 1266 + fxls8962af_buffer_predisable(indio_dev); 1267 + } else { 1268 + fxls8962af_runtime_suspend(dev); 1269 + } 1270 + 1271 + return 0; 1272 + } 1273 + 1274 + static int __maybe_unused fxls8962af_resume(struct device *dev) 1275 + { 1276 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 1277 + struct fxls8962af_data *data = iio_priv(indio_dev); 1278 + 1279 + if (device_may_wakeup(dev) && data->enable_event) { 1280 + disable_irq_wake(data->irq); 1281 + 1282 + if (iio_buffer_enabled(indio_dev)) 1283 + fxls8962af_buffer_postenable(indio_dev); 1284 + } else { 1285 + fxls8962af_runtime_resume(dev); 1286 + } 1287 + 1288 + return 0; 1289 + } 1290 + 1258 1291 const struct dev_pm_ops fxls8962af_pm_ops = { 1259 - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1260 - pm_runtime_force_resume) 1292 + SET_SYSTEM_SLEEP_PM_OPS(fxls8962af_suspend, fxls8962af_resume) 1261 1293 SET_RUNTIME_PM_OPS(fxls8962af_runtime_suspend, 1262 1294 fxls8962af_runtime_resume, NULL) 1263 1295 };