drivers/media/i2c/cs5345.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/i2c/cs5345.c
Extension
.c
Size
5088 bytes
Lines
207
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 cs5345_state {
	struct v4l2_subdev sd;
	struct v4l2_ctrl_handler hdl;
};

static inline struct cs5345_state *to_state(struct v4l2_subdev *sd)
{
	return container_of(sd, struct cs5345_state, sd);
}

static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{
	return &container_of(ctrl->handler, struct cs5345_state, hdl)->sd;
}

/* ----------------------------------------------------------------------- */

static inline int cs5345_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	return i2c_smbus_write_byte_data(client, reg, value);
}

static inline int cs5345_read(struct v4l2_subdev *sd, u8 reg)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	return i2c_smbus_read_byte_data(client, reg);
}

static int cs5345_s_routing(struct v4l2_subdev *sd,
			    u32 input, u32 output, u32 config)
{
	if ((input & 0xf) > 6) {
		v4l2_err(sd, "Invalid input %d.\n", input);
		return -EINVAL;
	}
	cs5345_write(sd, 0x09, input & 0xf);
	cs5345_write(sd, 0x05, input & 0xf0);
	return 0;
}

static int cs5345_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct v4l2_subdev *sd = to_sd(ctrl);

	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
		cs5345_write(sd, 0x04, ctrl->val ? 0x80 : 0);
		return 0;
	case V4L2_CID_AUDIO_VOLUME:
		cs5345_write(sd, 0x07, ((u8)ctrl->val) & 0x3f);
		cs5345_write(sd, 0x08, ((u8)ctrl->val) & 0x3f);
		return 0;
	}
	return -EINVAL;
}

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
	reg->size = 1;
	reg->val = cs5345_read(sd, reg->reg & 0x1f);
	return 0;
}

static int cs5345_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
	cs5345_write(sd, reg->reg & 0x1f, reg->val & 0xff);
	return 0;
}
#endif

static int cs5345_log_status(struct v4l2_subdev *sd)
{
	u8 v = cs5345_read(sd, 0x09) & 7;
	u8 m = cs5345_read(sd, 0x04);
	int vol = cs5345_read(sd, 0x08) & 0x3f;

	v4l2_info(sd, "Input:  %d%s\n", v,
			(m & 0x80) ? " (muted)" : "");
	if (vol >= 32)
		vol = vol - 64;
	v4l2_info(sd, "Volume: %d dB\n", vol);
	return 0;
}

/* ----------------------------------------------------------------------- */

Annotation

Implementation Notes