mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
Modified:
xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c
xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.h
xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_mm_i2c.c Add code to
access and initialize multimedia i2c bus. Hook it up.
This commit is contained in:
@@ -619,7 +619,6 @@ typedef struct {
|
||||
Bool IsDellServer;
|
||||
} RADEONInfoRec, *RADEONInfoPtr;
|
||||
|
||||
|
||||
#define RADEONWaitForFifo(pScrn, entries) \
|
||||
do { \
|
||||
if (info->fifo_slots < entries) \
|
||||
|
||||
599
src/radeon_mm_i2c.c
Normal file
599
src/radeon_mm_i2c.c
Normal file
@@ -0,0 +1,599 @@
|
||||
#include "radeon.h"
|
||||
#include "radeon_macros.h"
|
||||
#include "radeon_probe.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "Xv.h"
|
||||
#include "radeon_video.h"
|
||||
|
||||
#include "xf86.h"
|
||||
#include "xf86PciInfo.h"
|
||||
|
||||
/* i2c stuff */
|
||||
#include "xf86i2c.h"
|
||||
#include "fi1236.h"
|
||||
#include "msp3430.h"
|
||||
#include "tda9885.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);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* 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++;
|
||||
if(counter>1000000)
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Timeout condition on Radeon i2c bus\n");
|
||||
return I2C_HALT;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void RADEON_I2C_Halt (ScrnInfoPtr pScrn)
|
||||
{
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
unsigned char *RADEONMMIO = info->MMIO;
|
||||
CARD8 reg;
|
||||
long counter = 0;
|
||||
|
||||
/* 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 */
|
||||
RADEONWaitForIdleMMIO(pScrn);
|
||||
while (INREG8 (RADEON_I2C_CNTL_0 + 1) & (I2C_GO>>8))
|
||||
{
|
||||
counter++;
|
||||
if(counter>1000000)return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Bool RADEONI2CWriteRead(I2CDevPtr d, I2CByte *WriteBuffer, int nWrite,
|
||||
I2CByte *ReadBuffer, int nRead)
|
||||
{
|
||||
int loop, status;
|
||||
CARD32 i2c_cntl_0, i2c_cntl_1;
|
||||
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);
|
||||
|
||||
while(INREG8(RADEON_I2C_CNTL_0+1) & (I2C_GO >> 8));
|
||||
|
||||
status=RADEON_I2C_WaitForAck(pScrn,pPriv);
|
||||
|
||||
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);
|
||||
|
||||
RADEONWaitForIdleMMIO(pScrn);
|
||||
while(INREG8(RADEON_I2C_CNTL_0+1) & (I2C_GO >> 8));
|
||||
|
||||
status=RADEON_I2C_WaitForAck(pScrn,pPriv);
|
||||
|
||||
/* 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;
|
||||
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);
|
||||
|
||||
write_mem_barrier();
|
||||
|
||||
while(INREG8(RADEON_I2C_CNTL_0+1) & (I2C_GO >> 8));
|
||||
|
||||
status=RADEON_I2C_WaitForAck(pScrn,pPriv);
|
||||
|
||||
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);
|
||||
|
||||
write_mem_barrier();
|
||||
while(INREG8(RADEON_I2C_CNTL_0+1) & (I2C_GO >> 8));
|
||||
|
||||
status=RADEON_I2C_WaitForAck(pScrn,pPriv);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
#define I2C_CLOCK_FREQ (60000.0)
|
||||
|
||||
|
||||
const struct
|
||||
{
|
||||
char *name;
|
||||
int type;
|
||||
} RADEON_tuners[32] =
|
||||
{
|
||||
/* name ,index to tuner_parms table */
|
||||
{"NO TUNNER" , -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},
|
||||
{"Philips FI1236 (or compatible)" , TUNER_TYPE_FI1236},
|
||||
{"Philips FI1256 (or compatible)" , TUNER_TYPE_FI1256},
|
||||
{"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},
|
||||
{"Philips FI1236 (or compatible)" , TUNER_TYPE_FI1236},
|
||||
{"TEMIC-FN5AL" , TUNER_TYPE_TEMIC_FN5AL},
|
||||
{"FQ1216ME/P" , TUNER_TYPE_FI1216},
|
||||
{"FI1236W" , TUNER_TYPE_FI1236W},
|
||||
{"Alps TSBH5" , -1},
|
||||
{"Alps TSCxx" , -1},
|
||||
{"Alps TSCH5 FM" , -1},
|
||||
{"UNKNOWN-19" , -1},
|
||||
{"UNKNOWN-20" , -1},
|
||||
{"UNKNOWN-21" , -1},
|
||||
{"UNKNOWN-22" , -1},
|
||||
{"UNKNOWN-23" , -1},
|
||||
{"UNKNOWN-24" , -1},
|
||||
{"UNKNOWN-25" , -1},
|
||||
{"UNKNOWN-26" , -1},
|
||||
{"UNKNOWN-27" , -1},
|
||||
{"UNKNOWN-28" , -1},
|
||||
{"Microtuner MT2032" , TUNER_TYPE_MT2032},
|
||||
{"Microtuner MT2032" , TUNER_TYPE_MT2032},
|
||||
{"UNKNOWN-31" , -1}
|
||||
};
|
||||
|
||||
|
||||
void RADEONResetI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
|
||||
{
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
unsigned char *RADEONMMIO = info->MMIO;
|
||||
|
||||
RADEONWaitForFifo(pScrn, 2);
|
||||
OUTREG8(RADEON_I2C_CNTL_1+2, ((I2C_SEL | I2C_EN)>>16));
|
||||
OUTREG8(RADEON_I2C_CNTL_0+0, (I2C_DONE | I2C_NACK | I2C_HALT | I2C_SOFT_RST | I2C_DRIVE_EN | I2C_DRIVE_SEL));
|
||||
}
|
||||
|
||||
void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
|
||||
{
|
||||
double nm;
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
RADEONPLLPtr pll = &(info->pll);
|
||||
int i;
|
||||
unsigned char *RADEONMMIO = info->MMIO;
|
||||
|
||||
pPriv->i2c = NULL;
|
||||
pPriv->fi1236 = NULL;
|
||||
pPriv->msp3430 = NULL;
|
||||
pPriv->tda9885 = NULL;
|
||||
#if 0 /* put back on when saa7114 support is present */
|
||||
pPriv->saa7114 = NULL;
|
||||
#endif
|
||||
|
||||
/* Blacklist chipsets that lockup - these are usually older mobility chips */
|
||||
|
||||
switch(info->Chipset){
|
||||
case PCI_CHIP_RADEON_LY:
|
||||
case PCI_CHIP_RADEON_LZ:
|
||||
xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M6, disabling multimedia i2c\n");
|
||||
return;
|
||||
case PCI_CHIP_RADEON_LW:
|
||||
xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M7, disabling multimedia i2c\n");
|
||||
return;
|
||||
#ifndef PCI_CHIP_RADEON_If
|
||||
#define PCI_CHIP_RADEON_If 0x496e
|
||||
#endif
|
||||
case PCI_CHIP_RADEON_If:
|
||||
xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon 9000 - skipping multimedia i2c initialization code.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* no multimedia capabilities detected and no information was provided to substitute for it */
|
||||
if(!info->MM_TABLE_valid &&
|
||||
!(info->tunerType>=0))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No video input capabilities detected and no information is provided - disabling multimedia i2c\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(pPriv->i2c!=NULL) return; /* for some reason we are asked to init it again.. Stop ! */
|
||||
|
||||
if(!xf86LoadSubModule(pScrn,"i2c"))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to initialize i2c bus\n");
|
||||
pPriv->i2c = NULL;
|
||||
return;
|
||||
}
|
||||
xf86LoaderReqSymbols("xf86CreateI2CBusRec",
|
||||
"xf86I2CBusInit",
|
||||
"xf86DestroyI2CBus",
|
||||
"xf86CreateI2CDevRec",
|
||||
"xf86DestroyI2CDevRec",
|
||||
"xf86I2CDevInit",
|
||||
"xf86I2CWriteRead",
|
||||
NULL);
|
||||
pPriv->i2c=CreateI2CBusRec();
|
||||
pPriv->i2c->scrnIndex=pScrn->scrnIndex;
|
||||
pPriv->i2c->BusName="Radeon multimedia bus";
|
||||
pPriv->i2c->DriverPrivate.ptr=(pointer)pPriv;
|
||||
switch(info->ChipFamily){
|
||||
case CHIP_FAMILY_R300:
|
||||
case CHIP_FAMILY_R200:
|
||||
case CHIP_FAMILY_RV200:
|
||||
pPriv->i2c->I2CWriteRead=R200_I2CWriteRead;
|
||||
xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Using R200 i2c bus access method\n");
|
||||
break;
|
||||
default:
|
||||
pPriv->i2c->I2CWriteRead=RADEONI2CWriteRead;
|
||||
xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Using Radeon bus access method\n");
|
||||
}
|
||||
if(!I2CBusInit(pPriv->i2c))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Failed to register i2c bus\n");
|
||||
}
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "*** %p versus %p\n", xf86CreateI2CBusRec, CreateI2CBusRec);
|
||||
|
||||
#if 1
|
||||
switch(info->ChipFamily){
|
||||
case CHIP_FAMILY_RV200:
|
||||
nm=(pll->reference_freq * 40000.0)/(1.0*I2C_CLOCK_FREQ);
|
||||
break;
|
||||
case CHIP_FAMILY_R300:
|
||||
case CHIP_FAMILY_R200:
|
||||
if(info->MM_TABLE_valid && (RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type==TUNER_TYPE_MT2032)){
|
||||
nm=(pll->reference_freq * 40000.0)/(4.0*I2C_CLOCK_FREQ);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
nm=(pll->reference_freq * 10000.0)/(4.0*I2C_CLOCK_FREQ);
|
||||
}
|
||||
#else
|
||||
nm=(pll->xclk * 40000.0)/(1.0*I2C_CLOCK_FREQ);
|
||||
#endif
|
||||
for(pPriv->radeon_N=1; pPriv->radeon_N<255; pPriv->radeon_N++)
|
||||
if((pPriv->radeon_N * (pPriv->radeon_N-1)) > nm)break;
|
||||
pPriv->radeon_M=pPriv->radeon_N-1;
|
||||
pPriv->radeon_i2c_timing=2*pPriv->radeon_N;
|
||||
|
||||
|
||||
#if 0
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref=%d M=0x%02x N=0x%02x timing=0x%02x\n", pll->reference_freq, pPriv->radeon_M, pPriv->radeon_N, pPriv->radeon_i2c_timing);
|
||||
pPriv->radeon_M=0x32;
|
||||
pPriv->radeon_N=0x33;
|
||||
pPriv->radeon_i2c_timing=2*pPriv->radeon_N;
|
||||
#endif
|
||||
RADEONResetI2C(pScrn, pPriv);
|
||||
|
||||
#if 0 /* I don't know whether standalone boards are supported with Radeons */
|
||||
/* looks like none of them have AMC connectors anyway */
|
||||
if(!info->MM_TABLE_valid)RADEON_read_eeprom(pPriv);
|
||||
#endif
|
||||
|
||||
if(!xf86LoadSubModule(pScrn,"fi1236"))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize fi1236 driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
xf86LoaderReqSymbols(FI1236SymbolsList, NULL);
|
||||
if(pPriv->fi1236 == NULL)
|
||||
{
|
||||
pPriv->fi1236 = xf86_Detect_FI1236(pPriv->i2c, FI1236_ADDR_1);
|
||||
}
|
||||
if(pPriv->fi1236 == NULL)
|
||||
{
|
||||
pPriv->fi1236 = xf86_Detect_FI1236(pPriv->i2c, FI1236_ADDR_2);
|
||||
}
|
||||
}
|
||||
if(pPriv->fi1236 != NULL)
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected %s device at 0x%02x\n",
|
||||
RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].name,
|
||||
FI1236_ADDR(pPriv->fi1236));
|
||||
if(info->MM_TABLE_valid)xf86_FI1236_set_tuner_type(pPriv->fi1236, RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type);
|
||||
else {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MM_TABLE not found (standalone board ?), forcing tuner type to NTSC\n");
|
||||
xf86_FI1236_set_tuner_type(pPriv->fi1236, TUNER_TYPE_FI1236);
|
||||
}
|
||||
}
|
||||
|
||||
if(info->MM_TABLE_valid && (RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type==TUNER_TYPE_MT2032)){
|
||||
if(!xf86LoadSubModule(pScrn,"tda9885"))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize tda9885 driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
xf86LoaderReqSymbols(TDA9885SymbolsList, NULL);
|
||||
if(pPriv->tda9885 == NULL)
|
||||
{
|
||||
pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_1);
|
||||
}
|
||||
if(pPriv->tda9885 == NULL)
|
||||
{
|
||||
pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_2);
|
||||
}
|
||||
if(pPriv->tda9885 != NULL)
|
||||
{
|
||||
RADEON_TDA9885_Init(pPriv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!xf86LoadSubModule(pScrn,"msp3430"))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize msp3430 driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
xf86LoaderReqSymbols(MSP3430SymbolsList, NULL);
|
||||
if(pPriv->msp3430 == NULL)
|
||||
{
|
||||
pPriv->msp3430 = xf86_DetectMSP3430(pPriv->i2c, MSP3430_ADDR_1);
|
||||
}
|
||||
if(pPriv->msp3430 == NULL)
|
||||
{
|
||||
pPriv->msp3430 = xf86_DetectMSP3430(pPriv->i2c, MSP3430_ADDR_2);
|
||||
}
|
||||
#if 0 /* this would confuse bt829 with msp3430 */
|
||||
if(pPriv->msp3430 == NULL)
|
||||
{
|
||||
pPriv->msp3430 = xf86_DetectMSP3430(pPriv->i2c, MSP3430_ADDR_3);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if(pPriv->msp3430 != NULL)
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected MSP3430 at 0x%02x\n",
|
||||
MSP3430_ADDR(pPriv->msp3430));
|
||||
pPriv->msp3430->standard = MSP3430_NTSC;
|
||||
pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
|
||||
xf86_ResetMSP3430(pPriv->msp3430);
|
||||
xf86_InitMSP3430(pPriv->msp3430);
|
||||
xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
|
||||
}
|
||||
|
||||
#if 0 /* put this back when saa7114 driver is ready */
|
||||
if(!xf86LoadSubModule(pScrn,"saa7114"))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize saa7114 driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
xf86LoaderReqSymbols(SAA7114SymbolsList, NULL);
|
||||
if(pPriv->saa7114 == NULL)
|
||||
{
|
||||
pPriv->saa7114 = xf86_DetectSAA7114(pPriv->i2c, SAA7114_ADDR_1);
|
||||
}
|
||||
if(pPriv->saa7114 == NULL)
|
||||
{
|
||||
pPriv->saa7114 = xf86_DetectSAA7114(pPriv->i2c, SAA7114_ADDR_2);
|
||||
}
|
||||
}
|
||||
if(pPriv->saa7114 != NULL)
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected SAA7114 at 0x%02x\n",
|
||||
pPriv->saa7114->d.SlaveAddr);
|
||||
xf86_InitSAA7114(pPriv->saa7114);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void RADEON_TDA9885_Init(RADEONPortPrivPtr pPriv)
|
||||
{
|
||||
TDA9885Ptr t=pPriv->tda9885;
|
||||
t->sound_trap=0;
|
||||
t->auto_mute_fm=1; /* ? */
|
||||
t->carrier_mode=0; /* ??? */
|
||||
t->modulation=2; /* negative FM */
|
||||
t->forced_mute_audio=0;
|
||||
t->port1=1;
|
||||
t->port2=1;
|
||||
t->top_adjustment=0x10;
|
||||
t->deemphasis=1;
|
||||
t->audio_gain=0;
|
||||
t->minimum_gain=0;
|
||||
t->gating=0;
|
||||
t->vif_agc=1; /* set to 1 ? - depends on design */
|
||||
t->gating=0;
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "radeon_probe.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon_mergedfb.h"
|
||||
#include "radeon_video.h"
|
||||
|
||||
#include "xf86.h"
|
||||
#include "dixstruct.h"
|
||||
@@ -36,6 +37,7 @@ static int RADEONQueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
|
||||
unsigned short *, int *, int *);
|
||||
|
||||
static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
|
||||
static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv);
|
||||
|
||||
|
||||
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
|
||||
@@ -47,30 +49,6 @@ static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
|
||||
static Atom xvGamma, xvColorspace;
|
||||
static Atom xvSwitchCRT;
|
||||
|
||||
typedef struct {
|
||||
CARD32 transform_index;
|
||||
CARD32 gamma; /* gamma value x 1000 */
|
||||
int brightness;
|
||||
int saturation;
|
||||
int hue;
|
||||
int contrast;
|
||||
int red_intensity;
|
||||
int green_intensity;
|
||||
int blue_intensity;
|
||||
int ecp_div;
|
||||
|
||||
Bool doubleBuffer;
|
||||
unsigned char currentBuffer;
|
||||
RegionRec clip;
|
||||
CARD32 colorKey;
|
||||
CARD32 videoStatus;
|
||||
Time offTime;
|
||||
Time freeTime;
|
||||
Bool autopaint_colorkey;
|
||||
Bool crt2; /* 0=CRT1, 1=CRT2 */
|
||||
} RADEONPortPrivRec, *RADEONPortPrivPtr;
|
||||
|
||||
|
||||
#define GET_PORT_PRIVATE(pScrn) \
|
||||
(RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
|
||||
|
||||
@@ -855,6 +833,21 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
|
||||
else
|
||||
pPriv->crt2 = FALSE;
|
||||
|
||||
/* TV-in stuff */
|
||||
pPriv->video_stream_active = FALSE;
|
||||
pPriv->encoding = 4;
|
||||
pPriv->frequency = 1000;
|
||||
pPriv->volume = -1000;
|
||||
pPriv->mute = TRUE;
|
||||
pPriv->v = 0;
|
||||
pPriv->overlay_deinterlacing_method = METHOD_BOB;
|
||||
pPriv->capture_vbi_data = 0;
|
||||
pPriv->dec_brightness = 0;
|
||||
pPriv->dec_saturation = 0;
|
||||
pPriv->dec_contrast = 0;
|
||||
pPriv->dec_hue = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Unlike older Mach64 chips, RADEON has only two ECP settings:
|
||||
* 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
|
||||
@@ -892,6 +885,23 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
|
||||
*/
|
||||
OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
|
||||
}
|
||||
|
||||
/* Decide on tuner type */
|
||||
if((info->tunerType<0) && (info->MM_TABLE_valid)) {
|
||||
pPriv->tuner_type = info->MM_TABLE.tuner_type;
|
||||
} else
|
||||
pPriv->tuner_type = info->tunerType;
|
||||
|
||||
/* Initialize I2C bus */
|
||||
RADEONInitI2C(pScrn, pPriv);
|
||||
if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
|
||||
|
||||
#if 0 /* this is just here for easy debugging - normally off */
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n");
|
||||
for(i=0;i<255;i+=2)
|
||||
if(RADEONProbeAddress(pPriv->i2c, i))
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, " found device at address 0x%02x\n", i);
|
||||
#endif
|
||||
|
||||
info->adaptor = adapt;
|
||||
|
||||
@@ -1945,3 +1955,27 @@ RADEONInitOffscreenImages(ScreenPtr pScreen)
|
||||
|
||||
xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
|
||||
}
|
||||
|
||||
static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv)
|
||||
{
|
||||
/* Adjust PAL/SECAM constants for FI1216MF tuner */
|
||||
if((((pPriv->tuner_type & 0xf)==5) ||
|
||||
((pPriv->tuner_type & 0xf)==11)||
|
||||
((pPriv->tuner_type & 0xf)==14))
|
||||
&& (pPriv->fi1236!=NULL))
|
||||
{
|
||||
if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/
|
||||
{
|
||||
pPriv->fi1236->parm.band_low = 0xA1;
|
||||
pPriv->fi1236->parm.band_mid = 0x91;
|
||||
pPriv->fi1236->parm.band_high = 0x31;
|
||||
}
|
||||
if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/
|
||||
{
|
||||
pPriv->fi1236->parm.band_low = 0xA3;
|
||||
pPriv->fi1236->parm.band_mid = 0x93;
|
||||
pPriv->fi1236->parm.band_high = 0x33;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
77
src/radeon_video.h
Normal file
77
src/radeon_video.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef __RADEON_VIDEO_H__
|
||||
#define __RADEON_VIDEO_H__
|
||||
|
||||
#include "xf86i2c.h"
|
||||
#include "fi1236.h"
|
||||
#include "msp3430.h"
|
||||
#include "tda9885.h"
|
||||
#include "i2c_def.h"
|
||||
|
||||
/* Xvideo port struct */
|
||||
typedef struct {
|
||||
CARD32 transform_index;
|
||||
CARD32 gamma; /* gamma value x 1000 */
|
||||
int brightness;
|
||||
int saturation;
|
||||
int hue;
|
||||
int contrast;
|
||||
int red_intensity;
|
||||
int green_intensity;
|
||||
int blue_intensity;
|
||||
int ecp_div;
|
||||
|
||||
/* i2c bus and devices */
|
||||
I2CBusPtr i2c;
|
||||
CARD32 radeon_i2c_timing;
|
||||
CARD32 radeon_M;
|
||||
CARD32 radeon_N;
|
||||
CARD32 i2c_status;
|
||||
CARD32 i2c_cntl;
|
||||
|
||||
FI1236Ptr fi1236;
|
||||
CARD8 tuner_type;
|
||||
MSP3430Ptr msp3430;
|
||||
TDA9885Ptr tda9885;
|
||||
|
||||
Bool video_stream_active;
|
||||
int encoding;
|
||||
CARD32 frequency;
|
||||
int volume;
|
||||
Bool mute;
|
||||
int sap_channel;
|
||||
int v;
|
||||
CARD32 adjustment; /* general purpose variable */
|
||||
|
||||
#define METHOD_BOB 0
|
||||
#define METHOD_SINGLE 1
|
||||
#define METHOD_WEAVE 2
|
||||
#define METHOD_ADAPTIVE 3
|
||||
|
||||
int overlay_deinterlacing_method;
|
||||
|
||||
int capture_vbi_data;
|
||||
|
||||
int dec_brightness;
|
||||
int dec_saturation;
|
||||
int dec_hue;
|
||||
int dec_contrast;
|
||||
|
||||
Bool doubleBuffer;
|
||||
unsigned char currentBuffer;
|
||||
RegionRec clip;
|
||||
CARD32 colorKey;
|
||||
CARD32 videoStatus;
|
||||
Time offTime;
|
||||
Time freeTime;
|
||||
Bool autopaint_colorkey;
|
||||
Bool crt2; /* 0=CRT1, 1=CRT2 */
|
||||
|
||||
Atom device_id, location_id, instance_id;
|
||||
} RADEONPortPrivRec, *RADEONPortPrivPtr;
|
||||
|
||||
|
||||
void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
|
||||
void RADEONResetI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user