⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tda1004x.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                break;        case FE_TYPE_TDA10046H:                dspCodeCounterReg = TDA10046H_CODE_CPT;                dspCodeInReg = TDA10046H_CODE_IN;                dspVersion = 0x20;                fwInfoCount = tda10046h_fwinfo_count;                fwInfo = tda10046h_fwinfo;                break;        }	// Load the firmware	set_fs(get_ds());	fd = sys_open(tda1004x_firmware, 0, 0);	if (fd < 0) {		printk("%s: Unable to open firmware %s\n", __FUNCTION__,		       tda1004x_firmware);		return -EIO;	}	filesize = sys_lseek(fd, 0L, 2);	if (filesize <= 0) {		printk("%s: Firmware %s is empty\n", __FUNCTION__,		       tda1004x_firmware);		sys_close(fd);		return -EIO;	}        // find extraction parameters for firmware        for (fwinfo_idx = 0; fwinfo_idx < fwInfoCount; fwinfo_idx++) {                if (fwInfo[fwinfo_idx].file_size == filesize)			break;	}        if (fwinfo_idx >= fwInfoCount) {		printk("%s: Unsupported firmware %s\n", __FUNCTION__, tda1004x_firmware);		sys_close(fd);		return -EIO;	}        fw_size = fwInfo[fwinfo_idx].fw_size;        fw_offset = fwInfo[fwinfo_idx].fw_offset;	// allocate buffer for it	firmware = vmalloc(fw_size);	if (firmware == NULL) {		printk("%s: Out of memory loading firmware\n",		       __FUNCTION__);		sys_close(fd);		return -EIO;	}	// read it!	sys_lseek(fd, fw_offset, 0);	if (sys_read(fd, firmware, fw_size) != fw_size) {		printk("%s: Failed to read firmware\n", __FUNCTION__);		vfree(firmware);		sys_close(fd);		return -EIO;	}	sys_close(fd);	set_fs(fs);        // set some valid bandwith parameters before uploading        switch(tda_state->fe_type) {        case FE_TYPE_TDA10045H:                // reset chip		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0);                tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8);                tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 0);                dvb_delay(10);                // set parameters                tda10045h_set_bandwidth(i2c, tda_state, BANDWIDTH_8_MHZ);                break;        case FE_TYPE_TDA10046H:                // reset chip		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 1, 0);                tda1004x_write_mask(i2c, tda_state, TDA10046H_CONF_TRISTATE1, 1, 0);                dvb_delay(10);                // set parameters                tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL2, 10);                tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL3, 0);                tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_OFFSET, 99);                tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_MSB, 0xd4);                tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_LSB, 0x2c);                tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST                break;        }	// do the firmware upload        tda1004x_write_byte(i2c, tda_state, dspCodeCounterReg, 0); // clear code counter        fw_msg.addr = tda_state->tda1004x_address;	fw_pos = 0;	while (fw_pos != fw_size) {		// work out how much to send this time		tx_size = fw_size - fw_pos;                if (tx_size > 0x10) {                        tx_size = 0x10;		}		// send the chunk                fw_buf[0] = dspCodeInReg;		memcpy(fw_buf + 1, firmware + fw_pos, tx_size);		fw_msg.len = tx_size + 1;		if (i2c->xfer(i2c, &fw_msg, 1) != 1) {                        printk("tda1004x: Error during firmware upload\n");			vfree(firmware);			return -EIO;		}		fw_pos += tx_size;		dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, fw_pos);	}	vfree(firmware);        // wait for DSP to initialise        switch(tda_state->fe_type) {        case FE_TYPE_TDA10045H:                // DSPREADY doesn't seem to work on the TDA10045H                dvb_delay(100);                break;        case FE_TYPE_TDA10046H:                timeout = jiffies + HZ;                while(!(tda1004x_read_byte(i2c, tda_state, TDA1004X_STATUS_CD) & 0x20)) {                        if (time_after(jiffies, timeout)) {                                printk("tda1004x: DSP failed to initialised.\n");                                return -EIO;                        }                        dvb_delay(1);                }                break;        }        // check upload was OK        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP	tda1004x_write_byte(i2c, tda_state, TDA1004X_DSP_CMD, 0x67);	if ((tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA1) != 0x67) ||            (tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA2) != dspVersion)) {		printk("%s: firmware upload failed!\n", __FUNCTION__);		return -EIO;	}        // success        return 0;}static int tda10045h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state){        struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = NULL,.len = 0 };        static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };        dprintk("%s\n", __FUNCTION__);	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC        // Disable the MC44BC374C        tda1004x_enable_tuner_i2c(i2c, tda_state);        tuner_msg.addr = MC44BC374_ADDRESS;        tuner_msg.buf = disable_mc44BC374c;        tuner_msg.len = sizeof(disable_mc44BC374c);        if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {                i2c->xfer(i2c, &tuner_msg, 1);        }        tda1004x_disable_tuner_i2c(i2c, tda_state);	// tda setup        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 8, 0); // select HP stream        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x40, 0); // no frequency inversion        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset        tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface        tda1004x_write_mask(i2c, tda_state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONFADC1, 0x2e);	// done	return 0;}static int tda10046h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state){        struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = NULL,.len = 0 };        static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };        dprintk("%s\n", __FUNCTION__);	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 1, 0); // wake up the chip        // Disable the MC44BC374C        tda1004x_enable_tuner_i2c(i2c, tda_state);        tuner_msg.addr = MC44BC374_ADDRESS;        tuner_msg.buf = disable_mc44BC374c;        tuner_msg.len = sizeof(disable_mc44BC374c);        if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {                i2c->xfer(i2c, &tuner_msg, 1);        }        tda1004x_disable_tuner_i2c(i2c, tda_state);        // tda setup        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x40, 0x40); // TT TDA10046H needs inversion ON        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 8, 0); // select HP stream        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer        tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL2, 10); // PLL M = 10        tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0        tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99        tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221        tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_CONF, 0); // AGC setup        tda1004x_write_mask(i2c, tda_state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_TUN_MIN, 0);    // }        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_IF_MIN, 0);     // }        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_IF_MAX, 0xff);  // }        tda1004x_write_mask(i2c, tda_state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config        tda1004x_write_mask(i2c, tda_state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN        tda1004x_write_byte(i2c, tda_state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup        tda1004x_write_byte(i2c, tda_state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config        tda1004x_write_mask(i2c, tda_state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select        tda10046h_set_bandwidth(i2c, tda_state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz        // done        return 0;}static int tda1004x_encode_fec(int fec){	// convert known FEC values	switch (fec) {	case FEC_1_2:		return 0;	case FEC_2_3:		return 1;	case FEC_3_4:		return 2;	case FEC_5_6:		return 3;	case FEC_7_8:		return 4;	}	// unsupported	return -EINVAL;}static int tda1004x_decode_fec(int tdafec){	// convert known FEC values	switch (tdafec) {	case 0:		return FEC_1_2;	case 1:		return FEC_2_3;	case 2:		return FEC_3_4;	case 3:		return FEC_5_6;	case 4:		return FEC_7_8;	}	// unsupported	return -1;}static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c,			   struct tda1004x_state *tda_state,			   struct dvb_frontend_parameters *fe_params){	u8 tuner_buf[4];	struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };        int tuner_frequency = 0;        u8 band, cp, filter;	int counter, counter2;	dprintk("%s\n", __FUNCTION__);	// setup the frequency buffer        switch (tda_state->tuner_type) {        case TUNER_TYPE_TD1344:		// setup tuner buffer                // ((Fif+((1000000/6)/2)) + Finput)/(1000000/6)		tuner_frequency =                        (((fe_params->frequency / 1000) * 6) + 217502) / 1000;		tuner_buf[0] = tuner_frequency >> 8;		tuner_buf[1] = tuner_frequency & 0xff;		tuner_buf[2] = 0x88;		if (fe_params->frequency < 550000000) {			tuner_buf[3] = 0xab;		} else {			tuner_buf[3] = 0xeb;		}		// tune it		tda1004x_enable_tuner_i2c(i2c, tda_state);		tuner_msg.addr = tda_state->tuner_address;		tuner_msg.len = 4;		i2c->xfer(i2c, &tuner_msg, 1);		// wait for it to finish		tuner_msg.len = 1;		tuner_msg.flags = I2C_M_RD;		counter = 0;		counter2 = 0;		while (counter++ < 100) {			if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {				if (tuner_buf[0] & 0x40) {					counter2++;				} else {					counter2 = 0;				}			}			if (counter2 > 10) {				break;			}		}		tda1004x_disable_tuner_i2c(i2c, tda_state);		break;        case TUNER_TYPE_TD1316:		// determine charge pump		tuner_frequency = fe_params->frequency + 36130000;		if (tuner_frequency < 87000000) {			return -EINVAL;		} else if (tuner_frequency < 130000000) {                        cp = 3;		} else if (tuner_frequency < 160000000) {			cp = 5;		} else if (tuner_frequency < 200000000) {			cp = 6;		} else if (tuner_frequency < 290000000) {			cp = 3;		} else if (tuner_frequency < 420000000) {			cp = 5;		} else if (tuner_frequency < 480000000) {			cp = 6;		} else if (tuner_frequency < 620000000) {			cp = 3;		} else if (tuner_frequency < 830000000) {			cp = 5;		} else if (tuner_frequency < 895000000) {			cp = 7;		} else {			return -EINVAL;		}		// determine band		if (fe_params->frequency < 49000000) {                        return -EINVAL;		} else if (fe_params->frequency < 159000000) {                        band = 1;		} else if (fe_params->frequency < 444000000) {			band = 2;		} else if (fe_params->frequency < 861000000) {			band = 4;		} else {			return -EINVAL;		}		// work out filter		switch (fe_params->u.ofdm.bandwidth) {		case BANDWIDTH_6_MHZ:                        filter = 0;                        break;                case BANDWIDTH_7_MHZ:			filter = 0;			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -