drivers/iio/light/al3000a.c

Source file repositories/reference/linux-study-clean/drivers/iio/light/al3000a.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/light/al3000a.c
Extension
.c
Size
5318 bytes
Lines
211
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 al3000a_data {
	struct regmap *regmap;
	struct regulator *vdd_supply;
};

static const struct iio_chan_spec al3000a_channels[] = {
	{
		.type = IIO_LIGHT,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
	},
};

static int al3000a_set_pwr_on(struct al3000a_data *data)
{
	struct device *dev = regmap_get_device(data->regmap);
	int ret;

	ret = regulator_enable(data->vdd_supply);
	if (ret) {
		dev_err(dev, "failed to enable vdd power supply\n");
		return ret;
	}

	return regmap_write(data->regmap, AL3000A_REG_SYSTEM, AL3000A_CONFIG_ENABLE);
}

static void al3000a_set_pwr_off(void *_data)
{
	struct al3000a_data *data = _data;
	struct device *dev = regmap_get_device(data->regmap);
	int ret;

	ret = regmap_write(data->regmap, AL3000A_REG_SYSTEM, AL3000A_CONFIG_DISABLE);
	if (ret)
		dev_err(dev, "failed to write system register\n");

	ret = regulator_disable(data->vdd_supply);
	if (ret)
		dev_err(dev, "failed to disable vdd power supply\n");
}

static int al3000a_init(struct al3000a_data *data)
{
	struct device *dev = regmap_get_device(data->regmap);
	int ret;

	ret = al3000a_set_pwr_on(data);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev, al3000a_set_pwr_off, data);
	if (ret)
		return ret;

	ret = regmap_write(data->regmap, AL3000A_REG_SYSTEM, AL3000A_CONFIG_RESET);
	if (ret)
		return ret;

	return regmap_write(data->regmap, AL3000A_REG_SYSTEM, AL3000A_CONFIG_ENABLE);
}

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

	switch (mask) {
	case IIO_CHAN_INFO_PROCESSED:
		ret = regmap_read(data->regmap, AL3000A_REG_DATA, &gain);
		if (ret)
			return ret;

		*val = lux_table[gain & AL3000A_GAIN_MASK];

		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static const struct iio_info al3000a_info = {
	.read_raw = al3000a_read_raw,
};

static int al3000a_probe(struct i2c_client *client)
{
	struct al3000a_data *data;
	struct device *dev = &client->dev;

Annotation

Implementation Notes