Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * cc2.c - Support for the Amphenol ChipCap 2 relative humidity, temperature sensor
4 *
5 * Part numbers supported:
6 * CC2D23, CC2D23S, CC2D25, CC2D25S, CC2D33, CC2D33S, CC2D35, CC2D35S
7 *
8 * Author: Javier Carrasco <javier.carrasco.cruz@gmail.com>
9 *
10 * Datasheet and application notes:
11 * https://www.amphenol-sensors.com/en/telaire/humidity/527-humidity-sensors/3095-chipcap-2
12 */
13
14#include <linux/bitfield.h>
15#include <linux/bits.h>
16#include <linux/cleanup.h>
17#include <linux/completion.h>
18#include <linux/delay.h>
19#include <linux/hwmon.h>
20#include <linux/i2c.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/module.h>
24#include <linux/regulator/consumer.h>
25
26#define CC2_START_CM 0xA0
27#define CC2_START_NOM 0x80
28#define CC2_R_ALARM_H_ON 0x18
29#define CC2_R_ALARM_H_OFF 0x19
30#define CC2_R_ALARM_L_ON 0x1A
31#define CC2_R_ALARM_L_OFF 0x1B
32#define CC2_RW_OFFSET 0x40
33#define CC2_W_ALARM_H_ON (CC2_R_ALARM_H_ON + CC2_RW_OFFSET)
34#define CC2_W_ALARM_H_OFF (CC2_R_ALARM_H_OFF + CC2_RW_OFFSET)
35#define CC2_W_ALARM_L_ON (CC2_R_ALARM_L_ON + CC2_RW_OFFSET)
36#define CC2_W_ALARM_L_OFF (CC2_R_ALARM_L_OFF + CC2_RW_OFFSET)
37
38#define CC2_STATUS_FIELD GENMASK(7, 6)
39#define CC2_STATUS_VALID_DATA 0x00
40#define CC2_STATUS_STALE_DATA 0x01
41#define CC2_STATUS_CMD_MODE 0x02
42
43#define CC2_RESPONSE_FIELD GENMASK(1, 0)
44#define CC2_RESPONSE_BUSY 0x00
45#define CC2_RESPONSE_ACK 0x01
46#define CC2_RESPONSE_NACK 0x02
47
48#define CC2_ERR_CORR_EEPROM BIT(2)
49#define CC2_ERR_UNCORR_EEPROM BIT(3)
50#define CC2_ERR_RAM_PARITY BIT(4)
51#define CC2_ERR_CONFIG_LOAD BIT(5)
52
53#define CC2_EEPROM_SIZE 10
54#define CC2_EEPROM_DATA_LEN 3
55#define CC2_MEASUREMENT_DATA_LEN 4
56
57#define CC2_RH_DATA_FIELD GENMASK(13, 0)
58
59/* ensure clean off -> on transitions */
60#define CC2_POWER_CYCLE_MS 80
61
62#define CC2_STARTUP_TO_DATA_MS 55
63#define CC2_RESP_START_CM_US 100
64#define CC2_RESP_EEPROM_R_US 100
65#define CC2_RESP_EEPROM_W_MS 12
66#define CC2_STARTUP_TIME_US 1250
67
68#define CC2_RH_MAX (100 * 1000U)
69
70#define CC2_CM_RETRIES 5
71
72struct cc2_rh_alarm_info {
73 bool low_alarm;
74 bool high_alarm;
75 bool low_alarm_visible;
76 bool high_alarm_visible;
77};
78
79struct cc2_data {
80 struct cc2_rh_alarm_info rh_alarm;
81 struct completion complete;
82 struct device *hwmon;
83 struct i2c_client *client;
84 struct regulator *regulator;
85 const char *name;
86 int irq_ready;
87 int irq_low;
88 int irq_high;
89 bool process_irqs;
90};
91
92enum cc2_chan_addr {
93 CC2_CHAN_TEMP = 0,
94 CC2_CHAN_HUMIDITY,
95};
96
97/* %RH as a per cent mille from a register value */
98static long cc2_rh_convert(u16 data)
99{
100 unsigned long tmp = (data & CC2_RH_DATA_FIELD) * CC2_RH_MAX;
101
102 return tmp / ((1 << 14) - 1);
103}
104
105/* convert %RH to a register value */
106static u16 cc2_rh_to_reg(long data)
107{
108 return data * ((1 << 14) - 1) / CC2_RH_MAX;
109}
110
111/* temperature in milli degrees celsius from a register value */
112static long cc2_temp_convert(u16 data)
113{
114 unsigned long tmp = ((data >> 2) * 165 * 1000U) / ((1 << 14) - 1);
115
116 return tmp - 40 * 1000U;
117}
118
119static int cc2_enable(struct cc2_data *data)
120{
121 int ret;
122
123 /* exclusive regulator, check in case a disable failed */
124 if (regulator_is_enabled(data->regulator))
125 return 0;
126
127 /* clear any pending completion */
128 try_wait_for_completion(&data->complete);
129
130 ret = regulator_enable(data->regulator);
131 if (ret < 0)
132 return ret;
133
134 usleep_range(CC2_STARTUP_TIME_US, CC2_STARTUP_TIME_US + 125);
135
136 data->process_irqs = true;
137
138 return 0;
139}
140
141static void cc2_disable(struct cc2_data *data)
142{
143 int err;
144
145 /* ignore alarms triggered by voltage toggling when powering up */
146 data->process_irqs = false;
147
148 /* exclusive regulator, check in case an enable failed */
149 if (regulator_is_enabled(data->regulator)) {
150 err = regulator_disable(data->regulator);
151 if (err)
152 dev_dbg(&data->client->dev, "Failed to disable device");
153 }
154}
155
156static int cc2_cmd_response_diagnostic(struct device *dev, u8 status)
157{
158 int resp;
159
160 if (FIELD_GET(CC2_STATUS_FIELD, status) != CC2_STATUS_CMD_MODE) {
161 dev_dbg(dev, "Command sent out of command window\n");
162 return -ETIMEDOUT;
163 }
164
165 resp = FIELD_GET(CC2_RESPONSE_FIELD, status);
166 switch (resp) {
167 case CC2_RESPONSE_ACK:
168 return 0;
169 case CC2_RESPONSE_BUSY:
170 return -EBUSY;
171 case CC2_RESPONSE_NACK:
172 if (resp & CC2_ERR_CORR_EEPROM)
173 dev_dbg(dev, "Command failed: corrected EEPROM\n");
174 if (resp & CC2_ERR_UNCORR_EEPROM)
175 dev_dbg(dev, "Command failed: uncorrected EEPROM\n");
176 if (resp & CC2_ERR_RAM_PARITY)
177 dev_dbg(dev, "Command failed: RAM parity\n");
178 if (resp & CC2_ERR_RAM_PARITY)
179 dev_dbg(dev, "Command failed: configuration error\n");
180 return -ENODATA;
181 default:
182 dev_dbg(dev, "Unknown command reply\n");
183 return -EINVAL;
184 }
185}
186
187static int cc2_read_command_status(struct i2c_client *client)
188{
189 u8 status;
190 int ret;
191
192 ret = i2c_master_recv(client, &status, 1);
193 if (ret != 1) {
194 ret = ret < 0 ? ret : -EIO;
195 return ret;
196 }
197
198 return cc2_cmd_response_diagnostic(&client->dev, status);
199}
200
201/*
202 * The command mode is only accessible after sending the START_CM command in the
203 * first 10 ms after power-up. Only in case the command window is missed,
204 * CC2_CM_RETRIES retries are attempted before giving up and returning an error.
205 */
206static int cc2_command_mode_start(struct cc2_data *data)
207{
208 unsigned long timeout;
209 int i, ret;
210
211 for (i = 0; i < CC2_CM_RETRIES; i++) {
212 ret = cc2_enable(data);
213 if (ret < 0)
214 return ret;
215
216 ret = i2c_smbus_write_word_data(data->client, CC2_START_CM, 0);
217 if (ret < 0)
218 return ret;
219
220 if (data->irq_ready > 0) {
221 timeout = usecs_to_jiffies(2 * CC2_RESP_START_CM_US);
222 ret = wait_for_completion_timeout(&data->complete,
223 timeout);
224 if (!ret)
225 return -ETIMEDOUT;
226 } else {
227 usleep_range(CC2_RESP_START_CM_US,
228 2 * CC2_RESP_START_CM_US);
229 }
230 ret = cc2_read_command_status(data->client);
231 if (ret != -ETIMEDOUT || i == CC2_CM_RETRIES)
232 break;
233
234 /* command window missed, prepare for a retry */
235 cc2_disable(data);
236 msleep(CC2_POWER_CYCLE_MS);
237 }
238
239 return ret;
240}
241
242/* Sending a Start_NOM command finishes the command mode immediately with no
243 * reply and the device enters normal operation mode
244 */
245static int cc2_command_mode_finish(struct cc2_data *data)
246{
247 int ret;
248
249 ret = i2c_smbus_write_word_data(data->client, CC2_START_NOM, 0);
250 if (ret < 0)
251 return ret;
252
253 return 0;
254}
255
256static int cc2_write_reg(struct cc2_data *data, u8 reg, u16 val)
257{
258 unsigned long timeout;
259 int ret;
260
261 ret = cc2_command_mode_start(data);
262 if (ret < 0)
263 goto disable;
264
265 cpu_to_be16s(&val);
266 ret = i2c_smbus_write_word_data(data->client, reg, val);
267 if (ret < 0)
268 goto disable;
269
270 if (data->irq_ready > 0) {
271 timeout = msecs_to_jiffies(2 * CC2_RESP_EEPROM_W_MS);
272 ret = wait_for_completion_timeout(&data->complete, timeout);
273 if (!ret) {
274 ret = -ETIMEDOUT;
275 goto disable;
276 }
277 } else {
278 msleep(CC2_RESP_EEPROM_W_MS);
279 }
280
281 ret = cc2_read_command_status(data->client);
282
283disable:
284 cc2_disable(data);
285
286 return ret;
287}
288
289static int cc2_read_reg(struct cc2_data *data, u8 reg, u16 *val)
290{
291 u8 buf[CC2_EEPROM_DATA_LEN];
292 unsigned long timeout;
293 int ret;
294
295 ret = cc2_command_mode_start(data);
296 if (ret < 0)
297 return ret;
298
299 ret = i2c_smbus_write_word_data(data->client, reg, 0);
300 if (ret < 0)
301 return ret;
302
303 if (data->irq_ready > 0) {
304 timeout = usecs_to_jiffies(2 * CC2_RESP_EEPROM_R_US);
305 ret = wait_for_completion_timeout(&data->complete, timeout);
306 if (!ret)
307 return -ETIMEDOUT;
308
309 } else {
310 usleep_range(CC2_RESP_EEPROM_R_US, CC2_RESP_EEPROM_R_US + 10);
311 }
312 ret = i2c_master_recv(data->client, buf, CC2_EEPROM_DATA_LEN);
313 if (ret != CC2_EEPROM_DATA_LEN)
314 return ret < 0 ? ret : -EIO;
315
316 *val = be16_to_cpup((__be16 *)&buf[1]);
317
318 return cc2_read_command_status(data->client);
319}
320
321static int cc2_get_reg_val(struct cc2_data *data, u8 reg, long *val)
322{
323 u16 reg_val;
324 int ret;
325
326 ret = cc2_read_reg(data, reg, ®_val);
327 if (!ret)
328 *val = cc2_rh_convert(reg_val);
329
330 cc2_disable(data);
331
332 return ret;
333}
334
335static int cc2_data_fetch(struct i2c_client *client,
336 enum hwmon_sensor_types type, long *val)
337{
338 u8 data[CC2_MEASUREMENT_DATA_LEN];
339 u8 status;
340 int ret;
341
342 ret = i2c_master_recv(client, data, CC2_MEASUREMENT_DATA_LEN);
343 if (ret != CC2_MEASUREMENT_DATA_LEN) {
344 ret = ret < 0 ? ret : -EIO;
345 return ret;
346 }
347 status = FIELD_GET(CC2_STATUS_FIELD, data[0]);
348 if (status == CC2_STATUS_STALE_DATA)
349 return -EBUSY;
350
351 if (status != CC2_STATUS_VALID_DATA)
352 return -EIO;
353
354 switch (type) {
355 case hwmon_humidity:
356 *val = cc2_rh_convert(be16_to_cpup((__be16 *)&data[0]));
357 break;
358 case hwmon_temp:
359 *val = cc2_temp_convert(be16_to_cpup((__be16 *)&data[2]));
360 break;
361 default:
362 return -EINVAL;
363 }
364
365 return 0;
366}
367
368static int cc2_read_measurement(struct cc2_data *data,
369 enum hwmon_sensor_types type, long *val)
370{
371 unsigned long timeout;
372 int ret;
373
374 if (data->irq_ready > 0) {
375 timeout = msecs_to_jiffies(CC2_STARTUP_TO_DATA_MS * 2);
376 ret = wait_for_completion_timeout(&data->complete, timeout);
377 if (!ret)
378 return -ETIMEDOUT;
379
380 } else {
381 msleep(CC2_STARTUP_TO_DATA_MS);
382 }
383
384 ret = cc2_data_fetch(data->client, type, val);
385
386 return ret;
387}
388
389/*
390 * A measurement requires enabling the device, waiting for the automatic
391 * measurement to finish, reading the measurement data and disabling the device
392 * again.
393 */
394static int cc2_measurement(struct cc2_data *data, enum hwmon_sensor_types type,
395 long *val)
396{
397 int ret;
398
399 ret = cc2_enable(data);
400 if (ret)
401 return ret;
402
403 ret = cc2_read_measurement(data, type, val);
404
405 cc2_disable(data);
406
407 return ret;
408}
409
410/*
411 * In order to check alarm status, the corresponding ALARM_OFF (hysteresis)
412 * register must be read and a new measurement must be carried out to trigger
413 * the alarm signals. Given that the device carries out a measurement after
414 * exiting the command mode, there is no need to force two power-up sequences.
415 * Instead, a NOM command is sent and the device is disabled after the
416 * measurement is read.
417 */
418static int cc2_read_hyst_and_measure(struct cc2_data *data, u8 reg,
419 long *hyst, long *measurement)
420{
421 u16 reg_val;
422 int ret;
423
424 ret = cc2_read_reg(data, reg, ®_val);
425 if (ret)
426 goto disable;
427
428 *hyst = cc2_rh_convert(reg_val);
429
430 ret = cc2_command_mode_finish(data);
431 if (ret)
432 goto disable;
433
434 ret = cc2_read_measurement(data, hwmon_humidity, measurement);
435
436disable:
437 cc2_disable(data);
438
439 return ret;
440}
441
442static umode_t cc2_is_visible(const void *data, enum hwmon_sensor_types type,
443 u32 attr, int channel)
444{
445 const struct cc2_data *cc2 = data;
446
447 switch (type) {
448 case hwmon_humidity:
449 switch (attr) {
450 case hwmon_humidity_input:
451 return 0444;
452 case hwmon_humidity_min_alarm:
453 return cc2->rh_alarm.low_alarm_visible ? 0444 : 0;
454 case hwmon_humidity_max_alarm:
455 return cc2->rh_alarm.high_alarm_visible ? 0444 : 0;
456 case hwmon_humidity_min:
457 case hwmon_humidity_min_hyst:
458 return cc2->rh_alarm.low_alarm_visible ? 0644 : 0;
459 case hwmon_humidity_max:
460 case hwmon_humidity_max_hyst:
461 return cc2->rh_alarm.high_alarm_visible ? 0644 : 0;
462 default:
463 return 0;
464 }
465 case hwmon_temp:
466 switch (attr) {
467 case hwmon_temp_input:
468 return 0444;
469 default:
470 return 0;
471 }
472 default:
473 break;
474 }
475
476 return 0;
477}
478
479static irqreturn_t cc2_ready_interrupt(int irq, void *data)
480{
481 struct cc2_data *cc2 = data;
482
483 if (cc2->process_irqs)
484 complete(&cc2->complete);
485
486 return IRQ_HANDLED;
487}
488
489static irqreturn_t cc2_low_interrupt(int irq, void *data)
490{
491 struct cc2_data *cc2 = data;
492
493 if (cc2->process_irqs) {
494 hwmon_notify_event(cc2->hwmon, hwmon_humidity,
495 hwmon_humidity_min_alarm, CC2_CHAN_HUMIDITY);
496 cc2->rh_alarm.low_alarm = true;
497 }
498
499 return IRQ_HANDLED;
500}
501
502static irqreturn_t cc2_high_interrupt(int irq, void *data)
503{
504 struct cc2_data *cc2 = data;
505
506 if (cc2->process_irqs) {
507 hwmon_notify_event(cc2->hwmon, hwmon_humidity,
508 hwmon_humidity_max_alarm, CC2_CHAN_HUMIDITY);
509 cc2->rh_alarm.high_alarm = true;
510 }
511
512 return IRQ_HANDLED;
513}
514
515static int cc2_humidity_min_alarm_status(struct cc2_data *data, long *val)
516{
517 long measurement, min_hyst;
518 int ret;
519
520 ret = cc2_read_hyst_and_measure(data, CC2_R_ALARM_L_OFF, &min_hyst,
521 &measurement);
522 if (ret < 0)
523 return ret;
524
525 if (data->rh_alarm.low_alarm) {
526 *val = (measurement < min_hyst) ? 1 : 0;
527 data->rh_alarm.low_alarm = *val;
528 } else {
529 *val = 0;
530 }
531
532 return 0;
533}
534
535static int cc2_humidity_max_alarm_status(struct cc2_data *data, long *val)
536{
537 long measurement, max_hyst;
538 int ret;
539
540 ret = cc2_read_hyst_and_measure(data, CC2_R_ALARM_H_OFF, &max_hyst,
541 &measurement);
542 if (ret < 0)
543 return ret;
544
545 if (data->rh_alarm.high_alarm) {
546 *val = (measurement > max_hyst) ? 1 : 0;
547 data->rh_alarm.high_alarm = *val;
548 } else {
549 *val = 0;
550 }
551
552 return 0;
553}
554
555static int cc2_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
556 int channel, long *val)
557{
558 struct cc2_data *data = dev_get_drvdata(dev);
559
560 switch (type) {
561 case hwmon_temp:
562 return cc2_measurement(data, type, val);
563 case hwmon_humidity:
564 switch (attr) {
565 case hwmon_humidity_input:
566 return cc2_measurement(data, type, val);
567 case hwmon_humidity_min:
568 return cc2_get_reg_val(data, CC2_R_ALARM_L_ON, val);
569 case hwmon_humidity_min_hyst:
570 return cc2_get_reg_val(data, CC2_R_ALARM_L_OFF, val);
571 case hwmon_humidity_max:
572 return cc2_get_reg_val(data, CC2_R_ALARM_H_ON, val);
573 case hwmon_humidity_max_hyst:
574 return cc2_get_reg_val(data, CC2_R_ALARM_H_OFF, val);
575 case hwmon_humidity_min_alarm:
576 return cc2_humidity_min_alarm_status(data, val);
577 case hwmon_humidity_max_alarm:
578 return cc2_humidity_max_alarm_status(data, val);
579 default:
580 return -EOPNOTSUPP;
581 }
582 default:
583 return -EOPNOTSUPP;
584 }
585}
586
587static int cc2_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
588 int channel, long val)
589{
590 struct cc2_data *data = dev_get_drvdata(dev);
591 u16 arg;
592 u8 cmd;
593
594 if (type != hwmon_humidity)
595 return -EOPNOTSUPP;
596
597 if (val < 0 || val > CC2_RH_MAX)
598 return -EINVAL;
599
600 switch (attr) {
601 case hwmon_humidity_min:
602 cmd = CC2_W_ALARM_L_ON;
603 arg = cc2_rh_to_reg(val);
604 return cc2_write_reg(data, cmd, arg);
605 case hwmon_humidity_min_hyst:
606 cmd = CC2_W_ALARM_L_OFF;
607 arg = cc2_rh_to_reg(val);
608 return cc2_write_reg(data, cmd, arg);
609 case hwmon_humidity_max:
610 cmd = CC2_W_ALARM_H_ON;
611 arg = cc2_rh_to_reg(val);
612 return cc2_write_reg(data, cmd, arg);
613 case hwmon_humidity_max_hyst:
614 cmd = CC2_W_ALARM_H_OFF;
615 arg = cc2_rh_to_reg(val);
616 return cc2_write_reg(data, cmd, arg);
617 default:
618 return -EOPNOTSUPP;
619 }
620}
621
622static int cc2_request_ready_irq(struct cc2_data *data, struct device *dev)
623{
624 int ret = 0;
625
626 data->irq_ready = fwnode_irq_get_byname(dev_fwnode(dev), "ready");
627 if (data->irq_ready > 0) {
628 init_completion(&data->complete);
629 ret = devm_request_threaded_irq(dev, data->irq_ready, NULL,
630 cc2_ready_interrupt,
631 IRQF_ONESHOT |
632 IRQF_TRIGGER_RISING,
633 dev_name(dev), data);
634 }
635
636 return ret;
637}
638
639static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev)
640{
641 int ret = 0;
642
643 data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low");
644 if (data->irq_low > 0) {
645 ret = devm_request_threaded_irq(dev, data->irq_low, NULL,
646 cc2_low_interrupt,
647 IRQF_ONESHOT |
648 IRQF_TRIGGER_RISING,
649 dev_name(dev), data);
650 if (ret)
651 return ret;
652
653 data->rh_alarm.low_alarm_visible = true;
654 }
655
656 data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high");
657 if (data->irq_high > 0) {
658 ret = devm_request_threaded_irq(dev, data->irq_high, NULL,
659 cc2_high_interrupt,
660 IRQF_ONESHOT |
661 IRQF_TRIGGER_RISING,
662 dev_name(dev), data);
663 if (ret)
664 return ret;
665
666 data->rh_alarm.high_alarm_visible = true;
667 }
668
669 return ret;
670}
671
672static const struct hwmon_channel_info *cc2_info[] = {
673 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
674 HWMON_CHANNEL_INFO(humidity, HWMON_H_INPUT | HWMON_H_MIN | HWMON_H_MAX |
675 HWMON_H_MIN_HYST | HWMON_H_MAX_HYST |
676 HWMON_H_MIN_ALARM | HWMON_H_MAX_ALARM),
677 NULL
678};
679
680static const struct hwmon_ops cc2_hwmon_ops = {
681 .is_visible = cc2_is_visible,
682 .read = cc2_read,
683 .write = cc2_write,
684};
685
686static const struct hwmon_chip_info cc2_chip_info = {
687 .ops = &cc2_hwmon_ops,
688 .info = cc2_info,
689};
690
691static int cc2_probe(struct i2c_client *client)
692{
693 struct cc2_data *data;
694 struct device *dev = &client->dev;
695 int ret;
696
697 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
698 return -EOPNOTSUPP;
699
700 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
701 if (!data)
702 return -ENOMEM;
703
704 i2c_set_clientdata(client, data);
705
706 data->client = client;
707
708 data->regulator = devm_regulator_get_exclusive(dev, "vdd");
709 if (IS_ERR(data->regulator))
710 return dev_err_probe(dev, PTR_ERR(data->regulator),
711 "Failed to get regulator\n");
712
713 ret = cc2_request_ready_irq(data, dev);
714 if (ret)
715 return dev_err_probe(dev, ret, "Failed to request ready irq\n");
716
717 ret = cc2_request_alarm_irqs(data, dev);
718 if (ret)
719 return dev_err_probe(dev, ret, "Failed to request alarm irqs\n");
720
721 data->hwmon = devm_hwmon_device_register_with_info(dev, client->name,
722 data, &cc2_chip_info,
723 NULL);
724 if (IS_ERR(data->hwmon))
725 return dev_err_probe(dev, PTR_ERR(data->hwmon),
726 "Failed to register hwmon device\n");
727
728 return 0;
729}
730
731static void cc2_remove(struct i2c_client *client)
732{
733 struct cc2_data *data = i2c_get_clientdata(client);
734
735 cc2_disable(data);
736}
737
738static const struct i2c_device_id cc2_id[] = {
739 { "cc2d23" },
740 { "cc2d23s" },
741 { "cc2d25" },
742 { "cc2d25s" },
743 { "cc2d33" },
744 { "cc2d33s" },
745 { "cc2d35" },
746 { "cc2d35s" },
747 { }
748};
749MODULE_DEVICE_TABLE(i2c, cc2_id);
750
751static const struct of_device_id cc2_of_match[] = {
752 { .compatible = "amphenol,cc2d23" },
753 { .compatible = "amphenol,cc2d23s" },
754 { .compatible = "amphenol,cc2d25" },
755 { .compatible = "amphenol,cc2d25s" },
756 { .compatible = "amphenol,cc2d33" },
757 { .compatible = "amphenol,cc2d33s" },
758 { .compatible = "amphenol,cc2d35" },
759 { .compatible = "amphenol,cc2d35s" },
760 { },
761};
762MODULE_DEVICE_TABLE(of, cc2_of_match);
763
764static struct i2c_driver cc2_driver = {
765 .driver = {
766 .name = "cc2d23",
767 .of_match_table = cc2_of_match,
768 },
769 .probe = cc2_probe,
770 .remove = cc2_remove,
771 .id_table = cc2_id,
772};
773module_i2c_driver(cc2_driver);
774
775MODULE_AUTHOR("Javier Carrasco <javier.carrasco.cruz@gamil.com>");
776MODULE_DESCRIPTION("Amphenol ChipCap 2 humidity and temperature sensor driver");
777MODULE_LICENSE("GPL");