⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matroxfb_maven.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * 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>#define MGATVO_B	1#define MGATVO_C	2static 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	0x3FFstatic 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, ARRAY_SIZE(maven_gamma) - 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 ARRAY_SIZE(maven_controls)/* 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(__func__)	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 h2/post/in/feed have not been assigned, return zero (error) */	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 uninitialized_var(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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -