Enscript Output

extractedLnx/linux-2.6.37/drivers/staging/stradis/stradis.c_saa_ioctl.c

static long saa_ioctl(struct file *file,
		     unsigned int cmd, unsigned long argl)
{
	struct saa7146 *saa = file->private_data;
	void __user *arg = (void __user *)argl;

	switch (cmd) {
	case VIDIOCGCAP:
		{
			struct video_capability b;
			memset(&b, 0, sizeof(b));
			strcpy(b.name, saa->video_dev.name);
			b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY |
				VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
				VID_TYPE_SCALES;
			b.channels = 1;
			b.audios = 1;
			b.maxwidth = 768;
			b.maxheight = 576;
			b.minwidth = 32;
			b.minheight = 32;
			if (copy_to_user(arg, &b, sizeof(b)))
				return -EFAULT;
			return 0;
		}
	case VIDIOCGPICT:
		{
			struct video_picture p = saa->picture;
			if (saa->win.depth == 8)
				p.palette = VIDEO_PALETTE_HI240;
			if (saa->win.depth == 15)
				p.palette = VIDEO_PALETTE_RGB555;
			if (saa->win.depth == 16)
				p.palette = VIDEO_PALETTE_RGB565;
			if (saa->win.depth == 24)
				p.palette = VIDEO_PALETTE_RGB24;
			if (saa->win.depth == 32)
				p.palette = VIDEO_PALETTE_RGB32;
			if (copy_to_user(arg, &p, sizeof(p)))
				return -EFAULT;
			return 0;
		}
	case VIDIOCSPICT:
		{
			struct video_picture p;
			u32 format;
			if (copy_from_user(&p, arg, sizeof(p)))
				return -EFAULT;
			if (p.palette < ARRAY_SIZE(palette2fmt)) {
				format = palette2fmt[p.palette];
				saa->win.color_fmt = format;
				saawrite(format | 0x60,
					SAA7146_CLIP_FORMAT_CTRL);
			}
			saawrite(((p.brightness & 0xff00) << 16) |
				((p.contrast & 0xfe00) << 7) |
				((p.colour & 0xfe00) >> 9), SAA7146_BCS_CTRL);
			saa->picture = p;
			/* upload changed registers */
			saawrite(((SAA7146_MC2_UPLD_HPS_H |
				SAA7146_MC2_UPLD_HPS_V) << 16) |
				SAA7146_MC2_UPLD_HPS_H |
				SAA7146_MC2_UPLD_HPS_V, SAA7146_MC2);
			return 0;
		}
	case VIDIOCSWIN:
		{
			struct video_window vw;
			struct video_clip *vcp = NULL;

			if (copy_from_user(&vw, arg, sizeof(vw)))
				return -EFAULT;

			/* stop capture */
			if (vw.flags || vw.width < 16 || vw.height < 16) {
				saawrite((SAA7146_MC1_TR_E_1 << 16),
					SAA7146_MC1);
				return -EINVAL;
			}
			/* 32-bit align start and adjust width */
			if (saa->win.bpp < 4) {
				int i = vw.x;
				vw.x = (vw.x + 3) & ~3;
				i = vw.x - i;
				vw.width -= i;
			}
			saa->win.x = vw.x;
			saa->win.y = vw.y;
			saa->win.width = vw.width;
			if (saa->win.width > 768)
				saa->win.width = 768;
			saa->win.height = vw.height;
			if (CurrentMode == VIDEO_MODE_NTSC) {
				if (saa->win.height > 480)
					saa->win.height = 480;
			} else {
				if (saa->win.height > 576)
					saa->win.height = 576;
			}

			/* stop capture */
			saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
			saa7146_set_winsize(saa);

			/*
			 *    Do any clips.
			 */
			if (vw.clipcount < 0) {
				if (copy_from_user(saa->dmavid2, vw.clips,
						VIDEO_CLIPMAP_SIZE))
					return -EFAULT;
			} else if (vw.clipcount > 16384) {
				return -EINVAL;
			} else if (vw.clipcount > 0) {
				vcp = vmalloc(sizeof(struct video_clip) *
					vw.clipcount);
				if (vcp == NULL)
					return -ENOMEM;
				if (copy_from_user(vcp, vw.clips,
						sizeof(struct video_clip) *
						vw.clipcount)) {
					vfree(vcp);
					return -EFAULT;
				}
			} else	/* nothing clipped */
				memset(saa->dmavid2, 0, VIDEO_CLIPMAP_SIZE);

			make_clip_tab(saa, vcp, vw.clipcount);
			if (vw.clipcount > 0)
				vfree(vcp);

			/* start capture & clip dma if we have an address */
			if ((saa->cap & 3) && saa->win.vidadr != 0)
				saawrite(((SAA7146_MC1_TR_E_1 |
					SAA7146_MC1_TR_E_2) << 16) | 0xffff,
					SAA7146_MC1);
			return 0;
		}
	case VIDIOCGWIN:
		{
			struct video_window vw;
			memset(&vw, 0, sizeof(vw));
			vw.x = saa->win.x;
			vw.y = saa->win.y;
			vw.width = saa->win.width;
			vw.height = saa->win.height;
			vw.chromakey = 0;
			vw.flags = 0;
			if (copy_to_user(arg, &vw, sizeof(vw)))
				return -EFAULT;
			return 0;
		}
	case VIDIOCCAPTURE:
		{
			int v;
			if (copy_from_user(&v, arg, sizeof(v)))
				return -EFAULT;
			if (v == 0) {
				saa->cap &= ~1;
				saawrite((SAA7146_MC1_TR_E_1 << 16),
					SAA7146_MC1);
			} else {
				if (saa->win.vidadr == 0 || saa->win.width == 0
						|| saa->win.height == 0)
					return -EINVAL;
				saa->cap |= 1;
				saawrite((SAA7146_MC1_TR_E_1 << 16) | 0xffff,
					SAA7146_MC1);
			}
			return 0;
		}
	case VIDIOCGFBUF:
		{
			struct video_buffer v;
			memset(&v, 0, sizeof(v));
			v.base = (void *)saa->win.vidadr;
			v.height = saa->win.sheight;
			v.width = saa->win.swidth;
			v.depth = saa->win.depth;
			v.bytesperline = saa->win.bpl;
			if (copy_to_user(arg, &v, sizeof(v)))
				return -EFAULT;
			return 0;

		}
	case VIDIOCSFBUF:
		{
			struct video_buffer v;
			if (!capable(CAP_SYS_ADMIN))
				return -EPERM;
			if (copy_from_user(&v, arg, sizeof(v)))
				return -EFAULT;
			if (v.depth != 8 && v.depth != 15 && v.depth != 16 &&
			    v.depth != 24 && v.depth != 32 && v.width > 16 &&
			    v.height > 16 && v.bytesperline > 16)
				return -EINVAL;
			if (v.base)
				saa->win.vidadr = (unsigned long)v.base;
			saa->win.sheight = v.height;
			saa->win.swidth = v.width;
			saa->win.bpp = ((v.depth + 7) & 0x38) / 8;
			saa->win.depth = v.depth;
			saa->win.bpl = v.bytesperline;

			DEBUG(printk("Display at %p is %d by %d, bytedepth %d, "
					"bpl %d\n", v.base, v.width, v.height,
					saa->win.bpp, saa->win.bpl));
			saa7146_set_winsize(saa);
			return 0;
		}
	case VIDIOCKEY:
		{
			/* Will be handled higher up .. */
			return 0;
		}

	case VIDIOCGAUDIO:
		{
			struct video_audio v;
			memset(&v, 0, sizeof(v));
			v = saa->audio_dev;
			v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
			v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
			strcpy(v.name, "MPEG");
			v.mode = VIDEO_SOUND_STEREO;
			if (copy_to_user(arg, &v, sizeof(v)))
				return -EFAULT;
			return 0;
		}
	case VIDIOCSAUDIO:
		{
			struct video_audio v;
			int i;
			if (copy_from_user(&v, arg, sizeof(v)))
				return -EFAULT;
			i = (~(v.volume >> 8)) & 0xff;
			if (!HaveCS4341) {
				if (v.flags & VIDEO_AUDIO_MUTE)
					debiwrite(saa, debNormal,
						IBM_MP2_FRNT_ATTEN, 0xffff, 2);
				if (!(v.flags & VIDEO_AUDIO_MUTE))
					debiwrite(saa, debNormal,
						IBM_MP2_FRNT_ATTEN, 0x0000, 2);
				if (v.flags & VIDEO_AUDIO_VOLUME)
					debiwrite(saa, debNormal,
						IBM_MP2_FRNT_ATTEN,
						(i << 8) | i, 2);
			} else {
				if (v.flags & VIDEO_AUDIO_MUTE)
					cs4341_setlevel(saa, 0xff, 0xff);
				if (!(v.flags & VIDEO_AUDIO_MUTE))
					cs4341_setlevel(saa, 0, 0);
				if (v.flags & VIDEO_AUDIO_VOLUME)
					cs4341_setlevel(saa, i, i);
			}
			saa->audio_dev = v;
			return 0;
		}

	case VIDIOCGUNIT:
		{
			struct video_unit vu;
			memset(&vu, 0, sizeof(vu));
			vu.video = saa->video_dev.minor;
			vu.vbi = VIDEO_NO_UNIT;
			vu.radio = VIDEO_NO_UNIT;
			vu.audio = VIDEO_NO_UNIT;
			vu.teletext = VIDEO_NO_UNIT;
			if (copy_to_user(arg, &vu, sizeof(vu)))
				return -EFAULT;
			return 0;
		}
	case VIDIOCSPLAYMODE:
		{
			struct video_play_mode pmode;
			if (copy_from_user((void *)&pmode, arg,
					sizeof(struct video_play_mode)))
				return -EFAULT;
			switch (pmode.mode) {
			case VID_PLAY_VID_OUT_MODE:
				if (pmode.p1 != VIDEO_MODE_NTSC &&
						pmode.p1 != VIDEO_MODE_PAL)
					return -EINVAL;
				set_out_format(saa, pmode.p1);
				return 0;
			case VID_PLAY_GENLOCK:
				debiwrite(saa, debNormal, XILINX_CTL0,
					pmode.p1 ? 0x8000 : 0x8080, 2);
				if (NewCard)
					set_genlock_offset(saa, pmode.p2);
				return 0;
			case VID_PLAY_NORMAL:
				debiwrite(saa, debNormal,
					IBM_MP2_CHIP_CONTROL, ChipControl, 2);
				ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
				saa->playmode = pmode.mode;
				return 0;
			case VID_PLAY_PAUSE:
				/* IBM removed the PAUSE command */
				/* they say use SINGLE_FRAME now */
			case VID_PLAY_SINGLE_FRAME:
				ibm_send_command(saa, IBM_MP2_SINGLE_FRAME,0,0);
				if (saa->playmode == pmode.mode) {
					debiwrite(saa, debNormal,
						IBM_MP2_CHIP_CONTROL,
						ChipControl, 2);
				}
				saa->playmode = pmode.mode;
				return 0;
			case VID_PLAY_FAST_FORWARD:
				ibm_send_command(saa, IBM_MP2_FAST_FORWARD,0,0);
				saa->playmode = pmode.mode;
				return 0;
			case VID_PLAY_SLOW_MOTION:
				ibm_send_command(saa, IBM_MP2_SLOW_MOTION,
					pmode.p1, 0);
				saa->playmode = pmode.mode;
				return 0;
			case VID_PLAY_IMMEDIATE_NORMAL:
				/* ensure transfers resume */
				debiwrite(saa, debNormal,
					IBM_MP2_CHIP_CONTROL, ChipControl, 2);
				ibm_send_command(saa, IBM_MP2_IMED_NORM_PLAY,
					0, 0);
				saa->playmode = VID_PLAY_NORMAL;
				return 0;
			case VID_PLAY_SWITCH_CHANNELS:
				saa->audhead = saa->audtail = 0;
				saa->vidhead = saa->vidtail = 0;
				ibm_send_command(saa, IBM_MP2_FREEZE_FRAME,0,1);
				ibm_send_command(saa, IBM_MP2_RESET_AUD_RATE,
					0, 1);
				debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
					0, 2);
				ibm_send_command(saa, IBM_MP2_CHANNEL_SWITCH,
					0, 1);
				debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
					ChipControl, 2);
				ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
				saa->playmode = VID_PLAY_NORMAL;
				return 0;
			case VID_PLAY_FREEZE_FRAME:
				ibm_send_command(saa, IBM_MP2_FREEZE_FRAME,0,0);
				saa->playmode = pmode.mode;
				return 0;
			case VID_PLAY_STILL_MODE:
				ibm_send_command(saa, IBM_MP2_SET_STILL_MODE,
					0, 0);
				saa->playmode = pmode.mode;
				return 0;
			case VID_PLAY_MASTER_MODE:
				if (pmode.p1 == VID_PLAY_MASTER_NONE)
					saa->boardcfg[1] = 0x13;
				else if (pmode.p1 == VID_PLAY_MASTER_VIDEO)
					saa->boardcfg[1] = 0x23;
				else if (pmode.p1 == VID_PLAY_MASTER_AUDIO)
					saa->boardcfg[1] = 0x43;
				else
					return -EINVAL;
				debiwrite(saa, debNormal,
					  IBM_MP2_CHIP_CONTROL, ChipControl, 2);
				return 0;
			case VID_PLAY_ACTIVE_SCANLINES:
				if (CurrentMode == VIDEO_MODE_PAL) {
					if (pmode.p1 < 1 || pmode.p2 > 625)
						return -EINVAL;
					saa->boardcfg[5] = pmode.p1;
					saa->boardcfg[55] = (pmode.p1 +
						(pmode.p2 / 2) - 1) & 0xff;
				} else {
					if (pmode.p1 < 4 || pmode.p2 > 525)
						return -EINVAL;
					saa->boardcfg[4] = pmode.p1;
					saa->boardcfg[54] = (pmode.p1 +
						(pmode.p2 / 2) - 4) & 0xff;
				}
				set_out_format(saa, CurrentMode);
			case VID_PLAY_RESET:
				return do_ibm_reset(saa);
			case VID_PLAY_END_MARK:
				if (saa->endmarktail < saa->endmarkhead) {
					if (saa->endmarkhead -
							saa->endmarktail < 2)
						return -ENOSPC;
				} else if (saa->endmarkhead <=saa->endmarktail){
					if (saa->endmarktail - saa->endmarkhead
							> (MAX_MARKS - 2))
						return -ENOSPC;
				} else
					return -ENOSPC;
				saa->endmark[saa->endmarktail] = saa->audtail;
				saa->endmarktail++;
				if (saa->endmarktail >= MAX_MARKS)
					saa->endmarktail = 0;
			}
			return -EINVAL;
		}
	case VIDIOCSWRITEMODE:
		{
			int mode;
			if (copy_from_user((void *)&mode, arg, sizeof(int)))
				return -EFAULT;
			if (mode == VID_WRITE_MPEG_AUD ||
					mode == VID_WRITE_MPEG_VID ||
					mode == VID_WRITE_CC ||
					mode == VID_WRITE_TTX ||
					mode == VID_WRITE_OSD) {
				saa->writemode = mode;
				return 0;
			}
			return -EINVAL;
		}
	case VIDIOCSMICROCODE:
		{
			struct video_code ucode;
			__u8 *udata;
			int i;
			if (copy_from_user(&ucode, arg, sizeof(ucode)))
				return -EFAULT;
			if (ucode.datasize > 65536 || ucode.datasize < 1024 ||
					strncmp(ucode.loadwhat, "dec", 3))
				return -EINVAL;
			if ((udata = vmalloc(ucode.datasize)) == NULL)
				return -ENOMEM;
			if (copy_from_user(udata, ucode.data, ucode.datasize)) {
				vfree(udata);
				return -EFAULT;
			}
			ucode.data = udata;
			if (!strncmp(ucode.loadwhat, "decoder.aud", 11) ||
				!strncmp(ucode.loadwhat, "decoder.vid", 11))
				i = initialize_ibmmpeg2(&ucode);
			else
				i = initialize_fpga(&ucode);
			vfree(udata);
			if (i)
				return -EINVAL;
			return 0;

		}
	case VIDIOCGCHAN:	/* this makes xawtv happy */
		{
			struct video_channel v;
			if (copy_from_user(&v, arg, sizeof(v)))
				return -EFAULT;
			v.flags = VIDEO_VC_AUDIO;
			v.tuners = 0;
			v.type = VID_TYPE_MPEG_DECODER;
			v.norm = CurrentMode;
			strcpy(v.name, "MPEG2");
			if (copy_to_user(arg, &v, sizeof(v)))
				return -EFAULT;
			return 0;
		}
	case VIDIOCSCHAN:	/* this makes xawtv happy */
		{
			struct video_channel v;
			if (copy_from_user(&v, arg, sizeof(v)))
				return -EFAULT;
			/* do nothing */
			return 0;
		}
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}

Generated by GNU enscript 1.6.4.