/*
    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_param(triton1, uint, 0);
module_param_array(cardtype, uint, NULL, 0);
module_param(video_nr, int, 0);
module_param(vbi_nr, int, 0);

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 */
	bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
	ztv->fbuffer = 0;
	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,
	.compat_ioctl	= v4l_compat_ioctl32,
	.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,
			IRQF_SHARED|IRQF_DISABLED,"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);
