at v2.6.21 389 lines 12 kB view raw
1/* 2 * linux/drivers/video/macmodes.c -- Standard MacOS video modes 3 * 4 * Copyright (C) 1998 Geert Uytterhoeven 5 * 6 * 2000 - Removal of OpenFirmware dependencies by: 7 * - Ani Joshi 8 * - Brad Douglas <brad@neruo.com> 9 * 10 * 2001 - Documented with DocBook 11 * - Brad Douglas <brad@neruo.com> 12 * 13 * This file is subject to the terms and conditions of the GNU General Public 14 * License. See the file COPYING in the main directory of this archive for 15 * more details. 16 */ 17 18#include <linux/errno.h> 19#include <linux/fb.h> 20#include <linux/string.h> 21#include <linux/module.h> 22 23#include "macmodes.h" 24 25 /* 26 * MacOS video mode definitions 27 * 28 * Order IS important! If you change these, don't forget to update 29 * mac_modes[] below! 30 */ 31 32#define DEFAULT_MODEDB_INDEX 0 33 34static const struct fb_videomode mac_modedb[] = { 35 { 36 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 37 "mac5", 60, 640, 480, 39722, 32, 32, 33, 10, 96, 2, 38 0, FB_VMODE_NONINTERLACED 39 }, { 40 /* 640x480, 67Hz, Non-Interlaced (30.0 MHz dotclock) */ 41 "mac6", 67, 640, 480, 33334, 80, 80, 39, 3, 64, 3, 42 0, FB_VMODE_NONINTERLACED 43 }, { 44 /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */ 45 "mac9", 56, 800, 600, 27778, 112, 40, 22, 1, 72, 2, 46 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 47 }, { 48 /* 800x600, 60 Hz, Non-Interlaced (40.00 MHz dotclock) */ 49 "mac10", 60, 800, 600, 25000, 72, 56, 23, 1, 128, 4, 50 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 51 }, { 52 /* 800x600, 72 Hz, Non-Interlaced (50.00 MHz dotclock) */ 53 "mac11", 72, 800, 600, 20000, 48, 72, 23, 37, 120, 6, 54 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 55 }, { 56 /* 800x600, 75 Hz, Non-Interlaced (49.50 MHz dotclock) */ 57 "mac12", 75, 800, 600, 20203, 144, 32, 21, 1, 80, 3, 58 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 59 }, { 60 /* 832x624, 75Hz, Non-Interlaced (57.6 MHz dotclock) */ 61 "mac13", 75, 832, 624, 17362, 208, 48, 39, 1, 64, 3, 62 0, FB_VMODE_NONINTERLACED 63 }, { 64 /* 1024x768, 60 Hz, Non-Interlaced (65.00 MHz dotclock) */ 65 "mac14", 60, 1024, 768, 15385, 144, 40, 29, 3, 136, 6, 66 0, FB_VMODE_NONINTERLACED 67 }, { 68 /* 1024x768, 72 Hz, Non-Interlaced (75.00 MHz dotclock) */ 69 "mac15", 72, 1024, 768, 13334, 128, 40, 29, 3, 136, 6, 70 0, FB_VMODE_NONINTERLACED 71 }, { 72 /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */ 73 "mac16", 75, 1024, 768, 12699, 176, 16, 28, 1, 96, 3, 74 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 75 }, { 76 /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */ 77 "mac17", 75, 1024, 768, 12699, 160, 32, 28, 1, 96, 3, 78 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 79 }, { 80 /* 1152x870, 75 Hz, Non-Interlaced (100.0 MHz dotclock) */ 81 "mac18", 75, 1152, 870, 10000, 128, 48, 39, 3, 128, 3, 82 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 83 }, { 84 /* 1280x960, 75 Hz, Non-Interlaced (126.00 MHz dotclock) */ 85 "mac19", 75, 1280, 960, 7937, 224, 32, 36, 1, 144, 3, 86 0, FB_VMODE_NONINTERLACED 87 }, { 88 /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */ 89 "mac20", 75, 1280, 1024, 7408, 232, 64, 38, 1, 112, 3, 90 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 91 }, { 92 /* 1152x768, 60 Hz, Titanium PowerBook */ 93 "mac21", 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, 94 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 95 }, { 96 /* 1600x1024, 60 Hz, Non-Interlaced (112.27 MHz dotclock) */ 97 "mac22", 60, 1600, 1024, 8908, 88, 104, 1, 10, 16, 1, 98 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 99 } 100 101#if 0 102 /* Anyone who has timings for these? */ 103 { 104 /* VMODE_512_384_60I: 512x384, 60Hz, Interlaced (NTSC) */ 105 "mac1", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen, 106 sync, FB_VMODE_INTERLACED 107 }, { 108 /* VMODE_512_384_60: 512x384, 60Hz, Non-Interlaced */ 109 "mac2", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen, 110 sync, FB_VMODE_NONINTERLACED 111 }, { 112 /* VMODE_640_480_50I: 640x480, 50Hz, Interlaced (PAL) */ 113 "mac3", 50, 640, 480, pixclock, left, right, upper, lower, hslen, vslen, 114 sync, FB_VMODE_INTERLACED 115 }, { 116 /* VMODE_640_480_60I: 640x480, 60Hz, Interlaced (NTSC) */ 117 "mac4", 60, 640, 480, pixclock, left, right, upper, lower, hslen, vslen, 118 sync, FB_VMODE_INTERLACED 119 }, { 120 /* VMODE_640_870_75P: 640x870, 75Hz (portrait), Non-Interlaced */ 121 "mac7", 75, 640, 870, pixclock, left, right, upper, lower, hslen, vslen, 122 sync, FB_VMODE_NONINTERLACED 123 }, { 124 /* VMODE_768_576_50I: 768x576, 50Hz (PAL full frame), Interlaced */ 125 "mac8", 50, 768, 576, pixclock, left, right, upper, lower, hslen, vslen, 126 sync, FB_VMODE_INTERLACED 127 }, 128#endif 129}; 130 131 132 /* 133 * Mapping between MacOS video mode numbers and video mode definitions 134 * 135 * These MUST be ordered in 136 * - increasing resolution 137 * - decreasing refresh rate 138 */ 139 140static const struct mode_map { 141 int vmode; 142 const struct fb_videomode *mode; 143} mac_modes[] = { 144 /* 640x480 */ 145 { VMODE_640_480_67, &mac_modedb[1] }, 146 { VMODE_640_480_60, &mac_modedb[0] }, 147 /* 800x600 */ 148 { VMODE_800_600_75, &mac_modedb[5] }, 149 { VMODE_800_600_72, &mac_modedb[4] }, 150 { VMODE_800_600_60, &mac_modedb[3] }, 151 { VMODE_800_600_56, &mac_modedb[2] }, 152 /* 832x624 */ 153 { VMODE_832_624_75, &mac_modedb[6] }, 154 /* 1024x768 */ 155 { VMODE_1024_768_75, &mac_modedb[10] }, 156 { VMODE_1024_768_75V, &mac_modedb[9] }, 157 { VMODE_1024_768_70, &mac_modedb[8] }, 158 { VMODE_1024_768_60, &mac_modedb[7] }, 159 /* 1152x768 */ 160 { VMODE_1152_768_60, &mac_modedb[14] }, 161 /* 1152x870 */ 162 { VMODE_1152_870_75, &mac_modedb[11] }, 163 /* 1280x960 */ 164 { VMODE_1280_960_75, &mac_modedb[12] }, 165 /* 1280x1024 */ 166 { VMODE_1280_1024_75, &mac_modedb[13] }, 167 /* 1600x1024 */ 168 { VMODE_1600_1024_60, &mac_modedb[15] }, 169 { -1, NULL } 170}; 171 172 173 /* 174 * Mapping between monitor sense values and MacOS video mode numbers 175 */ 176 177static const struct monitor_map { 178 int sense; 179 int vmode; 180} mac_monitors[] = { 181 { 0x000, VMODE_1280_1024_75 }, /* 21" RGB */ 182 { 0x114, VMODE_640_870_75P }, /* Portrait Monochrome */ 183 { 0x221, VMODE_512_384_60 }, /* 12" RGB*/ 184 { 0x331, VMODE_1280_1024_75 }, /* 21" RGB (Radius) */ 185 { 0x334, VMODE_1280_1024_75 }, /* 21" mono (Radius) */ 186 { 0x335, VMODE_1280_1024_75 }, /* 21" mono */ 187 { 0x40A, VMODE_640_480_60I }, /* NTSC */ 188 { 0x51E, VMODE_640_870_75P }, /* Portrait RGB */ 189 { 0x603, VMODE_832_624_75 }, /* 12"-16" multiscan */ 190 { 0x60b, VMODE_1024_768_70 }, /* 13"-19" multiscan */ 191 { 0x623, VMODE_1152_870_75 }, /* 13"-21" multiscan */ 192 { 0x62b, VMODE_640_480_67 }, /* 13"/14" RGB */ 193 { 0x700, VMODE_640_480_50I }, /* PAL */ 194 { 0x714, VMODE_640_480_60I }, /* NTSC */ 195 { 0x717, VMODE_800_600_75 }, /* VGA */ 196 { 0x72d, VMODE_832_624_75 }, /* 16" RGB (Goldfish) */ 197 { 0x730, VMODE_768_576_50I }, /* PAL (Alternate) */ 198 { 0x73a, VMODE_1152_870_75 }, /* 3rd party 19" */ 199 { 0x73f, VMODE_640_480_67 }, /* no sense lines connected at all */ 200 { 0xBEEF, VMODE_1600_1024_60 }, /* 22" Apple Cinema Display */ 201 { -1, VMODE_640_480_60 }, /* catch-all, must be last */ 202}; 203 204/** 205 * mac_vmode_to_var - converts vmode/cmode pair to var structure 206 * @vmode: MacOS video mode 207 * @cmode: MacOS color mode 208 * @var: frame buffer video mode structure 209 * 210 * Converts a MacOS vmode/cmode pair to a frame buffer video 211 * mode structure. 212 * 213 * Returns negative errno on error, or zero for success. 214 * 215 */ 216 217int mac_vmode_to_var(int vmode, int cmode, struct fb_var_screeninfo *var) 218{ 219 const struct fb_videomode *mode = NULL; 220 const struct mode_map *map; 221 222 for (map = mac_modes; map->vmode != -1; map++) 223 if (map->vmode == vmode) { 224 mode = map->mode; 225 break; 226 } 227 if (!mode) 228 return -EINVAL; 229 230 memset(var, 0, sizeof(struct fb_var_screeninfo)); 231 switch (cmode) { 232 case CMODE_8: 233 var->bits_per_pixel = 8; 234 var->red.offset = 0; 235 var->red.length = 8; 236 var->green.offset = 0; 237 var->green.length = 8; 238 var->blue.offset = 0; 239 var->blue.length = 8; 240 break; 241 242 case CMODE_16: 243 var->bits_per_pixel = 16; 244 var->red.offset = 10; 245 var->red.length = 5; 246 var->green.offset = 5; 247 var->green.length = 5; 248 var->blue.offset = 0; 249 var->blue.length = 5; 250 break; 251 252 case CMODE_32: 253 var->bits_per_pixel = 32; 254 var->red.offset = 16; 255 var->red.length = 8; 256 var->green.offset = 8; 257 var->green.length = 8; 258 var->blue.offset = 0; 259 var->blue.length = 8; 260 var->transp.offset = 24; 261 var->transp.length = 8; 262 break; 263 264 default: 265 return -EINVAL; 266 } 267 var->xres = mode->xres; 268 var->yres = mode->yres; 269 var->xres_virtual = mode->xres; 270 var->yres_virtual = mode->yres; 271 var->height = -1; 272 var->width = -1; 273 var->pixclock = mode->pixclock; 274 var->left_margin = mode->left_margin; 275 var->right_margin = mode->right_margin; 276 var->upper_margin = mode->upper_margin; 277 var->lower_margin = mode->lower_margin; 278 var->hsync_len = mode->hsync_len; 279 var->vsync_len = mode->vsync_len; 280 var->sync = mode->sync; 281 var->vmode = mode->vmode; 282 return 0; 283} 284EXPORT_SYMBOL(mac_vmode_to_var); 285 286/** 287 * mac_var_to_vmode - convert var structure to MacOS vmode/cmode pair 288 * @var: frame buffer video mode structure 289 * @vmode: MacOS video mode 290 * @cmode: MacOS color mode 291 * 292 * Converts a frame buffer video mode structure to a MacOS 293 * vmode/cmode pair. 294 * 295 * Returns negative errno on error, or zero for success. 296 * 297 */ 298 299int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, 300 int *cmode) 301{ 302 const struct fb_videomode *mode = NULL; 303 const struct mode_map *map; 304 305 if (var->bits_per_pixel <= 8) 306 *cmode = CMODE_8; 307 else if (var->bits_per_pixel <= 16) 308 *cmode = CMODE_16; 309 else if (var->bits_per_pixel <= 32) 310 *cmode = CMODE_32; 311 else 312 return -EINVAL; 313 314 for (map = mac_modes; map->vmode != -1; map++) { 315 mode = map->mode; 316 if (var->xres > mode->xres || var->yres > mode->yres) 317 continue; 318 if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres) 319 continue; 320 if (var->pixclock > mode->pixclock) 321 continue; 322 if ((var->vmode & FB_VMODE_MASK) != mode->vmode) 323 continue; 324 *vmode = map->vmode; 325 return 0; 326 } 327 return -EINVAL; 328} 329 330/** 331 * mac_map_monitor_sense - Convert monitor sense to vmode 332 * @sense: Macintosh monitor sense number 333 * 334 * Converts a Macintosh monitor sense number to a MacOS 335 * vmode number. 336 * 337 * Returns MacOS vmode video mode number. 338 * 339 */ 340 341int mac_map_monitor_sense(int sense) 342{ 343 const struct monitor_map *map; 344 345 for (map = mac_monitors; map->sense != -1; map++) 346 if (map->sense == sense) 347 break; 348 return map->vmode; 349} 350EXPORT_SYMBOL(mac_map_monitor_sense); 351 352/** 353 * mac_find_mode - find a video mode 354 * @var: frame buffer user defined part of display 355 * @info: frame buffer info structure 356 * @mode_option: video mode name (see mac_modedb[]) 357 * @default_bpp: default color depth in bits per pixel 358 * 359 * Finds a suitable video mode. Tries to set mode specified 360 * by @mode_option. If the name of the wanted mode begins with 361 * 'mac', the Mac video mode database will be used, otherwise it 362 * will fall back to the standard video mode database. 363 * 364 * Note: Function marked as __init and can only be used during 365 * system boot. 366 * 367 * Returns error code from fb_find_mode (see fb_find_mode 368 * function). 369 * 370 */ 371 372int __devinit mac_find_mode(struct fb_var_screeninfo *var, 373 struct fb_info *info, const char *mode_option, 374 unsigned int default_bpp) 375{ 376 const struct fb_videomode *db = NULL; 377 unsigned int dbsize = 0; 378 379 if (mode_option && !strncmp(mode_option, "mac", 3)) { 380 mode_option += 3; 381 db = mac_modedb; 382 dbsize = ARRAY_SIZE(mac_modedb); 383 } 384 return fb_find_mode(var, info, mode_option, db, dbsize, 385 &mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp); 386} 387EXPORT_SYMBOL(mac_find_mode); 388 389MODULE_LICENSE("GPL");