drivers/media/dvb-frontends/sp887x.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/sp887x.c
Extension
.c
Size
15207 bytes
Lines
628
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 sp887x_state {
	struct i2c_adapter* i2c;
	const struct sp887x_config* config;
	struct dvb_frontend frontend;

	/* demodulator private data */
	u8 initialised:1;
};

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

static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
{
	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
	int err;

	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
		printk ("%s: i2c write error (addr %02x, err == %i)\n",
			__func__, state->config->demod_address, err);
		return -EREMOTEIO;
	}

	return 0;
}

static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
{
	u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
	int ret;

	if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
		/*
		 *  in case of soft reset we ignore ACK errors...
		 */
		if (!(reg == 0xf1a && data == 0x000 &&
			(ret == -EREMOTEIO || ret == -EFAULT)))
		{
			printk("%s: writereg error (reg %03x, data %03x, ret == %i)\n",
			       __func__, reg & 0xffff, data & 0xffff, ret);
			return ret;
		}
	}

	return 0;
}

static int sp887x_readreg (struct sp887x_state* state, u16 reg)
{
	u8 b0 [] = { reg >> 8 , reg & 0xff };
	u8 b1 [2];
	int ret;
	struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
			 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};

	if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
		printk("%s: readreg error (ret == %i)\n", __func__, ret);
		return -1;
	}

	return (((b1[0] << 8) | b1[1]) & 0xfff);
}

static void sp887x_microcontroller_stop (struct sp887x_state* state)
{
	dprintk("%s\n", __func__);
	sp887x_writereg(state, 0xf08, 0x000);
	sp887x_writereg(state, 0xf09, 0x000);

	/* microcontroller STOP */
	sp887x_writereg(state, 0xf00, 0x000);
}

static void sp887x_microcontroller_start (struct sp887x_state* state)
{
	dprintk("%s\n", __func__);
	sp887x_writereg(state, 0xf08, 0x000);
	sp887x_writereg(state, 0xf09, 0x000);

	/* microcontroller START */
	sp887x_writereg(state, 0xf00, 0x001);
}

static void sp887x_setup_agc (struct sp887x_state* state)
{
	/* setup AGC parameters */

Annotation

Implementation Notes