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}; 102 103 104 /* 105 * Mapping between MacOS video mode numbers and video mode definitions 106 * 107 * These MUST be ordered in 108 * - increasing resolution 109 * - decreasing refresh rate 110 */ 111 112static const struct mode_map { 113 int vmode; 114 const struct fb_videomode *mode; 115} mac_modes[] = { 116 /* 640x480 */ 117 { VMODE_640_480_67, &mac_modedb[1] }, 118 { VMODE_640_480_60, &mac_modedb[0] }, 119 /* 800x600 */ 120 { VMODE_800_600_75, &mac_modedb[5] }, 121 { VMODE_800_600_72, &mac_modedb[4] }, 122 { VMODE_800_600_60, &mac_modedb[3] }, 123 { VMODE_800_600_56, &mac_modedb[2] }, 124 /* 832x624 */ 125 { VMODE_832_624_75, &mac_modedb[6] }, 126 /* 1024x768 */ 127 { VMODE_1024_768_75, &mac_modedb[10] }, 128 { VMODE_1024_768_75V, &mac_modedb[9] }, 129 { VMODE_1024_768_70, &mac_modedb[8] }, 130 { VMODE_1024_768_60, &mac_modedb[7] }, 131 /* 1152x768 */ 132 { VMODE_1152_768_60, &mac_modedb[14] }, 133 /* 1152x870 */ 134 { VMODE_1152_870_75, &mac_modedb[11] }, 135 /* 1280x960 */ 136 { VMODE_1280_960_75, &mac_modedb[12] }, 137 /* 1280x1024 */ 138 { VMODE_1280_1024_75, &mac_modedb[13] }, 139 /* 1600x1024 */ 140 { VMODE_1600_1024_60, &mac_modedb[15] }, 141 { -1, NULL } 142}; 143 144 145 /* 146 * Mapping between monitor sense values and MacOS video mode numbers 147 */ 148 149static const struct monitor_map { 150 int sense; 151 int vmode; 152} mac_monitors[] = { 153 { 0x000, VMODE_1280_1024_75 }, /* 21" RGB */ 154 { 0x114, VMODE_640_870_75P }, /* Portrait Monochrome */ 155 { 0x221, VMODE_512_384_60 }, /* 12" RGB*/ 156 { 0x331, VMODE_1280_1024_75 }, /* 21" RGB (Radius) */ 157 { 0x334, VMODE_1280_1024_75 }, /* 21" mono (Radius) */ 158 { 0x335, VMODE_1280_1024_75 }, /* 21" mono */ 159 { 0x40A, VMODE_640_480_60I }, /* NTSC */ 160 { 0x51E, VMODE_640_870_75P }, /* Portrait RGB */ 161 { 0x603, VMODE_832_624_75 }, /* 12"-16" multiscan */ 162 { 0x60b, VMODE_1024_768_70 }, /* 13"-19" multiscan */ 163 { 0x623, VMODE_1152_870_75 }, /* 13"-21" multiscan */ 164 { 0x62b, VMODE_640_480_67 }, /* 13"/14" RGB */ 165 { 0x700, VMODE_640_480_50I }, /* PAL */ 166 { 0x714, VMODE_640_480_60I }, /* NTSC */ 167 { 0x717, VMODE_800_600_75 }, /* VGA */ 168 { 0x72d, VMODE_832_624_75 }, /* 16" RGB (Goldfish) */ 169 { 0x730, VMODE_768_576_50I }, /* PAL (Alternate) */ 170 { 0x73a, VMODE_1152_870_75 }, /* 3rd party 19" */ 171 { 0x73f, VMODE_640_480_67 }, /* no sense lines connected at all */ 172 { 0xBEEF, VMODE_1600_1024_60 }, /* 22" Apple Cinema Display */ 173 { -1, VMODE_640_480_60 }, /* catch-all, must be last */ 174}; 175 176/** 177 * mac_vmode_to_var - converts vmode/cmode pair to var structure 178 * @vmode: MacOS video mode 179 * @cmode: MacOS color mode 180 * @var: frame buffer video mode structure 181 * 182 * Converts a MacOS vmode/cmode pair to a frame buffer video 183 * mode structure. 184 * 185 * Returns negative errno on error, or zero for success. 186 * 187 */ 188 189int mac_vmode_to_var(int vmode, int cmode, struct fb_var_screeninfo *var) 190{ 191 const struct fb_videomode *mode = NULL; 192 const struct mode_map *map; 193 194 for (map = mac_modes; map->vmode != -1; map++) 195 if (map->vmode == vmode) { 196 mode = map->mode; 197 break; 198 } 199 if (!mode) 200 return -EINVAL; 201 202 memset(var, 0, sizeof(struct fb_var_screeninfo)); 203 switch (cmode) { 204 case CMODE_8: 205 var->bits_per_pixel = 8; 206 var->red.offset = 0; 207 var->red.length = 8; 208 var->green.offset = 0; 209 var->green.length = 8; 210 var->blue.offset = 0; 211 var->blue.length = 8; 212 break; 213 214 case CMODE_16: 215 var->bits_per_pixel = 16; 216 var->red.offset = 10; 217 var->red.length = 5; 218 var->green.offset = 5; 219 var->green.length = 5; 220 var->blue.offset = 0; 221 var->blue.length = 5; 222 break; 223 224 case CMODE_32: 225 var->bits_per_pixel = 32; 226 var->red.offset = 16; 227 var->red.length = 8; 228 var->green.offset = 8; 229 var->green.length = 8; 230 var->blue.offset = 0; 231 var->blue.length = 8; 232 var->transp.offset = 24; 233 var->transp.length = 8; 234 break; 235 236 default: 237 return -EINVAL; 238 } 239 var->xres = mode->xres; 240 var->yres = mode->yres; 241 var->xres_virtual = mode->xres; 242 var->yres_virtual = mode->yres; 243 var->height = -1; 244 var->width = -1; 245 var->pixclock = mode->pixclock; 246 var->left_margin = mode->left_margin; 247 var->right_margin = mode->right_margin; 248 var->upper_margin = mode->upper_margin; 249 var->lower_margin = mode->lower_margin; 250 var->hsync_len = mode->hsync_len; 251 var->vsync_len = mode->vsync_len; 252 var->sync = mode->sync; 253 var->vmode = mode->vmode; 254 return 0; 255} 256EXPORT_SYMBOL(mac_vmode_to_var); 257 258/** 259 * mac_var_to_vmode - convert var structure to MacOS vmode/cmode pair 260 * @var: frame buffer video mode structure 261 * @vmode: MacOS video mode 262 * @cmode: MacOS color mode 263 * 264 * Converts a frame buffer video mode structure to a MacOS 265 * vmode/cmode pair. 266 * 267 * Returns negative errno on error, or zero for success. 268 * 269 */ 270 271int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, 272 int *cmode) 273{ 274 const struct fb_videomode *mode = NULL; 275 const struct mode_map *map; 276 277 if (var->bits_per_pixel <= 8) 278 *cmode = CMODE_8; 279 else if (var->bits_per_pixel <= 16) 280 *cmode = CMODE_16; 281 else if (var->bits_per_pixel <= 32) 282 *cmode = CMODE_32; 283 else 284 return -EINVAL; 285 286 for (map = mac_modes; map->vmode != -1; map++) { 287 mode = map->mode; 288 if (var->xres > mode->xres || var->yres > mode->yres) 289 continue; 290 if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres) 291 continue; 292 if (var->pixclock > mode->pixclock) 293 continue; 294 if ((var->vmode & FB_VMODE_MASK) != mode->vmode) 295 continue; 296 *vmode = map->vmode; 297 return 0; 298 } 299 return -EINVAL; 300} 301 302/** 303 * mac_map_monitor_sense - Convert monitor sense to vmode 304 * @sense: Macintosh monitor sense number 305 * 306 * Converts a Macintosh monitor sense number to a MacOS 307 * vmode number. 308 * 309 * Returns MacOS vmode video mode number. 310 * 311 */ 312 313int mac_map_monitor_sense(int sense) 314{ 315 const struct monitor_map *map; 316 317 for (map = mac_monitors; map->sense != -1; map++) 318 if (map->sense == sense) 319 break; 320 return map->vmode; 321} 322EXPORT_SYMBOL(mac_map_monitor_sense); 323 324/** 325 * mac_find_mode - find a video mode 326 * @var: frame buffer user defined part of display 327 * @info: frame buffer info structure 328 * @mode_option: video mode name (see mac_modedb[]) 329 * @default_bpp: default color depth in bits per pixel 330 * 331 * Finds a suitable video mode. Tries to set mode specified 332 * by @mode_option. If the name of the wanted mode begins with 333 * 'mac', the Mac video mode database will be used, otherwise it 334 * will fall back to the standard video mode database. 335 * 336 * Note: Function marked as __init and can only be used during 337 * system boot. 338 * 339 * Returns error code from fb_find_mode (see fb_find_mode 340 * function). 341 * 342 */ 343 344int __devinit mac_find_mode(struct fb_var_screeninfo *var, 345 struct fb_info *info, const char *mode_option, 346 unsigned int default_bpp) 347{ 348 const struct fb_videomode *db = NULL; 349 unsigned int dbsize = 0; 350 351 if (mode_option && !strncmp(mode_option, "mac", 3)) { 352 mode_option += 3; 353 db = mac_modedb; 354 dbsize = ARRAY_SIZE(mac_modedb); 355 } 356 return fb_find_mode(var, info, mode_option, db, dbsize, 357 &mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp); 358} 359EXPORT_SYMBOL(mac_find_mode); 360 361MODULE_LICENSE("GPL"); 362