1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * rfd77402.c - Support for RF Digital RFD77402 Time-of-Flight (distance) sensor 4 * 5 * Copyright 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> 6 * 7 * 7-bit I2C slave address 0x4c 8 * 9 * https://media.digikey.com/pdf/Data%20Sheets/RF%20Digital%20PDFs/RFD77402.pdf 10 */ 11 12 #include <linux/bits.h> 13 #include <linux/completion.h> 14 #include <linux/delay.h> 15 #include <linux/dev_printk.h> 16 #include <linux/errno.h> 17 #include <linux/i2c.h> 18 #include <linux/interrupt.h> 19 #include <linux/iopoll.h> 20 #include <linux/jiffies.h> 21 #include <linux/module.h> 22 #include <linux/types.h> 23 24 #include <linux/iio/iio.h> 25 26 #define RFD77402_DRV_NAME "rfd77402" 27 28 #define RFD77402_ICSR 0x00 /* Interrupt Control Status Register */ 29 #define RFD77402_ICSR_CLR_CFG BIT(0) 30 #define RFD77402_ICSR_CLR_TYPE BIT(1) 31 #define RFD77402_ICSR_INT_MODE BIT(2) 32 #define RFD77402_ICSR_INT_POL BIT(3) 33 #define RFD77402_ICSR_RESULT BIT(4) 34 #define RFD77402_ICSR_M2H_MSG BIT(5) 35 #define RFD77402_ICSR_H2M_MSG BIT(6) 36 #define RFD77402_ICSR_RESET BIT(7) 37 38 #define RFD77402_IER 0x02 39 #define RFD77402_IER_RESULT BIT(0) 40 #define RFD77402_IER_M2H_MSG BIT(1) 41 #define RFD77402_IER_H2M_MSG BIT(2) 42 #define RFD77402_IER_RESET BIT(3) 43 44 #define RFD77402_CMD_R 0x04 45 #define RFD77402_CMD_SINGLE 0x01 46 #define RFD77402_CMD_STANDBY 0x10 47 #define RFD77402_CMD_MCPU_OFF 0x11 48 #define RFD77402_CMD_MCPU_ON 0x12 49 #define RFD77402_CMD_RESET BIT(6) 50 #define RFD77402_CMD_VALID BIT(7) 51 52 #define RFD77402_STATUS_R 0x06 53 #define RFD77402_STATUS_PM_MASK GENMASK(4, 0) 54 #define RFD77402_STATUS_STANDBY 0x00 55 #define RFD77402_STATUS_MCPU_OFF 0x10 56 #define RFD77402_STATUS_MCPU_ON 0x18 57 58 #define RFD77402_RESULT_R 0x08 59 #define RFD77402_RESULT_DIST_MASK GENMASK(12, 2) 60 #define RFD77402_RESULT_ERR_MASK GENMASK(14, 13) 61 #define RFD77402_RESULT_VALID BIT(15) 62 63 #define RFD77402_PMU_CFG 0x14 64 #define RFD77402_PMU_MCPU_INIT BIT(9) 65 66 #define RFD77402_I2C_INIT_CFG 0x1c 67 #define RFD77402_I2C_ADDR_INCR BIT(0) 68 #define RFD77402_I2C_DATA_INCR BIT(2) 69 #define RFD77402_I2C_HOST_DEBUG BIT(5) 70 #define RFD77402_I2C_MCPU_DEBUG BIT(6) 71 72 #define RFD77402_CMD_CFGR_A 0x0c 73 #define RFD77402_CMD_CFGR_B 0x0e 74 #define RFD77402_HFCFG_0 0x20 75 #define RFD77402_HFCFG_1 0x22 76 #define RFD77402_HFCFG_2 0x24 77 #define RFD77402_HFCFG_3 0x26 78 79 #define RFD77402_MOD_CHIP_ID 0x28 80 81 /* magic configuration values from datasheet */ 82 static const struct { 83 u8 reg; 84 u16 val; 85 } rf77402_tof_config[] = { 86 {RFD77402_CMD_CFGR_A, 0xe100}, 87 {RFD77402_CMD_CFGR_B, 0x10ff}, 88 {RFD77402_HFCFG_0, 0x07d0}, 89 {RFD77402_HFCFG_1, 0x5008}, 90 {RFD77402_HFCFG_2, 0xa041}, 91 {RFD77402_HFCFG_3, 0x45d4}, 92 }; 93 94 /** 95 * struct rfd77402_data - device-specific data for the RFD77402 sensor 96 * @client: I2C client handle 97 * @lock: mutex to serialize sensor reads 98 * @completion: completion used for interrupt-driven measurements 99 * @irq_en: indicates whether interrupt mode is enabled 100 */ 101 struct rfd77402_data { 102 struct i2c_client *client; 103 struct mutex lock; 104 struct completion completion; 105 bool irq_en; 106 }; 107 108 static const struct iio_chan_spec rfd77402_channels[] = { 109 { 110 .type = IIO_DISTANCE, 111 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 112 BIT(IIO_CHAN_INFO_SCALE), 113 }, 114 }; 115 116 static irqreturn_t rfd77402_interrupt_handler(int irq, void *pdata) 117 { 118 struct rfd77402_data *data = pdata; 119 int ret; 120 121 ret = i2c_smbus_read_byte_data(data->client, RFD77402_ICSR); 122 if (ret < 0) 123 return IRQ_NONE; 124 125 /* Check if the interrupt is from our device */ 126 if (!(ret & RFD77402_ICSR_RESULT)) 127 return IRQ_NONE; 128 129 /* Signal completion of measurement */ 130 complete(&data->completion); 131 return IRQ_HANDLED; 132 } 133 134 static int rfd77402_wait_for_irq(struct rfd77402_data *data) 135 { 136 int ret; 137 138 /* 139 * According to RFD77402 Datasheet v1.8, 140 * Section 3.1.1 "Single Measure" (Figure: Single Measure Flow Chart), 141 * the suggested timeout for single measure is 100 ms. 142 */ 143 ret = wait_for_completion_timeout(&data->completion, 144 msecs_to_jiffies(100)); 145 if (ret == 0) 146 return -ETIMEDOUT; 147 148 return 0; 149 } 150 151 static int rfd77402_set_state(struct i2c_client *client, u8 state, u16 check) 152 { 153 int ret; 154 155 ret = i2c_smbus_write_byte_data(client, RFD77402_CMD_R, 156 state | RFD77402_CMD_VALID); 157 if (ret < 0) 158 return ret; 159 160 usleep_range(10000, 20000); 161 162 ret = i2c_smbus_read_word_data(client, RFD77402_STATUS_R); 163 if (ret < 0) 164 return ret; 165 if ((ret & RFD77402_STATUS_PM_MASK) != check) 166 return -ENODEV; 167 168 return 0; 169 } 170 171 static int rfd77402_wait_for_result(struct rfd77402_data *data) 172 { 173 struct i2c_client *client = data->client; 174 int val, ret; 175 176 if (data->irq_en) { 177 reinit_completion(&data->completion); 178 return rfd77402_wait_for_irq(data); 179 } 180 181 /* 182 * As per RFD77402 datasheet section '3.1.1 Single Measure', the 183 * suggested timeout value for single measure is 100ms. 184 */ 185 ret = read_poll_timeout(i2c_smbus_read_byte_data, val, 186 (val < 0) || (val & RFD77402_ICSR_RESULT), 187 10 * USEC_PER_MSEC, 188 10 * 10 * USEC_PER_MSEC, 189 false, 190 client, RFD77402_ICSR); 191 if (val < 0) 192 return val; 193 194 return ret; 195 } 196 197 static int rfd77402_measure(struct rfd77402_data *data) 198 { 199 struct i2c_client *client = data->client; 200 int ret; 201 202 ret = rfd77402_set_state(client, RFD77402_CMD_MCPU_ON, 203 RFD77402_STATUS_MCPU_ON); 204 if (ret < 0) 205 return ret; 206 207 ret = i2c_smbus_write_byte_data(client, RFD77402_CMD_R, 208 RFD77402_CMD_SINGLE | 209 RFD77402_CMD_VALID); 210 if (ret < 0) 211 goto err; 212 213 ret = rfd77402_wait_for_result(data); 214 if (ret < 0) 215 goto err; 216 217 ret = i2c_smbus_read_word_data(client, RFD77402_RESULT_R); 218 if (ret < 0) 219 goto err; 220 221 if ((ret & RFD77402_RESULT_ERR_MASK) || 222 !(ret & RFD77402_RESULT_VALID)) { 223 ret = -EIO; 224 goto err; 225 } 226 227 return (ret & RFD77402_RESULT_DIST_MASK) >> 2; 228 229 err: 230 rfd77402_set_state(client, RFD77402_CMD_MCPU_OFF, 231 RFD77402_STATUS_MCPU_OFF); 232 return ret; 233 } 234 235 static int rfd77402_read_raw(struct iio_dev *indio_dev, 236 struct iio_chan_spec const *chan, 237 int *val, int *val2, long mask) 238 { 239 struct rfd77402_data *data = iio_priv(indio_dev); 240 int ret; 241 242 switch (mask) { 243 case IIO_CHAN_INFO_RAW: 244 mutex_lock(&data->lock); 245 ret = rfd77402_measure(data); 246 mutex_unlock(&data->lock); 247 if (ret < 0) 248 return ret; 249 *val = ret; 250 return IIO_VAL_INT; 251 case IIO_CHAN_INFO_SCALE: 252 /* 1 LSB is 1 mm */ 253 *val = 0; 254 *val2 = 1000; 255 return IIO_VAL_INT_PLUS_MICRO; 256 default: 257 return -EINVAL; 258 } 259 } 260 261 static const struct iio_info rfd77402_info = { 262 .read_raw = rfd77402_read_raw, 263 }; 264 265 static int rfd77402_config_irq(struct i2c_client *client, u8 csr, u8 ier) 266 { 267 int ret; 268 269 ret = i2c_smbus_write_byte_data(client, RFD77402_ICSR, csr); 270 if (ret) 271 return ret; 272 273 return i2c_smbus_write_byte_data(client, RFD77402_IER, ier); 274 } 275 276 static int rfd77402_init(struct rfd77402_data *data) 277 { 278 struct i2c_client *client = data->client; 279 int ret, i; 280 281 ret = rfd77402_set_state(client, RFD77402_CMD_STANDBY, 282 RFD77402_STATUS_STANDBY); 283 if (ret < 0) 284 return ret; 285 286 if (data->irq_en) { 287 /* 288 * Enable interrupt mode: 289 * - Configure ICSR for auto-clear on read and 290 * push-pull output 291 * - Enable "result ready" interrupt in IER 292 */ 293 ret = rfd77402_config_irq(client, 294 RFD77402_ICSR_CLR_CFG | 295 RFD77402_ICSR_INT_MODE, 296 RFD77402_IER_RESULT); 297 } else { 298 /* 299 * Disable all interrupts: 300 * - Clear ICSR configuration 301 * - Disable all interrupts in IER 302 */ 303 ret = rfd77402_config_irq(client, 0, 0); 304 } 305 if (ret) 306 return ret; 307 308 /* I2C configuration */ 309 ret = i2c_smbus_write_word_data(client, RFD77402_I2C_INIT_CFG, 310 RFD77402_I2C_ADDR_INCR | 311 RFD77402_I2C_DATA_INCR | 312 RFD77402_I2C_HOST_DEBUG | 313 RFD77402_I2C_MCPU_DEBUG); 314 if (ret < 0) 315 return ret; 316 317 /* set initialization */ 318 ret = i2c_smbus_write_word_data(client, RFD77402_PMU_CFG, 0x0500); 319 if (ret < 0) 320 return ret; 321 322 ret = rfd77402_set_state(client, RFD77402_CMD_MCPU_OFF, 323 RFD77402_STATUS_MCPU_OFF); 324 if (ret < 0) 325 return ret; 326 327 /* set initialization */ 328 ret = i2c_smbus_write_word_data(client, RFD77402_PMU_CFG, 0x0600); 329 if (ret < 0) 330 return ret; 331 332 ret = rfd77402_set_state(client, RFD77402_CMD_MCPU_ON, 333 RFD77402_STATUS_MCPU_ON); 334 if (ret < 0) 335 return ret; 336 337 for (i = 0; i < ARRAY_SIZE(rf77402_tof_config); i++) { 338 ret = i2c_smbus_write_word_data(client, 339 rf77402_tof_config[i].reg, 340 rf77402_tof_config[i].val); 341 if (ret < 0) 342 return ret; 343 } 344 345 ret = rfd77402_set_state(client, RFD77402_CMD_STANDBY, 346 RFD77402_STATUS_STANDBY); 347 348 return ret; 349 } 350 351 static int rfd77402_powerdown(struct i2c_client *client) 352 { 353 return rfd77402_set_state(client, RFD77402_CMD_STANDBY, 354 RFD77402_STATUS_STANDBY); 355 } 356 357 static void rfd77402_disable(void *client) 358 { 359 rfd77402_powerdown(client); 360 } 361 362 static int rfd77402_probe(struct i2c_client *client) 363 { 364 struct rfd77402_data *data; 365 struct iio_dev *indio_dev; 366 int ret; 367 368 ret = i2c_smbus_read_word_data(client, RFD77402_MOD_CHIP_ID); 369 if (ret < 0) 370 return ret; 371 if (ret != 0xad01 && ret != 0xad02) /* known chip ids */ 372 return -ENODEV; 373 374 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 375 if (!indio_dev) 376 return -ENOMEM; 377 378 data = iio_priv(indio_dev); 379 data->client = client; 380 381 ret = devm_mutex_init(&client->dev, &data->lock); 382 if (ret) 383 return ret; 384 385 init_completion(&data->completion); 386 387 if (client->irq > 0) { 388 ret = devm_request_threaded_irq(&client->dev, client->irq, 389 NULL, rfd77402_interrupt_handler, 390 IRQF_ONESHOT, 391 "rfd77402", data); 392 if (ret) 393 return ret; 394 395 data->irq_en = true; 396 dev_dbg(&client->dev, "Using interrupt mode\n"); 397 } else { 398 dev_dbg(&client->dev, "Using polling mode\n"); 399 } 400 401 indio_dev->info = &rfd77402_info; 402 indio_dev->channels = rfd77402_channels; 403 indio_dev->num_channels = ARRAY_SIZE(rfd77402_channels); 404 indio_dev->name = RFD77402_DRV_NAME; 405 indio_dev->modes = INDIO_DIRECT_MODE; 406 407 ret = rfd77402_init(data); 408 if (ret < 0) 409 return ret; 410 411 ret = devm_add_action_or_reset(&client->dev, rfd77402_disable, client); 412 if (ret) 413 return ret; 414 415 return devm_iio_device_register(&client->dev, indio_dev); 416 } 417 418 static int rfd77402_suspend(struct device *dev) 419 { 420 return rfd77402_powerdown(to_i2c_client(dev)); 421 } 422 423 static int rfd77402_resume(struct device *dev) 424 { 425 struct iio_dev *indio_dev = dev_get_drvdata(dev); 426 struct rfd77402_data *data = iio_priv(indio_dev); 427 428 return rfd77402_init(data); 429 } 430 431 static DEFINE_SIMPLE_DEV_PM_OPS(rfd77402_pm_ops, rfd77402_suspend, 432 rfd77402_resume); 433 434 static const struct i2c_device_id rfd77402_id[] = { 435 { "rfd77402" }, 436 { } 437 }; 438 MODULE_DEVICE_TABLE(i2c, rfd77402_id); 439 440 static const struct of_device_id rfd77402_of_match[] = { 441 { .compatible = "rfdigital,rfd77402" }, 442 { } 443 }; 444 MODULE_DEVICE_TABLE(of, rfd77402_of_match); 445 446 static struct i2c_driver rfd77402_driver = { 447 .driver = { 448 .name = RFD77402_DRV_NAME, 449 .pm = pm_sleep_ptr(&rfd77402_pm_ops), 450 .of_match_table = rfd77402_of_match, 451 }, 452 .probe = rfd77402_probe, 453 .id_table = rfd77402_id, 454 }; 455 456 module_i2c_driver(rfd77402_driver); 457 458 MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>"); 459 MODULE_DESCRIPTION("RFD77402 Time-of-Flight sensor driver"); 460 MODULE_LICENSE("GPL"); 461