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