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

📄 tda1004x.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                if (vber == -1) return -EIO;                status = tda1004x_read_byte(i2c, tda_state, TDA1004X_VBER_MID);                if (status == -1) return -EIO;                vber |= (status << 8);                status = tda1004x_read_byte(i2c, tda_state, TDA1004X_VBER_MSB);                if (status == -1) return -EIO;                vber |= ((status << 16) & 0x0f);                tda1004x_read_byte(i2c, tda_state, TDA1004X_CVBER_LUT);                // if RS has passed some valid TS packets, then we must be                // getting some SYNC bytes                if (vber < 16632) {                        *fe_status |= FE_HAS_SYNC;                }        }	// success	dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);	return 0;}static int tda1004x_read_signal_strength(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u16 * signal){	int tmp;        int reg = 0;	dprintk("%s\n", __FUNCTION__);        // determine the register to use        switch(tda_state->fe_type) {        case FE_TYPE_TDA10045H:                reg = TDA10045H_S_AGC;                break;        case FE_TYPE_TDA10046H:                reg = TDA10046H_AGC_IF_LEVEL;                break;        }	// read it        tmp = tda1004x_read_byte(i2c, tda_state, reg);	if (tmp < 0)		return -EIO;	// done	*signal = (tmp << 8) | tmp;	dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);	return 0;}static int tda1004x_read_snr(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u16 * snr){	int tmp;	dprintk("%s\n", __FUNCTION__);	// read it	tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_SNR);	if (tmp < 0)		return -EIO;        if (tmp) {                tmp = 255 - tmp;        }        // done	*snr = ((tmp << 8) | tmp);	dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);	return 0;}static int tda1004x_read_ucblocks(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u32* ucblocks){	int tmp;	int tmp2;	int counter;	dprintk("%s\n", __FUNCTION__);	// read the UCBLOCKS and reset	counter = 0;	tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_UNCOR);	if (tmp < 0)		return -EIO;        tmp &= 0x7f;	while (counter++ < 5) {		tda1004x_write_mask(i2c, tda_state, TDA1004X_UNCOR, 0x80, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_UNCOR, 0x80, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_UNCOR, 0x80, 0);		tmp2 = tda1004x_read_byte(i2c, tda_state, TDA1004X_UNCOR);		if (tmp2 < 0)			return -EIO;		tmp2 &= 0x7f;		if ((tmp2 < tmp) || (tmp2 == 0))			break;	}	// done	if (tmp != 0x7f) {		*ucblocks = tmp;	} else {		*ucblocks = 0xffffffff;	}	dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);	return 0;}static int tda1004x_read_ber(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u32* ber){        int tmp;	dprintk("%s\n", __FUNCTION__);	// read it in        tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_LSB);        if (tmp < 0) return -EIO;        *ber = tmp << 1;        tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_MSB);        if (tmp < 0) return -EIO;        *ber |= (tmp << 9);        tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_RESET);	// done	dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);	return 0;}static int tda1004x_sleep(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state){	switch(tda_state->fe_type) {	case FE_TYPE_TDA10045H:		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFADC1, 0x10, 0x10);		break;	case FE_TYPE_TDA10046H:		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 1, 1);		break;	}	return 0;}static int tda1004x_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg){	int status = 0;	struct dvb_i2c_bus *i2c = fe->i2c;	struct tda1004x_state *tda_state = (struct tda1004x_state *) fe->data;	dprintk("%s: cmd=0x%x\n", __FUNCTION__, cmd);	switch (cmd) {	case FE_GET_INFO:                switch(tda_state->fe_type) {                case FE_TYPE_TDA10045H:        		memcpy(arg, &tda10045h_info, sizeof(struct dvb_frontend_info));                        break;                case FE_TYPE_TDA10046H:                        memcpy(arg, &tda10046h_info, sizeof(struct dvb_frontend_info));                        break;                }		break;	case FE_READ_STATUS:		return tda1004x_read_status(i2c, tda_state, (fe_status_t *) arg);	case FE_READ_BER:		return tda1004x_read_ber(i2c, tda_state, (u32 *) arg);	case FE_READ_SIGNAL_STRENGTH:		return tda1004x_read_signal_strength(i2c, tda_state, (u16 *) arg);	case FE_READ_SNR:		return tda1004x_read_snr(i2c, tda_state, (u16 *) arg);	case FE_READ_UNCORRECTED_BLOCKS:		return tda1004x_read_ucblocks(i2c, tda_state, (u32 *) arg);	case FE_SET_FRONTEND:		return tda1004x_set_fe(i2c, tda_state, (struct dvb_frontend_parameters*) arg);	case FE_GET_FRONTEND:		return tda1004x_get_fe(i2c, tda_state, (struct dvb_frontend_parameters*) arg);	case FE_SLEEP:		tda_state->initialised = 0;		return tda1004x_sleep(i2c, tda_state);	case FE_INIT:		// don't bother reinitialising		if (tda_state->initialised)			return 0;		// OK, perform initialisation                switch(tda_state->fe_type) {                case FE_TYPE_TDA10045H:                        status = tda10045h_init(i2c, tda_state);                        break;                case FE_TYPE_TDA10046H:                        status = tda10046h_init(i2c, tda_state);                        break;                }		if (status == 0)			tda_state->initialised = 1;		return status;	case FE_GET_TUNE_SETTINGS:	{		struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg;		fesettings->min_delay_ms = 800;		fesettings->step_size = 166667;		fesettings->max_drift = 166667*2;		return 0;	}	    	default:		return -EOPNOTSUPP;	}	return 0;}static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data){        int tda1004x_address = -1;	int tuner_address = -1;        int fe_type = -1;        int tuner_type = -1;	struct tda1004x_state tda_state;	struct tda1004x_state* ptda_state;	struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=NULL, .len=0 };        static u8 td1344_init[] = { 0x0b, 0xf5, 0x88, 0xab };        static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };        static u8 td1316_init_tda10046h[] = { 0x0b, 0xf5, 0x80, 0xab };        int status;	dprintk("%s\n", __FUNCTION__);        // probe for tda10045h        if (tda1004x_address == -1) {                tda_state.tda1004x_address = 0x08;	if (tda1004x_read_byte(i2c, &tda_state, TDA1004X_CHIPID) == 0x25) {                        tda1004x_address = 0x08;                        fe_type = FE_TYPE_TDA10045H;                printk("tda1004x: Detected Philips TDA10045H.\n");        }        }        // probe for tda10046h        if (tda1004x_address == -1) {                tda_state.tda1004x_address = 0x08;                if (tda1004x_read_byte(i2c, &tda_state, TDA1004X_CHIPID) == 0x46) {                        tda1004x_address = 0x08;                        fe_type = FE_TYPE_TDA10046H;                        printk("tda1004x: Detected Philips TDA10046H.\n");                }        }        // did we find a frontend?        if (tda1004x_address == -1) {		return -ENODEV;        }        // enable access to the tuner	tda1004x_enable_tuner_i2c(i2c, &tda_state);        // check for a TD1344 first        if (tuner_address == -1) {                tuner_msg.addr = 0x61;	tuner_msg.buf = td1344_init;	tuner_msg.len = sizeof(td1344_init);	if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {                dvb_delay(1);                        tuner_address = 0x61;                        tuner_type = TUNER_TYPE_TD1344;                        printk("tda1004x: Detected Philips TD1344 tuner.\n");                }        }        // OK, try a TD1316 on address 0x63        if (tuner_address == -1) {                tuner_msg.addr = 0x63;                tuner_msg.buf = td1316_init;                tuner_msg.len = sizeof(td1316_init);                if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {                        dvb_delay(1);                        tuner_address = 0x63;                        tuner_type = TUNER_TYPE_TD1316;                        printk("tda1004x: Detected Philips TD1316 tuner.\n");                }        }        // OK, TD1316 again, on address 0x60 (TDA10046H)        if (tuner_address == -1) {                tuner_msg.addr = 0x60;                tuner_msg.buf = td1316_init_tda10046h;                tuner_msg.len = sizeof(td1316_init_tda10046h);                if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {                        dvb_delay(1);                        tuner_address = 0x60;                        tuner_type = TUNER_TYPE_TD1316;                        printk("tda1004x: Detected Philips TD1316 tuner.\n");		}	}	tda1004x_disable_tuner_i2c(i2c, &tda_state);	// did we find a tuner?	if (tuner_address == -1) {		printk("tda1004x: Detected, but with unknown tuner.\n");		return -ENODEV;	}        // create state        tda_state.tda1004x_address = tda1004x_address;        tda_state.fe_type = fe_type;	tda_state.tuner_address = tuner_address;        tda_state.tuner_type = tuner_type;	tda_state.initialised = 0;        // upload firmware        if ((status = tda1004x_fwupload(i2c, &tda_state)) != 0) return status;	// create the real state we'll be passing about	if ((ptda_state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL)) == NULL) {		return -ENOMEM;	}	memcpy(ptda_state, &tda_state, sizeof(struct tda1004x_state));	*data = ptda_state;	// register        switch(tda_state.fe_type) {        case FE_TYPE_TDA10045H:		return dvb_register_frontend(tda1004x_ioctl, i2c, ptda_state, &tda10045h_info);        case FE_TYPE_TDA10046H:		return dvb_register_frontend(tda1004x_ioctl, i2c, ptda_state, &tda10046h_info);        }        // should not get here        return -EINVAL;}staticvoid tda1004x_detach(struct dvb_i2c_bus *i2c, void *data){	dprintk("%s\n", __FUNCTION__);	kfree(data);	dvb_unregister_frontend(tda1004x_ioctl, i2c);}staticint __init init_tda1004x(void){	return dvb_register_i2c_device(THIS_MODULE, tda1004x_attach, tda1004x_detach);}staticvoid __exit exit_tda1004x(void){	dvb_unregister_i2c_device(tda1004x_attach);}module_init(init_tda1004x);module_exit(exit_tda1004x);MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Frontend");MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");MODULE_LICENSE("GPL");MODULE_PARM(tda1004x_debug, "i");MODULE_PARM_DESC(tda1004x_debug, "enable verbose debug messages");MODULE_PARM(tda1004x_firmware, "s");MODULE_PARM_DESC(tda1004x_firmware, "Where to find the firmware file");

⌨️ 快捷键说明

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