drivers/media/i2c/saa7115.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/i2c/saa7115.c
Extension
.c
Size
56571 bytes
Lines
1952
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 saa711x_state {
	struct v4l2_subdev sd;
#ifdef CONFIG_MEDIA_CONTROLLER
	struct media_pad pads[SAA711X_NUM_PADS];
#endif
	struct v4l2_ctrl_handler hdl;

	struct {
		/* chroma gain control cluster */
		struct v4l2_ctrl *agc;
		struct v4l2_ctrl *gain;
	};

	v4l2_std_id std;
	int input;
	int output;
	int enable;
	int radio;
	int width;
	int height;
	enum saa711x_model ident;
	u32 audclk_freq;
	u32 crystal_freq;
	bool ucgc;
	u8 cgcdiv;
	bool apll;
	bool double_asclk;
};

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

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

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

static inline int saa711x_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);
}

/* Sanity routine to check if a register is present */
static int saa711x_has_reg(const int id, const u8 reg)
{
	if (id == SAA7111)
		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
		       (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
	if (id == SAA7111A)
		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
		       reg != 0x14 && reg != 0x18 && reg != 0x19 &&
		       reg != 0x1d && reg != 0x1e;

	/* common for saa7113/4/5/8 */
	if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
	    reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
	    reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
	    reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
		return 0;

	switch (id) {
	case GM7113C:
		return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
	case SAA7113:
		return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
		       reg != 0x5d && reg < 0x63;
	case SAA7114:
		return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
		       (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
		       reg != 0x81 && reg < 0xf0;
	case SAA7115:
		return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
	case SAA7118:
		return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
		       (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
		       (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
	}
	return 1;
}

static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
{
	struct saa711x_state *state = to_state(sd);
	unsigned char reg, data;

Annotation

Implementation Notes