drivers/iio/chemical/scd30_core.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/chemical/scd30_core.c
Extension
.c
Size
18210 bytes
Lines
747
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

if (chan->output) {
			*val = state->pressure_comp;
			return IIO_VAL_INT;
		}

		if (!iio_device_claim_direct(indio_dev))
			return -EBUSY;

		ret = scd30_read(state);
		if (ret) {
			iio_device_release_direct(indio_dev);
			return ret;
		}

		*val = state->meas[chan->address];
		iio_device_release_direct(indio_dev);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = 1;
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SAMP_FREQ:
		ret = scd30_command_read(state, CMD_MEAS_INTERVAL, &tmp);
		if (ret)
			return ret;

		*val = 0;
		*val2 = 1000000000 / tmp;
		return IIO_VAL_INT_PLUS_NANO;
	case IIO_CHAN_INFO_CALIBBIAS:
		ret = scd30_command_read(state, CMD_TEMP_OFFSET, &tmp);
		if (ret)
			return ret;

		*val = tmp;
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
			   int val, int val2, long mask)
{
	struct scd30_state *state = iio_priv(indio_dev);
	int ret;

	guard(mutex)(&state->lock);
	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		if (val || !val2)
			return -EINVAL;

		val = 1000000000 / val2;
		if (val < SCD30_MEAS_INTERVAL_MIN_S || val > SCD30_MEAS_INTERVAL_MAX_S)
			return -EINVAL;

		ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val);
		if (ret)
			return ret;

		state->meas_interval = val;
		return 0;
	case IIO_CHAN_INFO_RAW:
		switch (chan->type) {
		case IIO_PRESSURE:
			if (val < SCD30_PRESSURE_COMP_MIN_MBAR ||
			    val > SCD30_PRESSURE_COMP_MAX_MBAR)
				return -EINVAL;

			ret = scd30_command_write(state, CMD_START_MEAS, val);
			if (ret)
				return ret;

			state->pressure_comp = val;
			return 0;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_CALIBBIAS:
		if (val < 0 || val > SCD30_TEMP_OFFSET_MAX)
			return -EINVAL;
		/*
		 * Manufacturer does not explicitly specify min/max sensible
		 * values hence check is omitted for simplicity.
		 */
		return scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
	default:
		return -EINVAL;
	}

Annotation

Implementation Notes