18 #include <linux/i2c.h>
20 #include <linux/slab.h>
21 #include <asm/div64.h>
26 static const struct maven_gamma {
37 { 131, 57, 223, 15, 117, 212, 251, 91, 156},
38 { 133, 61, 128, 63, 180, 147, 195, 100, 180},
39 { 131, 19, 63, 31, 50, 66, 171, 64, 176},
40 { 0, 0, 0, 31, 16, 16, 16, 100, 200},
41 { 8, 23, 47, 73, 147, 244, 220, 80, 195},
42 { 22, 43, 64, 80, 147, 115, 58, 85, 168},
43 { 34, 60, 80, 214, 147, 212, 188, 85, 167},
44 { 45, 77, 96, 216, 147, 99, 91, 85, 159},
45 { 56, 76, 112, 107, 147, 212, 148, 64, 144},
46 { 65, 91, 128, 137, 147, 196, 17, 69, 148},
47 { 72, 104, 136, 138, 147, 180, 245, 73, 147},
48 { 87, 116, 143, 126, 16, 83, 229, 77, 144},
49 { 95, 119, 152, 254, 244, 83, 221, 77, 151},
50 { 100, 129, 159, 156, 244, 148, 197, 77, 160},
51 { 105, 141, 167, 247, 244, 132, 181, 84, 166},
52 { 105, 147, 168, 247, 244, 245, 181, 90, 170},
53 { 120, 153, 175, 248, 212, 229, 165, 90, 180},
54 { 119, 156, 176, 248, 244, 229, 84, 74, 160},
55 { 119, 158, 183, 248, 244, 229, 149, 78, 165}
67 static const struct mctl maven_controls[] =
106 #define MAVCTRLS ARRAY_SIZE(maven_controls)
111 static int get_ctrl_id(
__u32 v4l2_id) {
115 if (v4l2_id < maven_controls[i].
desc.id) {
116 if (maven_controls[i].
desc.id == 0x08000000) {
121 if (v4l2_id == maven_controls[i].
desc.id) {
150 static int maven_set_reg(
struct i2c_client* c,
int reg,
int val) {
159 static int maven_set_reg_pair(
struct i2c_client* c,
int reg,
int val) {
211 unsigned int htotal,
unsigned int vtotal,
212 unsigned int*
in,
unsigned int* feed,
unsigned int*
post,
214 unsigned int besth2 = 0;
224 scrlen = htotal * (vtotal - 1);
225 fwant = htotal * vtotal;
226 fmax = pll->vco_freq_max / ctl->
den;
229 fwant, fxtal, htotal, vtotal, fmax);
230 for (p = 1; p <= pll->post_shift_max; p++) {
231 if (fwant * 2 > fmax)
237 for (; p-- > 0; fwant >>= 1) {
240 if (fwant < fmin)
break;
241 for (m = pll->
in_div_min; m <= pll->in_div_max; m++) {
246 n = (fwant *
m) / fxtal;
247 if (n < pll->feed_div_min)
279 dprintk(
KERN_ERR "clk: %02X %02X %02X %d %d\n", *in, *feed, *post, fxtal, fwant);
280 return fxtal * (*feed) / (*in) * ctl->
den;
284 unsigned int htotal,
unsigned int vtotal,
285 unsigned int* in,
unsigned int* feed,
unsigned int* post,
286 unsigned int* htotal2) {
290 fvco = matroxfb_PLL_mavenclock(&maven1000_pll, ctl, htotal, vtotal, in, feed, &p, htotal2);
294 if (fvco <= 100000000)
296 else if (fvco <= 140000000)
298 else if (fvco <= 180000000)
306 static void DAC1064_calcclock(
unsigned int freq,
unsigned int fmax,
307 unsigned int* in,
unsigned int* feed,
unsigned int* post) {
315 else if (fvco <= 140000)
317 else if (fvco <= 180000)
325 static unsigned char maven_compute_deflicker (
const struct maven_data*
md) {
329 switch (md->
primary_head->altout.tvo_params.deflicker) {
343 static void maven_compute_bwlevel (
const struct maven_data* md,
346 const int c = md->
primary_head->altout.tvo_params.contrast;
352 static const struct maven_gamma* maven_compute_gamma (
const struct maven_data* md) {
353 return maven_gamma + md->
primary_head->altout.tvo_params.gamma;
359 0x2A, 0x09, 0x8A, 0xCB,
411 0x21, 0xF0, 0x7C, 0x1F,
470 data->
regs[0x93] = maven_compute_deflicker(md);
474 const struct maven_gamma*
g;
475 g = maven_compute_gamma(md);
476 data->
regs[0x83] = g->reg83;
477 data->
regs[0x84] = g->reg84;
478 data->
regs[0x85] = g->reg85;
479 data->
regs[0x86] = g->reg86;
480 data->
regs[0x87] = g->reg87;
481 data->
regs[0x88] = g->reg88;
482 data->
regs[0x89] = g->reg89;
483 data->
regs[0x8A] = g->reg8a;
484 data->
regs[0x8B] = g->reg8b;
490 maven_compute_bwlevel (md, &bl, &wl);
491 data->
regs[0x0e] = bl >> 2;
492 data->
regs[0x0f] = bl & 3;
493 data->
regs[0x1e] = wl >> 2;
494 data->
regs[0x1f] = wl & 3;
500 data->
regs[0x22] = minfo->
altout.tvo_params.saturation;
504 data->
regs[0x25] = minfo->
altout.tvo_params.hue;
508 #define LR(x) maven_set_reg(c, (x), m->regs[(x)])
509 #define LRP(x) maven_set_reg_pair(c, (x), m->regs[(x)] | (m->regs[(x)+1] << 8))
514 maven_set_reg(c, 0x3E, 0x01);
515 maven_get_reg(c, 0x82);
516 maven_set_reg(c, 0x8C, 0x00);
517 maven_get_reg(c, 0x94);
518 maven_set_reg(c, 0x94, 0xA2);
521 maven_set_reg_pair(c, 0x8E, 0x1EFF);
522 maven_set_reg(c, 0xC6, 0x01);
526 maven_get_reg(c, 0x06);
527 maven_set_reg(c, 0x06, 0xF9);
533 LR(0x00);
LR(0x01);
LR(0x02);
LR(0x03);
547 maven_set_reg(c, 0x35, 0x10);
549 maven_set_reg(c, 0x35, 0x0F);
585 maven_set_reg(c, 0x35, 0x1D);
587 maven_set_reg(c, 0x35, 0x1C);
592 maven_set_reg(c, 0xB3, 0x01);
594 maven_get_reg(c, 0xB0);
595 maven_set_reg(c, 0xB0, 0x08);
596 maven_get_reg(c, 0xB9);
597 maven_set_reg(c, 0xB9, 0x78);
598 maven_get_reg(c, 0xBF);
599 maven_set_reg(c, 0xBF, 0x02);
600 maven_get_reg(c, 0x94);
601 maven_set_reg(c, 0x94, 0xB3);
607 maven_set_reg(c, 0x8C, 0x20);
608 maven_get_reg(c, 0x8D);
609 maven_set_reg(c, 0x8D, 0x10);
632 maven_get_reg(c, 0x8D);
633 maven_set_reg(c, 0x8D, 0x04);
657 val = maven_get_reg(c, 0x8D);
659 maven_set_reg(c, 0x8D, val);
685 maven_set_reg(c, 0x35, 0x1D);
687 maven_set_reg(c, 0x35, 0x1C);
692 maven_get_reg(c, 0xB0);
704 maven_set_reg(c, 0x3E, 0x00);
705 maven_set_reg(c, 0x95, 0x20);
708 static int maven_find_exact_clocks(
unsigned int ht,
unsigned int vt,
711 unsigned int err = ~0;
714 m->
regs[0x80] = 0x0F;
715 m->
regs[0x81] = 0x07;
716 m->
regs[0x82] = 0x81;
718 for (x = 0; x < 8; x++) {
722 unsigned int h = ht + 2 +
x;
725 unsigned int diff = h - h2;
729 m->
regs[0x80] =
a - 1;
730 m->
regs[0x81] =
b - 1;
731 m->
regs[0x82] = c | 0x80;
740 static inline int maven_compute_timming(
struct maven_data* md,
744 unsigned int a, bv,
c;
749 unsigned int lmargin;
750 unsigned int umargin;
755 maven_init_TVdata(md, m);
757 if (maven_find_exact_clocks(mt->
HTotal, mt->
VTotal, m) == 0)
770 if (hcrt + 2 > mt->
HTotal)
778 m->
regs[0x98] = 0x00; m->
regs[0x99] = 0x00;
780 m->
regs[0x9A] = lmargin;
781 m->
regs[0x9B] = lmargin >> 8;
783 m->
regs[0x9C] = 0x04;
784 m->
regs[0x9D] = 0x00;
793 m->
regs[0xA4] = 0x04;
794 m->
regs[0xA5] = 0x00;
796 m->
regs[0xA4] = 0x01;
797 m->
regs[0xA5] = 0x00;
800 m->
regs[0xA6] = 0x00;
801 m->
regs[0xA7] = 0x00;
806 m->
regs[0xAA] = hcrt;
807 m->
regs[0xAB] = hcrt >> 8;
812 m->
regs[0xAE] = 0x01;
813 m->
regs[0xAF] = 0x00;
817 unsigned int ibmin = 4 + lmargin + mt->
HDisplay;
824 hdec = 94208 / (mt->
HTotal);
832 hlen = 98304 - 128 - ((lmargin + mt->
HDisplay - 8) * hdec);
855 ib = ((0x3C0000 * i - 0x8000)/ hdec + 0x05E7) >> 8;
857 }
while (ib < ibmin);
858 if (ib >= m->
htotal + 2) {
862 m->
regs[0x90] = hdec;
863 m->
regs[0xC2] = hlen;
866 m->
regs[0x9F] = ib >> 8;
872 #define MATROX_USE64BIT_DIVIDE
874 #ifdef MATROX_USE64BIT_DIVIDE
892 vlen = (vslen + umargin + mt->
VDisplay) * vdec;
893 vlen = (vlen >> 16) - 146;
899 m->
regs[0x91] = vdec;
900 m->
regs[0x92] = vdec >> 8;
901 m->
regs[0xBE] = vlen;
903 m->
regs[0xB0] = 0x08;
907 DAC1064_calcclock(mt->
pixclock, 450000, &a, &bv, &c);
910 m->
regs[0x82] = c | 0x80;
912 m->
regs[0xB3] = 0x01;
913 m->
regs[0x94] = 0xB2;
919 m->
regs[0x98] = 0x00;
920 m->
regs[0x99] = 0x00;
923 m->
regs[0x9A] = tmpi;
924 m->
regs[0x9B] = tmpi >> 8;
927 m->
regs[0x9C] = tmpi;
928 m->
regs[0x9D] = tmpi >> 8;
931 m->
regs[0x9E] = tmpi;
932 m->
regs[0x9F] = tmpi >> 8;
935 m->
regs[0xA0] = tmpi;
936 m->
regs[0xA1] = tmpi >> 8;
939 m->
regs[0xA2] = tmpi;
940 m->
regs[0xA3] = tmpi >> 8;
943 m->
regs[0xA4] = tmpi;
944 m->
regs[0xA5] = tmpi >> 8;
947 m->
regs[0xA6] = tmpi;
948 m->
regs[0xA7] = tmpi >> 8;
950 m->
regs[0xA8] = tmpi;
951 m->
regs[0xA9] = tmpi >> 8;
954 m->
regs[0xAA] = tmpi;
955 m->
regs[0xAB] = tmpi >> 8;
958 m->
regs[0xAC] = tmpi;
959 m->
regs[0xAD] = tmpi >> 8;
961 m->
regs[0xAE] = 0x00;
962 m->
regs[0xAF] = 0x00;
964 m->
regs[0xB0] = 0x03;
965 m->
regs[0xB1] = 0xA0;
966 m->
regs[0x8C] = 0x20;
967 m->
regs[0x8D] = 0x04;
968 m->
regs[0xB9] = 0x1A;
969 m->
regs[0xBF] = 0x22;
974 static int maven_program_timming(
struct maven_data* md,
1007 maven_init_TV(c, m);
1012 static inline int maven_resync(
struct maven_data* md) {
1014 maven_set_reg(c, 0x95, 0x20);
1018 static int maven_get_queryctrl (
struct maven_data* md,
1022 i = get_ctrl_id(p->
id);
1024 *p = maven_controls[
i].
desc;
1040 static int maven_set_control (
struct maven_data* md,
1044 i = get_ctrl_id(p->
id);
1045 if (i < 0)
return -
EINVAL;
1050 if (p->
value == *get_ctrl_ptr(md, i))
return 0;
1061 *get_ctrl_ptr(md, i) = p->
value;
1067 int blacklevel, whitelevel;
1068 maven_compute_bwlevel(md, &blacklevel, &whitelevel);
1069 blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8);
1070 whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8);
1071 maven_set_reg_pair(md->
client, 0x0e, blacklevel);
1072 maven_set_reg_pair(md->
client, 0x1e, whitelevel);
1088 const struct maven_gamma*
g;
1089 g = maven_compute_gamma(md);
1090 maven_set_reg(md->
client, 0x83, g->reg83);
1091 maven_set_reg(md->
client, 0x84, g->reg84);
1092 maven_set_reg(md->
client, 0x85, g->reg85);
1093 maven_set_reg(md->
client, 0
x86, g->reg86);
1094 maven_set_reg(md->
client, 0x87, g->reg87);
1095 maven_set_reg(md->
client, 0x88, g->reg88);
1096 maven_set_reg(md->
client, 0x89, g->reg89);
1097 maven_set_reg(md->
client, 0x8a, g->reg8a);
1098 maven_set_reg(md->
client, 0x8b, g->reg8b);
1104 = maven_get_reg(md->
client, 0x8d);
1105 if (p->
value) val |= 0x10;
1107 maven_set_reg(md->
client, 0x8d, val);
1112 maven_set_reg(md->
client, 0x93, maven_compute_deflicker(md));
1121 static int maven_get_control (
struct maven_data* md,
1125 i = get_ctrl_id(p->
id);
1126 if (i < 0)
return -
EINVAL;
1127 p->
value = *get_ctrl_ptr(md, i);
1133 static int maven_out_compute(
void* md,
struct my_timming* mt) {
1134 #define mdinfo ((struct maven_data*)md)
1135 #define minfo (mdinfo->primary_head)
1136 return maven_compute_timming(md, mt, &minfo->
hw.maven);
1141 static int maven_out_program(
void* md) {
1142 #define mdinfo ((struct maven_data*)md)
1143 #define minfo (mdinfo->primary_head)
1144 return maven_program_timming(md, &minfo->
hw.maven);
1149 static int maven_out_start(
void* md) {
1150 return maven_resync(md);
1153 static int maven_out_verify_mode(
void* md,
u_int32_t arg) {
1163 static int maven_out_get_queryctrl(
void* md,
struct v4l2_queryctrl* p) {
1164 return maven_get_queryctrl(md, p);
1167 static int maven_out_get_ctrl(
void* md,
struct v4l2_control* p) {
1168 return maven_get_control(md, p);
1171 static int maven_out_set_ctrl(
void* md,
struct v4l2_control* p) {
1172 return maven_set_control(md, p);
1176 .name =
"Secondary output",
1177 .compute = maven_out_compute,
1178 .program = maven_out_program,
1179 .start = maven_out_start,
1180 .verifymode = maven_out_verify_mode,
1181 .getqueryctrl = maven_out_get_queryctrl,
1182 .getctrl = maven_out_get_ctrl,
1183 .setctrl = maven_out_set_ctrl,
1186 static int maven_init_client(
struct i2c_client* clnt) {
1187 struct maven_data* md = i2c_get_clientdata(clnt);
1195 minfo->
outputs[1].output = &maven_altout;
1200 if (maven_get_reg(clnt, 0xB2) < 0x14) {
1213 *get_ctrl_ptr(md, i) = maven_controls[
i].
desc.default_value;
1220 static int maven_shutdown_client(
struct i2c_client* clnt) {
1221 struct maven_data* md = i2c_get_clientdata(clnt);
1249 if (!(data = kzalloc(
sizeof(*data),
GFP_KERNEL))) {
1253 i2c_set_clientdata(client, data);
1254 err = maven_init_client(client);
1264 static int maven_remove(
struct i2c_client *client)
1266 maven_shutdown_client(client);
1267 kfree(i2c_get_clientdata(client));
1281 .probe = maven_probe,
1282 .remove = maven_remove,
1283 .id_table = maven_id,
1286 static int __init matroxfb_maven_init(
void)
1288 return i2c_add_driver(&maven_driver);
1291 static void __exit matroxfb_maven_exit(
void)