Merge tag 'sched-urgent-2024-03-24' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / iio / humidity / hdc3020.c
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");