368 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * ScioSense ENS160 multi-gas sensor driver4 *5 * Copyright (c) 2024 Gustavo Silva <gustavograzs@gmail.com>6 *7 * Datasheet:8 * https://www.sciosense.com/wp-content/uploads/2023/12/ENS160-Datasheet.pdf9 */10 11#include <linux/bitfield.h>12#include <linux/iio/iio.h>13#include <linux/iio/trigger.h>14#include <linux/iio/trigger_consumer.h>15#include <linux/iio/triggered_buffer.h>16#include <linux/module.h>17#include <linux/regmap.h>18 19#include "ens160.h"20 21#define ENS160_PART_ID 0x16022 23#define ENS160_BOOTING_TIME_MS 10U24 25#define ENS160_REG_PART_ID 0x0026 27#define ENS160_REG_OPMODE 0x1028 29#define ENS160_REG_CONFIG 0x1130#define ENS160_REG_CONFIG_INTEN BIT(0)31#define ENS160_REG_CONFIG_INTDAT BIT(1)32#define ENS160_REG_CONFIG_INT_CFG BIT(5)33 34#define ENS160_REG_MODE_DEEP_SLEEP 0x0035#define ENS160_REG_MODE_IDLE 0x0136#define ENS160_REG_MODE_STANDARD 0x0237#define ENS160_REG_MODE_RESET 0xF038 39#define ENS160_REG_COMMAND 0x1240#define ENS160_REG_COMMAND_GET_APPVER 0x0E41#define ENS160_REG_COMMAND_CLRGPR 0xCC42 43#define ENS160_REG_TEMP_IN 0x1344#define ENS160_REG_RH_IN 0x1545#define ENS160_REG_DEVICE_STATUS 0x2046#define ENS160_REG_DATA_AQI 0x2147#define ENS160_REG_DATA_TVOC 0x2248#define ENS160_REG_DATA_ECO2 0x2449#define ENS160_REG_DATA_T 0x3050#define ENS160_REG_DATA_RH 0x3251#define ENS160_REG_GPR_READ4 0x4C52 53#define ENS160_STATUS_VALIDITY_FLAG GENMASK(3, 2)54 55#define ENS160_STATUS_NORMAL 0x0056 57struct ens160_data {58 struct regmap *regmap;59 /* Protect reads from the sensor */60 struct mutex mutex;61 struct {62 __le16 chans[2];63 s64 timestamp __aligned(8);64 } scan __aligned(IIO_DMA_MINALIGN);65 u8 fw_version[3];66 __le16 buf;67};68 69static const struct iio_chan_spec ens160_channels[] = {70 {71 .type = IIO_CONCENTRATION,72 .channel2 = IIO_MOD_VOC,73 .modified = 1,74 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |75 BIT(IIO_CHAN_INFO_SCALE),76 .address = ENS160_REG_DATA_TVOC,77 .scan_index = 0,78 .scan_type = {79 .sign = 'u',80 .realbits = 16,81 .storagebits = 16,82 .endianness = IIO_LE,83 },84 },85 {86 .type = IIO_CONCENTRATION,87 .channel2 = IIO_MOD_CO2,88 .modified = 1,89 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |90 BIT(IIO_CHAN_INFO_SCALE),91 .address = ENS160_REG_DATA_ECO2,92 .scan_index = 1,93 .scan_type = {94 .sign = 'u',95 .realbits = 16,96 .storagebits = 16,97 .endianness = IIO_LE,98 },99 },100 IIO_CHAN_SOFT_TIMESTAMP(2),101};102 103static int ens160_read_raw(struct iio_dev *indio_dev,104 struct iio_chan_spec const *chan,105 int *val, int *val2, long mask)106{107 struct ens160_data *data = iio_priv(indio_dev);108 int ret;109 110 switch (mask) {111 case IIO_CHAN_INFO_RAW:112 iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {113 guard(mutex)(&data->mutex);114 ret = regmap_bulk_read(data->regmap, chan->address,115 &data->buf, sizeof(data->buf));116 if (ret)117 return ret;118 *val = le16_to_cpu(data->buf);119 return IIO_VAL_INT;120 }121 unreachable();122 case IIO_CHAN_INFO_SCALE:123 switch (chan->channel2) {124 case IIO_MOD_CO2:125 /* The sensor reads CO2 data as ppm */126 *val = 0;127 *val2 = 100;128 return IIO_VAL_INT_PLUS_MICRO;129 case IIO_MOD_VOC:130 /* The sensor reads VOC data as ppb */131 *val = 0;132 *val2 = 100;133 return IIO_VAL_INT_PLUS_NANO;134 default:135 return -EINVAL;136 }137 default:138 return -EINVAL;139 }140}141 142static int ens160_set_mode(struct ens160_data *data, u8 mode)143{144 int ret;145 146 ret = regmap_write(data->regmap, ENS160_REG_OPMODE, mode);147 if (ret)148 return ret;149 150 msleep(ENS160_BOOTING_TIME_MS);151 152 return 0;153}154 155static void ens160_set_idle(void *data)156{157 ens160_set_mode(data, ENS160_REG_MODE_IDLE);158}159 160static int ens160_chip_init(struct ens160_data *data)161{162 struct device *dev = regmap_get_device(data->regmap);163 unsigned int status;164 int ret;165 166 ret = ens160_set_mode(data, ENS160_REG_MODE_RESET);167 if (ret)168 return ret;169 170 ret = regmap_bulk_read(data->regmap, ENS160_REG_PART_ID, &data->buf,171 sizeof(data->buf));172 if (ret)173 return ret;174 175 if (le16_to_cpu(data->buf) != ENS160_PART_ID)176 return -ENODEV;177 178 ret = ens160_set_mode(data, ENS160_REG_MODE_IDLE);179 if (ret)180 return ret;181 182 ret = regmap_write(data->regmap, ENS160_REG_COMMAND,183 ENS160_REG_COMMAND_CLRGPR);184 if (ret)185 return ret;186 187 ret = regmap_write(data->regmap, ENS160_REG_COMMAND,188 ENS160_REG_COMMAND_GET_APPVER);189 if (ret)190 return ret;191 192 ret = regmap_bulk_read(data->regmap, ENS160_REG_GPR_READ4,193 data->fw_version, sizeof(data->fw_version));194 if (ret)195 return ret;196 197 dev_info(dev, "firmware version: %u.%u.%u\n", data->fw_version[2],198 data->fw_version[1], data->fw_version[0]);199 200 ret = ens160_set_mode(data, ENS160_REG_MODE_STANDARD);201 if (ret)202 return ret;203 204 ret = devm_add_action_or_reset(dev, ens160_set_idle, data);205 if (ret)206 return ret;207 208 ret = regmap_read(data->regmap, ENS160_REG_DEVICE_STATUS, &status);209 if (ret)210 return ret;211 212 if (FIELD_GET(ENS160_STATUS_VALIDITY_FLAG, status)213 != ENS160_STATUS_NORMAL)214 return -EINVAL;215 216 return 0;217}218 219static const struct iio_info ens160_info = {220 .read_raw = ens160_read_raw,221};222 223static int ens160_suspend(struct device *dev)224{225 struct iio_dev *indio_dev = dev_get_drvdata(dev);226 struct ens160_data *data = iio_priv(indio_dev);227 228 return ens160_set_mode(data, ENS160_REG_MODE_DEEP_SLEEP);229}230 231static int ens160_resume(struct device *dev)232{233 struct iio_dev *indio_dev = dev_get_drvdata(dev);234 struct ens160_data *data = iio_priv(indio_dev);235 int ret;236 237 ret = ens160_set_mode(data, ENS160_REG_MODE_IDLE);238 if (ret)239 return ret;240 241 return ens160_set_mode(data, ENS160_REG_MODE_STANDARD);242}243EXPORT_NS_SIMPLE_DEV_PM_OPS(ens160_pm_ops, ens160_suspend, ens160_resume,244 IIO_ENS160);245 246static irqreturn_t ens160_trigger_handler(int irq, void *p)247{248 struct iio_poll_func *pf = p;249 struct iio_dev *indio_dev = pf->indio_dev;250 struct ens160_data *data = iio_priv(indio_dev);251 int ret;252 253 guard(mutex)(&data->mutex);254 255 ret = regmap_bulk_read(data->regmap, ENS160_REG_DATA_TVOC,256 data->scan.chans, sizeof(data->scan.chans));257 if (ret)258 goto err;259 260 iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,261 pf->timestamp);262err:263 iio_trigger_notify_done(indio_dev->trig);264 265 return IRQ_HANDLED;266}267 268static int ens160_set_trigger_state(struct iio_trigger *trig, bool state)269{270 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);271 struct ens160_data *data = iio_priv(indio_dev);272 unsigned int int_bits = ENS160_REG_CONFIG_INTEN |273 ENS160_REG_CONFIG_INTDAT |274 ENS160_REG_CONFIG_INT_CFG;275 276 if (state)277 return regmap_set_bits(data->regmap, ENS160_REG_CONFIG,278 int_bits);279 else280 return regmap_clear_bits(data->regmap, ENS160_REG_CONFIG,281 int_bits);282}283 284static const struct iio_trigger_ops ens160_trigger_ops = {285 .set_trigger_state = ens160_set_trigger_state,286 .validate_device = iio_trigger_validate_own_device,287};288 289static int ens160_setup_trigger(struct iio_dev *indio_dev, int irq)290{291 struct device *dev = indio_dev->dev.parent;292 struct iio_trigger *trig;293 int ret;294 295 trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name,296 iio_device_id(indio_dev));297 if (!trig)298 return dev_err_probe(dev, -ENOMEM,299 "failed to allocate trigger\n");300 301 trig->ops = &ens160_trigger_ops;302 iio_trigger_set_drvdata(trig, indio_dev);303 304 ret = devm_iio_trigger_register(dev, trig);305 if (ret)306 return ret;307 308 indio_dev->trig = iio_trigger_get(trig);309 310 ret = devm_request_threaded_irq(dev, irq,311 iio_trigger_generic_data_rdy_poll,312 NULL,313 IRQF_ONESHOT,314 indio_dev->name,315 indio_dev->trig);316 if (ret)317 return dev_err_probe(dev, ret, "failed to request irq\n");318 319 return 0;320}321 322int devm_ens160_core_probe(struct device *dev, struct regmap *regmap, int irq,323 const char *name)324{325 struct ens160_data *data;326 struct iio_dev *indio_dev;327 int ret;328 329 indio_dev = devm_iio_device_alloc(dev, sizeof(*data));330 if (!indio_dev)331 return -ENOMEM;332 333 data = iio_priv(indio_dev);334 data->regmap = regmap;335 336 indio_dev->name = name;337 indio_dev->info = &ens160_info;338 indio_dev->modes = INDIO_DIRECT_MODE;339 indio_dev->channels = ens160_channels;340 indio_dev->num_channels = ARRAY_SIZE(ens160_channels);341 342 if (irq > 0) {343 ret = ens160_setup_trigger(indio_dev, irq);344 if (ret)345 return dev_err_probe(dev, ret,346 "failed to setup trigger\n");347 }348 349 ret = ens160_chip_init(data);350 if (ret)351 return dev_err_probe(dev, ret, "chip initialization failed\n");352 353 mutex_init(&data->mutex);354 355 ret = devm_iio_triggered_buffer_setup(dev, indio_dev,356 iio_pollfunc_store_time,357 ens160_trigger_handler, NULL);358 if (ret)359 return ret;360 361 return devm_iio_device_register(dev, indio_dev);362}363EXPORT_SYMBOL_NS(devm_ens160_core_probe, IIO_ENS160);364 365MODULE_AUTHOR("Gustavo Silva <gustavograzs@gmail.com>");366MODULE_DESCRIPTION("ScioSense ENS160 driver");367MODULE_LICENSE("GPL v2");368