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