📄 matroxfb_maven.c
字号:
/* * * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450. * * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz> * * Version: 1.51 2001/01/19 * * 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 MODE_PAL MATROXFB_OUTPUT_MODE_PAL#define MODE_NTSC MATROXFB_OUTPUT_MODE_NTSC#define MODE_TV(x) (((x) == MODE_PAL) || ((x) == MODE_NTSC))#define MODE_MONITOR MATROXFB_OUTPUT_MODE_MONITORstruct maven_data { struct matrox_fb_info* primary_head; struct i2c_client* client; int mode;};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), ® }, { 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("PLL_calcclock") scrlen = htotal * (vtotal - 1); fwant = htotal * vtotal; fmax = pll->vco_freq_max / ctl->den; printk(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; printk(KERN_DEBUG "Match: %u / %u / %u / %u\n", n, m, p, ln); if (ln > besth2) { printk(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 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 */ }, 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 */ }, MODE_NTSC, 525, 60 }; if (md->mode & MODE_PAL) *data = palregs; else *data = ntscregs; data->regs[0x93] = 0xA2; /* gamma correction registers */ data->regs[0x83] = 0x00; data->regs[0x84] = 0x00; data->regs[0x85] = 0x00; data->regs[0x86] = 0x1F; data->regs[0x87] = 0x10; data->regs[0x88] = 0x10; data->regs[0x89] = 0x10; data->regs[0x8A] = 0x64; /* 100 */ data->regs[0x8B] = 0xC8; /* 200 */ 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 & 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 & 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, 0x00); 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 &= 0x10; /* 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 & MODE_PAL) maven_set_reg(c, 0x35, 0x1D); else maven_set_reg(c, 0x35, 0x1C); LRP(0x3C); LR(0x37);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -