diff options
Diffstat (limited to 'src/sil164')
-rw-r--r-- | src/sil164/Makefile.am | 16 | ||||
-rw-r--r-- | src/sil164/sil164.c | 246 | ||||
-rw-r--r-- | src/sil164/sil164.h | 31 | ||||
-rw-r--r-- | src/sil164/sil164_module.c | 38 | ||||
-rw-r--r-- | src/sil164/sil164_reg.h | 74 |
5 files changed, 405 insertions, 0 deletions
diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am new file mode 100644 index 00000000..bb84d036 --- /dev/null +++ b/src/sil164/Makefile.am @@ -0,0 +1,16 @@ +# 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@ + +sil164_la_LTLIBRARIES = sil164.la +sil164_la_LDFLAGS = -module -avoid-version +sil164_ladir = @moduledir@/drivers + +sil164_la_SOURCES = \ + sil164.c \ + sil164_module.c \ + sil164.h \ + sil164_reg.h diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c new file mode 100644 index 00000000..d15b964f --- /dev/null +++ b/src/sil164/sil164.c @@ -0,0 +1,246 @@ +/* -*- c-basic-offset: 4 -*- */ +/************************************************************************** + +Copyright © 2006 Dave Airlie + +All Rights Reserved. + +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 AUTHOR 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 "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "miscstruct.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "../i2c_vid.h" +#include "sil164.h" +#include "sil164_reg.h" + +static Bool +sil164ReadByte(SIL164Ptr sil, int addr, CARD8 *ch) +{ + if (!xf86I2CReadByte(&(sil->d), addr, ch)) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to read from %s Slave %d.\n", + sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + return FALSE; + } + return TRUE; +} + +static Bool +sil164WriteByte(SIL164Ptr sil, int addr, CARD8 ch) +{ + if (!xf86I2CWriteByte(&(sil->d), addr, ch)) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to write to %s Slave %d.\n", + sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + return FALSE; + } + return TRUE; +} + +/* Silicon Image 164 driver for chip on i2c bus */ +static void * +sil164_init(I2CBusPtr b, I2CSlaveAddr addr) +{ + /* this will detect the SIL164 chip on the specified i2c bus */ + SIL164Ptr sil; + unsigned char ch; + + xf86DrvMsg(b->scrnIndex, X_ERROR, "detecting sil164\n"); + + sil = xcalloc(1, sizeof(SIL164Rec)); + if (sil == NULL) + return NULL; + + sil->d.DevName = "SIL164 TMDS Controller"; + sil->d.SlaveAddr = addr; + sil->d.pI2CBus = b; + sil->d.StartTimeout = b->StartTimeout; + sil->d.BitTimeout = b->BitTimeout; + sil->d.AcknTimeout = b->AcknTimeout; + sil->d.ByteTimeout = b->ByteTimeout; + sil->d.DriverPrivate.ptr = sil; + + if (!sil164ReadByte(sil, SIL164_VID_LO, &ch)) + goto out; + + if (ch!=(SIL164_VID & 0xFF)) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, + "sil164 not detected got %d: from %s Slave %d.\n", + ch, sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + goto out; + } + + if (!sil164ReadByte(sil, SIL164_DID_LO, &ch)) + goto out; + + if (ch!=(SIL164_DID & 0xFF)) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, + "sil164 not detected got %d: from %s Slave %d.\n", + ch, sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + goto out; + } + + if (!xf86I2CDevInit(&(sil->d))) { + goto out; + } + + return sil; + +out: + xfree(sil); + return NULL; +} + +static xf86OutputStatus +sil164_detect(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); + CARD8 reg9; + + sil164ReadByte(sil, SIL164_REG9, ®9); + + if (reg9 & SIL164_9_HTPLG) + return XF86OutputStatusConnected; + else + return XF86OutputStatusDisconnected; +} + +static ModeStatus +sil164_mode_valid(I2CDevPtr d, DisplayModePtr mode) +{ + return MODE_OK; +} + +static void +sil164_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) +{ + SIL164Ptr sil = SILPTR(d); + /* As long as the basics are set up, since we don't have clock dependencies + * in the mode setup, we can just leave the registers alone and everything + * will work fine. + */ + /* recommended programming sequence from doc */ + sil164WriteByte(sil, 0x08, 0x30); + sil164WriteByte(sil, 0x09, 0x00); + sil164WriteByte(sil, 0x0a, 0x90); + sil164WriteByte(sil, 0x0c, 0x89); + sil164WriteByte(sil, 0x08, 0x3b /*0x31*/); + /* don't do much */ + return; +} + +/* set the SIL164 power state */ +static void +sil164_dpms(I2CDevPtr d, int mode) +{ + SIL164Ptr sil = SILPTR(d); + int ret; + unsigned char ch; + + ret = sil164ReadByte(sil, SIL164_REG8, &ch); + if (ret == FALSE) + return; + + if (mode == DPMSModeOn) + ch |= SIL164_8_PD; + else + ch &= ~SIL164_8_PD; + + sil164WriteByte(sil, SIL164_REG8, ch); + + return; +} + +static void +sil164_dump_regs(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); + CARD8 val; + + sil164ReadByte(sil, SIL164_FREQ_LO, &val); + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_FREQ_LO: 0x%02x\n", + val); + sil164ReadByte(sil, SIL164_FREQ_HI, &val); + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_FREQ_HI: 0x%02x\n", + val); + sil164ReadByte(sil, SIL164_REG8, &val); + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_REG8: 0x%02x\n", val); + sil164ReadByte(sil, SIL164_REG9, &val); + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_REG9: 0x%02x\n", val); + sil164ReadByte(sil, SIL164_REGC, &val); + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_REGC: 0x%02x\n", val); +} + +static void +sil164_save(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); + + if (!sil164ReadByte(sil, SIL164_REG8, &sil->SavedReg.reg8)) + return; + + if (!sil164ReadByte(sil, SIL164_REG9, &sil->SavedReg.reg9)) + return; + + if (!sil164ReadByte(sil, SIL164_REGC, &sil->SavedReg.regc)) + return; + + return; +} + +static void +sil164_restore(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); + + /* Restore it powered down initially */ + sil164WriteByte(sil, SIL164_REG8, sil->SavedReg.reg8 & ~0x1); + + sil164WriteByte(sil, SIL164_REG9, sil->SavedReg.reg9); + sil164WriteByte(sil, SIL164_REGC, sil->SavedReg.regc); + sil164WriteByte(sil, SIL164_REG8, sil->SavedReg.reg8); +} + + +XF86I2CVidOutputRec SIL164VidOutput = { + .init = sil164_init, + .detect = sil164_detect, + .mode_valid = sil164_mode_valid, + .mode_set = sil164_mode_set, + .dpms = sil164_dpms, + .dump_regs = sil164_dump_regs, + .save = sil164_save, + .restore = sil164_restore, +}; diff --git a/src/sil164/sil164.h b/src/sil164/sil164.h new file mode 100644 index 00000000..9f823d6b --- /dev/null +++ b/src/sil164/sil164.h @@ -0,0 +1,31 @@ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +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 +on 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 COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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 SIL164_H +#define SIL164_H + +#define SIL164_ADDR_1 0x38 + +#endif diff --git a/src/sil164/sil164_module.c b/src/sil164/sil164_module.c new file mode 100644 index 00000000..d3bda819 --- /dev/null +++ b/src/sil164/sil164_module.c @@ -0,0 +1,38 @@ +/* -*- c-basic-offset: 4 -*- */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86Module.h" + +static MODULESETUPPROTO(sil164Setup); + +static XF86ModuleVersionInfo sil164VersRec = { + "sil164", + 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 sil164ModuleData = { + &sil164VersRec, + sil164Setup, + NULL +}; + +static pointer +sil164Setup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + return (pointer)1; +} diff --git a/src/sil164/sil164_reg.h b/src/sil164/sil164_reg.h new file mode 100644 index 00000000..ebfcb8c7 --- /dev/null +++ b/src/sil164/sil164_reg.h @@ -0,0 +1,74 @@ +/* -*- c-basic-offset: 4 -*- */ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +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 +on 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 COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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 SIL164_REG_H +#define SIL164_REG_H + +#define SIL164_VID 0x0001 +#define SIL164_DID 0x0006 + +#define SIL164_VID_LO 0x00 +#define SIL164_VID_HI 0x01 +#define SIL164_DID_LO 0x02 +#define SIL164_DID_HI 0x03 +#define SIL164_REV 0x04 +#define SIL164_RSVD 0x05 +#define SIL164_FREQ_LO 0x06 +#define SIL164_FREQ_HI 0x07 + +#define SIL164_REG8 0x08 +#define SIL164_8_VEN (1<<5) +#define SIL164_8_HEN (1<<4) +#define SIL164_8_DSEL (1<<3) +#define SIL164_8_BSEL (1<<2) +#define SIL164_8_EDGE (1<<1) +#define SIL164_8_PD (1<<0) + +#define SIL164_REG9 0x09 +#define SIL164_9_VLOW (1<<7) +#define SIL164_9_MSEL_MASK (0x7<<4) +#define SIL164_9_TSEL (1<<3) +#define SIL164_9_RSEN (1<<2) +#define SIL164_9_HTPLG (1<<1) +#define SIL164_9_MDI (1<<0) + +#define SIL164_REGC 0x0c + +typedef struct _Sil164SaveRec { + CARD8 reg8; + CARD8 reg9; + CARD8 regc; +} SIL164SaveRec; + +typedef struct { + I2CDevRec d; + SIL164SaveRec SavedReg; + SIL164SaveRec ModeReg; +} SIL164Rec, *SIL164Ptr; + +#define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr)) + +#endif |