#include "ffb.h"
#include "ffb_dac.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86DDC.h"
static void
WaitForVSYNC(ffb_dacPtr dac)
{
unsigned int vsap = DACCFG_READ(dac, FFBDAC_CFG_VSAP);
unsigned int vcnt;
vcnt = DACCFG_READ(dac, FFBDAC_CFG_TGVC);
while (vcnt > vsap)
vcnt = DACCFG_READ(dac, FFBDAC_CFG_TGVC);
while (vcnt <= vsap)
vcnt = DACCFG_READ(dac, FFBDAC_CFG_TGVC);
}
#define MDATA_NEEDS_BLANK
static unsigned int
FFBDacDdc1Read(ScrnInfoPtr pScrn)
{
FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
ffb_dacPtr dac = pFfb->dac;
unsigned int val;
#ifdef MDATA_NEEDS_BLANK
unsigned int uctrl;
#endif
#ifdef MDATA_NEEDS_BLANK
uctrl = DACCFG_READ(dac, FFBDAC_CFG_UCTRL);
DACCFG_WRITE(dac, FFBDAC_CFG_UCTRL,
(uctrl | FFBDAC_UCTRL_ABLANK));
#endif
DACCFG_WRITE(dac, FFBDAC_CFG_MPDATA,
FFBDAC_CFG_MPDATA_SCL);
WaitForVSYNC(dac);
val = DACCFG_READ(dac, FFBDAC_CFG_MPSENSE);
val = (val & FFBDAC_CFG_MPSENSE_SCL) ? 1 : 0;
DACCFG_WRITE(dac, FFBDAC_CFG_MPDATA, 0);
#ifdef MDATA_NEEDS_BLANK
DACCFG_WRITE(dac, FFBDAC_CFG_UCTRL, uctrl);
#endif
return val;
}
static void
FFBI2CGetBits(I2CBusPtr b, int *clock, int *data)
{
FFBPtr pFfb = GET_FFB_FROM_SCRN(xf86Screens[b->scrnIndex]);
ffb_dacPtr dac = pFfb->dac;
unsigned int val;
#ifdef MDATA_NEEDS_BLANK
unsigned int uctrl;
#endif
#ifdef MDATA_NEEDS_BLANK
uctrl = DACCFG_READ(dac, FFBDAC_CFG_UCTRL);
DACCFG_WRITE(dac, FFBDAC_CFG_UCTRL,
(uctrl | FFBDAC_UCTRL_ABLANK));
#endif
DACCFG_WRITE(dac, FFBDAC_CFG_MPDATA,
(FFBDAC_CFG_MPDATA_SCL | FFBDAC_CFG_MPDATA_SDA));
val = DACCFG_READ(dac, FFBDAC_CFG_MPSENSE);
*clock = (val & FFBDAC_CFG_MPSENSE_SCL) ? 1 : 0;
*data = (val & FFBDAC_CFG_MPSENSE_SDA) ? 1 : 0;
DACCFG_WRITE(dac, FFBDAC_CFG_MPDATA, 0);
#ifdef MDATA_NEEDS_BLANK
DACCFG_WRITE(dac, FFBDAC_CFG_UCTRL, uctrl);
#endif
}
static void
FFBI2CPutBits(I2CBusPtr b, int clock, int data)
{
FFBPtr pFfb = GET_FFB_FROM_SCRN(xf86Screens[b->scrnIndex]);
ffb_dacPtr dac = pFfb->dac;
unsigned int val;
#ifdef MDATA_NEEDS_BLANK
unsigned int uctrl;
#endif
val = 0;
if (clock)
val |= FFBDAC_CFG_MPDATA_SCL;
if (data)
val |= FFBDAC_CFG_MPDATA_SDA;
#ifdef MDATA_NEEDS_BLANK
uctrl = DACCFG_READ(dac, FFBDAC_CFG_UCTRL);
DACCFG_WRITE(dac, FFBDAC_CFG_UCTRL,
(uctrl | FFBDAC_UCTRL_ABLANK));
#endif
DACCFG_WRITE(dac, FFBDAC_CFG_MPDATA, val);
#ifdef MDATA_NEEDS_BLANK
DACCFG_WRITE(dac, FFBDAC_CFG_UCTRL, uctrl);
#endif
}
Bool
FFBi2cInit(ScrnInfoPtr pScrn)
{
FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
I2CBusPtr I2CPtr;
I2CPtr = xf86CreateI2CBusRec();
if (!I2CPtr)
return FALSE;
pFfb->I2C = I2CPtr;
I2CPtr->BusName = "DDC";
I2CPtr->scrnIndex = pScrn->scrnIndex;
I2CPtr->I2CPutBits = FFBI2CPutBits;
I2CPtr->I2CGetBits = FFBI2CGetBits;
I2CPtr->AcknTimeout = 5;
if (!xf86I2CBusInit(I2CPtr))
return FALSE;
return TRUE;
}