drivers/media/i2c/saa7110.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/i2c/saa7110.c
Extension
.c
Size
12620 bytes
Lines
457
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 saa7110 {
	struct v4l2_subdev sd;
	struct v4l2_ctrl_handler hdl;
	u8 reg[SAA7110_NR_REG];

	v4l2_std_id norm;
	int input;
	int enable;

	wait_queue_head_t wq;
};

static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
{
	return container_of(sd, struct saa7110, sd);
}

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

/* ----------------------------------------------------------------------- */
/* I2C support functions						   */
/* ----------------------------------------------------------------------- */

static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct saa7110 *decoder = to_saa7110(sd);

	decoder->reg[reg] = value;
	return i2c_smbus_write_byte_data(client, reg, value);
}

static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct saa7110 *decoder = to_saa7110(sd);
	int ret = -1;
	u8 reg = *data;		/* first register to write to */

	/* Sanity check */
	if (reg + (len - 1) > SAA7110_NR_REG)
		return ret;

	/* the saa7110 has an autoincrement function, use it if
	 * the adapter understands raw I2C */
	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		ret = i2c_master_send(client, data, len);

		/* Cache the written data */
		memcpy(decoder->reg + reg, data + 1, len - 1);
	} else {
		for (++data, --len; len; len--) {
			ret = saa7110_write(sd, reg++, *data++);
			if (ret < 0)
				break;
		}
	}

	return ret;
}

static inline int saa7110_read(struct v4l2_subdev *sd)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	return i2c_smbus_read_byte(client);
}

/* ----------------------------------------------------------------------- */
/* SAA7110 functions							   */
/* ----------------------------------------------------------------------- */

#define FRESP_06H_COMPST 0x03	/*0x13*/
#define FRESP_06H_SVIDEO 0x83	/*0xC0*/


static int saa7110_selmux(struct v4l2_subdev *sd, int chan)
{
	static const unsigned char modes[9][8] = {
		/* mode 0 */
		{FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03,
			      0x44, 0x75, 0x16},
		/* mode 1 */
		{FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03,
			      0x44, 0x75, 0x16},
		/* mode 2 */
		{FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03,

Annotation

Implementation Notes