1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Sensirion SCD4X carbon dioxide sensor i2c driver
4 *
5 * Copyright (C) 2021 Protonic Holland
6 * Author: Roan van Dijk <roan@protonic.nl>
7 *
8 * I2C slave address: 0x62
9 *
10 * Datasheets:
11 * https://www.sensirion.com/file/datasheet_scd4x
12 */
13
14#include <asm/unaligned.h>
15#include <linux/crc8.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/i2c.h>
19#include <linux/iio/buffer.h>
20#include <linux/iio/iio.h>
21#include <linux/iio/sysfs.h>
22#include <linux/iio/trigger.h>
23#include <linux/iio/trigger_consumer.h>
24#include <linux/iio/triggered_buffer.h>
25#include <linux/iio/types.h>
26#include <linux/kernel.h>
27#include <linux/mutex.h>
28#include <linux/string.h>
29#include <linux/sysfs.h>
30#include <linux/types.h>
31
32#define SCD4X_CRC8_POLYNOMIAL 0x31
33#define SCD4X_TIMEOUT_ERR 1000
34#define SCD4X_READ_BUF_SIZE 9
35#define SCD4X_COMMAND_BUF_SIZE 2
36#define SCD4X_WRITE_BUF_SIZE 5
37#define SCD4X_FRC_MIN_PPM 0
38#define SCD4X_FRC_MAX_PPM 2000
39#define SCD4X_PRESSURE_COMP_MIN_MBAR 700
40#define SCD4X_PRESSURE_COMP_MAX_MBAR 1200
41#define SCD4X_READY_MASK 0x01
42
43/*Commands SCD4X*/
44enum scd4x_cmd {
45 CMD_START_MEAS = 0x21b1,
46 CMD_READ_MEAS = 0xec05,
47 CMD_STOP_MEAS = 0x3f86,
48 CMD_SET_TEMP_OFFSET = 0x241d,
49 CMD_GET_TEMP_OFFSET = 0x2318,
50 CMD_SET_AMB_PRESSURE = 0xe000,
51 CMD_GET_AMB_PRESSURE = 0xe000,
52 CMD_FRC = 0x362f,
53 CMD_SET_ASC = 0x2416,
54 CMD_GET_ASC = 0x2313,
55 CMD_GET_DATA_READY = 0xe4b8,
56};
57
58enum scd4x_channel_idx {
59 SCD4X_CO2,
60 SCD4X_TEMP,
61 SCD4X_HR,
62};
63
64struct scd4x_state {
65 struct i2c_client *client;
66 /* maintain access to device, to prevent concurrent reads/writes */
67 struct mutex lock;
68 struct regulator *vdd;
69};
70
71DECLARE_CRC8_TABLE(scd4x_crc8_table);
72
73static int scd4x_i2c_xfer(struct scd4x_state *state, char *txbuf, int txsize,
74 char *rxbuf, int rxsize)
75{
76 struct i2c_client *client = state->client;
77 int ret;
78
79 ret = i2c_master_send(client, buf: txbuf, count: txsize);
80
81 if (ret < 0)
82 return ret;
83 if (ret != txsize)
84 return -EIO;
85
86 if (rxsize == 0)
87 return 0;
88
89 ret = i2c_master_recv(client, buf: rxbuf, count: rxsize);
90 if (ret < 0)
91 return ret;
92 if (ret != rxsize)
93 return -EIO;
94
95 return 0;
96}
97
98static int scd4x_send_command(struct scd4x_state *state, enum scd4x_cmd cmd)
99{
100 char buf[SCD4X_COMMAND_BUF_SIZE];
101 int ret;
102
103 /*
104 * Measurement needs to be stopped before sending commands.
105 * Except stop and start command.
106 */
107 if ((cmd != CMD_STOP_MEAS) && (cmd != CMD_START_MEAS)) {
108
109 ret = scd4x_send_command(state, cmd: CMD_STOP_MEAS);
110 if (ret)
111 return ret;
112
113 /* execution time for stopping measurement */
114 msleep_interruptible(msecs: 500);
115 }
116
117 put_unaligned_be16(val: cmd, p: buf);
118 ret = scd4x_i2c_xfer(state, txbuf: buf, txsize: 2, rxbuf: buf, rxsize: 0);
119 if (ret)
120 return ret;
121
122 if ((cmd != CMD_STOP_MEAS) && (cmd != CMD_START_MEAS)) {
123 ret = scd4x_send_command(state, cmd: CMD_START_MEAS);
124 if (ret)
125 return ret;
126 }
127
128 return 0;
129}
130
131static int scd4x_read(struct scd4x_state *state, enum scd4x_cmd cmd,
132 void *response, int response_sz)
133{
134 struct i2c_client *client = state->client;
135 char buf[SCD4X_READ_BUF_SIZE];
136 char *rsp = response;
137 int i, ret;
138 char crc;
139
140 /*
141 * Measurement needs to be stopped before sending commands.
142 * Except for reading measurement and data ready command.
143 */
144 if ((cmd != CMD_GET_DATA_READY) && (cmd != CMD_READ_MEAS) &&
145 (cmd != CMD_GET_AMB_PRESSURE)) {
146 ret = scd4x_send_command(state, cmd: CMD_STOP_MEAS);
147 if (ret)
148 return ret;
149
150 /* execution time for stopping measurement */
151 msleep_interruptible(msecs: 500);
152 }
153
154 /* CRC byte for every 2 bytes of data */
155 response_sz += response_sz / 2;
156
157 put_unaligned_be16(val: cmd, p: buf);
158 ret = scd4x_i2c_xfer(state, txbuf: buf, txsize: 2, rxbuf: buf, rxsize: response_sz);
159 if (ret)
160 return ret;
161
162 for (i = 0; i < response_sz; i += 3) {
163 crc = crc8(table: scd4x_crc8_table, pdata: buf + i, nbytes: 2, CRC8_INIT_VALUE);
164 if (crc != buf[i + 2]) {
165 dev_err(&client->dev, "CRC error\n");
166 return -EIO;
167 }
168
169 *rsp++ = buf[i];
170 *rsp++ = buf[i + 1];
171 }
172
173 /* start measurement */
174 if ((cmd != CMD_GET_DATA_READY) && (cmd != CMD_READ_MEAS) &&
175 (cmd != CMD_GET_AMB_PRESSURE)) {
176 ret = scd4x_send_command(state, cmd: CMD_START_MEAS);
177 if (ret)
178 return ret;
179 }
180
181 return 0;
182}
183
184static int scd4x_write(struct scd4x_state *state, enum scd4x_cmd cmd, uint16_t arg)
185{
186 char buf[SCD4X_WRITE_BUF_SIZE];
187 int ret;
188 char crc;
189
190 put_unaligned_be16(val: cmd, p: buf);
191 put_unaligned_be16(val: arg, p: buf + 2);
192
193 crc = crc8(table: scd4x_crc8_table, pdata: buf + 2, nbytes: 2, CRC8_INIT_VALUE);
194 buf[4] = crc;
195
196 /* measurement needs to be stopped before sending commands */
197 if (cmd != CMD_SET_AMB_PRESSURE) {
198 ret = scd4x_send_command(state, cmd: CMD_STOP_MEAS);
199 if (ret)
200 return ret;
201 }
202
203 /* execution time */
204 msleep_interruptible(msecs: 500);
205
206 ret = scd4x_i2c_xfer(state, txbuf: buf, SCD4X_WRITE_BUF_SIZE, rxbuf: buf, rxsize: 0);
207 if (ret)
208 return ret;
209
210 /* start measurement, except for forced calibration command */
211 if ((cmd != CMD_FRC) && (cmd != CMD_SET_AMB_PRESSURE)) {
212 ret = scd4x_send_command(state, cmd: CMD_START_MEAS);
213 if (ret)
214 return ret;
215 }
216
217 return 0;
218}
219
220static int scd4x_write_and_fetch(struct scd4x_state *state, enum scd4x_cmd cmd,
221 uint16_t arg, void *response, int response_sz)
222{
223 struct i2c_client *client = state->client;
224 char buf[SCD4X_READ_BUF_SIZE];
225 char *rsp = response;
226 int i, ret;
227 char crc;
228
229 ret = scd4x_write(state, cmd: CMD_FRC, arg);
230 if (ret)
231 goto err;
232
233 /* execution time */
234 msleep_interruptible(msecs: 400);
235
236 /* CRC byte for every 2 bytes of data */
237 response_sz += response_sz / 2;
238
239 ret = i2c_master_recv(client, buf, count: response_sz);
240 if (ret < 0)
241 goto err;
242 if (ret != response_sz) {
243 ret = -EIO;
244 goto err;
245 }
246
247 for (i = 0; i < response_sz; i += 3) {
248 crc = crc8(table: scd4x_crc8_table, pdata: buf + i, nbytes: 2, CRC8_INIT_VALUE);
249 if (crc != buf[i + 2]) {
250 dev_err(&client->dev, "CRC error\n");
251 ret = -EIO;
252 goto err;
253 }
254
255 *rsp++ = buf[i];
256 *rsp++ = buf[i + 1];
257 }
258
259 return scd4x_send_command(state, cmd: CMD_START_MEAS);
260
261err:
262 /*
263 * on error try to start the measurement,
264 * puts sensor back into continuous measurement
265 */
266 scd4x_send_command(state, cmd: CMD_START_MEAS);
267
268 return ret;
269}
270
271static int scd4x_read_meas(struct scd4x_state *state, uint16_t *meas)
272{
273 int i, ret;
274 __be16 buf[3];
275
276 ret = scd4x_read(state, cmd: CMD_READ_MEAS, response: buf, response_sz: sizeof(buf));
277 if (ret)
278 return ret;
279
280 for (i = 0; i < ARRAY_SIZE(buf); i++)
281 meas[i] = be16_to_cpu(buf[i]);
282
283 return 0;
284}
285
286static int scd4x_wait_meas_poll(struct scd4x_state *state)
287{
288 struct i2c_client *client = state->client;
289 int tries = 6;
290 int ret;
291
292 do {
293 __be16 bval;
294 uint16_t val;
295
296 ret = scd4x_read(state, cmd: CMD_GET_DATA_READY, response: &bval, response_sz: sizeof(bval));
297 if (ret)
298 return -EIO;
299 val = be16_to_cpu(bval);
300
301 /* new measurement available */
302 if (val & 0x7FF)
303 return 0;
304
305 msleep_interruptible(msecs: 1000);
306 } while (--tries);
307
308 /* try to start sensor on timeout */
309 ret = scd4x_send_command(state, cmd: CMD_START_MEAS);
310 if (ret)
311 dev_err(&client->dev, "failed to start measurement: %d\n", ret);
312
313 return -ETIMEDOUT;
314}
315
316static int scd4x_read_poll(struct scd4x_state *state, uint16_t *buf)
317{
318 int ret;
319
320 ret = scd4x_wait_meas_poll(state);
321 if (ret)
322 return ret;
323
324 return scd4x_read_meas(state, meas: buf);
325}
326
327static int scd4x_read_channel(struct scd4x_state *state, int chan)
328{
329 int ret;
330 uint16_t buf[3];
331
332 ret = scd4x_read_poll(state, buf);
333 if (ret)
334 return ret;
335
336 return buf[chan];
337}
338
339static int scd4x_read_raw(struct iio_dev *indio_dev,
340 struct iio_chan_spec const *chan, int *val,
341 int *val2, long mask)
342{
343 struct scd4x_state *state = iio_priv(indio_dev);
344 int ret;
345 __be16 tmp;
346
347 switch (mask) {
348 case IIO_CHAN_INFO_RAW:
349 if (chan->output) {
350 mutex_lock(&state->lock);
351 ret = scd4x_read(state, cmd: CMD_GET_AMB_PRESSURE, response: &tmp, response_sz: sizeof(tmp));
352 mutex_unlock(lock: &state->lock);
353
354 if (ret)
355 return ret;
356
357 *val = be16_to_cpu(tmp);
358 return IIO_VAL_INT;
359 }
360
361 ret = iio_device_claim_direct_mode(indio_dev);
362 if (ret)
363 return ret;
364
365 mutex_lock(&state->lock);
366 ret = scd4x_read_channel(state, chan: chan->address);
367 mutex_unlock(lock: &state->lock);
368
369 iio_device_release_direct_mode(indio_dev);
370 if (ret < 0)
371 return ret;
372
373 *val = ret;
374 return IIO_VAL_INT;
375 case IIO_CHAN_INFO_SCALE:
376 if (chan->type == IIO_CONCENTRATION) {
377 *val = 0;
378 *val2 = 100;
379 return IIO_VAL_INT_PLUS_MICRO;
380 } else if (chan->type == IIO_TEMP) {
381 *val = 175000;
382 *val2 = 65536;
383 return IIO_VAL_FRACTIONAL;
384 } else if (chan->type == IIO_HUMIDITYRELATIVE) {
385 *val = 100000;
386 *val2 = 65536;
387 return IIO_VAL_FRACTIONAL;
388 }
389 return -EINVAL;
390 case IIO_CHAN_INFO_OFFSET:
391 *val = -16852;
392 *val2 = 114286;
393 return IIO_VAL_INT_PLUS_MICRO;
394 case IIO_CHAN_INFO_CALIBBIAS:
395 mutex_lock(&state->lock);
396 ret = scd4x_read(state, cmd: CMD_GET_TEMP_OFFSET, response: &tmp, response_sz: sizeof(tmp));
397 mutex_unlock(lock: &state->lock);
398 if (ret)
399 return ret;
400
401 *val = be16_to_cpu(tmp);
402
403 return IIO_VAL_INT;
404 default:
405 return -EINVAL;
406 }
407}
408
409static const int scd4x_pressure_calibbias_available[] = {
410 SCD4X_PRESSURE_COMP_MIN_MBAR, 1, SCD4X_PRESSURE_COMP_MAX_MBAR,
411};
412
413static int scd4x_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
414 const int **vals, int *type, int *length, long mask)
415{
416 switch (mask) {
417 case IIO_CHAN_INFO_RAW:
418 *vals = scd4x_pressure_calibbias_available;
419 *type = IIO_VAL_INT;
420
421 return IIO_AVAIL_RANGE;
422 }
423
424 return -EINVAL;
425}
426
427
428static int scd4x_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
429 int val, int val2, long mask)
430{
431 struct scd4x_state *state = iio_priv(indio_dev);
432 int ret = 0;
433
434 switch (mask) {
435 case IIO_CHAN_INFO_CALIBBIAS:
436 mutex_lock(&state->lock);
437 ret = scd4x_write(state, cmd: CMD_SET_TEMP_OFFSET, arg: val);
438 mutex_unlock(lock: &state->lock);
439
440 return ret;
441 case IIO_CHAN_INFO_RAW:
442 switch (chan->type) {
443 case IIO_PRESSURE:
444 if (val < SCD4X_PRESSURE_COMP_MIN_MBAR ||
445 val > SCD4X_PRESSURE_COMP_MAX_MBAR)
446 return -EINVAL;
447
448 mutex_lock(&state->lock);
449 ret = scd4x_write(state, cmd: CMD_SET_AMB_PRESSURE, arg: val);
450 mutex_unlock(lock: &state->lock);
451
452 return ret;
453 default:
454 return -EINVAL;
455 }
456 default:
457 return -EINVAL;
458 }
459}
460
461static ssize_t calibration_auto_enable_show(struct device *dev,
462 struct device_attribute *attr, char *buf)
463{
464 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
465 struct scd4x_state *state = iio_priv(indio_dev);
466 int ret;
467 __be16 bval;
468 u16 val;
469
470 mutex_lock(&state->lock);
471 ret = scd4x_read(state, cmd: CMD_GET_ASC, response: &bval, response_sz: sizeof(bval));
472 mutex_unlock(lock: &state->lock);
473 if (ret) {
474 dev_err(dev, "failed to read automatic calibration");
475 return ret;
476 }
477
478 val = (be16_to_cpu(bval) & SCD4X_READY_MASK) ? 1 : 0;
479
480 return sysfs_emit(buf, fmt: "%d\n", val);
481}
482
483static ssize_t calibration_auto_enable_store(struct device *dev,
484 struct device_attribute *attr,
485 const char *buf, size_t len)
486{
487 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
488 struct scd4x_state *state = iio_priv(indio_dev);
489 bool val;
490 int ret;
491 uint16_t value;
492
493 ret = kstrtobool(s: buf, res: &val);
494 if (ret)
495 return ret;
496
497 value = val;
498
499 mutex_lock(&state->lock);
500 ret = scd4x_write(state, cmd: CMD_SET_ASC, arg: value);
501 mutex_unlock(lock: &state->lock);
502 if (ret)
503 dev_err(dev, "failed to set automatic calibration");
504
505 return ret ?: len;
506}
507
508static ssize_t calibration_forced_value_store(struct device *dev,
509 struct device_attribute *attr,
510 const char *buf, size_t len)
511{
512 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
513 struct scd4x_state *state = iio_priv(indio_dev);
514 uint16_t val, arg;
515 int ret;
516
517 ret = kstrtou16(s: buf, base: 0, res: &arg);
518 if (ret)
519 return ret;
520
521 if (arg < SCD4X_FRC_MIN_PPM || arg > SCD4X_FRC_MAX_PPM)
522 return -EINVAL;
523
524 mutex_lock(&state->lock);
525 ret = scd4x_write_and_fetch(state, cmd: CMD_FRC, arg, response: &val, response_sz: sizeof(val));
526 mutex_unlock(lock: &state->lock);
527
528 if (ret)
529 return ret;
530
531 if (val == 0xff) {
532 dev_err(dev, "forced calibration has failed");
533 return -EINVAL;
534 }
535
536 return len;
537}
538
539static IIO_DEVICE_ATTR_RW(calibration_auto_enable, 0);
540static IIO_DEVICE_ATTR_WO(calibration_forced_value, 0);
541
542static IIO_CONST_ATTR(calibration_forced_value_available,
543 __stringify([SCD4X_FRC_MIN_PPM 1 SCD4X_FRC_MAX_PPM]));
544
545static struct attribute *scd4x_attrs[] = {
546 &iio_dev_attr_calibration_auto_enable.dev_attr.attr,
547 &iio_dev_attr_calibration_forced_value.dev_attr.attr,
548 &iio_const_attr_calibration_forced_value_available.dev_attr.attr,
549 NULL
550};
551
552static const struct attribute_group scd4x_attr_group = {
553 .attrs = scd4x_attrs,
554};
555
556static const struct iio_info scd4x_info = {
557 .attrs = &scd4x_attr_group,
558 .read_raw = scd4x_read_raw,
559 .write_raw = scd4x_write_raw,
560 .read_avail = scd4x_read_avail,
561};
562
563static const struct iio_chan_spec scd4x_channels[] = {
564 {
565 /*
566 * this channel is special in a sense we are pretending that
567 * sensor is able to change measurement chamber pressure but in
568 * fact we're just setting pressure compensation value
569 */
570 .type = IIO_PRESSURE,
571 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
572 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),
573 .output = 1,
574 .scan_index = -1,
575 },
576 {
577 .type = IIO_CONCENTRATION,
578 .channel2 = IIO_MOD_CO2,
579 .modified = 1,
580 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
581 BIT(IIO_CHAN_INFO_SCALE),
582 .address = SCD4X_CO2,
583 .scan_index = SCD4X_CO2,
584 .scan_type = {
585 .sign = 'u',
586 .realbits = 16,
587 .storagebits = 16,
588 .endianness = IIO_BE,
589 },
590 },
591 {
592 .type = IIO_TEMP,
593 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
594 BIT(IIO_CHAN_INFO_SCALE) |
595 BIT(IIO_CHAN_INFO_OFFSET) |
596 BIT(IIO_CHAN_INFO_CALIBBIAS),
597 .address = SCD4X_TEMP,
598 .scan_index = SCD4X_TEMP,
599 .scan_type = {
600 .sign = 'u',
601 .realbits = 16,
602 .storagebits = 16,
603 .endianness = IIO_BE,
604 },
605 },
606 {
607 .type = IIO_HUMIDITYRELATIVE,
608 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
609 BIT(IIO_CHAN_INFO_SCALE),
610 .address = SCD4X_HR,
611 .scan_index = SCD4X_HR,
612 .scan_type = {
613 .sign = 'u',
614 .realbits = 16,
615 .storagebits = 16,
616 .endianness = IIO_BE,
617 },
618 },
619};
620
621static int scd4x_suspend(struct device *dev)
622{
623 struct iio_dev *indio_dev = dev_get_drvdata(dev);
624 struct scd4x_state *state = iio_priv(indio_dev);
625 int ret;
626
627 ret = scd4x_send_command(state, cmd: CMD_STOP_MEAS);
628 if (ret)
629 return ret;
630
631 return regulator_disable(regulator: state->vdd);
632}
633
634static int scd4x_resume(struct device *dev)
635{
636 struct iio_dev *indio_dev = dev_get_drvdata(dev);
637 struct scd4x_state *state = iio_priv(indio_dev);
638 int ret;
639
640 ret = regulator_enable(regulator: state->vdd);
641 if (ret)
642 return ret;
643
644 return scd4x_send_command(state, cmd: CMD_START_MEAS);
645}
646
647static DEFINE_SIMPLE_DEV_PM_OPS(scd4x_pm_ops, scd4x_suspend, scd4x_resume);
648
649static void scd4x_stop_meas(void *state)
650{
651 scd4x_send_command(state, cmd: CMD_STOP_MEAS);
652}
653
654static void scd4x_disable_regulator(void *data)
655{
656 struct scd4x_state *state = data;
657
658 regulator_disable(regulator: state->vdd);
659}
660
661static irqreturn_t scd4x_trigger_handler(int irq, void *p)
662{
663 struct iio_poll_func *pf = p;
664 struct iio_dev *indio_dev = pf->indio_dev;
665 struct scd4x_state *state = iio_priv(indio_dev);
666 struct {
667 uint16_t data[3];
668 int64_t ts __aligned(8);
669 } scan;
670 int ret;
671
672 memset(&scan, 0, sizeof(scan));
673 mutex_lock(&state->lock);
674 ret = scd4x_read_poll(state, buf: scan.data);
675 mutex_unlock(lock: &state->lock);
676 if (ret)
677 goto out;
678
679 iio_push_to_buffers_with_timestamp(indio_dev, data: &scan, timestamp: iio_get_time_ns(indio_dev));
680out:
681 iio_trigger_notify_done(trig: indio_dev->trig);
682 return IRQ_HANDLED;
683}
684
685static int scd4x_probe(struct i2c_client *client)
686{
687 static const unsigned long scd4x_scan_masks[] = { 0x07, 0x00 };
688 struct device *dev = &client->dev;
689 struct iio_dev *indio_dev;
690 struct scd4x_state *state;
691 int ret;
692
693 indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*state));
694 if (!indio_dev)
695 return -ENOMEM;
696
697 state = iio_priv(indio_dev);
698 mutex_init(&state->lock);
699 state->client = client;
700 crc8_populate_msb(table: scd4x_crc8_table, SCD4X_CRC8_POLYNOMIAL);
701
702 indio_dev->info = &scd4x_info;
703 indio_dev->name = client->name;
704 indio_dev->channels = scd4x_channels;
705 indio_dev->num_channels = ARRAY_SIZE(scd4x_channels);
706 indio_dev->modes = INDIO_DIRECT_MODE;
707 indio_dev->available_scan_masks = scd4x_scan_masks;
708
709 state->vdd = devm_regulator_get(dev, id: "vdd");
710 if (IS_ERR(ptr: state->vdd))
711 return dev_err_probe(dev, err: PTR_ERR(ptr: state->vdd), fmt: "failed to get regulator\n");
712
713 ret = regulator_enable(regulator: state->vdd);
714 if (ret)
715 return ret;
716
717 ret = devm_add_action_or_reset(dev, scd4x_disable_regulator, state);
718 if (ret)
719 return ret;
720
721 ret = scd4x_send_command(state, cmd: CMD_STOP_MEAS);
722 if (ret) {
723 dev_err(dev, "failed to stop measurement: %d\n", ret);
724 return ret;
725 }
726
727 /* execution time */
728 msleep_interruptible(msecs: 500);
729
730 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, scd4x_trigger_handler, NULL);
731 if (ret)
732 return ret;
733
734 ret = scd4x_send_command(state, cmd: CMD_START_MEAS);
735 if (ret) {
736 dev_err(dev, "failed to start measurement: %d\n", ret);
737 return ret;
738 }
739
740 ret = devm_add_action_or_reset(dev, scd4x_stop_meas, state);
741 if (ret)
742 return ret;
743
744 return devm_iio_device_register(dev, indio_dev);
745}
746
747static const struct of_device_id scd4x_dt_ids[] = {
748 { .compatible = "sensirion,scd40" },
749 { .compatible = "sensirion,scd41" },
750 { }
751};
752MODULE_DEVICE_TABLE(of, scd4x_dt_ids);
753
754static struct i2c_driver scd4x_i2c_driver = {
755 .driver = {
756 .name = KBUILD_MODNAME,
757 .of_match_table = scd4x_dt_ids,
758 .pm = pm_sleep_ptr(&scd4x_pm_ops),
759 },
760 .probe = scd4x_probe,
761};
762module_i2c_driver(scd4x_i2c_driver);
763
764MODULE_AUTHOR("Roan van Dijk <roan@protonic.nl>");
765MODULE_DESCRIPTION("Sensirion SCD4X carbon dioxide sensor core driver");
766MODULE_LICENSE("GPL v2");
767

source code of linux/drivers/iio/chemical/scd4x.c