1 // SPDX-License-Identifier: GPL-2.0
3 * Sensirion SCD4X carbon dioxide sensor i2c driver
5 * Copyright (C) 2021 Protonic Holland
6 * Author: Roan van Dijk <roan@protonic.nl>
8 * I2C slave address: 0x62
11 * https://www.sensirion.com/file/datasheet_scd4x
14 #include <linux/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>
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
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,
55 CMD_GET_DATA_READY
= 0xe4b8,
58 enum scd4x_channel_idx
{
65 struct i2c_client
*client
;
66 /* maintain access to device, to prevent concurrent reads/writes */
68 struct regulator
*vdd
;
71 DECLARE_CRC8_TABLE(scd4x_crc8_table
);
73 static int scd4x_i2c_xfer(struct scd4x_state
*state
, char *txbuf
, int txsize
,
74 char *rxbuf
, int rxsize
)
76 struct i2c_client
*client
= state
->client
;
79 ret
= i2c_master_send(client
, txbuf
, txsize
);
89 ret
= i2c_master_recv(client
, rxbuf
, rxsize
);
98 static int scd4x_send_command(struct scd4x_state
*state
, enum scd4x_cmd cmd
)
100 char buf
[SCD4X_COMMAND_BUF_SIZE
];
104 * Measurement needs to be stopped before sending commands.
105 * Except stop and start command.
107 if ((cmd
!= CMD_STOP_MEAS
) && (cmd
!= CMD_START_MEAS
)) {
109 ret
= scd4x_send_command(state
, CMD_STOP_MEAS
);
113 /* execution time for stopping measurement */
114 msleep_interruptible(500);
117 put_unaligned_be16(cmd
, buf
);
118 ret
= scd4x_i2c_xfer(state
, buf
, 2, buf
, 0);
122 if ((cmd
!= CMD_STOP_MEAS
) && (cmd
!= CMD_START_MEAS
)) {
123 ret
= scd4x_send_command(state
, CMD_START_MEAS
);
131 static int scd4x_read(struct scd4x_state
*state
, enum scd4x_cmd cmd
,
132 void *response
, int response_sz
)
134 struct i2c_client
*client
= state
->client
;
135 char buf
[SCD4X_READ_BUF_SIZE
];
136 char *rsp
= response
;
141 * Measurement needs to be stopped before sending commands.
142 * Except for reading measurement and data ready command.
144 if ((cmd
!= CMD_GET_DATA_READY
) && (cmd
!= CMD_READ_MEAS
) &&
145 (cmd
!= CMD_GET_AMB_PRESSURE
)) {
146 ret
= scd4x_send_command(state
, CMD_STOP_MEAS
);
150 /* execution time for stopping measurement */
151 msleep_interruptible(500);
154 /* CRC byte for every 2 bytes of data */
155 response_sz
+= response_sz
/ 2;
157 put_unaligned_be16(cmd
, buf
);
158 ret
= scd4x_i2c_xfer(state
, buf
, 2, buf
, response_sz
);
162 for (i
= 0; i
< response_sz
; i
+= 3) {
163 crc
= crc8(scd4x_crc8_table
, buf
+ i
, 2, CRC8_INIT_VALUE
);
164 if (crc
!= buf
[i
+ 2]) {
165 dev_err(&client
->dev
, "CRC error\n");
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_START_MEAS
);
184 static int scd4x_write(struct scd4x_state
*state
, enum scd4x_cmd cmd
, uint16_t arg
)
186 char buf
[SCD4X_WRITE_BUF_SIZE
];
190 put_unaligned_be16(cmd
, buf
);
191 put_unaligned_be16(arg
, buf
+ 2);
193 crc
= crc8(scd4x_crc8_table
, buf
+ 2, 2, CRC8_INIT_VALUE
);
196 /* measurement needs to be stopped before sending commands */
197 if (cmd
!= CMD_SET_AMB_PRESSURE
) {
198 ret
= scd4x_send_command(state
, CMD_STOP_MEAS
);
204 msleep_interruptible(500);
206 ret
= scd4x_i2c_xfer(state
, buf
, SCD4X_WRITE_BUF_SIZE
, buf
, 0);
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_START_MEAS
);
220 static int scd4x_write_and_fetch(struct scd4x_state
*state
, enum scd4x_cmd cmd
,
221 uint16_t arg
, void *response
, int response_sz
)
223 struct i2c_client
*client
= state
->client
;
224 char buf
[SCD4X_READ_BUF_SIZE
];
225 char *rsp
= response
;
229 ret
= scd4x_write(state
, CMD_FRC
, arg
);
234 msleep_interruptible(400);
236 /* CRC byte for every 2 bytes of data */
237 response_sz
+= response_sz
/ 2;
239 ret
= i2c_master_recv(client
, buf
, response_sz
);
242 if (ret
!= response_sz
) {
247 for (i
= 0; i
< response_sz
; i
+= 3) {
248 crc
= crc8(scd4x_crc8_table
, buf
+ i
, 2, CRC8_INIT_VALUE
);
249 if (crc
!= buf
[i
+ 2]) {
250 dev_err(&client
->dev
, "CRC error\n");
259 return scd4x_send_command(state
, CMD_START_MEAS
);
263 * on error try to start the measurement,
264 * puts sensor back into continuous measurement
266 scd4x_send_command(state
, CMD_START_MEAS
);
271 static int scd4x_read_meas(struct scd4x_state
*state
, uint16_t *meas
)
276 ret
= scd4x_read(state
, CMD_READ_MEAS
, buf
, sizeof(buf
));
280 for (i
= 0; i
< ARRAY_SIZE(buf
); i
++)
281 meas
[i
] = be16_to_cpu(buf
[i
]);
286 static int scd4x_wait_meas_poll(struct scd4x_state
*state
)
288 struct i2c_client
*client
= state
->client
;
296 ret
= scd4x_read(state
, CMD_GET_DATA_READY
, &bval
, sizeof(bval
));
299 val
= be16_to_cpu(bval
);
301 /* new measurement available */
305 msleep_interruptible(1000);
308 /* try to start sensor on timeout */
309 ret
= scd4x_send_command(state
, CMD_START_MEAS
);
311 dev_err(&client
->dev
, "failed to start measurement: %d\n", ret
);
316 static int scd4x_read_poll(struct scd4x_state
*state
, uint16_t *buf
)
320 ret
= scd4x_wait_meas_poll(state
);
324 return scd4x_read_meas(state
, buf
);
327 static int scd4x_read_channel(struct scd4x_state
*state
, int chan
)
332 ret
= scd4x_read_poll(state
, buf
);
339 static int scd4x_read_raw(struct iio_dev
*indio_dev
,
340 struct iio_chan_spec
const *chan
, int *val
,
341 int *val2
, long mask
)
343 struct scd4x_state
*state
= iio_priv(indio_dev
);
348 case IIO_CHAN_INFO_RAW
:
350 mutex_lock(&state
->lock
);
351 ret
= scd4x_read(state
, CMD_GET_AMB_PRESSURE
, &tmp
, sizeof(tmp
));
352 mutex_unlock(&state
->lock
);
357 *val
= be16_to_cpu(tmp
);
361 ret
= iio_device_claim_direct_mode(indio_dev
);
365 mutex_lock(&state
->lock
);
366 ret
= scd4x_read_channel(state
, chan
->address
);
367 mutex_unlock(&state
->lock
);
369 iio_device_release_direct_mode(indio_dev
);
375 case IIO_CHAN_INFO_SCALE
:
376 if (chan
->type
== IIO_CONCENTRATION
) {
379 return IIO_VAL_INT_PLUS_MICRO
;
380 } else if (chan
->type
== IIO_TEMP
) {
383 return IIO_VAL_FRACTIONAL
;
384 } else if (chan
->type
== IIO_HUMIDITYRELATIVE
) {
387 return IIO_VAL_FRACTIONAL
;
390 case IIO_CHAN_INFO_OFFSET
:
393 return IIO_VAL_INT_PLUS_MICRO
;
394 case IIO_CHAN_INFO_CALIBBIAS
:
395 mutex_lock(&state
->lock
);
396 ret
= scd4x_read(state
, CMD_GET_TEMP_OFFSET
, &tmp
, sizeof(tmp
));
397 mutex_unlock(&state
->lock
);
401 *val
= be16_to_cpu(tmp
);
409 static const int scd4x_pressure_calibbias_available
[] = {
410 SCD4X_PRESSURE_COMP_MIN_MBAR
, 1, SCD4X_PRESSURE_COMP_MAX_MBAR
,
413 static 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
)
417 case IIO_CHAN_INFO_RAW
:
418 *vals
= scd4x_pressure_calibbias_available
;
421 return IIO_AVAIL_RANGE
;
428 static int scd4x_write_raw(struct iio_dev
*indio_dev
, struct iio_chan_spec
const *chan
,
429 int val
, int val2
, long mask
)
431 struct scd4x_state
*state
= iio_priv(indio_dev
);
435 case IIO_CHAN_INFO_CALIBBIAS
:
436 mutex_lock(&state
->lock
);
437 ret
= scd4x_write(state
, CMD_SET_TEMP_OFFSET
, val
);
438 mutex_unlock(&state
->lock
);
441 case IIO_CHAN_INFO_RAW
:
442 switch (chan
->type
) {
444 if (val
< SCD4X_PRESSURE_COMP_MIN_MBAR
||
445 val
> SCD4X_PRESSURE_COMP_MAX_MBAR
)
448 mutex_lock(&state
->lock
);
449 ret
= scd4x_write(state
, CMD_SET_AMB_PRESSURE
, val
);
450 mutex_unlock(&state
->lock
);
461 static ssize_t
calibration_auto_enable_show(struct device
*dev
,
462 struct device_attribute
*attr
, char *buf
)
464 struct iio_dev
*indio_dev
= dev_to_iio_dev(dev
);
465 struct scd4x_state
*state
= iio_priv(indio_dev
);
470 mutex_lock(&state
->lock
);
471 ret
= scd4x_read(state
, CMD_GET_ASC
, &bval
, sizeof(bval
));
472 mutex_unlock(&state
->lock
);
474 dev_err(dev
, "failed to read automatic calibration");
478 val
= (be16_to_cpu(bval
) & SCD4X_READY_MASK
) ? 1 : 0;
480 return sysfs_emit(buf
, "%d\n", val
);
483 static ssize_t
calibration_auto_enable_store(struct device
*dev
,
484 struct device_attribute
*attr
,
485 const char *buf
, size_t len
)
487 struct iio_dev
*indio_dev
= dev_to_iio_dev(dev
);
488 struct scd4x_state
*state
= iio_priv(indio_dev
);
493 ret
= kstrtobool(buf
, &val
);
499 mutex_lock(&state
->lock
);
500 ret
= scd4x_write(state
, CMD_SET_ASC
, value
);
501 mutex_unlock(&state
->lock
);
503 dev_err(dev
, "failed to set automatic calibration");
508 static ssize_t
calibration_forced_value_store(struct device
*dev
,
509 struct device_attribute
*attr
,
510 const char *buf
, size_t len
)
512 struct iio_dev
*indio_dev
= dev_to_iio_dev(dev
);
513 struct scd4x_state
*state
= iio_priv(indio_dev
);
517 ret
= kstrtou16(buf
, 0, &arg
);
521 if (arg
< SCD4X_FRC_MIN_PPM
|| arg
> SCD4X_FRC_MAX_PPM
)
524 mutex_lock(&state
->lock
);
525 ret
= scd4x_write_and_fetch(state
, CMD_FRC
, arg
, &val
, sizeof(val
));
526 mutex_unlock(&state
->lock
);
532 dev_err(dev
, "forced calibration has failed");
539 static IIO_DEVICE_ATTR_RW(calibration_auto_enable
, 0);
540 static IIO_DEVICE_ATTR_WO(calibration_forced_value
, 0);
542 static IIO_CONST_ATTR(calibration_forced_value_available
,
543 __stringify([SCD4X_FRC_MIN_PPM
1 SCD4X_FRC_MAX_PPM
]));
545 static 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
,
552 static const struct attribute_group scd4x_attr_group
= {
553 .attrs
= scd4x_attrs
,
556 static 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
,
563 static const struct iio_chan_spec scd4x_channels
[] = {
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
570 .type
= IIO_PRESSURE
,
571 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
572 .info_mask_separate_available
= BIT(IIO_CHAN_INFO_RAW
),
577 .type
= IIO_CONCENTRATION
,
578 .channel2
= IIO_MOD_CO2
,
580 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
581 BIT(IIO_CHAN_INFO_SCALE
),
582 .address
= SCD4X_CO2
,
583 .scan_index
= SCD4X_CO2
,
588 .endianness
= IIO_BE
,
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
,
603 .endianness
= IIO_BE
,
607 .type
= IIO_HUMIDITYRELATIVE
,
608 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
609 BIT(IIO_CHAN_INFO_SCALE
),
611 .scan_index
= SCD4X_HR
,
616 .endianness
= IIO_BE
,
621 static int scd4x_suspend(struct device
*dev
)
623 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
624 struct scd4x_state
*state
= iio_priv(indio_dev
);
627 ret
= scd4x_send_command(state
, CMD_STOP_MEAS
);
631 return regulator_disable(state
->vdd
);
634 static int scd4x_resume(struct device
*dev
)
636 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
637 struct scd4x_state
*state
= iio_priv(indio_dev
);
640 ret
= regulator_enable(state
->vdd
);
644 return scd4x_send_command(state
, CMD_START_MEAS
);
647 static DEFINE_SIMPLE_DEV_PM_OPS(scd4x_pm_ops
, scd4x_suspend
, scd4x_resume
);
649 static void scd4x_stop_meas(void *state
)
651 scd4x_send_command(state
, CMD_STOP_MEAS
);
654 static void scd4x_disable_regulator(void *data
)
656 struct scd4x_state
*state
= data
;
658 regulator_disable(state
->vdd
);
661 static irqreturn_t
scd4x_trigger_handler(int irq
, void *p
)
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
);
668 int64_t ts
__aligned(8);
672 memset(&scan
, 0, sizeof(scan
));
673 mutex_lock(&state
->lock
);
674 ret
= scd4x_read_poll(state
, scan
.data
);
675 mutex_unlock(&state
->lock
);
679 iio_push_to_buffers_with_timestamp(indio_dev
, &scan
, iio_get_time_ns(indio_dev
));
681 iio_trigger_notify_done(indio_dev
->trig
);
685 static int scd4x_probe(struct i2c_client
*client
)
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
;
693 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*state
));
697 state
= iio_priv(indio_dev
);
698 mutex_init(&state
->lock
);
699 state
->client
= client
;
700 crc8_populate_msb(scd4x_crc8_table
, SCD4X_CRC8_POLYNOMIAL
);
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
;
709 state
->vdd
= devm_regulator_get(dev
, "vdd");
710 if (IS_ERR(state
->vdd
))
711 return dev_err_probe(dev
, PTR_ERR(state
->vdd
), "failed to get regulator\n");
713 ret
= regulator_enable(state
->vdd
);
717 ret
= devm_add_action_or_reset(dev
, scd4x_disable_regulator
, state
);
721 ret
= scd4x_send_command(state
, CMD_STOP_MEAS
);
723 dev_err(dev
, "failed to stop measurement: %d\n", ret
);
728 msleep_interruptible(500);
730 ret
= devm_iio_triggered_buffer_setup(dev
, indio_dev
, NULL
, scd4x_trigger_handler
, NULL
);
734 ret
= scd4x_send_command(state
, CMD_START_MEAS
);
736 dev_err(dev
, "failed to start measurement: %d\n", ret
);
740 ret
= devm_add_action_or_reset(dev
, scd4x_stop_meas
, state
);
744 return devm_iio_device_register(dev
, indio_dev
);
747 static const struct of_device_id scd4x_dt_ids
[] = {
748 { .compatible
= "sensirion,scd40" },
749 { .compatible
= "sensirion,scd41" },
752 MODULE_DEVICE_TABLE(of
, scd4x_dt_ids
);
754 static struct i2c_driver scd4x_i2c_driver
= {
756 .name
= KBUILD_MODNAME
,
757 .of_match_table
= scd4x_dt_ids
,
758 .pm
= pm_sleep_ptr(&scd4x_pm_ops
),
760 .probe
= scd4x_probe
,
762 module_i2c_driver(scd4x_i2c_driver
);
764 MODULE_AUTHOR("Roan van Dijk <roan@protonic.nl>");
765 MODULE_DESCRIPTION("Sensirion SCD4X carbon dioxide sensor core driver");
766 MODULE_LICENSE("GPL v2");