drivers/media/i2c/ths8200.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/i2c/ths8200.c
Extension
.c
Size
15116 bytes
Lines
514
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 ths8200_state {
	struct v4l2_subdev sd;
	uint8_t chip_version;
	/* Is the ths8200 powered on? */
	bool power_on;
	struct v4l2_dv_timings dv_timings;
};

static const struct v4l2_dv_timings_cap ths8200_timings_cap = {
	.type = V4L2_DV_BT_656_1120,
	/* keep this initialization for compatibility with GCC < 4.4.6 */
	.reserved = { 0 },
	V4L2_INIT_BT_TIMINGS(640, 1920, 350, 1080, 25000000, 148500000,
		V4L2_DV_BT_STD_CEA861, V4L2_DV_BT_CAP_PROGRESSIVE)
};

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

static inline unsigned htotal(const struct v4l2_bt_timings *t)
{
	return V4L2_DV_BT_FRAME_WIDTH(t);
}

static inline unsigned vtotal(const struct v4l2_bt_timings *t)
{
	return V4L2_DV_BT_FRAME_HEIGHT(t);
}

static int ths8200_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 ths8200_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	int ret;
	int i;

	for (i = 0; i < 3; i++) {
		ret = i2c_smbus_write_byte_data(client, reg, val);
		if (ret == 0)
			return 0;
	}
	v4l2_err(sd, "I2C Write Problem\n");
	return ret;
}

/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
 * and then the value-mask (to be OR-ed).
 */
static inline void
ths8200_write_and_or(struct v4l2_subdev *sd, u8 reg,
		     uint8_t clr_mask, uint8_t val_mask)
{
	ths8200_write(sd, reg, (ths8200_read(sd, reg) & clr_mask) | val_mask);
}

#ifdef CONFIG_VIDEO_ADV_DEBUG

static int ths8200_g_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
{
	reg->val = ths8200_read(sd, reg->reg & 0xff);
	reg->size = 1;

	return 0;
}

static int ths8200_s_register(struct v4l2_subdev *sd,
			      const struct v4l2_dbg_register *reg)
{
	ths8200_write(sd, reg->reg & 0xff, reg->val & 0xff);

	return 0;
}
#endif

static int ths8200_log_status(struct v4l2_subdev *sd)
{
	struct ths8200_state *state = to_state(sd);
	uint8_t reg_03 = ths8200_read(sd, THS8200_CHIP_CTL);

	v4l2_info(sd, "----- Chip status -----\n");
	v4l2_info(sd, "version: %u\n", state->chip_version);

Annotation

Implementation Notes