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

📄 dvb-ttusb-budget.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		numstuff++;}static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len){	int maxwork = 1024;	while (len) {		if (!(maxwork--)) {			printk("%s: too much work\n", __FUNCTION__);			break;		}		switch (ttusb->mux_state) {		case 0:		case 1:		case 2:			len--;			if (*data++ == 0xAA)				++ttusb->mux_state;			else {				ttusb->mux_state = 0;#if DEBUG > 3				if (ttusb->insync)					printk("%02x ", data[-1]);#else				if (ttusb->insync) {					printk("%s: lost sync.\n",					       __FUNCTION__);					ttusb->insync = 0;				}#endif			}			break;		case 3:			ttusb->insync = 1;			len--;			ttusb->mux_npacks = *data++;			++ttusb->mux_state;			ttusb->muxpack_ptr = 0;			/* maximum bytes, until we know the length */			ttusb->muxpack_len = 2;			break;		case 4:			{				int avail;				avail = len;				if (avail >				    (ttusb->muxpack_len -				     ttusb->muxpack_ptr))					avail =					    ttusb->muxpack_len -					    ttusb->muxpack_ptr;				memcpy(ttusb->muxpack + ttusb->muxpack_ptr,				       data, avail);				ttusb->muxpack_ptr += avail;				BUG_ON(ttusb->muxpack_ptr > 264);				data += avail;				len -= avail;				/* determine length */				if (ttusb->muxpack_ptr == 2) {					if (ttusb->muxpack[0] & 0x80) {						ttusb->muxpack_len =						    ttusb->muxpack[1] + 2;						if (ttusb->						    muxpack[0] & 0x20)							ttusb->							    muxpack_len++;						if ((!!						     (ttusb->						      muxpack[0] & 0x20)) ^						    !!(ttusb->						       muxpack[1] & 1))							ttusb->							    muxpack_len++;						ttusb->muxpack_len += 4;					} else if (ttusb->muxpack[0] ==						   0x47)						ttusb->muxpack_len =						    188 + 4;					else if (ttusb->muxpack[0] == 0x00)						ttusb->muxpack_len =						    ttusb->muxpack[1] + 2 +						    4;					else {						dprintk						    ("%s: invalid state: first byte is %x\n",						     __FUNCTION__,						     ttusb->muxpack[0]);						ttusb->mux_state = 0;					}				}			/**			 * if length is valid and we reached the end:			 * goto next muxpack			 */				if ((ttusb->muxpack_ptr >= 2) &&				    (ttusb->muxpack_ptr ==				     ttusb->muxpack_len)) {					ttusb_process_muxpack(ttusb,							      ttusb->							      muxpack,							      ttusb->							      muxpack_ptr);					ttusb->muxpack_ptr = 0;					/* maximum bytes, until we know the length */					ttusb->muxpack_len = 2;				/**				 * no muxpacks left?				 * return to search-sync state				 */					if (!ttusb->mux_npacks--) {						ttusb->mux_state = 0;						break;					}				}				break;			}		default:			BUG();			break;		}	}}static void ttusb_iso_irq(struct urb *urb){	struct ttusb *ttusb = urb->context;	if (!ttusb->iso_streaming)		return;#if 0	printk("%s: status %d, errcount == %d, length == %i\n",	       __FUNCTION__,	       urb->status, urb->error_count, urb->actual_length);#endif	if (!urb->status) {		int i;		for (i = 0; i < urb->number_of_packets; ++i) {			struct usb_iso_packet_descriptor *d;			u8 *data;			int len;			numpkt++;			if (time_after_eq(jiffies, lastj + HZ)) {#if DEBUG > 2				printk				    ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",				     numpkt * HZ / (jiffies - lastj),				     numts, numstuff, numsec, numinvalid,				     numts + numstuff + numsec +				     numinvalid);#endif				numts = numstuff = numsec = numinvalid = 0;				lastj = jiffies;				numpkt = 0;			}			d = &urb->iso_frame_desc[i];			data = urb->transfer_buffer + d->offset;			len = d->actual_length;			d->actual_length = 0;			d->status = 0;			ttusb_process_frame(ttusb, data, len);		}	}	usb_submit_urb(urb, GFP_ATOMIC);}static void ttusb_free_iso_urbs(struct ttusb *ttusb){	int i;	for (i = 0; i < ISO_BUF_COUNT; i++)		if (ttusb->iso_urb[i])			usb_free_urb(ttusb->iso_urb[i]);	pci_free_consistent(NULL,			    ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *			    ISO_BUF_COUNT, ttusb->iso_buffer,			    ttusb->iso_dma_handle);}static int ttusb_alloc_iso_urbs(struct ttusb *ttusb){	int i;	ttusb->iso_buffer = pci_alloc_consistent(NULL,						 ISO_FRAME_SIZE *						 FRAMES_PER_ISO_BUF *						 ISO_BUF_COUNT,						 &ttusb->iso_dma_handle);	memset(ttusb->iso_buffer, 0,	       ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);	for (i = 0; i < ISO_BUF_COUNT; i++) {		struct urb *urb;		if (!		    (urb =		     usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {			ttusb_free_iso_urbs(ttusb);			return -ENOMEM;		}		ttusb->iso_urb[i] = urb;	}	return 0;}static void ttusb_stop_iso_xfer(struct ttusb *ttusb){	int i;	for (i = 0; i < ISO_BUF_COUNT; i++)		usb_kill_urb(ttusb->iso_urb[i]);	ttusb->iso_streaming = 0;}static int ttusb_start_iso_xfer(struct ttusb *ttusb){	int i, j, err, buffer_offset = 0;	if (ttusb->iso_streaming) {		printk("%s: iso xfer already running!\n", __FUNCTION__);		return 0;	}	ttusb->cc = -1;	ttusb->insync = 0;	ttusb->mux_state = 0;	for (i = 0; i < ISO_BUF_COUNT; i++) {		int frame_offset = 0;		struct urb *urb = ttusb->iso_urb[i];		urb->dev = ttusb->dev;		urb->context = ttusb;		urb->complete = ttusb_iso_irq;		urb->pipe = ttusb->isoc_in_pipe;		urb->transfer_flags = URB_ISO_ASAP;		urb->interval = 1;		urb->number_of_packets = FRAMES_PER_ISO_BUF;		urb->transfer_buffer_length =		    ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;		urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;		buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;		for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {			urb->iso_frame_desc[j].offset = frame_offset;			urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;			frame_offset += ISO_FRAME_SIZE;		}	}	for (i = 0; i < ISO_BUF_COUNT; i++) {		if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {			ttusb_stop_iso_xfer(ttusb);			printk			    ("%s: failed urb submission (%i: err = %i)!\n",			     __FUNCTION__, i, err);			return err;		}	}	ttusb->iso_streaming = 1;	return 0;}#ifdef TTUSB_HWSECTIONSstatic void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,			  int len){	dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);}static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,			   int len){//      struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;#error TODO: handle ugly stuff//      dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);}#endifstatic int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed){	struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;	int feed_type = 1;	dprintk("ttusb_start_feed\n");	switch (dvbdmxfeed->type) {	case DMX_TYPE_TS:		break;	case DMX_TYPE_SEC:		break;	default:		return -EINVAL;	}	if (dvbdmxfeed->type == DMX_TYPE_TS) {		switch (dvbdmxfeed->pes_type) {		case DMX_TS_PES_VIDEO:		case DMX_TS_PES_AUDIO:		case DMX_TS_PES_TELETEXT:		case DMX_TS_PES_PCR:		case DMX_TS_PES_OTHER:			break;		default:			return -EINVAL;		}	}#ifdef TTUSB_HWSECTIONS#error TODO: allocate filters	if (dvbdmxfeed->type == DMX_TYPE_TS) {		feed_type = 1;	} else if (dvbdmxfeed->type == DMX_TYPE_SEC) {		feed_type = 2;	}#endif	ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);	if (0 == ttusb->running_feed_count++)		ttusb_start_iso_xfer(ttusb);	return 0;}static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed){	struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;	ttusb_del_channel(ttusb, dvbdmxfeed->index);	if (--ttusb->running_feed_count == 0)		ttusb_stop_iso_xfer(ttusb);	return 0;}static int ttusb_setup_interfaces(struct ttusb *ttusb){	usb_set_interface(ttusb->dev, 1, 1);	ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);	ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);	ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);	return 0;}#if 0static u8 stc_firmware[8192];static int stc_open(struct inode *inode, struct file *file){	struct ttusb *ttusb = file->private_data;	int addr;	for (addr = 0; addr < 8192; addr += 16) {		u8 snd_buf[2] = { addr >> 8, addr & 0xFF };		ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,			      16);	}	return 0;}static ssize_t stc_read(struct file *file, char *buf, size_t count,		 loff_t * offset){	int tc = count;	if ((tc + *offset) > 8192)		tc = 8192 - *offset;	if (tc < 0)		return 0;	if (copy_to_user(buf, stc_firmware + *offset, tc))		return -EFAULT;	*offset += tc;	return tc;}static int stc_release(struct inode *inode, struct file *file){	return 0;}static struct file_operations stc_fops = {	.owner = THIS_MODULE,	.read = stc_read,	.open = stc_open,	.release = stc_release,};#endifstatic u32 functionality(struct i2c_adapter *adapter){	return I2C_FUNC_I2C;}static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params){	struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;	u8 data[4];	struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };	u32 div;	div = (params->frequency + 36166667) / 166667;	data[0] = (div >> 8) & 0x7f;	data[1] = div & 0xff;	data[2] = ((div >> 10) & 0x60) | 0x85;	data[3] = params->frequency < 592000000 ? 0x40 : 0x80;	if (fe->ops.i2c_gate_ctrl)		fe->ops.i2c_gate_ctrl(fe, 1);	if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;	return 0;}static struct cx22700_config alps_tdmb7_config = {	.demod_address = 0x43,};static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe){	struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;	static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };	static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };	struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };	// setup PLL configuration	if (fe->ops.i2c_gate_ctrl)		fe->ops.i2c_gate_ctrl(fe, 1);	if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;	msleep(1);	// disable the mc44BC374c (do not check for errors)	tuner_msg.addr = 0x65;	tuner_msg.buf = disable_mc44BC374c;	tuner_msg.len = sizeof(disable_mc44BC374c);	if (fe->ops.i2c_gate_ctrl)		fe->ops.i2c_gate_ctrl(fe, 1);	if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {		i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);	}	return 0;}static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params){	struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;	u8 tuner_buf[4];	struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };	int tuner_frequency = 0;	u8 band, cp, filter;	// determine charge pump	tuner_frequency = 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 (params->frequency < 49000000) return -EINVAL;	else if (params->frequency < 159000000) band = 1;	else if (params->frequency < 444000000) band = 2;	else if (params->frequency < 861000000) band = 4;	else return -EINVAL;	// setup PLL filter	switch (params->u.ofdm.bandwidth) {	case BANDWIDTH_6_MHZ:		tda1004x_writereg(fe, 0x0C, 0);		filter = 0;		break;	case BANDWIDTH_7_MHZ:		tda1004x_writereg(fe, 0x0C, 0);		filter = 0;		break;	case BANDWIDTH_8_MHZ:		tda1004x_writereg(fe, 0x0C, 0xFF);		filter = 1;		break;	default:		return -EINVAL;	}	// calculate divisor	// ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)	tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;	// setup tuner buffer	tuner_buf[0] = tuner_frequency >> 8;	tuner_buf[1] = tuner_frequency & 0xff;	tuner_buf[2] = 0xca;	tuner_buf[3] = (cp << 5) | (filter << 3) | band;	if (fe->ops.i2c_gate_ctrl)		fe->ops.i2c_gate_ctrl(fe, 1);	if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)		return -EIO;	msleep(1);	return 0;}static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name){	struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;	return request_firmware(fw, name, &ttusb->dev->dev);}static struct tda1004x_config philips_tdm1316l_config = {	.demod_address = 0x8,	.invert = 1,	.invert_oclk = 0,	.request_firmware = philips_tdm1316l_request_firmware,};static u8 alps_bsbe1_inittab[] = {	0x01, 0x15,	0x02, 0x30,	0x03, 0x00,	0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */	0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */	0x06, 0x40,             /* DAC not used, set to high impendance mode */	0x07, 0x00,             /* DAC LSB */	0x08, 0x40,             /* DiSEqC off, LNB power on OP2/LOCK pin on */	0x09, 0x00,             /* FIFO */	0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */	0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */	0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */	0x10, 0x3f,             // AGC2  0x3d	0x11, 0x84,	0x12, 0xb9,	0x15, 0xc9,             // lock detector threshold	0x16, 0x00,	0x17, 0x00,	0x18, 0x00,	0x19, 0x00,	0x1a, 0x00,	0x1f, 0x50,	0x20, 0x00,	0x21, 0x00,	0x22, 0x00,	0x23, 0x00,	0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0	0x29, 0x1e,             // 1/2 threshold	0x2a, 0x14,             // 2/3 threshold	0x2b, 0x0f,             // 3/4 threshold	0x2c, 0x09,             // 5/6 threshold	0x2d, 0x05,             // 7/8 threshold	0x2e, 0x01,	0x31, 0x1f,             // test all FECs	0x32, 0x19,             // viterbi and synchro search	0x33, 0xfc,             // rs control	0x34, 0x93,             // error control	0x0f, 0x92,	0xff, 0xff};static u8 alps_bsru6_inittab[] = {	0x01, 0x15,	0x02, 0x30,	0x03, 0x00,	0x04, 0x7d,		/* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */	0x05, 0x35,		/* I2CT = 0, SCLT = 1, SDAT = 1 */	0x06, 0x40,		/* DAC not used, set to high impendance mode */	0x07, 0x00,		/* DAC LSB */	0x08, 0x40,		/* DiSEqC off, LNB power on OP2/LOCK pin on */	0x09, 0x00,		/* FIFO */	0x0c, 0x51,		/* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */	0x0d, 0x82,		/* DC offset compensation = ON, beta_agc1 = 2 */

⌨️ 快捷键说明

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