/*
 *	Media Vision Pro Movie Studio
 *			or
 *	"all you need is an I2C bus some RAM and a prayer"
 *
 *	This draws heavily on code
 *
 *	(c) Wolfgang Koehler,  wolf@first.gmd.de, Dec. 1994
 *	Kiefernring 15
 *	14478 Potsdam, Germany
 *
 *	Most of this code is directly derived from his userspace driver.
 *	His driver works so send any reports to alan@redhat.com unless the
 *	userspace driver also doesn't work for you...
 *      
 *      Changes:
 *      08/07/2003        Daniele Bellucci <bellucda@tiscali.it>
 *                        - pms_capture: report back -EFAULT 
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/sched.h>
#include <linux/videodev.h>
#include <asm/uaccess.h>


#define MOTOROLA	1
#define PHILIPS2	2
#define PHILIPS1	3
#define MVVMEMORYWIDTH	0x40		/* 512 bytes */

struct pms_device
{
	struct video_device v;
	struct video_picture picture;
	int height;
	int width;
	struct semaphore lock;
};

struct i2c_info
{
	u8 slave;
	u8 sub;
	u8 data;
	u8 hits;
};

static int i2c_count 		= 0;
static struct i2c_info i2cinfo[64];

static int decoder 		= PHILIPS2;
static int standard 		= 0;	/* 0 - auto 1 - ntsc 2 - pal 3 - secam */

/*
 *	I/O ports and Shared Memory
 */
 
static int io_port		=	0x250;
static int data_port		=	0x251;
static int mem_base		=	0xC8000;
static void __iomem *mem;
static int video_nr             =       -1;

	

static inline void mvv_write(u8 index, u8 value)
{
	outw(index|(value<<8), io_port);
}

static inline u8 mvv_read(u8 index)
{
	outb(index, io_port);
	return inb(data_port);
}

static int pms_i2c_stat(u8 slave)
{
	int counter;
	int i;
	
	outb(0x28, io_port);
	
	counter=0;
	while((inb(data_port)&0x01)==0)
		if(counter++==256)
			break;

	while((inb(data_port)&0x01)!=0)
		if(counter++==256)
			break;
			
	outb(slave, io_port);
	
	counter=0;
	while((inb(data_port)&0x01)==0)
		if(counter++==256)
			break;

	while((inb(data_port)&0x01)!=0)
		if(counter++==256)
			break;
			
	for(i=0;i<12;i++)
	{
		char st=inb(data_port);
		if((st&2)!=0)
			return -1;
		if((st&1)==0)
			break;
	}
	outb(0x29, io_port);
	return inb(data_port);		
}

static int pms_i2c_write(u16 slave, u16 sub, u16 data)
{
	int skip=0;
	int count;
	int i;
	
	for(i=0;i<i2c_count;i++)
	{
		if((i2cinfo[i].slave==slave) &&
		   (i2cinfo[i].sub == sub))
		{
		   	if(i2cinfo[i].data==data)
		   		skip=1;
		   	i2cinfo[i].data=data;
		   	i=i2c_count+1;
		}
	}
	
	if(i==i2c_count && i2c_count<64)
	{
		i2cinfo[i2c_count].slave=slave;
		i2cinfo[i2c_count].sub=sub;
		i2cinfo[i2c_count].data=data;
		i2c_count++;
	}
	
	if(skip)
		return 0;
		
	mvv_write(0x29, sub);
	mvv_write(0x2A, data);
	mvv_write(0x28, slave);
	
	outb(0x28, io_port);
	
	count=0;
	while((inb(data_port)&1)==0)
		if(count>255)
			break;
	while((inb(data_port)&1)!=0)
		if(count>255)
			break;
			
	count=inb(data_port);
	
	if(count&2)
		return -1;
	return count;
}

static int pms_i2c_read(int slave, int sub)
{
	int i=0;
	for(i=0;i<i2c_count;i++)
	{
		if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub)
			return i2cinfo[i].data;
	}
	return 0;
}


static void pms_i2c_andor(int slave, int sub, int and, int or)
{
	u8 tmp;	
	
	tmp=pms_i2c_read(slave, sub);
	tmp = (tmp&and)|or;
	pms_i2c_write(slave, sub, tmp);
}

/*
 *	Control functions
 */
 

static void pms_videosource(short source)
{
	mvv_write(0x2E, source?0x31:0x30);
}

static void pms_hue(short hue)
{
	switch(decoder)
	{
		case MOTOROLA:
			pms_i2c_write(0x8A, 0x00, hue);
			break;
		case PHILIPS2:
			pms_i2c_write(0x8A, 0x07, hue);
			break;
		case PHILIPS1:
			pms_i2c_write(0x42, 0x07, hue);
			break;
	}
}

static void pms_colour(short colour)
{
	switch(decoder)
	{
		case MOTOROLA:
			pms_i2c_write(0x8A, 0x00, colour);
			break;
		case PHILIPS1:
			pms_i2c_write(0x42, 0x12, colour);
			break;
	}
}
 
 
static void pms_contrast(short contrast)
{
	switch(decoder)
	{
		case MOTOROLA:
			pms_i2c_write(0x8A, 0x00, contrast);
			break;
		case PHILIPS1:
			pms_i2c_write(0x42, 0x13, contrast);
			break;
	}
}

static void pms_brightness(short brightness)
{
	switch(decoder)
	{
		case MOTOROLA:
			pms_i2c_write(0x8A, 0x00, brightness);
			pms_i2c_write(0x8A, 0x00, brightness);
			pms_i2c_write(0x8A, 0x00, brightness);
			break;
		case PHILIPS1:
			pms_i2c_write(0x42, 0x19, brightness);
			break;
	}
}


static void pms_format(short format)
{
	int target;
	standard = format;
	
	if(decoder==PHILIPS1)
		target=0x42;
	else if(decoder==PHILIPS2)
		target=0x8A;
	else
		return;
				
	switch(format)
	{
		case 0:	/* Auto */
			pms_i2c_andor(target, 0x0D, 0xFE,0x00);
			pms_i2c_andor(target, 0x0F, 0x3F,0x80);
			break;
		case 1: /* NTSC */
			pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
			pms_i2c_andor(target, 0x0F, 0x3F, 0x40);
			break;
		case 2: /* PAL */
			pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
			pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
			break;
		case 3:	/* SECAM */
			pms_i2c_andor(target, 0x0D, 0xFE, 0x01);
			pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
			break;
	}
}

#ifdef FOR_FUTURE_EXPANSION

/*
 *	These features of the PMS card are not currently exposes. They
 *	could become a private v4l ioctl for PMSCONFIG or somesuch if 
 *	people need it. We also don't yet use the PMS interrupt.
 */

static void pms_hstart(short start)
{
	switch(decoder)
	{
		case PHILIPS1:
			pms_i2c_write(0x8A, 0x05, start);
			pms_i2c_write(0x8A, 0x18, start);
			break;
		case PHILIPS2:
			pms_i2c_write(0x42, 0x05, start);
			pms_i2c_write(0x42, 0x18, start);
			break;
	}
}

/*
 *	Bandpass filters
 */
 
static void pms_bandpass(short pass)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4);
}

static void pms_antisnow(short snow)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2);
}

static void pms_sharpness(short sharp)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03);
}

static void pms_chromaagc(short agc)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5);
}

static void pms_vertnoise(short noise)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x10, 0xFC, noise&3);
}

static void pms_forcecolour(short colour)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7);
}

static void pms_antigamma(short gamma)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7);
}

static void pms_prefilter(short filter)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6);
}

static void pms_hfilter(short filter)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5);
}

static void pms_vfilter(short filter)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5);
}

static void pms_killcolour(short colour)
{
	if(decoder==PHILIPS2)
	{
		pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3);
		pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3);
	}
	else if(decoder==PHILIPS1)
	{
		pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
		pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
	}
}

static void pms_chromagain(short chroma)
{
	if(decoder==PHILIPS2)
	{
		pms_i2c_write(0x8A, 0x11, chroma);
	}
	else if(decoder==PHILIPS1)
	{
		pms_i2c_write(0x42, 0x11, chroma);
	}
}


static void pms_spacialcompl(short data)
{
	mvv_write(0x3B, data);
}

static void pms_spacialcomph(short data)
{
	mvv_write(0x3A, data);
}

static void pms_vstart(short start)
{
	mvv_write(0x16, start);
	mvv_write(0x17, (start>>8)&0x01);
}

#endif

static void pms_secamcross(short cross)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5);
}


static void pms_swsense(short sense)
{
	if(decoder==PHILIPS2)
	{
		pms_i2c_write(0x8A, 0x0A, sense);
		pms_i2c_write(0x8A, 0x0B, sense);
	}
	else if(decoder==PHILIPS1)
	{
		pms_i2c_write(0x42, 0x0A, sense);
		pms_i2c_write(0x42, 0x0B, sense);
	}
}


static void pms_framerate(short frr)
{
	int fps=(standard==1)?30:25;
	if(frr==0)
		return;
	fps=fps/frr;
	mvv_write(0x14,0x80|fps);
	mvv_write(0x15,1);
}

static void pms_vert(u8 deciden, u8 decinum)
{
	mvv_write(0x1C, deciden);	/* Denominator */
	mvv_write(0x1D, decinum);	/* Numerator */
}

/*
 *	Turn 16bit ratios into best small ratio the chipset can grok
 */
 
static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
{
	/* Knock it down by /5 once */
	if(decinum%5==0)
	{
		deciden/=5;
		decinum/=5;
	}
	/*
	 *	3's
	 */
	while(decinum%3==0 && deciden%3==0)
	{
		deciden/=3;
		decinum/=3;
	}
	/*
	 *	2's
	 */
	while(decinum%2==0 && deciden%2==0)
	{
		decinum/=2;
		deciden/=2;
	}
	/*
	 *	Fudgyify
	 */
	while(deciden>32)
	{
		deciden/=2;
		decinum=(decinum+1)/2;
	}
	if(deciden==32)
		deciden--;
	pms_vert(deciden,decinum);
}

static void pms_horzdeci(short decinum, short deciden)
{
	if(decinum<=512)
	{
		if(decinum%5==0)
		{
			decinum/=5;
			deciden/=5;
		}
	}
	else
	{
		decinum=512;
		deciden=640;	/* 768 would be ideal */
	}
	
	while(((decinum|deciden)&1)==0)
	{
		decinum>>=1;
		deciden>>=1;
	}
	while(deciden>32)
	{
		deciden>>=1;
		decinum=(decinum+1)>>1;
	}
	if(deciden==32)
		deciden--;
		
	mvv_write(0x24, 0x80|deciden);
	mvv_write(0x25, decinum);
}

static void pms_resolution(short width, short height)
{
	int fg_height;
	
	fg_height=height;
	if(fg_height>280)
		fg_height=280;
		
	mvv_write(0x18, fg_height);
	mvv_write(0x19, fg_height>>8);
	
	if(standard==1)
	{
		mvv_write(0x1A, 0xFC);
		mvv_write(0x1B, 0x00);
		if(height>fg_height)
			pms_vertdeci(240,240);
		else
			pms_vertdeci(fg_height,240);
	}
	else
	{
		mvv_write(0x1A, 0x1A);
		mvv_write(0x1B, 0x01);
		if(fg_height>256)
			pms_vertdeci(270,270);
		else
			pms_vertdeci(fg_height, 270);
	}
	mvv_write(0x12,0);
	mvv_write(0x13, MVVMEMORYWIDTH);
	mvv_write(0x42, 0x00);
	mvv_write(0x43, 0x00);
	mvv_write(0x44, MVVMEMORYWIDTH);
	
	mvv_write(0x22, width+8);
	mvv_write(0x23, (width+8)>> 8);

	if(standard==1)
		pms_horzdeci(width,640);
	else
		pms_horzdeci(width+8, 768);

	mvv_write(0x30, mvv_read(0x30)&0xFE);
	mvv_write(0x08, mvv_read(0x08)|0x01);
	mvv_write(0x01, mvv_read(0x01)&0xFD);
	mvv_write(0x32, 0x00);
	mvv_write(0x33, MVVMEMORYWIDTH);
}


/*
 *	Set Input
 */
 
static void pms_vcrinput(short input)
{
	if(decoder==PHILIPS2)
		pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7);
	else if(decoder==PHILIPS1)
		pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7);
}


static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count)
{
	int y;
	int dw = 2*dev->width;

	char tmp[dw+32]; /* using a temp buffer is faster than direct  */
	int cnt = 0;
	int len=0;
	unsigned char r8 = 0x5;  /* value for reg8  */

	if (rgb555)
		r8 |= 0x20; /* else use untranslated rgb = 565 */
	mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */

/*	printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
  
	for (y = 0; y < dev->height; y++ ) 
	{
		writeb(0, mem);  /* synchronisiert neue Zeile */
		
		/*
		 *	This is in truth a fifo, be very careful as if you
		 *	forgot this odd things will occur 8)
		 */
		 
		memcpy_fromio(tmp, mem, dw+32); /* discard 16 word   */
		cnt -= dev->height;
		while (cnt <= 0) 
		{ 
			/*
			 *	Don't copy too far
			 */
			int dt=dw;
			if(dt+len>count)
				dt=count-len;
			cnt += dev->height;
			if (copy_to_user(buf, tmp+32, dt))
				return len ? len : -EFAULT;
			buf += dt;    
			len += dt;
		}
	}
	return len;
}


/*
 *	Video4linux interfacing
 */

static int pms_do_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, void *arg)
{
	struct video_device *dev = video_devdata(file);
	struct pms_device *pd=(struct pms_device *)dev;
	
	switch(cmd)
	{
		case VIDIOCGCAP:
		{
			struct video_capability *b = arg;
			strcpy(b->name, "Mediavision PMS");
			b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
			b->channels = 4;
			b->audios = 0;
			b->maxwidth = 640;
			b->maxheight = 480;
			b->minwidth = 16;
			b->minheight = 16;
			return 0;
		}
		case VIDIOCGCHAN:
		{
			struct video_channel *v = arg;
			if(v->channel<0 || v->channel>3)
				return -EINVAL;
			v->flags=0;
			v->tuners=1;
			/* Good question.. its composite or SVHS so.. */
			v->type = VIDEO_TYPE_CAMERA;
			switch(v->channel)
			{
				case 0:
					strcpy(v->name, "Composite");break;
				case 1:
					strcpy(v->name, "SVideo");break;
				case 2:
					strcpy(v->name, "Composite(VCR)");break;
				case 3:
					strcpy(v->name, "SVideo(VCR)");break;
			}
			return 0;
		}
		case VIDIOCSCHAN:
		{
			struct video_channel *v = arg;
			if(v->channel<0 || v->channel>3)
				return -EINVAL;
			down(&pd->lock);
			pms_videosource(v->channel&1);
			pms_vcrinput(v->channel>>1);
			up(&pd->lock);
			return 0;
		}
		case VIDIOCGTUNER:
		{
			struct video_tuner *v = arg;
			if(v->tuner)
				return -EINVAL;
			strcpy(v->name, "Format");
			v->rangelow=0;
			v->rangehigh=0;
			v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
			switch(standard)
			{
				case 0:
					v->mode = VIDEO_MODE_AUTO;
					break;
				case 1:
					v->mode = VIDEO_MODE_NTSC;
					break;
				case 2:
					v->mode = VIDEO_MODE_PAL;
					break;
				case 3:
					v->mode = VIDEO_MODE_SECAM;
					break;
			}
			return 0;
		}
		case VIDIOCSTUNER:
		{
			struct video_tuner *v = arg;
			if(v->tuner)
				return -EINVAL;
			down(&pd->lock);
			switch(v->mode)
			{
				case VIDEO_MODE_AUTO:
					pms_framerate(25);
					pms_secamcross(0);
					pms_format(0);
					break;
				case VIDEO_MODE_NTSC:
					pms_framerate(30);
					pms_secamcross(0);
					pms_format(1);
					break;
				case VIDEO_MODE_PAL:
					pms_framerate(25);
					pms_secamcross(0);
					pms_format(2);
					break;
				case VIDEO_MODE_SECAM:
					pms_framerate(25);
					pms_secamcross(1);
					pms_format(2);
					break;
				default:
					up(&pd->lock);
					return -EINVAL;
			}
			up(&pd->lock);
			return 0;
		}
		case VIDIOCGPICT:
		{
			struct video_picture *p = arg;
			*p = pd->picture;
			return 0;
		}
		case VIDIOCSPICT:
		{
			struct video_picture *p = arg;
			if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
			    ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
			    	return -EINVAL;
			pd->picture= *p;
			
			/*
			 *	Now load the card.
			 */

			down(&pd->lock);
			pms_brightness(p->brightness>>8);
			pms_hue(p->hue>>8);
			pms_colour(p->colour>>8);
			pms_contrast(p->contrast>>8);	
			up(&pd->lock);
			return 0;
		}
		case VIDIOCSWIN:
		{
			struct video_window *vw = arg;
			if(vw->flags)
				return -EINVAL;
			if(vw->clipcount)
				return -EINVAL;
			if(vw->height<16||vw->height>480)
				return -EINVAL;
			if(vw->width<16||vw->width>640)
				return -EINVAL;
			pd->width=vw->width;
			pd->height=vw->height;
			down(&pd->lock);
			pms_resolution(pd->width, pd->height);
			up(&pd->lock);			/* Ok we figured out what to use from our wide choice */
			return 0;
		}
		case VIDIOCGWIN:
		{
			struct video_window *vw = arg;
			memset(vw,0,sizeof(*vw));
			vw->width=pd->width;
			vw->height=pd->height;
			return 0;
		}
		case VIDIOCKEY:
			return 0;
		case VIDIOCCAPTURE:
		case VIDIOCGFBUF:
		case VIDIOCSFBUF:
		case VIDIOCGFREQ:
		case VIDIOCSFREQ:
		case VIDIOCGAUDIO:
		case VIDIOCSAUDIO:
			return -EINVAL;
		default:
			return -ENOIOCTLCMD;
	}
	return 0;
}

static int pms_ioctl(struct inode *inode, struct file *file,
		     unsigned int cmd, unsigned long arg)
{
	return video_usercopy(inode, file, cmd, arg, pms_do_ioctl);
}

static ssize_t pms_read(struct file *file, char __user *buf,
		    size_t count, loff_t *ppos)
{
	struct video_device *v = video_devdata(file);
	struct pms_device *pd=(struct pms_device *)v;
	int len;
	
	down(&pd->lock);
	len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
	up(&pd->lock);
	return len;
}

static struct file_operations pms_fops = {
	.owner		= THIS_MODULE,
	.open           = video_exclusive_open,
	.release        = video_exclusive_release,
	.ioctl          = pms_ioctl,
	.compat_ioctl	= v4l_compat_ioctl32,
	.read           = pms_read,
	.llseek         = no_llseek,
};

static struct video_device pms_template=
{
	.owner		= THIS_MODULE,
	.name		= "Mediavision PMS",
	.type		= VID_TYPE_CAPTURE,
	.hardware	= VID_HARDWARE_PMS,
	.fops           = &pms_fops,
};

static struct pms_device pms_device;


/*
 *	Probe for and initialise the Mediavision PMS
 */
 
static int init_mediavision(void)
{
	int id;
	int idec, decst;
	int i;
		
	unsigned char i2c_defs[]={
		0x4C,0x30,0x00,0xE8,
		0xB6,0xE2,0x00,0x00,
		0xFF,0xFF,0x00,0x00,
		0x00,0x00,0x78,0x98,
		0x00,0x00,0x00,0x00,
		0x34,0x0A,0xF4,0xCE,
		0xE4
	};

	mem = ioremap(mem_base, 0x800);
	if (!mem)
		return -ENOMEM;
	
	if (!request_region(0x9A01, 1, "Mediavision PMS config"))
	{
		printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
		iounmap(mem);
		return -EBUSY;
	}
	if (!request_region(io_port, 3, "Mediavision PMS"))
	{
		printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port);
		release_region(0x9A01, 1);
		iounmap(mem);
		return -EBUSY;
	}
	outb(0xB8, 0x9A01);		/* Unlock */
	outb(io_port>>4, 0x9A01);	/* Set IO port */
	
	
	id=mvv_read(3);
	decst=pms_i2c_stat(0x43);
	
	if(decst!=-1)
		idec=2;
	else if(pms_i2c_stat(0xb9)!=-1)
		idec=3;
	else if(pms_i2c_stat(0x8b)!=-1)
		idec=1;
	else 
		idec=0;

	printk(KERN_INFO "PMS type is %d\n", idec);
	if(idec == 0) {
		release_region(io_port, 3);
		release_region(0x9A01, 1);
		iounmap(mem);
		return -ENODEV;
	}

	/*
	 *	Ok we have a PMS of some sort
	 */
	
	mvv_write(0x04, mem_base>>12);	/* Set the memory area */
	
	/* Ok now load the defaults */
	
	for(i=0;i<0x19;i++)
	{
		if(i2c_defs[i]==0xFF)
			pms_i2c_andor(0x8A, i, 0x07,0x00);
		else
			pms_i2c_write(0x8A, i, i2c_defs[i]);
	}
	
	pms_i2c_write(0xB8,0x00,0x12);
	pms_i2c_write(0xB8,0x04,0x00);
	pms_i2c_write(0xB8,0x07,0x00);
	pms_i2c_write(0xB8,0x08,0x00);
	pms_i2c_write(0xB8,0x09,0xFF);
	pms_i2c_write(0xB8,0x0A,0x00);
	pms_i2c_write(0xB8,0x0B,0x10);
	pms_i2c_write(0xB8,0x10,0x03);
	
	mvv_write(0x01, 0x00);
	mvv_write(0x05, 0xA0);
	mvv_write(0x08, 0x25);
	mvv_write(0x09, 0x00);
	mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);	
	
	mvv_write(0x10, 0x02);
	mvv_write(0x1E, 0x0C);
	mvv_write(0x1F, 0x03);
	mvv_write(0x26, 0x06);
	
	mvv_write(0x2B, 0x00);
	mvv_write(0x2C, 0x20);
	mvv_write(0x2D, 0x00);
	mvv_write(0x2F, 0x70);
	mvv_write(0x32, 0x00);
	mvv_write(0x33, MVVMEMORYWIDTH);
	mvv_write(0x34, 0x00);
	mvv_write(0x35, 0x00);
	mvv_write(0x3A, 0x80);
	mvv_write(0x3B, 0x10);
	mvv_write(0x20, 0x00);
	mvv_write(0x21, 0x00);
	mvv_write(0x30, 0x22);
	return 0;
}

/*
 *	Initialization and module stuff
 */
 
static int __init init_pms_cards(void)
{
	printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
	
	data_port = io_port +1;
	
	if(init_mediavision())
	{
		printk(KERN_INFO "Board not found.\n");
		return -ENODEV;
	}
	memcpy(&pms_device, &pms_template, sizeof(pms_template));
	init_MUTEX(&pms_device.lock);
	pms_device.height=240;
	pms_device.width=320;
	pms_swsense(75);
	pms_resolution(320,240);
	return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
}

module_param(io_port, int, 0);
module_param(mem_base, int, 0);
module_param(video_nr, int, 0);
MODULE_LICENSE("GPL");


static void __exit shutdown_mediavision(void)
{
	release_region(io_port,3);
	release_region(0x9A01, 1);
}

static void __exit cleanup_pms_module(void)
{
	shutdown_mediavision();
	video_unregister_device((struct video_device *)&pms_device);
	iounmap(mem);
}

module_init(init_pms_cards);
module_exit(cleanup_pms_module);

