drivers/media/dvb-frontends/lgdt3306a.c
Source file repositories/reference/linux-study-clean/drivers/media/dvb-frontends/lgdt3306a.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/dvb-frontends/lgdt3306a.c- Extension
.c- Size
- 56546 bytes
- Lines
- 2268
- 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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
asm/div64.hlinux/kernel.hlinux/dvb/frontend.hlinux/int_log.hlgdt3306a.hlinux/i2c-mux.h
Detected Declarations
struct lgdt3306a_stateenum lgdt3306a_lock_statusenum lgdt3306a_neverlock_statusenum lgdt3306a_modulationenum lgdt3306a_lock_checkfunction lgdt3306a_write_regfunction lgdt3306a_read_regfunction lgdt3306a_set_reg_bitfunction lgdt3306a_soft_resetfunction lgdt3306a_mpeg_modefunction lgdt3306a_mpeg_mode_polarityfunction lgdt3306a_mpeg_tristatefunction lgdt3306a_ts_bus_ctrlfunction lgdt3306a_powerfunction lgdt3306a_set_vsbfunction lgdt3306a_set_qamfunction lgdt3306a_set_modulationfunction lgdt3306a_agc_setupfunction lgdt3306a_set_inversionfunction lgdt3306a_set_inversion_autofunction lgdt3306a_set_iffunction lgdt3306a_i2c_gate_ctrlfunction lgdt3306a_sleepfunction lgdt3306a_fe_sleepfunction lgdt3306a_initfunction lgdt3306a_set_parametersfunction lgdt3306a_get_frontendfunction lgdt3306a_get_frontend_algofunction lgdt3306a_monitor_vsbfunction lgdt3306a_check_oper_modefunction lgdt3306a_check_lock_statusfunction lgdt3306a_check_neverlock_statusfunction lgdt3306a_pre_monitoringfunction lgdt3306a_sync_lock_pollfunction lgdt3306a_fec_lock_pollfunction lgdt3306a_neverlock_pollfunction lgdt3306a_get_packet_errorfunction log10_x1000function lgdt3306a_calculate_snr_x100function lgdt3306a_vsb_lock_pollfunction lgdt3306a_qam_lock_pollfunction lgdt3306a_read_statusfunction lgdt3306a_read_snrfunction lgdt3306a_read_signal_strengthfunction lgdt3306a_read_berfunction lgdt3306a_read_ucblocksfunction lgdt3306a_tunefunction lgdt3306a_get_tune_settings
Annotated Snippet
struct lgdt3306a_state {
struct i2c_adapter *i2c_adap;
const struct lgdt3306a_config *cfg;
struct dvb_frontend frontend;
enum fe_modulation current_modulation;
u32 current_frequency;
u32 snr;
struct i2c_mux_core *muxc;
};
/*
* LG3306A Register Usage
* (LG does not really name the registers, so this code does not either)
*
* 0000 -> 00FF Common control and status
* 1000 -> 10FF Synchronizer control and status
* 1F00 -> 1FFF Smart Antenna control and status
* 2100 -> 21FF VSB Equalizer control and status
* 2800 -> 28FF QAM Equalizer control and status
* 3000 -> 30FF FEC control and status
*/
enum lgdt3306a_lock_status {
LG3306_UNLOCK = 0x00,
LG3306_LOCK = 0x01,
LG3306_UNKNOWN_LOCK = 0xff
};
enum lgdt3306a_neverlock_status {
LG3306_NL_INIT = 0x00,
LG3306_NL_PROCESS = 0x01,
LG3306_NL_LOCK = 0x02,
LG3306_NL_FAIL = 0x03,
LG3306_NL_UNKNOWN = 0xff
};
enum lgdt3306a_modulation {
LG3306_VSB = 0x00,
LG3306_QAM64 = 0x01,
LG3306_QAM256 = 0x02,
LG3306_UNKNOWN_MODE = 0xff
};
enum lgdt3306a_lock_check {
LG3306_SYNC_LOCK,
LG3306_FEC_LOCK,
LG3306_TR_LOCK,
LG3306_AGC_LOCK,
};
#ifdef DBG_DUMP
static void lgdt3306a_DumpAllRegs(struct lgdt3306a_state *state);
static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state);
#endif
static int lgdt3306a_write_reg(struct lgdt3306a_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,
};
dbg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
ret = i2c_transfer(state->i2c_adap, &msg, 1);
if (ret != 1) {
pr_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 lgdt3306a_read_reg(struct lgdt3306a_state *state, u16 reg, u8 *val)
{
int ret;
u8 reg_buf[] = { reg >> 8, reg & 0xff };
struct i2c_msg msg[] = {
{ .addr = state->cfg->i2c_addr,
Annotation
- Immediate include surface: `asm/div64.h`, `linux/kernel.h`, `linux/dvb/frontend.h`, `linux/int_log.h`, `lgdt3306a.h`, `linux/i2c-mux.h`.
- Detected declarations: `struct lgdt3306a_state`, `enum lgdt3306a_lock_status`, `enum lgdt3306a_neverlock_status`, `enum lgdt3306a_modulation`, `enum lgdt3306a_lock_check`, `function lgdt3306a_write_reg`, `function lgdt3306a_read_reg`, `function lgdt3306a_set_reg_bit`, `function lgdt3306a_soft_reset`, `function lgdt3306a_mpeg_mode`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.