FILE
ens160_core.c
File preview with syntax highlighting.
linux-6.19.14/drivers/iio/chemical/ens160_core.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * ScioSense ENS160 multi-gas sensor driver 4 * 5 * Copyright (c) 2024 Gustavo Silva <gustavograzs@gmail.com> 6 * 7 * Datasheet: 8 * https://www.sciosense.com/wp-content/uploads/2023/12/ENS160-Datasheet.pdf 9 */ 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 0x160 22 23#define ENS160_BOOTING_TIME_MS 10U 24 25#define ENS160_REG_PART_ID 0x00 26 27#define ENS160_REG_OPMODE 0x10 28 29#define ENS160_REG_CONFIG 0x11 30#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 0x00 35#define ENS160_REG_MODE_IDLE 0x01 36#define ENS160_REG_MODE_STANDARD 0x02 37#define ENS160_REG_MODE_RESET 0xF0 38 39#define ENS160_REG_COMMAND 0x12 40#define ENS160_REG_COMMAND_GET_APPVER 0x0E 41#define ENS160_REG_COMMAND_CLRGPR 0xCC 42 43#define ENS160_REG_TEMP_IN 0x13 44#define ENS160_REG_RH_IN 0x15 45#define ENS160_REG_DEVICE_STATUS 0x20 46#define ENS160_REG_DATA_AQI 0x21 47#define ENS160_REG_DATA_TVOC 0x22 48#define ENS160_REG_DATA_ECO2 0x24 49#define ENS160_REG_DATA_T 0x30 50#define ENS160_REG_DATA_RH 0x32 51#define ENS160_REG_GPR_READ4 0x4C 52 53#define ENS160_STATUS_VALIDITY_FLAG GENMASK(3, 2) 54 55#define ENS160_STATUS_NORMAL 0x00 56 57struct ens160_data { 58 struct regmap *regmap; 59 /* Protect reads from the sensor */ 60 struct mutex mutex; 61 struct { 62 __le16 chans[2]; 63 aligned_s64 timestamp; 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) 106{ 107 struct ens160_data *data = iio_priv(indio_dev); 108 int ret; 109 110 guard(mutex)(&data->mutex); 111 ret = regmap_bulk_read(data->regmap, chan->address, 112 &data->buf, sizeof(data->buf)); 113 if (ret) 114 return ret; 115 *val = le16_to_cpu(data->buf); 116 return IIO_VAL_INT; 117} 118 119static int ens160_read_raw(struct iio_dev *indio_dev, 120 struct iio_chan_spec const *chan, 121 int *val, int *val2, long mask) 122{ 123 int ret; 124 125 switch (mask) { 126 case IIO_CHAN_INFO_RAW: 127 if (!iio_device_claim_direct(indio_dev)) 128 return -EBUSY; 129 ret = __ens160_read_raw(indio_dev, chan, val); 130 iio_device_release_direct(indio_dev); 131 return ret; 132 case IIO_CHAN_INFO_SCALE: 133 switch (chan->channel2) { 134 case IIO_MOD_CO2: 135 /* The sensor reads CO2 data as ppm */ 136 *val = 0; 137 *val2 = 100; 138 return IIO_VAL_INT_PLUS_MICRO; 139 case IIO_MOD_VOC: 140 /* The sensor reads VOC data as ppb */ 141 *val = 0; 142 *val2 = 100; 143 return IIO_VAL_INT_PLUS_NANO; 144 default: 145 return -EINVAL; 146 } 147 default: 148 return -EINVAL; 149 } 150} 151 152static int ens160_set_mode(struct ens160_data *data, u8 mode) 153{ 154 int ret; 155 156 ret = regmap_write(data->regmap, ENS160_REG_OPMODE, mode); 157 if (ret) 158 return ret; 159 160 msleep(ENS160_BOOTING_TIME_MS); 161 162 return 0; 163} 164 165static void ens160_set_idle(void *data) 166{ 167 ens160_set_mode(data, ENS160_REG_MODE_IDLE); 168} 169 170static int ens160_chip_init(struct ens160_data *data) 171{ 172 struct device *dev = regmap_get_device(data->regmap); 173 unsigned int status; 174 int ret; 175 176 ret = ens160_set_mode(data, ENS160_REG_MODE_RESET); 177 if (ret) 178 return ret; 179 180 ret = regmap_bulk_read(data->regmap, ENS160_REG_PART_ID, &data->buf, 181 sizeof(data->buf)); 182 if (ret) 183 return ret; 184 185 if (le16_to_cpu(data->buf) != ENS160_PART_ID) 186 return -ENODEV; 187 188 ret = ens160_set_mode(data, ENS160_REG_MODE_IDLE); 189 if (ret) 190 return ret; 191 192 ret = regmap_write(data->regmap, ENS160_REG_COMMAND, 193 ENS160_REG_COMMAND_CLRGPR); 194 if (ret) 195 return ret; 196 197 ret = regmap_write(data->regmap, ENS160_REG_COMMAND, 198 ENS160_REG_COMMAND_GET_APPVER); 199 if (ret) 200 return ret; 201 202 ret = regmap_bulk_read(data->regmap, ENS160_REG_GPR_READ4, 203 data->fw_version, sizeof(data->fw_version)); 204 if (ret) 205 return ret; 206 207 dev_info(dev, "firmware version: %u.%u.%u\n", data->fw_version[2], 208 data->fw_version[1], data->fw_version[0]); 209 210 ret = ens160_set_mode(data, ENS160_REG_MODE_STANDARD); 211 if (ret) 212 return ret; 213 214 ret = devm_add_action_or_reset(dev, ens160_set_idle, data); 215 if (ret) 216 return ret; 217 218 ret = regmap_read(data->regmap, ENS160_REG_DEVICE_STATUS, &status); 219 if (ret) 220 return ret; 221 222 if (FIELD_GET(ENS160_STATUS_VALIDITY_FLAG, status) 223 != ENS160_STATUS_NORMAL) 224 return -EINVAL; 225 226 return 0; 227} 228 229static const struct iio_info ens160_info = { 230 .read_raw = ens160_read_raw, 231}; 232 233static int ens160_suspend(struct device *dev) 234{ 235 struct iio_dev *indio_dev = dev_get_drvdata(dev); 236 struct ens160_data *data = iio_priv(indio_dev); 237 238 return ens160_set_mode(data, ENS160_REG_MODE_DEEP_SLEEP); 239} 240 241static int ens160_resume(struct device *dev) 242{ 243 struct iio_dev *indio_dev = dev_get_drvdata(dev); 244 struct ens160_data *data = iio_priv(indio_dev); 245 int ret; 246 247 ret = ens160_set_mode(data, ENS160_REG_MODE_IDLE); 248 if (ret) 249 return ret; 250 251 return ens160_set_mode(data, ENS160_REG_MODE_STANDARD); 252} 253EXPORT_NS_SIMPLE_DEV_PM_OPS(ens160_pm_ops, ens160_suspend, ens160_resume, 254 IIO_ENS160); 255 256static irqreturn_t ens160_trigger_handler(int irq, void *p) 257{ 258 struct iio_poll_func *pf = p; 259 struct iio_dev *indio_dev = pf->indio_dev; 260 struct ens160_data *data = iio_priv(indio_dev); 261 int ret; 262 263 guard(mutex)(&data->mutex); 264 265 ret = regmap_bulk_read(data->regmap, ENS160_REG_DATA_TVOC, 266 data->scan.chans, sizeof(data->scan.chans)); 267 if (ret) 268 goto err; 269 270 iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan), 271 pf->timestamp); 272err: 273 iio_trigger_notify_done(indio_dev->trig); 274 275 return IRQ_HANDLED; 276} 277 278static int ens160_set_trigger_state(struct iio_trigger *trig, bool state) 279{ 280 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 281 struct ens160_data *data = iio_priv(indio_dev); 282 unsigned int int_bits = ENS160_REG_CONFIG_INTEN | 283 ENS160_REG_CONFIG_INTDAT | 284 ENS160_REG_CONFIG_INT_CFG; 285 286 if (state) 287 return regmap_set_bits(data->regmap, ENS160_REG_CONFIG, 288 int_bits); 289 else 290 return regmap_clear_bits(data->regmap, ENS160_REG_CONFIG, 291 int_bits); 292} 293 294static const struct iio_trigger_ops ens160_trigger_ops = { 295 .set_trigger_state = ens160_set_trigger_state, 296 .validate_device = iio_trigger_validate_own_device, 297}; 298 299static int ens160_setup_trigger(struct iio_dev *indio_dev, int irq) 300{ 301 struct device *dev = indio_dev->dev.parent; 302 struct iio_trigger *trig; 303 int ret; 304 305 trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, 306 iio_device_id(indio_dev)); 307 if (!trig) 308 return -ENOMEM; 309 310 trig->ops = &ens160_trigger_ops; 311 iio_trigger_set_drvdata(trig, indio_dev); 312 313 ret = devm_iio_trigger_register(dev, trig); 314 if (ret) 315 return ret; 316 317 indio_dev->trig = iio_trigger_get(trig); 318 319 ret = devm_request_threaded_irq(dev, irq, 320 iio_trigger_generic_data_rdy_poll, 321 NULL, 322 IRQF_ONESHOT, 323 indio_dev->name, 324 indio_dev->trig); 325 if (ret) 326 return dev_err_probe(dev, ret, "failed to request irq\n"); 327 328 return 0; 329} 330 331int devm_ens160_core_probe(struct device *dev, struct regmap *regmap, int irq, 332 const char *name) 333{ 334 struct ens160_data *data; 335 struct iio_dev *indio_dev; 336 int ret; 337 338 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 339 if (!indio_dev) 340 return -ENOMEM; 341 342 data = iio_priv(indio_dev); 343 data->regmap = regmap; 344 345 indio_dev->name = name; 346 indio_dev->info = &ens160_info; 347 indio_dev->modes = INDIO_DIRECT_MODE; 348 indio_dev->channels = ens160_channels; 349 indio_dev->num_channels = ARRAY_SIZE(ens160_channels); 350 351 if (irq > 0) { 352 ret = ens160_setup_trigger(indio_dev, irq); 353 if (ret) 354 return dev_err_probe(dev, ret, 355 "failed to setup trigger\n"); 356 } 357 358 ret = ens160_chip_init(data); 359 if (ret) 360 return dev_err_probe(dev, ret, "chip initialization failed\n"); 361 362 mutex_init(&data->mutex); 363 364 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 365 iio_pollfunc_store_time, 366 ens160_trigger_handler, NULL); 367 if (ret) 368 return ret; 369 370 return devm_iio_device_register(dev, indio_dev); 371} 372EXPORT_SYMBOL_NS(devm_ens160_core_probe, "IIO_ENS160"); 373 374MODULE_AUTHOR("Gustavo Silva <gustavograzs@gmail.com>"); 375MODULE_DESCRIPTION("ScioSense ENS160 driver"); 376MODULE_LICENSE("GPL v2");
~/
Read-only file preview.