drivers/iio/proximity/vcnl3020.c

Source file repositories/reference/linux-study-clean/drivers/iio/proximity/vcnl3020.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/proximity/vcnl3020.c
Extension
.c
Size
15809 bytes
Lines
672
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 vcnl3020_data {
	struct regmap *regmap;
	struct device *dev;
	u8 rev;
	struct mutex lock;
	__be16 buf;
};

/**
 * struct vcnl3020_property - vcnl3020 property.
 * @name:	property name.
 * @reg:	i2c register offset.
 * @conversion_func:	conversion function.
 */
struct vcnl3020_property {
	const char *name;
	u32 reg;
	u32 (*conversion_func)(u32 *val);
};

static u32 microamp_to_reg(u32 *val)
{
	/*
	 * An example of conversion from uA to reg val:
	 * 200000 uA == 200 mA == 20
	 */
	return *val /= 10000;
};

static const struct vcnl3020_property vcnl3020_led_current_property = {
	.name = "vishay,led-current-microamp",
	.reg = VCNL_LED_CURRENT,
	.conversion_func = microamp_to_reg,
};

static int vcnl3020_get_and_apply_property(struct vcnl3020_data *data,
					   const struct vcnl3020_property *prop)
{
	int rc;
	u32 val;

	rc = device_property_read_u32(data->dev, prop->name, &val);
	if (rc)
		return 0;

	if (prop->conversion_func)
		prop->conversion_func(&val);

	rc = regmap_write(data->regmap, prop->reg, val);
	if (rc) {
		dev_err(data->dev, "Error (%d) setting property (%s)\n",
			rc, prop->name);
	}

	return rc;
}

static int vcnl3020_init(struct vcnl3020_data *data)
{
	int rc;
	unsigned int reg;

	rc = regmap_read(data->regmap, VCNL_PROD_REV, &reg);
	if (rc) {
		dev_err(data->dev,
			"Error (%d) reading product revision\n", rc);
		return rc;
	}

	if (reg != VCNL3020_PROD_ID) {
		dev_err(data->dev,
			"Product id (%x) did not match vcnl3020 (%x)\n", reg,
			VCNL3020_PROD_ID);
		return -ENODEV;
	}

	data->rev = reg;
	mutex_init(&data->lock);

	return vcnl3020_get_and_apply_property(data,
					       &vcnl3020_led_current_property);
};

static bool vcnl3020_is_in_periodic_mode(struct vcnl3020_data *data)
{
	int rc;
	unsigned int cmd;

	rc = regmap_read(data->regmap, VCNL_COMMAND, &cmd);
	if (rc) {

Annotation

Implementation Notes