drivers/iio/magnetometer/als31300.c

Source file repositories/reference/linux-study-clean/drivers/iio/magnetometer/als31300.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/magnetometer/als31300.c
Extension
.c
Size
12867 bytes
Lines
491
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: implementation source
Status
source 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 als31300_variant_info {
	u8 sensitivity;
};

struct als31300_data {
	struct device *dev;
	/* protects power on/off the device and access HW */
	struct mutex mutex;
	const struct als31300_variant_info *variant_info;
	struct regmap *map;
};

/* The whole measure is split into 2x32-bit registers, we need to read them both at once */
static int als31300_get_measure(struct als31300_data *data,
				u16 *t, s16 *x, s16 *y, s16 *z)
{
	u32 buf[2];
	int ret, err;

	guard(mutex)(&data->mutex);

	ret = pm_runtime_resume_and_get(data->dev);
	if (ret)
		return ret;

	/*
	 * Loop until data is valid, new data should have the
	 * ALS31300_VOL_MSB_NEW_DATA bit set to 1.
	 * Max update rate is 2KHz, wait up to 1ms.
	 */
	ret = read_poll_timeout(regmap_bulk_read, err,
				err || FIELD_GET(ALS31300_VOL_MSB_NEW_DATA, buf[0]),
				20, USEC_PER_MSEC, false,
				data->map, ALS31300_VOL_MSB, buf, ARRAY_SIZE(buf));
	/* Bail out on read_poll_timeout() error */
	if (ret)
		goto out;

	/* Bail out on regmap_bulk_read() error */
	if (err) {
		dev_err(data->dev, "read data failed, error %d\n", ret);
		ret = err;
		goto out;
	}

	*t = ALS31300_TEMPERATURE_GET(buf);
	*x = ALS31300_DATA_X_GET(buf);
	*y = ALS31300_DATA_Y_GET(buf);
	*z = ALS31300_DATA_Z_GET(buf);

out:
	pm_runtime_put_autosuspend(data->dev);

	return ret;
}

static int als31300_read_raw(struct iio_dev *indio_dev,
			     const struct iio_chan_spec *chan, int *val,
			     int *val2, long mask)
{
	struct als31300_data *data = iio_priv(indio_dev);
	s16 x, y, z;
	u16 t;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = als31300_get_measure(data, &t, &x, &y, &z);
		if (ret)
			return ret;

		switch (chan->address) {
		case TEMPERATURE:
			*val = t;
			return IIO_VAL_INT;
		case AXIS_X:
			*val = x;
			return IIO_VAL_INT;
		case AXIS_Y:
			*val = y;
			return IIO_VAL_INT;
		case AXIS_Z:
			*val = z;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_TEMP:

Annotation

Implementation Notes