/* FIXME: switch inputs here */ 
static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg){	struct saa7146_dev *dev = fh->dev;	struct av7110 *av7110 = (struct av7110*) dev->ext_priv;	dprintk(4, "saa7146_dev: %p\n", dev);	switch (cmd) {	case VIDIOC_G_TUNER:	{		struct v4l2_tuner *t = arg;		u16 stereo_det;		s8 stereo;		dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);		if (!av7110->analog_tuner_flags || t->index != 0)			return -EINVAL;		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;		// FIXME: standard / stereo detection is still broken		msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);		dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);		msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);		dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);		stereo = (s8)(stereo_det >> 8);		if (stereo > 0x10) {			/* stereo */			t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;			t->audmode = V4L2_TUNER_MODE_STEREO;		}		else if (stereo < -0x10) {			/* bilingual*/			t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;			t->audmode = V4L2_TUNER_MODE_LANG1;		}		else /* mono */			t->rxsubchans = V4L2_TUNER_SUB_MONO;		return 0;	}	case VIDIOC_S_TUNER:	{		struct v4l2_tuner *t = arg;		u16 fm_matrix, src;		dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);		if (!av7110->analog_tuner_flags || av7110->current_input != 1)			return -EINVAL;		switch (t->audmode) {		case V4L2_TUNER_MODE_STEREO:			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");			fm_matrix = 0x3001; // stereo			src = 0x0020;			break;		case V4L2_TUNER_MODE_LANG1:			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");			fm_matrix = 0x3000; // mono			src = 0x0000;			break;		case V4L2_TUNER_MODE_LANG2:			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");			fm_matrix = 0x3000; // mono			src = 0x0010;			break;		default: /* case V4L2_TUNER_MODE_MONO: {*/			dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");			fm_matrix = 0x3000; // mono			src = 0x0030;			break;		}		msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);		msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);		msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);		msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);		return 0;	}	case VIDIOC_G_FREQUENCY:	{		struct v4l2_frequency *f = arg;		dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);		if (!av7110->analog_tuner_flags || av7110->current_input != 1)			return -EINVAL;		memset(f, 0, sizeof(*f));		f->type = V4L2_TUNER_ANALOG_TV;		f->frequency =	av7110->current_freq;		return 0;	}	case VIDIOC_S_FREQUENCY:	{		struct v4l2_frequency *f = arg;		dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);		if (!av7110->analog_tuner_flags || av7110->current_input != 1)			return -EINVAL;		if (V4L2_TUNER_ANALOG_TV != f->type)			return -EINVAL;		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);		/* tune in desired frequency */		if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {			ves1820_set_tv_freq(dev, f->frequency);		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {			stv0297_set_tv_freq(dev, f->frequency);		}		av7110->current_freq = f->frequency;		msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection		msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume		return 0;	}	case VIDIOC_ENUMINPUT:	{		struct v4l2_input *i = arg;		dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);		if (av7110->analog_tuner_flags) {			if (i->index < 0 || i->index >= 2)				return -EINVAL;		} else {			if (i->index != 0)				return -EINVAL;		}		memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));		return 0;	}	case VIDIOC_G_INPUT:	{		int *input = (int *)arg;		*input = av7110->current_input;		dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);		return 0;	}	case VIDIOC_S_INPUT:	{		int input = *(int *)arg;		dprintk(2, "VIDIOC_S_INPUT: %d\n", input);		if (!av7110->analog_tuner_flags)			return 0;		if (input < 0 || input >= 2)			return -EINVAL;		/* FIXME: switch inputs here */		av7110->current_input = input;		return av7110_dvb_c_switch(fh);	}	case VIDIOC_G_AUDIO:	{		struct v4l2_audio *a = arg;		dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);		if (a->index != 0)			return -EINVAL;		memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));		break;	}	case VIDIOC_S_AUDIO:	{		struct v4l2_audio *a = arg;		dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);		break;	}	default:		printk("no such ioctl\n");		return -ENOIOCTLCMD;	}	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/f63f5346c943008fe8f6ac66a9026f6c35e24947/av7110_v4l.c/buggy/drivers/media/dvb/ttpci/av7110_v4l.c