18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * rfd77402.c - Support for RF Digital RFD77402 Time-of-Flight (distance) sensor 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * 7-bit I2C slave address 0x4c 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * TODO: interrupt 108c2ecf20Sopenharmony_ci * https://media.digikey.com/pdf/Data%20Sheets/RF%20Digital%20PDFs/RFD77402.pdf 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/i2c.h> 158c2ecf20Sopenharmony_ci#include <linux/delay.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define RFD77402_DRV_NAME "rfd77402" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define RFD77402_ICSR 0x00 /* Interrupt Control Status Register */ 228c2ecf20Sopenharmony_ci#define RFD77402_ICSR_INT_MODE BIT(2) 238c2ecf20Sopenharmony_ci#define RFD77402_ICSR_INT_POL BIT(3) 248c2ecf20Sopenharmony_ci#define RFD77402_ICSR_RESULT BIT(4) 258c2ecf20Sopenharmony_ci#define RFD77402_ICSR_M2H_MSG BIT(5) 268c2ecf20Sopenharmony_ci#define RFD77402_ICSR_H2M_MSG BIT(6) 278c2ecf20Sopenharmony_ci#define RFD77402_ICSR_RESET BIT(7) 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define RFD77402_CMD_R 0x04 308c2ecf20Sopenharmony_ci#define RFD77402_CMD_SINGLE 0x01 318c2ecf20Sopenharmony_ci#define RFD77402_CMD_STANDBY 0x10 328c2ecf20Sopenharmony_ci#define RFD77402_CMD_MCPU_OFF 0x11 338c2ecf20Sopenharmony_ci#define RFD77402_CMD_MCPU_ON 0x12 348c2ecf20Sopenharmony_ci#define RFD77402_CMD_RESET BIT(6) 358c2ecf20Sopenharmony_ci#define RFD77402_CMD_VALID BIT(7) 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define RFD77402_STATUS_R 0x06 388c2ecf20Sopenharmony_ci#define RFD77402_STATUS_PM_MASK GENMASK(4, 0) 398c2ecf20Sopenharmony_ci#define RFD77402_STATUS_STANDBY 0x00 408c2ecf20Sopenharmony_ci#define RFD77402_STATUS_MCPU_OFF 0x10 418c2ecf20Sopenharmony_ci#define RFD77402_STATUS_MCPU_ON 0x18 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define RFD77402_RESULT_R 0x08 448c2ecf20Sopenharmony_ci#define RFD77402_RESULT_DIST_MASK GENMASK(12, 2) 458c2ecf20Sopenharmony_ci#define RFD77402_RESULT_ERR_MASK GENMASK(14, 13) 468c2ecf20Sopenharmony_ci#define RFD77402_RESULT_VALID BIT(15) 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#define RFD77402_PMU_CFG 0x14 498c2ecf20Sopenharmony_ci#define RFD77402_PMU_MCPU_INIT BIT(9) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define RFD77402_I2C_INIT_CFG 0x1c 528c2ecf20Sopenharmony_ci#define RFD77402_I2C_ADDR_INCR BIT(0) 538c2ecf20Sopenharmony_ci#define RFD77402_I2C_DATA_INCR BIT(2) 548c2ecf20Sopenharmony_ci#define RFD77402_I2C_HOST_DEBUG BIT(5) 558c2ecf20Sopenharmony_ci#define RFD77402_I2C_MCPU_DEBUG BIT(6) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#define RFD77402_CMD_CFGR_A 0x0c 588c2ecf20Sopenharmony_ci#define RFD77402_CMD_CFGR_B 0x0e 598c2ecf20Sopenharmony_ci#define RFD77402_HFCFG_0 0x20 608c2ecf20Sopenharmony_ci#define RFD77402_HFCFG_1 0x22 618c2ecf20Sopenharmony_ci#define RFD77402_HFCFG_2 0x24 628c2ecf20Sopenharmony_ci#define RFD77402_HFCFG_3 0x26 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define RFD77402_MOD_CHIP_ID 0x28 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* magic configuration values from datasheet */ 678c2ecf20Sopenharmony_cistatic const struct { 688c2ecf20Sopenharmony_ci u8 reg; 698c2ecf20Sopenharmony_ci u16 val; 708c2ecf20Sopenharmony_ci} rf77402_tof_config[] = { 718c2ecf20Sopenharmony_ci {RFD77402_CMD_CFGR_A, 0xe100}, 728c2ecf20Sopenharmony_ci {RFD77402_CMD_CFGR_B, 0x10ff}, 738c2ecf20Sopenharmony_ci {RFD77402_HFCFG_0, 0x07d0}, 748c2ecf20Sopenharmony_ci {RFD77402_HFCFG_1, 0x5008}, 758c2ecf20Sopenharmony_ci {RFD77402_HFCFG_2, 0xa041}, 768c2ecf20Sopenharmony_ci {RFD77402_HFCFG_3, 0x45d4}, 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistruct rfd77402_data { 808c2ecf20Sopenharmony_ci struct i2c_client *client; 818c2ecf20Sopenharmony_ci /* Serialize reads from the sensor */ 828c2ecf20Sopenharmony_ci struct mutex lock; 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic const struct iio_chan_spec rfd77402_channels[] = { 868c2ecf20Sopenharmony_ci { 878c2ecf20Sopenharmony_ci .type = IIO_DISTANCE, 888c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 898c2ecf20Sopenharmony_ci BIT(IIO_CHAN_INFO_SCALE), 908c2ecf20Sopenharmony_ci }, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic int rfd77402_set_state(struct rfd77402_data *data, u8 state, u16 check) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci int ret; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(data->client, RFD77402_CMD_R, 988c2ecf20Sopenharmony_ci state | RFD77402_CMD_VALID); 998c2ecf20Sopenharmony_ci if (ret < 0) 1008c2ecf20Sopenharmony_ci return ret; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci usleep_range(10000, 20000); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci ret = i2c_smbus_read_word_data(data->client, RFD77402_STATUS_R); 1058c2ecf20Sopenharmony_ci if (ret < 0) 1068c2ecf20Sopenharmony_ci return ret; 1078c2ecf20Sopenharmony_ci if ((ret & RFD77402_STATUS_PM_MASK) != check) 1088c2ecf20Sopenharmony_ci return -ENODEV; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci return 0; 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic int rfd77402_measure(struct rfd77402_data *data) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci int ret; 1168c2ecf20Sopenharmony_ci int tries = 10; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_ON, 1198c2ecf20Sopenharmony_ci RFD77402_STATUS_MCPU_ON); 1208c2ecf20Sopenharmony_ci if (ret < 0) 1218c2ecf20Sopenharmony_ci return ret; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(data->client, RFD77402_CMD_R, 1248c2ecf20Sopenharmony_ci RFD77402_CMD_SINGLE | 1258c2ecf20Sopenharmony_ci RFD77402_CMD_VALID); 1268c2ecf20Sopenharmony_ci if (ret < 0) 1278c2ecf20Sopenharmony_ci goto err; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci while (tries-- > 0) { 1308c2ecf20Sopenharmony_ci ret = i2c_smbus_read_byte_data(data->client, RFD77402_ICSR); 1318c2ecf20Sopenharmony_ci if (ret < 0) 1328c2ecf20Sopenharmony_ci goto err; 1338c2ecf20Sopenharmony_ci if (ret & RFD77402_ICSR_RESULT) 1348c2ecf20Sopenharmony_ci break; 1358c2ecf20Sopenharmony_ci msleep(20); 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci if (tries < 0) { 1398c2ecf20Sopenharmony_ci ret = -ETIMEDOUT; 1408c2ecf20Sopenharmony_ci goto err; 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci ret = i2c_smbus_read_word_data(data->client, RFD77402_RESULT_R); 1448c2ecf20Sopenharmony_ci if (ret < 0) 1458c2ecf20Sopenharmony_ci goto err; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci if ((ret & RFD77402_RESULT_ERR_MASK) || 1488c2ecf20Sopenharmony_ci !(ret & RFD77402_RESULT_VALID)) { 1498c2ecf20Sopenharmony_ci ret = -EIO; 1508c2ecf20Sopenharmony_ci goto err; 1518c2ecf20Sopenharmony_ci } 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci return (ret & RFD77402_RESULT_DIST_MASK) >> 2; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cierr: 1568c2ecf20Sopenharmony_ci rfd77402_set_state(data, RFD77402_CMD_MCPU_OFF, 1578c2ecf20Sopenharmony_ci RFD77402_STATUS_MCPU_OFF); 1588c2ecf20Sopenharmony_ci return ret; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic int rfd77402_read_raw(struct iio_dev *indio_dev, 1628c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 1638c2ecf20Sopenharmony_ci int *val, int *val2, long mask) 1648c2ecf20Sopenharmony_ci{ 1658c2ecf20Sopenharmony_ci struct rfd77402_data *data = iio_priv(indio_dev); 1668c2ecf20Sopenharmony_ci int ret; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci switch (mask) { 1698c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 1708c2ecf20Sopenharmony_ci mutex_lock(&data->lock); 1718c2ecf20Sopenharmony_ci ret = rfd77402_measure(data); 1728c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1738c2ecf20Sopenharmony_ci if (ret < 0) 1748c2ecf20Sopenharmony_ci return ret; 1758c2ecf20Sopenharmony_ci *val = ret; 1768c2ecf20Sopenharmony_ci return IIO_VAL_INT; 1778c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_SCALE: 1788c2ecf20Sopenharmony_ci /* 1 LSB is 1 mm */ 1798c2ecf20Sopenharmony_ci *val = 0; 1808c2ecf20Sopenharmony_ci *val2 = 1000; 1818c2ecf20Sopenharmony_ci return IIO_VAL_INT_PLUS_MICRO; 1828c2ecf20Sopenharmony_ci default: 1838c2ecf20Sopenharmony_ci return -EINVAL; 1848c2ecf20Sopenharmony_ci } 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic const struct iio_info rfd77402_info = { 1888c2ecf20Sopenharmony_ci .read_raw = rfd77402_read_raw, 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistatic int rfd77402_init(struct rfd77402_data *data) 1928c2ecf20Sopenharmony_ci{ 1938c2ecf20Sopenharmony_ci int ret, i; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci ret = rfd77402_set_state(data, RFD77402_CMD_STANDBY, 1968c2ecf20Sopenharmony_ci RFD77402_STATUS_STANDBY); 1978c2ecf20Sopenharmony_ci if (ret < 0) 1988c2ecf20Sopenharmony_ci return ret; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* configure INT pad as push-pull, active low */ 2018c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(data->client, RFD77402_ICSR, 2028c2ecf20Sopenharmony_ci RFD77402_ICSR_INT_MODE); 2038c2ecf20Sopenharmony_ci if (ret < 0) 2048c2ecf20Sopenharmony_ci return ret; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci /* I2C configuration */ 2078c2ecf20Sopenharmony_ci ret = i2c_smbus_write_word_data(data->client, RFD77402_I2C_INIT_CFG, 2088c2ecf20Sopenharmony_ci RFD77402_I2C_ADDR_INCR | 2098c2ecf20Sopenharmony_ci RFD77402_I2C_DATA_INCR | 2108c2ecf20Sopenharmony_ci RFD77402_I2C_HOST_DEBUG | 2118c2ecf20Sopenharmony_ci RFD77402_I2C_MCPU_DEBUG); 2128c2ecf20Sopenharmony_ci if (ret < 0) 2138c2ecf20Sopenharmony_ci return ret; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci /* set initialization */ 2168c2ecf20Sopenharmony_ci ret = i2c_smbus_write_word_data(data->client, RFD77402_PMU_CFG, 0x0500); 2178c2ecf20Sopenharmony_ci if (ret < 0) 2188c2ecf20Sopenharmony_ci return ret; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_OFF, 2218c2ecf20Sopenharmony_ci RFD77402_STATUS_MCPU_OFF); 2228c2ecf20Sopenharmony_ci if (ret < 0) 2238c2ecf20Sopenharmony_ci return ret; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci /* set initialization */ 2268c2ecf20Sopenharmony_ci ret = i2c_smbus_write_word_data(data->client, RFD77402_PMU_CFG, 0x0600); 2278c2ecf20Sopenharmony_ci if (ret < 0) 2288c2ecf20Sopenharmony_ci return ret; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_ON, 2318c2ecf20Sopenharmony_ci RFD77402_STATUS_MCPU_ON); 2328c2ecf20Sopenharmony_ci if (ret < 0) 2338c2ecf20Sopenharmony_ci return ret; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rf77402_tof_config); i++) { 2368c2ecf20Sopenharmony_ci ret = i2c_smbus_write_word_data(data->client, 2378c2ecf20Sopenharmony_ci rf77402_tof_config[i].reg, 2388c2ecf20Sopenharmony_ci rf77402_tof_config[i].val); 2398c2ecf20Sopenharmony_ci if (ret < 0) 2408c2ecf20Sopenharmony_ci return ret; 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci ret = rfd77402_set_state(data, RFD77402_CMD_STANDBY, 2448c2ecf20Sopenharmony_ci RFD77402_STATUS_STANDBY); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci return ret; 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic int rfd77402_powerdown(struct rfd77402_data *data) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci return rfd77402_set_state(data, RFD77402_CMD_STANDBY, 2528c2ecf20Sopenharmony_ci RFD77402_STATUS_STANDBY); 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cistatic int rfd77402_probe(struct i2c_client *client, 2568c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 2578c2ecf20Sopenharmony_ci{ 2588c2ecf20Sopenharmony_ci struct rfd77402_data *data; 2598c2ecf20Sopenharmony_ci struct iio_dev *indio_dev; 2608c2ecf20Sopenharmony_ci int ret; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci ret = i2c_smbus_read_word_data(client, RFD77402_MOD_CHIP_ID); 2638c2ecf20Sopenharmony_ci if (ret < 0) 2648c2ecf20Sopenharmony_ci return ret; 2658c2ecf20Sopenharmony_ci if (ret != 0xad01 && ret != 0xad02) /* known chip ids */ 2668c2ecf20Sopenharmony_ci return -ENODEV; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 2698c2ecf20Sopenharmony_ci if (!indio_dev) 2708c2ecf20Sopenharmony_ci return -ENOMEM; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci data = iio_priv(indio_dev); 2738c2ecf20Sopenharmony_ci i2c_set_clientdata(client, indio_dev); 2748c2ecf20Sopenharmony_ci data->client = client; 2758c2ecf20Sopenharmony_ci mutex_init(&data->lock); 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci indio_dev->info = &rfd77402_info; 2788c2ecf20Sopenharmony_ci indio_dev->channels = rfd77402_channels; 2798c2ecf20Sopenharmony_ci indio_dev->num_channels = ARRAY_SIZE(rfd77402_channels); 2808c2ecf20Sopenharmony_ci indio_dev->name = RFD77402_DRV_NAME; 2818c2ecf20Sopenharmony_ci indio_dev->modes = INDIO_DIRECT_MODE; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci ret = rfd77402_init(data); 2848c2ecf20Sopenharmony_ci if (ret < 0) 2858c2ecf20Sopenharmony_ci return ret; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci ret = iio_device_register(indio_dev); 2888c2ecf20Sopenharmony_ci if (ret) 2898c2ecf20Sopenharmony_ci goto err_powerdown; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci return 0; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_cierr_powerdown: 2948c2ecf20Sopenharmony_ci rfd77402_powerdown(data); 2958c2ecf20Sopenharmony_ci return ret; 2968c2ecf20Sopenharmony_ci} 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_cistatic int rfd77402_remove(struct i2c_client *client) 2998c2ecf20Sopenharmony_ci{ 3008c2ecf20Sopenharmony_ci struct iio_dev *indio_dev = i2c_get_clientdata(client); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci iio_device_unregister(indio_dev); 3038c2ecf20Sopenharmony_ci rfd77402_powerdown(iio_priv(indio_dev)); 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci return 0; 3068c2ecf20Sopenharmony_ci} 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 3098c2ecf20Sopenharmony_cistatic int rfd77402_suspend(struct device *dev) 3108c2ecf20Sopenharmony_ci{ 3118c2ecf20Sopenharmony_ci struct rfd77402_data *data = iio_priv(i2c_get_clientdata( 3128c2ecf20Sopenharmony_ci to_i2c_client(dev))); 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci return rfd77402_powerdown(data); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic int rfd77402_resume(struct device *dev) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci struct rfd77402_data *data = iio_priv(i2c_get_clientdata( 3208c2ecf20Sopenharmony_ci to_i2c_client(dev))); 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci return rfd77402_init(data); 3238c2ecf20Sopenharmony_ci} 3248c2ecf20Sopenharmony_ci#endif 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(rfd77402_pm_ops, rfd77402_suspend, rfd77402_resume); 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_cistatic const struct i2c_device_id rfd77402_id[] = { 3298c2ecf20Sopenharmony_ci { "rfd77402", 0}, 3308c2ecf20Sopenharmony_ci { } 3318c2ecf20Sopenharmony_ci}; 3328c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, rfd77402_id); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistatic struct i2c_driver rfd77402_driver = { 3358c2ecf20Sopenharmony_ci .driver = { 3368c2ecf20Sopenharmony_ci .name = RFD77402_DRV_NAME, 3378c2ecf20Sopenharmony_ci .pm = &rfd77402_pm_ops, 3388c2ecf20Sopenharmony_ci }, 3398c2ecf20Sopenharmony_ci .probe = rfd77402_probe, 3408c2ecf20Sopenharmony_ci .remove = rfd77402_remove, 3418c2ecf20Sopenharmony_ci .id_table = rfd77402_id, 3428c2ecf20Sopenharmony_ci}; 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_cimodule_i2c_driver(rfd77402_driver); 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ciMODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>"); 3478c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("RFD77402 Time-of-Flight sensor driver"); 3488c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 349