📄 matroxfb_maven.c
字号:
/* * * 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 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, 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), ® }, { 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -