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

📄 dvb_frontend.c

📁 dvb的系统程序。基于lunix系统.经过改进更新
💻 C
📖 第 1 页 / 共 3 页
字号:
	default:	        printk("Unknown frontend type %i\n", fe->info->type);	        return 0;	}        // are we using autoinversion?        autoinversion = ((!(fe->info->caps & FE_CAN_INVERSION_AUTO)) && (fe->parameters.inversion == INVERSION_AUTO));        // setup parameters correctly        while(!ready) {	        // wrap the count if we've reached the maximum drift	        fe->lnb_drift = (fe->auto_count / 4) * stepsize;	        if (fe->lnb_drift >= maxdrift) {		        fe->auto_count = 0;		        fe->lnb_drift = 0;		        wrapped = 1;		}    	        // perform inversion and +/- zigzag	        switch(fe->auto_count % 4) {		case 0:		        fe->inversion = INVERSION_OFF;		        ready = 1;		        break;	    		case 1:		        if (!autoinversion) break;		        fe->inversion = INVERSION_ON;		        ready = 1;		        break;	    		case 2:		        if (fe->lnb_drift == 0) break;		    		        fe->inversion = INVERSION_OFF;		        fe->lnb_drift = -fe->lnb_drift;		        ready = 1;		        break;	    		case 3:		        if (fe->lnb_drift == 0) break;		        if (!autoinversion) break;		    		        fe->inversion = INVERSION_ON;		        fe->lnb_drift = -fe->lnb_drift;		        ready = 1;		        break;		}	    	        if (!ready) fe->auto_count++;	}           // perform frequency bending if enabled        if (dvb_frequency_bending)                dvb_bend_frequency(fe, 0);           // set the frontend itself	fe->parameters.frequency += fe->lnb_drift + fe->bending;        if (autoinversion) fe->parameters.inversion = fe->inversion;	dvb_frontend_internal_ioctl (&fe->frontend, FE_SET_FRONTEND, &fe->parameters);	fe->parameters.frequency = original_frequency;        fe->parameters.inversion = original_inversion;            // reset frontend IRQ bits to clean error stats    	dvb_frontend_internal_ioctl (&fe->frontend, FE_RESET, NULL);        // if we've hit where we started from, indicate a complete iteration has occurred	fe->auto_count++;        if ((fe->auto_count == fe->started_auto_count) || (fe->started_auto_count==0 && wrapped)) return 1;        return 0;}static int dvb_frontend_is_exiting (struct dvb_frontend_data *fe){	if (fe->exit)		return 1;	if (fe->dvbdev->writers == 1)		if (jiffies - fe->release_jiffies > dvb_shutdown_timeout * HZ)			return 1;	return 0;}static int dvb_frontend_thread (void *data){	struct dvb_frontend_data *fe = (struct dvb_frontend_data *) data;	unsigned long timeout;	char name [15];	int quality = 0, delay = 3*HZ;        int clean_setup_count = 0;	fe_status_t s;	dprintk ("%s\n", __FUNCTION__);	snprintf (name, sizeof(name), "kdvb-fe-%i:%i",		  fe->frontend.i2c->adapter->num, fe->frontend.i2c->id);	dvb_kernel_thread_setup (name);	dvb_call_frontend_notifiers (fe, 0);	dvb_frontend_init (fe);	while (1) {		up (&fe->sem);      /* is locked when we enter the thread... */		timeout = wait_event_interruptible_timeout(fe->wait_queue,0 != dvb_frontend_is_exiting (fe), delay);		if (-ERESTARTSYS == timeout || 0 != dvb_frontend_is_exiting (fe)) {			/* got signal or quitting */			break;		}		if (down_interruptible (&fe->sem))			break;	        // if we've got no parameters, just keep idling		if (fe->state & FESTATE_IDLE) {		        delay = 3*HZ;		        quality = 0;		        continue;		}	    	        // get the frontend status		dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);		if (s != fe->status)			dvb_frontend_add_event (fe, s);	        // if we're not tuned, and we have a lock, move to the TUNED state		if ((fe->state & FESTATE_SEARCHING) && (s & FE_HAS_LOCK)) {		        update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);		        fe->state = FESTATE_TUNED;		    		        // if we're tuned, then we have determined the correct inversion		        if ((!(fe->info->caps & FE_CAN_INVERSION_AUTO)) && (fe->parameters.inversion == INVERSION_AUTO)) {			        fe->parameters.inversion = fe->inversion;			}		        continue;		}	    	        // if we are tuned already, check we're still locked	        if (fe->state & FESTATE_TUNED) {		        update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);		    		        // we're tuned, and the lock is still good...		        if (s & FE_HAS_LOCK) {			        continue;			} else {			        // if we _WERE_ tuned, but now don't have a lock, need to zigzag			        fe->state = FESTATE_ZIGZAG_FAST;			        fe->started_auto_count = fe->auto_count;			        // fallthrough			}		}	        // don't actually do anything if we're in the LOSTLOCK state		// and the frontend can recover automatically		if ((fe->state & FESTATE_LOSTLOCK) && (fe->info->caps & FE_CAN_RECOVER)) {		        update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);		        continue;		}	   	        // if we're in the RETUNE state, set everything up for a brand new scan	        if (fe->state & FESTATE_RETUNE) {		        fe->lnb_drift = 0;		        fe->inversion = INVERSION_OFF;		        fe->auto_count = 0;		        fe->started_auto_count = 0;		        clean_setup_count = 0;		}	    	        // fast zigzag.		if ((fe->state & FESTATE_SEARCHING_FAST) || (fe->state & FESTATE_RETUNE)) {		        delay = fe->min_delay;		   		        // OK, if we've run out of trials at the fast speed. Drop back to			// slow for the _next_ attempt		        if (dvb_frontend_autotune(fe)) {			        fe->state = FESTATE_SEARCHING_SLOW;			        fe->started_auto_count = fe->auto_count;			        continue;			}		        // enter clean setup state after the first tune if necessary. yeuch		        if ((!(fe->info->caps & FE_CAN_CLEAN_SETUP)) && (clean_setup_count == 0)) {			        fe->state = FESTATE_CLEAN_SETUP;			}		    		        // if we've just retuned, enter the ZIGZAG_FAST state. This ensures			// we cannot return from an FE_SET_FRONTEND before the retune occurs.			if (fe->state & FESTATE_RETUNE) {			        fe->state = FESTATE_TUNING_FAST;			}		}	        // slow zigzag		if (fe->state & FESTATE_SEARCHING_SLOW) {		        update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);		        dvb_frontend_autotune(fe);		}	        // clean setup		if (fe->state & FESTATE_CLEAN_SETUP) {		        if ((clean_setup_count < 10) && (!(s & FE_HAS_LOCK))) {			        dvb_frontend_internal_ioctl(&fe->frontend, FE_RESET, NULL);			} else {			        // return to tuning state			        fe->state = FESTATE_TUNING_FAST;			}		        clean_setup_count++;		}	};	if (dvb_shutdown_timeout)		dvb_frontend_internal_ioctl (&fe->frontend, FE_SLEEP, NULL); 	up (&fe->sem);	fe->thread_pid = 0;	mb();	wake_up_interruptible (&fe->wait_queue);	return 0;}static void dvb_frontend_stop (struct dvb_frontend_data *fe){ 	unsigned long ret;		dprintk ("%s\n", __FUNCTION__);	fe->exit = 1;	mb();	if (!fe->thread_pid)		return;	/* check if the thread is really alive */	if (kill_proc(fe->thread_pid, 0, 1) == -ESRCH) {		printk("dvb_frontend_stop: thread PID %d already died\n",				fe->thread_pid);		/* make sure the mutex was not held by the thread */		init_MUTEX (&fe->sem);		return;	}	/* wake up the frontend thread, so it notices that fe->exit == 1 */	wake_up_interruptible(&fe->wait_queue);	/* wait until the frontend thread has exited */	ret = wait_event_interruptible(fe->wait_queue,0 == fe->thread_pid);	if (-ERESTARTSYS != ret) {	        fe->state = FESTATE_IDLE;		return;	}        fe->state = FESTATE_IDLE;	/* paranoia check in case a signal arrived */	if (fe->thread_pid)		printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",				fe->thread_pid);}static int dvb_frontend_start (struct dvb_frontend_data *fe){	int ret;	dprintk ("%s\n", __FUNCTION__);	if (fe->thread_pid) {		if (!fe->exit)			return 0;		else			dvb_frontend_stop (fe);	}	if (signal_pending(current))		return -EINTR;	if (down_interruptible (&fe->sem))		return -EINTR;        fe->state = FESTATE_IDLE;	fe->exit = 0;	fe->thread_pid = 0;	mb();#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)){	/* bug in linux 2.4.x: kernel_thread() fails when the process calling	 * open() is run in the debugger (fixed in kernel 2.5). I hope this	 * workaround does not have any ugly side effects...	 */	int pt = current->ptrace;	current->ptrace = 0;#endif	ret = kernel_thread (dvb_frontend_thread, fe, 0);#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))	current->ptrace = pt;}#endif	if (ret < 0) {		printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret);		up(&fe->sem);		return ret;	}	fe->thread_pid = ret;	return 0;}static int dvb_frontend_ioctl (struct inode *inode, struct file *file,			unsigned int cmd, void *parg){	struct dvb_device *dvbdev = file->private_data;	struct dvb_frontend_data *fe = dvbdev->priv;	int err = 0;        int delay_ms;	dprintk ("%s\n", __FUNCTION__);	if (!fe || !fe->frontend.ioctl || fe->exit)		return -ENODEV;	if (down_interruptible (&fe->sem))		return -ERESTARTSYS;	switch (cmd) {	case FE_DISEQC_SEND_MASTER_CMD:	case FE_DISEQC_SEND_BURST:	case FE_SET_TONE:		if (fe->status)			dvb_call_frontend_notifiers (fe, 0);		dvb_frontend_internal_ioctl (&fe->frontend, cmd, parg);	        fe->state = FESTATE_IDLE;		break;	case FE_SET_FRONTEND:		fe->state = FESTATE_RETUNE;	    		memcpy (&fe->parameters, parg,			sizeof (struct dvb_frontend_parameters));	        delay_ms = dvb_frontend_internal_ioctl(&fe->frontend, FE_GETMINDELAY, &fe->parameters);	        if (delay_ms >= 0) fe->min_delay = (delay_ms * HZ) / 1000;	        else {		        switch(fe->info->type) {			case FE_QPSK:			        fe->min_delay = HZ/20; // default mindelay of 50ms			        break;			    			case FE_QAM:			        fe->min_delay = HZ/20; // default mindelay of 50ms			        break;			    			case FE_OFDM:			        fe->min_delay = HZ/10; // default mindelay of 100ms			        break;			}		}		dvb_frontend_add_event (fe, 0);	    		break;	case FE_GET_EVENT:		err = dvb_frontend_get_event (fe, parg, file->f_flags);		break;	case FE_GET_FRONTEND:		memcpy (parg, &fe->parameters,			sizeof (struct dvb_frontend_parameters));		/*  fall-through... */	default:		dvb_frontend_internal_ioctl (&fe->frontend, cmd, parg);	};    	up (&fe->sem);        // Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't do it, it is done for it.	if ((cmd == FE_GET_INFO) && (err == 0)) {	        struct dvb_frontend_info* tmp = (struct dvb_frontend_info*) parg;	        tmp->caps |= FE_CAN_INVERSION_AUTO;	}

⌨️ 快捷键说明

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