drivers/media/dvb-frontends/stv0297.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/stv0297.c
Extension
.c
Size
17067 bytes
Lines
714
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 stv0297_state {
	struct i2c_adapter *i2c;
	const struct stv0297_config *config;
	struct dvb_frontend frontend;

	unsigned long last_ber;
	unsigned long base_freq;
};

#if 1
#define dprintk(x...) printk(x)
#else
#define dprintk(x...)
#endif

#define STV0297_CLOCK_KHZ   28900


static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
{
	int ret;
	u8 buf[] = { reg, data };
	struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };

	ret = i2c_transfer(state->i2c, &msg, 1);

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

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

static int stv0297_readreg(struct stv0297_state *state, u8 reg)
{
	int ret;
	u8 b0[] = { reg };
	u8 b1[] = { 0 };
	struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
				 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
			       };

	// this device needs a STOP between the register and data
	if (state->config->stop_during_read) {
		if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
			dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
			return -1;
		}
		if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
			dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
			return -1;
		}
	} else {
		if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
			dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
			return -1;
		}
	}

	return b1[0];
}

static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data)
{
	int val;

	val = stv0297_readreg(state, reg);
	val &= ~mask;
	val |= (data & mask);
	stv0297_writereg(state, reg, val);

	return 0;
}

static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len)
{
	int ret;
	struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
				  &reg1,.len = 1},
	{.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
	};

	// this device needs a STOP between the register and data
	if (state->config->stop_during_read) {
		if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
			dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
			return -1;
		}
		if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
			dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);

Annotation

Implementation Notes