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