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

📄 ttusb_dec.c

📁 linux_dvb的驱动程序:linuxtv-dvb-1.1.1.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
		b[j + 0] = 0xaa;		b[j + 1] = trans_count++;		b[j + 2] = 0xf0;		b[j + 3] = size;		memcpy(&b[j + 4], &firmware[i], size);		j += COMMAND_PACKET_SIZE + 4;		if (j >= ARM_PACKET_SIZE) {			result = usb_bulk_msg(dec->udev, dec->command_pipe, b,					      ARM_PACKET_SIZE, &actual_len,					      HZ / 10);			j = 0;		} else if (size < COMMAND_PACKET_SIZE) {			result = usb_bulk_msg(dec->udev, dec->command_pipe, b,					      j - COMMAND_PACKET_SIZE + size,					      &actual_len, HZ / 10);		}	}	result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);	kfree(b);	return result;}static int ttusb_dec_init_stb(struct ttusb_dec *dec){	int result;	unsigned int mode, model, version;	dprintk("%s\n", __FUNCTION__);	result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);	if (!result) {		if (!mode) {			if (version == 0xABCDEFAB)				printk(KERN_INFO "ttusb_dec: no version "				       "info in Firmware\n");			else				printk(KERN_INFO "ttusb_dec: Firmware "				       "%x.%02x%c%c\n",				       version >> 24, (version >> 16) & 0xff,				       (version >> 8) & 0xff, version & 0xff);			result = ttusb_dec_boot_dsp(dec);			if (result)				return result;			else				return 1;		} else {			/* We can't trust the USB IDs that some firmwares			   give the box */			switch (model) {			case 0x00070008:			case 0x0007000c:				ttusb_dec_set_model(dec, TTUSB_DEC3000S);				break;			case 0x00070009:				ttusb_dec_set_model(dec, TTUSB_DEC2000T);				break;			case 0x00070011:				ttusb_dec_set_model(dec, TTUSB_DEC2540T);				break;			default:				printk(KERN_ERR "%s: unknown model returned "				       "by firmware (%08x) - please report\n",				       __FUNCTION__, model);				return -1;				break;			}			if (version >= 0x01770000)				dec->can_playback = 1;			return 0;		}	}	else		return result;}static int ttusb_dec_init_dvb(struct ttusb_dec *dec){	int result;	dprintk("%s\n", __FUNCTION__);	if ((result = dvb_register_adapter(&dec->adapter,					   dec->model_name)) < 0) {		printk("%s: dvb_register_adapter failed: error %d\n",		       __FUNCTION__, result);		return result;	}	dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;	dec->demux.priv = (void *)dec;	dec->demux.filternum = 31;	dec->demux.feednum = 31;	dec->demux.start_feed = ttusb_dec_start_feed;	dec->demux.stop_feed = ttusb_dec_stop_feed;	dec->demux.write_to_decoder = NULL;	if ((result = dvb_dmx_init(&dec->demux)) < 0) {		printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,		       result);		dvb_unregister_adapter(dec->adapter);		return result;	}	dec->dmxdev.filternum = 32;	dec->dmxdev.demux = &dec->demux.dmx;	dec->dmxdev.capabilities = 0;	if ((result = dvb_dmxdev_init(&dec->dmxdev, dec->adapter)) < 0) {		printk("%s: dvb_dmxdev_init failed: error %d\n",		       __FUNCTION__, result);		dvb_dmx_release(&dec->demux);		dvb_unregister_adapter(dec->adapter);		return result;	}	dec->frontend.source = DMX_FRONTEND_0;	if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,						  &dec->frontend)) < 0) {		printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,		       result);		dvb_dmxdev_release(&dec->dmxdev);		dvb_dmx_release(&dec->demux);		dvb_unregister_adapter(dec->adapter);		return result;	}	if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,						      &dec->frontend)) < 0) {		printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,		       result);		dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);		dvb_dmxdev_release(&dec->dmxdev);		dvb_dmx_release(&dec->demux);		dvb_unregister_adapter(dec->adapter);		return result;	}	dvb_net_init(dec->adapter, &dec->dvb_net, &dec->demux.dmx);	return 0;}static void ttusb_dec_exit_dvb(struct ttusb_dec *dec){	dprintk("%s\n", __FUNCTION__);	dvb_net_release(&dec->dvb_net);	dec->demux.dmx.close(&dec->demux.dmx);	dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);	dvb_dmxdev_release(&dec->dmxdev);	dvb_dmx_release(&dec->demux);	dvb_unregister_adapter(dec->adapter);}static void ttusb_dec_exit_usb(struct ttusb_dec *dec){	int i;	dprintk("%s\n", __FUNCTION__);	dec->iso_stream_count = 0;	for (i = 0; i < ISO_BUF_COUNT; i++)		usb_unlink_urb(dec->iso_urb[i]);	ttusb_dec_free_iso_urbs(dec);}static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec){	struct list_head *item;	struct urb_frame *frame;	tasklet_kill(&dec->urb_tasklet);	while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {		frame = list_entry(item, struct urb_frame, urb_frame_list);		list_del(&frame->urb_frame_list);		kfree(frame);	}}static int ttusb_dec_2000t_frontend_ioctl(struct dvb_frontend *fe, unsigned int cmd,				  void *arg){	struct ttusb_dec *dec = fe->data;	dprintk("%s\n", __FUNCTION__);	switch (cmd) {	case FE_GET_INFO:		dprintk("%s: FE_GET_INFO\n", __FUNCTION__);		memcpy(arg, dec->frontend_info,		       sizeof (struct dvb_frontend_info));		break;	case FE_READ_STATUS: {		fe_status_t *status = (fe_status_t *)arg;		dprintk("%s: FE_READ_STATUS\n", __FUNCTION__);		*status = FE_HAS_SIGNAL | FE_HAS_VITERBI |			  FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;		break;	}	case FE_READ_BER: {		u32 *ber = (u32 *)arg;		dprintk("%s: FE_READ_BER\n", __FUNCTION__);		*ber = 0;		return -ENOSYS;		break;	}	case FE_READ_SIGNAL_STRENGTH: {		dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__);		*(s32 *)arg = 0xFF;		return -ENOSYS;		break;	}	case FE_READ_SNR:		dprintk("%s: FE_READ_SNR\n", __FUNCTION__);		*(s32 *)arg = 0;		return -ENOSYS;		break;	case FE_READ_UNCORRECTED_BLOCKS:		dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__);		*(u32 *)arg = 0;		return -ENOSYS;		break;	case FE_SET_FRONTEND: {		struct dvb_frontend_parameters *p =			(struct dvb_frontend_parameters *)arg;		u8 b[] = { 0x00, 0x00, 0x00, 0x03,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x01,			   0x00, 0x00, 0x00, 0xff,			   0x00, 0x00, 0x00, 0xff };		u32 freq;		dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__);		dprintk("            frequency->%d\n", p->frequency);		dprintk("            symbol_rate->%d\n",			p->u.qam.symbol_rate);		dprintk("            inversion->%d\n", p->inversion);		freq = htonl(p->frequency / 1000);		memcpy(&b[4], &freq, sizeof (u32));		ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL);		break;	}	case FE_GET_FRONTEND:		dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__);		break;	case FE_SLEEP:		dprintk("%s: FE_SLEEP\n", __FUNCTION__);		return -ENOSYS;		break;	case FE_INIT:		dprintk("%s: FE_INIT\n", __FUNCTION__);		break;	case FE_RESET:		dprintk("%s: FE_RESET\n", __FUNCTION__);		break;	default:		dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd);		return -EINVAL;	}	return 0;}static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,					  unsigned int cmd, void *arg){	struct ttusb_dec *dec = fe->data;	dprintk("%s\n", __FUNCTION__);	switch (cmd) {	case FE_GET_INFO:		dprintk("%s: FE_GET_INFO\n", __FUNCTION__);		memcpy(arg, dec->frontend_info,		       sizeof (struct dvb_frontend_info));		break;	case FE_READ_STATUS: {		fe_status_t *status = (fe_status_t *)arg;		dprintk("%s: FE_READ_STATUS\n", __FUNCTION__);		*status = FE_HAS_SIGNAL | FE_HAS_VITERBI |			  FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;		break;	}	case FE_READ_BER: {		u32 *ber = (u32 *)arg;		dprintk("%s: FE_READ_BER\n", __FUNCTION__);		*ber = 0;		return -ENOSYS;		break;	}	case FE_READ_SIGNAL_STRENGTH: {		dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__);		*(s32 *)arg = 0xFF;		return -ENOSYS;		break;	}	case FE_READ_SNR:		dprintk("%s: FE_READ_SNR\n", __FUNCTION__);		*(s32 *)arg = 0;		return -ENOSYS;		break;	case FE_READ_UNCORRECTED_BLOCKS:		dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__);		*(u32 *)arg = 0;		return -ENOSYS;		break;	case FE_SET_FRONTEND: {		struct dvb_frontend_parameters *p =			(struct dvb_frontend_parameters *)arg;		u8 b[] = { 0x00, 0x00, 0x00, 0x01,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x01,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x00,			   0x00, 0x00, 0x00, 0x00 };		u32 freq;		u32 sym_rate;		u32 band;		u32 lnb_voltage;		dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__);		dprintk("            frequency->%d\n", p->frequency);		dprintk("            symbol_rate->%d\n",			p->u.qam.symbol_rate);		dprintk("            inversion->%d\n", p->inversion);		freq = htonl(p->frequency * 1000 +		       (dec->hi_band ? LOF_HI : LOF_LO));		memcpy(&b[4], &freq, sizeof(u32));		sym_rate = htonl(p->u.qam.symbol_rate);		memcpy(&b[12], &sym_rate, sizeof(u32));		band = htonl(dec->hi_band ? LOF_HI : LOF_LO);		memcpy(&b[24], &band, sizeof(u32));		lnb_voltage = htonl(dec->voltage);		memcpy(&b[28], &lnb_voltage, sizeof(u32));		ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL);		break;	}	case FE_GET_FRONTEND:		dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__);		break;	case FE_SLEEP:		dprintk("%s: FE_SLEEP\n", __FUNCTION__);		return -ENOSYS;		break;	case FE_INIT:		dprintk("%s: FE_INIT\n", __FUNCTION__);		break;	case FE_RESET:		dprintk("%s: FE_RESET\n", __FUNCTION__);		break;	case FE_DISEQC_SEND_MASTER_CMD:		dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__);		break;	case FE_DISEQC_SEND_BURST:		dprintk("%s: FE_DISEQC_SEND_BURST\n", __FUNCTION__);		break;	case FE_SET_TONE: {		fe_sec_tone_mode_t tone = (fe_sec_tone_mode_t)arg;		dprintk("%s: FE_SET_TONE\n", __FUNCTION__);		dec->hi_band = (SEC_TONE_ON == tone);		break;	}	case FE_SET_VOLTAGE:		dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);		switch ((fe_sec_voltage_t) arg) {		case SEC_VOLTAGE_13:			dec->voltage = 13;			break;		case SEC_VOLTAGE_18:			dec->voltage = 18;			break;		default:			return -EINVAL;			break;		}		break;	default:		dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd);		return -EINVAL;	}	return 0;}static void ttusb_dec_init_frontend(struct ttusb_dec *dec){	dec->i2c_bus.adapter = dec->adapter;	dvb_register_frontend(dec->frontend_ioctl, &dec->i2c_bus, (void *)dec,			      dec->frontend_info);}static void ttusb_dec_exit_frontend(struct ttusb_dec *dec){	dvb_unregister_frontend(dec->frontend_ioctl, &dec->i2c_bus);}static void ttusb_dec_init_filters(struct ttusb_dec *dec){	INIT_LIST_HEAD(&dec->filter_info_list);	dec->filter_info_list_lock = SPIN_LOCK_UNLOCKED;}static void ttusb_dec_exit_filters(struct ttusb_dec *dec){	struct list_head *item;	struct filter_info *finfo;	while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {		finfo = list_entry(item, struct filter_info, filter_info_list);		list_del(&finfo->filter_info_list);		kfree(finfo);	}}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static void *ttusb_dec_probe(struct usb_device *udev, unsigned int ifnum,			     const struct usb_device_id *id){	struct ttusb_dec *dec;	dprintk("%s\n", __FUNCTION__);	if (ifnum != 0)		return NULL;	if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {		printk("%s: couldn't allocate memory.\n", __FUNCTION__);		return NULL;	}#elsestatic int ttusb_dec_probe(struct usb_interface *intf,			   const struct usb_device_id *id){	struct usb_device *udev;	struct ttusb_dec *dec;	dprintk("%s\n", __FUNCTION__);	udev = interface_to_usbdev(intf);	if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {		printk("%s: couldn't allocate memory.\n", __FUNCTION__);		return -ENOMEM;	}	usb_set_intfdata(intf, (void *)dec);#endif	memset(dec, 0, sizeof(struct ttusb_dec));	switch (id->idProduct) {	case 0x1006:		ttusb_dec_set_model(dec, TTUSB_DEC3000S);		break;	case 0x1008:		ttusb_dec_set_model(dec, TTUSB_DEC2000T);		break;	case 0x1009:		ttusb_dec_set_model(dec, TTUSB_DEC2540T);		break;	}	dec->udev = udev;	ttusb_dec_init_usb(dec);	if (ttusb_dec_init_stb(dec)) {		ttusb_dec_exit_usb(dec);		return 0;	}	ttusb_dec_init_dvb(dec);	ttusb_dec_init_frontend(dec);	ttusb_dec_init_v_pes(dec);	ttusb_dec_init_filters(dec);	ttusb_dec_init_tasklet(dec);	dec->active = 1;	ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	return (void *)dec;#else	return 0;#endif}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static void ttusb_dec_disconnect(struct usb_device *udev, void *data){	struct ttusb_dec *dec = data;#elsestatic void ttusb_dec_disconnect(struct usb_interface *intf){	struct ttusb_dec *dec = usb_get_intfdata(intf);	usb_set_intfdata(intf, NULL);#endif	dprintk("%s\n", __FUNCTION__);	if (dec->active) {		ttusb_dec_exit_tasklet(dec);		ttusb_dec_exit_filters(dec);		ttusb_dec_exit_usb(dec);		ttusb_dec_exit_frontend(dec);		ttusb_dec_exit_dvb(dec);	}	kfree(dec);}static void ttusb_dec_set_model(struct ttusb_dec *dec,				enum ttusb_dec_model model){	dec->model = model;	switch (model) {	case TTUSB_DEC2000T:		dec->model_name = "DEC2000-t";		dec->firmware_name = "dvb-ttusb-dec-2000t.fw";		dec->frontend_info = &dec2000t_frontend_info;		dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl;		break;	case TTUSB_DEC2540T:		dec->model_name = "DEC2540-t";		dec->firmware_name = "dvb-ttusb-dec-2540t.fw";		dec->frontend_info = &dec2000t_frontend_info;		dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl;		break;	case TTUSB_DEC3000S:		dec->model_name = "DEC3000-s";		dec->firmware_name = "dvb-ttusb-dec-3000s.fw";		dec->frontend_info = &dec3000s_frontend_info;		dec->frontend_ioctl = ttusb_dec_3000s_frontend_ioctl;		break;	}}static struct usb_device_id ttusb_dec_table[] = {	{USB_DEVICE(0x0b48, 0x1006)},	/* DEC3000-s */	/*{USB_DEVICE(0x0b48, 0x1007)},	   Unconfirmed */	{USB_DEVICE(0x0b48, 0x1008)},	/* DEC2000-t */	{USB_DEVICE(0x0b48, 0x1009)},	/* DEC2540-t */	{}};static struct usb_driver ttusb_dec_driver = {	.name		= "ttusb-dec",	.probe		= ttusb_dec_probe,	.disconnect	= ttusb_dec_disconnect,	.id_table	= ttusb_dec_table,};static int __init ttusb_dec_init(void){	int result;	if ((result = usb_register(&ttusb_dec_driver)) < 0) {		printk("%s: initialisation failed: error %d.\n", __FUNCTION__,		       result);		return result;	}	return 0;}static void __exit ttusb_dec_exit(void){	usb_deregister(&ttusb_dec_driver);}module_init(ttusb_dec_init);module_exit(ttusb_dec_exit);MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");MODULE_DESCRIPTION(DRIVER_NAME);MODULE_LICENSE("GPL");MODULE_DEVICE_TABLE(usb, ttusb_dec_table);MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debug level");MODULE_PARM(output_pva, "i");MODULE_PARM_DESC(output_pva, "Output PVA from dvr device");

⌨️ 快捷键说明

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