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