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