drivers/iio/accel/da280.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/accel/da280.c
Extension
.c
Size
4638 bytes
Lines
187
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 da280_match_data {
	const char *name;
	int num_channels;
};

struct da280_data {
	struct i2c_client *client;
};

static int da280_enable(struct i2c_client *client, bool enable)
{
	u8 data = enable ? DA280_MODE_ENABLE : DA280_MODE_DISABLE;

	return i2c_smbus_write_byte_data(client, DA280_REG_MODE_BW, data);
}

static int da280_read_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan,
				int *val, int *val2, long mask)
{
	struct da280_data *data = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = i2c_smbus_read_word_data(data->client, chan->address);
		if (ret < 0)
			return ret;
		/*
		 * Values are 14 bits, stored as 16 bits with the 2
		 * least significant bits always 0.
		 */
		*val = (short)ret >> 2;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = da280_nscale;
		return IIO_VAL_INT_PLUS_NANO;
	default:
		return -EINVAL;
	}
}

static const struct iio_info da280_info = {
	.read_raw	= da280_read_raw,
};

static void da280_disable(void *client)
{
	da280_enable(client, false);
}

static int da280_probe(struct i2c_client *client)
{
	const struct da280_match_data *match_data;
	struct iio_dev *indio_dev;
	struct da280_data *data;
	int ret;

	ret = i2c_smbus_read_byte_data(client, DA280_REG_CHIP_ID);
	if (ret != DA280_CHIP_ID)
		return (ret < 0) ? ret : -ENODEV;

	match_data = i2c_get_match_data(client);
	if (!match_data) {
		dev_err(&client->dev, "Error match-data not set\n");
		return -EINVAL;
	}

	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
	if (!indio_dev)
		return -ENOMEM;

	data = iio_priv(indio_dev);
	data->client = client;

	indio_dev->info = &da280_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = da280_channels;
	indio_dev->num_channels = match_data->num_channels;
	indio_dev->name = match_data->name;

	ret = da280_enable(client, true);
	if (ret < 0)
		return ret;

	ret = devm_add_action_or_reset(&client->dev, da280_disable, client);
	if (ret)
		return ret;

Annotation

Implementation Notes