drivers/media/dvb-frontends/zl10036.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/zl10036.c
Extension
.c
Size
11648 bytes
Lines
507
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 zl10036_state {
	struct i2c_adapter *i2c;
	const struct zl10036_config *config;
	u32 frequency;
	u8 br, bf;
};


/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
#define _XTAL 10111

/* Some of the possible dividers:
 *   64, (write 0x05 to reg), freq step size   158kHz
 *   10, (write 0x0a to reg), freq step size 1.011kHz (used here)
 *    5, (write 0x09 to reg), freq step size 2.022kHz
 */

#define _RDIV 10
#define _RDIV_REG 0x0a
#define _FR   (_XTAL/_RDIV)

#define STATUS_POR 0x80 /* Power on Reset */
#define STATUS_FL  0x40 /* Frequency & Phase Lock */

/* read/write for zl10036 and zl10038 */

static int zl10036_read_status_reg(struct zl10036_state *state)
{
	u8 status;
	struct i2c_msg msg[1] = {
		{ .addr = state->config->tuner_address, .flags = I2C_M_RD,
		  .buf = &status, .len = sizeof(status) },
	};

	if (i2c_transfer(state->i2c, msg, 1) != 1) {
		printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
			__func__, state->config->tuner_address);
		return -EIO;
	}

	deb_i2c("R(status): %02x  [FL=%d]\n", status,
		(status & STATUS_FL) ? 1 : 0);
	if (status & STATUS_POR)
		deb_info("%s: Power-On-Reset bit enabled - need to initialize the tuner\n",
			 __func__);

	return status;
}

static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
{
	struct i2c_msg msg[1] = {
		{ .addr = state->config->tuner_address, .flags = 0,
		  .buf = buf, .len = count },
	};
	u8 reg = 0;
	int ret;

	if (zl10036_debug & 0x02) {
		/* every 8bit-value satisfies this!
		 * so only check for debug log */
		if ((buf[0] & 0x80) == 0x00)
			reg = 2;
		else if ((buf[0] & 0xc0) == 0x80)
			reg = 4;
		else if ((buf[0] & 0xf0) == 0xc0)
			reg = 6;
		else if ((buf[0] & 0xf0) == 0xd0)
			reg = 8;
		else if ((buf[0] & 0xf0) == 0xe0)
			reg = 10;
		else if ((buf[0] & 0xf0) == 0xf0)
			reg = 12;

		deb_i2c("W(%d):", reg);
		{
			int i;
			for (i = 0; i < count; i++)
				printk(KERN_CONT " %02x", buf[i]);
			printk(KERN_CONT "\n");
		}
	}

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

	return 0;

Annotation

Implementation Notes