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.

Dependency Surface

Detected Declarations

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

Implementation Notes