drivers/media/dvb-frontends/lgdt3305.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/lgdt3305.c
Extension
.c
Size
31233 bytes
Lines
1203
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 lgdt3305_state {
	struct i2c_adapter *i2c_adap;
	const struct lgdt3305_config *cfg;

	struct dvb_frontend frontend;

	enum fe_modulation current_modulation;
	u32 current_frequency;
	u32 snr;
};

/* ------------------------------------------------------------------------ */

/* FIXME: verify & document the LGDT3304 registers */

#define LGDT3305_GEN_CTRL_1                   0x0000
#define LGDT3305_GEN_CTRL_2                   0x0001
#define LGDT3305_GEN_CTRL_3                   0x0002
#define LGDT3305_GEN_STATUS                   0x0003
#define LGDT3305_GEN_CONTROL                  0x0007
#define LGDT3305_GEN_CTRL_4                   0x000a
#define LGDT3305_DGTL_AGC_REF_1               0x0012
#define LGDT3305_DGTL_AGC_REF_2               0x0013
#define LGDT3305_CR_CTR_FREQ_1                0x0106
#define LGDT3305_CR_CTR_FREQ_2                0x0107
#define LGDT3305_CR_CTR_FREQ_3                0x0108
#define LGDT3305_CR_CTR_FREQ_4                0x0109
#define LGDT3305_CR_MSE_1                     0x011b
#define LGDT3305_CR_MSE_2                     0x011c
#define LGDT3305_CR_LOCK_STATUS               0x011d
#define LGDT3305_CR_CTRL_7                    0x0126
#define LGDT3305_AGC_POWER_REF_1              0x0300
#define LGDT3305_AGC_POWER_REF_2              0x0301
#define LGDT3305_AGC_DELAY_PT_1               0x0302
#define LGDT3305_AGC_DELAY_PT_2               0x0303
#define LGDT3305_RFAGC_LOOP_FLTR_BW_1         0x0306
#define LGDT3305_RFAGC_LOOP_FLTR_BW_2         0x0307
#define LGDT3305_IFBW_1                       0x0308
#define LGDT3305_IFBW_2                       0x0309
#define LGDT3305_AGC_CTRL_1                   0x030c
#define LGDT3305_AGC_CTRL_4                   0x0314
#define LGDT3305_EQ_MSE_1                     0x0413
#define LGDT3305_EQ_MSE_2                     0x0414
#define LGDT3305_EQ_MSE_3                     0x0415
#define LGDT3305_PT_MSE_1                     0x0417
#define LGDT3305_PT_MSE_2                     0x0418
#define LGDT3305_PT_MSE_3                     0x0419
#define LGDT3305_FEC_BLOCK_CTRL               0x0504
#define LGDT3305_FEC_LOCK_STATUS              0x050a
#define LGDT3305_FEC_PKT_ERR_1                0x050c
#define LGDT3305_FEC_PKT_ERR_2                0x050d
#define LGDT3305_TP_CTRL_1                    0x050e
#define LGDT3305_BERT_PERIOD                  0x0801
#define LGDT3305_BERT_ERROR_COUNT_1           0x080a
#define LGDT3305_BERT_ERROR_COUNT_2           0x080b
#define LGDT3305_BERT_ERROR_COUNT_3           0x080c
#define LGDT3305_BERT_ERROR_COUNT_4           0x080d

static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
{
	int ret;
	u8 buf[] = { reg >> 8, reg & 0xff, val };
	struct i2c_msg msg = {
		.addr = state->cfg->i2c_addr, .flags = 0,
		.buf = buf, .len = 3,
	};

	lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);

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

	if (ret != 1) {
		lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
		       msg.buf[0], msg.buf[1], msg.buf[2], ret);
		if (ret < 0)
			return ret;
		else
			return -EREMOTEIO;
	}
	return 0;
}

static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
{
	int ret;
	u8 reg_buf[] = { reg >> 8, reg & 0xff };
	struct i2c_msg msg[] = {
		{ .addr = state->cfg->i2c_addr,
		  .flags = 0, .buf = reg_buf, .len = 2 },
		{ .addr = state->cfg->i2c_addr,

Annotation

Implementation Notes