summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJUNG, Christian <christian.jung@shsservices.org>2015-01-10 17:47:48 -0700
committerJames Simmons <jsimmons@infradead.org>2015-01-10 17:48:02 -0700
commita8c2f04e2ef21e64f2e91dd6f3e237f80e8c80c6 (patch)
tree3d93636d7d2a44ff3b02687830021a2b20e6bd29
parent02480da73b76df500aaca8dd6eff9d56acdb58d2 (diff)
Add support for VT1632 DVI transmitter for UMS mode.
Signed-off-by: JUNG, Christian <christian.jung@shsservices.org> Reviewed-by: James Simmons <jsimmons@infradead.org>
-rw-r--r--src/Makefile.am2
-rw-r--r--src/via_driver.h2
-rw-r--r--src/via_outputs.c190
-rw-r--r--src/via_vt1632.c204
-rw-r--r--src/via_vt1632.h54
5 files changed, 452 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7f67bed..c3c38cc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -72,6 +72,8 @@ openchrome_drv_la_SOURCES = \
via_xv.h \
via_vt162x.c \
via_vt162x.h \
+ via_vt1632.c \
+ via_vt1632.h \
via_xvpriv.h
if DRI
diff --git a/src/via_driver.h b/src/via_driver.h
index b1b077d..be0e73d 100644
--- a/src/via_driver.h
+++ b/src/via_driver.h
@@ -86,6 +86,8 @@
#endif
#include <errno.h>
+#include "via_vt1632.h"
+
#include "compat-api.h"
#define VIA_AGP_UPL_SIZE (1024*128)
#define VIA_DMA_DL_SIZE (1024*128)
diff --git a/src/via_outputs.c b/src/via_outputs.c
index 1876937..84a383e 100644
--- a/src/via_outputs.c
+++ b/src/via_outputs.c
@@ -888,6 +888,10 @@ ViaOutputsDetect(ScrnInfoPtr pScrn)
if ((pVia->Chipset != VIA_P4M900) || (pVia->ActiveDevice & VIA_DEVICE_TV))
via_tv_init(pScrn);
+ if (pVia->Chipset == VIA_VM800) {
+ via_dvi_init(pScrn);
+ }
+
if (pVia->ActiveDevice & VIA_DEVICE_DFP) {
switch (pVia->Chipset) {
case VIA_CX700:
@@ -1370,3 +1374,189 @@ ViaModeSecondCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode)
hwp->disablePalette(hwp);
}
+
+static void
+via_dvi_create_resources(xf86OutputPtr output)
+{
+}
+
+#ifdef RANDR_12_INTERFACE
+static Bool
+via_dvi_set_property(xf86OutputPtr output, Atom property,
+ RRPropertyValuePtr value)
+{
+ return FALSE;
+}
+
+static Bool
+via_dvi_get_property(xf86OutputPtr output, Atom property)
+{
+ return FALSE;
+}
+#endif
+
+static void
+via_dvi_dpms(xf86OutputPtr output, int mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+
+ switch (mode) {
+ case DPMSModeOn:
+ ViaDFPPower(pScrn, TRUE);
+ break;
+
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ case DPMSModeOff:
+ ViaDFPPower(pScrn, FALSE);
+ break;
+ }
+
+}
+
+static void
+via_dvi_save(xf86OutputPtr output)
+{
+ via_vt1632_save(output);
+}
+
+static void
+via_dvi_restore(xf86OutputPtr output)
+{
+ via_vt1632_restore(output);
+}
+
+static int
+via_dvi_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+{
+ return via_vt1632_mode_valid(output, pMode);
+}
+
+static Bool
+via_dvi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ return TRUE;
+}
+
+static void
+via_dvi_prepare(xf86OutputPtr output)
+{
+}
+
+static void
+via_dvi_commit(xf86OutputPtr output)
+{
+}
+
+static void
+via_dvi_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ via_vt1632_power(output, FALSE);
+ ViaModeSecondCRTC(pScrn, mode);
+ via_vt1632_mode_set(output, mode, adjusted_mode);
+ via_vt1632_power(output, TRUE);
+}
+
+static xf86OutputStatus
+via_dvi_detect(xf86OutputPtr output)
+{
+ xf86OutputStatus status = XF86OutputStatusDisconnected;
+ ScrnInfoPtr pScrn = output->scrn;
+ VIAPtr pVia = VIAPTR(pScrn);
+ xf86MonPtr mon;
+
+ mon = xf86OutputGetEDID(output, pVia->pI2CBus2);
+ if (mon && DIGITAL(mon->features.input_type)) {
+ xf86OutputSetEDID(output, mon);
+ status = XF86OutputStatusConnected;
+ } else {
+ status = via_vt1632_detect(output);
+ }
+ return status;
+}
+
+static void
+via_dvi_destroy(xf86OutputPtr output)
+{
+}
+
+static const xf86OutputFuncsRec via_dvi_funcs = {
+ .create_resources = via_dvi_create_resources,
+#ifdef RANDR_12_INTERFACE
+ .set_property = via_dvi_set_property,
+ .get_property = via_dvi_get_property,
+#endif
+ .dpms = via_dvi_dpms,
+ .save = via_dvi_save,
+ .restore = via_dvi_restore,
+ .mode_valid = via_dvi_mode_valid,
+ .mode_fixup = via_dvi_mode_fixup,
+ .prepare = via_dvi_prepare,
+ .commit = via_dvi_commit,
+ .mode_set = via_dvi_mode_set,
+ .detect = via_dvi_detect,
+ .get_modes = xf86OutputGetEDIDModes,
+ .destroy = via_dvi_destroy,
+};
+
+void
+via_dvi_init(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ xf86OutputPtr output = NULL;
+ struct ViaVT1632PrivateData *private_data = NULL;
+ I2CBusPtr pBus = NULL;
+ I2CDevPtr pDev = NULL;
+
+ if (!pVia->pI2CBus2 || !pVia->pI2CBus3) {
+ return;
+ }
+
+ pDev = xf86CreateI2CDevRec();
+ if (!pDev) {
+ return;
+ }
+
+ pDev->DevName = "VT1632";
+ pDev->SlaveAddr = 0x10;
+
+ if (xf86I2CProbeAddress(pVia->pI2CBus3, pDev->SlaveAddr)) {
+ pDev->pI2CBus = pVia->pI2CBus3;
+ } else if (xf86I2CProbeAddress(pVia->pI2CBus2, pDev->SlaveAddr)) {
+ pDev->pI2CBus = pVia->pI2CBus2;
+ } else {
+ xf86DestroyI2CDevRec(pDev, TRUE);
+ return;
+ }
+
+ if (!xf86I2CDevInit(pDev)) {
+ xf86DestroyI2CDevRec(pDev, TRUE);
+ return;
+ }
+
+ if (!via_vt1632_probe(pScrn, pDev)) {
+ xf86DestroyI2CDevRec(pDev, TRUE);
+ return;
+ }
+
+ private_data = via_vt1632_init(pScrn, pDev);
+ if (!private_data) {
+ xf86DestroyI2CDevRec(pDev, TRUE);
+ return;
+ }
+
+ output = xf86OutputCreate(pScrn, &via_dvi_funcs, "DVI-1");
+ if (output) {
+ output->driver_private = private_data;
+ output->possible_crtcs = 0x2;
+ output->possible_clones = 0;
+ output->interlaceAllowed = FALSE;
+ output->doubleScanAllowed = FALSE;
+ }
+}
+
diff --git a/src/via_vt1632.c b/src/via_vt1632.c
new file mode 100644
index 0000000..bc41128
--- /dev/null
+++ b/src/via_vt1632.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2014 SHS SERVICES GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via_driver.h"
+#include "via_vt1632.h"
+
+static Bool
+xf86I2CMaskByte(I2CDevPtr d, I2CByte subaddr, I2CByte value, I2CByte mask)
+{
+ I2CByte tmp;
+ Bool ret;
+
+ ret = xf86I2CReadByte(d, subaddr, &tmp);
+ if (!ret)
+ return FALSE;
+
+ tmp &= ~mask;
+ tmp |= (value & mask);
+
+ return xf86I2CWriteByte(d, subaddr, tmp);
+}
+
+static void
+via_vt1632_dump_registers(ScrnInfoPtr pScrn, I2CDevPtr pDev)
+{
+ int i;
+ CARD8 tmp;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_DEBUG, "VT1632: dumping registers:\n"));
+ for (i = 0; i <= 0x0f; i++) {
+ xf86I2CReadByte(pDev, i, &tmp);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_DEBUG, "VT1632: 0x%02x: 0x%02x\n", i, tmp));
+ }
+}
+
+
+void
+via_vt1632_power(xf86OutputPtr output, BOOL on)
+{
+ struct ViaVT1632PrivateData * Private = output->driver_private;
+ ScrnInfoPtr pScrn = output->scrn;
+
+
+ if (on == TRUE) {
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_DEBUG, "VT1632: power on\n"));
+ xf86I2CMaskByte(Private->VT1632I2CDev, 0x08, 0x01, 0x01);
+ } else {
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_DEBUG, "VT1632: power off\n"));
+ xf86I2CMaskByte(Private->VT1632I2CDev, 0x08, 0x00, 0x01);
+ }
+}
+
+void
+via_vt1632_save(xf86OutputPtr output)
+{
+ struct ViaVT1632PrivateData * Private = output->driver_private;
+ ScrnInfoPtr pScrn = output->scrn;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_DEBUG,
+ "VT1632: saving state of registers 0x08, 0x09, 0x0A and 0x0C\n"));
+
+ xf86I2CReadByte(Private->VT1632I2CDev, 0x08, &Private->Register08);
+ xf86I2CReadByte(Private->VT1632I2CDev, 0x09, &Private->Register09);
+ xf86I2CReadByte(Private->VT1632I2CDev, 0x0A, &Private->Register0A);
+ xf86I2CReadByte(Private->VT1632I2CDev, 0x0C, &Private->Register0C);
+}
+
+void
+via_vt1632_restore(xf86OutputPtr output)
+{
+ struct ViaVT1632PrivateData * Private = output->driver_private;
+ ScrnInfoPtr pScrn = output->scrn;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_DEBUG,
+ "VT1632: restoring register 0x08, 0x09, 0x0A and 0x0C\n"));
+ xf86I2CWriteByte(Private->VT1632I2CDev, 0x08, Private->Register08);
+ xf86I2CWriteByte(Private->VT1632I2CDev, 0x09, Private->Register09);
+ xf86I2CWriteByte(Private->VT1632I2CDev, 0x0A, Private->Register0A);
+ xf86I2CWriteByte(Private->VT1632I2CDev, 0x0C, Private->Register0C);
+}
+
+int
+via_vt1632_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+{
+ struct ViaVT1632PrivateData * Private = output->driver_private;
+
+ if (pMode->Clock < Private->DotclockMin)
+ return MODE_CLOCK_LOW;
+
+ if (pMode->Clock > Private->DotclockMax)
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+}
+
+void
+via_vt1632_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ struct ViaVT1632PrivateData * Private = output->driver_private;
+ ScrnInfoPtr pScrn = output->scrn;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_DEBUG,
+ "VT1632: enabling DVI encoder\n"));
+ xf86I2CWriteByte(Private->VT1632I2CDev, 0x0C, 0x89);
+ xf86I2CWriteByte(Private->VT1632I2CDev, 0x08,
+ VIA_VT1632_VEN | VIA_VT1632_HEN | VIA_VT1632_EDGE |
+ VIA_VT1632_PDB);
+ via_vt1632_dump_registers(pScrn, Private->VT1632I2CDev);
+}
+
+xf86OutputStatus
+via_vt1632_detect(xf86OutputPtr output)
+{
+ struct ViaVT1632PrivateData * Private = output->driver_private;
+ xf86OutputStatus status = XF86OutputStatusDisconnected;
+ ScrnInfoPtr pScrn = output->scrn;
+ CARD8 tmp;
+
+ xf86I2CReadByte(Private->VT1632I2CDev, 0x09, &tmp);
+ if (tmp && 0x02) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1632: DVI is connected\n");
+ status = XF86OutputStatusConnected;
+ }
+
+ return status;
+}
+
+BOOL
+via_vt1632_probe(ScrnInfoPtr pScrn, I2CDevPtr pDev) {
+ CARD8 buf = 0;
+ CARD16 VendorID = 0;
+ CARD16 DeviceID = 0;
+
+ xf86I2CReadByte(pDev, 0, &buf);
+ VendorID = buf;
+ xf86I2CReadByte(pDev, 1, &buf);
+ VendorID |= buf << 8;
+
+ xf86I2CReadByte(pDev, 2, &buf);
+ DeviceID = buf;
+ xf86I2CReadByte(pDev, 3, &buf);
+ DeviceID |= buf << 8;
+
+ if (VendorID != 0x1106 || DeviceID != 0x3192) {
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1632 DVI transmitter detected\n");
+
+ return TRUE;
+}
+
+struct ViaVT1632PrivateData *
+via_vt1632_init(ScrnInfoPtr pScrn, I2CDevPtr pDev)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ struct ViaVT1632PrivateData * Private = NULL;
+ CARD8 buf = 0;
+
+ Private = xnfcalloc(1, sizeof(struct ViaVT1632PrivateData));
+ if (!Private) {
+ return NULL;
+ }
+ Private->VT1632I2CDev = pDev;
+
+ xf86I2CReadByte(pDev, 0x06, &buf);
+ Private->DotclockMin = buf * 1000;
+
+ xf86I2CReadByte(pDev, 0x07, &buf);
+ Private->DotclockMax = (buf + 65) * 1000;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1632: dotclock range %d-%dMHz\n",
+ Private->DotclockMin / 1000,
+ Private->DotclockMax / 1000);
+
+ via_vt1632_dump_registers(pScrn, pDev);
+
+ return Private;
+}
diff --git a/src/via_vt1632.h b/src/via_vt1632.h
new file mode 100644
index 0000000..535bf17
--- /dev/null
+++ b/src/via_vt1632.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2014 SHS SERVICES GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIA_VT1632_H_
+#define _VIA_VT1632_H_ 1
+
+#define VIA_VT1632_VEN 0x20
+#define VIA_VT1632_HEN 0x10
+#define VIA_VT1632_DSEL 0x08
+#define VIA_VT1632_BSEL 0x04
+#define VIA_VT1632_EDGE 0x02
+#define VIA_VT1632_PDB 0x01
+
+struct ViaVT1632PrivateData {
+ I2CDevPtr VT1632I2CDev;
+
+ int DotclockMin;
+ int DotclockMax;
+ CARD8 Register08;
+ CARD8 Register09;
+ CARD8 Register0A;
+ CARD8 Register0C;
+};
+
+void via_vt1632_power(xf86OutputPtr output, BOOL on);
+void via_vt1632_save(xf86OutputPtr output);
+void via_vt1632_restore(xf86OutputPtr output);
+int via_vt1632_mode_valid(xf86OutputPtr output, DisplayModePtr pMode);
+void via_vt1632_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode);
+xf86OutputStatus via_vt1632_detect(xf86OutputPtr output);
+BOOL via_vt1632_probe(ScrnInfoPtr pScrn, I2CDevPtr pDev);
+struct ViaVT1632PrivateData * via_vt1632_init(ScrnInfoPtr pScrn, I2CDevPtr pDev);
+
+#endif /* _VIA_VT1632_H_ */