memset(f,0,sizeof(*f)); f->type = V4L2_TUNER_ANALOG_TV; f->frequency =  mxb->cur_freq;  DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq)); 
*f = mxb->cur_freq;  DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency)); 
static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) {	struct saa7146_dev *dev = fh->dev;	struct mxb* mxb = (struct mxb*)dev->ext_priv;	struct saa7146_vv *vv = dev->vv_data; 		switch(cmd) {	case VIDIOC_ENUMINPUT:	{		struct v4l2_input *i = arg;				DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));		if( i->index < 0 || i->index >= MXB_INPUTS) {			return -EINVAL;		}		memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));		return 0;	}	/* the saa7146 provides some controls (brightness, contrast, saturation)	   which gets registered *after* this function. because of this we have	   to return with a value != 0 even if the function succeded.. */	case VIDIOC_QUERYCTRL:	{		struct v4l2_queryctrl *qc = arg;		int i;		for (i = MAXCONTROLS - 1; i >= 0; i--) {			if (mxb_controls[i].id == qc->id) {				*qc = mxb_controls[i];				DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));				return 0;			}		}		return -EAGAIN;	}	case VIDIOC_G_CTRL:	{		struct v4l2_control *vc = arg;		int i;		for (i = MAXCONTROLS - 1; i >= 0; i--) {			if (mxb_controls[i].id == vc->id) {				break;			}		}				if( i < 0 ) {			return -EAGAIN;		}					switch (vc->id ) {			case V4L2_CID_AUDIO_MUTE: {				vc->value = mxb->cur_mute;				DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));				return 0;			}		}				DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));		return 0;	}	case VIDIOC_S_CTRL:	{		struct	v4l2_control	*vc = arg;		int i = 0;				for (i = MAXCONTROLS - 1; i >= 0; i--) {			if (mxb_controls[i].id == vc->id) {				break;			}		}				if( i < 0 ) {			return -EAGAIN;		}				switch (vc->id ) {			case V4L2_CID_AUDIO_MUTE: {				mxb->cur_mute = vc->value;				if( 0 == vc->value ) {					/* switch the audio-source */					mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);					mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);				} else {					mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);					mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);				}				DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));				break;			}		}		return 0;	}	case VIDIOC_G_INPUT:	{		int *input = (int *)arg;		*input = mxb->cur_input;		DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));		return 0;			}		case VIDIOC_S_INPUT:	{		int input = *(int *)arg;		struct	tea6415c_multiplex vm;			int i = 0;		DEB_EE(("VIDIOC_S_INPUT %d.\n",input));		if (input < 0 || input >= MXB_INPUTS) {			return -EINVAL;		}				/* fixme: locke das setzen des inputs mit hilfe des mutexes		down(&dev->lock);		video_mux(dev,*i);		up(&dev->lock);		*/						/* fixme: check if streaming capture		if ( 0 != dev->streaming ) {			DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));			return -EPERM;		}		*/				mxb->cur_input = input;			saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);				/* prepare switching of tea6415c and saa7111a;		   have a look at the 'background'-file for further informations  */		switch( input ) {						case TUNER:			{				i = 0;				vm.in  = 3;				vm.out = 17;											if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {					printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");					return -EFAULT;				}				/* connect tuner-output always to multicable */				vm.in  = 3;				vm.out = 13;				break;							}			case AUX3_YC:			{				/* nothing to be done here. aux3_yc is				   directly connected to the saa711a */				i = 5;				break;			}			case AUX3:			{				/* nothing to be done here. aux3 is				   directly connected to the saa711a */				i = 1;				break;			}			case AUX1:			{				i = 0;				vm.in  = 1;				vm.out = 17;				break;			}		}		/* switch video in tea6415c only if necessary */		switch( input ) {			case TUNER:			case AUX1:			{				if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {					printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");					return -EFAULT;				}				break;			}			default:			{				break;			}		}						/* switch video in saa7111a */		if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {			printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");		}					/* switch the audio-source only if necessary */		if( 0 == mxb->cur_mute ) {			mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);			mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);		}		return 0;	}	case VIDIOC_G_TUNER:	{		struct v4l2_tuner *t = arg;		int byte = 0;		if( 0 != t->index ) {			DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));			return -EINVAL;		}		DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));		memset(t,0,sizeof(*t));		strcpy(t->name, "Television");		t->type = V4L2_TUNER_ANALOG_TV;		t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;		t->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */		t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */		/* FIXME: add the real signal strength here */		t->signal = 0xffff;		t->afc = 0;				mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);		t->audmode = mxb->cur_mode;				if( byte < 0 ) {			t->rxsubchans  = V4L2_TUNER_SUB_MONO;		} else {			switch(byte) {				case TDA9840_MONO_DETECT: {					t->rxsubchans 	= V4L2_TUNER_SUB_MONO;					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));					break;				}				case TDA9840_DUAL_DETECT: {					t->rxsubchans 	= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));					break;				}				case TDA9840_STEREO_DETECT: {					t->rxsubchans 	= V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));					break;				}				default: { /* TDA9840_INCORRECT_DETECT */					t->rxsubchans 	= V4L2_TUNER_MODE_MONO;					DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));					break;				}			}		}		return 0;	}	case VIDIOC_S_TUNER:	{		struct v4l2_tuner *t = arg;		int result = 0;		int byte = 0;				if( 0 != t->index ) {			DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));			return -EINVAL;		}			switch(t->audmode) {			case V4L2_TUNER_MODE_STEREO: {				mxb->cur_mode = V4L2_TUNER_MODE_STEREO;				byte = TDA9840_SET_STEREO;				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));				break;			}			case V4L2_TUNER_MODE_LANG1: {				mxb->cur_mode = V4L2_TUNER_MODE_LANG1;				byte = TDA9840_SET_LANG1;				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));				break;			}			case V4L2_TUNER_MODE_LANG2: {				mxb->cur_mode = V4L2_TUNER_MODE_LANG2;				byte = TDA9840_SET_LANG2;				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));				break;			}			default: { /* case V4L2_TUNER_MODE_MONO: {*/				mxb->cur_mode = V4L2_TUNER_MODE_MONO;				byte = TDA9840_SET_MONO;				DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));				break;			}		}		if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {			printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);		}						return 0;	}	case VIDIOC_G_FREQUENCY:	{		struct v4l2_frequency *f = arg;		if(0 != mxb->cur_input) {			DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));			return -EINVAL;		}		memset(f,0,sizeof(*f));		f->type = V4L2_TUNER_ANALOG_TV;		f->frequency =  mxb->cur_freq;		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq));		return 0;	}	case VIDIOC_S_FREQUENCY:	{		struct v4l2_frequency *f = arg;		int t_locked = 0;		int v_byte = 0;		if (0 != f->tuner)			return -EINVAL;		if (V4L2_TUNER_ANALOG_TV != f->type)			return -EINVAL;				if(0 != mxb->cur_input) {			DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));			return -EINVAL;		}		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));		mxb->cur_freq = f->frequency;		/* tune in desired frequency */					mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &mxb->cur_freq);		/* check if pll of tuner & saa7111a is locked *///		mxb->tuner->driver->command(mxb->tuner,TUNER_IS_LOCKED, &t_locked);		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_GET_STATUS, &v_byte);		/* not locked -- anything to do here ? */		if( 0 == t_locked || 0 == (v_byte & DECODER_STATUS_GOOD)) {		}		/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */		spin_lock(&dev->slock);		vv->vbi_fieldcount = 0;		spin_unlock(&dev->slock);		return 0;	}	case MXB_S_AUDIO_CD:	{		int i = *(int*)arg;						if( i < 0 || i >= MXB_AUDIOS ) {			DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));			return -EINVAL;		}				DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);		return 0;	}	case MXB_S_AUDIO_LINE:	{		int i = *(int*)arg;						if( i < 0 || i >= MXB_AUDIOS ) {			DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));			return -EINVAL;		}				DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);		return 0;	}	case VIDIOC_G_AUDIO:	{		struct v4l2_audio *a = arg;		if( a->index < 0 || a->index > MXB_INPUTS ) {	 		DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));			return -EINVAL;		}		 		DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));		memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));				return 0;	}	case VIDIOC_S_AUDIO:	{		struct v4l2_audio *a = arg;		DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));		return 0;	}		default:/*		DEB2(printk("does not handle this ioctl.\n"));*/		return -ENOIOCTLCMD;	}	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/9d2599d98e9cb511f326b2d1b353e462bc360774/mxb.c/clean/drivers/media/video/mxb.c