drivers/iio/pressure/mpl3115.c

Source file repositories/reference/linux-study-clean/drivers/iio/pressure/mpl3115.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/pressure/mpl3115.c
Extension
.c
Size
19839 bytes
Lines
812
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 mpl3115_data {
	struct i2c_client *client;
	struct iio_trigger *drdy_trig;
	struct mutex lock;
	u8 ctrl_reg1;
	u8 ctrl_reg4;
};

enum mpl3115_irq_pin {
	MPL3115_IRQ_INT1,
	MPL3115_IRQ_INT2,
};

static int mpl3115_request(struct mpl3115_data *data)
{
	int ret, tries = 15;

	/* trigger measurement */
	ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
		data->ctrl_reg1 | MPL3115_CTRL1_OST);
	if (ret < 0)
		return ret;

	while (tries-- > 0) {
		ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG1);
		if (ret < 0)
			return ret;
		/* wait for data ready, i.e. OST cleared */
		if (!(ret & MPL3115_CTRL1_OST))
			break;
		msleep(20);
	}

	if (tries < 0) {
		dev_err(&data->client->dev, "data not ready\n");
		return -EIO;
	}

	return 0;
}

static int mpl3115_read_info_raw(struct mpl3115_data *data,
				 struct iio_chan_spec const *chan, int *val)
{
	int ret;

	switch (chan->type) {
	case IIO_PRESSURE: { /* in 0.25 pascal / LSB */
		u8 press_be24[3];

		guard(mutex)(&data->lock);
		ret = mpl3115_request(data);
		if (ret < 0)
			return ret;

		ret = i2c_smbus_read_i2c_block_data(data->client,
						    MPL3115_OUT_PRESS,
						    sizeof(press_be24),
						    press_be24);
		if (ret < 0)
			return ret;

		/*
		 * The pressure channel shift is applied in the case where the
		 * data (24-bit big endian) is read into a 32-bit buffer. Here
		 * the data is stored in a 24-bit buffer, so the shift is 4.
		 */
		*val = get_unaligned_be24(press_be24) >> 4;
		return IIO_VAL_INT;
	}
	case IIO_TEMP: { /* in 0.0625 celsius / LSB */
		__be16 tmp;

		guard(mutex)(&data->lock);
		ret = mpl3115_request(data);
		if (ret < 0)
			return ret;

		ret = i2c_smbus_read_i2c_block_data(data->client,
						    MPL3115_OUT_TEMP,
						    2, (u8 *) &tmp);
		if (ret < 0)
			return ret;

		*val = sign_extend32(be16_to_cpu(tmp) >> chan->scan_type.shift,
				     chan->scan_type.realbits - 1);
		return IIO_VAL_INT;
	}
	default:
		return -EINVAL;

Annotation

Implementation Notes