diff options
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/common.h | 1 | ||||
-rw-r--r-- | src/i810_driver.c | 8 | ||||
-rw-r--r-- | src/i810_reg.h | 4 | ||||
-rw-r--r-- | src/i830.h | 4 | ||||
-rw-r--r-- | src/i830_driver.c | 49 | ||||
-rw-r--r-- | src/i830_i2c.c | 116 | ||||
-rw-r--r-- | src/i830_raw.c | 1 |
8 files changed, 184 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2e0ffd09..40c53f0c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -55,7 +55,8 @@ i810_drv_la_SOURCES = \ i830_video.c \ i830_rotate.c \ i830_randr.c \ - i830_raw.c + i830_raw.c \ + i830_i2c.c if DRI i810_drv_la_SOURCES += \ diff --git a/src/common.h b/src/common.h index d5c810f0..10267360 100644 --- a/src/common.h +++ b/src/common.h @@ -81,6 +81,7 @@ extern const char *I810fbSymbols[]; extern const char *I810xaaSymbols[]; extern const char *I810shadowFBSymbols[]; extern const char *I810shadowSymbols[]; +extern const char *I810i2cSymbols[]; #ifdef XF86DRI extern const char *I810driSymbols[]; extern const char *I810drmSymbols[]; diff --git a/src/i810_driver.c b/src/i810_driver.c index 7d854df2..4d1f50dd 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -335,6 +335,14 @@ const char *I810shadowSymbols[] = { NULL }; + +const char *I810i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + NULL +}; + + #ifndef I810_DEBUG int I810_DEBUG = (0 /* | DEBUG_ALWAYS_SYNC */ diff --git a/src/i810_reg.h b/src/i810_reg.h index 0e2a627a..fabc7ff0 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -263,7 +263,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define HSYNC_ON 0x00 #define HSYNC_OFF 0x02 - +#define GPIOA 0x5010 +#define GPIOB 0x5014 +#define GPIOC 0x501C /* p317, 319 */ @@ -441,6 +441,10 @@ typedef struct _I830Rec { OsTimerPtr devicesTimer; Bool rawmode; int MaxClock; + Bool ddc2; + I2CBusPtr pI2CBus; + CARD32 DDCReg; + } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) diff --git a/src/i830_driver.c b/src/i830_driver.c index 9f35d850..41bdd3ac 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2085,6 +2085,52 @@ I830UseDDC(ScrnInfoPtr pScrn) return mon_range->max_clock; } +void +I830PreInitDDC(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (!xf86LoadSubModule(pScrn, "ddc")) { + pI830->ddc2 = FALSE; + } else { + xf86LoaderReqSymLists(I810ddcSymbols, NULL); + pI830->ddc2 = TRUE; + } + + /* DDC can use I2C bus */ + /* Load I2C if we have the code to use it */ + if (pI830->ddc2) { + if (xf86LoadSubModule(pScrn, "i2c")) { + xf86LoaderReqSymLists(I810i2cSymbols,NULL); + pI830->ddc2 = I830I2cInit(pScrn); + } + else pI830->ddc2 = FALSE; + } + +} + +void I830DetectMonitors(ScrnInfoPtr pScrn) +{ + volatile xf86MonPtr MonInfo[3]; + I830Ptr pI830 = I830PTR(pScrn); + int i; + int DDCReg[] = {GPIOA, GPIOB, GPIOC}; + + for (i=0; i<3; i++) + { + pI830->DDCReg = DDCReg[i]; + + MonInfo[i] = xf86DoEDID_DDC2(pScrn->scrnIndex, pI830->pI2CBus); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "doing monitor %d\n", i); + xf86PrintEDID(MonInfo[i]); + + } + + return; + +} + static void PreInitCleanup(ScrnInfoPtr pScrn) { @@ -2570,6 +2616,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->fixedPipe = 1; } + I830PreInitDDC(pScrn); + + I830DetectMonitors(pScrn); pI830->MonType1 = PIPE_NONE; pI830->MonType2 = PIPE_NONE; pI830->specifiedMonitor = FALSE; diff --git a/src/i830_i2c.c b/src/i830_i2c.c new file mode 100644 index 00000000..9cb65251 --- /dev/null +++ b/src/i830_i2c.c @@ -0,0 +1,116 @@ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +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 +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. + +**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "compiler.h" +#include "mibstore.h" +#include "vgaHW.h" +#include "mipointer.h" +#include "micmap.h" +#include "shadowfb.h" +#include <X11/extensions/randr.h> +#include "fb.h" +#include "miscstruct.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> +#include "shadow.h" +#include "i830.h" + +/* bit locations in the registers */ +#define SCL_DIR_MASK 0x0001 +#define SCL_DIR 0x0002 +#define SCL_VAL_MASK 0x0004 +#define SCL_VAL_OUT 0x0008 +#define SCL_VAL_IN 0x0010 +#define SDA_DIR_MASK 0x0100 +#define SDA_DIR 0x0200 +#define SDA_VAL_MASK 0x0400 +#define SDA_VAL_OUT 0x0800 +#define SDA_VAL_IN 0x1000 + +static void I830I2CGetBits(I2CBusPtr b, int *clock, int *data) +{ + ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long val; + + OUTREG(pI830->DDCReg, (SCL_DIR_MASK)); + OUTREG(pI830->DDCReg, 0); + val = INREG(pI830->DDCReg); + + *clock = (val & SCL_VAL_IN) != 0; + + OUTREG(pI830->DDCReg, (SDA_DIR_MASK)); + OUTREG(pI830->DDCReg, 0); + val = INREG(pI830->DDCReg); + + *data = (val & SDA_VAL_IN) != 0; +} + +static void I830I2CPutBits(I2CBusPtr b, int clock, int data) +{ + ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long val; + + /* do this in two passes */ + OUTREG(pI830->DDCReg, (clock ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); + val = INREG(pI830->DDCReg); + + OUTREG(pI830->DDCReg, (data ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); + val = INREG(pI830->DDCReg); +} + +Bool +I830I2cInit(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + pI830->pI2CBus = xf86CreateI2CBusRec(); + + if (!pI830->pI2CBus) return FALSE; + + pI830->pI2CBus->BusName = "DDC"; + pI830->pI2CBus->scrnIndex = pScrn->scrnIndex; + pI830->pI2CBus->I2CPutBits = I830I2CPutBits; + pI830->pI2CBus->I2CGetBits = I830I2CGetBits; + pI830->pI2CBus->AcknTimeout = 10; + + if (!xf86I2CBusInit(pI830->pI2CBus)) return FALSE; + + return TRUE; + +} diff --git a/src/i830_raw.c b/src/i830_raw.c index e2260547..480edf7c 100644 --- a/src/i830_raw.c +++ b/src/i830_raw.c @@ -674,3 +674,4 @@ I830RawSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) return ret; } + |