/*
 * 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[4] = {
	{
		.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,
	}, {
		.index		= 2,
		.name		= "Video",
		.type		= V4L2_INPUT_TYPE_CAMERA,
		.audioset	= 0,
		.tuner		= 0,
		.std		= V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
		.status		= 0,
	}, {
		.index		= 3,
		.name		= "Y/C",
		.type		= V4L2_INPUT_TYPE_CAMERA,
		.audioset	= 0,
		.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) {
		dprintk(1, "switching to analog TV:\n");
		adswitch = 1;
		source = SAA7146_HPS_SOURCE_PORT_B;
		sync = SAA7146_HPS_SYNC_PORT_B;
		memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);

		switch (av7110->current_input) {
		case 1:
			dprintk(1, "switching SAA7113 to Analog Tuner Input.\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)
			}
			if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
				dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
			break;
		case 2:
			dprintk(1, "switching SAA7113 to Video AV CVBS Input.\n");
			if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
				dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
			break;
		case 3:
			dprintk(1, "switching SAA7113 to Video AV Y/C Input.\n");
			if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
				dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
			break;
		default:
			dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input.\n");
		}
	} 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 >= 4)
				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 >= 4)
			return -EINVAL;

		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,
};

