/*
 *
 * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
 *
 * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
 *
 * Portions Copyright (c) 2001 Matrox Graphics Inc.
 *
 * Version: 1.65 2002/08/14
 *
 * See matroxfb_base.c for contributors.
 *
 */

#include "matroxfb_maven.h"
#include "matroxfb_misc.h"
#include "matroxfb_DAC1064.h"
#include <linux/i2c.h>
#include <linux/matroxfb.h>
#include <asm/div64.h>
#include <asm/uaccess.h>

#define MAVEN_I2CID	(0x1B)

#define MGATVO_B	1
#define MGATVO_C	2

static const struct maven_gamma {
  unsigned char reg83;
  unsigned char reg84;
  unsigned char reg85;
  unsigned char reg86;
  unsigned char reg87;
  unsigned char reg88;
  unsigned char reg89;
  unsigned char reg8a;
  unsigned char reg8b;
} maven_gamma[] = {
  { 131, 57, 223, 15, 117, 212, 251, 91, 156},
  { 133, 61, 128, 63, 180, 147, 195, 100, 180},
  { 131, 19, 63, 31, 50, 66, 171, 64, 176},
  { 0, 0, 0, 31, 16, 16, 16, 100, 200},
  { 8, 23, 47, 73, 147, 244, 220, 80, 195},
  { 22, 43, 64, 80, 147, 115, 58, 85, 168},
  { 34, 60, 80, 214, 147, 212, 188, 85, 167},
  { 45, 77, 96, 216, 147, 99, 91, 85, 159},
  { 56, 76, 112, 107, 147, 212, 148, 64, 144},
  { 65, 91, 128, 137, 147, 196, 17, 69, 148},
  { 72, 104, 136, 138, 147, 180, 245, 73, 147},
  { 87, 116, 143, 126, 16, 83, 229, 77, 144},
  { 95, 119, 152, 254, 244, 83, 221, 77, 151},
  { 100, 129, 159, 156, 244, 148, 197, 77, 160},
  { 105, 141, 167, 247, 244, 132, 181, 84, 166},
  { 105, 147, 168, 247, 244, 245, 181, 90, 170},
  { 120, 153, 175, 248, 212, 229, 165, 90, 180},
  { 119, 156, 176, 248, 244, 229, 84, 74, 160},
  { 119, 158, 183, 248, 244, 229, 149, 78, 165}
};

/* Definition of the various controls */
struct mctl {
	struct v4l2_queryctrl desc;
	size_t control;
};

#define BLMIN	0x0FF
#define WLMAX	0x3FF

static const struct mctl maven_controls[] =
{	{ { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER,
	  "brightness",
	  0, WLMAX - BLMIN, 1, 379 - BLMIN, 
	  0,
	}, offsetof(struct matrox_fb_info, altout.tvo_params.brightness) },
	{ { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER,
	  "contrast",
	  0, 1023, 1, 127,
	  0,
	}, offsetof(struct matrox_fb_info, altout.tvo_params.contrast) },
	{ { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER,
	  "saturation",
	  0, 255, 1, 155,
	  0,
	}, offsetof(struct matrox_fb_info, altout.tvo_params.saturation) },
	{ { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER,
	  "hue",
	  0, 255, 1, 0,
	  0,
	}, offsetof(struct matrox_fb_info, altout.tvo_params.hue) },
	{ { V4L2_CID_GAMMA, V4L2_CTRL_TYPE_INTEGER,
	  "gamma",
	  0, sizeof(maven_gamma)/sizeof(maven_gamma[0])-1, 1, 3,
	  0,
	}, offsetof(struct matrox_fb_info, altout.tvo_params.gamma) },
	{ { MATROXFB_CID_TESTOUT, V4L2_CTRL_TYPE_BOOLEAN,
	  "test output",
	  0, 1, 1, 0, 
	  0,
	}, offsetof(struct matrox_fb_info, altout.tvo_params.testout) },
	{ { MATROXFB_CID_DEFLICKER, V4L2_CTRL_TYPE_INTEGER,
	  "deflicker mode",
	  0, 2, 1, 0,
	  0,
	}, offsetof(struct matrox_fb_info, altout.tvo_params.deflicker) },

};

#define MAVCTRLS (sizeof(maven_controls)/sizeof(maven_controls[0]))

/* Return: positive number: id found
           -EINVAL:         id not found, return failure
	   -ENOENT:         id not found, create fake disabled control */
static int get_ctrl_id(__u32 v4l2_id) {
	int i;

	for (i = 0; i < MAVCTRLS; i++) {
		if (v4l2_id < maven_controls[i].desc.id) {
			if (maven_controls[i].desc.id == 0x08000000) {
				return -EINVAL;
			}
			return -ENOENT;
		}
		if (v4l2_id == maven_controls[i].desc.id) {
			return i;
		}
	}
	return -EINVAL;
}

struct maven_data {
	struct matrox_fb_info*		primary_head;
	struct i2c_client*		client;
	int				version;
};

static int* get_ctrl_ptr(struct maven_data* md, int idx) {
	return (int*)((char*)(md->primary_head) + maven_controls[idx].control);
}

static int maven_get_reg(struct i2c_client* c, char reg) {
	char dst;
	struct i2c_msg msgs[] = {{ c->addr, I2C_M_REV_DIR_ADDR, sizeof(reg), &reg },
				 { c->addr, I2C_M_RD | I2C_M_NOSTART, sizeof(dst), &dst }};
	s32 err;

	err = i2c_transfer(c->adapter, msgs, 2);
	if (err < 0)
		printk(KERN_INFO "ReadReg(%d) failed\n", reg);
	return dst & 0xFF;
}

static int maven_set_reg(struct i2c_client* c, int reg, int val) {
	s32 err;

	err = i2c_smbus_write_byte_data(c, reg, val);
	if (err)
		printk(KERN_INFO "WriteReg(%d) failed\n", reg);
	return err;
}

static int maven_set_reg_pair(struct i2c_client* c, int reg, int val) {
	s32 err;

	err = i2c_smbus_write_word_data(c, reg, val);
	if (err)
		printk(KERN_INFO "WriteRegPair(%d) failed\n", reg);
	return err;
}

static const struct matrox_pll_features maven_pll = {
	50000,
	27000,
	4, 127,
	2, 31,
	3
};

struct matrox_pll_features2 {
	unsigned int	vco_freq_min;
	unsigned int	vco_freq_max;
	unsigned int	feed_div_min;
	unsigned int	feed_div_max;
	unsigned int	in_div_min;
	unsigned int	in_div_max;
	unsigned int	post_shift_max;
};

struct matrox_pll_ctl {
	unsigned int	ref_freq;
	unsigned int	den;
};

static const struct matrox_pll_features2 maven1000_pll = {
	 50000000,
	300000000,
	 5, 128,
	 3,  32,
	 3
};

static const struct matrox_pll_ctl maven_PAL = {
	540000,
	    50
};

static const struct matrox_pll_ctl maven_NTSC = {
	450450,	/* 27027000/60 == 27000000/59.94005994 */
	    60
};

static int matroxfb_PLL_mavenclock(const struct matrox_pll_features2* pll,
		const struct matrox_pll_ctl* ctl,
		unsigned int htotal, unsigned int vtotal,
		unsigned int* in, unsigned int* feed, unsigned int* post,
		unsigned int* h2) {
	unsigned int besth2 = 0;
	unsigned int fxtal = ctl->ref_freq;
	unsigned int fmin = pll->vco_freq_min / ctl->den;
	unsigned int fwant;
	unsigned int p;
	unsigned int scrlen;
	unsigned int fmax;

	DBG(__FUNCTION__)

	scrlen = htotal * (vtotal - 1);
	fwant = htotal * vtotal;
	fmax = pll->vco_freq_max / ctl->den;

	dprintk(KERN_DEBUG "want: %u, xtal: %u, h: %u, v: %u, fmax: %u\n",
		fwant, fxtal, htotal, vtotal, fmax);
	for (p = 1; p <= pll->post_shift_max; p++) {
		if (fwant * 2 > fmax)
			break;
		fwant *= 2;
	}
	if (fwant > fmax)
		return 0;
	for (; p-- > 0; fwant >>= 1) {
		unsigned int m;

		if (fwant < fmin) break;
		for (m = pll->in_div_min; m <= pll->in_div_max; m++) {
			unsigned int n;
			unsigned int dvd;
			unsigned int ln;

			n = (fwant * m) / fxtal;
			if (n < pll->feed_div_min)
				continue;
			if (n > pll->feed_div_max)
				break;

			ln = fxtal * n;
			dvd = m << p;

			if (ln % dvd)
				continue;
			ln = ln / dvd;

			if (ln < scrlen + 2)
				continue;
			ln = ln - scrlen;
			if (ln > htotal)
				continue;
			dprintk(KERN_DEBUG "Match: %u / %u / %u / %u\n", n, m, p, ln);
			if (ln > besth2) {
				dprintk(KERN_DEBUG "Better...\n");
				*h2 = besth2 = ln;
				*post = p;
				*in = m;
				*feed = n;
			}
		}
	}
	if (besth2 < 2)
		return 0;
	dprintk(KERN_ERR "clk: %02X %02X %02X %d %d\n", *in, *feed, *post, fxtal, fwant);
	return fxtal * (*feed) / (*in) * ctl->den;
}

static unsigned int matroxfb_mavenclock(const struct matrox_pll_ctl* ctl,
		unsigned int htotal, unsigned int vtotal,
		unsigned int* in, unsigned int* feed, unsigned int* post,
		unsigned int* htotal2) {
	unsigned int fvco;
	unsigned int p;

	fvco = matroxfb_PLL_mavenclock(&maven1000_pll, ctl, htotal, vtotal, in, feed, &p, htotal2);
	if (!fvco)
		return -EINVAL;
	p = (1 << p) - 1;
	if (fvco <= 100000000)
		;
	else if (fvco <= 140000000)
		p |= 0x08;
	else if (fvco <= 180000000)
		p |= 0x10;
	else
		p |= 0x18;
	*post = p;
	return 0;
}

static void DAC1064_calcclock(unsigned int freq, unsigned int fmax,
		unsigned int* in, unsigned int* feed, unsigned int* post) {
	unsigned int fvco;
	unsigned int p;

	fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p);
	p = (1 << p) - 1;
	if (fvco <= 100000)
		;
	else if (fvco <= 140000)
		p |= 0x08;
	else if (fvco <= 180000)
		p |= 0x10;
	else
		p |= 0x18;
	*post = p;
	return;
}

static unsigned char maven_compute_deflicker (const struct maven_data* md) {
	unsigned char df;
	
	df = (md->version == MGATVO_B?0x40:0x00);
	switch (md->primary_head->altout.tvo_params.deflicker) {
		case 0:
/*			df |= 0x00; */
			break;
		case 1:
			df |= 0xB1;
			break;
		case 2:
			df |= 0xA2;
			break;
	}
	return df;
}

static void maven_compute_bwlevel (const struct maven_data* md,
				   int *bl, int *wl) {
	const int b = md->primary_head->altout.tvo_params.brightness + BLMIN;
	const int c = md->primary_head->altout.tvo_params.contrast;

	*bl = max(b - c, BLMIN);
	*wl = min(b + c, WLMAX);
}

static const struct maven_gamma* maven_compute_gamma (const struct maven_data* md) {
 	return maven_gamma + md->primary_head->altout.tvo_params.gamma;
}


static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* data) {
	static struct mavenregs palregs = { {
		0x2A, 0x09, 0x8A, 0xCB,	/* 00: chroma subcarrier */
		0x00,
		0x00,	/* ? not written */
		0x00,	/* modified by code (F9 written...) */
		0x00,	/* ? not written */
		0x7E,	/* 08 */
		0x44,	/* 09 */
		0x9C,	/* 0A */
		0x2E,	/* 0B */
		0x21,	/* 0C */
		0x00,	/* ? not written */
		0x3F, 0x03, /* 0E-0F */
		0x3F, 0x03, /* 10-11 */
		0x1A,	/* 12 */
		0x2A,	/* 13 */
		0x1C, 0x3D, 0x14, /* 14-16 */
		0x9C, 0x01, /* 17-18 */
		0x00,	/* 19 */
		0xFE,	/* 1A */
		0x7E,	/* 1B */
		0x60,	/* 1C */
		0x05,	/* 1D */
		0x89, 0x03, /* 1E-1F */
		0x72,	/* 20 */
		0x07,	/* 21 */
		0x72,	/* 22 */
		0x00,	/* 23 */
		0x00,	/* 24 */
		0x00,	/* 25 */
		0x08,	/* 26 */
		0x04,	/* 27 */
		0x00,	/* 28 */
		0x1A,	/* 29 */
		0x55, 0x01, /* 2A-2B */
		0x26,	/* 2C */
		0x07, 0x7E, /* 2D-2E */
		0x02, 0x54, /* 2F-30 */
		0xB0, 0x00, /* 31-32 */
		0x14,	/* 33 */
		0x49,	/* 34 */
		0x00,	/* 35 written multiple times */
		0x00,	/* 36 not written */
		0xA3,	/* 37 */
		0xC8,	/* 38 */
		0x22,	/* 39 */
		0x02,	/* 3A */
		0x22,	/* 3B */
		0x3F, 0x03, /* 3C-3D */
		0x00,	/* 3E written multiple times */
		0x00,	/* 3F not written */
	}, MATROXFB_OUTPUT_MODE_PAL, 625, 50 };
	static struct mavenregs ntscregs = { {
		0x21, 0xF0, 0x7C, 0x1F,	/* 00: chroma subcarrier */
		0x00,
		0x00,	/* ? not written */
		0x00,	/* modified by code (F9 written...) */
		0x00,	/* ? not written */
		0x7E,	/* 08 */
		0x43,	/* 09 */
		0x7E,	/* 0A */
		0x3D,	/* 0B */
		0x00,	/* 0C */
		0x00,	/* ? not written */
		0x41, 0x00, /* 0E-0F */
		0x3C, 0x00, /* 10-11 */
		0x17,	/* 12 */
		0x21,	/* 13 */
		0x1B, 0x1B, 0x24, /* 14-16 */
		0x83, 0x01, /* 17-18 */
		0x00,	/* 19 */
		0x0F,	/* 1A */
		0x0F,	/* 1B */
		0x60,	/* 1C */
		0x05,	/* 1D */
		0x89, 0x02, /* 1E-1F */
		0x5F,	/* 20 */
		0x04,	/* 21 */
		0x5F,	/* 22 */
		0x01,	/* 23 */
		0x02,	/* 24 */
		0x00,	/* 25 */
		0x0A,	/* 26 */
		0x05,	/* 27 */
		0x00,	/* 28 */
		0x10,	/* 29 */
		0xFF, 0x03, /* 2A-2B */
		0x24,	/* 2C */
		0x0F, 0x78, /* 2D-2E */
		0x00, 0x00, /* 2F-30 */
		0xB2, 0x04, /* 31-32 */
		0x14,	/* 33 */
		0x02,	/* 34 */
		0x00,	/* 35 written multiple times */
		0x00,	/* 36 not written */
		0xA3,	/* 37 */
		0xC8,	/* 38 */
		0x15,	/* 39 */
		0x05,	/* 3A */
		0x3B,	/* 3B */
		0x3C, 0x00, /* 3C-3D */
		0x00,	/* 3E written multiple times */
		0x00,	/* never written */
	}, MATROXFB_OUTPUT_MODE_NTSC, 525, 60 };
	MINFO_FROM(md->primary_head);

	if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_PAL)
		*data = palregs;
	else
		*data = ntscregs;

	/* Set deflicker */
	data->regs[0x93] = maven_compute_deflicker(md);
 
	/* set gamma */
	{
		const struct maven_gamma* g;
		g = maven_compute_gamma(md);
		data->regs[0x83] = g->reg83;
		data->regs[0x84] = g->reg84;
		data->regs[0x85] = g->reg85;
		data->regs[0x86] = g->reg86;
		data->regs[0x87] = g->reg87;
		data->regs[0x88] = g->reg88;
		data->regs[0x89] = g->reg89;
		data->regs[0x8A] = g->reg8a;
		data->regs[0x8B] = g->reg8b;
	}
 
	/* Set contrast / brightness */
	{
		int bl, wl;
		maven_compute_bwlevel (md, &bl, &wl);
		data->regs[0x0e] = bl >> 2;
		data->regs[0x0f] = bl & 3;
		data->regs[0x1e] = wl >> 2;
		data->regs[0x1f] = wl & 3;
	}

	/* Set saturation */
	{
		data->regs[0x20] =
		data->regs[0x22] = ACCESS_FBINFO(altout.tvo_params.saturation);
	}
 
	/* Set HUE */
	data->regs[0x25] = ACCESS_FBINFO(altout.tvo_params.hue);
	return;
}

#define LR(x) maven_set_reg(c, (x), m->regs[(x)])
#define LRP(x) maven_set_reg_pair(c, (x), m->regs[(x)] | (m->regs[(x)+1] << 8))
static void maven_init_TV(struct i2c_client* c, const struct mavenregs* m) {
	int val;


	maven_set_reg(c, 0x3E, 0x01);
	maven_get_reg(c, 0x82);	/* fetch oscillator state? */
	maven_set_reg(c, 0x8C, 0x00);
	maven_get_reg(c, 0x94);	/* get 0x82 */
	maven_set_reg(c, 0x94, 0xA2);
	/* xmiscctrl */

	maven_set_reg_pair(c, 0x8E, 0x1EFF);
	maven_set_reg(c, 0xC6, 0x01);

	/* removed code... */

	maven_get_reg(c, 0x06);
	maven_set_reg(c, 0x06, 0xF9);	/* or read |= 0xF0 ? */

	/* removed code here... */

	/* real code begins here? */
	/* chroma subcarrier */
	LR(0x00); LR(0x01); LR(0x02); LR(0x03);

	LR(0x04);

	LR(0x2C);
	LR(0x08);
	LR(0x0A);
	LR(0x09);
	LR(0x29);
	LRP(0x31);
	LRP(0x17);
	LR(0x0B);
	LR(0x0C);
	if (m->mode == MATROXFB_OUTPUT_MODE_PAL) {
		maven_set_reg(c, 0x35, 0x10); /* ... */
	} else {
		maven_set_reg(c, 0x35, 0x0F); /* ... */
	}

	LRP(0x10);

	LRP(0x0E);
	LRP(0x1E);

	LR(0x20);	/* saturation #1 */
	LR(0x22);	/* saturation #2 */
	LR(0x25);	/* hue */
	LR(0x34);
	LR(0x33);
	LR(0x19);
	LR(0x12);
	LR(0x3B);
	LR(0x13);
	LR(0x39);
	LR(0x1D);
	LR(0x3A);
	LR(0x24);
	LR(0x14);
	LR(0x15);
	LR(0x16);
	LRP(0x2D);
	LRP(0x2F);
	LR(0x1A);
	LR(0x1B);
	LR(0x1C);
	LR(0x23);
	LR(0x26);
	LR(0x28);
	LR(0x27);
	LR(0x21);
	LRP(0x2A);
	if (m->mode == MATROXFB_OUTPUT_MODE_PAL)
		maven_set_reg(c, 0x35, 0x1D);	/* ... */
	else
		maven_set_reg(c, 0x35, 0x1C);

	LRP(0x3C);
	LR(0x37);
	LR(0x38);
	maven_set_reg(c, 0xB3, 0x01);

	maven_get_reg(c, 0xB0);	/* read 0x80 */
	maven_set_reg(c, 0xB0, 0x08);	/* ugh... */
	maven_get_reg(c, 0xB9);	/* read 0x7C */
	maven_set_reg(c, 0xB9, 0x78);
	maven_get_reg(c, 0xBF);	/* read 0x00 */
	maven_set_reg(c, 0xBF, 0x02);
	maven_get_reg(c, 0x94);	/* read 0x82 */
	maven_set_reg(c, 0x94, 0xB3);

	LR(0x80); /* 04 1A 91 or 05 21 91 */
	LR(0x81);
	LR(0x82);

	maven_set_reg(c, 0x8C, 0x20);
	maven_get_reg(c, 0x8D);
	maven_set_reg(c, 0x8D, 0x10);

	LR(0x90); /* 4D 50 52 or 4E 05 45 */
	LR(0x91);
	LR(0x92);

	LRP(0x9A); /* 0049 or 004F */
	LRP(0x9C); /* 0004 or 0004 */
	LRP(0x9E); /* 0458 or 045E */
	LRP(0xA0); /* 05DA or 051B */
	LRP(0xA2); /* 00CC or 00CF */
	LRP(0xA4); /* 007D or 007F */
	LRP(0xA6); /* 007C or 007E */
	LRP(0xA8); /* 03CB or 03CE */
	LRP(0x98); /* 0000 or 0000 */
	LRP(0xAE); /* 0044 or 003A */
	LRP(0x96); /* 05DA or 051B */
	LRP(0xAA); /* 04BC or 046A */
	LRP(0xAC); /* 004D or 004E */

	LR(0xBE);
	LR(0xC2);

	maven_get_reg(c, 0x8D);
	maven_set_reg(c, 0x8D, 0x04);

	LR(0x20);	/* saturation #1 */
	LR(0x22);	/* saturation #2 */
	LR(0x93);	/* whoops */
	LR(0x20);	/* oh, saturation #1 again */
	LR(0x22);	/* oh, saturation #2 again */
	LR(0x25);	/* hue */
	LRP(0x0E);
	LRP(0x1E);
	LRP(0x0E);	/* problems with memory? */
	LRP(0x1E);	/* yes, matrox must have problems in memory area... */

	/* load gamma correction stuff */
	LR(0x83);
	LR(0x84);
	LR(0x85);
	LR(0x86);
	LR(0x87);
	LR(0x88);
	LR(0x89);
	LR(0x8A);
	LR(0x8B);

	val = maven_get_reg(c, 0x8D);
	val &= 0x14;			/* 0x10 or anything ored with it */
	maven_set_reg(c, 0x8D, val);

	LR(0x33);
	LR(0x19);
	LR(0x12);
	LR(0x3B);
	LR(0x13);
	LR(0x39);
	LR(0x1D);
	LR(0x3A);
	LR(0x24);
	LR(0x14);
	LR(0x15);
	LR(0x16);
	LRP(0x2D);
	LRP(0x2F);
	LR(0x1A);
	LR(0x1B);
	LR(0x1C);
	LR(0x23);
	LR(0x26);
	LR(0x28);
	LR(0x27);
	LR(0x21);
	LRP(0x2A);
	if (m->mode == MATROXFB_OUTPUT_MODE_PAL)
		maven_set_reg(c, 0x35, 0x1D);
	else
		maven_set_reg(c, 0x35, 0x1C);
	LRP(0x3C);
	LR(0x37);
	LR(0x38);

	maven_get_reg(c, 0xB0);
	LR(0xB0);	/* output mode */
	LR(0x90);
	LR(0xBE);
	LR(0xC2);

	LRP(0x9A);
	LRP(0xA2);
	LRP(0x9E);
	LRP(0xA6);
	LRP(0xAA);
	LRP(0xAC);
	maven_set_reg(c, 0x3E, 0x00);
	maven_set_reg(c, 0x95, 0x20);
}

static int maven_find_exact_clocks(unsigned int ht, unsigned int vt,
		struct mavenregs* m) {
	unsigned int x;
	unsigned int err = ~0;

	/* 1:1 */
	m->regs[0x80] = 0x0F;
	m->regs[0x81] = 0x07;
	m->regs[0x82] = 0x81;

	for (x = 0; x < 8; x++) {
		unsigned int a, b, c, h2;
		unsigned int h = ht + 2 + x;

		if (!matroxfb_mavenclock((m->mode == MATROXFB_OUTPUT_MODE_PAL) ? &maven_PAL : &maven_NTSC, h, vt, &a, &b, &c, &h2)) {
			unsigned int diff = h - h2;

			if (diff < err) {
				err = diff;
				m->regs[0x80] = a - 1;
				m->regs[0x81] = b - 1;
				m->regs[0x82] = c | 0x80;
				m->hcorr = h2 - 2;
				m->htotal = h - 2;
			}
		}
	}
	return err != ~0U;
}

static inline int maven_compute_timming(struct maven_data* md,
		struct my_timming* mt,
		struct mavenregs* m) {
	unsigned int tmpi;
	unsigned int a, bv, c;
	MINFO_FROM(md->primary_head);

	m->mode = ACCESS_FBINFO(outputs[1]).mode;
	if (m->mode != MATROXFB_OUTPUT_MODE_MONITOR) {
		unsigned int lmargin;
		unsigned int umargin;
		unsigned int vslen;
		unsigned int hcrt;
		unsigned int slen;

		maven_init_TVdata(md, m);

		if (maven_find_exact_clocks(mt->HTotal, mt->VTotal, m) == 0)
			return -EINVAL;

		lmargin = mt->HTotal - mt->HSyncEnd;
		slen = mt->HSyncEnd - mt->HSyncStart;
		hcrt = mt->HTotal - slen - mt->delay;
		umargin = mt->VTotal - mt->VSyncEnd;
		vslen = mt->VSyncEnd - mt->VSyncStart;

		if (m->hcorr < mt->HTotal)
			hcrt += m->hcorr;
		if (hcrt > mt->HTotal)
			hcrt -= mt->HTotal;
		if (hcrt + 2 > mt->HTotal)
			hcrt = 0;	/* or issue warning? */

		/* last (first? middle?) line in picture can have different length */
		/* hlen - 2 */
		m->regs[0x96] = m->hcorr;
		m->regs[0x97] = m->hcorr >> 8;
		/* ... */
		m->regs[0x98] = 0x00; m->regs[0x99] = 0x00;
		/* hblanking end */
		m->regs[0x9A] = lmargin;	/* 100% */
		m->regs[0x9B] = lmargin >> 8;	/* 100% */
		/* who knows */
		m->regs[0x9C] = 0x04;
		m->regs[0x9D] = 0x00;
		/* htotal - 2 */
		m->regs[0xA0] = m->htotal;
		m->regs[0xA1] = m->htotal >> 8;
		/* vblanking end */
		m->regs[0xA2] = mt->VTotal - mt->VSyncStart - 1;	/* stop vblanking */
		m->regs[0xA3] = (mt->VTotal - mt->VSyncStart - 1) >> 8;
		/* something end... [A6]+1..[A8] */
		if (md->version == MGATVO_B) {
			m->regs[0xA4] = 0x04;
			m->regs[0xA5] = 0x00;
		} else {
			m->regs[0xA4] = 0x01;
			m->regs[0xA5] = 0x00;
		}
		/* something start... 0..[A4]-1 */
		m->regs[0xA6] = 0x00;
		m->regs[0xA7] = 0x00;
		/* vertical line count - 1 */
		m->regs[0xA8] = mt->VTotal - 1;
		m->regs[0xA9] = (mt->VTotal - 1) >> 8;
		/* horizontal vidrst pos */
		m->regs[0xAA] = hcrt;		/* 0 <= hcrt <= htotal - 2 */
		m->regs[0xAB] = hcrt >> 8;
		/* vertical vidrst pos */
		m->regs[0xAC] = mt->VTotal - 2;
		m->regs[0xAD] = (mt->VTotal - 2) >> 8;
		/* moves picture up/down and so on... */
		m->regs[0xAE] = 0x01; /* Fix this... 0..VTotal */
		m->regs[0xAF] = 0x00;
		{
			int hdec;
			int hlen;
			unsigned int ibmin = 4 + lmargin + mt->HDisplay;
			unsigned int ib;
			int i;

			/* Verify! */
			/* Where 94208 came from? */
			if (mt->HTotal)
				hdec = 94208 / (mt->HTotal);
			else
				hdec = 0x81;
			if (hdec > 0x81)
				hdec = 0x81;
			if (hdec < 0x41)
				hdec = 0x41;
			hdec--;
			hlen = 98304 - 128 - ((lmargin + mt->HDisplay - 8) * hdec);
			if (hlen < 0)
				hlen = 0;
			hlen = hlen >> 8;
			if (hlen > 0xFF)
				hlen = 0xFF;
			/* Now we have to compute input buffer length.
			   If you want any picture, it must be between
			     4 + lmargin + xres
			   and
			     94208 / hdec
			   If you want perfect picture even on the top
			   of screen, it must be also
			     0x3C0000 * i / hdec + Q - R / hdec
			   where
			        R      Qmin   Qmax
			     0x07000   0x5AE  0x5BF
			     0x08000   0x5CF  0x5FF
			     0x0C000   0x653  0x67F
			     0x10000   0x6F8  0x6FF
			 */
			i = 1;
			do {
				ib = ((0x3C0000 * i - 0x8000)/ hdec + 0x05E7) >> 8;
				i++;
			} while (ib < ibmin);
			if (ib >= m->htotal + 2) {
				ib = ibmin;
			}

			m->regs[0x90] = hdec;	/* < 0x40 || > 0x80 is bad... 0x80 is questionable */
			m->regs[0xC2] = hlen;
			/* 'valid' input line length */
			m->regs[0x9E] = ib;
			m->regs[0x9F] = ib >> 8;
		}
		{
			int vdec;
			int vlen;

#define MATROX_USE64BIT_DIVIDE
			if (mt->VTotal) {
#ifdef MATROX_USE64BIT_DIVIDE
				u64 f1;
				u32 a;
				u32 b;

				a = m->vlines * (m->htotal + 2);
				b = (mt->VTotal - 1) * (m->htotal + 2) + m->hcorr + 2;

				f1 = ((u64)a) << 15;	/* *32768 */
				do_div(f1, b);
				vdec = f1;
#else
				vdec = m->vlines * 32768 / mt->VTotal;
#endif
			} else
				vdec = 0x8000;
			if (vdec > 0x8000)
				vdec = 0x8000;
			vlen = (vslen + umargin + mt->VDisplay) * vdec;
			vlen = (vlen >> 16) - 146; /* FIXME: 146?! */
			if (vlen < 0)
				vlen = 0;
			if (vlen > 0xFF)
				vlen = 0xFF;
			vdec--;
			m->regs[0x91] = vdec;
			m->regs[0x92] = vdec >> 8;
			m->regs[0xBE] = vlen;
		}
		m->regs[0xB0] = 0x08;	/* output: SVideo/Composite */
		return 0;
	}

	DAC1064_calcclock(mt->pixclock, 450000, &a, &bv, &c);
	m->regs[0x80] = a;
	m->regs[0x81] = bv;
	m->regs[0x82] = c | 0x80;

	m->regs[0xB3] = 0x01;
	m->regs[0x94] = 0xB2;

	/* htotal... */
	m->regs[0x96] = mt->HTotal;
	m->regs[0x97] = mt->HTotal >> 8;
	/* ?? */
	m->regs[0x98] = 0x00;
	m->regs[0x99] = 0x00;
	/* hsync len */
	tmpi = mt->HSyncEnd - mt->HSyncStart;
	m->regs[0x9A] = tmpi;
	m->regs[0x9B] = tmpi >> 8;
	/* hblank end */
	tmpi = mt->HTotal - mt->HSyncStart;
	m->regs[0x9C] = tmpi;
	m->regs[0x9D] = tmpi >> 8;
	/* hblank start */
	tmpi += mt->HDisplay;
	m->regs[0x9E] = tmpi;
	m->regs[0x9F] = tmpi >> 8;
	/* htotal + 1 */
	tmpi = mt->HTotal + 1;
	m->regs[0xA0] = tmpi;
	m->regs[0xA1] = tmpi >> 8;
	/* vsync?! */
	tmpi = mt->VSyncEnd - mt->VSyncStart - 1;
	m->regs[0xA2] = tmpi;
	m->regs[0xA3] = tmpi >> 8;
	/* ignored? */
	tmpi = mt->VTotal - mt->VSyncStart;
	m->regs[0xA4] = tmpi;
	m->regs[0xA5] = tmpi >> 8;
	/* ignored? */
	tmpi = mt->VTotal - 1;
	m->regs[0xA6] = tmpi;
	m->regs[0xA7] = tmpi >> 8;
	/* vtotal - 1 */
	m->regs[0xA8] = tmpi;
	m->regs[0xA9] = tmpi >> 8;
	/* hor vidrst */
	tmpi = mt->HTotal - mt->delay;
	m->regs[0xAA] = tmpi;
	m->regs[0xAB] = tmpi >> 8;
	/* vert vidrst */
	tmpi = mt->VTotal - 2;
	m->regs[0xAC] = tmpi;
	m->regs[0xAD] = tmpi >> 8;
	/* ignored? */
	m->regs[0xAE] = 0x00;
	m->regs[0xAF] = 0x00;

	m->regs[0xB0] = 0x03;	/* output: monitor */
	m->regs[0xB1] = 0xA0;	/* ??? */
	m->regs[0x8C] = 0x20;	/* must be set... */
	m->regs[0x8D] = 0x04;	/* defaults to 0x10: test signal */
	m->regs[0xB9] = 0x1A;	/* defaults to 0x2C: too bright */
	m->regs[0xBF] = 0x22;	/* makes picture stable */

	return 0;
}

static int maven_program_timming(struct maven_data* md,
		const struct mavenregs* m) {
	struct i2c_client* c = md->client;

	if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) {
		LR(0x80);
		LR(0x81);
		LR(0x82);

		LR(0xB3);
		LR(0x94);

		LRP(0x96);
		LRP(0x98);
		LRP(0x9A);
		LRP(0x9C);
		LRP(0x9E);
		LRP(0xA0);
		LRP(0xA2);
		LRP(0xA4);
		LRP(0xA6);
		LRP(0xA8);
		LRP(0xAA);
		LRP(0xAC);
		LRP(0xAE);

		LR(0xB0);	/* output: monitor */
		LR(0xB1);	/* ??? */
		LR(0x8C);	/* must be set... */
		LR(0x8D);	/* defaults to 0x10: test signal */
		LR(0xB9);	/* defaults to 0x2C: too bright */
		LR(0xBF);	/* makes picture stable */
	} else {
		maven_init_TV(c, m);
	}
	return 0;
}

static inline int maven_resync(struct maven_data* md) {
	struct i2c_client* c = md->client;
	maven_set_reg(c, 0x95, 0x20);	/* start whole thing */
	return 0;
}

static int maven_get_queryctrl (struct maven_data* md, 
				struct v4l2_queryctrl *p) {
	int i;
	
	i = get_ctrl_id(p->id);
	if (i >= 0) {
		*p = maven_controls[i].desc;
		return 0;
	}
	if (i == -ENOENT) {
		static const struct v4l2_queryctrl disctrl = 
			{ .flags = V4L2_CTRL_FLAG_DISABLED };
			
		i = p->id;
		*p = disctrl;
		p->id = i;
		sprintf(p->name, "Ctrl #%08X", i);
		return 0;
	}
	return -EINVAL;
}

static int maven_set_control (struct maven_data* md, 
			      struct v4l2_control *p) {
	int i;
	
	i = get_ctrl_id(p->id);
	if (i < 0) return -EINVAL;

	/*
	 * Check if changed.
	 */
	if (p->value == *get_ctrl_ptr(md, i)) return 0;

	/*
	 * Check limits.
	 */
	if (p->value > maven_controls[i].desc.maximum) return -EINVAL;
	if (p->value < maven_controls[i].desc.minimum) return -EINVAL;

	/*
	 * Store new value.
	 */
	*get_ctrl_ptr(md, i) = p->value;

	switch (p->id) {
		case V4L2_CID_BRIGHTNESS:
		case V4L2_CID_CONTRAST:
		{
		  int blacklevel, whitelevel;
		  maven_compute_bwlevel(md, &blacklevel, &whitelevel);
		  blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8);
		  whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8);
		  maven_set_reg_pair(md->client, 0x0e, blacklevel);
		  maven_set_reg_pair(md->client, 0x1e, whitelevel);
		}
		break;
		case V4L2_CID_SATURATION:
		{
		  maven_set_reg(md->client, 0x20, p->value);
		  maven_set_reg(md->client, 0x22, p->value);
		}
		break;
		case V4L2_CID_HUE:
		{
		  maven_set_reg(md->client, 0x25, p->value);
		}
		break;
		case V4L2_CID_GAMMA:
		{
		  const struct maven_gamma* g;
		  g = maven_compute_gamma(md);
		  maven_set_reg(md->client, 0x83, g->reg83);
		  maven_set_reg(md->client, 0x84, g->reg84);
		  maven_set_reg(md->client, 0x85, g->reg85);
		  maven_set_reg(md->client, 0x86, g->reg86);
		  maven_set_reg(md->client, 0x87, g->reg87);
		  maven_set_reg(md->client, 0x88, g->reg88);
		  maven_set_reg(md->client, 0x89, g->reg89);
		  maven_set_reg(md->client, 0x8a, g->reg8a);
		  maven_set_reg(md->client, 0x8b, g->reg8b);
		}
		break;
		case MATROXFB_CID_TESTOUT:
		{
			unsigned char val 
			  = maven_get_reg (md->client,0x8d);
			if (p->value) val |= 0x10;
			else          val &= ~0x10;
			maven_set_reg (md->client, 0x8d, val);
		}
		break;
		case MATROXFB_CID_DEFLICKER:
		{
		  maven_set_reg(md->client, 0x93, maven_compute_deflicker(md));
		}
		break;
	}
	

	return 0;
}

static int maven_get_control (struct maven_data* md, 
			      struct v4l2_control *p) {
	int i;
	
	i = get_ctrl_id(p->id);
	if (i < 0) return -EINVAL;
	p->value = *get_ctrl_ptr(md, i);
	return 0;
}

/******************************************************/

static int maven_out_compute(void* md, struct my_timming* mt) {
#define mdinfo ((struct maven_data*)md)
#define minfo (mdinfo->primary_head)
	return maven_compute_timming(md, mt, &ACCESS_FBINFO(hw).maven);
#undef minfo
#undef mdinfo
}

static int maven_out_program(void* md) {
#define mdinfo ((struct maven_data*)md)
#define minfo (mdinfo->primary_head)
	return maven_program_timming(md, &ACCESS_FBINFO(hw).maven);
#undef minfo
#undef mdinfo
}

static int maven_out_start(void* md) {
	return maven_resync(md);
}

static int maven_out_verify_mode(void* md, u_int32_t arg) {
	switch (arg) {
		case MATROXFB_OUTPUT_MODE_PAL:
		case MATROXFB_OUTPUT_MODE_NTSC:
		case MATROXFB_OUTPUT_MODE_MONITOR:
			return 0;
	}
	return -EINVAL;
}

static int maven_out_get_queryctrl(void* md, struct v4l2_queryctrl* p) {
        return maven_get_queryctrl(md, p);
}

static int maven_out_get_ctrl(void* md, struct v4l2_control* p) {
	return maven_get_control(md, p);
}

static int maven_out_set_ctrl(void* md, struct v4l2_control* p) {
	return maven_set_control(md, p);
}

static struct matrox_altout maven_altout = {
	.name		= "Secondary output",
	.compute	= maven_out_compute,
	.program	= maven_out_program,
	.start		= maven_out_start,
	.verifymode	= maven_out_verify_mode,
	.getqueryctrl	= maven_out_get_queryctrl,
	.getctrl	= maven_out_get_ctrl,
	.setctrl	= maven_out_set_ctrl,
};

static int maven_init_client(struct i2c_client* clnt) {
	struct maven_data* md = i2c_get_clientdata(clnt);
	MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo);

	md->primary_head = MINFO;
	md->client = clnt;
	down_write(&ACCESS_FBINFO(altout.lock));
	ACCESS_FBINFO(outputs[1]).output = &maven_altout;
	ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src;
	ACCESS_FBINFO(outputs[1]).data = md;
	ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
	up_write(&ACCESS_FBINFO(altout.lock));
	if (maven_get_reg(clnt, 0xB2) < 0x14) {
		md->version = MGATVO_B;
		/* Tweak some things for this old chip */
	} else {
		md->version = MGATVO_C;
	}
	/*
	 * Set all parameters to its initial values.
	 */
	{
		unsigned int i;

		for (i = 0; i < MAVCTRLS; ++i) {
			*get_ctrl_ptr(md, i) = maven_controls[i].desc.default_value;
		}
	}

	return 0;
}

static int maven_shutdown_client(struct i2c_client* clnt) {
	struct maven_data* md = i2c_get_clientdata(clnt);

	if (md->primary_head) {
		MINFO_FROM(md->primary_head);

		down_write(&ACCESS_FBINFO(altout.lock));
		ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE;
		ACCESS_FBINFO(outputs[1]).output = NULL;
		ACCESS_FBINFO(outputs[1]).data = NULL;
		ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
		up_write(&ACCESS_FBINFO(altout.lock));
		md->primary_head = NULL;
	}
	return 0;
}

static unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END };
I2C_CLIENT_INSMOD;

static struct i2c_driver maven_driver;

static int maven_detect_client(struct i2c_adapter* adapter, int address, int kind) {
	int err = 0;
	struct i2c_client* new_client;
	struct maven_data* data;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA |
					      I2C_FUNC_SMBUS_BYTE_DATA |
					      I2C_FUNC_PROTOCOL_MANGLING))
		goto ERROR0;
	if (!(new_client = (struct i2c_client*)kmalloc(sizeof(*new_client) + sizeof(*data),
			GFP_KERNEL))) {
		err = -ENOMEM;
		goto ERROR0;
	}
	memset(new_client, 0, sizeof(*new_client) + sizeof(*data));
	data = (struct maven_data*)(new_client + 1);
	i2c_set_clientdata(new_client, data);
	new_client->addr = address;
	new_client->adapter = adapter;
	new_client->driver = &maven_driver;
	new_client->flags = 0;
	strcpy(new_client->name, "maven client");
	if ((err = i2c_attach_client(new_client)))
		goto ERROR3;
	err = maven_init_client(new_client);
	if (err)
		goto ERROR4;
	return 0;
ERROR4:;
	i2c_detach_client(new_client);
ERROR3:;
	kfree(new_client);
ERROR0:;
	return err;
}

static int maven_attach_adapter(struct i2c_adapter* adapter) {
	if (adapter->id == I2C_HW_B_G400)
		return i2c_probe(adapter, &addr_data, &maven_detect_client);
	return 0;
}

static int maven_detach_client(struct i2c_client* client) {
	int err;

	if ((err = i2c_detach_client(client))) {
		printk(KERN_ERR "maven: Cannot deregister client\n");
		return err;
	}
	maven_shutdown_client(client);
	kfree(client);
	return 0;
}

static struct i2c_driver maven_driver={
	.driver = {
		.name	= "maven",
	},
	.id		= I2C_DRIVERID_MGATVO,
	.attach_adapter	= maven_attach_adapter,
	.detach_client	= maven_detach_client,
};

/* ************************** */

static int matroxfb_maven_init(void) {
	int err;

	err = i2c_add_driver(&maven_driver);
	if (err) {
		printk(KERN_ERR "maven: Maven driver failed to register (%d).\n", err);
		return err;
	}
	return 0;
}

static void matroxfb_maven_exit(void) {
	i2c_del_driver(&maven_driver);
}

MODULE_AUTHOR("(c) 1999-2002 Petr Vandrovec <vandrove@vc.cvut.cz>");
MODULE_DESCRIPTION("Matrox G200/G400 Matrox MGA-TVO driver");
MODULE_LICENSE("GPL");
module_init(matroxfb_maven_init);
module_exit(matroxfb_maven_exit);
/* we do not have __setup() yet */
