drivers/iio/light/isl29018.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/light/isl29018.c
Extension
.c
Size
22077 bytes
Lines
861
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 isl29018_chip {
	struct regmap		*regmap;
	struct mutex		lock;
	int			type;
	unsigned int		calibscale;
	unsigned int		ucalibscale;
	unsigned int		int_time;
	struct isl29018_scale	scale;
	int			prox_scheme;
	bool			suspended;
	struct regulator	*vcc_reg;
};

static int isl29018_set_integration_time(struct isl29018_chip *chip,
					 unsigned int utime)
{
	unsigned int i;
	int ret;
	unsigned int int_time, new_int_time;

	for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i) {
		if (utime == isl29018_int_utimes[chip->type][i]) {
			new_int_time = i;
			break;
		}
	}

	if (i >= ARRAY_SIZE(isl29018_int_utimes[chip->type]))
		return -EINVAL;

	ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
				 ISL29018_CMD2_RESOLUTION_MASK,
				 i << ISL29018_CMD2_RESOLUTION_SHIFT);
	if (ret < 0)
		return ret;

	/* Keep the same range when integration time changes */
	int_time = chip->int_time;
	for (i = 0; i < ARRAY_SIZE(isl29018_scales[int_time]); ++i) {
		if (chip->scale.scale == isl29018_scales[int_time][i].scale &&
		    chip->scale.uscale == isl29018_scales[int_time][i].uscale) {
			chip->scale = isl29018_scales[new_int_time][i];
			break;
		}
	}
	chip->int_time = new_int_time;

	return 0;
}

static int isl29018_set_scale(struct isl29018_chip *chip, int scale, int uscale)
{
	unsigned int i;
	int ret;
	struct isl29018_scale new_scale;

	for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i) {
		if (scale == isl29018_scales[chip->int_time][i].scale &&
		    uscale == isl29018_scales[chip->int_time][i].uscale) {
			new_scale = isl29018_scales[chip->int_time][i];
			break;
		}
	}

	if (i >= ARRAY_SIZE(isl29018_scales[chip->int_time]))
		return -EINVAL;

	ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
				 ISL29018_CMD2_RANGE_MASK,
				 i << ISL29018_CMD2_RANGE_SHIFT);
	if (ret < 0)
		return ret;

	chip->scale = new_scale;

	return 0;
}

static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode)
{
	int status;
	unsigned int lsb;
	unsigned int msb;
	struct device *dev = regmap_get_device(chip->regmap);

	/* Set mode */
	status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1,
			      mode << ISL29018_CMD1_OPMODE_SHIFT);
	if (status) {
		dev_err(dev,

Annotation

Implementation Notes