13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/string.h>
23 #include <linux/pci.h>
28 static char *mode_option;
29 static int noclear, nopanel, nocrt;
40 {
NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2,
44 {
NULL, 70, 640, 400, 39770, 40, 8, 28, 5, 96, 2,
48 {
NULL, 70, 640, 480, 35014, 88, 24, 15, 2, 64, 3,
51 {
NULL, 72, 640, 480, 32102, 120, 16, 20, 1, 40, 3,
55 {
NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
59 {
NULL, 85, 640, 480, 27780, 80, 56, 25, 1, 56, 3,
63 {
NULL, 90, 640, 480, 26392, 96, 32, 22, 1, 64, 3,
66 {
NULL, 100, 640, 480, 23167, 104, 40, 25, 1, 64, 3,
69 {
NULL, 60, 640, 480, 39682, 48, 16, 25, 10, 88, 2,
73 {
NULL, 56, 800, 600, 27901, 128, 24, 22, 1, 72, 2,
76 {
NULL, 60, 800, 600, 25131, 72, 32, 23, 1, 136, 4,
79 {
NULL, 70, 800, 600, 21873, 120, 40, 21, 4, 80, 3,
82 {
NULL, 72, 800, 600, 20052, 64, 56, 23, 37, 120, 6,
85 {
NULL, 75, 800, 600, 20202, 160, 16, 21, 1, 80, 3,
88 {
NULL, 85, 800, 600, 17790, 152, 32, 27, 1, 64, 3,
91 {
NULL, 90, 800, 600, 16648, 128, 40, 28, 1, 88, 3,
94 {
NULL, 100, 800, 600, 14667, 136, 48, 27, 1, 88, 3,
97 {
NULL, 60, 800, 600, 25131, 88, 40, 23, 1, 128, 4,
101 {
NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
105 {
NULL, 70, 1024, 768, 13346, 144, 24, 29, 3, 136, 6,
109 {
NULL, 72, 1024, 768, 12702, 168, 56, 29, 4, 112, 3,
112 {
NULL, 75, 1024, 768, 12703, 176, 16, 28, 1, 96, 3,
115 {
NULL, 85, 1024, 768, 10581, 208, 48, 36, 1, 96, 3,
118 {
NULL, 90, 1024, 768, 9981, 176, 64, 37, 1, 112, 3,
121 {
NULL, 100, 1024, 768, 8825, 184, 72, 42, 1, 112, 3,
124 {
NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
128 {
NULL, 60, 1152, 864, 12251, 184, 64, 27, 1, 120, 3,
131 {
NULL, 70, 1152, 864, 10254, 192, 72, 32, 8, 120, 3,
134 {
NULL, 72, 1152, 864, 9866, 200, 72, 33, 7, 128, 3,
137 {
NULL, 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3,
140 {
NULL, 85, 1152, 864, 8357, 200, 72, 37, 3, 128, 3,
143 {
NULL, 90, 1152, 864, 7719, 208, 80, 42, 9, 128, 3,
146 {
NULL, 100, 1152, 864, 6947, 208, 80, 48, 3, 128, 3,
149 {
NULL, 60, 1152, 864, 12251, 184, 64, 27, 1, 120, 3,
153 {
NULL, 60, 1280, 1024, 9262, 248, 48, 38, 1, 112, 3,
156 {
NULL, 70, 1280, 1024, 7719, 224, 88, 38, 6, 136, 3,
159 {
NULL, 72, 1280, 1024, 7490, 224, 88, 39, 7, 136, 3,
162 {
NULL, 75, 1280, 1024, 7409, 248, 16, 38, 1, 144, 3,
165 {
NULL, 85, 1280, 1024, 6351, 224, 64, 44, 1, 160, 3,
168 {
NULL, 90, 1280, 1024, 5791, 240, 96, 51, 12, 144, 3,
171 {
NULL, 100, 1280, 1024, 5212, 240, 96, 57, 6, 144, 3,
174 {
NULL, 60, 1280, 1024, 9262, 248, 48, 38, 1, 112, 3,
178 {
NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
181 {
NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
184 {
NULL, 72, 1600, 1200, 5053, 288, 112, 47, 13, 176, 3,
187 {
NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
190 {
NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
193 {
NULL, 90, 1600, 1200, 3981, 304, 128, 60, 1, 176, 3,
196 {
NULL, 100, 1600, 1200, 3563, 304, 128, 67, 1, 176, 3,
199 {
NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
203 {
NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 208, 3,
206 {
NULL, 70, 1920, 1440, 3593, 360, 152, 55, 8, 208, 3,
209 {
NULL, 72, 1920, 1440, 3472, 360, 152, 68, 4, 208, 3,
212 {
NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
215 {
NULL, 85, 1920, 1440, 2929, 368, 152, 68, 1, 216, 3,
222 static struct fb_videomode olpc_dcon_modedb[] __devinitdata = {
224 {
NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
232 if (olpc_has_dcon()) {
252 if (var->
xres > 1920 || var->
yres > 1440)
256 var->
red.offset = 16; var->
red.length = 8;
258 var->
blue.offset = 0; var->
blue.length = 8;
260 var->
red.offset = 11; var->
red.length = 5;
262 var->
blue.offset = 0; var->
blue.length = 5;
264 var->
red.offset = 0; var->
red.length = 8;
266 var->
blue.offset = 0; var->
blue.length = 8;
274 > info->
fix.smem_len)
280 static int lxfb_set_par(
struct fb_info *info)
282 if (info->
var.bits_per_pixel > 8)
287 info->
fix.line_length = lx_get_pitch(info->
var.xres,
288 info->
var.bits_per_pixel);
298 return chan << bf->
offset;
301 static int lxfb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
305 if (info->
var.grayscale) {
307 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
318 v = chan_to_field(red, &info->
var.red);
319 v |= chan_to_field(green, &info->
var.green);
320 v |= chan_to_field(blue, &info->
var.blue);
333 static int lxfb_blank(
int blank_mode,
struct fb_info *info)
399 dev_info(&dev->
dev,
"%d KB of video memory at 0x%lx\n",
400 info->
fix.smem_len / 1024, info->
fix.smem_start);
405 static struct fb_ops lxfb_ops = {
407 .fb_check_var = lxfb_check_var,
408 .fb_set_par = lxfb_set_par,
409 .fb_setcolreg = lxfb_setcolreg,
410 .fb_blank = lxfb_blank,
433 info->
fix.type_aux = 0;
434 info->
fix.xpanstep = 0;
435 info->
fix.ypanstep = 0;
436 info->
fix.ywrapstep = 0;
439 info->
var.nonstd = 0;
441 info->
var.height = -1;
442 info->
var.width = -1;
443 info->
var.accel_flags = 0;
446 info->
fbops = &lxfb_ops;
457 info->
var.grayscale = 0;
465 struct fb_info *info = pci_get_drvdata(pdev);
482 struct fb_info *info = pci_get_drvdata(pdev);
486 ret = lx_powerup(info);
497 #define lxfb_suspend NULL
498 #define lxfb_resume NULL
509 unsigned int modedb_size;
511 info = lxfb_init_fbinfo(&pdev->
dev);
518 ret = lxfb_map_video_memory(info, pdev);
522 "failed to map frame buffer or controller registers\n");
534 get_modedb(&modedb_ptr, &modedb_size);
536 modedb_ptr, modedb_size,
NULL, 16);
538 if (ret == 0 || ret == 4) {
539 dev_err(&pdev->
dev,
"could not find valid video mode\n");
552 lxfb_check_var(&info->
var, info);
561 pci_set_drvdata(pdev, info);
595 struct fb_info *info = pci_get_drvdata(pdev);
613 pci_set_drvdata(pdev,
NULL);
626 .id_table = lxfb_id_table,
628 .remove = lxfb_remove,
638 if (!options || !*options)
641 while ((opt =
strsep(&options,
",")) !=
NULL) {
645 if (!
strcmp(opt,
"noclear"))
647 else if (!
strcmp(opt,
"nopanel"))
649 else if (!
strcmp(opt,
"nocrt"))
659 static int __init lxfb_init(
void)
669 return pci_register_driver(&lxfb_driver);
671 static void __exit lxfb_cleanup(
void)