1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * pulsedlight-lidar-lite-v2.c - Support for PulsedLight LIDAR sensor 4 * 5 * Copyright (C) 2015, 2017-2018 6 * Author: Matt Ranostay <matt.ranostay@konsulko.com> 7 * 8 * TODO: interrupt mode, and signal strength reporting 9 */ 10 11 #include <linux/err.h> 12 #include <linux/init.h> 13 #include <linux/i2c.h> 14 #include <linux/delay.h> 15 #include <linux/module.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/iio/iio.h> 18 #include <linux/iio/sysfs.h> 19 #include <linux/iio/buffer.h> 20 #include <linux/iio/trigger.h> 21 #include <linux/iio/triggered_buffer.h> 22 #include <linux/iio/trigger_consumer.h> 23 24 #define LIDAR_REG_CONTROL 0x00 25 #define LIDAR_REG_CONTROL_ACQUIRE BIT(2) 26 27 #define LIDAR_REG_STATUS 0x01 28 #define LIDAR_REG_STATUS_INVALID BIT(3) 29 #define LIDAR_REG_STATUS_READY BIT(0) 30 31 #define LIDAR_REG_DATA_HBYTE 0x0f 32 #define LIDAR_REG_DATA_LBYTE 0x10 33 #define LIDAR_REG_DATA_WORD_READ BIT(7) 34 35 #define LIDAR_REG_PWR_CONTROL 0x65 36 37 #define LIDAR_DRV_NAME "lidar" 38 39 struct lidar_data { 40 struct iio_dev *indio_dev; 41 struct i2c_client *client; 42 43 int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len); 44 int i2c_enabled; 45 46 u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */ 47 }; 48 49 static const struct iio_chan_spec lidar_channels[] = { 50 { 51 .type = IIO_DISTANCE, 52 .info_mask_separate = 53 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 54 .scan_index = 0, 55 .scan_type = { 56 .sign = 'u', 57 .realbits = 16, 58 .storagebits = 16, 59 }, 60 }, 61 IIO_CHAN_SOFT_TIMESTAMP(1), 62 }; 63 64 static int lidar_i2c_xfer(struct lidar_data *data, u8 reg, u8 *val, int len) 65 { 66 struct i2c_client *client = data->client; 67 struct i2c_msg msg[2]; 68 int ret; 69 70 msg[0].addr = client->addr; 71 msg[0].flags = client->flags | I2C_M_STOP; 72 msg[0].len = 1; 73 msg[0].buf = (char *) ® 74 75 msg[1].addr = client->addr; 76 msg[1].flags = client->flags | I2C_M_RD; 77 msg[1].len = len; 78 msg[1].buf = (char *) val; 79 80 ret = i2c_transfer(client->adapter, msg, 2); 81 82 return (ret == 2) ? 0 : -EIO; 83 } 84 85 static int lidar_smbus_xfer(struct lidar_data *data, u8 reg, u8 *val, int len) 86 { 87 struct i2c_client *client = data->client; 88 int ret; 89 90 /* 91 * Device needs a STOP condition between address write, and data read 92 * so in turn i2c_smbus_read_byte_data cannot be used 93 */ 94 95 while (len--) { 96 ret = i2c_smbus_write_byte(client, reg++); 97 if (ret < 0) { 98 dev_err(&client->dev, "cannot write addr value"); 99 return ret; 100 } 101 102 ret = i2c_smbus_read_byte(client); 103 if (ret < 0) { 104 dev_err(&client->dev, "cannot read data value"); 105 return ret; 106 } 107 108 *(val++) = ret; 109 } 110 111 return 0; 112 } 113 114 static int lidar_read_byte(struct lidar_data *data, u8 reg) 115 { 116 int ret; 117 u8 val; 118 119 ret = data->xfer(data, reg, &val, 1); 120 if (ret < 0) 121 return ret; 122 123 return val; 124 } 125 126 static inline int lidar_write_control(struct lidar_data *data, int val) 127 { 128 return i2c_smbus_write_byte_data(data->client, LIDAR_REG_CONTROL, val); 129 } 130 131 static inline int lidar_write_power(struct lidar_data *data, int val) 132 { 133 return i2c_smbus_write_byte_data(data->client, 134 LIDAR_REG_PWR_CONTROL, val); 135 } 136 137 static int lidar_read_measurement(struct lidar_data *data, u16 *reg) 138 { 139 int ret = data->xfer(data, LIDAR_REG_DATA_HBYTE | 140 (data->i2c_enabled ? LIDAR_REG_DATA_WORD_READ : 0), 141 (u8 *) reg, 2); 142 143 if (!ret) 144 *reg = be16_to_cpu(*reg); 145 146 return ret; 147 } 148 149 static int lidar_get_measurement(struct lidar_data *data, u16 *reg) 150 { 151 struct i2c_client *client = data->client; 152 int tries = 10; 153 int ret; 154 155 pm_runtime_get_sync(&client->dev); 156 157 /* start sample */ 158 ret = lidar_write_control(data, LIDAR_REG_CONTROL_ACQUIRE); 159 if (ret < 0) { 160 dev_err(&client->dev, "cannot send start measurement command"); 161 return ret; 162 } 163 164 while (tries--) { 165 usleep_range(1000, 2000); 166 167 ret = lidar_read_byte(data, LIDAR_REG_STATUS); 168 if (ret < 0) 169 break; 170 171 /* return -EINVAL since laser is likely pointed out of range */ 172 if (ret & LIDAR_REG_STATUS_INVALID) { 173 *reg = 0; 174 ret = -EINVAL; 175 break; 176 } 177 178 /* sample ready to read */ 179 if (!(ret & LIDAR_REG_STATUS_READY)) { 180 ret = lidar_read_measurement(data, reg); 181 break; 182 } 183 ret = -EIO; 184 } 185 pm_runtime_mark_last_busy(&client->dev); 186 pm_runtime_put_autosuspend(&client->dev); 187 188 return ret; 189 } 190 191 static int lidar_read_raw(struct iio_dev *indio_dev, 192 struct iio_chan_spec const *chan, 193 int *val, int *val2, long mask) 194 { 195 struct lidar_data *data = iio_priv(indio_dev); 196 int ret = -EINVAL; 197 198 switch (mask) { 199 case IIO_CHAN_INFO_RAW: { 200 u16 reg; 201 202 if (iio_device_claim_direct_mode(indio_dev)) 203 return -EBUSY; 204 205 ret = lidar_get_measurement(data, ®); 206 if (!ret) { 207 *val = reg; 208 ret = IIO_VAL_INT; 209 } 210 iio_device_release_direct_mode(indio_dev); 211 break; 212 } 213 case IIO_CHAN_INFO_SCALE: 214 *val = 0; 215 *val2 = 10000; 216 ret = IIO_VAL_INT_PLUS_MICRO; 217 break; 218 } 219 220 return ret; 221 } 222 223 static irqreturn_t lidar_trigger_handler(int irq, void *private) 224 { 225 struct iio_poll_func *pf = private; 226 struct iio_dev *indio_dev = pf->indio_dev; 227 struct lidar_data *data = iio_priv(indio_dev); 228 int ret; 229 230 ret = lidar_get_measurement(data, data->buffer); 231 if (!ret) { 232 iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, 233 iio_get_time_ns(indio_dev)); 234 } else if (ret != -EINVAL) { 235 dev_err(&data->client->dev, "cannot read LIDAR measurement"); 236 } 237 238 iio_trigger_notify_done(indio_dev->trig); 239 240 return IRQ_HANDLED; 241 } 242 243 static const struct iio_info lidar_info = { 244 .read_raw = lidar_read_raw, 245 }; 246 247 static int lidar_probe(struct i2c_client *client, 248 const struct i2c_device_id *id) 249 { 250 struct lidar_data *data; 251 struct iio_dev *indio_dev; 252 int ret; 253 254 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 255 if (!indio_dev) 256 return -ENOMEM; 257 data = iio_priv(indio_dev); 258 259 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 260 data->xfer = lidar_i2c_xfer; 261 data->i2c_enabled = 1; 262 } else if (i2c_check_functionality(client->adapter, 263 I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE)) 264 data->xfer = lidar_smbus_xfer; 265 else 266 return -EOPNOTSUPP; 267 268 indio_dev->info = &lidar_info; 269 indio_dev->name = LIDAR_DRV_NAME; 270 indio_dev->channels = lidar_channels; 271 indio_dev->num_channels = ARRAY_SIZE(lidar_channels); 272 indio_dev->dev.parent = &client->dev; 273 indio_dev->modes = INDIO_DIRECT_MODE; 274 275 i2c_set_clientdata(client, indio_dev); 276 277 data->client = client; 278 data->indio_dev = indio_dev; 279 280 ret = iio_triggered_buffer_setup(indio_dev, NULL, 281 lidar_trigger_handler, NULL); 282 if (ret) 283 return ret; 284 285 ret = iio_device_register(indio_dev); 286 if (ret) 287 goto error_unreg_buffer; 288 289 pm_runtime_set_autosuspend_delay(&client->dev, 1000); 290 pm_runtime_use_autosuspend(&client->dev); 291 292 ret = pm_runtime_set_active(&client->dev); 293 if (ret) 294 goto error_unreg_buffer; 295 pm_runtime_enable(&client->dev); 296 pm_runtime_idle(&client->dev); 297 298 return 0; 299 300 error_unreg_buffer: 301 iio_triggered_buffer_cleanup(indio_dev); 302 303 return ret; 304 } 305 306 static int lidar_remove(struct i2c_client *client) 307 { 308 struct iio_dev *indio_dev = i2c_get_clientdata(client); 309 310 iio_device_unregister(indio_dev); 311 iio_triggered_buffer_cleanup(indio_dev); 312 313 pm_runtime_disable(&client->dev); 314 pm_runtime_set_suspended(&client->dev); 315 316 return 0; 317 } 318 319 static const struct i2c_device_id lidar_id[] = { 320 {"lidar-lite-v2", 0}, 321 {"lidar-lite-v3", 0}, 322 { }, 323 }; 324 MODULE_DEVICE_TABLE(i2c, lidar_id); 325 326 static const struct of_device_id lidar_dt_ids[] = { 327 { .compatible = "pulsedlight,lidar-lite-v2" }, 328 { .compatible = "grmn,lidar-lite-v3" }, 329 { } 330 }; 331 MODULE_DEVICE_TABLE(of, lidar_dt_ids); 332 333 #ifdef CONFIG_PM 334 static int lidar_pm_runtime_suspend(struct device *dev) 335 { 336 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 337 struct lidar_data *data = iio_priv(indio_dev); 338 339 return lidar_write_power(data, 0x0f); 340 } 341 342 static int lidar_pm_runtime_resume(struct device *dev) 343 { 344 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 345 struct lidar_data *data = iio_priv(indio_dev); 346 int ret = lidar_write_power(data, 0); 347 348 /* regulator and FPGA needs settling time */ 349 usleep_range(15000, 20000); 350 351 return ret; 352 } 353 #endif 354 355 static const struct dev_pm_ops lidar_pm_ops = { 356 SET_RUNTIME_PM_OPS(lidar_pm_runtime_suspend, 357 lidar_pm_runtime_resume, NULL) 358 }; 359 360 static struct i2c_driver lidar_driver = { 361 .driver = { 362 .name = LIDAR_DRV_NAME, 363 .of_match_table = of_match_ptr(lidar_dt_ids), 364 .pm = &lidar_pm_ops, 365 }, 366 .probe = lidar_probe, 367 .remove = lidar_remove, 368 .id_table = lidar_id, 369 }; 370 module_i2c_driver(lidar_driver); 371 372 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 373 MODULE_DESCRIPTION("PulsedLight LIDAR sensor"); 374 MODULE_LICENSE("GPL"); 375