Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Sensirion SCD4X carbon dioxide sensor i2c driver
0004  *
0005  * Copyright (C) 2021 Protonic Holland
0006  * Author: Roan van Dijk <roan@protonic.nl>
0007  *
0008  * I2C slave address: 0x62
0009  *
0010  * Datasheets:
0011  * https://www.sensirion.com/file/datasheet_scd4x
0012  */
0013 
0014 #include <asm/unaligned.h>
0015 #include <linux/crc8.h>
0016 #include <linux/delay.h>
0017 #include <linux/device.h>
0018 #include <linux/i2c.h>
0019 #include <linux/iio/buffer.h>
0020 #include <linux/iio/iio.h>
0021 #include <linux/iio/sysfs.h>
0022 #include <linux/iio/trigger.h>
0023 #include <linux/iio/trigger_consumer.h>
0024 #include <linux/iio/triggered_buffer.h>
0025 #include <linux/iio/types.h>
0026 #include <linux/kernel.h>
0027 #include <linux/mutex.h>
0028 #include <linux/string.h>
0029 #include <linux/sysfs.h>
0030 #include <linux/types.h>
0031 
0032 #define SCD4X_CRC8_POLYNOMIAL 0x31
0033 #define SCD4X_TIMEOUT_ERR 1000
0034 #define SCD4X_READ_BUF_SIZE 9
0035 #define SCD4X_COMMAND_BUF_SIZE 2
0036 #define SCD4X_WRITE_BUF_SIZE 5
0037 #define SCD4X_FRC_MIN_PPM 0
0038 #define SCD4X_FRC_MAX_PPM 2000
0039 #define SCD4X_READY_MASK 0x01
0040 
0041 /*Commands SCD4X*/
0042 enum scd4x_cmd {
0043     CMD_START_MEAS          = 0x21b1,
0044     CMD_READ_MEAS           = 0xec05,
0045     CMD_STOP_MEAS           = 0x3f86,
0046     CMD_SET_TEMP_OFFSET     = 0x241d,
0047     CMD_GET_TEMP_OFFSET     = 0x2318,
0048     CMD_FRC                 = 0x362f,
0049     CMD_SET_ASC             = 0x2416,
0050     CMD_GET_ASC             = 0x2313,
0051     CMD_GET_DATA_READY      = 0xe4b8,
0052 };
0053 
0054 enum scd4x_channel_idx {
0055     SCD4X_CO2,
0056     SCD4X_TEMP,
0057     SCD4X_HR,
0058 };
0059 
0060 struct scd4x_state {
0061     struct i2c_client *client;
0062     /* maintain access to device, to prevent concurrent reads/writes */
0063     struct mutex lock;
0064     struct regulator *vdd;
0065 };
0066 
0067 DECLARE_CRC8_TABLE(scd4x_crc8_table);
0068 
0069 static int scd4x_i2c_xfer(struct scd4x_state *state, char *txbuf, int txsize,
0070                 char *rxbuf, int rxsize)
0071 {
0072     struct i2c_client *client = state->client;
0073     int ret;
0074 
0075     ret = i2c_master_send(client, txbuf, txsize);
0076 
0077     if (ret < 0)
0078         return ret;
0079     if (ret != txsize)
0080         return -EIO;
0081 
0082     if (rxsize == 0)
0083         return 0;
0084 
0085     ret = i2c_master_recv(client, rxbuf, rxsize);
0086     if (ret < 0)
0087         return ret;
0088     if (ret != rxsize)
0089         return -EIO;
0090 
0091     return 0;
0092 }
0093 
0094 static int scd4x_send_command(struct scd4x_state *state, enum scd4x_cmd cmd)
0095 {
0096     char buf[SCD4X_COMMAND_BUF_SIZE];
0097     int ret;
0098 
0099     /*
0100      * Measurement needs to be stopped before sending commands.
0101      * Except stop and start command.
0102      */
0103     if ((cmd != CMD_STOP_MEAS) && (cmd != CMD_START_MEAS)) {
0104 
0105         ret = scd4x_send_command(state, CMD_STOP_MEAS);
0106         if (ret)
0107             return ret;
0108 
0109         /* execution time for stopping measurement */
0110         msleep_interruptible(500);
0111     }
0112 
0113     put_unaligned_be16(cmd, buf);
0114     ret = scd4x_i2c_xfer(state, buf, 2, buf, 0);
0115     if (ret)
0116         return ret;
0117 
0118     if ((cmd != CMD_STOP_MEAS) && (cmd != CMD_START_MEAS)) {
0119         ret = scd4x_send_command(state, CMD_START_MEAS);
0120         if (ret)
0121             return ret;
0122     }
0123 
0124     return 0;
0125 }
0126 
0127 static int scd4x_read(struct scd4x_state *state, enum scd4x_cmd cmd,
0128             void *response, int response_sz)
0129 {
0130     struct i2c_client *client = state->client;
0131     char buf[SCD4X_READ_BUF_SIZE];
0132     char *rsp = response;
0133     int i, ret;
0134     char crc;
0135 
0136     /*
0137      * Measurement needs to be stopped before sending commands.
0138      * Except for reading measurement and data ready command.
0139      */
0140     if ((cmd != CMD_GET_DATA_READY) && (cmd != CMD_READ_MEAS)) {
0141         ret = scd4x_send_command(state, CMD_STOP_MEAS);
0142         if (ret)
0143             return ret;
0144 
0145         /* execution time for stopping measurement */
0146         msleep_interruptible(500);
0147     }
0148 
0149     /* CRC byte for every 2 bytes of data */
0150     response_sz += response_sz / 2;
0151 
0152     put_unaligned_be16(cmd, buf);
0153     ret = scd4x_i2c_xfer(state, buf, 2, buf, response_sz);
0154     if (ret)
0155         return ret;
0156 
0157     for (i = 0; i < response_sz; i += 3) {
0158         crc = crc8(scd4x_crc8_table, buf + i, 2, CRC8_INIT_VALUE);
0159         if (crc != buf[i + 2]) {
0160             dev_err(&client->dev, "CRC error\n");
0161             return -EIO;
0162         }
0163 
0164         *rsp++ = buf[i];
0165         *rsp++ = buf[i + 1];
0166     }
0167 
0168     /* start measurement */
0169     if ((cmd != CMD_GET_DATA_READY) && (cmd != CMD_READ_MEAS)) {
0170         ret = scd4x_send_command(state, CMD_START_MEAS);
0171         if (ret)
0172             return ret;
0173     }
0174 
0175     return 0;
0176 }
0177 
0178 static int scd4x_write(struct scd4x_state *state, enum scd4x_cmd cmd, uint16_t arg)
0179 {
0180     char buf[SCD4X_WRITE_BUF_SIZE];
0181     int ret;
0182     char crc;
0183 
0184     put_unaligned_be16(cmd, buf);
0185     put_unaligned_be16(arg, buf + 2);
0186 
0187     crc = crc8(scd4x_crc8_table, buf + 2, 2, CRC8_INIT_VALUE);
0188     buf[4] = crc;
0189 
0190     /* measurement needs to be stopped before sending commands */
0191     ret = scd4x_send_command(state, CMD_STOP_MEAS);
0192     if (ret)
0193         return ret;
0194 
0195     /* execution time */
0196     msleep_interruptible(500);
0197 
0198     ret = scd4x_i2c_xfer(state, buf, SCD4X_WRITE_BUF_SIZE, buf, 0);
0199     if (ret)
0200         return ret;
0201 
0202     /* start measurement, except for forced calibration command */
0203     if (cmd != CMD_FRC) {
0204         ret = scd4x_send_command(state, CMD_START_MEAS);
0205         if (ret)
0206             return ret;
0207     }
0208 
0209     return 0;
0210 }
0211 
0212 static int scd4x_write_and_fetch(struct scd4x_state *state, enum scd4x_cmd cmd,
0213                 uint16_t arg, void *response, int response_sz)
0214 {
0215     struct i2c_client *client = state->client;
0216     char buf[SCD4X_READ_BUF_SIZE];
0217     char *rsp = response;
0218     int i, ret;
0219     char crc;
0220 
0221     ret = scd4x_write(state, CMD_FRC, arg);
0222     if (ret)
0223         goto err;
0224 
0225     /* execution time */
0226     msleep_interruptible(400);
0227 
0228     /* CRC byte for every 2 bytes of data */
0229     response_sz += response_sz / 2;
0230 
0231     ret = i2c_master_recv(client, buf, response_sz);
0232     if (ret < 0)
0233         goto err;
0234     if (ret != response_sz) {
0235         ret = -EIO;
0236         goto err;
0237     }
0238 
0239     for (i = 0; i < response_sz; i += 3) {
0240         crc = crc8(scd4x_crc8_table, buf + i, 2, CRC8_INIT_VALUE);
0241         if (crc != buf[i + 2]) {
0242             dev_err(&client->dev, "CRC error\n");
0243             ret = -EIO;
0244             goto err;
0245         }
0246 
0247         *rsp++ = buf[i];
0248         *rsp++ = buf[i + 1];
0249     }
0250 
0251     return scd4x_send_command(state, CMD_START_MEAS);
0252 
0253 err:
0254     /*
0255      * on error try to start the measurement,
0256      * puts sensor back into continuous measurement
0257      */
0258     scd4x_send_command(state, CMD_START_MEAS);
0259 
0260     return ret;
0261 }
0262 
0263 static int scd4x_read_meas(struct scd4x_state *state, uint16_t *meas)
0264 {
0265     int i, ret;
0266     __be16 buf[3];
0267 
0268     ret = scd4x_read(state, CMD_READ_MEAS, buf, sizeof(buf));
0269     if (ret)
0270         return ret;
0271 
0272     for (i = 0; i < ARRAY_SIZE(buf); i++)
0273         meas[i] = be16_to_cpu(buf[i]);
0274 
0275     return 0;
0276 }
0277 
0278 static int scd4x_wait_meas_poll(struct scd4x_state *state)
0279 {
0280     struct i2c_client *client = state->client;
0281     int tries = 6;
0282     int ret;
0283 
0284     do {
0285         __be16 bval;
0286         uint16_t val;
0287 
0288         ret = scd4x_read(state, CMD_GET_DATA_READY, &bval, sizeof(bval));
0289         if (ret)
0290             return -EIO;
0291         val = be16_to_cpu(bval);
0292 
0293         /* new measurement available */
0294         if (val & 0x7FF)
0295             return 0;
0296 
0297         msleep_interruptible(1000);
0298     } while (--tries);
0299 
0300     /* try to start sensor on timeout */
0301     ret = scd4x_send_command(state, CMD_START_MEAS);
0302     if (ret)
0303         dev_err(&client->dev, "failed to start measurement: %d\n", ret);
0304 
0305     return -ETIMEDOUT;
0306 }
0307 
0308 static int scd4x_read_poll(struct scd4x_state *state, uint16_t *buf)
0309 {
0310     int ret;
0311 
0312     ret = scd4x_wait_meas_poll(state);
0313     if (ret)
0314         return ret;
0315 
0316     return scd4x_read_meas(state, buf);
0317 }
0318 
0319 static int scd4x_read_channel(struct scd4x_state *state, int chan)
0320 {
0321     int ret;
0322     uint16_t buf[3];
0323 
0324     ret = scd4x_read_poll(state, buf);
0325     if (ret)
0326         return ret;
0327 
0328     return buf[chan];
0329 }
0330 
0331 static int scd4x_read_raw(struct iio_dev *indio_dev,
0332             struct iio_chan_spec const *chan, int *val,
0333             int *val2, long mask)
0334 {
0335     struct scd4x_state *state = iio_priv(indio_dev);
0336     int ret;
0337     __be16 tmp;
0338 
0339     switch (mask) {
0340     case IIO_CHAN_INFO_RAW:
0341         ret = iio_device_claim_direct_mode(indio_dev);
0342         if (ret)
0343             return ret;
0344 
0345         mutex_lock(&state->lock);
0346         ret = scd4x_read_channel(state, chan->address);
0347         mutex_unlock(&state->lock);
0348 
0349         iio_device_release_direct_mode(indio_dev);
0350         if (ret < 0)
0351             return ret;
0352 
0353         *val = ret;
0354         return IIO_VAL_INT;
0355     case IIO_CHAN_INFO_SCALE:
0356         if (chan->type == IIO_CONCENTRATION) {
0357             *val = 0;
0358             *val2 = 100;
0359             return IIO_VAL_INT_PLUS_MICRO;
0360         } else if (chan->type == IIO_TEMP) {
0361             *val = 175000;
0362             *val2 = 65536;
0363             return IIO_VAL_FRACTIONAL;
0364         } else if (chan->type == IIO_HUMIDITYRELATIVE) {
0365             *val = 100000;
0366             *val2 = 65536;
0367             return IIO_VAL_FRACTIONAL;
0368         }
0369         return -EINVAL;
0370     case IIO_CHAN_INFO_OFFSET:
0371         *val = -16852;
0372         *val2 = 114286;
0373         return IIO_VAL_INT_PLUS_MICRO;
0374     case IIO_CHAN_INFO_CALIBBIAS:
0375         mutex_lock(&state->lock);
0376         ret = scd4x_read(state, CMD_GET_TEMP_OFFSET, &tmp, sizeof(tmp));
0377         mutex_unlock(&state->lock);
0378         if (ret)
0379             return ret;
0380 
0381         *val = be16_to_cpu(tmp);
0382 
0383         return IIO_VAL_INT;
0384     default:
0385         return -EINVAL;
0386     }
0387 }
0388 
0389 static int scd4x_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
0390                 int val, int val2, long mask)
0391 {
0392     struct scd4x_state *state = iio_priv(indio_dev);
0393     int ret = 0;
0394 
0395     switch (mask) {
0396     case IIO_CHAN_INFO_CALIBBIAS:
0397         mutex_lock(&state->lock);
0398         ret = scd4x_write(state, CMD_SET_TEMP_OFFSET, val);
0399         mutex_unlock(&state->lock);
0400 
0401         return ret;
0402     default:
0403         return -EINVAL;
0404     }
0405 }
0406 
0407 static ssize_t calibration_auto_enable_show(struct device *dev,
0408             struct device_attribute *attr, char *buf)
0409 {
0410     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0411     struct scd4x_state *state = iio_priv(indio_dev);
0412     int ret;
0413     __be16 bval;
0414     u16 val;
0415 
0416     mutex_lock(&state->lock);
0417     ret = scd4x_read(state, CMD_GET_ASC, &bval, sizeof(bval));
0418     mutex_unlock(&state->lock);
0419     if (ret) {
0420         dev_err(dev, "failed to read automatic calibration");
0421         return ret;
0422     }
0423 
0424     val = (be16_to_cpu(bval) & SCD4X_READY_MASK) ? 1 : 0;
0425 
0426     return sysfs_emit(buf, "%d\n", val);
0427 }
0428 
0429 static ssize_t calibration_auto_enable_store(struct device *dev,
0430                     struct device_attribute *attr,
0431                     const char *buf, size_t len)
0432 {
0433     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0434     struct scd4x_state *state = iio_priv(indio_dev);
0435     bool val;
0436     int ret;
0437     uint16_t value;
0438 
0439     ret = kstrtobool(buf, &val);
0440     if (ret)
0441         return ret;
0442 
0443     value = val;
0444 
0445     mutex_lock(&state->lock);
0446     ret = scd4x_write(state, CMD_SET_ASC, value);
0447     mutex_unlock(&state->lock);
0448     if (ret)
0449         dev_err(dev, "failed to set automatic calibration");
0450 
0451     return ret ?: len;
0452 }
0453 
0454 static ssize_t calibration_forced_value_store(struct device *dev,
0455                     struct device_attribute *attr,
0456                     const char *buf, size_t len)
0457 {
0458     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0459     struct scd4x_state *state = iio_priv(indio_dev);
0460     uint16_t val, arg;
0461     int ret;
0462 
0463     ret = kstrtou16(buf, 0, &arg);
0464     if (ret)
0465         return ret;
0466 
0467     if (arg < SCD4X_FRC_MIN_PPM || arg > SCD4X_FRC_MAX_PPM)
0468         return -EINVAL;
0469 
0470     mutex_lock(&state->lock);
0471     ret = scd4x_write_and_fetch(state, CMD_FRC, arg, &val, sizeof(val));
0472     mutex_unlock(&state->lock);
0473 
0474     if (ret)
0475         return ret;
0476 
0477     if (val == 0xff) {
0478         dev_err(dev, "forced calibration has failed");
0479         return -EINVAL;
0480     }
0481 
0482     return len;
0483 }
0484 
0485 static IIO_DEVICE_ATTR_RW(calibration_auto_enable, 0);
0486 static IIO_DEVICE_ATTR_WO(calibration_forced_value, 0);
0487 
0488 static IIO_CONST_ATTR(calibration_forced_value_available,
0489            __stringify([SCD4X_FRC_MIN_PPM 1 SCD4X_FRC_MAX_PPM]));
0490 
0491 static struct attribute *scd4x_attrs[] = {
0492     &iio_dev_attr_calibration_auto_enable.dev_attr.attr,
0493     &iio_dev_attr_calibration_forced_value.dev_attr.attr,
0494     &iio_const_attr_calibration_forced_value_available.dev_attr.attr,
0495     NULL
0496 };
0497 
0498 static const struct attribute_group scd4x_attr_group = {
0499     .attrs = scd4x_attrs,
0500 };
0501 
0502 static const struct iio_info scd4x_info = {
0503     .attrs = &scd4x_attr_group,
0504     .read_raw = scd4x_read_raw,
0505     .write_raw = scd4x_write_raw,
0506 };
0507 
0508 static const struct iio_chan_spec scd4x_channels[] = {
0509     {
0510         .type = IIO_CONCENTRATION,
0511         .channel2 = IIO_MOD_CO2,
0512         .modified = 1,
0513         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0514                     BIT(IIO_CHAN_INFO_SCALE),
0515         .address = SCD4X_CO2,
0516         .scan_index = SCD4X_CO2,
0517         .scan_type = {
0518             .sign = 'u',
0519             .realbits = 16,
0520             .storagebits = 16,
0521             .endianness = IIO_BE,
0522         },
0523     },
0524     {
0525         .type = IIO_TEMP,
0526         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0527                     BIT(IIO_CHAN_INFO_SCALE) |
0528                     BIT(IIO_CHAN_INFO_OFFSET) |
0529                     BIT(IIO_CHAN_INFO_CALIBBIAS),
0530         .address = SCD4X_TEMP,
0531         .scan_index = SCD4X_TEMP,
0532         .scan_type = {
0533             .sign = 'u',
0534             .realbits = 16,
0535             .storagebits = 16,
0536             .endianness = IIO_BE,
0537         },
0538     },
0539     {
0540         .type = IIO_HUMIDITYRELATIVE,
0541         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0542                     BIT(IIO_CHAN_INFO_SCALE),
0543         .address = SCD4X_HR,
0544         .scan_index = SCD4X_HR,
0545         .scan_type = {
0546             .sign = 'u',
0547             .realbits = 16,
0548             .storagebits = 16,
0549             .endianness = IIO_BE,
0550         },
0551     },
0552 };
0553 
0554 static int scd4x_suspend(struct device *dev)
0555 {
0556     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0557     struct scd4x_state *state  = iio_priv(indio_dev);
0558     int ret;
0559 
0560     ret = scd4x_send_command(state, CMD_STOP_MEAS);
0561     if (ret)
0562         return ret;
0563 
0564     return regulator_disable(state->vdd);
0565 }
0566 
0567 static int scd4x_resume(struct device *dev)
0568 {
0569     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0570     struct scd4x_state *state = iio_priv(indio_dev);
0571     int ret;
0572 
0573     ret = regulator_enable(state->vdd);
0574     if (ret)
0575         return ret;
0576 
0577     return scd4x_send_command(state, CMD_START_MEAS);
0578 }
0579 
0580 static DEFINE_SIMPLE_DEV_PM_OPS(scd4x_pm_ops, scd4x_suspend, scd4x_resume);
0581 
0582 static void scd4x_stop_meas(void *state)
0583 {
0584     scd4x_send_command(state, CMD_STOP_MEAS);
0585 }
0586 
0587 static void scd4x_disable_regulator(void *data)
0588 {
0589     struct scd4x_state *state = data;
0590 
0591     regulator_disable(state->vdd);
0592 }
0593 
0594 static irqreturn_t scd4x_trigger_handler(int irq, void *p)
0595 {
0596     struct iio_poll_func *pf = p;
0597     struct iio_dev *indio_dev = pf->indio_dev;
0598     struct scd4x_state *state = iio_priv(indio_dev);
0599     struct {
0600         uint16_t data[3];
0601         int64_t ts __aligned(8);
0602     } scan;
0603     int ret;
0604 
0605     memset(&scan, 0, sizeof(scan));
0606     mutex_lock(&state->lock);
0607     ret = scd4x_read_poll(state, scan.data);
0608     mutex_unlock(&state->lock);
0609     if (ret)
0610         goto out;
0611 
0612     iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev));
0613 out:
0614     iio_trigger_notify_done(indio_dev->trig);
0615     return IRQ_HANDLED;
0616 }
0617 
0618 static int scd4x_probe(struct i2c_client *client, const struct i2c_device_id *id)
0619 {
0620     static const unsigned long scd4x_scan_masks[] = { 0x07, 0x00 };
0621     struct device *dev = &client->dev;
0622     struct iio_dev *indio_dev;
0623     struct scd4x_state *state;
0624     int ret;
0625 
0626     indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
0627     if (!indio_dev)
0628         return -ENOMEM;
0629 
0630     state = iio_priv(indio_dev);
0631     mutex_init(&state->lock);
0632     state->client = client;
0633     crc8_populate_msb(scd4x_crc8_table, SCD4X_CRC8_POLYNOMIAL);
0634 
0635     indio_dev->info = &scd4x_info;
0636     indio_dev->name = client->name;
0637     indio_dev->channels = scd4x_channels;
0638     indio_dev->num_channels = ARRAY_SIZE(scd4x_channels);
0639     indio_dev->modes = INDIO_DIRECT_MODE;
0640     indio_dev->available_scan_masks = scd4x_scan_masks;
0641 
0642     state->vdd = devm_regulator_get(dev, "vdd");
0643     if (IS_ERR(state->vdd))
0644         return dev_err_probe(dev, PTR_ERR(state->vdd), "failed to get regulator\n");
0645 
0646     ret = regulator_enable(state->vdd);
0647     if (ret)
0648         return ret;
0649 
0650     ret = devm_add_action_or_reset(dev, scd4x_disable_regulator, state);
0651     if (ret)
0652         return ret;
0653 
0654     ret = scd4x_send_command(state, CMD_STOP_MEAS);
0655     if (ret) {
0656         dev_err(dev, "failed to stop measurement: %d\n", ret);
0657         return ret;
0658     }
0659 
0660     /* execution time */
0661     msleep_interruptible(500);
0662 
0663     ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, scd4x_trigger_handler, NULL);
0664     if (ret)
0665         return ret;
0666 
0667     ret = scd4x_send_command(state, CMD_START_MEAS);
0668     if (ret) {
0669         dev_err(dev, "failed to start measurement: %d\n", ret);
0670         return ret;
0671     }
0672 
0673     ret = devm_add_action_or_reset(dev, scd4x_stop_meas, state);
0674     if (ret)
0675         return ret;
0676 
0677     return devm_iio_device_register(dev, indio_dev);
0678 }
0679 
0680 static const struct of_device_id scd4x_dt_ids[] = {
0681     { .compatible = "sensirion,scd40" },
0682     { .compatible = "sensirion,scd41" },
0683     { }
0684 };
0685 MODULE_DEVICE_TABLE(of, scd4x_dt_ids);
0686 
0687 static struct i2c_driver scd4x_i2c_driver = {
0688     .driver = {
0689         .name = KBUILD_MODNAME,
0690         .of_match_table = scd4x_dt_ids,
0691         .pm = pm_sleep_ptr(&scd4x_pm_ops),
0692     },
0693     .probe = scd4x_probe,
0694 };
0695 module_i2c_driver(scd4x_i2c_driver);
0696 
0697 MODULE_AUTHOR("Roan van Dijk <roan@protonic.nl>");
0698 MODULE_DESCRIPTION("Sensirion SCD4X carbon dioxide sensor core driver");
0699 MODULE_LICENSE("GPL v2");