/*
 * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
 *
 * Copyright (C) 1999-2002 Ralph  Metzler
 *                       & Marcus Metzler for convergence integrated media GmbH
 *
 * originally based on code by:
 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 *
 * the project's page is at http://www.linuxtv.org/dvb/
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
#include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h>

#include "av7110.h"
#include "av7110_hw.h"
#include "av7110_av.h"

int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
{
	u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
	struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };

	if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
		dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
		       av7110->dvb_adapter.num, reg, val);
		return -EIO;
	}
	return 0;
}

static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
{
	u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
	u8 msg2[2];
	struct i2c_msg msgs[2] = {
		{ .flags = 0,	     .addr = 0x40, .len = 3, .buf = msg1 },
		{ .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 }
	};

	if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
		dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
		       av7110->dvb_adapter.num, reg);
		return -EIO;
	}
	*val = (msg2[0] << 8) | msg2[1];
	return 0;
}

static struct v4l2_input inputs[2] = {
	{
		.index		= 0,
		.name		= "DVB",
		.type		= V4L2_INPUT_TYPE_CAMERA,
		.audioset	= 1,
		.tuner		= 0, /* ignored */
		.std		= V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
		.status		= 0,
	}, {
		.index		= 1,
		.name		= "Television",
		.type		= V4L2_INPUT_TYPE_TUNER,
		.audioset	= 2,
		.tuner		= 0,
		.std		= V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
		.status		= 0,
	}
};

static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
{
	u8 buf[] = { 0x00, reg, data };
	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };

	dprintk(4, "dev: %p\n", dev);

	if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
		return -1;
	return 0;
}

static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
{
        u8 buf [] = { reg, data };
        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };

	if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
		return -1;
	return 0;
}


static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
{
	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };

	dprintk(4, "dev: %p\n", dev);

	if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
		return -1;
	return 0;
}

static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
{
	u32 div;
	u8 config;
	u8 buf[4];

	dprintk(4, "freq: 0x%08x\n", freq);

	/* magic number: 614. tuning with the frequency given by v4l2
	   is always off by 614*62.5 = 38375 kHz...*/
	div = freq + 614;

	buf[0] = (div >> 8) & 0x7f;
	buf[1] = div & 0xff;
	buf[2] = 0x8e;

	if (freq < (u32) (16 * 168.25))
		config = 0xa0;
	else if (freq < (u32) (16 * 447.25))
		config = 0x90;
	else
		config = 0x30;
	config &= ~0x02;

	buf[3] = config;

	return tuner_write(dev, 0x61, buf);
}

static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
{
	u32 div;
	u8 data[4];

	div = (freq + 38900000 + 31250) / 62500;

	data[0] = (div >> 8) & 0x7f;
	data[1] = div & 0xff;
	data[2] = 0xce;

	if (freq < 45000000)
		return -EINVAL;
	else if (freq < 137000000)
		data[3] = 0x01;
	else if (freq < 403000000)
		data[3] = 0x02;
	else if (freq < 860000000)
		data[3] = 0x04;
	else
		return -EINVAL;

	stv0297_writereg(dev, 0x1C, 0x87, 0x78);
	stv0297_writereg(dev, 0x1C, 0x86, 0xc8);
	return tuner_write(dev, 0x63, data);
}



static struct saa7146_standard analog_standard[];
static struct saa7146_standard dvb_standard[];
static struct saa7146_standard standard[];

static struct v4l2_audio msp3400_v4l2_audio = {
	.index = 0,
	.name = "Television",
	.capability = V4L2_AUDCAP_STEREO
};

static int av7110_dvb_c_switch(struct saa7146_fh *fh)
{
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_vv *vv = dev->vv_data;
	struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
	u16 adswitch;
	int source, sync, err;

	dprintk(4, "%p\n", av7110);

	if ((vv->video_status & STATUS_OVERLAY) != 0) {
		vv->ov_suspend = vv->video_fh;
		err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
		if (err != 0) {
			dprintk(2, "suspending video failed\n");
			vv->ov_suspend = NULL;
		}
	}

	if (0 != av7110->current_input) {
		adswitch = 1;
		source = SAA7146_HPS_SOURCE_PORT_B;
		sync = SAA7146_HPS_SYNC_PORT_B;
		memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
		dprintk(1, "switching to analog TV\n");
		msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
		msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
		msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
		msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume

		if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
			if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
				dprintk(1, "setting band in demodulator failed.\n");
		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
		}
	} else {
		adswitch = 0;
		source = SAA7146_HPS_SOURCE_PORT_A;
		sync = SAA7146_HPS_SYNC_PORT_A;
		memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
		dprintk(1, "switching DVB mode\n");
		msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
		msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
		msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
		msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume

		if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
			if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
				dprintk(1, "setting band in demodulator failed.\n");
		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
		}
	}

	/* hmm, this does not do anything!? */
	if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
		dprintk(1, "ADSwitch error\n");

	saa7146_set_hps_source_and_sync(dev, source, sync);

	if (vv->ov_suspend != NULL) {
		saa7146_start_preview(vv->ov_suspend);
		vv->ov_suspend = NULL;
	}

	return 0;
}

static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
{
	struct saa7146_dev *dev = fh->dev;
	struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
	dprintk(4, "saa7146_dev: %p\n", dev);

	switch (cmd) {
	case VIDIOC_G_TUNER:
	{
		struct v4l2_tuner *t = arg;
		u16 stereo_det;
		s8 stereo;

		dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);

		if (!av7110->analog_tuner_flags || t->index != 0)
			return -EINVAL;

		memset(t, 0, sizeof(*t));
		strcpy(t->name, "Television");

		t->type = V4L2_TUNER_ANALOG_TV;
		t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
		t->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
		t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */
		/* FIXME: add the real signal strength here */
		t->signal = 0xffff;
		t->afc = 0;

		// FIXME: standard / stereo detection is still broken
		msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
		dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);

		msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
		dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
		stereo = (s8)(stereo_det >> 8);
		if (stereo > 0x10) {
			/* stereo */
			t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
			t->audmode = V4L2_TUNER_MODE_STEREO;
		}
		else if (stereo < -0x10) {
			/* bilingual*/
			t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
			t->audmode = V4L2_TUNER_MODE_LANG1;
		}
		else /* mono */
			t->rxsubchans = V4L2_TUNER_SUB_MONO;

		return 0;
	}
	case VIDIOC_S_TUNER:
	{
		struct v4l2_tuner *t = arg;
		u16 fm_matrix, src;
		dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);

		if (!av7110->analog_tuner_flags || av7110->current_input != 1)
			return -EINVAL;

		switch (t->audmode) {
		case V4L2_TUNER_MODE_STEREO:
			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
			fm_matrix = 0x3001; // stereo
			src = 0x0020;
			break;
		case V4L2_TUNER_MODE_LANG1:
			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
			fm_matrix = 0x3000; // mono
			src = 0x0000;
			break;
		case V4L2_TUNER_MODE_LANG2:
			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
			fm_matrix = 0x3000; // mono
			src = 0x0010;
			break;
		default: /* case V4L2_TUNER_MODE_MONO: {*/
			dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
			fm_matrix = 0x3000; // mono
			src = 0x0030;
			break;
		}
		msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
		msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
		msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
		msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
		return 0;
	}
	case VIDIOC_G_FREQUENCY:
	{
		struct v4l2_frequency *f = arg;

		dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);

		if (!av7110->analog_tuner_flags || av7110->current_input != 1)
			return -EINVAL;

		memset(f, 0, sizeof(*f));
		f->type = V4L2_TUNER_ANALOG_TV;
		f->frequency =	av7110->current_freq;
		return 0;
	}
	case VIDIOC_S_FREQUENCY:
	{
		struct v4l2_frequency *f = arg;

		dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);

		if (!av7110->analog_tuner_flags || av7110->current_input != 1)
			return -EINVAL;

		if (V4L2_TUNER_ANALOG_TV != f->type)
			return -EINVAL;

		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);

		/* tune in desired frequency */
		if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
			ves1820_set_tv_freq(dev, f->frequency);
		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
			stv0297_set_tv_freq(dev, f->frequency);
		}
		av7110->current_freq = f->frequency;

		msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
		msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
		return 0;
	}
	case VIDIOC_ENUMINPUT:
	{
		struct v4l2_input *i = arg;

		dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);

		if (av7110->analog_tuner_flags) {
			if (i->index < 0 || i->index >= 2)
				return -EINVAL;
		} else {
			if (i->index != 0)
				return -EINVAL;
		}

		memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));

		return 0;
	}
	case VIDIOC_G_INPUT:
	{
		int *input = (int *)arg;
		*input = av7110->current_input;
		dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
		return 0;
	}
	case VIDIOC_S_INPUT:
	{
		int input = *(int *)arg;

		dprintk(2, "VIDIOC_S_INPUT: %d\n", input);

		if (!av7110->analog_tuner_flags)
			return 0;

		if (input < 0 || input >= 2)
			return -EINVAL;

		/* FIXME: switch inputs here */
		av7110->current_input = input;
		return av7110_dvb_c_switch(fh);
	}
	case VIDIOC_G_AUDIO:
	{
		struct v4l2_audio *a = arg;

		dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
		if (a->index != 0)
			return -EINVAL;
		memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
		break;
	}
	case VIDIOC_S_AUDIO:
	{
		struct v4l2_audio *a = arg;
		dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
		break;
	}
	default:
		printk("no such ioctl\n");
		return -ENOIOCTLCMD;
	}
	return 0;
}


/****************************************************************************
 * INITIALIZATION
 ****************************************************************************/

static struct saa7146_extension_ioctls ioctls[] = {
	{ VIDIOC_ENUMINPUT,	SAA7146_EXCLUSIVE },
	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
	{ VIDIOC_G_FREQUENCY,	SAA7146_EXCLUSIVE },
	{ VIDIOC_S_FREQUENCY,	SAA7146_EXCLUSIVE },
	{ VIDIOC_G_TUNER,	SAA7146_EXCLUSIVE },
	{ VIDIOC_S_TUNER,	SAA7146_EXCLUSIVE },
	{ VIDIOC_G_AUDIO,	SAA7146_EXCLUSIVE },
	{ VIDIOC_S_AUDIO,	SAA7146_EXCLUSIVE },
	{ 0, 0 }
};

static u8 saa7113_init_regs[] = {
	0x02, 0xd0,
	0x03, 0x23,
	0x04, 0x00,
	0x05, 0x00,
	0x06, 0xe9,
	0x07, 0x0d,
	0x08, 0x98,
	0x09, 0x02,
	0x0a, 0x80,
	0x0b, 0x40,
	0x0c, 0x40,
	0x0d, 0x00,
	0x0e, 0x01,
	0x0f, 0x7c,
	0x10, 0x48,
	0x11, 0x0c,
	0x12, 0x8b,
	0x13, 0x1a,
	0x14, 0x00,
	0x15, 0x00,
	0x16, 0x00,
	0x17, 0x00,
	0x18, 0x00,
	0x19, 0x00,
	0x1a, 0x00,
	0x1b, 0x00,
	0x1c, 0x00,
	0x1d, 0x00,
	0x1e, 0x00,

	0x41, 0x77,
	0x42, 0x77,
	0x43, 0x77,
	0x44, 0x77,
	0x45, 0x77,
	0x46, 0x77,
	0x47, 0x77,
	0x48, 0x77,
	0x49, 0x77,
	0x4a, 0x77,
	0x4b, 0x77,
	0x4c, 0x77,
	0x4d, 0x77,
	0x4e, 0x77,
	0x4f, 0x77,
	0x50, 0x77,
	0x51, 0x77,
	0x52, 0x77,
	0x53, 0x77,
	0x54, 0x77,
	0x55, 0x77,
	0x56, 0x77,
	0x57, 0xff,

	0xff
};


static struct saa7146_ext_vv av7110_vv_data_st;
static struct saa7146_ext_vv av7110_vv_data_c;

int av7110_init_analog_module(struct av7110 *av7110)
{
	u16 version1, version2;

	if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1
	    || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
		return -ENODEV;

	printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
		av7110->dvb_adapter.num);
	av7110->adac_type = DVB_ADAC_MSP;
	msleep(100); // the probing above resets the msp...
	msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
	msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
	dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
		av7110->dvb_adapter.num, version1, version2);
	msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
	msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
	msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
	msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
	msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
	msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
	msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
	msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART

	if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
		INFO(("saa7113 not accessible.\n"));
	} else {
		u8 *i = saa7113_init_regs;

		if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
			/* Fujitsu/Siemens DVB-Cable */
			av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
		} else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
			/* Hauppauge/TT DVB-C premium */
			av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
		} else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
			/* Hauppauge/TT DVB-C premium */
			av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
		}

		/* setup for DVB by default */
		if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
			if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
				dprintk(1, "setting band in demodulator failed.\n");
		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
			saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
			saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
		}

		/* init the saa7113 */
		while (*i != 0xff) {
			if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
				dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num);
				break;
			}
			i += 2;
		}
		/* setup msp for analog sound: B/G Dual-FM */
		msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
		msp_writereg(av7110, MSP_WR_DEM, 0x0001,  3); // FIR1
		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
		msp_writereg(av7110, MSP_WR_DEM, 0x0005,  4); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005,  0); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005,  3); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
		msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
		msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
		msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
		msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
		msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
		msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
	}

	memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
	/* set dd1 stream a & b */
	saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
	saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
	saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));

	return 0;
}

int av7110_init_v4l(struct av7110 *av7110)
{
	struct saa7146_dev* dev = av7110->dev;
	int ret;

	/* special case DVB-C: these cards have an analog tuner
	   plus need some special handling, so we have separate
	   saa7146_ext_vv data for these... */
	if (av7110->analog_tuner_flags)
		ret = saa7146_vv_init(dev, &av7110_vv_data_c);
	else
		ret = saa7146_vv_init(dev, &av7110_vv_data_st);

	if (ret) {
		ERR(("cannot init capture device. skipping.\n"));
		return -ENODEV;
	}

	if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
		ERR(("cannot register capture device. skipping.\n"));
		saa7146_vv_release(dev);
		return -ENODEV;
	}
	if (av7110->analog_tuner_flags) {
		if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
			ERR(("cannot register vbi v4l2 device. skipping.\n"));
		} else {
			av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
		}
	}
	return 0;
}

int av7110_exit_v4l(struct av7110 *av7110)
{
	saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
	if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI)
		saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
	return 0;
}



/* FIXME: these values are experimental values that look better than the
   values from the latest "official" driver -- at least for me... (MiHu) */
static struct saa7146_standard standard[] = {
	{
		.name	= "PAL",	.id		= V4L2_STD_PAL_BG,
		.v_offset	= 0x15,	.v_field	= 288,
		.h_offset	= 0x48,	.h_pixels	= 708,
		.v_max_out	= 576,	.h_max_out	= 768,
	}, {
		.name	= "NTSC",	.id		= V4L2_STD_NTSC,
		.v_offset	= 0x10,	.v_field	= 244,
		.h_offset	= 0x40,	.h_pixels	= 708,
		.v_max_out	= 480,	.h_max_out	= 640,
	}
};

static struct saa7146_standard analog_standard[] = {
	{
		.name	= "PAL",	.id		= V4L2_STD_PAL_BG,
		.v_offset	= 0x1b,	.v_field	= 288,
		.h_offset	= 0x08,	.h_pixels	= 708,
		.v_max_out	= 576,	.h_max_out	= 768,
	}, {
		.name	= "NTSC",	.id		= V4L2_STD_NTSC,
		.v_offset	= 0x10,	.v_field	= 244,
		.h_offset	= 0x40,	.h_pixels	= 708,
		.v_max_out	= 480,	.h_max_out	= 640,
	}
};

static struct saa7146_standard dvb_standard[] = {
	{
		.name	= "PAL",	.id		= V4L2_STD_PAL_BG,
		.v_offset	= 0x14,	.v_field	= 288,
		.h_offset	= 0x48,	.h_pixels	= 708,
		.v_max_out	= 576,	.h_max_out	= 768,
	}, {
		.name	= "NTSC",	.id		= V4L2_STD_NTSC,
		.v_offset	= 0x10,	.v_field	= 244,
		.h_offset	= 0x40,	.h_pixels	= 708,
		.v_max_out	= 480,	.h_max_out	= 640,
	}
};

static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
{
	struct av7110 *av7110 = (struct av7110*) dev->ext_priv;

	if (std->id & V4L2_STD_PAL) {
		av7110->vidmode = VIDEO_MODE_PAL;
		av7110_set_vidmode(av7110, av7110->vidmode);
	}
	else if (std->id & V4L2_STD_NTSC) {
		av7110->vidmode = VIDEO_MODE_NTSC;
		av7110_set_vidmode(av7110, av7110->vidmode);
	}
	else
		return -1;

	return 0;
}


static struct saa7146_ext_vv av7110_vv_data_st = {
	.inputs		= 1,
	.audios		= 1,
	.capabilities	= 0,
	.flags		= 0,

	.stds		= &standard[0],
	.num_stds	= ARRAY_SIZE(standard),
	.std_callback	= &std_callback,

	.ioctls		= &ioctls[0],
	.ioctl		= av7110_ioctl,
};

static struct saa7146_ext_vv av7110_vv_data_c = {
	.inputs		= 1,
	.audios		= 1,
	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
	.flags		= SAA7146_USE_PORT_B_FOR_VBI,

	.stds		= &standard[0],
	.num_stds	= ARRAY_SIZE(standard),
	.std_callback	= &std_callback,

	.ioctls		= &ioctls[0],
	.ioctl		= av7110_ioctl,
};

