regulator: tps65086: Update regulator driver for the TPS65086 PMIC
[cascardo/linux.git] / drivers / iio / proximity / pulsedlight-lidar-lite-v2.c
1 /*
2  * pulsedlight-lidar-lite-v2.c - Support for PulsedLight LIDAR sensor
3  *
4  * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * TODO: runtime pm, interrupt mode, and signal strength reporting
17  */
18
19 #include <linux/err.h>
20 #include <linux/init.h>
21 #include <linux/i2c.h>
22 #include <linux/delay.h>
23 #include <linux/module.h>
24 #include <linux/iio/iio.h>
25 #include <linux/iio/sysfs.h>
26 #include <linux/iio/buffer.h>
27 #include <linux/iio/trigger.h>
28 #include <linux/iio/triggered_buffer.h>
29 #include <linux/iio/trigger_consumer.h>
30
31 #define LIDAR_REG_CONTROL               0x00
32 #define LIDAR_REG_CONTROL_ACQUIRE       BIT(2)
33
34 #define LIDAR_REG_STATUS                0x01
35 #define LIDAR_REG_STATUS_INVALID        BIT(3)
36 #define LIDAR_REG_STATUS_READY          BIT(0)
37
38 #define LIDAR_REG_DATA_HBYTE    0x0f
39 #define LIDAR_REG_DATA_LBYTE    0x10
40
41 #define LIDAR_DRV_NAME "lidar"
42
43 struct lidar_data {
44         struct iio_dev *indio_dev;
45         struct i2c_client *client;
46
47         u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */
48 };
49
50 static const struct iio_chan_spec lidar_channels[] = {
51         {
52                 .type = IIO_DISTANCE,
53                 .info_mask_separate =
54                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
55                 .scan_index = 0,
56                 .scan_type = {
57                         .sign = 'u',
58                         .realbits = 16,
59                         .storagebits = 16,
60                 },
61         },
62         IIO_CHAN_SOFT_TIMESTAMP(1),
63 };
64
65 static int lidar_read_byte(struct lidar_data *data, int reg)
66 {
67         struct i2c_client *client = data->client;
68         int ret;
69
70         /*
71          * Device needs a STOP condition between address write, and data read
72          * so in turn i2c_smbus_read_byte_data cannot be used
73          */
74
75         ret = i2c_smbus_write_byte(client, reg);
76         if (ret < 0) {
77                 dev_err(&client->dev, "cannot write addr value");
78                 return ret;
79         }
80
81         ret = i2c_smbus_read_byte(client);
82         if (ret < 0)
83                 dev_err(&client->dev, "cannot read data value");
84
85         return ret;
86 }
87
88 static inline int lidar_write_control(struct lidar_data *data, int val)
89 {
90         return i2c_smbus_write_byte_data(data->client, LIDAR_REG_CONTROL, val);
91 }
92
93 static int lidar_read_measurement(struct lidar_data *data, u16 *reg)
94 {
95         int ret;
96         int val;
97
98         ret = lidar_read_byte(data, LIDAR_REG_DATA_HBYTE);
99         if (ret < 0)
100                 return ret;
101         val = ret << 8;
102
103         ret = lidar_read_byte(data, LIDAR_REG_DATA_LBYTE);
104         if (ret < 0)
105                 return ret;
106
107         val |= ret;
108         *reg = val;
109
110         return 0;
111 }
112
113 static int lidar_get_measurement(struct lidar_data *data, u16 *reg)
114 {
115         struct i2c_client *client = data->client;
116         int tries = 10;
117         int ret;
118
119         /* start sample */
120         ret = lidar_write_control(data, LIDAR_REG_CONTROL_ACQUIRE);
121         if (ret < 0) {
122                 dev_err(&client->dev, "cannot send start measurement command");
123                 return ret;
124         }
125
126         while (tries--) {
127                 usleep_range(1000, 2000);
128
129                 ret = lidar_read_byte(data, LIDAR_REG_STATUS);
130                 if (ret < 0)
131                         break;
132
133                 /* return 0 since laser is likely pointed out of range */
134                 if (ret & LIDAR_REG_STATUS_INVALID) {
135                         *reg = 0;
136                         ret = 0;
137                         break;
138                 }
139
140                 /* sample ready to read */
141                 if (!(ret & LIDAR_REG_STATUS_READY)) {
142                         ret = lidar_read_measurement(data, reg);
143                         break;
144                 }
145                 ret = -EIO;
146         }
147
148         return ret;
149 }
150
151 static int lidar_read_raw(struct iio_dev *indio_dev,
152                           struct iio_chan_spec const *chan,
153                           int *val, int *val2, long mask)
154 {
155         struct lidar_data *data = iio_priv(indio_dev);
156         int ret = -EINVAL;
157
158         mutex_lock(&indio_dev->mlock);
159
160         if (iio_buffer_enabled(indio_dev) && mask == IIO_CHAN_INFO_RAW) {
161                 ret = -EBUSY;
162                 goto error_busy;
163         }
164
165         switch (mask) {
166         case IIO_CHAN_INFO_RAW: {
167                 u16 reg;
168
169                 ret = lidar_get_measurement(data, &reg);
170                 if (!ret) {
171                         *val = reg;
172                         ret = IIO_VAL_INT;
173                 }
174                 break;
175         }
176         case IIO_CHAN_INFO_SCALE:
177                 *val = 0;
178                 *val2 = 10000;
179                 ret = IIO_VAL_INT_PLUS_MICRO;
180                 break;
181         }
182
183 error_busy:
184         mutex_unlock(&indio_dev->mlock);
185
186         return ret;
187 }
188
189 static irqreturn_t lidar_trigger_handler(int irq, void *private)
190 {
191         struct iio_poll_func *pf = private;
192         struct iio_dev *indio_dev = pf->indio_dev;
193         struct lidar_data *data = iio_priv(indio_dev);
194         int ret;
195
196         ret = lidar_get_measurement(data, data->buffer);
197         if (!ret) {
198                 iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
199                                                    iio_get_time_ns());
200         } else {
201                 dev_err(&data->client->dev, "cannot read LIDAR measurement");
202         }
203
204         iio_trigger_notify_done(indio_dev->trig);
205
206         return IRQ_HANDLED;
207 }
208
209 static const struct iio_info lidar_info = {
210         .driver_module = THIS_MODULE,
211         .read_raw = lidar_read_raw,
212 };
213
214 static int lidar_probe(struct i2c_client *client,
215                        const struct i2c_device_id *id)
216 {
217         struct lidar_data *data;
218         struct iio_dev *indio_dev;
219         int ret;
220
221         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
222         if (!indio_dev)
223                 return -ENOMEM;
224
225         indio_dev->info = &lidar_info;
226         indio_dev->name = LIDAR_DRV_NAME;
227         indio_dev->channels = lidar_channels;
228         indio_dev->num_channels = ARRAY_SIZE(lidar_channels);
229         indio_dev->modes = INDIO_DIRECT_MODE;
230
231         data = iio_priv(indio_dev);
232         i2c_set_clientdata(client, indio_dev);
233
234         data->client = client;
235         data->indio_dev = indio_dev;
236
237         ret = iio_triggered_buffer_setup(indio_dev, NULL,
238                                          lidar_trigger_handler, NULL);
239         if (ret)
240                 return ret;
241
242         ret = iio_device_register(indio_dev);
243         if (ret)
244                 goto error_unreg_buffer;
245
246         return 0;
247
248 error_unreg_buffer:
249         iio_triggered_buffer_cleanup(indio_dev);
250
251         return ret;
252 }
253
254 static int lidar_remove(struct i2c_client *client)
255 {
256         struct iio_dev *indio_dev = i2c_get_clientdata(client);
257
258         iio_device_unregister(indio_dev);
259         iio_triggered_buffer_cleanup(indio_dev);
260
261         return 0;
262 }
263
264 static const struct i2c_device_id lidar_id[] = {
265         {"lidar-lite-v2", 0},
266         { },
267 };
268 MODULE_DEVICE_TABLE(i2c, lidar_id);
269
270 static const struct of_device_id lidar_dt_ids[] = {
271         { .compatible = "pulsedlight,lidar-lite-v2" },
272         { }
273 };
274 MODULE_DEVICE_TABLE(of, lidar_dt_ids);
275
276 static struct i2c_driver lidar_driver = {
277         .driver = {
278                 .name   = LIDAR_DRV_NAME,
279                 .of_match_table = of_match_ptr(lidar_dt_ids),
280         },
281         .probe          = lidar_probe,
282         .remove         = lidar_remove,
283         .id_table       = lidar_id,
284 };
285 module_i2c_driver(lidar_driver);
286
287 MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
288 MODULE_DESCRIPTION("PulsedLight LIDAR sensor");
289 MODULE_LICENSE("GPL");