aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/proximity
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/proximity')
-rw-r--r--drivers/iio/proximity/pulsedlight-lidar-lite-v2.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
index 961f9f990faf..be8ccef735f8 100644
--- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
+++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
@@ -13,7 +13,7 @@
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * TODO: runtime pm, interrupt mode, and signal strength reporting 16 * TODO: interrupt mode, and signal strength reporting
17 */ 17 */
18 18
19#include <linux/err.h> 19#include <linux/err.h>
@@ -21,6 +21,7 @@
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/pm_runtime.h>
24#include <linux/iio/iio.h> 25#include <linux/iio/iio.h>
25#include <linux/iio/sysfs.h> 26#include <linux/iio/sysfs.h>
26#include <linux/iio/buffer.h> 27#include <linux/iio/buffer.h>
@@ -37,6 +38,7 @@
37 38
38#define LIDAR_REG_DATA_HBYTE 0x0f 39#define LIDAR_REG_DATA_HBYTE 0x0f
39#define LIDAR_REG_DATA_LBYTE 0x10 40#define LIDAR_REG_DATA_LBYTE 0x10
41#define LIDAR_REG_PWR_CONTROL 0x65
40 42
41#define LIDAR_DRV_NAME "lidar" 43#define LIDAR_DRV_NAME "lidar"
42 44
@@ -90,6 +92,12 @@ static inline int lidar_write_control(struct lidar_data *data, int val)
90 return i2c_smbus_write_byte_data(data->client, LIDAR_REG_CONTROL, val); 92 return i2c_smbus_write_byte_data(data->client, LIDAR_REG_CONTROL, val);
91} 93}
92 94
95static inline int lidar_write_power(struct lidar_data *data, int val)
96{
97 return i2c_smbus_write_byte_data(data->client,
98 LIDAR_REG_PWR_CONTROL, val);
99}
100
93static int lidar_read_measurement(struct lidar_data *data, u16 *reg) 101static int lidar_read_measurement(struct lidar_data *data, u16 *reg)
94{ 102{
95 int ret; 103 int ret;
@@ -116,6 +124,8 @@ static int lidar_get_measurement(struct lidar_data *data, u16 *reg)
116 int tries = 10; 124 int tries = 10;
117 int ret; 125 int ret;
118 126
127 pm_runtime_get_sync(&client->dev);
128
119 /* start sample */ 129 /* start sample */
120 ret = lidar_write_control(data, LIDAR_REG_CONTROL_ACQUIRE); 130 ret = lidar_write_control(data, LIDAR_REG_CONTROL_ACQUIRE);
121 if (ret < 0) { 131 if (ret < 0) {
@@ -144,6 +154,8 @@ static int lidar_get_measurement(struct lidar_data *data, u16 *reg)
144 } 154 }
145 ret = -EIO; 155 ret = -EIO;
146 } 156 }
157 pm_runtime_mark_last_busy(&client->dev);
158 pm_runtime_put_autosuspend(&client->dev);
147 159
148 return ret; 160 return ret;
149} 161}
@@ -243,6 +255,17 @@ static int lidar_probe(struct i2c_client *client,
243 if (ret) 255 if (ret)
244 goto error_unreg_buffer; 256 goto error_unreg_buffer;
245 257
258 pm_runtime_set_autosuspend_delay(&client->dev, 1000);
259 pm_runtime_use_autosuspend(&client->dev);
260
261 ret = pm_runtime_set_active(&client->dev);
262 if (ret)
263 goto error_unreg_buffer;
264 pm_runtime_enable(&client->dev);
265
266 pm_runtime_mark_last_busy(&client->dev);
267 pm_runtime_idle(&client->dev);
268
246 return 0; 269 return 0;
247 270
248error_unreg_buffer: 271error_unreg_buffer:
@@ -258,6 +281,9 @@ static int lidar_remove(struct i2c_client *client)
258 iio_device_unregister(indio_dev); 281 iio_device_unregister(indio_dev);
259 iio_triggered_buffer_cleanup(indio_dev); 282 iio_triggered_buffer_cleanup(indio_dev);
260 283
284 pm_runtime_disable(&client->dev);
285 pm_runtime_set_suspended(&client->dev);
286
261 return 0; 287 return 0;
262} 288}
263 289
@@ -273,10 +299,38 @@ static const struct of_device_id lidar_dt_ids[] = {
273}; 299};
274MODULE_DEVICE_TABLE(of, lidar_dt_ids); 300MODULE_DEVICE_TABLE(of, lidar_dt_ids);
275 301
302#ifdef CONFIG_PM
303static int lidar_pm_runtime_suspend(struct device *dev)
304{
305 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
306 struct lidar_data *data = iio_priv(indio_dev);
307
308 return lidar_write_power(data, 0x0f);
309}
310
311static int lidar_pm_runtime_resume(struct device *dev)
312{
313 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
314 struct lidar_data *data = iio_priv(indio_dev);
315 int ret = lidar_write_power(data, 0);
316
317 /* regulator and FPGA needs settling time */
318 usleep_range(15000, 20000);
319
320 return ret;
321}
322#endif
323
324static const struct dev_pm_ops lidar_pm_ops = {
325 SET_RUNTIME_PM_OPS(lidar_pm_runtime_suspend,
326 lidar_pm_runtime_resume, NULL)
327};
328
276static struct i2c_driver lidar_driver = { 329static struct i2c_driver lidar_driver = {
277 .driver = { 330 .driver = {
278 .name = LIDAR_DRV_NAME, 331 .name = LIDAR_DRV_NAME,
279 .of_match_table = of_match_ptr(lidar_dt_ids), 332 .of_match_table = of_match_ptr(lidar_dt_ids),
333 .pm = &lidar_pm_ops,
280 }, 334 },
281 .probe = lidar_probe, 335 .probe = lidar_probe,
282 .remove = lidar_remove, 336 .remove = lidar_remove,