diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/i830_dvo.c | 13 | ||||
-rw-r--r-- | src/ivch/Makefile.am | 15 | ||||
-rw-r--r-- | src/ivch/ivch.c | 234 | ||||
-rw-r--r-- | src/ivch/ivch_module.c | 64 | ||||
-rw-r--r-- | src/ivch/ivch_reg.h | 97 |
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 */ |