drivers/media/radio/saa7706h.c

Source file repositories/reference/linux-study-clean/drivers/media/radio/saa7706h.c

File Facts

System
Linux kernel
Corpus path
drivers/media/radio/saa7706h.c
Extension
.c
Size
11146 bytes
Lines
418
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 saa7706h_state {
	struct v4l2_subdev sd;
	struct v4l2_ctrl_handler hdl;
	unsigned muted;
};

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

static int saa7706h_i2c_send(struct i2c_client *client, const u8 *data, int len)
{
	int err = i2c_master_send(client, data, len);
	if (err == len)
		return 0;
	return err > 0 ? -EIO : err;
}

static int saa7706h_i2c_transfer(struct i2c_client *client,
	struct i2c_msg *msgs, int num)
{
	int err = i2c_transfer(client->adapter, msgs, num);
	if (err == num)
		return 0;
	return err > 0 ? -EIO : err;
}

static int saa7706h_set_reg24(struct v4l2_subdev *sd, u16 reg, u32 val)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	u8 buf[5];
	int pos = 0;

	buf[pos++] = reg >> 8;
	buf[pos++] = reg;
	buf[pos++] = val >> 16;
	buf[pos++] = val >> 8;
	buf[pos++] = val;

	return saa7706h_i2c_send(client, buf, pos);
}

static int saa7706h_set_reg24_err(struct v4l2_subdev *sd, u16 reg, u32 val,
	int *err)
{
	return *err ? *err : saa7706h_set_reg24(sd, reg, val);
}

static int saa7706h_set_reg16(struct v4l2_subdev *sd, u16 reg, u16 val)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	u8 buf[4];
	int pos = 0;

	buf[pos++] = reg >> 8;
	buf[pos++] = reg;
	buf[pos++] = val >> 8;
	buf[pos++] = val;

	return saa7706h_i2c_send(client, buf, pos);
}

static int saa7706h_set_reg16_err(struct v4l2_subdev *sd, u16 reg, u16 val,
	int *err)
{
	return *err ? *err : saa7706h_set_reg16(sd, reg, val);
}

static int saa7706h_get_reg16(struct v4l2_subdev *sd, u16 reg)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	u8 buf[2];
	int err;
	u8 regaddr[] = {reg >> 8, reg};
	struct i2c_msg msg[] = {
					{
						.addr = client->addr,
						.len = sizeof(regaddr),
						.buf = regaddr
					},
					{
						.addr = client->addr,
						.flags = I2C_M_RD,
						.len = sizeof(buf),
						.buf = buf
					}
				};

	err = saa7706h_i2c_transfer(client, msg, ARRAY_SIZE(msg));

Annotation

Implementation Notes