1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * hdc3020.c - Support for the TI HDC3020,HDC3021 and HDC3022 4 * temperature + relative humidity sensors 5 * 6 * Copyright (C) 2023 7 * 8 * Copyright (C) 2024 Liebherr-Electronics and Drives GmbH 9 * 10 * Datasheet: https://www.ti.com/lit/ds/symlink/hdc3020.pdf 11 */ 12 13 #include <linux/bitfield.h> 14 #include <linux/bitops.h> 15 #include <linux/cleanup.h> 16 #include <linux/crc8.h> 17 #include <linux/delay.h> 18 #include <linux/i2c.h> 19 #include <linux/init.h> 20 #include <linux/interrupt.h> 21 #include <linux/module.h> 22 #include <linux/mutex.h> 23 #include <linux/units.h> 24 25 #include <asm/unaligned.h> 26 27 #include <linux/iio/events.h> 28 #include <linux/iio/iio.h> 29 30 #define HDC3020_S_AUTO_10HZ_MOD0 0x2737 31 #define HDC3020_S_STATUS 0x3041 32 #define HDC3020_HEATER_DISABLE 0x3066 33 #define HDC3020_HEATER_ENABLE 0x306D 34 #define HDC3020_HEATER_CONFIG 0x306E 35 #define HDC3020_EXIT_AUTO 0x3093 36 #define HDC3020_S_T_RH_THRESH_LOW 0x6100 37 #define HDC3020_S_T_RH_THRESH_LOW_CLR 0x610B 38 #define HDC3020_S_T_RH_THRESH_HIGH_CLR 0x6116 39 #define HDC3020_S_T_RH_THRESH_HIGH 0x611D 40 #define HDC3020_R_T_RH_AUTO 0xE000 41 #define HDC3020_R_T_LOW_AUTO 0xE002 42 #define HDC3020_R_T_HIGH_AUTO 0xE003 43 #define HDC3020_R_RH_LOW_AUTO 0xE004 44 #define HDC3020_R_RH_HIGH_AUTO 0xE005 45 #define HDC3020_R_T_RH_THRESH_LOW 0xE102 46 #define HDC3020_R_T_RH_THRESH_LOW_CLR 0xE109 47 #define HDC3020_R_T_RH_THRESH_HIGH_CLR 0xE114 48 #define HDC3020_R_T_RH_THRESH_HIGH 0xE11F 49 #define HDC3020_R_STATUS 0xF32D 50 51 #define HDC3020_THRESH_TEMP_MASK GENMASK(8, 0) 52 #define HDC3020_THRESH_TEMP_TRUNC_SHIFT 7 53 #define HDC3020_THRESH_HUM_MASK GENMASK(15, 9) 54 #define HDC3020_THRESH_HUM_TRUNC_SHIFT 9 55 56 #define HDC3020_STATUS_T_LOW_ALERT BIT(6) 57 #define HDC3020_STATUS_T_HIGH_ALERT BIT(7) 58 #define HDC3020_STATUS_RH_LOW_ALERT BIT(8) 59 #define HDC3020_STATUS_RH_HIGH_ALERT BIT(9) 60 61 #define HDC3020_READ_RETRY_TIMES 10 62 #define HDC3020_BUSY_DELAY_MS 10 63 64 #define HDC3020_CRC8_POLYNOMIAL 0x31 65 66 #define HDC3020_MIN_TEMP -40 67 #define HDC3020_MAX_TEMP 125 68 69 struct hdc3020_data { 70 struct i2c_client *client; 71 /* 72 * Ensure that the sensor configuration (currently only heater is 73 * supported) will not be changed during the process of reading 74 * sensor data (this driver will try HDC3020_READ_RETRY_TIMES times 75 * if the device does not respond). 76 */ 77 struct mutex lock; 78 }; 79 80 static const int hdc3020_heater_vals[] = {0, 1, 0x3FFF}; 81 82 static const struct iio_event_spec hdc3020_t_rh_event[] = { 83 { 84 .type = IIO_EV_TYPE_THRESH, 85 .dir = IIO_EV_DIR_RISING, 86 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 87 BIT(IIO_EV_INFO_HYSTERESIS), 88 }, 89 { 90 .type = IIO_EV_TYPE_THRESH, 91 .dir = IIO_EV_DIR_FALLING, 92 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 93 BIT(IIO_EV_INFO_HYSTERESIS), 94 }, 95 }; 96 97 static const struct iio_chan_spec hdc3020_channels[] = { 98 { 99 .type = IIO_TEMP, 100 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 101 BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_PEAK) | 102 BIT(IIO_CHAN_INFO_TROUGH) | BIT(IIO_CHAN_INFO_OFFSET), 103 .event_spec = hdc3020_t_rh_event, 104 .num_event_specs = ARRAY_SIZE(hdc3020_t_rh_event), 105 }, 106 { 107 .type = IIO_HUMIDITYRELATIVE, 108 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 109 BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_PEAK) | 110 BIT(IIO_CHAN_INFO_TROUGH), 111 .event_spec = hdc3020_t_rh_event, 112 .num_event_specs = ARRAY_SIZE(hdc3020_t_rh_event), 113 }, 114 { 115 /* 116 * For setting the internal heater, which can be switched on to 117 * prevent or remove any condensation that may develop when the 118 * ambient environment approaches its dew point temperature. 119 */ 120 .type = IIO_CURRENT, 121 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 122 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW), 123 .output = 1, 124 }, 125 }; 126 127 DECLARE_CRC8_TABLE(hdc3020_crc8_table); 128 129 static int hdc3020_write_bytes(struct hdc3020_data *data, u8 *buf, u8 len) 130 { 131 struct i2c_client *client = data->client; 132 struct i2c_msg msg; 133 int ret, cnt; 134 135 msg.addr = client->addr; 136 msg.flags = 0; 137 msg.buf = buf; 138 msg.len = len; 139 140 /* 141 * During the measurement process, HDC3020 will not return data. 142 * So wait for a while and try again 143 */ 144 for (cnt = 0; cnt < HDC3020_READ_RETRY_TIMES; cnt++) { 145 ret = i2c_transfer(client->adapter, &msg, 1); 146 if (ret == 1) 147 return 0; 148 149 mdelay(HDC3020_BUSY_DELAY_MS); 150 } 151 dev_err(&client->dev, "Could not write sensor command\n"); 152 153 return -ETIMEDOUT; 154 } 155 156 static 157 int hdc3020_read_bytes(struct hdc3020_data *data, u16 reg, u8 *buf, int len) 158 { 159 u8 reg_buf[2]; 160 int ret, cnt; 161 struct i2c_client *client = data->client; 162 struct i2c_msg msg[2] = { 163 [0] = { 164 .addr = client->addr, 165 .flags = 0, 166 .buf = reg_buf, 167 .len = 2, 168 }, 169 [1] = { 170 .addr = client->addr, 171 .flags = I2C_M_RD, 172 .buf = buf, 173 .len = len, 174 }, 175 }; 176 177 put_unaligned_be16(reg, reg_buf); 178 /* 179 * During the measurement process, HDC3020 will not return data. 180 * So wait for a while and try again 181 */ 182 for (cnt = 0; cnt < HDC3020_READ_RETRY_TIMES; cnt++) { 183 ret = i2c_transfer(client->adapter, msg, 2); 184 if (ret == 2) 185 return 0; 186 187 mdelay(HDC3020_BUSY_DELAY_MS); 188 } 189 dev_err(&client->dev, "Could not read sensor data\n"); 190 191 return -ETIMEDOUT; 192 } 193 194 static int hdc3020_read_be16(struct hdc3020_data *data, u16 reg) 195 { 196 u8 crc, buf[3]; 197 int ret; 198 199 ret = hdc3020_read_bytes(data, reg, buf, 3); 200 if (ret < 0) 201 return ret; 202 203 crc = crc8(hdc3020_crc8_table, buf, 2, CRC8_INIT_VALUE); 204 if (crc != buf[2]) 205 return -EINVAL; 206 207 return get_unaligned_be16(buf); 208 } 209 210 static int hdc3020_exec_cmd(struct hdc3020_data *data, u16 reg) 211 { 212 u8 reg_buf[2]; 213 214 put_unaligned_be16(reg, reg_buf); 215 return hdc3020_write_bytes(data, reg_buf, 2); 216 } 217 218 static int hdc3020_read_measurement(struct hdc3020_data *data, 219 enum iio_chan_type type, int *val) 220 { 221 u8 crc, buf[6]; 222 int ret; 223 224 ret = hdc3020_read_bytes(data, HDC3020_R_T_RH_AUTO, buf, 6); 225 if (ret < 0) 226 return ret; 227 228 /* CRC check of the temperature measurement */ 229 crc = crc8(hdc3020_crc8_table, buf, 2, CRC8_INIT_VALUE); 230 if (crc != buf[2]) 231 return -EINVAL; 232 233 /* CRC check of the relative humidity measurement */ 234 crc = crc8(hdc3020_crc8_table, buf + 3, 2, CRC8_INIT_VALUE); 235 if (crc != buf[5]) 236 return -EINVAL; 237 238 if (type == IIO_TEMP) 239 *val = get_unaligned_be16(buf); 240 else if (type == IIO_HUMIDITYRELATIVE) 241 *val = get_unaligned_be16(&buf[3]); 242 else 243 return -EINVAL; 244 245 return 0; 246 } 247 248 static int hdc3020_read_raw(struct iio_dev *indio_dev, 249 struct iio_chan_spec const *chan, int *val, 250 int *val2, long mask) 251 { 252 struct hdc3020_data *data = iio_priv(indio_dev); 253 int ret; 254 255 if (chan->type != IIO_TEMP && chan->type != IIO_HUMIDITYRELATIVE) 256 return -EINVAL; 257 258 switch (mask) { 259 case IIO_CHAN_INFO_RAW: { 260 guard(mutex)(&data->lock); 261 ret = hdc3020_read_measurement(data, chan->type, val); 262 if (ret < 0) 263 return ret; 264 265 return IIO_VAL_INT; 266 } 267 case IIO_CHAN_INFO_PEAK: { 268 guard(mutex)(&data->lock); 269 if (chan->type == IIO_TEMP) 270 ret = hdc3020_read_be16(data, HDC3020_R_T_HIGH_AUTO); 271 else 272 ret = hdc3020_read_be16(data, HDC3020_R_RH_HIGH_AUTO); 273 274 if (ret < 0) 275 return ret; 276 277 *val = ret; 278 return IIO_VAL_INT; 279 } 280 case IIO_CHAN_INFO_TROUGH: { 281 guard(mutex)(&data->lock); 282 if (chan->type == IIO_TEMP) 283 ret = hdc3020_read_be16(data, HDC3020_R_T_LOW_AUTO); 284 else 285 ret = hdc3020_read_be16(data, HDC3020_R_RH_LOW_AUTO); 286 287 if (ret < 0) 288 return ret; 289 290 *val = ret; 291 return IIO_VAL_INT; 292 } 293 case IIO_CHAN_INFO_SCALE: 294 *val2 = 65536; 295 if (chan->type == IIO_TEMP) 296 *val = 175; 297 else 298 *val = 100; 299 return IIO_VAL_FRACTIONAL; 300 301 case IIO_CHAN_INFO_OFFSET: 302 if (chan->type != IIO_TEMP) 303 return -EINVAL; 304 305 *val = -16852; 306 return IIO_VAL_INT; 307 308 default: 309 return -EINVAL; 310 } 311 } 312 313 static int hdc3020_read_available(struct iio_dev *indio_dev, 314 struct iio_chan_spec const *chan, 315 const int **vals, 316 int *type, int *length, long mask) 317 { 318 if (mask != IIO_CHAN_INFO_RAW || chan->type != IIO_CURRENT) 319 return -EINVAL; 320 321 *vals = hdc3020_heater_vals; 322 *type = IIO_VAL_INT; 323 324 return IIO_AVAIL_RANGE; 325 } 326 327 static int hdc3020_update_heater(struct hdc3020_data *data, int val) 328 { 329 u8 buf[5]; 330 int ret; 331 332 if (val < hdc3020_heater_vals[0] || val > hdc3020_heater_vals[2]) 333 return -EINVAL; 334 335 if (!val) 336 hdc3020_exec_cmd(data, HDC3020_HEATER_DISABLE); 337 338 put_unaligned_be16(HDC3020_HEATER_CONFIG, buf); 339 put_unaligned_be16(val & GENMASK(13, 0), &buf[2]); 340 buf[4] = crc8(hdc3020_crc8_table, buf + 2, 2, CRC8_INIT_VALUE); 341 ret = hdc3020_write_bytes(data, buf, 5); 342 if (ret < 0) 343 return ret; 344 345 return hdc3020_exec_cmd(data, HDC3020_HEATER_ENABLE); 346 } 347 348 static int hdc3020_write_raw(struct iio_dev *indio_dev, 349 struct iio_chan_spec const *chan, 350 int val, int val2, long mask) 351 { 352 struct hdc3020_data *data = iio_priv(indio_dev); 353 354 switch (mask) { 355 case IIO_CHAN_INFO_RAW: 356 if (chan->type != IIO_CURRENT) 357 return -EINVAL; 358 359 guard(mutex)(&data->lock); 360 return hdc3020_update_heater(data, val); 361 } 362 363 return -EINVAL; 364 } 365 366 static int hdc3020_write_thresh(struct iio_dev *indio_dev, 367 const struct iio_chan_spec *chan, 368 enum iio_event_type type, 369 enum iio_event_direction dir, 370 enum iio_event_info info, 371 int val, int val2) 372 { 373 struct hdc3020_data *data = iio_priv(indio_dev); 374 u8 buf[5]; 375 u64 tmp; 376 u16 reg; 377 int ret; 378 379 /* Supported temperature range is from –40 to 125 degree celsius */ 380 if (val < HDC3020_MIN_TEMP || val > HDC3020_MAX_TEMP) 381 return -EINVAL; 382 383 /* Select threshold register */ 384 if (info == IIO_EV_INFO_VALUE) { 385 if (dir == IIO_EV_DIR_RISING) 386 reg = HDC3020_S_T_RH_THRESH_HIGH; 387 else 388 reg = HDC3020_S_T_RH_THRESH_LOW; 389 } else { 390 if (dir == IIO_EV_DIR_RISING) 391 reg = HDC3020_S_T_RH_THRESH_HIGH_CLR; 392 else 393 reg = HDC3020_S_T_RH_THRESH_LOW_CLR; 394 } 395 396 guard(mutex)(&data->lock); 397 ret = hdc3020_read_be16(data, reg); 398 if (ret < 0) 399 return ret; 400 401 switch (chan->type) { 402 case IIO_TEMP: 403 /* 404 * Calculate temperature threshold, shift it down to get the 405 * truncated threshold representation in the 9LSBs while keeping 406 * the current humidity threshold in the 7 MSBs. 407 */ 408 tmp = ((u64)(((val + 45) * MICRO) + val2)) * 65535ULL; 409 tmp = div_u64(tmp, MICRO * 175); 410 val = tmp >> HDC3020_THRESH_TEMP_TRUNC_SHIFT; 411 val = FIELD_PREP(HDC3020_THRESH_TEMP_MASK, val); 412 val |= (FIELD_GET(HDC3020_THRESH_HUM_MASK, ret) << 413 HDC3020_THRESH_HUM_TRUNC_SHIFT); 414 break; 415 case IIO_HUMIDITYRELATIVE: 416 /* 417 * Calculate humidity threshold, shift it down and up to get the 418 * truncated threshold representation in the 7MSBs while keeping 419 * the current temperature threshold in the 9 LSBs. 420 */ 421 tmp = ((u64)((val * MICRO) + val2)) * 65535ULL; 422 tmp = div_u64(tmp, MICRO * 100); 423 val = tmp >> HDC3020_THRESH_HUM_TRUNC_SHIFT; 424 val = FIELD_PREP(HDC3020_THRESH_HUM_MASK, val); 425 val |= FIELD_GET(HDC3020_THRESH_TEMP_MASK, ret); 426 break; 427 default: 428 return -EOPNOTSUPP; 429 } 430 431 put_unaligned_be16(reg, buf); 432 put_unaligned_be16(val, buf + 2); 433 buf[4] = crc8(hdc3020_crc8_table, buf + 2, 2, CRC8_INIT_VALUE); 434 return hdc3020_write_bytes(data, buf, 5); 435 } 436 437 static int hdc3020_read_thresh(struct iio_dev *indio_dev, 438 const struct iio_chan_spec *chan, 439 enum iio_event_type type, 440 enum iio_event_direction dir, 441 enum iio_event_info info, 442 int *val, int *val2) 443 { 444 struct hdc3020_data *data = iio_priv(indio_dev); 445 u16 reg; 446 int ret; 447 448 /* Select threshold register */ 449 if (info == IIO_EV_INFO_VALUE) { 450 if (dir == IIO_EV_DIR_RISING) 451 reg = HDC3020_R_T_RH_THRESH_HIGH; 452 else 453 reg = HDC3020_R_T_RH_THRESH_LOW; 454 } else { 455 if (dir == IIO_EV_DIR_RISING) 456 reg = HDC3020_R_T_RH_THRESH_HIGH_CLR; 457 else 458 reg = HDC3020_R_T_RH_THRESH_LOW_CLR; 459 } 460 461 guard(mutex)(&data->lock); 462 ret = hdc3020_read_be16(data, reg); 463 if (ret < 0) 464 return ret; 465 466 switch (chan->type) { 467 case IIO_TEMP: 468 /* 469 * Get the temperature threshold from 9 LSBs, shift them to get 470 * the truncated temperature threshold representation and 471 * calculate the threshold according to the formula in the 472 * datasheet. 473 */ 474 *val = FIELD_GET(HDC3020_THRESH_TEMP_MASK, ret); 475 *val = *val << HDC3020_THRESH_TEMP_TRUNC_SHIFT; 476 *val = -2949075 + (175 * (*val)); 477 *val2 = 65535; 478 return IIO_VAL_FRACTIONAL; 479 case IIO_HUMIDITYRELATIVE: 480 /* 481 * Get the humidity threshold from 7 MSBs, shift them to get the 482 * truncated humidity threshold representation and calculate the 483 * threshold according to the formula in the datasheet. 484 */ 485 *val = FIELD_GET(HDC3020_THRESH_HUM_MASK, ret); 486 *val = (*val << HDC3020_THRESH_HUM_TRUNC_SHIFT) * 100; 487 *val2 = 65535; 488 return IIO_VAL_FRACTIONAL; 489 default: 490 return -EOPNOTSUPP; 491 } 492 } 493 494 static irqreturn_t hdc3020_interrupt_handler(int irq, void *private) 495 { 496 struct iio_dev *indio_dev = private; 497 struct hdc3020_data *data; 498 s64 time; 499 int ret; 500 501 data = iio_priv(indio_dev); 502 ret = hdc3020_read_be16(data, HDC3020_R_STATUS); 503 if (ret < 0) 504 return IRQ_HANDLED; 505 506 if (!(ret & (HDC3020_STATUS_T_HIGH_ALERT | HDC3020_STATUS_T_LOW_ALERT | 507 HDC3020_STATUS_RH_HIGH_ALERT | HDC3020_STATUS_RH_LOW_ALERT))) 508 return IRQ_NONE; 509 510 time = iio_get_time_ns(indio_dev); 511 if (ret & HDC3020_STATUS_T_HIGH_ALERT) 512 iio_push_event(indio_dev, 513 IIO_MOD_EVENT_CODE(IIO_TEMP, 0, 514 IIO_NO_MOD, 515 IIO_EV_TYPE_THRESH, 516 IIO_EV_DIR_RISING), 517 time); 518 519 if (ret & HDC3020_STATUS_T_LOW_ALERT) 520 iio_push_event(indio_dev, 521 IIO_MOD_EVENT_CODE(IIO_TEMP, 0, 522 IIO_NO_MOD, 523 IIO_EV_TYPE_THRESH, 524 IIO_EV_DIR_FALLING), 525 time); 526 527 if (ret & HDC3020_STATUS_RH_HIGH_ALERT) 528 iio_push_event(indio_dev, 529 IIO_MOD_EVENT_CODE(IIO_HUMIDITYRELATIVE, 0, 530 IIO_NO_MOD, 531 IIO_EV_TYPE_THRESH, 532 IIO_EV_DIR_RISING), 533 time); 534 535 if (ret & HDC3020_STATUS_RH_LOW_ALERT) 536 iio_push_event(indio_dev, 537 IIO_MOD_EVENT_CODE(IIO_HUMIDITYRELATIVE, 0, 538 IIO_NO_MOD, 539 IIO_EV_TYPE_THRESH, 540 IIO_EV_DIR_FALLING), 541 time); 542 543 return IRQ_HANDLED; 544 } 545 546 static const struct iio_info hdc3020_info = { 547 .read_raw = hdc3020_read_raw, 548 .write_raw = hdc3020_write_raw, 549 .read_avail = hdc3020_read_available, 550 .read_event_value = hdc3020_read_thresh, 551 .write_event_value = hdc3020_write_thresh, 552 }; 553 554 static void hdc3020_stop(void *data) 555 { 556 hdc3020_exec_cmd((struct hdc3020_data *)data, HDC3020_EXIT_AUTO); 557 } 558 559 static int hdc3020_probe(struct i2c_client *client) 560 { 561 struct iio_dev *indio_dev; 562 struct hdc3020_data *data; 563 int ret; 564 565 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 566 return -EOPNOTSUPP; 567 568 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 569 if (!indio_dev) 570 return -ENOMEM; 571 572 data = iio_priv(indio_dev); 573 data->client = client; 574 mutex_init(&data->lock); 575 576 crc8_populate_msb(hdc3020_crc8_table, HDC3020_CRC8_POLYNOMIAL); 577 578 indio_dev->name = "hdc3020"; 579 indio_dev->modes = INDIO_DIRECT_MODE; 580 indio_dev->info = &hdc3020_info; 581 indio_dev->channels = hdc3020_channels; 582 indio_dev->num_channels = ARRAY_SIZE(hdc3020_channels); 583 if (client->irq) { 584 ret = devm_request_threaded_irq(&client->dev, client->irq, 585 NULL, hdc3020_interrupt_handler, 586 IRQF_ONESHOT, "hdc3020", 587 indio_dev); 588 if (ret) 589 return dev_err_probe(&client->dev, ret, 590 "Failed to request IRQ\n"); 591 592 /* 593 * The alert output is activated by default upon power up, 594 * hardware reset, and soft reset. Clear the status register. 595 */ 596 ret = hdc3020_exec_cmd(data, HDC3020_S_STATUS); 597 if (ret) 598 return ret; 599 } 600 601 ret = hdc3020_exec_cmd(data, HDC3020_S_AUTO_10HZ_MOD0); 602 if (ret) 603 return dev_err_probe(&client->dev, ret, 604 "Unable to set up measurement\n"); 605 606 ret = devm_add_action_or_reset(&data->client->dev, hdc3020_stop, data); 607 if (ret) 608 return ret; 609 610 ret = devm_iio_device_register(&data->client->dev, indio_dev); 611 if (ret) 612 return dev_err_probe(&client->dev, ret, "Failed to add device"); 613 614 return 0; 615 } 616 617 static const struct i2c_device_id hdc3020_id[] = { 618 { "hdc3020" }, 619 { "hdc3021" }, 620 { "hdc3022" }, 621 { } 622 }; 623 MODULE_DEVICE_TABLE(i2c, hdc3020_id); 624 625 static const struct of_device_id hdc3020_dt_ids[] = { 626 { .compatible = "ti,hdc3020" }, 627 { .compatible = "ti,hdc3021" }, 628 { .compatible = "ti,hdc3022" }, 629 { } 630 }; 631 MODULE_DEVICE_TABLE(of, hdc3020_dt_ids); 632 633 static struct i2c_driver hdc3020_driver = { 634 .driver = { 635 .name = "hdc3020", 636 .of_match_table = hdc3020_dt_ids, 637 }, 638 .probe = hdc3020_probe, 639 .id_table = hdc3020_id, 640 }; 641 module_i2c_driver(hdc3020_driver); 642 643 MODULE_AUTHOR("Javier Carrasco <javier.carrasco.cruz@gmail.com>"); 644 MODULE_AUTHOR("Li peiyu <579lpy@gmail.com>"); 645 MODULE_DESCRIPTION("TI HDC3020 humidity and temperature sensor driver"); 646 MODULE_LICENSE("GPL"); 647