drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c

Source file repositories/reference/linux-study-clean/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
Extension
.c
Size
23223 bytes
Lines
886
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 st_lsm6dsx_decimator_entry {
	u8 decimator;
	u8 val;
};

enum st_lsm6dsx_fifo_tag {
	ST_LSM6DSX_GYRO_TAG = 0x01,
	ST_LSM6DSX_ACC_TAG = 0x02,
	ST_LSM6DSX_TS_TAG = 0x04,
	ST_LSM6DSX_EXT0_TAG = 0x0f,
	ST_LSM6DSX_EXT1_TAG = 0x10,
	ST_LSM6DSX_EXT2_TAG = 0x11,
};

static const
struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
	{  0, 0x0 },
	{  1, 0x1 },
	{  2, 0x2 },
	{  3, 0x3 },
	{  4, 0x4 },
	{  8, 0x5 },
	{ 16, 0x6 },
	{ 32, 0x7 },
};

static int
st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr)
{
	const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table);
	u32 decimator = max_odr / sensor->hwfifo_odr_mHz;
	int i;

	if (decimator > 1)
		decimator = round_down(decimator, 2);

	for (i = 0; i < max_size; i++) {
		if (st_lsm6dsx_decimator_table[i].decimator == decimator)
			break;
	}

	sensor->decimator = decimator;
	return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
}

static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
				       u32 *max_odr, u32 *min_odr)
{
	struct st_lsm6dsx_sensor *sensor;
	int i;

	*max_odr = 0, *min_odr = ~0;
	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
		if (!hw->iio_devs[i])
			continue;

		sensor = iio_priv(hw->iio_devs[i]);

		if (!(hw->enable_mask & BIT(sensor->id)))
			continue;

		*max_odr = max(*max_odr, sensor->hwfifo_odr_mHz);
		*min_odr = min(*min_odr, sensor->hwfifo_odr_mHz);
	}
}

static u8 st_lsm6dsx_get_sip(struct st_lsm6dsx_sensor *sensor, u32 min_odr)
{
	u8 sip = sensor->hwfifo_odr_mHz / min_odr;

	return sip > 1 ? round_down(sip, 2) : sip;
}

static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
{
	const struct st_lsm6dsx_reg *ts_dec_reg;
	struct st_lsm6dsx_sensor *sensor;
	u16 sip = 0, ts_sip = 0;
	u32 max_odr, min_odr;
	int err = 0, i;
	u8 data;

	st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr);

	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
		const struct st_lsm6dsx_reg *dec_reg;

		if (!hw->iio_devs[i])
			continue;

Annotation

Implementation Notes