drivers/iio/proximity/pulsedlight-lidar-lite-v2.c

Source file repositories/reference/linux-study-clean/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
Extension
.c
Size
8450 bytes
Lines
374
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 lidar_data {
	struct iio_dev *indio_dev;
	struct i2c_client *client;

	int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len);
	int i2c_enabled;
};

static const struct iio_chan_spec lidar_channels[] = {
	{
		.type = IIO_DISTANCE,
		.info_mask_separate =
			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = 0,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(1),
};

static int lidar_i2c_xfer(struct lidar_data *data, u8 reg, u8 *val, int len)
{
	struct i2c_client *client = data->client;
	struct i2c_msg msg[2];
	int ret;

	msg[0].addr = client->addr;
	msg[0].flags = client->flags | I2C_M_STOP;
	msg[0].len = 1;
	msg[0].buf  = (char *) ®

	msg[1].addr = client->addr;
	msg[1].flags = client->flags | I2C_M_RD;
	msg[1].len = len;
	msg[1].buf = (char *) val;

	ret = i2c_transfer(client->adapter, msg, 2);

	return (ret == 2) ? 0 : -EIO;
}

static int lidar_smbus_xfer(struct lidar_data *data, u8 reg, u8 *val, int len)
{
	struct i2c_client *client = data->client;
	int ret;

	/*
	 * Device needs a STOP condition between address write, and data read
	 * so in turn i2c_smbus_read_byte_data cannot be used
	 */

	while (len--) {
		ret = i2c_smbus_write_byte(client, reg++);
		if (ret < 0) {
			dev_err(&client->dev, "cannot write addr value");
			return ret;
		}

		ret = i2c_smbus_read_byte(client);
		if (ret < 0) {
			dev_err(&client->dev, "cannot read data value");
			return ret;
		}

		*(val++) = ret;
	}

	return 0;
}

static int lidar_read_byte(struct lidar_data *data, u8 reg)
{
	int ret;
	u8 val;

	ret = data->xfer(data, reg, &val, 1);
	if (ret < 0)
		return ret;

	return val;
}

static inline int lidar_write_control(struct lidar_data *data, int val)
{
	return i2c_smbus_write_byte_data(data->client, LIDAR_REG_CONTROL, val);
}

Annotation

Implementation Notes