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

📄 pvrusb2-hdw.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	return 0;}/* Set the current value of a given control.  This assumes we are already   inside our critical region. */int pvr2_ctrl_internal_set_value(struct pvr2_ctrl *cptr,int value){	const struct pvr2_ctl_def *dptr;	int ret;	if (!cptr) return -EINVAL;	if (!cptr->is_valid) return -EINVAL;	dptr = cptr->ctl_def;	if (!dptr->is_valid) return -EINVAL;	if (value < dptr->min_value) return -EINVAL;	if (value > dptr->max_value) return -EINVAL;	if (dptr->set_func) {		ret = dptr->set_func(cptr,value);		pvr2_i2c_core_check_stale(cptr->hdw);		pvr2_i2c_core_sync(cptr->hdw);		return ret;	} else if (dptr->get_func) {		/* If there's no "set" function yet there is still a "get"		   function, then treat this as a read-only value. */		return -EINVAL;	}	if ((cptr->value != value) || (ctlchg != 0)) {		cptr->value = value;		cptr->dirty = !0;	}	return 0;}/* Get the current value of a given control.  This assumes that we are   already inside our critical region. */int pvr2_ctrl_internal_get_value(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	if (!cptr->is_valid) return 0;	dptr = cptr->ctl_def;	if (!dptr->is_valid) return 0;	if (dptr->get_func) {		return dptr->get_func(cptr);	}	return cptr->value;}/* Set the current value of the given control. */int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val){	int ret;	if (!cptr) return -EINVAL;	LOCK_TAKE(cptr->hdw->big_lock); do {		ret = pvr2_ctrl_internal_set_value(cptr,val);	} while(0); LOCK_GIVE(cptr->hdw->big_lock);	return ret;}/* Get the current value of the given control. */int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr){	int ret;	if (!cptr) return -EINVAL;	LOCK_TAKE(cptr->hdw->big_lock); do {		ret = pvr2_ctrl_internal_get_value(cptr);	} while(0); LOCK_GIVE(cptr->hdw->big_lock);	return ret;}/* Return the type of the given control (int, enum, or bit mask). */int pvr2_ctrl_get_type(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return PVR2_CTRL_TYPE_INVALID;	dptr = cptr->ctl_def;	if (dptr->mask_value) {		return PVR2_CTRL_TYPE_BITMASK;	}	if (dptr->value_defs_ptr) {		return PVR2_CTRL_TYPE_ENUM;	}	return PVR2_CTRL_TYPE_INT;}/* Return the minimum legal value for a given control.  This command is   only relevant for int or enum types. */int pvr2_ctrl_get_min_value(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	return dptr->min_value;}/* Return the maximum legal value for a given control.  This command is   only relevant for int or enum types. */int pvr2_ctrl_get_max_value(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	return dptr->max_value;}/* Return the default value for a given control. */int pvr2_ctrl_get_default_value(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	return dptr->default_value;}/* Return a mask of which bits are used within the bit mask of a given   control.  This command is only relevant for bit mask types. */int pvr2_ctrl_get_mask_value(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	return dptr->mask_value;}/* Return true if this is a valid control. */int pvr2_ctrl_is_valid(struct pvr2_ctrl *cptr){	if (!cptr) return 0;	return cptr->is_valid;}/* Return true if the control can be set (otherwise it may only be read,   assuming that it is valid). */int pvr2_ctrl_is_writeable(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	if (!dptr->is_valid) return 0;	if (dptr->set_func) return !0;	if (dptr->get_func) return 0;	return !0;}/* Return the control's name, or null if there isn't a name or the control   isn't otherwise valid. */const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	return dptr->name;}/* Return the control's description, or null if there isn't a name or the   control isn't otherwise valid. */const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr){	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	return dptr->desc;}/* Return the name for an enumeration value or bit mask position for the   given control.  If the control is not an enumeration or bit mask type,   then return null. */const char *pvr2_ctrl_get_value_name(struct pvr2_ctrl *cptr,int val){	int msk,idx;	const struct pvr2_ctl_def *dptr;	if (!cptr) return 0;	dptr = cptr->ctl_def;	if (dptr->mask_value) {		for (idx = 0, msk = 1;		     (idx < dptr->value_defs_count) && msk;		     idx++, msk <<= 1) {			if (val & msk) {				return dptr->value_defs_ptr[idx];			}		}	} else {		val -= dptr->min_value;		if (val < 0) return 0;		if (val >= dptr->value_defs_count) return 0;		return dptr->value_defs_ptr[val];	}	return 0;}/* Commit all control changes made up to this point.  Subsystems can be   indirectly affected by these changes.  For a given set of things being   committed, we'll clear the affected subsystem bits and then once we're   done committing everything we'll make a request to restore the subsystem   state(s) back to their previous value before this function was called.   Thus we can automatically reconfigure affected pieces of the driver as   controls are changed. */int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw){	unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;	unsigned long stale_subsys_mask = 0;	unsigned int idx;	const struct pvr2_ctl_def *dptr;	struct pvr2_ctrl *cptr;	int value;	const char *ctl_name;	const char *ctl_value;	int commit_flag = 0;	/* Let's see if the channel changed and we have to update the	   frequency because of it.  This setup means one can tune the	   receiver either by just setting the channel (using the frequency	   table), or by directly programming the frequency.  How do we	   resolve the obvious conflict here?  The direct frequency takes	   priority; if directly set then we commit that value and force	   the channel to zero which is interpreted to mean "none".  If on	   the other hand we see that the channel has been set and it's a	   legal value, then we copy that into the frequency.  The metaphor	   here is similar to when you tune your digital radio: You an	   either set a frequency directly or punch up a pre-programmed	   station.  Either way a frequency is set, and if you do use a	   preset, then the radio also shows you which preset it is - until	   you override that by directly entering a new frequency. */	if (hdw->controls[PVR2_CID_FREQUENCY].dirty) {		/* Frequency has been directly set, so clear out the		   channel. */		hdw->controls[PVR2_CID_CHANNEL].value = 0;	} else if (hdw->controls[PVR2_CID_CHANNEL].dirty) {		int id = hdw->controls[PVR2_CID_CHANNEL].value;		if ((id > 0) && (id <= FREQTABLE_SIZE)) {			if (hdw->controls[PVR2_CID_FREQUENCY].value !=			    hdw->freqTable[id-1]) {				hdw->controls[PVR2_CID_FREQUENCY].value =					hdw->freqTable[id-1];				hdw->controls[PVR2_CID_FREQUENCY].dirty = !0;			}		}	}	for (idx = 0; idx < CTRL_COUNT; idx++) {		cptr = hdw->controls + idx;		if (!cptr->dirty) continue;		if (!commit_flag) {			commit_flag = !0;		}		value = cptr->value;		dptr = cptr->ctl_def;		ctl_name = dptr->name;		if (dptr->value_defs_ptr) {			if (value < dptr->value_defs_count) {				ctl_value = dptr->value_defs_ptr[value];			} else {				ctl_value = "<out of range>";			}		} else {			ctl_value = "<integer>";		}		pvr2_trace(PVR2_TRACE_CTL,			   "/*--TRACE_COMMIT--*/ \"%s\" <-- %d (%s)",			   ctl_name,value,ctl_value);	}	if (!commit_flag) {		/* Nothing has changed */		return 0;	}	/* When video standard changes, reset the hres and vres values -	   but if the user has pending changes there, then let the changes	   take priority. */	if (hdw->controls[PVR2_CID_STDCUR].dirty) {		/* Rewrite the vertical resolution to be appropriate to the		   video standard that has been selected. */		int nvres;		if (hdw->video_std_cur & V4L2_STD_525_60) {			nvres = 480;		} else {			nvres = 576;		}		if (nvres != hdw->controls[PVR2_CID_VRES].value) {			hdw->controls[PVR2_CID_VRES].value = nvres;			hdw->controls[PVR2_CID_VRES].dirty = !0;		}		if (!hdw->controls[PVR2_CID_INTERLACE].value) {			hdw->controls[PVR2_CID_INTERLACE].value = 0;			hdw->controls[PVR2_CID_INTERLACE].dirty = !0;		}	}	if (hdw->controls[PVR2_CID_STDCUR].dirty ||	    hdw->controls[PVR2_CID_VRES].dirty ||	    hdw->controls[PVR2_CID_HRES].dirty ||	    hdw->controls[PVR2_CID_INTERLACE].dirty ||	    hdw->controls[PVR2_CID_VBR].dirty ||	    hdw->controls[PVR2_CID_AVERAGEVIDEOBITRATE].dirty ||	    hdw->controls[PVR2_CID_PEAKVIDEOBITRATE].dirty ||	    hdw->controls[PVR2_CID_AUDIOBITRATE].dirty ||	    hdw->controls[PVR2_CID_SRATE].dirty ||	    hdw->controls[PVR2_CID_AUDIOLAYER].dirty ||	    hdw->controls[PVR2_CID_AUDIOCRC].dirty ||	    hdw->controls[PVR2_CID_AUDIOEMPHASIS].dirty) {		/* If any of this changes, then the encoder needs to be		   reconfigured, and we need to reset the stream. */		stale_subsys_mask |= PVR2_SUBSYS_ENC_CFG;		stale_subsys_mask |= hdw->subsys_stream_mask;	}	/* Scan i2c core at this point - before we clear all the dirty	   bits.  Various parts of the i2c core will notice dirty bits as	   appropriate and arrange to broadcast or directly send updates to	   the client drivers in order to keep everything in sync */	pvr2_i2c_core_check_stale(hdw);	for (idx = 0; idx < CTRL_COUNT; idx++) {		cptr = hdw->controls + idx;		cptr->dirty = 0;	}	/* Now execute i2c core update */	pvr2_i2c_core_sync(hdw);	pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);	pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);	return 0;}int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw){	LOCK_TAKE(hdw->big_lock); do {		pvr2_hdw_commit_ctl_internal(hdw);	} while (0); LOCK_GIVE(hdw->big_lock);	return 0;}void pvr2_hdw_poll(struct pvr2_hdw *hdw){	LOCK_TAKE(hdw->big_lock); do {		pvr2_i2c_core_sync(hdw);	} while (0); LOCK_GIVE(hdw->big_lock);}void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,				 void (*func)(void *),				 void *data){	LOCK_TAKE(hdw->big_lock); do {		hdw->poll_trigger_func = func;		hdw->poll_trigger_data = data;	} while (0); LOCK_GIVE(hdw->big_lock);}void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw){	if (hdw->poll_trigger_func) {		hdw->poll_trigger_func(hdw->poll_trigger_data);	}}void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw){	LOCK_TAKE(hdw->big_lock); do {		pvr2_hdw_poll_trigger_unlocked(hdw);	} while (0); LOCK_GIVE(hdw->big_lock);}/* Return name for this driver instance */const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw){	return hdw->name;}/* Return bit mask indicating signal status */unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw){	unsigned int msk = 0;	switch (hdw->controls[PVR2_CID_INPUT].value) {	case PVR2_CVAL_INPUT_TV:	case PVR2_CVAL_INPUT_RADIO:		if (hdw->decoder_ctrl &&		    hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {			msk |= PVR2_SIGNAL_OK;			if (hdw->audio_stat &&			    hdw->audio_stat->status(hdw->audio_stat->ctxt)) {				if (hdw->flag_stereo) {					msk |= PVR2_SIGNAL_STEREO;				}				if (hdw->flag_bilingual) {					msk |= PVR2_SIGNAL_SAP;				}			}		}		break;	default:		msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;	}	return msk;}static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr){	return cptr->hdw->subsys_enabled_mask;}static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val){	pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,~0,val);	return 0;}static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr){	return cptr->hdw->subsys_stream_mask;}static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr,					   int val){	pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,~0,val);	return 0;}static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr){	int result = pvr2_hdw_is_hsm(cptr->hdw);	if (result < 0) return PVR2_CVAL_HSM_FAIL;	if (result) return PVR2_CVAL_HSM_HIGH;	return PVR2_CVAL_HSM_FULL;}int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw){	int result;	LOCK_TAKE(hdw->ctl_lock); do {		hdw->cmd_buffer[0] = 0x0b;		result = pvr2_send_request(hdw,					   hdw->cmd_buffer,1,					   hdw->cmd_buffer,1);		if (result < 0) break;		result = (hdw->cmd_buffer[0] != 0);	} while(0); LOCK_GIVE(hdw->ctl_lock);	return result;}static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr){	return ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &		 PVR2_SIGNAL_OK) ? 1 : 0);}/* Return bit mask indicating signal status */unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw){	unsigned int msk = 0;	LOCK_TAKE(hdw->big_lock); do {		msk = pvr2_hdw_get_signal_status_internal(hdw);	} while (0); LOCK_GIVE(hdw->big_lock);	return msk;}/* Get handle

⌨️ 快捷键说明

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