drm/nouveau: off by one in init_i2c_device_find()
[safe/jmp/linux-2.6] / drivers / video / macmodes.c
index de5a0f3..af86c08 100644 (file)
@@ -15,7 +15,6 @@
  *  more details.
  */
 
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/fb.h>
 #include <linux/string.h>
 
 static const struct fb_videomode mac_modedb[] = {
     {
+       /* 512x384, 60Hz, Non-Interlaced (15.67 MHz dot clock) */
+       "mac2", 60, 512, 384, 63828, 80, 16, 19, 1, 32, 3,
+       0, FB_VMODE_NONINTERLACED
+    }, {
        /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
        "mac5", 60, 640, 480, 39722, 32, 32, 33, 10, 96, 2,
        0, FB_VMODE_NONINTERLACED
@@ -42,6 +45,10 @@ static const struct fb_videomode mac_modedb[] = {
        "mac6", 67, 640, 480, 33334, 80, 80, 39, 3, 64, 3,
        0, FB_VMODE_NONINTERLACED
     }, {
+       /* 640x870, 75Hz (portrait), Non-Interlaced (57.28 MHz dot clock) */
+       "mac7", 75, 640, 870, 17457, 80, 32, 42, 3, 80, 3,
+       0, FB_VMODE_NONINTERLACED
+    }, {
        /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */
        "mac9", 56, 800, 600, 27778, 112, 40, 22, 1, 72, 2,
        FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
@@ -106,10 +113,6 @@ static const struct fb_videomode mac_modedb[] = {
        "mac1", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
        sync, FB_VMODE_INTERLACED
     }, {
-       /* VMODE_512_384_60: 512x384, 60Hz, Non-Interlaced */
-       "mac2", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
-       sync, FB_VMODE_NONINTERLACED
-    }, {
        /* VMODE_640_480_50I: 640x480, 50Hz, Interlaced (PAL) */
        "mac3", 50, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
        sync, FB_VMODE_INTERLACED
@@ -118,10 +121,6 @@ static const struct fb_videomode mac_modedb[] = {
        "mac4", 60, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
        sync, FB_VMODE_INTERLACED
     }, {
-       /* VMODE_640_870_75P: 640x870, 75Hz (portrait), Non-Interlaced */
-       "mac7", 75, 640, 870, pixclock, left, right, upper, lower, hslen, vslen,
-       sync, FB_VMODE_NONINTERLACED
-    }, {
        /* VMODE_768_576_50I: 768x576, 50Hz (PAL full frame), Interlaced */
        "mac8", 50, 768, 576, pixclock, left, right, upper, lower, hslen, vslen,
        sync, FB_VMODE_INTERLACED
@@ -135,38 +134,42 @@ static const struct fb_videomode mac_modedb[] = {
      *
      *  These MUST be ordered in
      *    - increasing resolution
-     *    - decreasing refresh rate
+     *    - decreasing pixel clock period
      */
 
 static const struct mode_map {
     int vmode;
     const struct fb_videomode *mode;
 } mac_modes[] = {
+    /* 512x384 */
+    { VMODE_512_384_60, &mac_modedb[0] },
     /* 640x480 */
-    { VMODE_640_480_67, &mac_modedb[1] },
-    { VMODE_640_480_60, &mac_modedb[0] },
+    { VMODE_640_480_60, &mac_modedb[1] },
+    { VMODE_640_480_67, &mac_modedb[2] },
+    /* 640x870 */
+    { VMODE_640_870_75P, &mac_modedb[3] },
     /* 800x600 */
-    { VMODE_800_600_75, &mac_modedb[5] },
-    { VMODE_800_600_72, &mac_modedb[4] },
-    { VMODE_800_600_60, &mac_modedb[3] },
-    { VMODE_800_600_56, &mac_modedb[2] },
+    { VMODE_800_600_56, &mac_modedb[4] },
+    { VMODE_800_600_60, &mac_modedb[5] },
+    { VMODE_800_600_75, &mac_modedb[7] },
+    { VMODE_800_600_72, &mac_modedb[6] },
     /* 832x624 */
-    { VMODE_832_624_75, &mac_modedb[6] },
+    { VMODE_832_624_75, &mac_modedb[8] },
     /* 1024x768 */
-    { VMODE_1024_768_75, &mac_modedb[10] },
-    { VMODE_1024_768_75V, &mac_modedb[9] },
-    { VMODE_1024_768_70, &mac_modedb[8] },
-    { VMODE_1024_768_60, &mac_modedb[7] },
+    { VMODE_1024_768_60, &mac_modedb[9] },
+    { VMODE_1024_768_70, &mac_modedb[10] },
+    { VMODE_1024_768_75V, &mac_modedb[11] },
+    { VMODE_1024_768_75, &mac_modedb[12] },
     /* 1152x768 */
-    { VMODE_1152_768_60, &mac_modedb[14] },
+    { VMODE_1152_768_60, &mac_modedb[16] },
     /* 1152x870 */
-    { VMODE_1152_870_75, &mac_modedb[11] },
+    { VMODE_1152_870_75, &mac_modedb[13] },
     /* 1280x960 */
-    { VMODE_1280_960_75, &mac_modedb[12] },
+    { VMODE_1280_960_75, &mac_modedb[14] },
     /* 1280x1024 */
-    { VMODE_1280_1024_75, &mac_modedb[13] },
+    { VMODE_1280_1024_75, &mac_modedb[15] },
     /* 1600x1024 */
-    { VMODE_1600_1024_60, &mac_modedb[15] },
+    { VMODE_1600_1024_60, &mac_modedb[17] },
     { -1, NULL }
 };
 
@@ -300,7 +303,6 @@ EXPORT_SYMBOL(mac_vmode_to_var);
 int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
                     int *cmode)
 {
-    const struct fb_videomode *mode = NULL;
     const struct mode_map *map;
 
     if (var->bits_per_pixel <= 8)
@@ -312,8 +314,13 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
     else
        return -EINVAL;
 
+    /*
+     * Find the mac_mode with a matching resolution or failing that, the
+     * closest larger resolution. Skip modes with a shorter pixel clock period.
+     */
     for (map = mac_modes; map->vmode != -1; map++) {
-       mode = map->mode;
+       const struct fb_videomode *mode = map->mode;
+
        if (var->xres > mode->xres || var->yres > mode->yres)
            continue;
        if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres)
@@ -323,11 +330,28 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
        if ((var->vmode & FB_VMODE_MASK) != mode->vmode)
            continue;
        *vmode = map->vmode;
+
+       /*
+        * Having found a good resolution, find the matching pixel clock
+        * or failing that, the closest longer pixel clock period.
+        */
+       map++;
+       while (map->vmode != -1) {
+           const struct fb_videomode *clk_mode = map->mode;
+
+           if (mode->xres != clk_mode->xres || mode->yres != clk_mode->yres)
+               break;
+           if (var->pixclock > mode->pixclock)
+               break;
+           if (mode->vmode != clk_mode->vmode)
+               continue;
+           *vmode = map->vmode;
+           map++;
+       }
        return 0;
     }
     return -EINVAL;
 }
-EXPORT_SYMBOL(mac_var_to_vmode);
 
 /**
  *     mac_map_monitor_sense - Convert monitor sense to vmode
@@ -371,8 +395,8 @@ EXPORT_SYMBOL(mac_map_monitor_sense);
  *
  */
 
-int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
-                        const char *mode_option, unsigned int default_bpp)
+int mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
+                 const char *mode_option, unsigned int default_bpp)
 {
     const struct fb_videomode *db = NULL;
     unsigned int dbsize = 0;
@@ -380,10 +404,11 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
     if (mode_option && !strncmp(mode_option, "mac", 3)) {
        mode_option += 3;
        db = mac_modedb;
-       dbsize = sizeof(mac_modedb)/sizeof(*mac_modedb);
+       dbsize = ARRAY_SIZE(mac_modedb);
     }
     return fb_find_mode(var, info, mode_option, db, dbsize,
                        &mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp);
 }
 EXPORT_SYMBOL(mac_find_mode);
 
+MODULE_LICENSE("GPL");