drivers/media/dvb-frontends/tda1004x.c
Source file repositories/reference/linux-study-clean/drivers/media/dvb-frontends/tda1004x.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/dvb-frontends/tda1004x.c- Extension
.c- Size
- 39048 bytes
- Lines
- 1383
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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
linux/init.hlinux/module.hlinux/device.hlinux/jiffies.hlinux/string.hlinux/slab.hmedia/dvb_frontend.htda1004x.h
Detected Declarations
function tda1004x_write_byteIfunction tda1004x_read_bytefunction tda1004x_write_maskfunction tda1004x_write_buffunction tda1004x_enable_tuner_i2cfunction tda1004x_disable_tuner_i2cfunction tda10045h_set_bandwidthfunction tda10046h_set_bandwidthfunction tda1004x_do_uploadfunction tda1004x_check_upload_okfunction tda10045_fwuploadfunction tda10046_init_pllsfunction tda10046_fwuploadfunction tda1004x_encode_fecfunction tda1004x_decode_fecfunction tda1004x_writefunction tda10045_initfunction tda10046_initfunction tda1004x_set_fefunction tda1004x_get_fefunction tda1004x_read_statusfunction tda1004x_read_signal_strengthfunction tda1004x_read_snrfunction tda1004x_read_ucblocksfunction tda1004x_read_berfunction tda1004x_sleepfunction tda1004x_i2c_gate_ctrlfunction tda1004x_get_tune_settingsfunction tda1004x_releasefunction tda10045_attachfunction tda10046_attachexport tda10045_attachexport tda10046_attach
Annotated Snippet
if (state->config->if_freq == TDA10046_FREQ_045) {
tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab);
}
break;
case 7000000:
if (tda10046_clk53m)
tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M,
sizeof(bandwidth_7mhz_53M));
else
tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M,
sizeof(bandwidth_7mhz_48M));
if (state->config->if_freq == TDA10046_FREQ_045) {
tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
}
break;
case 8000000:
if (tda10046_clk53m)
tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M,
sizeof(bandwidth_8mhz_53M));
else
tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M,
sizeof(bandwidth_8mhz_48M));
if (state->config->if_freq == TDA10046_FREQ_045) {
tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55);
}
break;
default:
return -EINVAL;
}
return 0;
}
static int tda1004x_do_upload(struct tda1004x_state *state,
const unsigned char *mem, unsigned int len,
u8 dspCodeCounterReg, u8 dspCodeInReg)
{
u8 buf[65];
struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 };
int tx_size;
int pos = 0;
/* clear code counter */
tda1004x_write_byteI(state, dspCodeCounterReg, 0);
fw_msg.addr = state->config->demod_address;
i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT);
buf[0] = dspCodeInReg;
while (pos != len) {
// work out how much to send this time
tx_size = len - pos;
if (tx_size > 0x10)
tx_size = 0x10;
// send the chunk
memcpy(buf + 1, mem + pos, tx_size);
fw_msg.len = tx_size + 1;
if (__i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
printk(KERN_ERR "tda1004x: Error during firmware upload\n");
i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
return -EIO;
}
pos += tx_size;
dprintk("%s: fw_pos=0x%x\n", __func__, pos);
}
i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
/* give the DSP a chance to settle 03/10/05 Hac */
msleep(100);
return 0;
}
static int tda1004x_check_upload_ok(struct tda1004x_state *state)
{
u8 data1, data2;
unsigned long timeout;
if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
timeout = jiffies + 2 * HZ;
while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
if (time_after(jiffies, timeout)) {
printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
Annotation
- Immediate include surface: `linux/init.h`, `linux/module.h`, `linux/device.h`, `linux/jiffies.h`, `linux/string.h`, `linux/slab.h`, `media/dvb_frontend.h`, `tda1004x.h`.
- Detected declarations: `function tda1004x_write_byteI`, `function tda1004x_read_byte`, `function tda1004x_write_mask`, `function tda1004x_write_buf`, `function tda1004x_enable_tuner_i2c`, `function tda1004x_disable_tuner_i2c`, `function tda10045h_set_bandwidth`, `function tda10046h_set_bandwidth`, `function tda1004x_do_upload`, `function tda1004x_check_upload_ok`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.