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 return rfd77402_wait_for_irq(data); 178 179 /* 180 * As per RFD77402 datasheet section '3.1.1 Single Measure', the 181 * suggested timeout value for single measure is 100ms. 182 */ 183 ret = read_poll_timeout(i2c_smbus_read_byte_data, val, 184 (val < 0) || (val & RFD77402_ICSR_RESULT), 185 10 * USEC_PER_MSEC, 186 10 * 10 * USEC_PER_MSEC, 187 false, 188 client, RFD77402_ICSR); 189 if (val < 0) 190 return val; 191 192 return ret; 193 } 194 195 static int rfd77402_measure(struct rfd77402_data *data) 196 { 197 struct i2c_client *client = data->client; 198 int ret; 199 200 ret = rfd77402_set_state(client, RFD77402_CMD_MCPU_ON, 201 RFD77402_STATUS_MCPU_ON); 202 if (ret < 0) 203 return ret; 204 205 if (data->irq_en) 206 reinit_completion(&data->completion); 207 208 ret = i2c_smbus_write_byte_data(client, RFD77402_CMD_R, 209 RFD77402_CMD_SINGLE | 210 RFD77402_CMD_VALID); 211 if (ret < 0) 212 goto err; 213 214 ret = rfd77402_wait_for_result(data); 215 if (ret < 0) 216 goto err; 217 218 ret = i2c_smbus_read_word_data(client, RFD77402_RESULT_R); 219 if (ret < 0) 220 goto err; 221 222 if ((ret & RFD77402_RESULT_ERR_MASK) || 223 !(ret & RFD77402_RESULT_VALID)) { 224 ret = -EIO; 225 goto err; 226 } 227 228 return (ret & RFD77402_RESULT_DIST_MASK) >> 2; 229 230 err: 231 rfd77402_set_state(client, RFD77402_CMD_MCPU_OFF, 232 RFD77402_STATUS_MCPU_OFF); 233 return ret; 234 } 235 236 static int rfd77402_read_raw(struct iio_dev *indio_dev, 237 struct iio_chan_spec const *chan, 238 int *val, int *val2, long mask) 239 { 240 struct rfd77402_data *data = iio_priv(indio_dev); 241 int ret; 242 243 switch (mask) { 244 case IIO_CHAN_INFO_RAW: 245 mutex_lock(&data->lock); 246 ret = rfd77402_measure(data); 247 mutex_unlock(&data->lock); 248 if (ret < 0) 249 return ret; 250 *val = ret; 251 return IIO_VAL_INT; 252 case IIO_CHAN_INFO_SCALE: 253 /* 1 LSB is 1 mm */ 254 *val = 0; 255 *val2 = 1000; 256 return IIO_VAL_INT_PLUS_MICRO; 257 default: 258 return -EINVAL; 259 } 260 } 261 262 static const struct iio_info rfd77402_info = { 263 .read_raw = rfd77402_read_raw, 264 }; 265 266 static int rfd77402_config_irq(struct i2c_client *client, u8 csr, u8 ier) 267 { 268 int ret; 269 270 ret = i2c_smbus_write_byte_data(client, RFD77402_ICSR, csr); 271 if (ret) 272 return ret; 273 274 return i2c_smbus_write_byte_data(client, RFD77402_IER, ier); 275 } 276 277 static int rfd77402_init(struct rfd77402_data *data) 278 { 279 struct i2c_client *client = data->client; 280 int ret, i; 281 282 ret = rfd77402_set_state(client, RFD77402_CMD_STANDBY, 283 RFD77402_STATUS_STANDBY); 284 if (ret < 0) 285 return ret; 286 287 if (data->irq_en) { 288 /* 289 * Enable interrupt mode: 290 * - Configure ICSR for auto-clear on read and 291 * push-pull output 292 * - Enable "result ready" interrupt in IER 293 */ 294 ret = rfd77402_config_irq(client, 295 RFD77402_ICSR_CLR_CFG | 296 RFD77402_ICSR_INT_MODE, 297 RFD77402_IER_RESULT); 298 } else { 299 /* 300 * Disable all interrupts: 301 * - Clear ICSR configuration 302 * - Disable all interrupts in IER 303 */ 304 ret = rfd77402_config_irq(client, 0, 0); 305 } 306 if (ret) 307 return ret; 308 309 /* I2C configuration */ 310 ret = i2c_smbus_write_word_data(client, RFD77402_I2C_INIT_CFG, 311 RFD77402_I2C_ADDR_INCR | 312 RFD77402_I2C_DATA_INCR | 313 RFD77402_I2C_HOST_DEBUG | 314 RFD77402_I2C_MCPU_DEBUG); 315 if (ret < 0) 316 return ret; 317 318 /* set initialization */ 319 ret = i2c_smbus_write_word_data(client, RFD77402_PMU_CFG, 0x0500); 320 if (ret < 0) 321 return ret; 322 323 ret = rfd77402_set_state(client, RFD77402_CMD_MCPU_OFF, 324 RFD77402_STATUS_MCPU_OFF); 325 if (ret < 0) 326 return ret; 327 328 /* set initialization */ 329 ret = i2c_smbus_write_word_data(client, RFD77402_PMU_CFG, 0x0600); 330 if (ret < 0) 331 return ret; 332 333 ret = rfd77402_set_state(client, RFD77402_CMD_MCPU_ON, 334 RFD77402_STATUS_MCPU_ON); 335 if (ret < 0) 336 return ret; 337 338 for (i = 0; i < ARRAY_SIZE(rf77402_tof_config); i++) { 339 ret = i2c_smbus_write_word_data(client, 340 rf77402_tof_config[i].reg, 341 rf77402_tof_config[i].val); 342 if (ret < 0) 343 return ret; 344 } 345 346 ret = rfd77402_set_state(client, RFD77402_CMD_STANDBY, 347 RFD77402_STATUS_STANDBY); 348 349 return ret; 350 } 351 352 static int rfd77402_powerdown(struct i2c_client *client) 353 { 354 return rfd77402_set_state(client, RFD77402_CMD_STANDBY, 355 RFD77402_STATUS_STANDBY); 356 } 357 358 static void rfd77402_disable(void *client) 359 { 360 rfd77402_powerdown(client); 361 } 362 363 static int rfd77402_probe(struct i2c_client *client) 364 { 365 struct rfd77402_data *data; 366 struct iio_dev *indio_dev; 367 int ret; 368 369 ret = i2c_smbus_read_word_data(client, RFD77402_MOD_CHIP_ID); 370 if (ret < 0) 371 return ret; 372 if (ret != 0xad01 && ret != 0xad02) /* known chip ids */ 373 return -ENODEV; 374 375 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 376 if (!indio_dev) 377 return -ENOMEM; 378 379 data = iio_priv(indio_dev); 380 data->client = client; 381 382 ret = devm_mutex_init(&client->dev, &data->lock); 383 if (ret) 384 return ret; 385 386 init_completion(&data->completion); 387 388 if (client->irq > 0) { 389 ret = devm_request_threaded_irq(&client->dev, client->irq, 390 NULL, rfd77402_interrupt_handler, 391 IRQF_ONESHOT, 392 "rfd77402", data); 393 if (ret) 394 return ret; 395 396 data->irq_en = true; 397 dev_dbg(&client->dev, "Using interrupt mode\n"); 398 } else { 399 dev_dbg(&client->dev, "Using polling mode\n"); 400 } 401 402 indio_dev->info = &rfd77402_info; 403 indio_dev->channels = rfd77402_channels; 404 indio_dev->num_channels = ARRAY_SIZE(rfd77402_channels); 405 indio_dev->name = RFD77402_DRV_NAME; 406 indio_dev->modes = INDIO_DIRECT_MODE; 407 408 ret = rfd77402_init(data); 409 if (ret < 0) 410 return ret; 411 412 ret = devm_add_action_or_reset(&client->dev, rfd77402_disable, client); 413 if (ret) 414 return ret; 415 416 return devm_iio_device_register(&client->dev, indio_dev); 417 } 418 419 static int rfd77402_suspend(struct device *dev) 420 { 421 return rfd77402_powerdown(to_i2c_client(dev)); 422 } 423 424 static int rfd77402_resume(struct device *dev) 425 { 426 struct iio_dev *indio_dev = dev_get_drvdata(dev); 427 struct rfd77402_data *data = iio_priv(indio_dev); 428 429 return rfd77402_init(data); 430 } 431 432 static DEFINE_SIMPLE_DEV_PM_OPS(rfd77402_pm_ops, rfd77402_suspend, 433 rfd77402_resume); 434 435 static const struct i2c_device_id rfd77402_id[] = { 436 { "rfd77402" }, 437 { } 438 }; 439 MODULE_DEVICE_TABLE(i2c, rfd77402_id); 440 441 static const struct of_device_id rfd77402_of_match[] = { 442 { .compatible = "rfdigital,rfd77402" }, 443 { } 444 }; 445 MODULE_DEVICE_TABLE(of, rfd77402_of_match); 446 447 static struct i2c_driver rfd77402_driver = { 448 .driver = { 449 .name = RFD77402_DRV_NAME, 450 .pm = pm_sleep_ptr(&rfd77402_pm_ops), 451 .of_match_table = rfd77402_of_match, 452 }, 453 .probe = rfd77402_probe, 454 .id_table = rfd77402_id, 455 }; 456 457 module_i2c_driver(rfd77402_driver); 458 459 MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>"); 460 MODULE_DESCRIPTION("RFD77402 Time-of-Flight sensor driver"); 461 MODULE_LICENSE("GPL"); 462