drivers/iio/accel/stk8312.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/accel/stk8312.c
Extension
.c
Size
16049 bytes
Lines
654
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 stk8312_data {
	struct i2c_client *client;
	struct mutex lock;
	u8 range;
	u8 sample_rate_idx;
	u8 mode;
	struct iio_trigger *dready_trig;
	bool dready_trigger_on;
	/* Ensure timestamp is naturally aligned */
	struct {
		s8 chans[3];
		aligned_s64 timestamp;
	} scan;
};

static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL);

static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("3.125 6.25 12.5 25 50 100 200 400");

static struct attribute *stk8312_attributes[] = {
	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
	NULL,
};

static const struct attribute_group stk8312_attribute_group = {
	.attrs = stk8312_attributes
};

static int stk8312_otp_init(struct stk8312_data *data)
{
	int ret;
	int count = 10;
	struct i2c_client *client = data->client;

	ret = i2c_smbus_write_byte_data(client, STK8312_REG_OTPADDR, 0x70);
	if (ret < 0)
		goto exit_err;
	ret = i2c_smbus_write_byte_data(client, STK8312_REG_OTPCTRL, 0x02);
	if (ret < 0)
		goto exit_err;

	do {
		usleep_range(1000, 5000);
		ret = i2c_smbus_read_byte_data(client, STK8312_REG_OTPCTRL);
		if (ret < 0)
			goto exit_err;
		count--;
	} while (!(ret & BIT(7)) && count > 0);

	if (count == 0) {
		ret = -ETIMEDOUT;
		goto exit_err;
	}

	ret = i2c_smbus_read_byte_data(client, STK8312_REG_OTPDATA);
	if (ret == 0)
		ret = -EINVAL;
	if (ret < 0)
		goto exit_err;

	ret = i2c_smbus_write_byte_data(data->client, STK8312_REG_AFECTRL, ret);
	if (ret < 0)
		goto exit_err;
	msleep(150);

	return 0;

exit_err:
	dev_err(&client->dev, "failed to initialize sensor\n");
	return ret;
}

static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
{
	int ret;
	struct i2c_client *client = data->client;

	if (mode == data->mode)
		return 0;

	ret = i2c_smbus_write_byte_data(client, STK8312_REG_MODE, mode);
	if (ret < 0) {
		dev_err(&client->dev, "failed to change sensor mode\n");
		return ret;
	}

	data->mode = mode;
	if (mode & STK8312_MODE_ACTIVE) {
		/* Need to run OTP sequence before entering active mode */

Annotation

Implementation Notes