diff options
Diffstat (limited to 'drivers/iio/chemical')
-rw-r--r-- | drivers/iio/chemical/Kconfig | 11 | ||||
-rw-r--r-- | drivers/iio/chemical/Makefile | 1 | ||||
-rw-r--r-- | drivers/iio/chemical/atlas-ezo-sensor.c | 177 | ||||
-rw-r--r-- | drivers/iio/chemical/atlas-sensor.c | 50 | ||||
-rw-r--r-- | drivers/iio/chemical/bme680_core.c | 36 | ||||
-rw-r--r-- | drivers/iio/chemical/ccs811.c | 112 | ||||
-rw-r--r-- | drivers/iio/chemical/pms7003.c | 17 | ||||
-rw-r--r-- | drivers/iio/chemical/sps30.c | 9 |
8 files changed, 375 insertions, 38 deletions
diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig index a7e65a59bf42..7f21afd73b1c 100644 --- a/drivers/iio/chemical/Kconfig +++ b/drivers/iio/chemical/Kconfig @@ -22,6 +22,17 @@ config ATLAS_PH_SENSOR To compile this driver as module, choose M here: the module will be called atlas-ph-sensor. +config ATLAS_EZO_SENSOR + tristate "Atlas Scientific EZO sensors" + depends on I2C + help + Say Y here to build I2C interface support for the following + Atlas Scientific EZO sensors + * CO2 EZO Sensor + + To compile this driver as module, choose M here: the + module will be called atlas-ezo-sensor. + config BME680 tristate "Bosch Sensortec BME680 sensor driver" depends on (I2C || SPI) diff --git a/drivers/iio/chemical/Makefile b/drivers/iio/chemical/Makefile index 33d3a595dda9..aba4167db745 100644 --- a/drivers/iio/chemical/Makefile +++ b/drivers/iio/chemical/Makefile @@ -5,6 +5,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_ATLAS_PH_SENSOR) += atlas-sensor.o +obj-$(CONFIG_ATLAS_EZO_SENSOR) += atlas-ezo-sensor.o obj-$(CONFIG_BME680) += bme680_core.o obj-$(CONFIG_BME680_I2C) += bme680_i2c.o obj-$(CONFIG_BME680_SPI) += bme680_spi.o diff --git a/drivers/iio/chemical/atlas-ezo-sensor.c b/drivers/iio/chemical/atlas-ezo-sensor.c new file mode 100644 index 000000000000..f5a6d8ec6d4d --- /dev/null +++ b/drivers/iio/chemical/atlas-ezo-sensor.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * atlas-ezo-sensor.c - Support for Atlas Scientific EZO sensors + * + * Copyright (C) 2020 Konsulko Group + * Author: Matt Ranostay <matt.ranostay@konsulko.com> + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/of_device.h> +#include <linux/iio/iio.h> + +#define ATLAS_EZO_DRV_NAME "atlas-ezo-sensor" +#define ATLAS_CO2_INT_TIME_IN_MS 950 + +enum { + ATLAS_CO2_EZO, +}; + +struct atlas_ezo_device { + const struct iio_chan_spec *channels; + int num_channels; + int delay; +}; + +struct atlas_ezo_data { + struct i2c_client *client; + struct atlas_ezo_device *chip; + + /* lock to avoid multiple concurrent read calls */ + struct mutex lock; + + u8 buffer[8]; +}; + +static const struct iio_chan_spec atlas_co2_ezo_channels[] = { + { + .type = IIO_CONCENTRATION, + .modified = 1, + .channel2 = IIO_MOD_CO2, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_CPU, + }, + }, +}; + +static struct atlas_ezo_device atlas_ezo_devices[] = { + [ATLAS_CO2_EZO] = { + .channels = atlas_co2_ezo_channels, + .num_channels = 1, + .delay = ATLAS_CO2_INT_TIME_IN_MS, + }, +}; + +static int atlas_ezo_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct atlas_ezo_data *data = iio_priv(indio_dev); + struct i2c_client *client = data->client; + int ret = 0; + + if (chan->type != IIO_CONCENTRATION) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: { + long tmp; + + mutex_lock(&data->lock); + + tmp = i2c_smbus_write_byte(client, 'R'); + + if (tmp < 0) { + mutex_unlock(&data->lock); + return tmp; + } + + msleep(data->chip->delay); + + tmp = i2c_master_recv(client, data->buffer, sizeof(data->buffer)); + + if (tmp < 0 || data->buffer[0] != 1) { + mutex_unlock(&data->lock); + return -EBUSY; + } + + ret = kstrtol(data->buffer + 1, 10, &tmp); + + *val = tmp; + + mutex_unlock(&data->lock); + + return ret ? ret : IIO_VAL_INT; + } + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = 100; /* 0.0001 */ + return IIO_VAL_INT_PLUS_MICRO; + } + + return ret; +} + +static const struct iio_info atlas_info = { + .read_raw = atlas_ezo_read_raw, +}; + +static const struct i2c_device_id atlas_ezo_id[] = { + { "atlas-co2-ezo", ATLAS_CO2_EZO }, + {} +}; +MODULE_DEVICE_TABLE(i2c, atlas_ezo_id); + +static const struct of_device_id atlas_ezo_dt_ids[] = { + { .compatible = "atlas,co2-ezo", .data = (void *)ATLAS_CO2_EZO, }, + {} +}; +MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids); + +static int atlas_ezo_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct atlas_ezo_data *data; + struct atlas_ezo_device *chip; + const struct of_device_id *of_id; + struct iio_dev *indio_dev; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + of_id = of_match_device(atlas_ezo_dt_ids, &client->dev); + if (!of_id) + chip = &atlas_ezo_devices[id->driver_data]; + else + chip = &atlas_ezo_devices[(unsigned long)of_id->data]; + + indio_dev->info = &atlas_info; + indio_dev->name = ATLAS_EZO_DRV_NAME; + indio_dev->channels = chip->channels; + indio_dev->num_channels = chip->num_channels; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->dev.parent = &client->dev; + + data = iio_priv(indio_dev); + data->client = client; + data->chip = chip; + mutex_init(&data->lock); + + return devm_iio_device_register(&client->dev, indio_dev); +}; + +static struct i2c_driver atlas_ezo_driver = { + .driver = { + .name = ATLAS_EZO_DRV_NAME, + .of_match_table = atlas_ezo_dt_ids, + }, + .probe = atlas_ezo_probe, + .id_table = atlas_ezo_id, +}; +module_i2c_driver(atlas_ezo_driver); + +MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); +MODULE_DESCRIPTION("Atlas Scientific EZO sensors"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index 82d470561ad3..78a27e36bf32 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -53,6 +53,8 @@ #define ATLAS_REG_DO_CALIB_STATUS_PRESSURE BIT(0) #define ATLAS_REG_DO_CALIB_STATUS_DO BIT(1) +#define ATLAS_REG_RTD_DATA 0x0e + #define ATLAS_REG_PH_TEMP_DATA 0x0e #define ATLAS_REG_PH_DATA 0x16 @@ -72,12 +74,14 @@ #define ATLAS_EC_INT_TIME_IN_MS 650 #define ATLAS_ORP_INT_TIME_IN_MS 450 #define ATLAS_DO_INT_TIME_IN_MS 450 +#define ATLAS_RTD_INT_TIME_IN_MS 450 enum { ATLAS_PH_SM, ATLAS_EC_SM, ATLAS_ORP_SM, ATLAS_DO_SM, + ATLAS_RTD_SM, }; struct atlas_data { @@ -194,7 +198,19 @@ static const struct iio_chan_spec atlas_orp_channels[] = { }; static const struct iio_chan_spec atlas_do_channels[] = { - ATLAS_CONCENTRATION_CHANNEL(0, ATLAS_REG_DO_DATA), + { + .type = IIO_CONCENTRATION, + .address = ATLAS_REG_DO_DATA, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_BE, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(1), { .type = IIO_TEMP, @@ -206,6 +222,22 @@ static const struct iio_chan_spec atlas_do_channels[] = { }, }; +static const struct iio_chan_spec atlas_rtd_channels[] = { + { + .type = IIO_TEMP, + .address = ATLAS_REG_RTD_DATA, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_BE, + }, + }, + IIO_CHAN_SOFT_TIMESTAMP(1), +}; + static int atlas_check_ph_calibration(struct atlas_data *data) { struct device *dev = &data->client->dev; @@ -350,6 +382,12 @@ static struct atlas_device atlas_devices[] = { .calibration = &atlas_check_do_calibration, .delay = ATLAS_DO_INT_TIME_IN_MS, }, + [ATLAS_RTD_SM] = { + .channels = atlas_rtd_channels, + .num_channels = 2, + .data_reg = ATLAS_REG_RTD_DATA, + .delay = ATLAS_RTD_INT_TIME_IN_MS, + }, }; static int atlas_set_powermode(struct atlas_data *data, int on) @@ -426,8 +464,7 @@ static irqreturn_t atlas_trigger_handler(int irq, void *private) int ret; ret = regmap_bulk_read(data->regmap, data->chip->data_reg, - (u8 *) &data->buffer, - sizeof(__be32) * channels); + &data->buffer, sizeof(__be32) * channels); if (!ret) iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, @@ -463,7 +500,7 @@ static int atlas_read_measurement(struct atlas_data *data, int reg, __be32 *val) if (suspended) msleep(data->chip->delay); - ret = regmap_bulk_read(data->regmap, reg, (u8 *) val, sizeof(*val)); + ret = regmap_bulk_read(data->regmap, reg, val, sizeof(*val)); pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); @@ -478,6 +515,7 @@ static int atlas_read_raw(struct iio_dev *indio_dev, struct atlas_data *data = iio_priv(indio_dev); switch (mask) { + case IIO_CHAN_INFO_PROCESSED: case IIO_CHAN_INFO_RAW: { int ret; __be32 reg; @@ -485,7 +523,7 @@ static int atlas_read_raw(struct iio_dev *indio_dev, switch (chan->type) { case IIO_TEMP: ret = regmap_bulk_read(data->regmap, chan->address, - (u8 *) ®, sizeof(reg)); + ®, sizeof(reg)); break; case IIO_PH: case IIO_CONCENTRATION: @@ -566,6 +604,7 @@ static const struct i2c_device_id atlas_id[] = { { "atlas-ec-sm", ATLAS_EC_SM}, { "atlas-orp-sm", ATLAS_ORP_SM}, { "atlas-do-sm", ATLAS_DO_SM}, + { "atlas-rtd-sm", ATLAS_RTD_SM}, {} }; MODULE_DEVICE_TABLE(i2c, atlas_id); @@ -575,6 +614,7 @@ static const struct of_device_id atlas_dt_ids[] = { { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, }, { .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, }, { .compatible = "atlas,do-sm", .data = (void *)ATLAS_DO_SM, }, + { .compatible = "atlas,rtd-sm", .data = (void *)ATLAS_RTD_SM, }, { } }; MODULE_DEVICE_TABLE(of, atlas_dt_ids); diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c index ccde4c65ff93..13773e01699b 100644 --- a/drivers/iio/chemical/bme680_core.c +++ b/drivers/iio/chemical/bme680_core.c @@ -114,14 +114,16 @@ static int bme680_read_calib(struct bme680_data *data, __le16 buf; /* Temperature related coefficients */ - ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_T1_LSB_REG\n"); return ret; } calib->par_t1 = le16_to_cpu(buf); - ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_T2_LSB_REG\n"); return ret; @@ -136,14 +138,16 @@ static int bme680_read_calib(struct bme680_data *data, calib->par_t3 = tmp; /* Pressure related coefficients */ - ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_P1_LSB_REG\n"); return ret; } calib->par_p1 = le16_to_cpu(buf); - ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_P2_LSB_REG\n"); return ret; @@ -157,14 +161,16 @@ static int bme680_read_calib(struct bme680_data *data, } calib->par_p3 = tmp; - ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_P4_LSB_REG\n"); return ret; } calib->par_p4 = le16_to_cpu(buf); - ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_P5_LSB_REG\n"); return ret; @@ -185,14 +191,16 @@ static int bme680_read_calib(struct bme680_data *data, } calib->par_p7 = tmp; - ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_P8_LSB_REG\n"); return ret; } calib->par_p8 = le16_to_cpu(buf); - ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG, (u8 *) &buf, 2); + ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_P9_LSB_REG\n"); return ret; @@ -276,8 +284,8 @@ static int bme680_read_calib(struct bme680_data *data, } calib->par_gh1 = tmp; - ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG, (u8 *) &buf, - 2); + ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG, + &buf, sizeof(buf)); if (ret < 0) { dev_err(dev, "failed to read BME680_GH2_LSB_REG\n"); return ret; @@ -615,7 +623,7 @@ static int bme680_read_temp(struct bme680_data *data, int *val) return ret; ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB, - (u8 *) &tmp, 3); + &tmp, 3); if (ret < 0) { dev_err(dev, "failed to read temperature\n"); return ret; @@ -656,7 +664,7 @@ static int bme680_read_press(struct bme680_data *data, return ret; ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB, - (u8 *) &tmp, 3); + &tmp, 3); if (ret < 0) { dev_err(dev, "failed to read pressure\n"); return ret; @@ -689,7 +697,7 @@ static int bme680_read_humid(struct bme680_data *data, return ret; ret = regmap_bulk_read(data->regmap, BM6880_REG_HUMIDITY_MSB, - (u8 *) &tmp, 2); + &tmp, sizeof(tmp)); if (ret < 0) { dev_err(dev, "failed to read humidity\n"); return ret; @@ -754,7 +762,7 @@ static int bme680_read_gas(struct bme680_data *data, } ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB, - (u8 *) &tmp, 2); + &tmp, sizeof(tmp)); if (ret < 0) { dev_err(dev, "failed to read gas resistance\n"); return ret; diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index 2ebdfc35bcda..3ecd633f9ed3 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c @@ -16,6 +16,7 @@ */ #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -36,6 +37,7 @@ #define CCS811_ERR 0xE0 /* Used to transition from boot to application mode */ #define CCS811_APP_START 0xF4 +#define CCS811_SW_RESET 0xFF /* Status register flags */ #define CCS811_STATUS_ERROR BIT(0) @@ -74,6 +76,7 @@ struct ccs811_data { struct mutex lock; /* Protect readings */ struct ccs811_reading buffer; struct iio_trigger *drdy_trig; + struct gpio_desc *wakeup_gpio; bool drdy_trig_on; }; @@ -166,10 +169,25 @@ static int ccs811_setup(struct i2c_client *client) CCS811_MODE_IAQ_1SEC); } +static void ccs811_set_wakeup(struct ccs811_data *data, bool enable) +{ + if (!data->wakeup_gpio) + return; + + gpiod_set_value(data->wakeup_gpio, enable); + + if (enable) + usleep_range(50, 60); + else + usleep_range(20, 30); +} + static int ccs811_get_measurement(struct ccs811_data *data) { int ret, tries = 11; + ccs811_set_wakeup(data, true); + /* Maximum waiting time: 1s, as measurements are made every second */ while (tries-- > 0) { ret = i2c_smbus_read_byte_data(data->client, CCS811_STATUS); @@ -183,9 +201,12 @@ static int ccs811_get_measurement(struct ccs811_data *data) if (!(ret & CCS811_STATUS_DATA_READY)) return -EIO; - return i2c_smbus_read_i2c_block_data(data->client, + ret = i2c_smbus_read_i2c_block_data(data->client, CCS811_ALG_RESULT_DATA, 8, (char *)&data->buffer); + ccs811_set_wakeup(data, false); + + return ret; } static int ccs811_read_raw(struct iio_dev *indio_dev, @@ -336,6 +357,45 @@ static irqreturn_t ccs811_data_rdy_trigger_poll(int irq, void *private) return IRQ_HANDLED; } +static int ccs811_reset(struct i2c_client *client) +{ + struct gpio_desc *reset_gpio; + int ret; + + reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) + return PTR_ERR(reset_gpio); + + /* Try to reset using nRESET pin if available else do SW reset */ + if (reset_gpio) { + gpiod_set_value(reset_gpio, 1); + usleep_range(20, 30); + gpiod_set_value(reset_gpio, 0); + } else { + /* + * As per the datasheet, this sequence of values needs to be + * written to the SW_RESET register for triggering the soft + * reset in the device and placing it in boot mode. + */ + static const u8 reset_seq[] = { + 0x11, 0xE5, 0x72, 0x8A, + }; + + ret = i2c_smbus_write_i2c_block_data(client, CCS811_SW_RESET, + sizeof(reset_seq), reset_seq); + if (ret < 0) { + dev_err(&client->dev, "Failed to reset sensor\n"); + return ret; + } + } + + /* tSTART delay required after reset */ + usleep_range(1000, 2000); + + return 0; +} + static int ccs811_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -348,36 +408,59 @@ static int ccs811_probe(struct i2c_client *client, | I2C_FUNC_SMBUS_READ_I2C_BLOCK)) return -EOPNOTSUPP; + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + data->wakeup_gpio = devm_gpiod_get_optional(&client->dev, "wakeup", + GPIOD_OUT_HIGH); + if (IS_ERR(data->wakeup_gpio)) + return PTR_ERR(data->wakeup_gpio); + + ccs811_set_wakeup(data, true); + + ret = ccs811_reset(client); + if (ret) { + ccs811_set_wakeup(data, false); + return ret; + } + /* Check hardware id (should be 0x81 for this family of devices) */ ret = i2c_smbus_read_byte_data(client, CCS811_HW_ID); - if (ret < 0) + if (ret < 0) { + ccs811_set_wakeup(data, false); return ret; + } if (ret != CCS811_HW_ID_VALUE) { dev_err(&client->dev, "hardware id doesn't match CCS81x\n"); + ccs811_set_wakeup(data, false); return -ENODEV; } ret = i2c_smbus_read_byte_data(client, CCS811_HW_VERSION); - if (ret < 0) + if (ret < 0) { + ccs811_set_wakeup(data, false); return ret; + } if ((ret & CCS811_HW_VERSION_MASK) != CCS811_HW_VERSION_VALUE) { dev_err(&client->dev, "no CCS811 sensor\n"); + ccs811_set_wakeup(data, false); return -ENODEV; } - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); - if (!indio_dev) - return -ENOMEM; - ret = ccs811_setup(client); - if (ret < 0) + if (ret < 0) { + ccs811_set_wakeup(data, false); return ret; + } - data = iio_priv(indio_dev); - i2c_set_clientdata(client, indio_dev); - data->client = client; + ccs811_set_wakeup(data, false); mutex_init(&data->lock); @@ -466,9 +549,16 @@ static const struct i2c_device_id ccs811_id[] = { }; MODULE_DEVICE_TABLE(i2c, ccs811_id); +static const struct of_device_id ccs811_dt_ids[] = { + { .compatible = "ams,ccs811" }, + { } +}; +MODULE_DEVICE_TABLE(of, ccs811_dt_ids); + static struct i2c_driver ccs811_driver = { .driver = { .name = "ccs811", + .of_match_table = ccs811_dt_ids, }, .probe = ccs811_probe, .remove = ccs811_remove, diff --git a/drivers/iio/chemical/pms7003.c b/drivers/iio/chemical/pms7003.c index 23c9ab252470..07bb90d72434 100644 --- a/drivers/iio/chemical/pms7003.c +++ b/drivers/iio/chemical/pms7003.c @@ -73,6 +73,11 @@ struct pms7003_state { struct pms7003_frame frame; struct completion frame_ready; struct mutex lock; /* must be held whenever state gets touched */ + /* Used to construct scan to push to the IIO buffer */ + struct { + u16 data[3]; /* PM1, PM2P5, PM10 */ + s64 ts; + } scan; }; static int pms7003_do_cmd(struct pms7003_state *state, enum pms7003_cmd cmd) @@ -104,7 +109,6 @@ static irqreturn_t pms7003_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct pms7003_state *state = iio_priv(indio_dev); struct pms7003_frame *frame = &state->frame; - u16 data[3 + 1 + 4]; /* PM1, PM2P5, PM10, padding, timestamp */ int ret; mutex_lock(&state->lock); @@ -114,12 +118,15 @@ static irqreturn_t pms7003_trigger_handler(int irq, void *p) goto err; } - data[PM1] = pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET); - data[PM2P5] = pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET); - data[PM10] = pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET); + state->scan.data[PM1] = + pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET); + state->scan.data[PM2P5] = + pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET); + state->scan.data[PM10] = + pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET); mutex_unlock(&state->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, &state->scan, iio_get_time_ns(indio_dev)); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/chemical/sps30.c b/drivers/iio/chemical/sps30.c index acb9f8ecbb3d..a88c1fb875a0 100644 --- a/drivers/iio/chemical/sps30.c +++ b/drivers/iio/chemical/sps30.c @@ -230,15 +230,18 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct sps30_state *state = iio_priv(indio_dev); int ret; - s32 data[4 + 2]; /* PM1, PM2P5, PM4, PM10, timestamp */ + struct { + s32 data[4]; /* PM1, PM2P5, PM4, PM10 */ + s64 ts; + } scan; mutex_lock(&state->lock); - ret = sps30_do_meas(state, data, 4); + ret = sps30_do_meas(state, scan.data, ARRAY_SIZE(scan.data)); mutex_unlock(&state->lock); if (ret) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); err: iio_trigger_notify_done(indio_dev->trig); |