drivers/media/dvb-frontends/tda10086.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/tda10086.c
Extension
.c
Size
18515 bytes
Lines
768
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 tda10086_state {
	struct i2c_adapter* i2c;
	const struct tda10086_config* config;
	struct dvb_frontend frontend;

	/* private demod data */
	u32 frequency;
	u32 symbol_rate;
	bool has_lock;
};

static int debug;
#define dprintk(args...) \
	do { \
		if (debug) printk(KERN_DEBUG "tda10086: " args); \
	} while (0)

static int tda10086_write_byte(struct tda10086_state *state, int reg, int data)
{
	int ret;
	u8 b0[] = { reg, data };
	struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 };

	msg.addr = state->config->demod_address;
	ret = i2c_transfer(state->i2c, &msg, 1);

	if (ret != 1)
		dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
			__func__, reg, data, ret);

	return (ret != 1) ? ret : 0;
}

static int tda10086_read_byte(struct tda10086_state *state, int reg)
{
	int ret;
	u8 b0[] = { reg };
	u8 b1[] = { 0 };
	struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
				{ .flags = I2C_M_RD, .buf = b1, .len = 1 }};

	msg[0].addr = state->config->demod_address;
	msg[1].addr = state->config->demod_address;
	ret = i2c_transfer(state->i2c, msg, 2);

	if (ret != 2) {
		dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
			ret);
		return ret;
	}

	return b1[0];
}

static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data)
{
	int val;

	/* read a byte and check */
	val = tda10086_read_byte(state, reg);
	if (val < 0)
		return val;

	/* mask if off */
	val = val & ~mask;
	val |= data & 0xff;

	/* write it out again */
	return tda10086_write_byte(state, reg, val);
}

static int tda10086_init(struct dvb_frontend* fe)
{
	struct tda10086_state* state = fe->demodulator_priv;
	u8 t22k_off = 0x80;

	dprintk ("%s\n", __func__);

	if (state->config->diseqc_tone)
		t22k_off = 0;
	/* reset */
	tda10086_write_byte(state, 0x00, 0x00);
	msleep(10);

	/* misc setup */
	tda10086_write_byte(state, 0x01, 0x94);
	tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */
	tda10086_write_byte(state, 0x03, 0xe4);
	tda10086_write_byte(state, 0x04, 0x43);
	tda10086_write_byte(state, 0x0c, 0x0c);

Annotation

Implementation Notes