1983b4bf2Smrg/*
2983b4bf2Smrg * Copyright 2005-2016 The OpenChrome Project
3983b4bf2Smrg *                     [https://www.freedesktop.org/wiki/Openchrome]
4983b4bf2Smrg * Copyright 2004-2005 The Unichrome Project  [unichrome.sf.net]
5983b4bf2Smrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
6983b4bf2Smrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
7983b4bf2Smrg *
8983b4bf2Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9983b4bf2Smrg * copy of this software and associated documentation files (the "Software"),
10983b4bf2Smrg * to deal in the Software without restriction, including without limitation
11983b4bf2Smrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
12983b4bf2Smrg * and/or sell copies of the Software, and to permit persons to whom the
13983b4bf2Smrg * Software is furnished to do so, subject to the following conditions:
14983b4bf2Smrg *
15983b4bf2Smrg * The above copyright notice and this permission notice (including the
16983b4bf2Smrg * next paragraph) shall be included in all copies or substantial portions
17983b4bf2Smrg * of the Software.
18983b4bf2Smrg *
19983b4bf2Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20983b4bf2Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21983b4bf2Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22983b4bf2Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23983b4bf2Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24983b4bf2Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25983b4bf2Smrg * DEALINGS IN THE SOFTWARE.
26983b4bf2Smrg */
27983b4bf2Smrg
28983b4bf2Smrg/*
29983b4bf2Smrg * via_analog.c
30983b4bf2Smrg *
31983b4bf2Smrg * Handles the initialization and management of analog VGA related
32983b4bf2Smrg * resources.
33983b4bf2Smrg *
34983b4bf2Smrg */
35983b4bf2Smrg
36983b4bf2Smrg#ifdef HAVE_CONFIG_H
37983b4bf2Smrg#include "config.h"
38983b4bf2Smrg#endif
39983b4bf2Smrg
40983b4bf2Smrg#include "via_driver.h"
41983b4bf2Smrg#include <unistd.h>
42983b4bf2Smrg
43983b4bf2Smrg
44983b4bf2Smrg/*
45983b4bf2Smrg * Enables or disables analog VGA output by controlling DAC
46983b4bf2Smrg * (Digital to Analog Converter) output state.
47983b4bf2Smrg */
48983b4bf2Smrgstatic void
49983b4bf2SmrgviaAnalogOutput(ScrnInfoPtr pScrn, Bool outputState)
50983b4bf2Smrg{
51983b4bf2Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
52983b4bf2Smrg
53983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
54983b4bf2Smrg                        "Entered viaAnalogOutput.\n"));
55983b4bf2Smrg
56983b4bf2Smrg    /* This register controls analog VGA DAC output state. */
57983b4bf2Smrg    /* 3X5.47[2] - DACOFF Backdoor Register
58983b4bf2Smrg     *             0: DAC on
59983b4bf2Smrg     *             1: DAC off */
60983b4bf2Smrg    ViaCrtcMask(hwp, 0x47, outputState ? 0x00 : 0x04, 0x04);
61983b4bf2Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
62983b4bf2Smrg                "Analog VGA Output: %s\n",
63983b4bf2Smrg                outputState ? "On" : "Off");
64983b4bf2Smrg
65983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
66983b4bf2Smrg                        "Exiting viaAnalogOutput.\n"));
67983b4bf2Smrg}
68983b4bf2Smrg
69983b4bf2Smrg/*
70983b4bf2Smrg * Specifies IGA1 or IGA2 for analog VGA DAC source.
71983b4bf2Smrg */
72983b4bf2Smrgstatic void
73983b4bf2SmrgviaAnalogSetDisplaySource(ScrnInfoPtr pScrn, CARD8 displaySource)
74983b4bf2Smrg{
75983b4bf2Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
76983b4bf2Smrg    CARD8 value = displaySource;
77983b4bf2Smrg
78983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
79983b4bf2Smrg                        "Entered viaAnalogSetDisplaySource.\n"));
80983b4bf2Smrg
81983b4bf2Smrg    ViaSeqMask(hwp, 0x16, value << 6, 0x40);
82983b4bf2Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
83983b4bf2Smrg                "Analog VGA Display Output Source: IGA%d\n",
84983b4bf2Smrg                (value & 0x01) + 1);
85983b4bf2Smrg
86983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
87983b4bf2Smrg                        "Exiting viaAnalogSetDisplaySource.\n"));
88983b4bf2Smrg}
89983b4bf2Smrg
90983b4bf2Smrg/*
91983b4bf2Smrg * Intializes analog VGA related registers.
92983b4bf2Smrg */
93983b4bf2Smrgstatic void
94983b4bf2SmrgviaAnalogInit(ScrnInfoPtr pScrn)
95983b4bf2Smrg{
96983b4bf2Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
97983b4bf2Smrg    VIAPtr pVia = VIAPTR(pScrn);
98983b4bf2Smrg
99983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
100983b4bf2Smrg                        "Entered viaAnalogInit.\n"));
101983b4bf2Smrg
102983b4bf2Smrg    /* 3X5.37[7]   - DAC Power Save Control 1
103983b4bf2Smrg     *               0: Depend on Rx3X5.37[5:4] setting
104983b4bf2Smrg     *               1: DAC always goes into power save mode
105983b4bf2Smrg     * 3X5.37[6]   - DAC Power Down Control
106983b4bf2Smrg     *               0: Depend on Rx3X5.47[2] setting
107983b4bf2Smrg     *               1: DAC never goes to power down mode
108983b4bf2Smrg     * 3X5.37[5:4] - DAC Power Save Control 2
109983b4bf2Smrg     *               00: DAC never goes to power save mode
110983b4bf2Smrg     *               01: DAC goes to power save mode by line
111983b4bf2Smrg     *               10: DAC goes to power save mode by frame
112983b4bf2Smrg     *               11: DAC goes to power save mode by line and frame
113983b4bf2Smrg     * 3X5.37[3]   - DAC PEDESTAL Control
114983b4bf2Smrg     * 3X5.37[2:0] - DAC Factor
115983b4bf2Smrg     *               (Default: 100) */
116983b4bf2Smrg    ViaCrtcMask(hwp, 0x37, 0x04, 0xFF);
117983b4bf2Smrg
118983b4bf2Smrg    switch (pVia->Chipset) {
119983b4bf2Smrg    case VIA_CX700:
120983b4bf2Smrg    case VIA_VX800:
121983b4bf2Smrg    case VIA_VX855:
122983b4bf2Smrg    case VIA_VX900:
123983b4bf2Smrg        /* 3C5.5E[0] - CRT DACOFF Setting
124983b4bf2Smrg         *             1: CRT DACOFF controlled by 3C5.01[5] */
125983b4bf2Smrg        ViaSeqMask(hwp, 0x5E, 0x01, 0x01);
126983b4bf2Smrg        break;
127983b4bf2Smrg    default:
128983b4bf2Smrg        break;
129983b4bf2Smrg    }
130983b4bf2Smrg
131983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
132983b4bf2Smrg                        "Exiting viaAnalogInit.\n"));
133983b4bf2Smrg}
134983b4bf2Smrg
135983b4bf2Smrg/*
136983b4bf2Smrg * Sets the polarity of horizontal synchronization and vertical
137983b4bf2Smrg * synchronization.
138983b4bf2Smrg */
139983b4bf2Smrgstatic void
140983b4bf2SmrgviaAnalogSetSyncPolarity(ScrnInfoPtr pScrn, DisplayModePtr mode)
141983b4bf2Smrg{
142983b4bf2Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
143983b4bf2Smrg    CARD8 miscRegister;
144983b4bf2Smrg
145983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
146983b4bf2Smrg                        "Entered viaAnalogSetSyncPolarity.\n"));
147983b4bf2Smrg
148983b4bf2Smrg/* Set certain bits of miscellaneous output register
149983b4bf2Smrg * meant for IGA1. */
150983b4bf2Smrg    miscRegister = hwp->readMiscOut(hwp);
151983b4bf2Smrg    if (mode->Flags & V_NHSYNC) {
152983b4bf2Smrg        miscRegister |= 0x40;
153983b4bf2Smrg    } else {
154983b4bf2Smrg        miscRegister &= (~0x40);
155983b4bf2Smrg    }
156983b4bf2Smrg
157983b4bf2Smrg    if (mode->Flags & V_NVSYNC) {
158983b4bf2Smrg        miscRegister |= 0x80;
159983b4bf2Smrg    } else {
160983b4bf2Smrg        miscRegister &= (~0x80);
161983b4bf2Smrg    }
162983b4bf2Smrg
163983b4bf2Smrg    hwp->writeMiscOut(hwp, miscRegister);
164983b4bf2Smrg
165983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
166983b4bf2Smrg                        "Exiting viaAnalogSetSyncPolarity.\n"));
167983b4bf2Smrg}
168983b4bf2Smrg
169983b4bf2Smrg
170983b4bf2Smrgstatic void
171983b4bf2Smrgvia_analog_create_resources(xf86OutputPtr output)
172983b4bf2Smrg{
173983b4bf2Smrg}
174983b4bf2Smrg
175983b4bf2Smrgstatic void
176983b4bf2Smrgvia_analog_dpms(xf86OutputPtr output, int mode)
177983b4bf2Smrg{
178983b4bf2Smrg    ScrnInfoPtr pScrn = output->scrn;
179983b4bf2Smrg
180983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
181983b4bf2Smrg                        "Entered via_analog_dpms.\n"));
182983b4bf2Smrg
183983b4bf2Smrg    switch (mode) {
184983b4bf2Smrg    case DPMSModeOn:
185983b4bf2Smrg        viaAnalogOutput(pScrn, TRUE);
186983b4bf2Smrg        break;
187983b4bf2Smrg    case DPMSModeStandby:
188983b4bf2Smrg    case DPMSModeSuspend:
189983b4bf2Smrg    case DPMSModeOff:
190983b4bf2Smrg        viaAnalogOutput(pScrn, FALSE);
191983b4bf2Smrg        break;
192983b4bf2Smrg    default:
193983b4bf2Smrg        break;
194983b4bf2Smrg    }
195983b4bf2Smrg
196983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
197983b4bf2Smrg                        "Exiting via_analog_dpms.\n"));
198983b4bf2Smrg}
199983b4bf2Smrg
200983b4bf2Smrgstatic void
201983b4bf2Smrgvia_analog_save(xf86OutputPtr output)
202983b4bf2Smrg{
203983b4bf2Smrg}
204983b4bf2Smrg
205983b4bf2Smrgstatic void
206983b4bf2Smrgvia_analog_restore(xf86OutputPtr output)
207983b4bf2Smrg{
208983b4bf2Smrg}
209983b4bf2Smrg
210983b4bf2Smrgstatic int
211983b4bf2Smrgvia_analog_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
212983b4bf2Smrg{
213983b4bf2Smrg    ScrnInfoPtr pScrn = output->scrn;
214983b4bf2Smrg
215983b4bf2Smrg    if (!ViaModeDotClockTranslate(pScrn, pMode))
216983b4bf2Smrg        return MODE_NOCLOCK;
217983b4bf2Smrg    return MODE_OK;
218983b4bf2Smrg}
219983b4bf2Smrg
220983b4bf2Smrgstatic Bool
221983b4bf2Smrgvia_analog_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
222983b4bf2Smrg                      DisplayModePtr adjusted_mode)
223983b4bf2Smrg{
224983b4bf2Smrg    return TRUE;
225983b4bf2Smrg}
226983b4bf2Smrg
227983b4bf2Smrgstatic void
228983b4bf2Smrgvia_analog_prepare(xf86OutputPtr output)
229983b4bf2Smrg{
230983b4bf2Smrg    via_analog_dpms(output, DPMSModeOff);
231983b4bf2Smrg}
232983b4bf2Smrg
233983b4bf2Smrgstatic void
234983b4bf2Smrgvia_analog_commit(xf86OutputPtr output)
235983b4bf2Smrg{
236983b4bf2Smrg    via_analog_dpms(output, DPMSModeOn);
237983b4bf2Smrg}
238983b4bf2Smrg
239983b4bf2Smrgstatic void
240983b4bf2Smrgvia_analog_mode_set(xf86OutputPtr output, DisplayModePtr mode,
241983b4bf2Smrg                    DisplayModePtr adjusted_mode)
242983b4bf2Smrg{
243983b4bf2Smrg    ScrnInfoPtr pScrn = output->scrn;
244983b4bf2Smrg    drmmode_crtc_private_ptr iga = output->crtc->driver_private;
245983b4bf2Smrg
246983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
247983b4bf2Smrg                        "Entered via_analog_mode_set.\n"));
248983b4bf2Smrg
249983b4bf2Smrg    if (output->crtc) {
250983b4bf2Smrg        viaAnalogInit(pScrn);
251983b4bf2Smrg        viaAnalogSetSyncPolarity(pScrn, adjusted_mode);
252983b4bf2Smrg        viaAnalogSetDisplaySource(pScrn, iga->index ? 0x01 : 0x00);
253983b4bf2Smrg    }
254983b4bf2Smrg
255983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
256983b4bf2Smrg                        "Exiting via_analog_mode_set.\n"));
257983b4bf2Smrg}
258983b4bf2Smrg
259983b4bf2Smrgstatic xf86OutputStatus
260983b4bf2Smrgvia_analog_detect(xf86OutputPtr output)
261983b4bf2Smrg{
262983b4bf2Smrg    xf86OutputStatus status = XF86OutputStatusDisconnected;
263983b4bf2Smrg    ScrnInfoPtr pScrn = output->scrn;
264983b4bf2Smrg    VIAPtr pVia = VIAPTR(pScrn);
265983b4bf2Smrg    xf86MonPtr mon;
266983b4bf2Smrg
267983b4bf2Smrg    /* Probe I2C Bus 1 to see if a VGA monitor is connected. */
268983b4bf2Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
269983b4bf2Smrg                "Probing for a VGA monitor on I2C Bus 1.\n");
270983b4bf2Smrg    mon = xf86OutputGetEDID(output, pVia->pI2CBus1);
271983b4bf2Smrg    if (mon && (!mon->features.input_type)) {
272983b4bf2Smrg        xf86OutputSetEDID(output, mon);
273983b4bf2Smrg        status = XF86OutputStatusConnected;
274983b4bf2Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
275983b4bf2Smrg                    "Detected a VGA monitor on I2C Bus 1.\n");
276983b4bf2Smrg    } else {
277983b4bf2Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
278983b4bf2Smrg                    "Did not detect a VGA monitor on I2C Bus 1.\n");
279983b4bf2Smrg
280983b4bf2Smrg        /* Probe I2C Bus 2 to see if a VGA monitor is connected. */
281983b4bf2Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
282983b4bf2Smrg                    "Probing for a VGA monitor on I2C Bus 2.\n");
283983b4bf2Smrg        mon = xf86OutputGetEDID(output, pVia->pI2CBus2);
284983b4bf2Smrg        if (mon && (!mon->features.input_type)) {
285983b4bf2Smrg            xf86OutputSetEDID(output, mon);
286983b4bf2Smrg            status = XF86OutputStatusConnected;
287983b4bf2Smrg            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
288983b4bf2Smrg                        "Detected a VGA monitor on I2C Bus 2.\n");
289983b4bf2Smrg        } else {
290983b4bf2Smrg            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
291983b4bf2Smrg                        "Did not detect a VGA monitor on I2C Bus 2.\n");
292983b4bf2Smrg
293983b4bf2Smrg            /* Perform manual detection of a VGA monitor since */
294983b4bf2Smrg            /* it was not detected via I2C buses. */
295983b4bf2Smrg            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
296983b4bf2Smrg                        "Now perform manual detection of a VGA "
297983b4bf2Smrg                        "monitor.\n");
298983b4bf2Smrg            vgaHWPtr hwp = VGAHWPTR(pScrn);
299983b4bf2Smrg            CARD8 SR01 = hwp->readSeq(hwp, 0x01);
300983b4bf2Smrg            CARD8 SR40 = hwp->readSeq(hwp, 0x40);
301983b4bf2Smrg            CARD8 CR36 = hwp->readCrtc(hwp, 0x36);
302983b4bf2Smrg
303983b4bf2Smrg            /* We have to power on the display to detect it */
304983b4bf2Smrg            ViaSeqMask(hwp, 0x01, 0x00, 0x20);
305983b4bf2Smrg            ViaCrtcMask(hwp, 0x36, 0x00, 0xF0);
306983b4bf2Smrg
307983b4bf2Smrg            /* Wait for vblank */
308983b4bf2Smrg            usleep(16);
309983b4bf2Smrg
310983b4bf2Smrg            /* Detect the load on pins */
311983b4bf2Smrg            ViaSeqMask(hwp, 0x40, 0x80, 0x80);
312983b4bf2Smrg
313983b4bf2Smrg            if ((VIA_CX700 == pVia->Chipset) ||
314983b4bf2Smrg                (VIA_VX800 == pVia->Chipset) ||
315983b4bf2Smrg                (VIA_VX855 == pVia->Chipset) ||
316983b4bf2Smrg                (VIA_VX900 == pVia->Chipset))
317983b4bf2Smrg                ViaSeqMask(hwp, 0x40, 0x00, 0x80);
318983b4bf2Smrg
319983b4bf2Smrg            if (ViaVgahwIn(hwp, 0x3C2) & 0x20) {
320983b4bf2Smrg                status = XF86OutputStatusConnected;
321983b4bf2Smrg                xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
322983b4bf2Smrg                            "Detected a VGA monitor using manual "
323983b4bf2Smrg                            "detection method.\n");
324983b4bf2Smrg            }
325983b4bf2Smrg
326983b4bf2Smrg            if ((VIA_CX700 == pVia->Chipset) ||
327983b4bf2Smrg                (VIA_VX800 == pVia->Chipset) ||
328983b4bf2Smrg                (VIA_VX855 == pVia->Chipset) ||
329983b4bf2Smrg                (VIA_VX900 == pVia->Chipset))
330983b4bf2Smrg                ViaSeqMask(hwp, 0x40, 0x00, 0x80);
331983b4bf2Smrg
332983b4bf2Smrg            /* Restore previous state */
333983b4bf2Smrg            hwp->writeSeq(hwp, 0x40, SR40);
334983b4bf2Smrg            hwp->writeSeq(hwp, 0x01, SR01);
335983b4bf2Smrg            hwp->writeCrtc(hwp, 0x36, CR36);
336983b4bf2Smrg        }
337983b4bf2Smrg    }
338983b4bf2Smrg
339983b4bf2Smrg    return status;
340983b4bf2Smrg}
341983b4bf2Smrg
342983b4bf2Smrg#ifdef RANDR_12_INTERFACE
343983b4bf2Smrgstatic Bool
344983b4bf2Smrgvia_analog_set_property(xf86OutputPtr output, Atom property,
345983b4bf2Smrg                        RRPropertyValuePtr value)
346983b4bf2Smrg{
347983b4bf2Smrg    return TRUE;
348983b4bf2Smrg}
349983b4bf2Smrg#endif
350983b4bf2Smrg
351983b4bf2Smrg#ifdef RANDR_13_INTERFACE
352983b4bf2Smrgstatic Bool
353983b4bf2Smrgvia_analog_get_property(xf86OutputPtr output, Atom property)
354983b4bf2Smrg{
355983b4bf2Smrg    return FALSE;
356983b4bf2Smrg}
357983b4bf2Smrg#endif
358983b4bf2Smrg
359983b4bf2Smrgstatic void
360983b4bf2Smrgvia_analog_destroy(xf86OutputPtr output)
361983b4bf2Smrg{
362983b4bf2Smrg}
363983b4bf2Smrg
364983b4bf2Smrgstatic const xf86OutputFuncsRec via_analog_funcs = {
365983b4bf2Smrg    .create_resources   = via_analog_create_resources,
366983b4bf2Smrg    .dpms               = via_analog_dpms,
367983b4bf2Smrg    .save               = via_analog_save,
368983b4bf2Smrg    .restore            = via_analog_restore,
369983b4bf2Smrg    .mode_valid         = via_analog_mode_valid,
370983b4bf2Smrg    .mode_fixup         = via_analog_mode_fixup,
371983b4bf2Smrg    .prepare            = via_analog_prepare,
372983b4bf2Smrg    .commit             = via_analog_commit,
373983b4bf2Smrg    .mode_set           = via_analog_mode_set,
374983b4bf2Smrg    .detect             = via_analog_detect,
375983b4bf2Smrg    .get_modes          = xf86OutputGetEDIDModes,
376983b4bf2Smrg#ifdef RANDR_12_INTERFACE
377983b4bf2Smrg    .set_property       = via_analog_set_property,
378983b4bf2Smrg#endif
379983b4bf2Smrg#ifdef RANDR_13_INTERFACE
380983b4bf2Smrg    .get_property       = via_analog_get_property,
381983b4bf2Smrg#endif
382983b4bf2Smrg    .destroy            = via_analog_destroy,
383983b4bf2Smrg};
384983b4bf2Smrg
385983b4bf2Smrgvoid
386983b4bf2Smrgvia_analog_init(ScrnInfoPtr pScrn)
387983b4bf2Smrg{
388983b4bf2Smrg    VIAPtr pVia = VIAPTR(pScrn);
389983b4bf2Smrg    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
390983b4bf2Smrg    xf86OutputPtr output = NULL;
391983b4bf2Smrg    char outputNameBuffer[32];
392983b4bf2Smrg
393983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
394983b4bf2Smrg                        "Entered via_analog_init.\n"));
395983b4bf2Smrg
396983b4bf2Smrg    if (!pVia->pI2CBus1 || !pVia->pI2CBus2) {
397983b4bf2Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
398983b4bf2Smrg                    "I2C Bus 1 or I2C Bus 2 does not exist.\n");
399983b4bf2Smrg        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
400983b4bf2Smrg                            "Exiting via_analog_init.\n"));
401983b4bf2Smrg        return;
402983b4bf2Smrg    }
403983b4bf2Smrg
404983b4bf2Smrg    /* The code to dynamically designate the output name for
405983b4bf2Smrg     * xrandr was borrowed from xf86-video-r128 DDX. */
406983b4bf2Smrg    sprintf(outputNameBuffer, "VGA-%d", (pVia->numberVGA + 1));
407983b4bf2Smrg    output = xf86OutputCreate(pScrn, &via_analog_funcs, outputNameBuffer);
408983b4bf2Smrg
409983b4bf2Smrg    /* While there are two (2) display controllers registered with the
410983b4bf2Smrg     * X.Org Server, it is often desirable to fix the analog VGA output
411983b4bf2Smrg     * to IGA1 since LVDS FP (Flat Panel) typically prefers IGA2. (While
412983b4bf2Smrg     * it is not used at this point, only IGA2 contains panel resolution
413983b4bf2Smrg     * scaling functionality. IGA1 does not have this.)
414983b4bf2Smrg     * With this arrangement, DVI should end up getting assigned to IGA2
415983b4bf2Smrg     * since DVI can go to either display controller without limitations.
416983b4bf2Smrg     * This should be the case for TV as well. */
417983b4bf2Smrg    output->possible_crtcs = (1 << 0);
418983b4bf2Smrg
419983b4bf2Smrg    output->possible_clones = 0;
420983b4bf2Smrg    output->interlaceAllowed = TRUE;
421983b4bf2Smrg    output->doubleScanAllowed = FALSE;
422983b4bf2Smrg    pBIOSInfo->analog = output;
423983b4bf2Smrg
424983b4bf2Smrg    /* Increment the number of analog VGA connectors. */
425983b4bf2Smrg    pVia->numberVGA++;
426983b4bf2Smrg
427983b4bf2Smrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
428983b4bf2Smrg                        "Exiting via_analog_init.\n"));
429983b4bf2Smrg}
430