⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radeon_mm_i2c.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include "radeon.h"#include "radeon_reg.h"#include "radeon_macros.h"#include "radeon_probe.h"#include <X11/extensions/Xv.h>#include "radeon_video.h"#include "atipciids.h"#include "xf86.h"/* i2c stuff */#include "xf86i2c.h"#include "fi1236.h"#include "msp3430.h"#include "tda9885.h"#include "uda1380.h"#include "i2c_def.h"#define I2C_DONE        (1<<0)#define I2C_NACK        (1<<1)#define I2C_HALT        (1<<2)#define I2C_SOFT_RST    (1<<5)#define I2C_DRIVE_EN    (1<<6)#define I2C_DRIVE_SEL   (1<<7)#define I2C_START       (1<<8)#define I2C_STOP        (1<<9)#define I2C_RECEIVE     (1<<10)#define I2C_ABORT       (1<<11)#define I2C_GO          (1<<12)#define I2C_SEL         (1<<16)#define I2C_EN          (1<<17)static void RADEON_TDA9885_Init(RADEONPortPrivPtr pPriv);/* Wait for 10ms at the most for the I2C_GO register to drop. */#define I2C_WAIT_FOR_GO() { \	int i2ctries = 0; \	RADEONWaitForIdleMMIO(pScrn); \	write_mem_barrier(); \	while (i2ctries < 10) { \		reg = INREG8(RADEON_I2C_CNTL_0+1); \		if (!(reg & (I2C_GO >> 8))) \			break; \		if (reg & (I2C_ABORT >> 8)) \			break; \		usleep(1000); \		i2ctries++; \	} \}/* Wait, and dump the status in the 'status' register.  If we time out or * receive an abort signal, halt/restart the I2C bus and leave _ABORT in the * status register. */#define I2C_WAIT_WITH_STATUS() { \	I2C_WAIT_FOR_GO() \	if (reg & ((I2C_ABORT >> 8) | (I2C_GO >> 8))) { \		RADEON_I2C_Halt(pScrn); \		status = I2C_ABORT; \	} \	else \		status = RADEON_I2C_WaitForAck(pScrn, pPriv); \}/**************************************************************************** *  I2C_WaitForAck (void)                                                   * *                                                                          * *  Function: polls the I2C status bits, waiting for an acknowledge or      * *            an error condition.                                           * *    Inputs: NONE                                                          * *   Outputs: I2C_DONE - the I2C transfer was completed                     * *            I2C_NACK - an NACK was received from the slave                * *            I2C_HALT - a timeout condition has occured                    * ****************************************************************************/static CARD8 RADEON_I2C_WaitForAck (ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv){    CARD8 retval = 0;    RADEONInfoPtr info = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    long counter = 0;    usleep(1000);    while(1)    {        RADEONWaitForIdleMMIO(pScrn);         retval = INREG8(RADEON_I2C_CNTL_0);        if (retval & I2C_HALT)        {            return (I2C_HALT);        }        if (retval & I2C_NACK)        {            return (I2C_NACK);        }        if(retval & I2C_DONE)        {            return I2C_DONE;        }               counter++;	/* 50ms ought to be long enough. */        if(counter > 50)        {             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Timeout condition on Radeon i2c bus\n");             return I2C_HALT;        }	usleep(1000);    }}static void RADEON_I2C_Halt (ScrnInfoPtr pScrn){    RADEONInfoPtr info = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    CARD8    reg;    /* reset status flags */    RADEONWaitForIdleMMIO(pScrn);    reg = INREG8 (RADEON_I2C_CNTL_0 + 0) & ~(I2C_DONE|I2C_NACK|I2C_HALT);    OUTREG8 (RADEON_I2C_CNTL_0 + 0, reg);    /* issue ABORT call */    RADEONWaitForIdleMMIO(pScrn);    reg = INREG8 (RADEON_I2C_CNTL_0 + 1) & 0xE7;    OUTREG8 (RADEON_I2C_CNTL_0 + 1, (reg |((I2C_GO|I2C_ABORT) >> 8)));    /* wait for GO bit to go low */    I2C_WAIT_FOR_GO();}static Bool RADEONI2CWriteRead(I2CDevPtr d, I2CByte *WriteBuffer, int nWrite,                            I2CByte *ReadBuffer, int nRead){    int loop, status;    CARD32 i2c_cntl_0, i2c_cntl_1;    CARD8 reg;    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)(d->pI2CBus->DriverPrivate.ptr);    ScrnInfoPtr pScrn = xf86Screens[d->pI2CBus->scrnIndex];    RADEONInfoPtr info = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    status=I2C_DONE;    RADEONWaitForIdleMMIO(pScrn);    if(nWrite>0){/*       RADEONWaitForFifo(pScrn, 4+nWrite); */       /* Clear the status bits of the I2C Controller */       OUTREG(RADEON_I2C_CNTL_0, I2C_DONE | I2C_NACK | I2C_HALT | I2C_SOFT_RST);       /* Write the address into the buffer first */       OUTREG(RADEON_I2C_DATA, (CARD32) (d->SlaveAddr) & ~(1));       /* Write Value into the buffer */       for (loop = 0; loop < nWrite; loop++)       {          OUTREG8(RADEON_I2C_DATA, WriteBuffer[loop]);       }       i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | I2C_EN | I2C_SEL |                        nWrite | 0x100;       OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1);           i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) |                         I2C_GO | I2C_START | ((nRead >0)?0:I2C_STOP) | I2C_DRIVE_EN;       OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0);           I2C_WAIT_WITH_STATUS();       if(status!=I2C_DONE){          RADEON_I2C_Halt(pScrn);          return FALSE;          }    }            if(nRead > 0) {       RADEONWaitForFifo(pScrn, 4+nRead);           OUTREG(RADEON_I2C_CNTL_0, I2C_DONE | I2C_NACK | I2C_HALT | I2C_SOFT_RST);        /* Write the address into the buffer first */       OUTREG(RADEON_I2C_DATA, (CARD32) (d->SlaveAddr) | (1));       i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | I2C_EN | I2C_SEL |                         nRead | 0x100;       OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1);           i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) |                         I2C_GO | I2C_START | I2C_STOP | I2C_DRIVE_EN | I2C_RECEIVE;       OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0);           I2C_WAIT_WITH_STATUS();         /* Write Value into the buffer */       for (loop = 0; loop < nRead; loop++)       {          RADEONWaitForFifo(pScrn, 1);          if((status == I2C_HALT) || (status == I2C_NACK))          {          ReadBuffer[loop]=0xff;          } else {          RADEONWaitForIdleMMIO(pScrn);          ReadBuffer[loop]=INREG8(RADEON_I2C_DATA) & 0xff;          }       }    }        if(status!=I2C_DONE){       RADEON_I2C_Halt(pScrn);       return FALSE;       }    return TRUE;}static Bool R200_I2CWriteRead(I2CDevPtr d, I2CByte *WriteBuffer, int nWrite,                            I2CByte *ReadBuffer, int nRead){    int loop, status;    CARD32 i2c_cntl_0, i2c_cntl_1;    CARD8 reg;    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)(d->pI2CBus->DriverPrivate.ptr);    ScrnInfoPtr pScrn = xf86Screens[d->pI2CBus->scrnIndex];    RADEONInfoPtr info = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    status=I2C_DONE;    RADEONWaitForIdleMMIO(pScrn);    if(nWrite>0){/*       RADEONWaitForFifo(pScrn, 4+nWrite); */       /* Clear the status bits of the I2C Controller */       OUTREG(RADEON_I2C_CNTL_0, I2C_DONE | I2C_NACK | I2C_HALT | I2C_SOFT_RST);       /* Write the address into the buffer first */       OUTREG(RADEON_I2C_DATA, (CARD32) (d->SlaveAddr) & ~(1));       /* Write Value into the buffer */       for (loop = 0; loop < nWrite; loop++)       {          OUTREG8(RADEON_I2C_DATA, WriteBuffer[loop]);       }       i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | I2C_EN | I2C_SEL |                        nWrite | 0x010;       OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1);           i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) |                         I2C_GO | I2C_START | ((nRead >0)?0:I2C_STOP) | I2C_DRIVE_EN;       OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0);           I2C_WAIT_WITH_STATUS();       if(status!=I2C_DONE){          RADEON_I2C_Halt(pScrn);          return FALSE;          }    }            if(nRead > 0) {       RADEONWaitForFifo(pScrn, 4+nRead);           OUTREG(RADEON_I2C_CNTL_0, I2C_DONE | I2C_NACK | I2C_HALT | I2C_SOFT_RST);        /* Write the address into the buffer first */       OUTREG(RADEON_I2C_DATA, (CARD32) (d->SlaveAddr) | (1));       i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | I2C_EN | I2C_SEL |                         nRead | 0x010;       OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1);           i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) |                         I2C_GO | I2C_START | I2C_STOP | I2C_DRIVE_EN | I2C_RECEIVE;       OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0);           I2C_WAIT_WITH_STATUS();         RADEONWaitForIdleMMIO(pScrn);       /* Write Value into the buffer */       for (loop = 0; loop < nRead; loop++)       {          if((status == I2C_HALT) || (status == I2C_NACK))          {          ReadBuffer[loop]=0xff;          } else {          ReadBuffer[loop]=INREG8(RADEON_I2C_DATA) & 0xff;          }       }    }        if(status!=I2C_DONE){       RADEON_I2C_Halt(pScrn);       return FALSE;       }    return TRUE;}#if 0static Bool RADEONProbeAddress(I2CBusPtr b, I2CSlaveAddr addr){     I2CByte a;     I2CDevRec d;          d.DevName = "Probing";     d.SlaveAddr = addr;     d.pI2CBus = b;     d.NextDev = NULL;          return I2C_WriteRead(&d, NULL, 0, &a, 1);}#endif#define I2C_CLOCK_FREQ     (60000.0)const struct {   char *name;    int type;} RADEON_tuners[32] =    {        /* name ,index to tuner_parms table */        {"NO TUNER"            , -1},        {"Philips FI1236 (or compatible)"               , TUNER_TYPE_FI1236},        {"Philips FI1236 (or compatible)"               , TUNER_TYPE_FI1236},        {"Philips FI1216 (or compatible)"               , TUNER_TYPE_FI1216},        {"Philips FI1246 (or compatible)"               , TUNER_TYPE_FI1246},        {"Philips FI1216MF (or compatible)"             , TUNER_TYPE_FI1216},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -