| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  | 
|  | 35 | static 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 |  | 
|  | 141 | static 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 |  | 
|  | 178 | static 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 |  | 
|  | 218 | int 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 | } | 
|  | 285 | EXPORT_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 |  | 
|  | 300 | int 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 | } | 
|  | 330 | EXPORT_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 |  | 
|  | 343 | int 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 | } | 
|  | 352 | EXPORT_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 |  | 
|  | 374 | int __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 | } | 
|  | 388 | EXPORT_SYMBOL(mac_find_mode); | 
|  | 389 |  | 
| Randy Dunlap | 9a47696 | 2005-06-13 22:58:09 -0700 | [diff] [blame] | 390 | MODULE_LICENSE("GPL"); |