summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/i830_dvo.c13
-rw-r--r--src/ivch/Makefile.am15
-rw-r--r--src/ivch/ivch.c234
-rw-r--r--src/ivch/ivch_module.c64
-rw-r--r--src/ivch/ivch_reg.h97
6 files changed, 424 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d843ecff..77a19175 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,8 @@
# 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.
-SUBDIRS = xvmc bios_reader ch7xxx sil164
+SUBDIRS = xvmc bios_reader ch7xxx ivch sil164
+
# this is obnoxious:
# -module lets us name the module exactly how we want
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 6d119721..6d4039a5 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -45,13 +45,24 @@ static const char *CH7xxxSymbols[] = {
NULL
};
+#if 0
+static const char *ivch_symbols[] = {
+ "ivch_methods",
+ NULL
+};
+#endif
+
/* driver list */
struct _I830DVODriver i830_dvo_drivers[] =
{
{I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput",
(SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
{I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput",
- (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL}
+ (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
+ /*
+ {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+ (0x2 << 1), ivch_symbols, NULL, NULL, NULL},
+ */
};
#define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver))
diff --git a/src/ivch/Makefile.am b/src/ivch/Makefile.am
new file mode 100644
index 00000000..fac074db
--- /dev/null
+++ b/src/ivch/Makefile.am
@@ -0,0 +1,15 @@
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
+
+ivch_la_LTLIBRARIES = ivch.la
+ivch_la_LDFLAGS = -module -avoid-version
+ivch_ladir = @moduledir@/drivers
+
+ivch_la_SOURCES = \
+ ivch.c \
+ ivch_module.c \
+ ivch_reg.h
diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
new file mode 100644
index 00000000..6c5db6c9
--- /dev/null
+++ b/src/ivch/ivch.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "compiler.h"
+#include "miscstruct.h"
+#include "xf86i2c.h"
+#include "../i830_xf86Crtc.h"
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+#include "../i2c_vid.h"
+#include "ivch_reg.h"
+
+struct ivch_priv {
+ I2CDevRec d;
+
+ CARD16 save_VR01;
+ CARD16 save_VR40;
+};
+
+static void
+ivch_dump_regs(I2CDevPtr d);
+
+/**
+ * Reads a register on the ivch.
+ *
+ * Each of the 256 registers are 16 bits long.
+ */
+static Bool
+ivch_read(struct ivch_priv *priv, int addr, CARD16 *data)
+{
+ if (!xf86I2CReadWord(&priv->d, addr, data)) {
+ xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
+ "Unable to read register 0x%02x from %s:%d.\n",
+ addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/** Writes a 16-bit register on the ivch */
+static Bool
+ivch_write(struct ivch_priv *priv, int addr, CARD16 data)
+{
+ if (!xf86I2CWriteWord(&priv->d, addr, data)) {
+ xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
+ "Unable to write register 0x%02x to %s:%d.\n",
+ addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/** Probes the given bus and slave address for an ivch */
+static void *
+ivch_init(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ struct ivch_priv *priv;
+ CARD16 temp;
+
+ xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ivch\n");
+
+ priv = xcalloc(1, sizeof(struct ivch_priv));
+ if (priv = NULL)
+ return NULL;
+
+ priv->d.DevName = "i82807aa \"ivch\" LVDS/CMOS panel controller";
+ priv->d.SlaveAddr = addr;
+ priv->d.pI2CBus = b;
+ priv->d.StartTimeout = b->StartTimeout;
+ priv->d.BitTimeout = b->BitTimeout;
+ priv->d.AcknTimeout = b->AcknTimeout;
+ priv->d.ByteTimeout = b->ByteTimeout;
+ priv->d.DriverPrivate.ptr = priv;
+
+ if (!xf86I2CReadWord(&priv->d, VR00, &temp))
+ goto out;
+
+ /* Since the identification bits are probably zeroes, which doesn't seem
+ * very unique, check that the value in the base address field matches
+ * the address it's responding on.
+ */
+ if ((temp & VR00_BASE_ADDRESS_MASK) != priv->d.SlaveAddr) {
+ xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
+ "ivch detect failed due to address mismatch "
+ "(%d vs %d)\n",
+ (temp & VR00_BASE_ADDRESS_MASK), priv->d.SlaveAddr);
+ }
+
+ if (!xf86I2CDevInit(&priv->d)) {
+ goto out;
+ }
+
+ return priv;
+
+out:
+ xfree(priv);
+ return NULL;
+}
+
+static xf86OutputStatus
+ivch_detect(I2CDevPtr d)
+{
+ return XF86OutputStatusUnknown;
+}
+
+static ModeStatus
+ivch_mode_valid(I2CDevPtr d, DisplayModePtr mode)
+{
+ if (mode->Clock > 112000)
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+}
+
+/** Sets the power state of the panel connected to the ivch */
+static void
+ivch_dpms(I2CDevPtr d, int mode)
+{
+ struct ivch_priv *priv = d->DriverPrivate.ptr;
+ int i;
+ CARD16 temp;
+
+ /* Set the new power state of the panel. */
+ if (!ivch_read(priv, VR01, &temp))
+ return;
+
+ if (mode == DPMSModeOn)
+ temp |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
+ else
+ temp &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
+
+ ivch_write(priv, VR01, temp);
+
+ /* Wait for the panel to make its state transition */
+ for (i = 0; i < 1000; i++) {
+ if (!ivch_read(priv, VR30, &temp))
+ break;
+
+ if (((temp & VR30_PANEL_ON) != 0) == (mode == DPMSModeOn))
+ break;
+ }
+}
+
+static void
+ivch_mode_set(I2CDevPtr d, DisplayModePtr mode)
+{
+ struct ivch_priv *priv = d->DriverPrivate.ptr;
+
+ /* Disable panel fitting for now, until we can test. */
+ ivch_write(priv, VR40, 0);
+
+ ivch_dpms(d, DPMSModeOn);
+
+ ivch_dump_regs(d);
+}
+
+static void
+ivch_dump_regs(I2CDevPtr d)
+{
+ struct ivch_priv *priv = d->DriverPrivate.ptr;
+ CARD16 val;
+
+ ivch_read(priv, VR00, &val);
+ xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR00: 0x%04x\n", val);
+ ivch_read(priv, VR01, &val);
+ xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR01: 0x%04x\n", val);
+ ivch_read(priv, VR30, &val);
+ xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR30: 0x%04x\n", val);
+ ivch_read(priv, VR40, &val);
+ xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR40: 0x%04x\n", val);
+
+}
+
+static void
+ivch_save(I2CDevPtr d)
+{
+ struct ivch_priv *priv = d->DriverPrivate.ptr;
+
+ ivch_read(priv, VR01, &priv->save_VR01);
+ ivch_read(priv, VR40, &priv->save_VR40);
+}
+
+static void
+ivch_restore(I2CDevPtr d)
+{
+ struct ivch_priv *priv = d->DriverPrivate.ptr;
+
+ ivch_write(priv, VR01, priv->save_VR01);
+ ivch_write(priv, VR40, priv->save_VR40);
+}
+
+
+I830I2CVidOutputRec ivch_methods = {
+ .init = ivch_init,
+ .detect = ivch_detect,
+ .mode_valid = ivch_mode_valid,
+ .mode_set = ivch_mode_set,
+ .dpms = ivch_dpms,
+ .dump_regs = ivch_dump_regs,
+ .save = ivch_save,
+ .restore = ivch_restore,
+};
diff --git a/src/ivch/ivch_module.c b/src/ivch/ivch_module.c
new file mode 100644
index 00000000..1ed483b1
--- /dev/null
+++ b/src/ivch/ivch_module.c
@@ -0,0 +1,64 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(ivch_setup);
+
+static XF86ModuleVersionInfo ivch_version = {
+ "ivch",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ { 0,0,0,0 }
+};
+
+_X_EXPORT XF86ModuleData ivchModuleData = {
+ &ivch_version,
+ ivch_setup,
+ NULL
+};
+
+static pointer
+ivch_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ return (pointer)1;
+}
diff --git a/src/ivch/ivch_reg.h b/src/ivch/ivch_reg.h
new file mode 100644
index 00000000..112c97d6
--- /dev/null
+++ b/src/ivch/ivch_reg.h
@@ -0,0 +1,97 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file
+ * This file contains the register definitions for the i82807aa.
+ *
+ * Documentation on this chipset can be found in datasheet #29069001 at
+ * intel.com.
+ */
+#ifndef I82807AA_REG_H
+#define I82807AA_REG_H
+
+/** @defgroup VR00
+ * @{
+ */
+#define VR00 0x00
+# define VR00_BASE_ADDRESS_MASK 0x007f
+/** @} */
+
+/** @defgroup VR01
+ * @{
+ */
+#define VR01 0x01
+# define VR01_PANEL_FIT_ENABLE (1 << 3)
+/**
+ * Enables the LCD display.
+ *
+ * This must not be set while VR01_DVO_BYPASS_ENABLE is set.
+ */
+# define VR01_LCD_ENABLE (1 << 2)
+/** Enables the DVO repeater. */
+# define VR01_DVO_BYPASS_ENABLE (1 << 1)
+/** Enables the DVO clock */
+# define VR01_DVO_ENABLE (1 << 0)
+/** @} */
+
+/** @defgroup VR10
+ * @{
+ */
+#define VR10 0x10
+/** Enables LVDS output instead of CMOS */
+# define VR10_LVDS_ENABLE (1 << 4)
+/** Enables 18-bit LVDS output. */
+# define VR10_INTERFACE_1X18 (0 << 2)
+/** Enables 24-bit LVDS or CMOS output */
+# define VR10_INTERFACE_1X24 (1 << 2)
+/** Enables 2x18-bit LVDS or CMOS output. */
+# define VR10_INTERFACE_2X18 (2 << 2)
+/** Enables 2x24-bit LVDS output */
+# define VR10_INTERFACE_2X24 (3 << 2)
+/** @} */
+
+/** @defgroup VR30
+ * @{
+ */
+#define VR30 0x30
+/** Read only bit indicating that the panel is not in a safe poweroff state. */
+# define VR30_PANEL_ON (1 << 15)
+/** @} */
+
+/** @defgroup VR40
+ * @{
+ */
+#define VR40 0x40
+# define VR40_STALL_ENABLE (1 << 13)
+# define VR40_VERTICAL_INTERP_ENABLE (1 << 11)
+# define VR40_HORIZONTAL_INTERP_ENABLE (1 << 10)
+# define VR40_RATIO_ENABLE (1 << 9)
+# define VR40_PANEL_FIT_ENABLE (1 << 8)
+/** @} */
+
+#endif /* I82807AA_REG_H */