patch-2.4.21 linux-2.4.21/drivers/video/matrox/matroxfb_maven.c
Next file: linux-2.4.21/drivers/video/matrox/matroxfb_maven.h
Previous file: linux-2.4.21/drivers/video/matrox/matroxfb_g450.h
Back to the patch index
Back to the overall index
- Lines: 608
- Date:
2003-06-13 07:51:37.000000000 -0700
- Orig file:
linux-2.4.20/drivers/video/matrox/matroxfb_maven.c
- Orig date:
2002-08-02 17:39:45.000000000 -0700
diff -urN linux-2.4.20/drivers/video/matrox/matroxfb_maven.c linux-2.4.21/drivers/video/matrox/matroxfb_maven.c
@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
*
- * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
+ * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Portions Copyright (c) 2001 Matrox Graphics Inc.
*
- * Version: 1.62 2001/11/29
+ * Version: 1.64 2002/06/10
*
* See matroxfb_base.c for contributors.
*
@@ -30,13 +30,125 @@
#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 matroxfb_queryctrl desc;
+ size_t control;
+};
+
+#define BLMIN 0x0FF
+#define WLMAX 0x3FF
+
+static const struct mctl maven_controls[] =
+{ { { MATROXFB_CID_BRIGHTNESS,
+ "brightness",
+ 0, WLMAX - BLMIN, 1, 379 - BLMIN,
+ MATROXFB_CTRL_TYPE_INTEGER, 0, 0,
+ "picture"
+ }, offsetof(struct matrox_fb_info, altout.tvo_params.brightness) },
+ { { MATROXFB_CID_CONTRAST,
+ "contrast",
+ 0, 1023, 1, 127,
+ MATROXFB_CTRL_TYPE_INTEGER, 0, 0,
+ "picture"
+ }, offsetof(struct matrox_fb_info, altout.tvo_params.contrast) },
+ { { MATROXFB_CID_SATURATION,
+ "saturation",
+ 0, 255, 1, 155,
+ MATROXFB_CTRL_TYPE_INTEGER, 0, 0,
+ "picture"
+ }, offsetof(struct matrox_fb_info, altout.tvo_params.saturation) },
+ { { MATROXFB_CID_HUE,
+ "hue",
+ 0, 255, 1, 0,
+ MATROXFB_CTRL_TYPE_INTEGER, 0, 0,
+ "picture"
+ }, offsetof(struct matrox_fb_info, altout.tvo_params.hue) },
+ { { MATROXFB_CID_GAMMA,
+ "gamma",
+ 0, sizeof(maven_gamma)/sizeof(maven_gamma[0])-1, 1, 3,
+ MATROXFB_CTRL_TYPE_INTEGER, 0, 0,
+ "picture"
+ }, offsetof(struct matrox_fb_info, altout.tvo_params.gamma) },
+ { { MATROXFB_CID_TESTOUT,
+ "test output",
+ 0, 1, 1, 0,
+ MATROXFB_CTRL_TYPE_BOOLEAN, 0, 0,
+ "picture"
+ }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) },
+ { { MATROXFB_CID_DEFLICKER,
+ "deflicker mode",
+ 0, 2, 1, 0,
+ MATROXFB_CTRL_TYPE_INTEGER, 0, 0,
+ "picture"
+ }, 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 mode;
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), ® },
@@ -127,8 +239,8 @@
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);
+/* 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;
@@ -163,9 +275,9 @@
ln = ln - scrlen;
if (ln > htotal)
continue;
- printk(KERN_DEBUG "Match: %u / %u / %u / %u\n", n, m, p, ln);
+ dprintk(KERN_DEBUG "Match: %u / %u / %u / %u\n", n, m, p, ln);
if (ln > besth2) {
- printk(KERN_DEBUG "Better...\n");
+ dprintk(KERN_DEBUG "Better...\n");
*h2 = besth2 = ln;
*post = p;
*in = m;
@@ -221,6 +333,38 @@
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 */
@@ -326,26 +470,50 @@
0x00, /* 3E written multiple times */
0x00, /* never written */
}, MODE_NTSC, 525, 60 };
+ MINFO_FROM(md->primary_head);
- if (md->mode & MODE_PAL)
+ if (ACCESS_FBINFO(outputs[1].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;
+ 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)])
@@ -386,7 +554,7 @@
LRP(0x17);
LR(0x0B);
LR(0x0C);
- if (m->mode & MODE_PAL) {
+ if (m->mode == MODE_PAL) {
maven_set_reg(c, 0x35, 0x10); /* ... */
} else {
maven_set_reg(c, 0x35, 0x0F); /* ... */
@@ -424,7 +592,7 @@
LR(0x27);
LR(0x21);
LRP(0x2A);
- if (m->mode & MODE_PAL)
+ if (m->mode == MODE_PAL)
maven_set_reg(c, 0x35, 0x1D); /* ... */
else
maven_set_reg(c, 0x35, 0x1C);
@@ -473,7 +641,7 @@
LR(0xC2);
maven_get_reg(c, 0x8D);
- maven_set_reg(c, 0x8D, 0x00);
+ maven_set_reg(c, 0x8D, 0x04);
LR(0x20); /* saturation #1 */
LR(0x22); /* saturation #2 */
@@ -498,7 +666,7 @@
LR(0x8B);
val = maven_get_reg(c, 0x8D);
- val &= 0x10; /* 0x10 or anything ored with it */
+ val &= 0x14; /* 0x10 or anything ored with it */
maven_set_reg(c, 0x8D, val);
LR(0x33);
@@ -524,7 +692,7 @@
LR(0x27);
LR(0x21);
LRP(0x2A);
- if (m->mode & MODE_PAL)
+ if (m->mode == MODE_PAL)
maven_set_reg(c, 0x35, 0x1D);
else
maven_set_reg(c, 0x35, 0x1C);
@@ -562,7 +730,7 @@
unsigned int a, b, c, h2;
unsigned int h = ht + 2 + x;
- if (!matroxfb_mavenclock((m->mode & MODE_PAL) ? &maven_PAL : &maven_NTSC, h, vt, &a, &b, &c, &h2)) {
+ if (!matroxfb_mavenclock((m->mode == MODE_PAL) ? &maven_PAL : &maven_NTSC, h, vt, &a, &b, &c, &h2)) {
unsigned int diff = h - h2;
if (diff < err) {
@@ -584,8 +752,8 @@
unsigned int tmpi;
unsigned int a, bv, c;
- m->mode = md->mode;
- if (MODE_TV(md->mode)) {
+ m->mode = md->primary_head->outputs[1].mode;
+ if (MODE_TV(m->mode)) {
unsigned int lmargin;
unsigned int umargin;
unsigned int vslen;
@@ -804,7 +972,7 @@
m->regs[0xB0] = 0x03; /* output: monitor */
m->regs[0xB1] = 0xA0; /* ??? */
m->regs[0x8C] = 0x20; /* must be set... */
- m->regs[0x8D] = 0x00; /* defaults to 0x10: test signal */
+ 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 */
@@ -849,25 +1017,122 @@
return 0;
}
-static inline int maven_resync(struct maven_data* md) {
+static inline int maven_start(struct maven_data* md) {
struct i2c_client* c = md->client;
maven_set_reg(c, 0x95, 0x20); /* start whole thing */
return 0;
}
-static int maven_set_output_mode(struct maven_data* md, u_int32_t arg) {
- switch (arg) {
- case MATROXFB_OUTPUT_MODE_PAL:
- case MATROXFB_OUTPUT_MODE_NTSC:
- case MATROXFB_OUTPUT_MODE_MONITOR:
- md->mode = arg;
- return 1;
+static int maven_get_queryctrl (struct maven_data* md,
+ struct matroxfb_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 matroxfb_queryctrl disctrl =
+ { 0, "", 0, 0, 0, 0, 0, 1, 1, "Disabled" };
+
+ i = p->id;
+ *p = disctrl;
+ p->id = i;
+ sprintf(p->name, "Ctrl #%08X", i);
+ return 0;
}
return -EINVAL;
}
-static int maven_get_output_mode(struct maven_data* md, u_int32_t *arg) {
- *arg = md->mode;
+static int maven_set_control (struct maven_data* md,
+ struct matroxfb_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 MATROXFB_CID_BRIGHTNESS:
+ case MATROXFB_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 MATROXFB_CID_SATURATION:
+ {
+ maven_set_reg(md->client, 0x20, p->value);
+ maven_set_reg(md->client, 0x22, p->value);
+ }
+ break;
+ case MATROXFB_CID_HUE:
+ {
+ maven_set_reg(md->client, 0x25, p->value);
+ }
+ break;
+ case MATROXFB_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 matroxfb_control *p) {
+ int i;
+
+ i = get_ctrl_id(p->id);
+ if (i < 0) return -EINVAL;
+ p->value = *get_ctrl_ptr(md, i);
return 0;
}
@@ -890,56 +1155,73 @@
}
static int maven_out_start(void* md) {
- return maven_resync(md);
+ return maven_start(md);
}
-static void maven_out_incuse(void* md) {
- if (md)
- i2c_inc_use_client(((struct maven_data*)md)->client);
+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 void maven_out_decuse(void* md) {
- if (md)
- i2c_dec_use_client(((struct maven_data*)md)->client);
+static int maven_out_get_queryctrl(void* md, struct matroxfb_queryctrl* p) {
+ return maven_get_queryctrl(md, p);
}
-static int maven_out_set_mode(void* md, u_int32_t arg) {
- return maven_set_output_mode(md, arg);
+static int maven_out_get_ctrl(void* md, struct matroxfb_control* p) {
+ return maven_get_control(md, p);
}
-static int maven_out_get_mode(void* md, u_int32_t* arg) {
- return maven_get_output_mode(md, arg);
+static int maven_out_set_ctrl(void* md, struct matroxfb_control* p) {
+ return maven_set_control(md, p);
}
static struct matrox_altout maven_altout = {
- maven_out_compute,
- maven_out_program,
- maven_out_start,
- maven_out_incuse,
- maven_out_decuse,
- maven_out_set_mode,
- maven_out_get_mode
+ .owner = THIS_MODULE,
+ .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 i2c_adapter* a = clnt->adapter;
struct maven_data* md = clnt->data;
- struct matroxfb_dh_maven_info* m2info __attribute__((unused)) = ((struct i2c_bit_adapter*)a)->minfo;
- MINFO_FROM(m2info->primary_dev);
+ MINFO_FROM(list_entry(a, struct i2c_bit_adapter, adapter)->minfo);
- md->mode = MODE_MONITOR;
md->primary_head = MINFO;
md->client = clnt;
down_write(&ACCESS_FBINFO(altout.lock));
- ACCESS_FBINFO(altout.device) = md;
- ACCESS_FBINFO(altout.output) = &maven_altout;
+ ACCESS_FBINFO(outputs[1]).output = &maven_altout;
+ ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE;
+ ACCESS_FBINFO(outputs[1]).data = md;
+ ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
up_write(&ACCESS_FBINFO(altout.lock));
- ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY;
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;
}
@@ -947,13 +1229,14 @@
struct maven_data* md = clnt->data;
if (md->primary_head) {
- md->primary_head->output.all &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
- md->primary_head->output.ph &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
- md->primary_head->output.sh &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
- down_write(&md->primary_head->altout.lock);
- md->primary_head->altout.device = NULL;
- md->primary_head->altout.output = NULL;
- up_write(&md->primary_head->altout.lock);
+ 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;
@@ -1066,7 +1349,7 @@
i2c_del_driver(&maven_driver);
}
-MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <vandrove@vc.cvut.cz>");
+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);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)