drivers/media/i2c/ad5820.c

Source file repositories/reference/linux-study-clean/drivers/media/i2c/ad5820.c

File Facts

System
Linux kernel
Corpus path
drivers/media/i2c/ad5820.c
Extension
.c
Size
8899 bytes
Lines
381
Domain
Driver Families
Bucket
drivers/media
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 ad5820_device {
	struct v4l2_subdev subdev;
	struct ad5820_platform_data *platform_data;
	struct regulator *vana;

	struct v4l2_ctrl_handler ctrls;
	u32 focus_absolute;
	u32 focus_ramp_time;
	u32 focus_ramp_mode;

	struct gpio_desc *enable_gpio;

	struct mutex power_lock;
	int power_count;

	bool standby;
};

static int ad5820_write(struct ad5820_device *coil, u16 data)
{
	struct i2c_client *client = v4l2_get_subdevdata(&coil->subdev);
	struct i2c_msg msg;
	__be16 be_data;
	int r;

	if (!client->adapter)
		return -ENODEV;

	be_data = cpu_to_be16(data);
	msg.addr  = client->addr;
	msg.flags = 0;
	msg.len   = 2;
	msg.buf   = (u8 *)&be_data;

	r = i2c_transfer(client->adapter, &msg, 1);
	if (r < 0) {
		dev_err(&client->dev, "write failed, error %d\n", r);
		return r;
	}

	return 0;
}

/*
 * Calculate status word and write it to the device based on current
 * values of V4L2 controls. It is assumed that the stored V4L2 control
 * values are properly limited and rounded.
 */
static int ad5820_update_hw(struct ad5820_device *coil)
{
	u16 status;

	status = RAMP_US_TO_CODE(coil->focus_ramp_time);
	status |= coil->focus_ramp_mode
		? AD5820_RAMP_MODE_64_16 : AD5820_RAMP_MODE_LINEAR;
	status |= coil->focus_absolute << AD5820_DAC_SHIFT;

	if (coil->standby)
		status |= AD5820_POWER_DOWN;

	return ad5820_write(coil, status);
}

/*
 * Power handling
 */
static int ad5820_power_off(struct ad5820_device *coil, bool standby)
{
	int ret = 0, ret2;

	/*
	 * Go to standby first as real power off my be denied by the hardware
	 * (single power line control for both coil and sensor).
	 */
	if (standby) {
		coil->standby = true;
		ret = ad5820_update_hw(coil);
	}

	gpiod_set_value_cansleep(coil->enable_gpio, 0);

	ret2 = regulator_disable(coil->vana);
	if (ret)
		return ret;
	return ret2;
}

static int ad5820_power_on(struct ad5820_device *coil, bool restore)
{
	int ret;

Annotation

Implementation Notes