File Index
Files and directories
Sign in
FILE

scd4x.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/chemical/scd4x.c C
  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 <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>
 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, txbuf, 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, rxbuf, 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_STOP_MEAS);
110		if (ret)
111			return ret;
112
113		/* execution time for stopping measurement */
114		msleep_interruptible(500);
115	}
116
117	put_unaligned_be16(cmd, buf);
118	ret = scd4x_i2c_xfer(state, buf, 2, buf, 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_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_STOP_MEAS);
147		if (ret)
148			return ret;
149
150		/* execution time for stopping measurement */
151		msleep_interruptible(500);
152	}
153
154	/* CRC byte for every 2 bytes of data */
155	response_sz += response_sz / 2;
156
157	put_unaligned_be16(cmd, buf);
158	ret = scd4x_i2c_xfer(state, buf, 2, buf, response_sz);
159	if (ret)
160		return ret;
161
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");
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_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(cmd, buf);
191	put_unaligned_be16(arg, buf + 2);
192
193	crc = crc8(scd4x_crc8_table, buf + 2, 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_STOP_MEAS);
199		if (ret)
200			return ret;
201	}
202
203	/* execution time */
204	msleep_interruptible(500);
205
206	ret = scd4x_i2c_xfer(state, buf, SCD4X_WRITE_BUF_SIZE, buf, 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_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_FRC, arg);
230	if (ret)
231		goto err;
232
233	/* execution time */
234	msleep_interruptible(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, 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(scd4x_crc8_table, buf + i, 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_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_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_READ_MEAS, buf, 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_GET_DATA_READY, &bval, 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(1000);
306	} while (--tries);
307
308	/* try to start sensor on timeout */
309	ret = scd4x_send_command(state, 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, 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_GET_AMB_PRESSURE, &tmp, sizeof(tmp));
352			mutex_unlock(&state->lock);
353
354			if (ret)
355				return ret;
356
357			*val = be16_to_cpu(tmp);
358			return IIO_VAL_INT;
359		}
360
361		if (!iio_device_claim_direct(indio_dev))
362			return -EBUSY;
363
364		mutex_lock(&state->lock);
365		ret = scd4x_read_channel(state, chan->address);
366		mutex_unlock(&state->lock);
367
368		iio_device_release_direct(indio_dev);
369		if (ret < 0)
370			return ret;
371
372		*val = ret;
373		return IIO_VAL_INT;
374	case IIO_CHAN_INFO_SCALE:
375		if (chan->type == IIO_CONCENTRATION) {
376			*val = 0;
377			*val2 = 100;
378			return IIO_VAL_INT_PLUS_MICRO;
379		} else if (chan->type == IIO_TEMP) {
380			*val = 175000;
381			*val2 = 65536;
382			return IIO_VAL_FRACTIONAL;
383		} else if (chan->type == IIO_HUMIDITYRELATIVE) {
384			*val = 100000;
385			*val2 = 65536;
386			return IIO_VAL_FRACTIONAL;
387		}
388		return -EINVAL;
389	case IIO_CHAN_INFO_OFFSET:
390		*val = -16852;
391		*val2 = 114286;
392		return IIO_VAL_INT_PLUS_MICRO;
393	case IIO_CHAN_INFO_CALIBBIAS:
394		mutex_lock(&state->lock);
395		ret = scd4x_read(state, CMD_GET_TEMP_OFFSET, &tmp, sizeof(tmp));
396		mutex_unlock(&state->lock);
397		if (ret)
398			return ret;
399
400		*val = be16_to_cpu(tmp);
401
402		return IIO_VAL_INT;
403	default:
404		return -EINVAL;
405	}
406}
407
408static const int scd4x_pressure_calibbias_available[] = {
409	SCD4X_PRESSURE_COMP_MIN_MBAR, 1, SCD4X_PRESSURE_COMP_MAX_MBAR,
410};
411
412static int scd4x_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
413			    const int **vals, int *type, int *length, long mask)
414{
415	switch (mask) {
416	case IIO_CHAN_INFO_RAW:
417		*vals = scd4x_pressure_calibbias_available;
418		*type = IIO_VAL_INT;
419
420		return IIO_AVAIL_RANGE;
421	}
422
423	return -EINVAL;
424}
425
426
427static int scd4x_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
428				int val, int val2, long mask)
429{
430	struct scd4x_state *state = iio_priv(indio_dev);
431	int ret = 0;
432
433	switch (mask) {
434	case IIO_CHAN_INFO_CALIBBIAS:
435		mutex_lock(&state->lock);
436		ret = scd4x_write(state, CMD_SET_TEMP_OFFSET, val);
437		mutex_unlock(&state->lock);
438
439		return ret;
440	case IIO_CHAN_INFO_RAW:
441		switch (chan->type) {
442		case IIO_PRESSURE:
443			if (val < SCD4X_PRESSURE_COMP_MIN_MBAR ||
444			    val > SCD4X_PRESSURE_COMP_MAX_MBAR)
445				return -EINVAL;
446
447			mutex_lock(&state->lock);
448			ret = scd4x_write(state, CMD_SET_AMB_PRESSURE, val);
449			mutex_unlock(&state->lock);
450
451			return ret;
452		default:
453			return -EINVAL;
454		}
455	default:
456		return -EINVAL;
457	}
458}
459
460static ssize_t calibration_auto_enable_show(struct device *dev,
461			struct device_attribute *attr, char *buf)
462{
463	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
464	struct scd4x_state *state = iio_priv(indio_dev);
465	int ret;
466	__be16 bval;
467	u16 val;
468
469	mutex_lock(&state->lock);
470	ret = scd4x_read(state, CMD_GET_ASC, &bval, sizeof(bval));
471	mutex_unlock(&state->lock);
472	if (ret) {
473		dev_err(dev, "failed to read automatic calibration");
474		return ret;
475	}
476
477	val = (be16_to_cpu(bval) & SCD4X_READY_MASK) ? 1 : 0;
478
479	return sysfs_emit(buf, "%d\n", val);
480}
481
482static ssize_t calibration_auto_enable_store(struct device *dev,
483					struct device_attribute *attr,
484					const char *buf, size_t len)
485{
486	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
487	struct scd4x_state *state = iio_priv(indio_dev);
488	bool val;
489	int ret;
490	uint16_t value;
491
492	ret = kstrtobool(buf, &val);
493	if (ret)
494		return ret;
495
496	value = val;
497
498	mutex_lock(&state->lock);
499	ret = scd4x_write(state, CMD_SET_ASC, value);
500	mutex_unlock(&state->lock);
501	if (ret)
502		dev_err(dev, "failed to set automatic calibration");
503
504	return ret ?: len;
505}
506
507static ssize_t calibration_forced_value_store(struct device *dev,
508					struct device_attribute *attr,
509					const char *buf, size_t len)
510{
511	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
512	struct scd4x_state *state = iio_priv(indio_dev);
513	uint16_t val, arg;
514	int ret;
515
516	ret = kstrtou16(buf, 0, &arg);
517	if (ret)
518		return ret;
519
520	if (arg < SCD4X_FRC_MIN_PPM || arg > SCD4X_FRC_MAX_PPM)
521		return -EINVAL;
522
523	mutex_lock(&state->lock);
524	ret = scd4x_write_and_fetch(state, CMD_FRC, arg, &val, sizeof(val));
525	mutex_unlock(&state->lock);
526
527	if (ret)
528		return ret;
529
530	if (val == 0xff) {
531		dev_err(dev, "forced calibration has failed");
532		return -EINVAL;
533	}
534
535	return len;
536}
537
538static IIO_DEVICE_ATTR_RW(calibration_auto_enable, 0);
539static IIO_DEVICE_ATTR_WO(calibration_forced_value, 0);
540
541static IIO_CONST_ATTR(calibration_forced_value_available,
542	       __stringify([SCD4X_FRC_MIN_PPM 1 SCD4X_FRC_MAX_PPM]));
543
544static struct attribute *scd4x_attrs[] = {
545	&iio_dev_attr_calibration_auto_enable.dev_attr.attr,
546	&iio_dev_attr_calibration_forced_value.dev_attr.attr,
547	&iio_const_attr_calibration_forced_value_available.dev_attr.attr,
548	NULL
549};
550
551static const struct attribute_group scd4x_attr_group = {
552	.attrs = scd4x_attrs,
553};
554
555static const struct iio_info scd4x_info = {
556	.attrs = &scd4x_attr_group,
557	.read_raw = scd4x_read_raw,
558	.write_raw = scd4x_write_raw,
559	.read_avail = scd4x_read_avail,
560};
561
562static const struct iio_chan_spec scd4x_channels[] = {
563	{
564		/*
565		 * this channel is special in a sense we are pretending that
566		 * sensor is able to change measurement chamber pressure but in
567		 * fact we're just setting pressure compensation value
568		 */
569		.type = IIO_PRESSURE,
570		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
571		.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),
572		.output = 1,
573		.scan_index = -1,
574	},
575	{
576		.type = IIO_CONCENTRATION,
577		.channel2 = IIO_MOD_CO2,
578		.modified = 1,
579		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
580					BIT(IIO_CHAN_INFO_SCALE),
581		.address = SCD4X_CO2,
582		.scan_index = SCD4X_CO2,
583		.scan_type = {
584			.sign = 'u',
585			.realbits = 16,
586			.storagebits = 16,
587			.endianness = IIO_CPU,
588		},
589	},
590	{
591		.type = IIO_TEMP,
592		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
593					BIT(IIO_CHAN_INFO_SCALE) |
594					BIT(IIO_CHAN_INFO_OFFSET) |
595					BIT(IIO_CHAN_INFO_CALIBBIAS),
596		.address = SCD4X_TEMP,
597		.scan_index = SCD4X_TEMP,
598		.scan_type = {
599			.sign = 'u',
600			.realbits = 16,
601			.storagebits = 16,
602			.endianness = IIO_CPU,
603		},
604	},
605	{
606		.type = IIO_HUMIDITYRELATIVE,
607		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
608					BIT(IIO_CHAN_INFO_SCALE),
609		.address = SCD4X_HR,
610		.scan_index = SCD4X_HR,
611		.scan_type = {
612			.sign = 'u',
613			.realbits = 16,
614			.storagebits = 16,
615			.endianness = IIO_CPU,
616		},
617	},
618};
619
620static int scd4x_suspend(struct device *dev)
621{
622	struct iio_dev *indio_dev = dev_get_drvdata(dev);
623	struct scd4x_state *state  = iio_priv(indio_dev);
624	int ret;
625
626	ret = scd4x_send_command(state, CMD_STOP_MEAS);
627	if (ret)
628		return ret;
629
630	return regulator_disable(state->vdd);
631}
632
633static int scd4x_resume(struct device *dev)
634{
635	struct iio_dev *indio_dev = dev_get_drvdata(dev);
636	struct scd4x_state *state = iio_priv(indio_dev);
637	int ret;
638
639	ret = regulator_enable(state->vdd);
640	if (ret)
641		return ret;
642
643	return scd4x_send_command(state, CMD_START_MEAS);
644}
645
646static DEFINE_SIMPLE_DEV_PM_OPS(scd4x_pm_ops, scd4x_suspend, scd4x_resume);
647
648static void scd4x_stop_meas(void *state)
649{
650	scd4x_send_command(state, CMD_STOP_MEAS);
651}
652
653static void scd4x_disable_regulator(void *data)
654{
655	struct scd4x_state *state = data;
656
657	regulator_disable(state->vdd);
658}
659
660static irqreturn_t scd4x_trigger_handler(int irq, void *p)
661{
662	struct iio_poll_func *pf = p;
663	struct iio_dev *indio_dev = pf->indio_dev;
664	struct scd4x_state *state = iio_priv(indio_dev);
665	struct {
666		uint16_t data[3];
667		aligned_s64 ts;
668	} scan = { };
669	int ret;
670
671	mutex_lock(&state->lock);
672	ret = scd4x_read_poll(state, scan.data);
673	mutex_unlock(&state->lock);
674	if (ret)
675		goto out;
676
677	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
678				    iio_get_time_ns(indio_dev));
679out:
680	iio_trigger_notify_done(indio_dev->trig);
681	return IRQ_HANDLED;
682}
683
684static int scd4x_probe(struct i2c_client *client)
685{
686	static const unsigned long scd4x_scan_masks[] = { 0x07, 0x00 };
687	struct device *dev = &client->dev;
688	struct iio_dev *indio_dev;
689	struct scd4x_state *state;
690	int ret;
691
692	indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
693	if (!indio_dev)
694		return -ENOMEM;
695
696	state = iio_priv(indio_dev);
697	mutex_init(&state->lock);
698	state->client = client;
699	crc8_populate_msb(scd4x_crc8_table, SCD4X_CRC8_POLYNOMIAL);
700
701	indio_dev->info = &scd4x_info;
702	indio_dev->name = client->name;
703	indio_dev->channels = scd4x_channels;
704	indio_dev->num_channels = ARRAY_SIZE(scd4x_channels);
705	indio_dev->modes = INDIO_DIRECT_MODE;
706	indio_dev->available_scan_masks = scd4x_scan_masks;
707
708	state->vdd = devm_regulator_get(dev, "vdd");
709	if (IS_ERR(state->vdd))
710		return dev_err_probe(dev, PTR_ERR(state->vdd), "failed to get regulator\n");
711
712	ret = regulator_enable(state->vdd);
713	if (ret)
714		return ret;
715
716	ret = devm_add_action_or_reset(dev, scd4x_disable_regulator, state);
717	if (ret)
718		return ret;
719
720	ret = scd4x_send_command(state, CMD_STOP_MEAS);
721	if (ret) {
722		dev_err(dev, "failed to stop measurement: %d\n", ret);
723		return ret;
724	}
725
726	/* execution time */
727	msleep_interruptible(500);
728
729	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, scd4x_trigger_handler, NULL);
730	if (ret)
731		return ret;
732
733	ret = scd4x_send_command(state, CMD_START_MEAS);
734	if (ret) {
735		dev_err(dev, "failed to start measurement: %d\n", ret);
736		return ret;
737	}
738
739	ret = devm_add_action_or_reset(dev, scd4x_stop_meas, state);
740	if (ret)
741		return ret;
742
743	return devm_iio_device_register(dev, indio_dev);
744}
745
746static const struct of_device_id scd4x_dt_ids[] = {
747	{ .compatible = "sensirion,scd40" },
748	{ .compatible = "sensirion,scd41" },
749	{ }
750};
751MODULE_DEVICE_TABLE(of, scd4x_dt_ids);
752
753static struct i2c_driver scd4x_i2c_driver = {
754	.driver = {
755		.name = KBUILD_MODNAME,
756		.of_match_table = scd4x_dt_ids,
757		.pm = pm_sleep_ptr(&scd4x_pm_ops),
758	},
759	.probe = scd4x_probe,
760};
761module_i2c_driver(scd4x_i2c_driver);
762
763MODULE_AUTHOR("Roan van Dijk <roan@protonic.nl>");
764MODULE_DESCRIPTION("Sensirion SCD4X carbon dioxide sensor core driver");
765MODULE_LICENSE("GPL v2");
~/ Read-only file preview.