drivers/iio/chemical/ens160_core.c

Source file repositories/reference/linux-study-clean/drivers/iio/chemical/ens160_core.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/chemical/ens160_core.c
Extension
.c
Size
8907 bytes
Lines
374
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ens160_data {
	struct regmap *regmap;
	/* Protect reads from the sensor */
	struct mutex mutex;
	struct {
		__le16 chans[2];
		aligned_s64 timestamp;
	} scan __aligned(IIO_DMA_MINALIGN);
	u8 fw_version[3];
	__le16 buf;
};

static const struct iio_chan_spec ens160_channels[] = {
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_VOC,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.address = ENS160_REG_DATA_TVOC,
		.scan_index = 0,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_LE,
		},
	},
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_CO2,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.address = ENS160_REG_DATA_ECO2,
		.scan_index = 1,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_LE,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(2),
};

static int __ens160_read_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int *val)
{
	struct ens160_data *data = iio_priv(indio_dev);
	int ret;

	guard(mutex)(&data->mutex);
	ret = regmap_bulk_read(data->regmap, chan->address,
			       &data->buf, sizeof(data->buf));
	if (ret)
		return ret;
	*val = le16_to_cpu(data->buf);
	return IIO_VAL_INT;
}

static int ens160_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long mask)
{
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (!iio_device_claim_direct(indio_dev))
			return -EBUSY;
		ret = __ens160_read_raw(indio_dev, chan, val);
		iio_device_release_direct(indio_dev);
		return ret;
	case IIO_CHAN_INFO_SCALE:
		switch (chan->channel2) {
		case IIO_MOD_CO2:
			/* The sensor reads CO2 data as ppm */
			*val = 0;
			*val2 = 100;
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_MOD_VOC:
			/* The sensor reads VOC data as ppb */
			*val = 0;
			*val2 = 100;
			return IIO_VAL_INT_PLUS_NANO;
		default:
			return -EINVAL;
		}

Annotation

Implementation Notes