1 /*
2  * icw.c:
3  *
4  * RAMDAC definition for IC Works DACs.
5  * This version only supports the 16-bit ZoomDAC (w30C516), which
6  * is compatible with the AT&T 20C498.
7  * This DAC exists in 110, 135 and 170 MHz versions.
8  * It can do packed 24-bit color (BG-RB-GR).
9  * The 170 MHz version has a PCLK limit of 135 MHz
10  * (170 pixel clock for 16-bit path for 8bpp LUT).
11  */
12 
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include "libvga.h"
16 
17 #include "timing.h"
18 #include "vgaregs.h"
19 #include "driver.h"		/* for __svgalib_driver_report */
20 #include "ramdac.h"
21 
22 #ifdef INCLUDE_ICW_DAC_TEST
ICW_probe(void)23 static int ICW_probe(void)
24 {
25     unsigned char mi, di;
26 
27     _ramdac_dactocomm();
28     inb(PEL_MSK);		/* Control register 0. */
29     mi = inb(PEL_MSK);		/* Manufacturer ID. */
30     di = inb(PEL_MSK);		/* Device ID. */
31     if (mi == 0x84) {
32 	if (di == 0x98)
33 	    return 1;
34 	printf("svgalib: ICW_probe: Unknown IC Works DAC.\n");
35     }
36     return 0;
37 }
38 #else
39 #define ICW_probe 0
40 #endif
41 
42 #ifdef INCLUDE_ICW_DAC
ICW_init(void)43 static void ICW_init(void)
44 {
45     if (__svgalib_driver_report)
46 	printf("svgalib: Using IC Works DAC (AT&T20C498-compatible).\n");
47 }
48 
ICW_map_clock(int bpp,int pixelclock)49 static int ICW_map_clock(int bpp, int pixelclock)
50 {
51     if (bpp == 8 && pixelclock > 80000)
52 	/* Use 16-bit path, clock doubling at RAMDAC. */
53 	return pixelclock / 2;
54     if (bpp == 16)
55 	return pixelclock;
56     if (bpp == 24)
57 	/* Use the packed 24-bit mode. */
58 	return pixelclock * 3 / 2;
59     if (bpp == 32)
60 	return pixelclock * 2;
61     return pixelclock;
62 }
63 
ICW_map_horizontal_crtc(int bpp,int pixelclock,int htiming)64 static int ICW_map_horizontal_crtc(int bpp, int pixelclock, int htiming)
65 {
66     /* Not sure. */
67     if (bpp == 8 && pixelclock > 80000)
68 	/* Use 16-bit path, clock doubling at RAMDAC. */
69 	return htiming / 2;
70     if (bpp == 24)
71 	return htiming * 3 / 2;
72     if (bpp == 32)
73 	return htiming * 2;
74     return htiming;
75 }
76 
ICW_initializestate(unsigned char * regs,int bpp,int colormode,int pixelclock)77 static void ICW_initializestate(unsigned char *regs, int bpp, int colormode,
78 				int pixelclock)
79 {
80     regs[0] = 0;
81     if (colormode == CLUT8_8)
82 	regs[0] = 0x02;
83     if (colormode == RGB16_555)
84 	regs[0] = 0x10;
85     if (colormode == RGB16_565)
86 	regs[0] = 0x30;
87     if (colormode == RGB24_888_B)
88 	/* Packed mode. */
89 	regs[0] = 0xB0;
90     if (colormode == RGB32_888_B)
91 	regs[0] = 0x50;
92 }
93 
ICW_qualify_cardspecs(CardSpecs * cardspecs,int dacspeed)94 static void ICW_qualify_cardspecs(CardSpecs * cardspecs, int dacspeed)
95 {
96     dacspeed = __svgalib_setDacSpeed(dacspeed, 110000);
97     cardspecs->maxPixelClock4bpp = 0;
98     cardspecs->maxPixelClock8bpp = dacspeed;
99     cardspecs->maxPixelClock16bpp = dacspeed;
100     cardspecs->maxPixelClock24bpp = dacspeed * 2 / 3;
101     cardspecs->maxPixelClock32bpp = dacspeed / 2;
102     cardspecs->mapClock = ICW_map_clock;
103     cardspecs->mapHorizontalCrtc = ICW_map_horizontal_crtc;
104 }
105 
106 DacMethods __svgalib_ICW_methods =
107 {
108     IC_WORKS,
109     "IC Works DAC",
110     0,
111     ICW_probe,
112     ICW_init,
113     ICW_qualify_cardspecs,
114     __svgalib_Sierra_32K_savestate,
115     __svgalib_Sierra_32K_restorestate,
116     ICW_initializestate,
117     1				/* State size. */
118 };
119 #endif
120