/*
    zr36120.c - Zoran 36120/36125 based framegrabbers

    Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/signal.h>
#include <linux/wait.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <linux/sched.h>
#include <linux/video_decoder.h>

#include <asm/uaccess.h>

#include "tuner.h"
#include "zr36120.h"
#include "zr36120_mem.h"

/* mark an required function argument unused - lintism */
#define	UNUSED(x)	(void)(x)

/* sensible default */
#ifndef CARDTYPE
#define CARDTYPE 0
#endif

/* Anybody who uses more than four? */
#define ZORAN_MAX 4

static unsigned int triton1=0;			/* triton1 chipset? */
static unsigned int cardtype[ZORAN_MAX]={ [ 0 ... ZORAN_MAX-1 ] = CARDTYPE };
static int video_nr = -1;
static int vbi_nr = -1;

static struct pci_device_id zr36120_pci_tbl[] = {
	{ PCI_VENDOR_ID_ZORAN,PCI_DEVICE_ID_ZORAN_36120,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, zr36120_pci_tbl);

MODULE_AUTHOR("Pauline Middelink <middelin@polyware.nl>");
MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber");
MODULE_LICENSE("GPL");

MODULE_PARM(triton1,"i");
MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i");
MODULE_PARM(video_nr,"i");
MODULE_PARM(vbi_nr,"i");

static int zoran_cards;
static struct zoran zorans[ZORAN_MAX];

/*
 * the meaning of each element can be found in zr36120.h
 * Determining the value of gpdir/gpval can be tricky. The
 * best way is to run the card under the original software
 * and read the values from the general purpose registers
 * 0x28 and 0x2C. How you do that is left as an exercise
 * to the impatient reader :)
 */
#define T 1	/* to separate the bools from the ints */
#define F 0
static struct tvcard tvcards[] = {
	/* reported working by <middelin@polyware.nl> */
/*0*/	{ "Trust Victor II",
	  2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
	/* reported working by <Michael.Paxton@aihw.gov.au>  */
/*1*/   { "Aitech WaveWatcher TV-PCI",
	  3, 0, T, F, T, T, 0x7F, 0x80, { 1, TUNER(3), SVHS(6) }, { 0 } },
	/* reported working by ? */
/*2*/	{ "Genius Video Wonder PCI Video Capture Card",
	  2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
	/* reported working by <Pascal.Gabriel@wanadoo.fr> */
/*3*/	{ "Guillemot Maxi-TV PCI",
	  2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
	/* reported working by "Craig Whitmore <lennon@igrin.co.nz> */
/*4*/	{ "Quadrant Buster",
	  3, 3, T, F, T, T, 0x7F, 0x80, { SVHS(1), TUNER(2), 3 }, { 1, 2, 3 } },
	/* a debug entry which has all inputs mapped */
/*5*/	{ "ZR36120 based framegrabber (all inputs enabled)",
	  6, 0, T, T, T, T, 0x7F, 0x80, { 1, 2, 3, 4, 5, 6 }, { 0 } }
};
#undef T
#undef F
#define NRTVCARDS (sizeof(tvcards)/sizeof(tvcards[0]))

#ifdef __sparc__
#define	ENDIANESS	0
#else
#define	ENDIANESS	ZORAN_VFEC_LE
#endif

static struct { const char name[8]; uint mode; uint bpp; } palette2fmt[] = {
/* n/a     */	{ "n/a",     0, 0 },
/* GREY    */	{ "GRAY",    0, 0 },
/* HI240   */	{ "HI240",   0, 0 },
/* RGB565  */	{ "RGB565",  ZORAN_VFEC_RGB_RGB565|ENDIANESS, 2 },
/* RGB24   */	{ "RGB24",   ZORAN_VFEC_RGB_RGB888|ENDIANESS|ZORAN_VFEC_PACK24, 3 },
/* RGB32   */	{ "RGB32",   ZORAN_VFEC_RGB_RGB888|ENDIANESS, 4 },
/* RGB555  */	{ "RGB555",  ZORAN_VFEC_RGB_RGB555|ENDIANESS, 2 },
/* YUV422  */	{ "YUV422",  ZORAN_VFEC_RGB_YUV422|ENDIANESS, 2 },
/* YUYV    */	{ "YUYV",    0, 0 },
/* UYVY    */	{ "UYVY",    0, 0 },
/* YUV420  */	{ "YUV420",  0, 0 },
/* YUV411  */	{ "YUV411",  0, 0 },
/* RAW     */	{ "RAW",     0, 0 },
/* YUV422P */	{ "YUV422P", 0, 0 },
/* YUV411P */	{ "YUV411P", 0, 0 }};
#define NRPALETTES (sizeof(palette2fmt)/sizeof(palette2fmt[0]))
#undef ENDIANESS

/* ----------------------------------------------------------------------- */
/* ZORAN chipset detector                                                 */
/* shamelessly stolen from bttv.c                                         */
/* Reason for beeing here: we need to detect if we are running on a        */
/* Triton based chipset, and if so, enable a certain bit                   */
/* ----------------------------------------------------------------------- */
static
void __init handle_chipset(void)
{
	/* Just in case some nut set this to something dangerous */
	if (triton1)
		triton1 = ZORAN_VDC_TRICOM;

	if (pci_pci_problems & PCIPCI_TRITON) {
		printk(KERN_INFO "zoran: Host bridge 82437FX Triton PIIX\n");
		triton1 = ZORAN_VDC_TRICOM;
	}
}

/* ----------------------------------------------------------------------- */
/* ZORAN functions							   */
/* ----------------------------------------------------------------------- */

static void zoran_set_geo(struct zoran* ztv, struct vidinfo* i);

#if 0 /* unused */
static
void zoran_dump(struct zoran *ztv)
{
	char	str[256];
	char	*p=str; /* shut up, gcc! */
	int	i;

	for (i=0; i<0x60; i+=4) {
		if ((i % 16) == 0) {
			if (i) printk("%s\n",str);
			p = str;
			p+= sprintf(str, KERN_DEBUG "       %04x: ",i);
		}
		p += sprintf(p, "%08x ",zrread(i));
	}
}
#endif /* unused */

static
void reap_states(struct zoran* ztv)
{
	/* count frames */
	ztv->fieldnr++;

	/*
	 * Are we busy at all?
	 * This depends on if there is a workqueue AND the
	 * videotransfer is enabled on the chip...
	 */
	if (ztv->workqueue && (zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
	{
		struct vidinfo* newitem;

		/* did we get a complete frame? */
		if (zrread(ZORAN_VSTR) & ZORAN_VSTR_GRAB)
			return;

DEBUG(printk(CARD_DEBUG "completed %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));

		/* we are done with this buffer, tell everyone */
		ztv->workqueue->status = FBUFFER_DONE;
		ztv->workqueue->fieldnr = ztv->fieldnr;
		/* not good, here for BTTV_FIELDNR reasons */
		ztv->lastfieldnr = ztv->fieldnr;

		switch (ztv->workqueue->kindof) {
		 case FBUFFER_GRAB:
			wake_up_interruptible(&ztv->grabq);
			break;
		 case FBUFFER_VBI:
			wake_up_interruptible(&ztv->vbiq);
			break;
		 default:
			printk(CARD_INFO "somebody killed the workqueue (kindof=%d)!\n",CARD,ztv->workqueue->kindof);
		}

		/* item completed, skip to next item in queue */
		write_lock(&ztv->lock);
		newitem = ztv->workqueue->next;
		ztv->workqueue->next = 0;	/* mark completed */
		ztv->workqueue = newitem;
		write_unlock(&ztv->lock);
	}

	/*
	 * ok, so it seems we have nothing in progress right now.
	 * Lets see if we can find some work.
	 */
	if (ztv->workqueue)
	{
		struct vidinfo* newitem;
again:

DEBUG(printk(CARD_DEBUG "starting %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));

		/* loadup the frame settings */
		read_lock(&ztv->lock);
		zoran_set_geo(ztv,ztv->workqueue);
		read_unlock(&ztv->lock);

		switch (ztv->workqueue->kindof) {
		 case FBUFFER_GRAB:
		 case FBUFFER_VBI:
			zrand(~ZORAN_OCR_OVLEN, ZORAN_OCR);
			zror(ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
			zror(ZORAN_VDC_VIDEN,ZORAN_VDC);

			/* start single-shot grab */
			zror(ZORAN_VSTR_GRAB, ZORAN_VSTR);
			break;
		 default:
			printk(CARD_INFO "what is this doing on the queue? (kindof=%d)\n",CARD,ztv->workqueue->kindof);
			write_lock(&ztv->lock);
			newitem = ztv->workqueue->next;
			ztv->workqueue->next = 0;
			ztv->workqueue = newitem;
			write_unlock(&ztv->lock);
			if (newitem)
				goto again;	/* yeah, sure.. */
		}
		/* bye for now */
		return;
	}
DEBUG(printk(CARD_DEBUG "nothing in queue\n",CARD));

	/*
	 * What? Even the workqueue is empty? Am i really here
	 * for nothing? Did i come all that way to... do nothing?
	 */

	/* do we need to overlay? */
	if (test_bit(STATE_OVERLAY, &ztv->state))
	{
		/* are we already overlaying? */
		if (!(zrread(ZORAN_OCR) & ZORAN_OCR_OVLEN) ||
		    !(zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
		{
DEBUG(printk(CARD_DEBUG "starting overlay\n",CARD));

			read_lock(&ztv->lock);
			zoran_set_geo(ztv,&ztv->overinfo);
			read_unlock(&ztv->lock);

			zror(ZORAN_OCR_OVLEN, ZORAN_OCR);
			zrand(~ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
			zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
		}

		/*
		 * leave overlaying on, but turn interrupts off.
		 */
		zrand(~ZORAN_ICR_EN,ZORAN_ICR);
		return;
	}

	/* do we have any VBI idle time processing? */
	if (test_bit(STATE_VBI, &ztv->state))
	{
		struct vidinfo* item;
		struct vidinfo* lastitem;

		/* protect the workqueue */
		write_lock(&ztv->lock);
		lastitem = ztv->workqueue;
		if (lastitem)
			while (lastitem->next) lastitem = lastitem->next;
		for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
			if (item->next == 0 && item->status == FBUFFER_FREE)
			{
DEBUG(printk(CARD_DEBUG "%p added to queue\n",CARD,item));
				item->status = FBUFFER_BUSY;
				if (!lastitem)
					ztv->workqueue = item;
				else 
					lastitem->next = item;
				lastitem = item;
			}
		write_unlock(&ztv->lock);
		if (ztv->workqueue)
			goto again;	/* hey, _i_ graduated :) */
	}

	/*
	 * Then we must be realy IDLE
	 */
DEBUG(printk(CARD_DEBUG "turning off\n",CARD));
	/* nothing further to do, disable DMA and further IRQs */
	zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
	zrand(~ZORAN_ICR_EN,ZORAN_ICR);
}

static
void zoran_irq(int irq, void *dev_id, struct pt_regs * regs)
{
	u32 stat,estat;
	int count = 0;
	struct zoran *ztv = dev_id;

	UNUSED(irq); UNUSED(regs);
	for (;;) {
		/* get/clear interrupt status bits */
		stat=zrread(ZORAN_ISR);
		estat=stat & zrread(ZORAN_ICR);
		if (!estat)
			return;
		zrwrite(estat,ZORAN_ISR);
		IDEBUG(printk(CARD_DEBUG "estat %08x\n",CARD,estat));
		IDEBUG(printk(CARD_DEBUG " stat %08x\n",CARD,stat));

		if (estat & ZORAN_ISR_CODE)
		{
			IDEBUG(printk(CARD_DEBUG "CodReplIRQ\n",CARD));
		}
		if (estat & ZORAN_ISR_GIRQ0)
		{
			IDEBUG(printk(CARD_DEBUG "GIRQ0\n",CARD));
			if (!ztv->card->usegirq1)
				reap_states(ztv);
		}
		if (estat & ZORAN_ISR_GIRQ1)
		{
			IDEBUG(printk(CARD_DEBUG "GIRQ1\n",CARD));
			if (ztv->card->usegirq1)
				reap_states(ztv);
		}

		count++;
		if (count > 10)
			printk(CARD_ERR "irq loop %d (%x)\n",CARD,count,estat);
		if (count > 20)
		{
			zrwrite(0, ZORAN_ICR);
			printk(CARD_ERR "IRQ lockup, cleared int mask\n",CARD);
		}
	}
}

static
int zoran_muxsel(struct zoran* ztv, int channel, int norm)
{
	int	rv;

	/* set the new video norm */
	rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &norm);
	if (rv)
		return rv;
	ztv->norm = norm;

	/* map the given channel to the cards decoder's channel */
	channel = ztv->card->video_mux[channel] & CHANNEL_MASK;

	/* set the new channel */
	rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &channel);
	return rv;
}

/* Tell the interrupt handler what to to.  */
static
void zoran_cap(struct zoran* ztv, int on)
{
DEBUG(printk(CARD_DEBUG "zoran_cap(%d) state=%x\n",CARD,on,ztv->state));

	if (on) {
		ztv->running = 1;

		/*
		 * turn interrupts (back) on. The DMA will be enabled
		 * inside the irq handler when it detects a restart.
		 */
		zror(ZORAN_ICR_EN,ZORAN_ICR);
	}
	else {
		/*
		 * turn both interrupts and DMA off
		 */
		zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
		zrand(~ZORAN_ICR_EN,ZORAN_ICR);

		ztv->running = 0;
	}
}

static ulong dmask[] = {
	0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8,
	0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80,
	0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800,
	0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000,
	0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000,
	0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000,
	0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000,
	0xF0000000, 0xE0000000, 0xC0000000, 0x80000000
};

static
void zoran_built_overlay(struct zoran* ztv, int count, struct video_clip *vcp)
{
	ulong*	mtop;
	int	ystep = (ztv->vidXshift + ztv->vidWidth+31)/32;	/* next DWORD */
	int	i;

DEBUG(printk(KERN_DEBUG "       overlay at %p, ystep=%d, clips=%d\n",ztv->overinfo.overlay,ystep,count));

	for (i=0; i<count; i++) {
		struct video_clip *vp = vcp+i;
		UNUSED(vp);
DEBUG(printk(KERN_DEBUG "       %d: clip(%d,%d,%d,%d)\n", i,vp->x,vp->y,vp->width,vp->height));
	}

	/*
	 * activate the visible portion of the screen
	 * Note we take some shortcuts here, because we
	 * know the width can never be < 32. (I.e. a DWORD)
	 * We also assume the overlay starts somewhere in
	 * the FIRST dword.
	 */
	{
		int start = ztv->vidXshift;
		ulong firstd = dmask[start];
		ulong lastd = ~dmask[(start + ztv->overinfo.w) & 31];
		mtop = ztv->overinfo.overlay;
		for (i=0; i<ztv->overinfo.h; i++) {
			int w = ztv->vidWidth;
			ulong* line = mtop;
			if (start & 31) {
				*line++ = firstd;
				w -= 32-(start&31);
			}
			memset(line, ~0, w/8);
			if (w & 31)
				line[w/32] = lastd;
			mtop += ystep;
		}
	}

	/* process clipping regions */
	for (i=0; i<count; i++) {
		int h;
		if (vcp->x < 0 || (uint)vcp->x > ztv->overinfo.w ||
		    vcp->y < 0 || vcp->y > ztv->overinfo.h ||
		    vcp->width < 0 || (uint)(vcp->x+vcp->width) > ztv->overinfo.w ||
		    vcp->height < 0 || (vcp->y+vcp->height) > ztv->overinfo.h)
		{
			DEBUG(printk(CARD_DEBUG "invalid clipzone (%d,%d,%d,%d) not in (0,0,%d,%d), adapting\n",CARD,vcp->x,vcp->y,vcp->width,vcp->height,ztv->overinfo.w,ztv->overinfo.h));
			if (vcp->x < 0) vcp->x = 0;
			if ((uint)vcp->x > ztv->overinfo.w) vcp->x = ztv->overinfo.w;
			if (vcp->y < 0) vcp->y = 0;
			if (vcp->y > ztv->overinfo.h) vcp->y = ztv->overinfo.h;
			if (vcp->width < 0) vcp->width = 0;
			if ((uint)(vcp->x+vcp->width) > ztv->overinfo.w) vcp->width = ztv->overinfo.w - vcp->x;
			if (vcp->height < 0) vcp->height = 0;
			if (vcp->y+vcp->height > ztv->overinfo.h) vcp->height = ztv->overinfo.h - vcp->y;
//			continue;
		}

		mtop = &ztv->overinfo.overlay[vcp->y*ystep];
		for (h=0; h<=vcp->height; h++) {
			int w;
			int x = ztv->vidXshift + vcp->x;
			for (w=0; w<=vcp->width; w++) {
				clear_bit(x&31, &mtop[x/32]);
				x++;
			}
			mtop += ystep;
		}
		++vcp;
	}

	mtop = ztv->overinfo.overlay;
	zrwrite(virt_to_bus(mtop), ZORAN_MTOP);
	zrwrite(virt_to_bus(mtop+ystep), ZORAN_MBOT);
	zraor((ztv->vidInterlace*ystep)<<0,~ZORAN_OCR_MASKSTRIDE,ZORAN_OCR);
}

struct tvnorm 
{
	u16 Wt, Wa, Ht, Ha, HStart, VStart;
};

static struct tvnorm tvnorms[] = {
	/* PAL-BDGHI */
/*	{ 864, 720, 625, 576, 131, 21 },*/
/*00*/	{ 864, 768, 625, 576, 81, 17 },
	/* NTSC */
/*01*/	{ 858, 720, 525, 480, 121, 10 },
	/* SECAM */
/*02*/	{ 864, 720, 625, 576, 131, 21 },
	/* BW50 */
/*03*/	{ 864, 720, 625, 576, 131, 21 },
	/* BW60 */
/*04*/	{ 858, 720, 525, 480, 121, 10 }
};
#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))

/*
 * Program the chip for a setup as described in the vidinfo struct.
 *
 * Side-effects: calculates vidXshift, vidInterlace,
 * vidHeight, vidWidth which are used in a later stage
 * to calculate the overlay mask
 *
 * This is an internal function, as such it does not check the
 * validity of the struct members... Spectaculair crashes will
 * follow /very/ quick when you're wrong and the chip right :)
 */
static
void zoran_set_geo(struct zoran* ztv, struct vidinfo* i)
{
	ulong	top, bot;
	int	stride;
	int	winWidth, winHeight;
	int	maxWidth, maxHeight, maxXOffset, maxYOffset;
	long	vfec;

DEBUG(printk(CARD_DEBUG "set_geo(rect=(%d,%d,%d,%d), norm=%d, format=%d, bpp=%d, bpl=%d, busadr=%lx, overlay=%p)\n",CARD,i->x,i->y,i->w,i->h,ztv->norm,i->format,i->bpp,i->bpl,i->busadr,i->overlay));

	/*
	 * make sure the DMA transfers are inhibited during our
	 * reprogramming of the chip
	 */
	zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);

	maxWidth = tvnorms[ztv->norm].Wa;
	maxHeight = tvnorms[ztv->norm].Ha/2;
	maxXOffset = tvnorms[ztv->norm].HStart;
	maxYOffset = tvnorms[ztv->norm].VStart;

	/* setup vfec register (keep ExtFl,TopField and VCLKPol settings) */
	vfec = (zrread(ZORAN_VFEC) & (ZORAN_VFEC_EXTFL|ZORAN_VFEC_TOPFIELD|ZORAN_VFEC_VCLKPOL)) |
	       (palette2fmt[i->format].mode & (ZORAN_VFEC_RGB|ZORAN_VFEC_ERRDIF|ZORAN_VFEC_LE|ZORAN_VFEC_PACK24));

	/*
	 * Set top, bottom ptrs. Since these must be DWORD aligned,
	 * possible adjust the x and the width of the window.
	 * so the endposition stay the same. The vidXshift will make
	 * sure we are not writing pixels before the requested x.
	 */
	ztv->vidXshift = 0;
	winWidth = i->w;
	if (winWidth < 0)
		winWidth = -winWidth;
	top = i->busadr + i->x*i->bpp + i->y*i->bpl;
	if (top & 3) {
		ztv->vidXshift = (top & 3) / i->bpp;
		winWidth += ztv->vidXshift;
		DEBUG(printk(KERN_DEBUG "       window-x shifted %d pixels left\n",ztv->vidXshift));
		top &= ~3;
	}

	/*
	 * bottom points to next frame but in interleaved mode we want
	 * to 'mix' the 2 frames to one capture, so 'bot' points to one
	 * (physical) line below the top line.
	 */
	bot = top + i->bpl;
	zrwrite(top,ZORAN_VTOP);
	zrwrite(bot,ZORAN_VBOT);

	/*
	 * Make sure the winWidth is DWORD aligned too,
	 * thereby automaticly making sure the stride to the
	 * next line is DWORD aligned too (as required by spec).
	 */
	if ((winWidth*i->bpp) & 3) {
DEBUG(printk(KERN_DEBUG "       window-width enlarged by %d pixels\n",(winWidth*i->bpp) & 3));
		winWidth += (winWidth*i->bpp) & 3;
	}

	/* determine the DispMode and stride */
	if (i->h >= 0 && i->h <= maxHeight) {
		/* single frame grab suffices for this height. */
		vfec |= ZORAN_VFEC_DISPMOD;
		ztv->vidInterlace = 0;
		stride = i->bpl - (winWidth*i->bpp);
		winHeight = i->h;
	}
	else {
		/* interleaving needed for this height */
		ztv->vidInterlace = 1;
		stride = i->bpl*2 - (winWidth*i->bpp);
		winHeight = i->h/2;
	}
	if (winHeight < 0)	/* can happen for VBI! */
		winHeight = -winHeight;

	/* safety net, sometimes bpl is too short??? */
	if (stride<0) {
DEBUG(printk(CARD_DEBUG "WARNING stride = %d\n",CARD,stride));
		stride = 0;
	}

	zraor((winHeight<<12)|(winWidth<<0),~(ZORAN_VDC_VIDWINHT|ZORAN_VDC_VIDWINWID), ZORAN_VDC);
	zraor(stride<<16,~ZORAN_VSTR_DISPSTRIDE,ZORAN_VSTR);

	/* remember vidWidth, vidHeight for overlay calculations */
	ztv->vidWidth = winWidth;
	ztv->vidHeight = winHeight;
DEBUG(printk(KERN_DEBUG "       top=%08lx, bottom=%08lx\n",top,bot));
DEBUG(printk(KERN_DEBUG "       winWidth=%d, winHeight=%d\n",winWidth,winHeight));
DEBUG(printk(KERN_DEBUG "       maxWidth=%d, maxHeight=%d\n",maxWidth,maxHeight));
DEBUG(printk(KERN_DEBUG "       stride=%d\n",stride));

	/*
	 * determine horizontal scales and crops
	 */
	if (i->w < 0) {
		int Hstart = 1;
		int Hend = Hstart + winWidth;
DEBUG(printk(KERN_DEBUG "       Y: scale=0, start=%d, end=%d\n", Hstart, Hend));
		zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
	}
	else {
		int Wa = maxWidth;
		int X = (winWidth*64+Wa-1)/Wa;
		int We = winWidth*64/X;
		int HorDcm = 64-X;
		int hcrop1 = 2*(Wa-We)/4;
		/*
		 * BUGFIX: Juha Nurmela <junki@qn-lpr2-165.quicknet.inet.fi> 
		 * found the solution to the color phase shift.
		 * See ChangeLog for the full explanation)
		 */
		int Hstart = (maxXOffset + hcrop1) | 1;
		int Hend = Hstart + We - 1;

DEBUG(printk(KERN_DEBUG "       X: scale=%d, start=%d, end=%d\n", HorDcm, Hstart, Hend));

		zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
		vfec |= HorDcm<<14;

		if (HorDcm<16)
			vfec |= ZORAN_VFEC_HFILTER_1; /* no filter */
		else if (HorDcm<32)
			vfec |= ZORAN_VFEC_HFILTER_3; /* 3 tap filter */
		else if (HorDcm<48)
			vfec |= ZORAN_VFEC_HFILTER_4; /* 4 tap filter */
		else	vfec |= ZORAN_VFEC_HFILTER_5; /* 5 tap filter */
	}

	/*
	 * Determine vertical scales and crops
	 *
	 * when height is negative, we want to read starting at line 0
	 * One day someone might need access to these lines...
	 */
	if (i->h < 0) {
		int Vstart = 0;
		int Vend = Vstart + winHeight;
DEBUG(printk(KERN_DEBUG "       Y: scale=0, start=%d, end=%d\n", Vstart, Vend));
		zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
	}
	else {
		int Ha = maxHeight;
		int Y = (winHeight*64+Ha-1)/Ha;
		int He = winHeight*64/Y;
		int VerDcm = 64-Y;
		int vcrop1 = 2*(Ha-He)/4;
		int Vstart = maxYOffset + vcrop1;
		int Vend = Vstart + He - 1;

DEBUG(printk(KERN_DEBUG "       Y: scale=%d, start=%d, end=%d\n", VerDcm, Vstart, Vend));
		zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
		vfec |= VerDcm<<8;
	}

DEBUG(printk(KERN_DEBUG "       F: format=%d(=%s)\n",i->format,palette2fmt[i->format].name));

	/* setup the requested format */
	zrwrite(vfec, ZORAN_VFEC);
}

static
void zoran_common_open(struct zoran* ztv, int flags)
{
	UNUSED(flags);

	/* already opened? */
	if (ztv->users++ != 0)
		return;

	/* unmute audio */
	/* /what/ audio? */

	ztv->state = 0;

	/* setup the encoder to the initial values */
	ztv->picture.colour=254<<7;
	ztv->picture.brightness=128<<8;
	ztv->picture.hue=128<<8;
	ztv->picture.contrast=216<<7;
	i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &ztv->picture);

	/* default to the composite input since my camera is there */
	zoran_muxsel(ztv, 0, VIDEO_MODE_PAL);
}

static
void zoran_common_close(struct zoran* ztv)
{
	if (--ztv->users != 0)
		return;

	/* mute audio */
	/* /what/ audio? */

	/* stop the chip */
	zoran_cap(ztv, 0);
}

/*
 * Open a zoran card. Right now the flags are just a hack
 */
static int zoran_open(struct video_device *dev, int flags)
{
	struct zoran *ztv = (struct zoran*)dev;
	struct vidinfo* item;
	char* pos;

	DEBUG(printk(CARD_DEBUG "open(dev,%d)\n",CARD,flags));

	/*********************************************
	 * We really should be doing lazy allocing...
	 *********************************************/
	/* allocate a frame buffer */
	if (!ztv->fbuffer)
		ztv->fbuffer = bmalloc(ZORAN_MAX_FBUFSIZE);
	if (!ztv->fbuffer) {
		/* could not get a buffer, bail out */
		return -ENOBUFS;
	}
	/* at this time we _always_ have a framebuffer */
	memset(ztv->fbuffer,0,ZORAN_MAX_FBUFSIZE);

	if (!ztv->overinfo.overlay)
		ztv->overinfo.overlay = kmalloc(1024*1024/8, GFP_KERNEL);
	if (!ztv->overinfo.overlay) {
		/* could not get an overlay buffer, bail out */
		bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
		return -ENOBUFS;
	}
	/* at this time we _always_ have a overlay */

	/* clear buffer status, and give them a DMAable address */
	pos = ztv->fbuffer;
	for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
	{
		item->status = FBUFFER_FREE;
		item->memadr = pos;
		item->busadr = virt_to_bus(pos);
		pos += ZORAN_MAX_FBUFFER;
	}

	/* do the common part of all open's */
	zoran_common_open(ztv, flags);

	return 0;
}

static
void zoran_close(struct video_device* dev)
{
	struct zoran *ztv = (struct zoran*)dev;

	DEBUG(printk(CARD_DEBUG "close(dev)\n",CARD));

	/* driver specific closure */
	clear_bit(STATE_OVERLAY, &ztv->state);

	zoran_common_close(ztv);

        /*
         *      This is sucky but right now I can't find a good way to
         *      be sure its safe to free the buffer. We wait 5-6 fields
         *      which is more than sufficient to be sure.
         */
        msleep(100);			/* Wait 1/10th of a second */

	/* free the allocated framebuffer */
	if (ztv->fbuffer)
		bfree( ztv->fbuffer, ZORAN_MAX_FBUFSIZE );
	ztv->fbuffer = 0;
	if (ztv->overinfo.overlay)
		kfree( ztv->overinfo.overlay );
	ztv->overinfo.overlay = 0;

}

/*
 * This read function could be used reentrant in a SMP situation.
 *
 * This is made possible by the spinlock which is kept till we
 * found and marked a buffer for our own use. The lock must
 * be released as soon as possible to prevent lock contention.
 */
static
long zoran_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
{
	struct zoran *ztv = (struct zoran*)dev;
	unsigned long max;
	struct vidinfo* unused = 0;
	struct vidinfo* done = 0;

	DEBUG(printk(CARD_DEBUG "zoran_read(%p,%ld,%d)\n",CARD,buf,count,nonblock));

	/* find ourself a free or completed buffer */
	for (;;) {
		struct vidinfo* item;

		write_lock_irq(&ztv->lock);
		for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
		{
			if (!unused && item->status == FBUFFER_FREE)
				unused = item;
			if (!done && item->status == FBUFFER_DONE)
				done = item;
		}
		if (done || unused)
			break;

		/* no more free buffers, wait for them. */
		write_unlock_irq(&ztv->lock);
		if (nonblock)
			return -EWOULDBLOCK;
		interruptible_sleep_on(&ztv->grabq);
		if (signal_pending(current))
			return -EINTR;
	}

	/* Do we have 'ready' data? */
	if (!done) {
		/* no? than this will take a while... */
		if (nonblock) {
			write_unlock_irq(&ztv->lock);
			return -EWOULDBLOCK;
		}

		/* mark the unused buffer as wanted */
		unused->status = FBUFFER_BUSY;
		unused->w = 320;
		unused->h = 240;
		unused->format = VIDEO_PALETTE_RGB24;
		unused->bpp = palette2fmt[unused->format].bpp;
		unused->bpl = unused->w * unused->bpp;
		unused->next = 0;
		{ /* add to tail of queue */
		  struct vidinfo* oldframe = ztv->workqueue;
		  if (!oldframe) ztv->workqueue = unused;
		  else {
		    while (oldframe->next) oldframe = oldframe->next;
		    oldframe->next = unused;
		  }
		}
		write_unlock_irq(&ztv->lock);

		/* tell the state machine we want it filled /NOW/ */
		zoran_cap(ztv, 1);

		/* wait till this buffer gets grabbed */
		wait_event_interruptible(ztv->grabq,
				(unused->status != FBUFFER_BUSY));
		/* see if a signal did it */
		if (signal_pending(current))
			return -EINTR;
		done = unused;
	}
	else
		write_unlock_irq(&ztv->lock);

	/* Yes! we got data! */
	max = done->bpl * done->h;
	if (count > max)
		count = max;
	if (copy_to_user((void*)buf, done->memadr, count))
		count = -EFAULT;

	/* keep the engine running */
	done->status = FBUFFER_FREE;
//	zoran_cap(ztv,1);

	/* tell listeners this buffer became free */
	wake_up_interruptible(&ztv->grabq);

	/* goodbye */
	DEBUG(printk(CARD_DEBUG "zoran_read() returns %lu\n",CARD,count));
	return count;
}

static
long zoran_write(struct video_device* dev, const char* buf, unsigned long count, int nonblock)
{
	struct zoran *ztv = (struct zoran *)dev;
	UNUSED(ztv); UNUSED(dev); UNUSED(buf); UNUSED(count); UNUSED(nonblock);
	DEBUG(printk(CARD_DEBUG "zoran_write\n",CARD));
	return -EINVAL;
}

static
unsigned int zoran_poll(struct video_device *dev, struct file *file, poll_table *wait)
{
	struct zoran *ztv = (struct zoran *)dev;
	struct vidinfo* item;
	unsigned int mask = 0;

	poll_wait(file, &ztv->grabq, wait);

	for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
		if (item->status == FBUFFER_DONE)
		{
			mask |= (POLLIN | POLLRDNORM);
			break;
		}

	DEBUG(printk(CARD_DEBUG "zoran_poll()=%x\n",CARD,mask));

	return mask;
}

/* append a new clipregion to the vector of video_clips */
static
void new_clip(struct video_window* vw, struct video_clip* vcp, int x, int y, int w, int h)
{
	vcp[vw->clipcount].x = x;
	vcp[vw->clipcount].y = y;
	vcp[vw->clipcount].width = w;
	vcp[vw->clipcount].height = h;
	vw->clipcount++;
}

static
int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
{
	struct zoran* ztv = (struct zoran*)dev;

	switch (cmd) {
	 case VIDIOCGCAP:
	 {
		struct video_capability c;
		DEBUG(printk(CARD_DEBUG "VIDIOCGCAP\n",CARD));

		strcpy(c.name,ztv->video_dev.name);
		c.type = VID_TYPE_CAPTURE|
			 VID_TYPE_OVERLAY|
			 VID_TYPE_CLIPPING|
			 VID_TYPE_FRAMERAM|
			 VID_TYPE_SCALES;
		if (ztv->have_tuner)
			c.type |= VID_TYPE_TUNER;
		if (ztv->have_decoder) {
			c.channels = ztv->card->video_inputs;
			c.audios = ztv->card->audio_inputs;
		} else
			/* no decoder -> no channels */
			c.channels = c.audios = 0;
		c.maxwidth = 768;
		c.maxheight = 576;
		c.minwidth = 32;
		c.minheight = 32;
		if (copy_to_user(arg,&c,sizeof(c)))
			return -EFAULT;
		break;
	 }

	 case VIDIOCGCHAN:
	 {
		struct video_channel v;
		int mux;
		if (copy_from_user(&v, arg,sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCGCHAN(%d)\n",CARD,v.channel));
		v.flags=VIDEO_VC_AUDIO
#ifdef VIDEO_VC_NORM
			|VIDEO_VC_NORM
#endif
			;
		v.tuners=0;
		v.type=VIDEO_TYPE_CAMERA;
#ifdef I_EXPECT_POSSIBLE_NORMS_IN_THE_API
		v.norm=VIDEO_MODE_PAL|
		       VIDEO_MODE_NTSC|
		       VIDEO_MODE_SECAM;
#else
		v.norm=VIDEO_MODE_PAL;
#endif
		/* too many inputs? no decoder -> no channels */
		if (!ztv->have_decoder || v.channel < 0 ||  v.channel >= ztv->card->video_inputs)
			return -EINVAL;

		/* now determine the name of the channel */
		mux = ztv->card->video_mux[v.channel];
		if (mux & IS_TUNER) {
			/* lets assume only one tuner, yes? */
			strcpy(v.name,"Television");
			v.type = VIDEO_TYPE_TV;
			if (ztv->have_tuner) {
				v.flags |= VIDEO_VC_TUNER;
				v.tuners = 1;
			}
		}
		else if (mux & IS_SVHS)
			sprintf(v.name,"S-Video-%d",v.channel);
		else
			sprintf(v.name,"CVBS-%d",v.channel);

		if (copy_to_user(arg,&v,sizeof(v)))
			return -EFAULT;
		break;
	 }
	 case VIDIOCSCHAN:
	 {	/* set video channel */
		struct video_channel v;
		if (copy_from_user(&v, arg,sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCSCHAN(%d,%d)\n",CARD,v.channel,v.norm));

		/* too many inputs? no decoder -> no channels */
		if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs || v.channel < 0)
			return -EINVAL;

		if (v.norm != VIDEO_MODE_PAL &&
		    v.norm != VIDEO_MODE_NTSC &&
		    v.norm != VIDEO_MODE_SECAM &&
		    v.norm != VIDEO_MODE_AUTO)
			return -EOPNOTSUPP;

		/* make it happen, nr1! */
		return zoran_muxsel(ztv,v.channel,v.norm);
	 }

	 case VIDIOCGTUNER:
	 {
		struct video_tuner v;
		if (copy_from_user(&v, arg,sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCGTUNER(%d)\n",CARD,v.tuner));

		/* Only no or one tuner for now */
		if (!ztv->have_tuner || v.tuner)
			return -EINVAL;

		strcpy(v.name,"Television");
		v.rangelow  = 0;
		v.rangehigh = ~0;
		v.flags     = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
		v.mode      = ztv->norm;
		v.signal    = 0xFFFF; /* unknown */

		if (copy_to_user(arg,&v,sizeof(v)))
			return -EFAULT;
		break;
	 }
	 case VIDIOCSTUNER:
	 {
		struct video_tuner v;
		if (copy_from_user(&v, arg, sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCSTUNER(%d,%d)\n",CARD,v.tuner,v.mode));

		/* Only no or one tuner for now */
		if (!ztv->have_tuner || v.tuner)
			return -EINVAL;

		/* and it only has certain valid modes */
		if( v.mode != VIDEO_MODE_PAL &&
		    v.mode != VIDEO_MODE_NTSC &&
		    v.mode != VIDEO_MODE_SECAM)
			return -EOPNOTSUPP;

		/* engage! */
		return zoran_muxsel(ztv,v.tuner,v.mode);
	 }

	 case VIDIOCGPICT:
	 {
		struct video_picture p = ztv->picture;
		DEBUG(printk(CARD_DEBUG "VIDIOCGPICT\n",CARD));
		p.depth = ztv->depth;
		switch (p.depth) {
		 case  8: p.palette=VIDEO_PALETTE_YUV422;
			  break;
		 case 15: p.palette=VIDEO_PALETTE_RGB555;
			  break;
		 case 16: p.palette=VIDEO_PALETTE_RGB565;
			  break;
		 case 24: p.palette=VIDEO_PALETTE_RGB24;
			  break;
		 case 32: p.palette=VIDEO_PALETTE_RGB32;
			  break;
		}
		if (copy_to_user(arg, &p, sizeof(p)))
			return -EFAULT;
		break;
	 }
	 case VIDIOCSPICT:
	 {
		struct video_picture p;
		if (copy_from_user(&p, arg,sizeof(p)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCSPICT(%d,%d,%d,%d,%d,%d,%d)\n",CARD,p.brightness,p.hue,p.colour,p.contrast,p.whiteness,p.depth,p.palette));

		/* depth must match with framebuffer */
		if (p.depth != ztv->depth)
			return -EINVAL;

		/* check if palette matches this bpp */
		if (p.palette>NRPALETTES ||
		    palette2fmt[p.palette].bpp != ztv->overinfo.bpp)
			return -EINVAL;

		write_lock_irq(&ztv->lock);
		ztv->overinfo.format = p.palette;
		ztv->picture = p;
		write_unlock_irq(&ztv->lock);

		/* tell the decoder */
		i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);
		break;
	 }

	 case VIDIOCGWIN:
	 {
		struct video_window vw;
		DEBUG(printk(CARD_DEBUG "VIDIOCGWIN\n",CARD));
		read_lock(&ztv->lock);
		vw.x      = ztv->overinfo.x;
		vw.y      = ztv->overinfo.y;
		vw.width  = ztv->overinfo.w;
		vw.height = ztv->overinfo.h;
		vw.chromakey= 0;
		vw.flags  = 0;
		if (ztv->vidInterlace)
			vw.flags|=VIDEO_WINDOW_INTERLACE;
		read_unlock(&ztv->lock);
		if (copy_to_user(arg,&vw,sizeof(vw)))
			return -EFAULT;
		break;
	 }
	 case VIDIOCSWIN:
	 {
		struct video_window vw;
		struct video_clip *vcp;
		int on;
		if (copy_from_user(&vw,arg,sizeof(vw)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCSWIN(%d,%d,%d,%d,%x,%d)\n",CARD,vw.x,vw.y,vw.width,vw.height,vw.flags,vw.clipcount));

		if (vw.flags)
			return -EINVAL;

		if (vw.clipcount <0 || vw.clipcount>256)
			return -EDOM;   /* Too many! */

		/*
		 *      Do any clips.
		 */
		vcp = vmalloc(sizeof(struct video_clip)*(vw.clipcount+4));
		if (vcp==NULL)
			return -ENOMEM;
		if (vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount)) {
			vfree(vcp);
			return -EFAULT;
		}

		on = ztv->running;
		if (on)
			zoran_cap(ztv, 0);

		/*
		 * strange, it seems xawtv sometimes calls us with 0
		 * width and/or height. Ignore these values
		 */
		if (vw.x == 0)
			vw.x = ztv->overinfo.x;
		if (vw.y == 0)
			vw.y = ztv->overinfo.y;

		/* by now we are committed to the new data... */
		write_lock_irq(&ztv->lock);
		ztv->overinfo.x = vw.x;
		ztv->overinfo.y = vw.y;
		ztv->overinfo.w = vw.width;
		ztv->overinfo.h = vw.height;
		write_unlock_irq(&ztv->lock);

		/*
		 *      Impose display clips
		 */
		if (vw.x+vw.width > ztv->swidth)
			new_clip(&vw, vcp, ztv->swidth-vw.x, 0, vw.width-1, vw.height-1);
		if (vw.y+vw.height > ztv->sheight)
			new_clip(&vw, vcp, 0, ztv->sheight-vw.y, vw.width-1, vw.height-1);

		/* built the requested clipping zones */
		zoran_set_geo(ztv, &ztv->overinfo);
		zoran_built_overlay(ztv, vw.clipcount, vcp);
		vfree(vcp);

		/* if we were on, restart the video engine */
		if (on)
			zoran_cap(ztv, 1);
		break;
	 }

	 case VIDIOCCAPTURE:
	 {
		int v;
		if (get_user(v, (int *)arg))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCCAPTURE(%d)\n",CARD,v));

		if (v==0) {
			clear_bit(STATE_OVERLAY, &ztv->state);
			zoran_cap(ztv, 1);
		}
		else {
			/* is VIDIOCSFBUF, VIDIOCSWIN done? */
			if (ztv->overinfo.busadr==0 || ztv->overinfo.w==0 || ztv->overinfo.h==0)
				return -EINVAL;

			set_bit(STATE_OVERLAY, &ztv->state);
			zoran_cap(ztv, 1);
		}
		break;
	 }

	 case VIDIOCGFBUF:
	 {
		struct video_buffer v;
		DEBUG(printk(CARD_DEBUG "VIDIOCGFBUF\n",CARD));
		read_lock(&ztv->lock);
		v.base   = (void *)ztv->overinfo.busadr;
		v.height = ztv->sheight;
		v.width  = ztv->swidth;
		v.depth  = ztv->depth;
		v.bytesperline = ztv->overinfo.bpl;
		read_unlock(&ztv->lock);
		if(copy_to_user(arg, &v,sizeof(v)))
			return -EFAULT;
		break;
	 }
	 case VIDIOCSFBUF:
	 {
		struct video_buffer v;
		if(!capable(CAP_SYS_ADMIN))
			return -EPERM;
		if (copy_from_user(&v, arg,sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCSFBUF(%p,%d,%d,%d,%d)\n",CARD,v.base, v.width,v.height,v.depth,v.bytesperline));

		if (v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
			return -EINVAL;
		if (v.bytesperline<1)
			return -EINVAL;
		if (ztv->running)
			return -EBUSY;
		write_lock_irq(&ztv->lock);
		ztv->overinfo.busadr  = (ulong)v.base;
		ztv->sheight      = v.height;
		ztv->swidth       = v.width;
		ztv->depth        = v.depth;		/* bits per pixel */
		ztv->overinfo.bpp = ((v.depth+1)&0x38)/8;/* bytes per pixel */
		ztv->overinfo.bpl = v.bytesperline;	/* bytes per line */
		write_unlock_irq(&ztv->lock);
		break;
	 }

	 case VIDIOCKEY:
	 {
		/* Will be handled higher up .. */
		break;
	 }

	 case VIDIOCSYNC:
	 {
		int i;
		if (get_user(i, (int *) arg))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d)\n",CARD,i));
		if (i<0 || i>ZORAN_MAX_FBUFFERS)
			return -EINVAL;
		switch (ztv->grabinfo[i].status) {
		 case FBUFFER_FREE:
			return -EINVAL;
		 case FBUFFER_BUSY:
			/* wait till this buffer gets grabbed */
			wait_event_interruptible(ztv->grabq,
					(ztv->grabinfo[i].status != FBUFFER_BUSY));
			/* see if a signal did it */
			if (signal_pending(current))
				return -EINTR;
			/* don't fall through; a DONE buffer is not UNUSED */
			break;
		 case FBUFFER_DONE:
			ztv->grabinfo[i].status = FBUFFER_FREE;
			/* tell ppl we have a spare buffer */
			wake_up_interruptible(&ztv->grabq);
			break;
		}
		DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d) returns\n",CARD,i));
		break;
	 }

	 case VIDIOCMCAPTURE:
	 {
		struct video_mmap vm;
		struct vidinfo* frame;
		if (copy_from_user(&vm,arg,sizeof(vm)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCMCAPTURE(%d,(%d,%d),%d)\n",CARD,vm.frame,vm.width,vm.height,vm.format));
		if (vm.frame<0 || vm.frame>ZORAN_MAX_FBUFFERS ||
		    vm.width<32 || vm.width>768 ||
		    vm.height<32 || vm.height>576 ||
		    vm.format>NRPALETTES ||
		    palette2fmt[vm.format].mode == 0)
			return -EINVAL;

		/* we are allowed to take over UNUSED and DONE buffers */
		frame = &ztv->grabinfo[vm.frame];
		if (frame->status == FBUFFER_BUSY)
			return -EBUSY;

		/* setup the other parameters if they are given */
		write_lock_irq(&ztv->lock);
		frame->w = vm.width;
		frame->h = vm.height;
		frame->format = vm.format;
		frame->bpp = palette2fmt[frame->format].bpp;
		frame->bpl = frame->w*frame->bpp;
		frame->status = FBUFFER_BUSY;
		frame->next = 0;
		{ /* add to tail of queue */
		  struct vidinfo* oldframe = ztv->workqueue;
		  if (!oldframe) ztv->workqueue = frame;
		  else {
		    while (oldframe->next) oldframe = oldframe->next;
		    oldframe->next = frame;
		  }
		}
		write_unlock_irq(&ztv->lock);
		zoran_cap(ztv, 1);
		break;
	 }

	 case VIDIOCGMBUF:
	 {
		struct video_mbuf mb;
		int i;
		DEBUG(printk(CARD_DEBUG "VIDIOCGMBUF\n",CARD));
		mb.size = ZORAN_MAX_FBUFSIZE;
		mb.frames = ZORAN_MAX_FBUFFERS;
		for (i=0; i<ZORAN_MAX_FBUFFERS; i++)
			mb.offsets[i] = i*ZORAN_MAX_FBUFFER;
		if(copy_to_user(arg, &mb,sizeof(mb)))
			return -EFAULT;
		break;
	 }

	 case VIDIOCGUNIT:
	 {
		struct video_unit vu;
		DEBUG(printk(CARD_DEBUG "VIDIOCGUNIT\n",CARD));
		vu.video = ztv->video_dev.minor;
		vu.vbi = ztv->vbi_dev.minor;
		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;
		break;
	 }

	 case VIDIOCGFREQ:
	 {
		unsigned long v = ztv->tuner_freq;
		if (copy_to_user(arg,&v,sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCGFREQ\n",CARD));
		break;
	 }
	 case VIDIOCSFREQ:
	 {
		unsigned long v;
		if (copy_from_user(&v, arg, sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCSFREQ\n",CARD));

		if (ztv->have_tuner) {
			int fixme = v;
			if (i2c_control_device(&(ztv->i2c), I2C_DRIVERID_TUNER, TUNER_SET_TVFREQ, &fixme) < 0)
				return -EAGAIN;
		}
		ztv->tuner_freq = v;
		break;
	 }

	 /* Why isn't this in the API?
	  * And why doesn't it take a buffer number?
	 case BTTV_FIELDNR: 
	 {
		unsigned long v = ztv->lastfieldnr;
		if (copy_to_user(arg,&v,sizeof(v)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "BTTV_FIELDNR\n",CARD));
		break;
	 }
	 */

	 default:
		return -ENOIOCTLCMD;
	}
	return 0;
}

static
int zoran_mmap(struct vm_area_struct *vma, struct video_device* dev, const char* adr, unsigned long size)
{
	struct zoran* ztv = (struct zoran*)dev;
	unsigned long start = (unsigned long)adr;
	unsigned long pos;

	DEBUG(printk(CARD_DEBUG "zoran_mmap(0x%p,%ld)\n",CARD,adr,size));

	/* sanity checks */
	if (size > ZORAN_MAX_FBUFSIZE || !ztv->fbuffer)
		return -EINVAL;

	/* start mapping the whole shabang to user memory */
	pos = (unsigned long)ztv->fbuffer;
	while (size>0) {
		unsigned long pfn = virt_to_phys((void*)pos) >> PAGE_SHIFT;
		if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
			return -EAGAIN;
		start += PAGE_SIZE;
		pos += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	return 0;
}

static struct video_device zr36120_template=
{
	.owner		= THIS_MODULE,
	.name		= "UNSET",
	.type		= VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
	.hardware	= VID_HARDWARE_ZR36120,
	.open		= zoran_open,
	.close		= zoran_close,
	.read		= zoran_read,
	.write		= zoran_write,
	.poll		= zoran_poll,
	.ioctl		= zoran_ioctl,
	.mmap		= zoran_mmap,
	.minor		= -1,
};

static
int vbi_open(struct video_device *dev, int flags)
{
	struct zoran *ztv = dev->priv;
	struct vidinfo* item;

	DEBUG(printk(CARD_DEBUG "vbi_open(dev,%d)\n",CARD,flags));

	/*
	 * During VBI device open, we continiously grab VBI-like
	 * data in the vbi buffer when we have nothing to do.
	 * Only when there is an explicit request for VBI data
	 * (read call) we /force/ a read.
	 */

	/* allocate buffers */
	for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
	{
		item->status = FBUFFER_FREE;

		/* alloc */
		if (!item->memadr) {
			item->memadr = bmalloc(ZORAN_VBI_BUFSIZE);
			if (!item->memadr) {
				/* could not get a buffer, bail out */
				while (item != ztv->readinfo) {
					item--;
					bfree(item->memadr, ZORAN_VBI_BUFSIZE);
					item->memadr = 0;
					item->busadr = 0;
				}
				return -ENOBUFS;
			}
		}

		/* determine the DMAable address */
		item->busadr = virt_to_bus(item->memadr);
	}

	/* do the common part of all open's */
	zoran_common_open(ztv, flags);

	set_bit(STATE_VBI, &ztv->state);
	/* start read-ahead */
	zoran_cap(ztv, 1);

	return 0;
}

static
void vbi_close(struct video_device *dev)
{
	struct zoran *ztv = dev->priv;
	struct vidinfo* item;

	DEBUG(printk(CARD_DEBUG "vbi_close(dev)\n",CARD));

	/* driver specific closure */
	clear_bit(STATE_VBI, &ztv->state);

	zoran_common_close(ztv);

        /*
         *      This is sucky but right now I can't find a good way to
         *      be sure its safe to free the buffer. We wait 5-6 fields
         *      which is more than sufficient to be sure.
         */
        msleep(100);			/* Wait 1/10th of a second */

	for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
	{
		if (item->memadr)
			bfree(item->memadr, ZORAN_VBI_BUFSIZE);
		item->memadr = 0;
	}

}

/*
 * This read function could be used reentrant in a SMP situation.
 *
 * This is made possible by the spinlock which is kept till we
 * found and marked a buffer for our own use. The lock must
 * be released as soon as possible to prevent lock contention.
 */
static
long vbi_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
{
	struct zoran *ztv = dev->priv;
	unsigned long max;
	struct vidinfo* unused = 0;
	struct vidinfo* done = 0;

	DEBUG(printk(CARD_DEBUG "vbi_read(0x%p,%ld,%d)\n",CARD,buf,count,nonblock));

	/* find ourself a free or completed buffer */
	for (;;) {
		struct vidinfo* item;

		write_lock_irq(&ztv->lock);
		for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++) {
			if (!unused && item->status == FBUFFER_FREE)
				unused = item;
			if (!done && item->status == FBUFFER_DONE)
				done = item;
		}
		if (done || unused)
			break;

		/* no more free buffers, wait for them. */
		write_unlock_irq(&ztv->lock);
		if (nonblock)
			return -EWOULDBLOCK;
		interruptible_sleep_on(&ztv->vbiq);
		if (signal_pending(current))
			return -EINTR;
	}

	/* Do we have 'ready' data? */
	if (!done) {
		/* no? than this will take a while... */
		if (nonblock) {
			write_unlock_irq(&ztv->lock);
			return -EWOULDBLOCK;
		}
		
		/* mark the unused buffer as wanted */
		unused->status = FBUFFER_BUSY;
		unused->next = 0;
		{ /* add to tail of queue */
		  struct vidinfo* oldframe = ztv->workqueue;
		  if (!oldframe) ztv->workqueue = unused;
		  else {
		    while (oldframe->next) oldframe = oldframe->next;
		    oldframe->next = unused;
		  }
		}
		write_unlock_irq(&ztv->lock);

		/* tell the state machine we want it filled /NOW/ */
		zoran_cap(ztv, 1);

		/* wait till this buffer gets grabbed */
		wait_event_interruptible(ztv->vbiq,
				(unused->status != FBUFFER_BUSY));
		/* see if a signal did it */
		if (signal_pending(current))
			return -EINTR;
		done = unused;
	}
	else
		write_unlock_irq(&ztv->lock);

	/* Yes! we got data! */
	max = done->bpl * -done->h;
	if (count > max)
		count = max;

	/* check if the user gave us enough room to write the data */
	if (!access_ok(VERIFY_WRITE, buf, count)) {
		count = -EFAULT;
		goto out;
	}

	/*
	 * Now transform/strip the data from YUV to Y-only
	 * NB. Assume the Y is in the LSB of the YUV data.
	 */
	{
	unsigned char* optr = buf;
	unsigned char* eptr = buf+count;

	/* are we beeing accessed from an old driver? */
	if (count == 2*19*2048) {
		/*
		 * Extreme HACK, old VBI programs expect 2048 points
		 * of data, and we only got 864 orso. Double each 
		 * datapoint and clear the rest of the line.
		 * This way we have appear to have a
		 * sample_frequency of 29.5 Mc.
		 */
		int x,y;
		unsigned char* iptr = done->memadr+1;
		for (y=done->h; optr<eptr && y<0; y++)
		{
			/* copy to doubled data to userland */
			for (x=0; optr+1<eptr && x<-done->w; x++)
			{
				unsigned char a = iptr[x*2];
				__put_user(a, optr++);
				__put_user(a, optr++);
			}
			/* and clear the rest of the line */
			for (x*=2; optr<eptr && x<done->bpl; x++)
				__put_user(0, optr++);
			/* next line */
			iptr += done->bpl;
		}
	}
	else {
		/*
		 * Other (probably newer) programs asked
		 * us what geometry we are using, and are
		 * reading the correct size.
		 */
		int x,y;
		unsigned char* iptr = done->memadr+1;
		for (y=done->h; optr<eptr && y<0; y++)
		{
			/* copy to doubled data to userland */
			for (x=0; optr<eptr && x<-done->w; x++)
				__put_user(iptr[x*2], optr++);
			/* and clear the rest of the line */
			for (;optr<eptr && x<done->bpl; x++)
				__put_user(0, optr++);
			/* next line */
			iptr += done->bpl;
		}
	}

	/* API compliance:
	 * place the framenumber (half fieldnr) in the last long
	 */
	__put_user(done->fieldnr/2, ((ulong*)eptr)[-1]);
	}

	/* keep the engine running */
	done->status = FBUFFER_FREE;
	zoran_cap(ztv, 1);

	/* tell listeners this buffer just became free */
	wake_up_interruptible(&ztv->vbiq);

	/* goodbye */
out:
	DEBUG(printk(CARD_DEBUG "vbi_read() returns %lu\n",CARD,count));
	return count;
}

static
unsigned int vbi_poll(struct video_device *dev, struct file *file, poll_table *wait)
{
	struct zoran *ztv = dev->priv;
	struct vidinfo* item;
	unsigned int mask = 0;

	poll_wait(file, &ztv->vbiq, wait);

	for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
		if (item->status == FBUFFER_DONE)
		{
			mask |= (POLLIN | POLLRDNORM);
			break;
		}

	DEBUG(printk(CARD_DEBUG "vbi_poll()=%x\n",CARD,mask));

	return mask;
}

static
int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
{
	struct zoran* ztv = dev->priv;

	switch (cmd) {
	 case VIDIOCGVBIFMT:
	 {
		struct vbi_format f;
		DEBUG(printk(CARD_DEBUG "VIDIOCGVBIINFO\n",CARD));
		f.sampling_rate = 14750000UL;
		f.samples_per_line = -ztv->readinfo[0].w;
		f.sample_format = VIDEO_PALETTE_RAW;
		f.start[0] = f.start[1] = ztv->readinfo[0].y;
		f.start[1] += 312;
		f.count[0] = f.count[1] = -ztv->readinfo[0].h;
		f.flags = VBI_INTERLACED;
		if (copy_to_user(arg,&f,sizeof(f)))
			return -EFAULT;
		break;
	 }
	 case VIDIOCSVBIFMT:
	 {
		struct vbi_format f;
		int i;
		if (copy_from_user(&f, arg,sizeof(f)))
			return -EFAULT;
		DEBUG(printk(CARD_DEBUG "VIDIOCSVBIINFO(%d,%d,%d,%d,%d,%d,%d,%x)\n",CARD,f.sampling_rate,f.samples_per_line,f.sample_format,f.start[0],f.start[1],f.count[0],f.count[1],f.flags));

		/* lots of parameters are fixed... (PAL) */
		if (f.sampling_rate != 14750000UL ||
		    f.samples_per_line > 864 ||
		    f.sample_format != VIDEO_PALETTE_RAW ||
		    f.start[0] < 0 ||
		    f.start[0] != f.start[1]-312 ||
		    f.count[0] != f.count[1] ||
		    f.start[0]+f.count[0] >= 288 ||
		    f.flags != VBI_INTERLACED)
			return -EINVAL;

		write_lock_irq(&ztv->lock);
		ztv->readinfo[0].y = f.start[0];
		ztv->readinfo[0].w = -f.samples_per_line;
		ztv->readinfo[0].h = -f.count[0];
		ztv->readinfo[0].bpl = f.samples_per_line*ztv->readinfo[0].bpp;
		for (i=1; i<ZORAN_VBI_BUFFERS; i++)
			ztv->readinfo[i] = ztv->readinfo[i];
		write_unlock_irq(&ztv->lock);
		break;
	 }
	 default:
		return -ENOIOCTLCMD;
	}
	return 0;
}

static struct video_device vbi_template=
{
	.owner		= THIS_MODULE,
	.name		= "UNSET",
	.type		= VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
	.hardware	= VID_HARDWARE_ZR36120,
	.open		= vbi_open,
	.close		= vbi_close,
	.read		= vbi_read,
	.write		= zoran_write,
	.poll		= vbi_poll,
	.ioctl		= vbi_ioctl,
	.minor		= -1,
};

/*
 *      Scan for a Zoran chip, request the irq and map the io memory
 */
static
int __init find_zoran(void)
{
	int result;
	struct zoran *ztv;
	struct pci_dev *dev = NULL;
	unsigned char revision;
	int zoran_num=0;

	while ((dev = pci_find_device(PCI_VENDOR_ID_ZORAN,PCI_DEVICE_ID_ZORAN_36120, dev)))
	{
		/* Ok, a ZR36120/ZR36125 found! */
		ztv = &zorans[zoran_num];
		ztv->dev = dev;

		if (pci_enable_device(dev))
			return -EIO;

		pci_read_config_byte(dev, PCI_CLASS_REVISION, &revision);
		printk(KERN_INFO "zoran: Zoran %x (rev %d) ",
			dev->device, revision);
		printk("bus: %d, devfn: %d, irq: %d, ",
			dev->bus->number, dev->devfn, dev->irq);
		printk("memory: 0x%08lx.\n", ztv->zoran_adr);

		ztv->zoran_mem = ioremap(ztv->zoran_adr, 0x1000);
		DEBUG(printk(KERN_DEBUG "zoran: mapped-memory at 0x%p\n",ztv->zoran_mem));

		result = request_irq(dev->irq, zoran_irq,
			SA_SHIRQ|SA_INTERRUPT,"zoran", ztv);
		if (result==-EINVAL)
		{
			iounmap(ztv->zoran_mem);
			printk(KERN_ERR "zoran: Bad irq number or handler\n");
			return -EINVAL;
		}
		if (result==-EBUSY)
			printk(KERN_ERR "zoran: IRQ %d busy, change your PnP config in BIOS\n",dev->irq);
		if (result < 0) {
			iounmap(ztv->zoran_mem);
			return result;
		}
		/* Enable bus-mastering */
		pci_set_master(dev);

		zoran_num++;
	}
	if(zoran_num)
		printk(KERN_INFO "zoran: %d Zoran card(s) found.\n",zoran_num);
	return zoran_num;
}

static
int __init init_zoran(int card)
{
	struct zoran *ztv = &zorans[card];
	int	i;

	/* if the given cardtype valid? */
	if (cardtype[card]>=NRTVCARDS) {
		printk(KERN_INFO "invalid cardtype(%d) detected\n",cardtype[card]);
		return -1;
	}

	/* reset the zoran */
	zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
	udelay(10);
	zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
	udelay(10);

	/* zoran chip specific details */
	ztv->card = tvcards+cardtype[card];	/* point to the selected card */
	ztv->norm = 0;				/* PAL */
	ztv->tuner_freq = 0;

	/* videocard details */
	ztv->swidth = 800;
	ztv->sheight = 600;
	ztv->depth = 16;

	/* State details */
	ztv->fbuffer = 0;
	ztv->overinfo.kindof = FBUFFER_OVERLAY;
	ztv->overinfo.status = FBUFFER_FREE;
	ztv->overinfo.x = 0;
	ztv->overinfo.y = 0;
	ztv->overinfo.w = 768; /* 640 */
	ztv->overinfo.h = 576; /* 480 */
	ztv->overinfo.format = VIDEO_PALETTE_RGB565;
	ztv->overinfo.bpp = palette2fmt[ztv->overinfo.format].bpp;
	ztv->overinfo.bpl = ztv->overinfo.bpp*ztv->swidth;
	ztv->overinfo.busadr = 0;
	ztv->overinfo.memadr = 0;
	ztv->overinfo.overlay = 0;
	for (i=0; i<ZORAN_MAX_FBUFFERS; i++) {
		ztv->grabinfo[i] = ztv->overinfo;
		ztv->grabinfo[i].kindof = FBUFFER_GRAB;
	}
	init_waitqueue_head(&ztv->grabq);

	/* VBI details */
	ztv->readinfo[0] = ztv->overinfo;
	ztv->readinfo[0].kindof = FBUFFER_VBI;
	ztv->readinfo[0].w = -864;
	ztv->readinfo[0].h = -38;
	ztv->readinfo[0].format = VIDEO_PALETTE_YUV422;
	ztv->readinfo[0].bpp = palette2fmt[ztv->readinfo[0].format].bpp;
	ztv->readinfo[0].bpl = 1024*ztv->readinfo[0].bpp;
	for (i=1; i<ZORAN_VBI_BUFFERS; i++)
		ztv->readinfo[i] = ztv->readinfo[0];
	init_waitqueue_head(&ztv->vbiq);

	/* maintenance data */
	ztv->have_decoder = 0;
	ztv->have_tuner = 0;
	ztv->tuner_type = 0;
	ztv->running = 0;
	ztv->users = 0;
	rwlock_init(&ztv->lock);
	ztv->workqueue = 0;
	ztv->fieldnr = 0;
	ztv->lastfieldnr = 0;

	if (triton1)
		zrand(~ZORAN_VDC_TRICOM, ZORAN_VDC);

	/* external FL determines TOP frame */
	zror(ZORAN_VFEC_EXTFL, ZORAN_VFEC); 

	/* set HSpol */
	if (ztv->card->hsync_pos)
		zrwrite(ZORAN_VFEH_HSPOL, ZORAN_VFEH);
	/* set VSpol */
	if (ztv->card->vsync_pos)
		zrwrite(ZORAN_VFEV_VSPOL, ZORAN_VFEV);

	/* Set the proper General Purpuse register bits */
	/* implicit: no softreset, 0 waitstates */
	zrwrite(ZORAN_PCI_SOFTRESET|(ztv->card->gpdir<<0),ZORAN_PCI);
	/* implicit: 3 duration and recovery PCI clocks on guest 0-3 */
	zrwrite(ztv->card->gpval<<24,ZORAN_GUEST);

	/* clear interrupt status */
	zrwrite(~0, ZORAN_ISR);

	/*
	 * i2c template
	 */
	ztv->i2c = zoran_i2c_bus_template;
	sprintf(ztv->i2c.name,"zoran-%d",card);
	ztv->i2c.data = ztv;

	/*
	 * Now add the template and register the device unit
	 */
	ztv->video_dev = zr36120_template;
	strcpy(ztv->video_dev.name, ztv->i2c.name);
	ztv->video_dev.priv = ztv;
	if (video_register_device(&ztv->video_dev, VFL_TYPE_GRABBER, video_nr) < 0)
		return -1;

	ztv->vbi_dev = vbi_template;
	strcpy(ztv->vbi_dev.name, ztv->i2c.name);
	ztv->vbi_dev.priv = ztv;
	if (video_register_device(&ztv->vbi_dev, VFL_TYPE_VBI, vbi_nr) < 0) {
		video_unregister_device(&ztv->video_dev);
		return -1;
	}
	i2c_register_bus(&ztv->i2c);

	/* set interrupt mask - the PIN enable will be set later */
	zrwrite(ZORAN_ICR_GIRQ0|ZORAN_ICR_GIRQ1|ZORAN_ICR_CODE, ZORAN_ICR);

	printk(KERN_INFO "%s: installed %s\n",ztv->i2c.name,ztv->card->name);
	return 0;
}

static
void release_zoran(int max)
{
	struct zoran *ztv;
	int i;

	for (i=0;i<max; i++) 
	{
		ztv = &zorans[i];

		/* turn off all capturing, DMA and IRQs */
		/* reset the zoran */
		zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
		udelay(10);
		zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
		udelay(10);

		/* first disable interrupts before unmapping the memory! */
		zrwrite(0, ZORAN_ICR);
		zrwrite(0xffffffffUL,ZORAN_ISR);

		/* free it */
		free_irq(ztv->dev->irq,ztv);
 
    		/* unregister i2c_bus */
		i2c_unregister_bus((&ztv->i2c));

		/* unmap and free memory */
		if (ztv->zoran_mem)
			iounmap(ztv->zoran_mem);

		video_unregister_device(&ztv->video_dev);
		video_unregister_device(&ztv->vbi_dev);
	}
}

void __exit zr36120_exit(void)
{
	release_zoran(zoran_cards);
}

int __init zr36120_init(void)
{
	int	card;
 
	handle_chipset();
	zoran_cards = find_zoran();
	if (zoran_cards<0)
		/* no cards found, no need for a driver */
		return -EIO;

	/* initialize Zorans */
	for (card=0; card<zoran_cards; card++) {
		if (init_zoran(card)<0) {
			/* only release the zorans we have registered */
			release_zoran(card);
			return -EIO;
		} 
	}
	return 0;
}

module_init(zr36120_init);
module_exit(zr36120_exit);
