drivers/iio/light/veml6075.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/light/veml6075.c
Extension
.c
Size
11705 bytes
Lines
479
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 veml6075_data {
	struct i2c_client *client;
	struct regmap *regmap;
	/*
	 * prevent integration time modification and triggering
	 * measurements while a measurement is underway.
	 */
	struct mutex lock;
};

/* channel number */
enum veml6075_chan {
	CH_UVA,
	CH_UVB,
};

static const struct iio_chan_spec veml6075_channels[] = {
	{
		.type = IIO_INTENSITY,
		.channel = CH_UVA,
		.modified = 1,
		.channel2 = IIO_MOD_LIGHT_UVA,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
			BIT(IIO_CHAN_INFO_SCALE),
		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME),
		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME),
	},
	{
		.type = IIO_INTENSITY,
		.channel = CH_UVB,
		.modified = 1,
		.channel2 = IIO_MOD_LIGHT_UVB,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
			BIT(IIO_CHAN_INFO_SCALE),
		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME),
		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME),
	},
	{
		.type = IIO_UVINDEX,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME),
		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME),
	},
};

static int veml6075_request_measurement(struct veml6075_data *data)
{
	int ret, conf, int_time;

	ret = regmap_read(data->regmap, VEML6075_CMD_CONF, &conf);
	if (ret < 0)
		return ret;

	/* disable shutdown and trigger measurement */
	ret = regmap_write(data->regmap, VEML6075_CMD_CONF,
			   (conf | VEML6075_CONF_TRIG) & ~VEML6075_CONF_SD);
	if (ret < 0)
		return ret;

	/*
	 * A measurement requires between 1.30 and 1.40 times the integration
	 * time for all possible configurations. Using a 1.50 factor simplifies
	 * operations and ensures reliability under all circumstances.
	 */
	int_time = veml6075_it_ms[FIELD_GET(VEML6075_CONF_IT, conf)];
	msleep(int_time + (int_time / 2));

	/* shutdown again, data registers are still accessible */
	return regmap_update_bits(data->regmap, VEML6075_CMD_CONF,
				  VEML6075_CONF_SD, VEML6075_CONF_SD);
}

static int veml6075_uva_comp(int raw_uva, int comp1, int comp2)
{
	int comp1a_c, comp2a_c, uva_comp;

	comp1a_c = (comp1 * VEML6075_A_COEF) / 1000U;
	comp2a_c = (comp2 * VEML6075_B_COEF) / 1000U;
	uva_comp = raw_uva - comp1a_c - comp2a_c;

	return clamp_val(uva_comp, 0, U16_MAX);
}

static int veml6075_uvb_comp(int raw_uvb, int comp1, int comp2)
{
	int comp1b_c, comp2b_c, uvb_comp;

	comp1b_c = (comp1 * VEML6075_C_COEF) / 1000U;
	comp2b_c = (comp2 * VEML6075_D_COEF) / 1000U;
	uvb_comp = raw_uvb - comp1b_c - comp2b_c;

Annotation

Implementation Notes