1*79e64188SPeter Meerwald-Stadler /* 2*79e64188SPeter Meerwald-Stadler * rfd77402.c - Support for RF Digital RFD77402 Time-of-Flight (distance) sensor 3*79e64188SPeter Meerwald-Stadler * 4*79e64188SPeter Meerwald-Stadler * Copyright 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> 5*79e64188SPeter Meerwald-Stadler * 6*79e64188SPeter Meerwald-Stadler * This file is subject to the terms and conditions of version 2 of 7*79e64188SPeter Meerwald-Stadler * the GNU General Public License. See the file COPYING in the main 8*79e64188SPeter Meerwald-Stadler * directory of this archive for more details. 9*79e64188SPeter Meerwald-Stadler * 10*79e64188SPeter Meerwald-Stadler * 7-bit I2C slave address 0x4c 11*79e64188SPeter Meerwald-Stadler * 12*79e64188SPeter Meerwald-Stadler * TODO: interrupt 13*79e64188SPeter Meerwald-Stadler * https://media.digikey.com/pdf/Data%20Sheets/RF%20Digital%20PDFs/RFD77402.pdf 14*79e64188SPeter Meerwald-Stadler */ 15*79e64188SPeter Meerwald-Stadler 16*79e64188SPeter Meerwald-Stadler #include <linux/module.h> 17*79e64188SPeter Meerwald-Stadler #include <linux/i2c.h> 18*79e64188SPeter Meerwald-Stadler #include <linux/delay.h> 19*79e64188SPeter Meerwald-Stadler 20*79e64188SPeter Meerwald-Stadler #include <linux/iio/iio.h> 21*79e64188SPeter Meerwald-Stadler 22*79e64188SPeter Meerwald-Stadler #define RFD77402_DRV_NAME "rfd77402" 23*79e64188SPeter Meerwald-Stadler 24*79e64188SPeter Meerwald-Stadler #define RFD77402_ICSR 0x00 /* Interrupt Control Status Register */ 25*79e64188SPeter Meerwald-Stadler #define RFD77402_ICSR_INT_MODE BIT(2) 26*79e64188SPeter Meerwald-Stadler #define RFD77402_ICSR_INT_POL BIT(3) 27*79e64188SPeter Meerwald-Stadler #define RFD77402_ICSR_RESULT BIT(4) 28*79e64188SPeter Meerwald-Stadler #define RFD77402_ICSR_M2H_MSG BIT(5) 29*79e64188SPeter Meerwald-Stadler #define RFD77402_ICSR_H2M_MSG BIT(6) 30*79e64188SPeter Meerwald-Stadler #define RFD77402_ICSR_RESET BIT(7) 31*79e64188SPeter Meerwald-Stadler 32*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_R 0x04 33*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_SINGLE 0x01 34*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_STANDBY 0x10 35*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_MCPU_OFF 0x11 36*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_MCPU_ON 0x12 37*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_RESET BIT(6) 38*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_VALID BIT(7) 39*79e64188SPeter Meerwald-Stadler 40*79e64188SPeter Meerwald-Stadler #define RFD77402_STATUS_R 0x06 41*79e64188SPeter Meerwald-Stadler #define RFD77402_STATUS_PM_MASK GENMASK(4, 0) 42*79e64188SPeter Meerwald-Stadler #define RFD77402_STATUS_STANDBY 0x00 43*79e64188SPeter Meerwald-Stadler #define RFD77402_STATUS_MCPU_OFF 0x10 44*79e64188SPeter Meerwald-Stadler #define RFD77402_STATUS_MCPU_ON 0x18 45*79e64188SPeter Meerwald-Stadler 46*79e64188SPeter Meerwald-Stadler #define RFD77402_RESULT_R 0x08 47*79e64188SPeter Meerwald-Stadler #define RFD77402_RESULT_DIST_MASK GENMASK(12, 2) 48*79e64188SPeter Meerwald-Stadler #define RFD77402_RESULT_ERR_MASK GENMASK(14, 13) 49*79e64188SPeter Meerwald-Stadler #define RFD77402_RESULT_VALID BIT(15) 50*79e64188SPeter Meerwald-Stadler 51*79e64188SPeter Meerwald-Stadler #define RFD77402_PMU_CFG 0x14 52*79e64188SPeter Meerwald-Stadler #define RFD77402_PMU_MCPU_INIT BIT(9) 53*79e64188SPeter Meerwald-Stadler 54*79e64188SPeter Meerwald-Stadler #define RFD77402_I2C_INIT_CFG 0x1c 55*79e64188SPeter Meerwald-Stadler #define RFD77402_I2C_ADDR_INCR BIT(0) 56*79e64188SPeter Meerwald-Stadler #define RFD77402_I2C_DATA_INCR BIT(2) 57*79e64188SPeter Meerwald-Stadler #define RFD77402_I2C_HOST_DEBUG BIT(5) 58*79e64188SPeter Meerwald-Stadler #define RFD77402_I2C_MCPU_DEBUG BIT(6) 59*79e64188SPeter Meerwald-Stadler 60*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_CFGR_A 0x0c 61*79e64188SPeter Meerwald-Stadler #define RFD77402_CMD_CFGR_B 0x0e 62*79e64188SPeter Meerwald-Stadler #define RFD77402_HFCFG_0 0x20 63*79e64188SPeter Meerwald-Stadler #define RFD77402_HFCFG_1 0x22 64*79e64188SPeter Meerwald-Stadler #define RFD77402_HFCFG_2 0x24 65*79e64188SPeter Meerwald-Stadler #define RFD77402_HFCFG_3 0x26 66*79e64188SPeter Meerwald-Stadler 67*79e64188SPeter Meerwald-Stadler #define RFD77402_MOD_CHIP_ID 0x28 68*79e64188SPeter Meerwald-Stadler 69*79e64188SPeter Meerwald-Stadler /* magic configuration values from datasheet */ 70*79e64188SPeter Meerwald-Stadler static const struct { 71*79e64188SPeter Meerwald-Stadler u8 reg; 72*79e64188SPeter Meerwald-Stadler u16 val; 73*79e64188SPeter Meerwald-Stadler } rf77402_tof_config[] = { 74*79e64188SPeter Meerwald-Stadler {RFD77402_CMD_CFGR_A, 0xe100}, 75*79e64188SPeter Meerwald-Stadler {RFD77402_CMD_CFGR_B, 0x10ff}, 76*79e64188SPeter Meerwald-Stadler {RFD77402_HFCFG_0, 0x07d0}, 77*79e64188SPeter Meerwald-Stadler {RFD77402_HFCFG_1, 0x5008}, 78*79e64188SPeter Meerwald-Stadler {RFD77402_HFCFG_2, 0xa041}, 79*79e64188SPeter Meerwald-Stadler {RFD77402_HFCFG_3, 0x45d4}, 80*79e64188SPeter Meerwald-Stadler }; 81*79e64188SPeter Meerwald-Stadler 82*79e64188SPeter Meerwald-Stadler struct rfd77402_data { 83*79e64188SPeter Meerwald-Stadler struct i2c_client *client; 84*79e64188SPeter Meerwald-Stadler /* Serialize reads from the sensor */ 85*79e64188SPeter Meerwald-Stadler struct mutex lock; 86*79e64188SPeter Meerwald-Stadler }; 87*79e64188SPeter Meerwald-Stadler 88*79e64188SPeter Meerwald-Stadler static const struct iio_chan_spec rfd77402_channels[] = { 89*79e64188SPeter Meerwald-Stadler { 90*79e64188SPeter Meerwald-Stadler .type = IIO_DISTANCE, 91*79e64188SPeter Meerwald-Stadler .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 92*79e64188SPeter Meerwald-Stadler BIT(IIO_CHAN_INFO_SCALE), 93*79e64188SPeter Meerwald-Stadler }, 94*79e64188SPeter Meerwald-Stadler }; 95*79e64188SPeter Meerwald-Stadler 96*79e64188SPeter Meerwald-Stadler static int rfd77402_set_state(struct rfd77402_data *data, u8 state, u16 check) 97*79e64188SPeter Meerwald-Stadler { 98*79e64188SPeter Meerwald-Stadler int ret; 99*79e64188SPeter Meerwald-Stadler 100*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_write_byte_data(data->client, RFD77402_CMD_R, 101*79e64188SPeter Meerwald-Stadler state | RFD77402_CMD_VALID); 102*79e64188SPeter Meerwald-Stadler if (ret < 0) 103*79e64188SPeter Meerwald-Stadler return ret; 104*79e64188SPeter Meerwald-Stadler 105*79e64188SPeter Meerwald-Stadler usleep_range(10000, 20000); 106*79e64188SPeter Meerwald-Stadler 107*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_read_word_data(data->client, RFD77402_STATUS_R); 108*79e64188SPeter Meerwald-Stadler if (ret < 0) 109*79e64188SPeter Meerwald-Stadler return ret; 110*79e64188SPeter Meerwald-Stadler if ((ret & RFD77402_STATUS_PM_MASK) != check) 111*79e64188SPeter Meerwald-Stadler return -ENODEV; 112*79e64188SPeter Meerwald-Stadler 113*79e64188SPeter Meerwald-Stadler return 0; 114*79e64188SPeter Meerwald-Stadler } 115*79e64188SPeter Meerwald-Stadler 116*79e64188SPeter Meerwald-Stadler static int rfd77402_measure(struct rfd77402_data *data) 117*79e64188SPeter Meerwald-Stadler { 118*79e64188SPeter Meerwald-Stadler int ret; 119*79e64188SPeter Meerwald-Stadler int tries = 10; 120*79e64188SPeter Meerwald-Stadler 121*79e64188SPeter Meerwald-Stadler ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_ON, 122*79e64188SPeter Meerwald-Stadler RFD77402_STATUS_MCPU_ON); 123*79e64188SPeter Meerwald-Stadler if (ret < 0) 124*79e64188SPeter Meerwald-Stadler return ret; 125*79e64188SPeter Meerwald-Stadler 126*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_write_byte_data(data->client, RFD77402_CMD_R, 127*79e64188SPeter Meerwald-Stadler RFD77402_CMD_SINGLE | 128*79e64188SPeter Meerwald-Stadler RFD77402_CMD_VALID); 129*79e64188SPeter Meerwald-Stadler if (ret < 0) 130*79e64188SPeter Meerwald-Stadler goto err; 131*79e64188SPeter Meerwald-Stadler 132*79e64188SPeter Meerwald-Stadler while (tries-- > 0) { 133*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_read_byte_data(data->client, RFD77402_ICSR); 134*79e64188SPeter Meerwald-Stadler if (ret < 0) 135*79e64188SPeter Meerwald-Stadler goto err; 136*79e64188SPeter Meerwald-Stadler if (ret & RFD77402_ICSR_RESULT) 137*79e64188SPeter Meerwald-Stadler break; 138*79e64188SPeter Meerwald-Stadler msleep(20); 139*79e64188SPeter Meerwald-Stadler } 140*79e64188SPeter Meerwald-Stadler 141*79e64188SPeter Meerwald-Stadler if (tries < 0) { 142*79e64188SPeter Meerwald-Stadler ret = -ETIMEDOUT; 143*79e64188SPeter Meerwald-Stadler goto err; 144*79e64188SPeter Meerwald-Stadler } 145*79e64188SPeter Meerwald-Stadler 146*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_read_word_data(data->client, RFD77402_RESULT_R); 147*79e64188SPeter Meerwald-Stadler if (ret < 0) 148*79e64188SPeter Meerwald-Stadler goto err; 149*79e64188SPeter Meerwald-Stadler 150*79e64188SPeter Meerwald-Stadler if ((ret & RFD77402_RESULT_ERR_MASK) || 151*79e64188SPeter Meerwald-Stadler !(ret & RFD77402_RESULT_VALID)) { 152*79e64188SPeter Meerwald-Stadler ret = -EIO; 153*79e64188SPeter Meerwald-Stadler goto err; 154*79e64188SPeter Meerwald-Stadler } 155*79e64188SPeter Meerwald-Stadler 156*79e64188SPeter Meerwald-Stadler return (ret & RFD77402_RESULT_DIST_MASK) >> 2; 157*79e64188SPeter Meerwald-Stadler 158*79e64188SPeter Meerwald-Stadler err: 159*79e64188SPeter Meerwald-Stadler rfd77402_set_state(data, RFD77402_CMD_MCPU_OFF, 160*79e64188SPeter Meerwald-Stadler RFD77402_STATUS_MCPU_OFF); 161*79e64188SPeter Meerwald-Stadler return ret; 162*79e64188SPeter Meerwald-Stadler } 163*79e64188SPeter Meerwald-Stadler 164*79e64188SPeter Meerwald-Stadler static int rfd77402_read_raw(struct iio_dev *indio_dev, 165*79e64188SPeter Meerwald-Stadler struct iio_chan_spec const *chan, 166*79e64188SPeter Meerwald-Stadler int *val, int *val2, long mask) 167*79e64188SPeter Meerwald-Stadler { 168*79e64188SPeter Meerwald-Stadler struct rfd77402_data *data = iio_priv(indio_dev); 169*79e64188SPeter Meerwald-Stadler int ret; 170*79e64188SPeter Meerwald-Stadler 171*79e64188SPeter Meerwald-Stadler switch (mask) { 172*79e64188SPeter Meerwald-Stadler case IIO_CHAN_INFO_RAW: 173*79e64188SPeter Meerwald-Stadler mutex_lock(&data->lock); 174*79e64188SPeter Meerwald-Stadler ret = rfd77402_measure(data); 175*79e64188SPeter Meerwald-Stadler mutex_unlock(&data->lock); 176*79e64188SPeter Meerwald-Stadler if (ret < 0) 177*79e64188SPeter Meerwald-Stadler return ret; 178*79e64188SPeter Meerwald-Stadler *val = ret; 179*79e64188SPeter Meerwald-Stadler return IIO_VAL_INT; 180*79e64188SPeter Meerwald-Stadler case IIO_CHAN_INFO_SCALE: 181*79e64188SPeter Meerwald-Stadler /* 1 LSB is 1 mm */ 182*79e64188SPeter Meerwald-Stadler *val = 0; 183*79e64188SPeter Meerwald-Stadler *val2 = 1000; 184*79e64188SPeter Meerwald-Stadler return IIO_VAL_INT_PLUS_MICRO; 185*79e64188SPeter Meerwald-Stadler default: 186*79e64188SPeter Meerwald-Stadler return -EINVAL; 187*79e64188SPeter Meerwald-Stadler } 188*79e64188SPeter Meerwald-Stadler } 189*79e64188SPeter Meerwald-Stadler 190*79e64188SPeter Meerwald-Stadler static const struct iio_info rfd77402_info = { 191*79e64188SPeter Meerwald-Stadler .read_raw = rfd77402_read_raw, 192*79e64188SPeter Meerwald-Stadler }; 193*79e64188SPeter Meerwald-Stadler 194*79e64188SPeter Meerwald-Stadler static int rfd77402_init(struct rfd77402_data *data) 195*79e64188SPeter Meerwald-Stadler { 196*79e64188SPeter Meerwald-Stadler int ret, i; 197*79e64188SPeter Meerwald-Stadler 198*79e64188SPeter Meerwald-Stadler ret = rfd77402_set_state(data, RFD77402_CMD_STANDBY, 199*79e64188SPeter Meerwald-Stadler RFD77402_STATUS_STANDBY); 200*79e64188SPeter Meerwald-Stadler if (ret < 0) 201*79e64188SPeter Meerwald-Stadler return ret; 202*79e64188SPeter Meerwald-Stadler 203*79e64188SPeter Meerwald-Stadler /* configure INT pad as push-pull, active low */ 204*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_write_byte_data(data->client, RFD77402_ICSR, 205*79e64188SPeter Meerwald-Stadler RFD77402_ICSR_INT_MODE); 206*79e64188SPeter Meerwald-Stadler if (ret < 0) 207*79e64188SPeter Meerwald-Stadler return ret; 208*79e64188SPeter Meerwald-Stadler 209*79e64188SPeter Meerwald-Stadler /* I2C configuration */ 210*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_write_word_data(data->client, RFD77402_I2C_INIT_CFG, 211*79e64188SPeter Meerwald-Stadler RFD77402_I2C_ADDR_INCR | 212*79e64188SPeter Meerwald-Stadler RFD77402_I2C_DATA_INCR | 213*79e64188SPeter Meerwald-Stadler RFD77402_I2C_HOST_DEBUG | 214*79e64188SPeter Meerwald-Stadler RFD77402_I2C_MCPU_DEBUG); 215*79e64188SPeter Meerwald-Stadler if (ret < 0) 216*79e64188SPeter Meerwald-Stadler return ret; 217*79e64188SPeter Meerwald-Stadler 218*79e64188SPeter Meerwald-Stadler /* set initialization */ 219*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_write_word_data(data->client, RFD77402_PMU_CFG, 0x0500); 220*79e64188SPeter Meerwald-Stadler if (ret < 0) 221*79e64188SPeter Meerwald-Stadler return ret; 222*79e64188SPeter Meerwald-Stadler 223*79e64188SPeter Meerwald-Stadler ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_OFF, 224*79e64188SPeter Meerwald-Stadler RFD77402_STATUS_MCPU_OFF); 225*79e64188SPeter Meerwald-Stadler if (ret < 0) 226*79e64188SPeter Meerwald-Stadler return ret; 227*79e64188SPeter Meerwald-Stadler 228*79e64188SPeter Meerwald-Stadler /* set initialization */ 229*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_write_word_data(data->client, RFD77402_PMU_CFG, 0x0600); 230*79e64188SPeter Meerwald-Stadler if (ret < 0) 231*79e64188SPeter Meerwald-Stadler return ret; 232*79e64188SPeter Meerwald-Stadler 233*79e64188SPeter Meerwald-Stadler ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_ON, 234*79e64188SPeter Meerwald-Stadler RFD77402_STATUS_MCPU_ON); 235*79e64188SPeter Meerwald-Stadler if (ret < 0) 236*79e64188SPeter Meerwald-Stadler return ret; 237*79e64188SPeter Meerwald-Stadler 238*79e64188SPeter Meerwald-Stadler for (i = 0; i < ARRAY_SIZE(rf77402_tof_config); i++) { 239*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_write_word_data(data->client, 240*79e64188SPeter Meerwald-Stadler rf77402_tof_config[i].reg, 241*79e64188SPeter Meerwald-Stadler rf77402_tof_config[i].val); 242*79e64188SPeter Meerwald-Stadler if (ret < 0) 243*79e64188SPeter Meerwald-Stadler return ret; 244*79e64188SPeter Meerwald-Stadler } 245*79e64188SPeter Meerwald-Stadler 246*79e64188SPeter Meerwald-Stadler ret = rfd77402_set_state(data, RFD77402_CMD_STANDBY, 247*79e64188SPeter Meerwald-Stadler RFD77402_STATUS_STANDBY); 248*79e64188SPeter Meerwald-Stadler 249*79e64188SPeter Meerwald-Stadler return ret; 250*79e64188SPeter Meerwald-Stadler } 251*79e64188SPeter Meerwald-Stadler 252*79e64188SPeter Meerwald-Stadler static int rfd77402_powerdown(struct rfd77402_data *data) 253*79e64188SPeter Meerwald-Stadler { 254*79e64188SPeter Meerwald-Stadler return rfd77402_set_state(data, RFD77402_CMD_STANDBY, 255*79e64188SPeter Meerwald-Stadler RFD77402_STATUS_STANDBY); 256*79e64188SPeter Meerwald-Stadler } 257*79e64188SPeter Meerwald-Stadler 258*79e64188SPeter Meerwald-Stadler static int rfd77402_probe(struct i2c_client *client, 259*79e64188SPeter Meerwald-Stadler const struct i2c_device_id *id) 260*79e64188SPeter Meerwald-Stadler { 261*79e64188SPeter Meerwald-Stadler struct rfd77402_data *data; 262*79e64188SPeter Meerwald-Stadler struct iio_dev *indio_dev; 263*79e64188SPeter Meerwald-Stadler int ret; 264*79e64188SPeter Meerwald-Stadler 265*79e64188SPeter Meerwald-Stadler ret = i2c_smbus_read_word_data(client, RFD77402_MOD_CHIP_ID); 266*79e64188SPeter Meerwald-Stadler if (ret < 0) 267*79e64188SPeter Meerwald-Stadler return ret; 268*79e64188SPeter Meerwald-Stadler if (ret != 0xad01 && ret != 0xad02) /* known chip ids */ 269*79e64188SPeter Meerwald-Stadler return -ENODEV; 270*79e64188SPeter Meerwald-Stadler 271*79e64188SPeter Meerwald-Stadler indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 272*79e64188SPeter Meerwald-Stadler if (!indio_dev) 273*79e64188SPeter Meerwald-Stadler return -ENOMEM; 274*79e64188SPeter Meerwald-Stadler 275*79e64188SPeter Meerwald-Stadler data = iio_priv(indio_dev); 276*79e64188SPeter Meerwald-Stadler i2c_set_clientdata(client, indio_dev); 277*79e64188SPeter Meerwald-Stadler data->client = client; 278*79e64188SPeter Meerwald-Stadler mutex_init(&data->lock); 279*79e64188SPeter Meerwald-Stadler 280*79e64188SPeter Meerwald-Stadler indio_dev->dev.parent = &client->dev; 281*79e64188SPeter Meerwald-Stadler indio_dev->info = &rfd77402_info; 282*79e64188SPeter Meerwald-Stadler indio_dev->channels = rfd77402_channels; 283*79e64188SPeter Meerwald-Stadler indio_dev->num_channels = ARRAY_SIZE(rfd77402_channels); 284*79e64188SPeter Meerwald-Stadler indio_dev->name = RFD77402_DRV_NAME; 285*79e64188SPeter Meerwald-Stadler indio_dev->modes = INDIO_DIRECT_MODE; 286*79e64188SPeter Meerwald-Stadler 287*79e64188SPeter Meerwald-Stadler ret = rfd77402_init(data); 288*79e64188SPeter Meerwald-Stadler if (ret < 0) 289*79e64188SPeter Meerwald-Stadler return ret; 290*79e64188SPeter Meerwald-Stadler 291*79e64188SPeter Meerwald-Stadler ret = iio_device_register(indio_dev); 292*79e64188SPeter Meerwald-Stadler if (ret) 293*79e64188SPeter Meerwald-Stadler goto err_powerdown; 294*79e64188SPeter Meerwald-Stadler 295*79e64188SPeter Meerwald-Stadler return 0; 296*79e64188SPeter Meerwald-Stadler 297*79e64188SPeter Meerwald-Stadler err_powerdown: 298*79e64188SPeter Meerwald-Stadler rfd77402_powerdown(data); 299*79e64188SPeter Meerwald-Stadler return ret; 300*79e64188SPeter Meerwald-Stadler } 301*79e64188SPeter Meerwald-Stadler 302*79e64188SPeter Meerwald-Stadler static int rfd77402_remove(struct i2c_client *client) 303*79e64188SPeter Meerwald-Stadler { 304*79e64188SPeter Meerwald-Stadler struct iio_dev *indio_dev = i2c_get_clientdata(client); 305*79e64188SPeter Meerwald-Stadler 306*79e64188SPeter Meerwald-Stadler iio_device_unregister(indio_dev); 307*79e64188SPeter Meerwald-Stadler rfd77402_powerdown(iio_priv(indio_dev)); 308*79e64188SPeter Meerwald-Stadler 309*79e64188SPeter Meerwald-Stadler return 0; 310*79e64188SPeter Meerwald-Stadler } 311*79e64188SPeter Meerwald-Stadler 312*79e64188SPeter Meerwald-Stadler #ifdef CONFIG_PM_SLEEP 313*79e64188SPeter Meerwald-Stadler static int rfd77402_suspend(struct device *dev) 314*79e64188SPeter Meerwald-Stadler { 315*79e64188SPeter Meerwald-Stadler struct rfd77402_data *data = iio_priv(i2c_get_clientdata( 316*79e64188SPeter Meerwald-Stadler to_i2c_client(dev))); 317*79e64188SPeter Meerwald-Stadler 318*79e64188SPeter Meerwald-Stadler return rfd77402_powerdown(data); 319*79e64188SPeter Meerwald-Stadler } 320*79e64188SPeter Meerwald-Stadler 321*79e64188SPeter Meerwald-Stadler static int rfd77402_resume(struct device *dev) 322*79e64188SPeter Meerwald-Stadler { 323*79e64188SPeter Meerwald-Stadler struct rfd77402_data *data = iio_priv(i2c_get_clientdata( 324*79e64188SPeter Meerwald-Stadler to_i2c_client(dev))); 325*79e64188SPeter Meerwald-Stadler 326*79e64188SPeter Meerwald-Stadler return rfd77402_init(data); 327*79e64188SPeter Meerwald-Stadler } 328*79e64188SPeter Meerwald-Stadler #endif 329*79e64188SPeter Meerwald-Stadler 330*79e64188SPeter Meerwald-Stadler static SIMPLE_DEV_PM_OPS(rfd77402_pm_ops, rfd77402_suspend, rfd77402_resume); 331*79e64188SPeter Meerwald-Stadler 332*79e64188SPeter Meerwald-Stadler static const struct i2c_device_id rfd77402_id[] = { 333*79e64188SPeter Meerwald-Stadler { "rfd77402", 0}, 334*79e64188SPeter Meerwald-Stadler { } 335*79e64188SPeter Meerwald-Stadler }; 336*79e64188SPeter Meerwald-Stadler MODULE_DEVICE_TABLE(i2c, rfd77402_id); 337*79e64188SPeter Meerwald-Stadler 338*79e64188SPeter Meerwald-Stadler static struct i2c_driver rfd77402_driver = { 339*79e64188SPeter Meerwald-Stadler .driver = { 340*79e64188SPeter Meerwald-Stadler .name = RFD77402_DRV_NAME, 341*79e64188SPeter Meerwald-Stadler .pm = &rfd77402_pm_ops, 342*79e64188SPeter Meerwald-Stadler }, 343*79e64188SPeter Meerwald-Stadler .probe = rfd77402_probe, 344*79e64188SPeter Meerwald-Stadler .remove = rfd77402_remove, 345*79e64188SPeter Meerwald-Stadler .id_table = rfd77402_id, 346*79e64188SPeter Meerwald-Stadler }; 347*79e64188SPeter Meerwald-Stadler 348*79e64188SPeter Meerwald-Stadler module_i2c_driver(rfd77402_driver); 349*79e64188SPeter Meerwald-Stadler 350*79e64188SPeter Meerwald-Stadler MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>"); 351*79e64188SPeter Meerwald-Stadler MODULE_DESCRIPTION("RFD77402 Time-of-Flight sensor driver"); 352*79e64188SPeter Meerwald-Stadler MODULE_LICENSE("GPL"); 353