drivers/media/dvb-frontends/tc90522.c

Source file repositories/reference/linux-study-clean/drivers/media/dvb-frontends/tc90522.c

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/tc90522.c
Extension
.c
Size
20245 bytes
Lines
853
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 tc90522_state {
	struct tc90522_config cfg;
	struct dvb_frontend fe;
	struct i2c_client *i2c_client;
	struct i2c_adapter tuner_i2c;

	bool lna;
};

struct reg_val {
	u8 reg;
	u8 val;
};

static int
reg_write(struct tc90522_state *state, const struct reg_val *regs, int num)
{
	int i, ret;
	struct i2c_msg msg;

	ret = 0;
	msg.addr = state->i2c_client->addr;
	msg.flags = 0;
	msg.len = 2;
	for (i = 0; i < num; i++) {
		msg.buf = (u8 *)&regs[i];
		ret = i2c_transfer(state->i2c_client->adapter, &msg, 1);
		if (ret == 0)
			ret = -EIO;
		if (ret < 0)
			return ret;
	}
	return 0;
}

static int reg_read(struct tc90522_state *state, u8 reg, u8 *val, u8 len)
{
	struct i2c_msg msgs[2] = {
		{
			.addr = state->i2c_client->addr,
			.flags = 0,
			.buf = &reg,
			.len = 1,
		},
		{
			.addr = state->i2c_client->addr,
			.flags = I2C_M_RD,
			.buf = val,
			.len = len,
		},
	};
	int ret;

	ret = i2c_transfer(state->i2c_client->adapter, msgs, ARRAY_SIZE(msgs));
	if (ret == ARRAY_SIZE(msgs))
		ret = 0;
	else if (ret >= 0)
		ret = -EIO;
	return ret;
}

static struct tc90522_state *cfg_to_state(struct tc90522_config *c)
{
	return container_of(c, struct tc90522_state, cfg);
}


static int tc90522s_set_tsid(struct dvb_frontend *fe)
{
	struct reg_val set_tsid[] = {
		{ 0x8f, 00 },
		{ 0x90, 00 }
	};

	set_tsid[0].val = (fe->dtv_property_cache.stream_id & 0xff00) >> 8;
	set_tsid[1].val = fe->dtv_property_cache.stream_id & 0xff;
	return reg_write(fe->demodulator_priv, set_tsid, ARRAY_SIZE(set_tsid));
}

static int tc90522t_set_layers(struct dvb_frontend *fe)
{
	struct reg_val rv;
	u8 laysel;

	laysel = ~fe->dtv_property_cache.isdbt_layer_enabled & 0x07;
	laysel = (laysel & 0x01) << 2 | (laysel & 0x02) | (laysel & 0x04) >> 2;
	rv.reg = 0x71;
	rv.val = laysel;
	return reg_write(fe->demodulator_priv, &rv, 1);
}

Annotation

Implementation Notes