drivers/iio/accel/da311.c

Source file repositories/reference/linux-study-clean/drivers/iio/accel/da311.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/accel/da311.c
Extension
.c
Size
7260 bytes
Lines
290
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 da311_data {
	struct i2c_client *client;
};

static int da311_register_mask_write(struct i2c_client *client, u16 addr,
				     u8 mask, u8 data)
{
	int ret;
	u8 tmp_data = 0;

	if (addr & 0xff00) {
		/* Select bank 1 */
		ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x01);
		if (ret < 0)
			return ret;
	}

	if (mask != 0xff) {
		ret = i2c_smbus_read_byte_data(client, addr);
		if (ret < 0)
			return ret;
		tmp_data = ret;
	}

	tmp_data &= ~mask;
	tmp_data |= data & mask;
	ret = i2c_smbus_write_byte_data(client, addr & 0xff, tmp_data);
	if (ret < 0)
		return ret;

	if (addr & 0xff00) {
		/* Back to bank 0 */
		ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x00);
		if (ret < 0)
			return ret;
	}

	return 0;
}

/* Init sequence taken from the android driver */
static int da311_reset(struct i2c_client *client)
{
	static const struct {
		u16 addr;
		u8 mask;
		u8 data;
	} init_data[] = {
		{ DA311_REG_TEMP_CFG_REG,       0xff,   0x08 },
		{ DA311_REG_CTRL_REG5,          0xff,   0x80 },
		{ DA311_REG_CTRL_REG4,          0x30,   0x00 },
		{ DA311_REG_CTRL_REG1,          0xff,   0x6f },
		{ DA311_REG_TEMP_CFG_REG,       0xff,   0x88 },
		{ DA311_REG_LDO_REG,            0xff,   0x02 },
		{ DA311_REG_OTP_TRIM_OSC,       0xff,   0x27 },
		{ DA311_REG_LPF_ABSOLUTE,       0xff,   0x30 },
		{ DA311_REG_TEMP_OFF1,          0xff,   0x3f },
		{ DA311_REG_TEMP_OFF2,          0xff,   0xff },
		{ DA311_REG_TEMP_OFF3,          0xff,   0x0f },
	};
	int i, ret;

	/* Reset */
	ret = da311_register_mask_write(client, DA311_REG_SOFT_RESET,
					0xff, 0xaa);
	if (ret < 0)
		return ret;

	for (i = 0; i < ARRAY_SIZE(init_data); i++) {
		ret = da311_register_mask_write(client,
						init_data[i].addr,
						init_data[i].mask,
						init_data[i].data);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int da311_enable(struct i2c_client *client, bool enable)
{
	u8 data = enable ? 0x00 : 0x20;

	return da311_register_mask_write(client, DA311_REG_TEMP_CFG_REG,
					 0x20, data);
}

static int da311_read_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan,

Annotation

Implementation Notes