drivers/iio/light/isl76682.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/light/isl76682.c
Extension
.c
Size
8384 bytes
Lines
346
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 isl76682_chip {
	/*
	 * Lock to synchronize access to device command register
	 * and the content of range variable below.
	 */
	struct mutex			lock;
	struct regmap			*regmap;
	u8				range;
	u8				command;
};

struct isl76682_range {
	u8				range;
	u32				als;
	u32				ir;
};

static const struct isl76682_range isl76682_range_table[] = {
	{ ISL76682_COMMAND_RANGE_LUX_1K, 15000, 10500 },
	{ ISL76682_COMMAND_RANGE_LUX_4K, 60000, 42000 },
	{ ISL76682_COMMAND_RANGE_LUX_16K, 240000, 168000 },
	{ ISL76682_COMMAND_RANGE_LUX_64K, 960000, 673000 }
};

static int isl76682_get(struct isl76682_chip *chip, bool mode_ir, int *data)
{
	u8 command;
	int ret;

	command = ISL76682_COMMAND_EN | ISL76682_COMMAND_MODE_CONTINUOUS |
		  chip->range;

	if (mode_ir)
		command |= ISL76682_COMMAND_LIGHT_IR;

	if (command != chip->command) {
		ret = regmap_write(chip->regmap, ISL76682_REG_COMMAND, command);
		if (ret)
			return ret;

		/* Need to wait for conversion time if ALS/IR mode enabled */
		msleep(ISL76682_CONV_TIME_MS);

		chip->command = command;
	}

	ret = regmap_bulk_read(chip->regmap, ISL76682_REG_ALSIR_L, data, 2);
	*data &= ISL76682_ADC_MAX;
	return ret;
}

static int isl76682_write_raw(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan,
			      int val, int val2, long mask)
{
	struct isl76682_chip *chip = iio_priv(indio_dev);
	int i;

	if (mask != IIO_CHAN_INFO_SCALE)
		return -EINVAL;

	if (val != 0)
		return -EINVAL;

	for (i = 0; i < ARRAY_SIZE(isl76682_range_table); i++) {
		if (chan->type == IIO_LIGHT && val2 != isl76682_range_table[i].als)
			continue;
		if (chan->type == IIO_INTENSITY && val2 != isl76682_range_table[i].ir)
			continue;

		scoped_guard(mutex, &chip->lock)
			chip->range = isl76682_range_table[i].range;
		return 0;
	}

	return -EINVAL;
}

static int isl76682_read_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int *val, int *val2, long mask)
{
	struct isl76682_chip *chip = iio_priv(indio_dev);
	int ret;
	int i;

	guard(mutex)(&chip->lock);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:

Annotation

Implementation Notes