drivers/media/dvb-frontends/mt312.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/mt312.c
Extension
.c
Size
18265 bytes
Lines
840
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 mt312_state {
	struct i2c_adapter *i2c;
	/* configuration settings */
	const struct mt312_config *config;
	struct dvb_frontend frontend;

	u8 id;
	unsigned long xtal;
	u8 freq_mult;
};

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

#define MT312_PLL_CLK		10000000UL	/* 10 MHz */
#define MT312_PLL_CLK_10_111	10111000UL	/* 10.111 MHz */

static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
		      u8 *buf, const size_t count)
{
	int ret;
	struct i2c_msg msg[2];
	u8 regbuf[1] = { reg };

	msg[0].addr = state->config->demod_address;
	msg[0].flags = 0;
	msg[0].buf = regbuf;
	msg[0].len = 1;
	msg[1].addr = state->config->demod_address;
	msg[1].flags = I2C_M_RD;
	msg[1].buf = buf;
	msg[1].len = count;

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

	if (ret != 2) {
		printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret);
		return -EREMOTEIO;
	}

	if (debug) {
		int i;
		dprintk("R(%d):", reg & 0x7f);
		for (i = 0; i < count; i++)
			printk(KERN_CONT " %02x", buf[i]);
		printk("\n");
	}

	return 0;
}

static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
		       const u8 *src, const size_t count)
{
	int ret;
	u8 buf[MAX_XFER_SIZE];
	struct i2c_msg msg;

	if (1 + count > sizeof(buf)) {
		printk(KERN_WARNING
		       "mt312: write: len=%zu is too big!\n", count);
		return -EINVAL;
	}

	if (debug) {
		int i;
		dprintk("W(%d):", reg & 0x7f);
		for (i = 0; i < count; i++)
			printk(KERN_CONT " %02x", src[i]);
		printk("\n");
	}

	buf[0] = reg;
	memcpy(&buf[1], src, count);

	msg.addr = state->config->demod_address;
	msg.flags = 0;
	msg.buf = buf;
	msg.len = count + 1;

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

	if (ret != 1) {
		dprintk("%s: ret == %d\n", __func__, ret);
		return -EREMOTEIO;
	}

Annotation

Implementation Notes