/*
 *	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 <linux/mutex.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 mutex 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;
			mutex_lock(&pd->lock);
			pms_videosource(v->channel&1);
			pms_vcrinput(v->channel>>1);
			mutex_unlock(&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;
			mutex_lock(&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:
					mutex_unlock(&pd->lock);
					return -EINVAL;
			}
			mutex_unlock(&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.
			 */

			mutex_lock(&pd->lock);
			pms_brightness(p->brightness>>8);
			pms_hue(p->hue>>8);
			pms_colour(p->colour>>8);
			pms_contrast(p->contrast>>8);
			mutex_unlock(&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;
			mutex_lock(&pd->lock);
			pms_resolution(pd->width, pd->height);
			mutex_unlock(&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;

	mutex_lock(&pd->lock);
	len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
	mutex_unlock(&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));
	mutex_init(&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);

