1209ff23fSmrg#ifdef HAVE_CONFIG_H 2209ff23fSmrg#include "config.h" 3209ff23fSmrg#endif 4209ff23fSmrg 5209ff23fSmrg#include <math.h> 6209ff23fSmrg 7209ff23fSmrg#include "radeon.h" 8209ff23fSmrg#include "radeon_reg.h" 9209ff23fSmrg#include "radeon_macros.h" 10209ff23fSmrg#include "radeon_probe.h" 11209ff23fSmrg#include <X11/extensions/Xv.h> 12209ff23fSmrg#include "radeon_video.h" 13209ff23fSmrg#include "atipciids.h" 14209ff23fSmrg 15209ff23fSmrg#include "xf86.h" 16209ff23fSmrg 17209ff23fSmrg/* i2c stuff */ 18209ff23fSmrg#include "xf86i2c.h" 19209ff23fSmrg#include "fi1236.h" 20209ff23fSmrg#include "msp3430.h" 21209ff23fSmrg#include "tda9885.h" 22209ff23fSmrg#include "uda1380.h" 23209ff23fSmrg#include "i2c_def.h" 24209ff23fSmrg 25209ff23fSmrg 26209ff23fSmrgstatic void RADEON_TDA9885_Init(RADEONPortPrivPtr pPriv); 27209ff23fSmrg 28209ff23fSmrg/* Wait for 10ms at the most for the I2C_GO register to drop. */ 29209ff23fSmrg#define I2C_WAIT_FOR_GO() { \ 30209ff23fSmrg int i2ctries = 0; \ 31209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); \ 32209ff23fSmrg write_mem_barrier(); \ 33209ff23fSmrg while (i2ctries < 10) { \ 34209ff23fSmrg reg = INREG8(RADEON_I2C_CNTL_0+1); \ 35209ff23fSmrg if (!(reg & (RADEON_I2C_GO >> 8))) \ 36209ff23fSmrg break; \ 37209ff23fSmrg if (reg & (RADEON_I2C_ABORT >> 8)) \ 38209ff23fSmrg break; \ 39209ff23fSmrg usleep(1000); \ 40209ff23fSmrg i2ctries++; \ 41209ff23fSmrg } \ 42209ff23fSmrg} 43209ff23fSmrg 44209ff23fSmrg/* Wait, and dump the status in the 'status' register. If we time out or 45209ff23fSmrg * receive an abort signal, halt/restart the I2C bus and leave _ABORT in the 46209ff23fSmrg * status register. */ 47209ff23fSmrg#define I2C_WAIT_WITH_STATUS() { \ 48209ff23fSmrg I2C_WAIT_FOR_GO() \ 49209ff23fSmrg if (reg & ((RADEON_I2C_ABORT >> 8) | (RADEON_I2C_GO >> 8))) { \ 50209ff23fSmrg RADEON_I2C_Halt(pScrn); \ 51209ff23fSmrg status = RADEON_I2C_ABORT; \ 52209ff23fSmrg } \ 53209ff23fSmrg else \ 54209ff23fSmrg status = RADEON_I2C_WaitForAck(pScrn, pPriv); \ 55209ff23fSmrg} 56209ff23fSmrg 57209ff23fSmrg/**************************************************************************** 58209ff23fSmrg * I2C_WaitForAck (void) * 59209ff23fSmrg * * 60209ff23fSmrg * Function: polls the I2C status bits, waiting for an acknowledge or * 61209ff23fSmrg * an error condition. * 62209ff23fSmrg * Inputs: NONE * 63209ff23fSmrg * Outputs: I2C_DONE - the I2C transfer was completed * 64209ff23fSmrg * I2C_NACK - an NACK was received from the slave * 65209ff23fSmrg * I2C_HALT - a timeout condition has occured * 66209ff23fSmrg ****************************************************************************/ 67209ff23fSmrgstatic uint8_t RADEON_I2C_WaitForAck (ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 68209ff23fSmrg{ 69209ff23fSmrg uint8_t retval = 0; 70209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 71209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 72209ff23fSmrg long counter = 0; 73209ff23fSmrg 74209ff23fSmrg usleep(1000); 75209ff23fSmrg while(1) 76209ff23fSmrg { 77209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 78209ff23fSmrg retval = INREG8(RADEON_I2C_CNTL_0); 79209ff23fSmrg if (retval & RADEON_I2C_HALT) 80209ff23fSmrg { 81209ff23fSmrg return (RADEON_I2C_HALT); 82209ff23fSmrg } 83209ff23fSmrg if (retval & RADEON_I2C_NACK) 84209ff23fSmrg { 85209ff23fSmrg return (RADEON_I2C_NACK); 86209ff23fSmrg } 87209ff23fSmrg if(retval & RADEON_I2C_DONE) 88209ff23fSmrg { 89209ff23fSmrg return RADEON_I2C_DONE; 90209ff23fSmrg } 91209ff23fSmrg counter++; 92209ff23fSmrg /* 50ms ought to be long enough. */ 93209ff23fSmrg if(counter > 50) 94209ff23fSmrg { 95209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Timeout condition on Radeon i2c bus\n"); 96209ff23fSmrg return RADEON_I2C_HALT; 97209ff23fSmrg } 98209ff23fSmrg usleep(1000); 99209ff23fSmrg } 100209ff23fSmrg} 101209ff23fSmrg 102209ff23fSmrgstatic void RADEON_I2C_Halt (ScrnInfoPtr pScrn) 103209ff23fSmrg{ 104209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 105209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 106209ff23fSmrg uint8_t reg; 107209ff23fSmrg 108209ff23fSmrg /* reset status flags */ 109209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 110209ff23fSmrg reg = INREG8 (RADEON_I2C_CNTL_0 + 0) & ~(RADEON_I2C_DONE|RADEON_I2C_NACK|RADEON_I2C_HALT); 111209ff23fSmrg OUTREG8 (RADEON_I2C_CNTL_0 + 0, reg); 112209ff23fSmrg 113209ff23fSmrg /* issue ABORT call */ 114209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 115209ff23fSmrg reg = INREG8 (RADEON_I2C_CNTL_0 + 1) & 0xE7; 116209ff23fSmrg OUTREG8 (RADEON_I2C_CNTL_0 + 1, (reg |((RADEON_I2C_GO|RADEON_I2C_ABORT) >> 8))); 117209ff23fSmrg 118209ff23fSmrg /* wait for GO bit to go low */ 119209ff23fSmrg I2C_WAIT_FOR_GO(); 120209ff23fSmrg} 121209ff23fSmrg 122209ff23fSmrg 123209ff23fSmrgstatic Bool RADEONI2CWriteRead(I2CDevPtr d, I2CByte *WriteBuffer, int nWrite, 124209ff23fSmrg I2CByte *ReadBuffer, int nRead) 125209ff23fSmrg{ 126209ff23fSmrg int loop, status; 127209ff23fSmrg uint32_t i2c_cntl_0, i2c_cntl_1; 128209ff23fSmrg uint8_t reg; 129209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)(d->pI2CBus->DriverPrivate.ptr); 130209ff23fSmrg ScrnInfoPtr pScrn = xf86Screens[d->pI2CBus->scrnIndex]; 131209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 132209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 133209ff23fSmrg 134209ff23fSmrg status=RADEON_I2C_DONE; 135209ff23fSmrg 136209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 137209ff23fSmrg if(nWrite>0){ 138209ff23fSmrg/* RADEONWaitForFifo(pScrn, 4+nWrite); */ 139209ff23fSmrg 140209ff23fSmrg /* Clear the status bits of the I2C Controller */ 141209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, RADEON_I2C_DONE | RADEON_I2C_NACK | RADEON_I2C_HALT | RADEON_I2C_SOFT_RST); 142209ff23fSmrg 143209ff23fSmrg /* Write the address into the buffer first */ 144209ff23fSmrg OUTREG(RADEON_I2C_DATA, (uint32_t) (d->SlaveAddr) & ~(1)); 145209ff23fSmrg 146209ff23fSmrg /* Write Value into the buffer */ 147209ff23fSmrg for (loop = 0; loop < nWrite; loop++) 148209ff23fSmrg { 149209ff23fSmrg OUTREG8(RADEON_I2C_DATA, WriteBuffer[loop]); 150209ff23fSmrg } 151209ff23fSmrg 152209ff23fSmrg i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | RADEON_I2C_EN | RADEON_I2C_SEL | 153209ff23fSmrg nWrite | 0x100; 154209ff23fSmrg OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1); 155209ff23fSmrg 156209ff23fSmrg i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) | 157209ff23fSmrg RADEON_I2C_GO | RADEON_I2C_START | ((nRead >0)?0:RADEON_I2C_STOP) | RADEON_I2C_DRIVE_EN; 158209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0); 159209ff23fSmrg 160209ff23fSmrg I2C_WAIT_WITH_STATUS(); 161209ff23fSmrg 162209ff23fSmrg if(status!=RADEON_I2C_DONE){ 163209ff23fSmrg RADEON_I2C_Halt(pScrn); 164209ff23fSmrg return FALSE; 165209ff23fSmrg } 166209ff23fSmrg } 167209ff23fSmrg 168209ff23fSmrg 169209ff23fSmrg if(nRead > 0) { 170209ff23fSmrg RADEONWaitForFifo(pScrn, 4+nRead); 171209ff23fSmrg 172209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, RADEON_I2C_DONE | RADEON_I2C_NACK | RADEON_I2C_HALT | RADEON_I2C_SOFT_RST); 173209ff23fSmrg 174209ff23fSmrg /* Write the address into the buffer first */ 175209ff23fSmrg OUTREG(RADEON_I2C_DATA, (uint32_t) (d->SlaveAddr) | (1)); 176209ff23fSmrg 177209ff23fSmrg i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | RADEON_I2C_EN | RADEON_I2C_SEL | 178209ff23fSmrg nRead | 0x100; 179209ff23fSmrg OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1); 180209ff23fSmrg 181209ff23fSmrg i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) | 182209ff23fSmrg RADEON_I2C_GO | RADEON_I2C_START | RADEON_I2C_STOP | RADEON_I2C_DRIVE_EN | RADEON_I2C_RECEIVE; 183209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0); 184209ff23fSmrg 185209ff23fSmrg I2C_WAIT_WITH_STATUS(); 186209ff23fSmrg 187209ff23fSmrg /* Write Value into the buffer */ 188209ff23fSmrg for (loop = 0; loop < nRead; loop++) 189209ff23fSmrg { 190209ff23fSmrg RADEONWaitForFifo(pScrn, 1); 191209ff23fSmrg if((status == RADEON_I2C_HALT) || (status == RADEON_I2C_NACK)) 192209ff23fSmrg { 193209ff23fSmrg ReadBuffer[loop]=0xff; 194209ff23fSmrg } else { 195209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 196209ff23fSmrg ReadBuffer[loop]=INREG8(RADEON_I2C_DATA) & 0xff; 197209ff23fSmrg } 198209ff23fSmrg } 199209ff23fSmrg } 200209ff23fSmrg 201209ff23fSmrg if(status!=RADEON_I2C_DONE){ 202209ff23fSmrg RADEON_I2C_Halt(pScrn); 203209ff23fSmrg return FALSE; 204209ff23fSmrg } 205209ff23fSmrg return TRUE; 206209ff23fSmrg} 207209ff23fSmrg 208209ff23fSmrgstatic Bool R200_I2CWriteRead(I2CDevPtr d, I2CByte *WriteBuffer, int nWrite, 209209ff23fSmrg I2CByte *ReadBuffer, int nRead) 210209ff23fSmrg{ 211209ff23fSmrg int loop, status; 212209ff23fSmrg uint32_t i2c_cntl_0, i2c_cntl_1; 213209ff23fSmrg uint8_t reg; 214209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)(d->pI2CBus->DriverPrivate.ptr); 215209ff23fSmrg ScrnInfoPtr pScrn = xf86Screens[d->pI2CBus->scrnIndex]; 216209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 217209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 218209ff23fSmrg 219209ff23fSmrg status=RADEON_I2C_DONE; 220209ff23fSmrg 221209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 222209ff23fSmrg if(nWrite>0){ 223209ff23fSmrg/* RADEONWaitForFifo(pScrn, 4+nWrite); */ 224209ff23fSmrg 225209ff23fSmrg /* Clear the status bits of the I2C Controller */ 226209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, RADEON_I2C_DONE | RADEON_I2C_NACK | RADEON_I2C_HALT | RADEON_I2C_SOFT_RST); 227209ff23fSmrg 228209ff23fSmrg /* Write the address into the buffer first */ 229209ff23fSmrg OUTREG(RADEON_I2C_DATA, (uint32_t) (d->SlaveAddr) & ~(1)); 230209ff23fSmrg 231209ff23fSmrg /* Write Value into the buffer */ 232209ff23fSmrg for (loop = 0; loop < nWrite; loop++) 233209ff23fSmrg { 234209ff23fSmrg OUTREG8(RADEON_I2C_DATA, WriteBuffer[loop]); 235209ff23fSmrg } 236209ff23fSmrg 237209ff23fSmrg i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | RADEON_I2C_EN | RADEON_I2C_SEL | 238209ff23fSmrg nWrite | 0x010; 239209ff23fSmrg OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1); 240209ff23fSmrg 241209ff23fSmrg i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) | 242209ff23fSmrg RADEON_I2C_GO | RADEON_I2C_START | ((nRead >0)?0:RADEON_I2C_STOP) | RADEON_I2C_DRIVE_EN; 243209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0); 244209ff23fSmrg 245209ff23fSmrg I2C_WAIT_WITH_STATUS(); 246209ff23fSmrg 247209ff23fSmrg if(status!=RADEON_I2C_DONE){ 248209ff23fSmrg RADEON_I2C_Halt(pScrn); 249209ff23fSmrg return FALSE; 250209ff23fSmrg } 251209ff23fSmrg } 252209ff23fSmrg 253209ff23fSmrg 254209ff23fSmrg if(nRead > 0) { 255209ff23fSmrg RADEONWaitForFifo(pScrn, 4+nRead); 256209ff23fSmrg 257209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, RADEON_I2C_DONE | RADEON_I2C_NACK | RADEON_I2C_HALT | RADEON_I2C_SOFT_RST); 258209ff23fSmrg 259209ff23fSmrg /* Write the address into the buffer first */ 260209ff23fSmrg OUTREG(RADEON_I2C_DATA, (uint32_t) (d->SlaveAddr) | (1)); 261209ff23fSmrg 262209ff23fSmrg i2c_cntl_1 = (pPriv->radeon_i2c_timing << 24) | RADEON_I2C_EN | RADEON_I2C_SEL | 263209ff23fSmrg nRead | 0x010; 264209ff23fSmrg OUTREG(RADEON_I2C_CNTL_1, i2c_cntl_1); 265209ff23fSmrg 266209ff23fSmrg i2c_cntl_0 = (pPriv->radeon_N << 24) | (pPriv->radeon_M << 16) | 267209ff23fSmrg RADEON_I2C_GO | RADEON_I2C_START | RADEON_I2C_STOP | RADEON_I2C_DRIVE_EN | RADEON_I2C_RECEIVE; 268209ff23fSmrg OUTREG(RADEON_I2C_CNTL_0, i2c_cntl_0); 269209ff23fSmrg 270209ff23fSmrg I2C_WAIT_WITH_STATUS(); 271209ff23fSmrg 272209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 273209ff23fSmrg /* Write Value into the buffer */ 274209ff23fSmrg for (loop = 0; loop < nRead; loop++) 275209ff23fSmrg { 276209ff23fSmrg if((status == RADEON_I2C_HALT) || (status == RADEON_I2C_NACK)) 277209ff23fSmrg { 278209ff23fSmrg ReadBuffer[loop]=0xff; 279209ff23fSmrg } else { 280209ff23fSmrg ReadBuffer[loop]=INREG8(RADEON_I2C_DATA) & 0xff; 281209ff23fSmrg } 282209ff23fSmrg } 283209ff23fSmrg } 284209ff23fSmrg 285209ff23fSmrg if(status!=RADEON_I2C_DONE){ 286209ff23fSmrg RADEON_I2C_Halt(pScrn); 287209ff23fSmrg return FALSE; 288209ff23fSmrg } 289209ff23fSmrg return TRUE; 290209ff23fSmrg} 291209ff23fSmrg 292209ff23fSmrg#if 0 293209ff23fSmrgstatic Bool RADEONProbeAddress(I2CBusPtr b, I2CSlaveAddr addr) 294209ff23fSmrg{ 295209ff23fSmrg I2CByte a; 296209ff23fSmrg I2CDevRec d; 297209ff23fSmrg 298209ff23fSmrg d.DevName = "Probing"; 299209ff23fSmrg d.SlaveAddr = addr; 300209ff23fSmrg d.pI2CBus = b; 301209ff23fSmrg d.NextDev = NULL; 302209ff23fSmrg 303209ff23fSmrg return I2C_WriteRead(&d, NULL, 0, &a, 1); 304209ff23fSmrg} 305209ff23fSmrg#endif 306209ff23fSmrg 307209ff23fSmrg#define I2C_CLOCK_FREQ (60000.0) 308209ff23fSmrg 309209ff23fSmrg 310209ff23fSmrgconst struct 311209ff23fSmrg{ 312209ff23fSmrg char *name; 313209ff23fSmrg int type; 314209ff23fSmrg} RADEON_tuners[32] = 315209ff23fSmrg { 316209ff23fSmrg /* name ,index to tuner_parms table */ 317209ff23fSmrg {"NO TUNER" , -1}, 318209ff23fSmrg {"Philips FI1236 (or compatible)" , TUNER_TYPE_FI1236}, 319209ff23fSmrg {"Philips FI1236 (or compatible)" , TUNER_TYPE_FI1236}, 320209ff23fSmrg {"Philips FI1216 (or compatible)" , TUNER_TYPE_FI1216}, 321209ff23fSmrg {"Philips FI1246 (or compatible)" , TUNER_TYPE_FI1246}, 322209ff23fSmrg {"Philips FI1216MF (or compatible)" , TUNER_TYPE_FI1216}, 323209ff23fSmrg {"Philips FI1236 (or compatible)" , TUNER_TYPE_FI1236}, 324209ff23fSmrg {"Philips FI1256 (or compatible)" , TUNER_TYPE_FI1256}, 325209ff23fSmrg {"Philips FI1236 (or compatible)" , TUNER_TYPE_FI1236}, 326209ff23fSmrg {"Philips FI1216 (or compatible)" , TUNER_TYPE_FI1216}, 327209ff23fSmrg {"Philips FI1246 (or compatible)" , TUNER_TYPE_FI1246}, 328209ff23fSmrg {"Philips FI1216MF (or compatible)" , TUNER_TYPE_FI1216}, 329209ff23fSmrg {"Philips FI1236 (or compatible)" , TUNER_TYPE_FI1236}, 330209ff23fSmrg {"TEMIC-FN5AL" , TUNER_TYPE_TEMIC_FN5AL}, 331209ff23fSmrg {"FQ1216ME/P" , TUNER_TYPE_FI1216}, 332209ff23fSmrg {"FI1236W" , TUNER_TYPE_FI1236W}, 333209ff23fSmrg {"Philips FI1216ME (or compatible)" , TUNER_TYPE_FM1216ME}, 334209ff23fSmrg /*{"Alps TSCxx" , -1},*/ 335209ff23fSmrg {"Philips FM1236/F" , TUNER_TYPE_FI1236W}, 336209ff23fSmrg {"Philips FI1216ME (or compatible)" , TUNER_TYPE_FM1216ME}, 337209ff23fSmrg {"UNKNOWN-19" , -1}, 338209ff23fSmrg {"UNKNOWN-20" , -1}, 339209ff23fSmrg {"UNKNOWN-21" , -1}, 340209ff23fSmrg {"UNKNOWN-22" , -1}, 341209ff23fSmrg {"UNKNOWN-23" , -1}, 342209ff23fSmrg {"UNKNOWN-24" , -1}, 343209ff23fSmrg {"UNKNOWN-25" , -1}, 344209ff23fSmrg {"UNKNOWN-26" , -1}, 345209ff23fSmrg {"UNKNOWN-27" , -1}, 346209ff23fSmrg {"UNKNOWN-28" , -1}, 347209ff23fSmrg {"Microtuner MT2032" , TUNER_TYPE_MT2032}, 348209ff23fSmrg {"Microtuner MT2032" , TUNER_TYPE_MT2032}, 349209ff23fSmrg {"UNKNOWN-31" , -1} 350209ff23fSmrg }; 351209ff23fSmrg 352209ff23fSmrg 353209ff23fSmrgvoid RADEONResetI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 354209ff23fSmrg{ 355209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 356209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 357209ff23fSmrg 358209ff23fSmrg RADEONWaitForFifo(pScrn, 2); 359209ff23fSmrg OUTREG8(RADEON_I2C_CNTL_1+2, ((RADEON_I2C_SEL | RADEON_I2C_EN)>>16)); 360209ff23fSmrg OUTREG8(RADEON_I2C_CNTL_0+0, (RADEON_I2C_DONE | RADEON_I2C_NACK | RADEON_I2C_HALT | RADEON_I2C_SOFT_RST | RADEON_I2C_DRIVE_EN | RADEON_I2C_DRIVE_SEL)); 361209ff23fSmrg} 362209ff23fSmrg 363209ff23fSmrgvoid RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 364209ff23fSmrg{ 365209ff23fSmrg double nm; 366209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 367209ff23fSmrg RADEONPLLPtr pll = &(info->pll); 368209ff23fSmrg 369209ff23fSmrg pPriv->i2c = NULL; 370209ff23fSmrg pPriv->fi1236 = NULL; 371209ff23fSmrg pPriv->msp3430 = NULL; 372209ff23fSmrg pPriv->tda9885 = NULL; 373209ff23fSmrg pPriv->uda1380 = NULL; 374209ff23fSmrg #if 0 /* put back on when saa7114 support is present */ 375209ff23fSmrg pPriv->saa7114 = NULL; 376209ff23fSmrg #endif 377209ff23fSmrg 378209ff23fSmrg /* Blacklist chipsets that lockup - these are usually older mobility chips */ 379209ff23fSmrg 380209ff23fSmrg switch(info->Chipset){ 381209ff23fSmrg case PCI_CHIP_RADEON_LY: 382209ff23fSmrg case PCI_CHIP_RADEON_LZ: 383209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M6, disabling multimedia i2c\n"); 384209ff23fSmrg return; 385209ff23fSmrg case PCI_CHIP_RADEON_LW: 386209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M7, disabling multimedia i2c\n"); 387209ff23fSmrg return; 388209ff23fSmrg /*case PCI_CHIP_RV250_If: 389209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon 9000 - skipping multimedia i2c initialization code.\n"); 390209ff23fSmrg return;*/ 391209ff23fSmrg case PCI_CHIP_RV370_5460: 392209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility X300, disabling multimedia i2c\n"); 393209ff23fSmrg return; 394209ff23fSmrg } 395209ff23fSmrg 396209ff23fSmrg /* no multimedia capabilities detected and no information was provided to substitute for it */ 397209ff23fSmrg if(!info->MM_TABLE_valid && 398209ff23fSmrg !(info->tunerType>=0)) 399209ff23fSmrg { 400209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No video input capabilities detected and no information is provided - disabling multimedia i2c\n"); 401209ff23fSmrg return; 402209ff23fSmrg } 403209ff23fSmrg 404209ff23fSmrg 405209ff23fSmrg if(pPriv->i2c!=NULL) return; /* for some reason we are asked to init it again.. Stop ! */ 406209ff23fSmrg 407209ff23fSmrg if(!xf86LoadSubModule(pScrn,"i2c")) 408209ff23fSmrg { 409209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to initialize i2c bus\n"); 410209ff23fSmrg pPriv->i2c = NULL; 411209ff23fSmrg return; 412209ff23fSmrg } 413209ff23fSmrg pPriv->i2c=CreateI2CBusRec(); 414209ff23fSmrg pPriv->i2c->scrnIndex=pScrn->scrnIndex; 415209ff23fSmrg pPriv->i2c->BusName="Radeon multimedia bus"; 416209ff23fSmrg pPriv->i2c->DriverPrivate.ptr=(pointer)pPriv; 417209ff23fSmrg switch(info->ChipFamily){ 418209ff23fSmrg case CHIP_FAMILY_RV350: 419209ff23fSmrg case CHIP_FAMILY_R350: 420209ff23fSmrg case CHIP_FAMILY_R300: 421209ff23fSmrg case CHIP_FAMILY_RV250: 422209ff23fSmrg case CHIP_FAMILY_R200: 423209ff23fSmrg case CHIP_FAMILY_RV200: 424209ff23fSmrg pPriv->i2c->I2CWriteRead=R200_I2CWriteRead; 425209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Using R200 i2c bus access method\n"); 426209ff23fSmrg break; 427209ff23fSmrg default: 428209ff23fSmrg pPriv->i2c->I2CWriteRead=RADEONI2CWriteRead; 429209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Using Radeon bus access method\n"); 430209ff23fSmrg } 431209ff23fSmrg if(!I2CBusInit(pPriv->i2c)) 432209ff23fSmrg { 433209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Failed to register i2c bus\n"); 434209ff23fSmrg } 435209ff23fSmrg 436209ff23fSmrg#if 1 437209ff23fSmrg switch(info->ChipFamily){ 438209ff23fSmrg case CHIP_FAMILY_RV200: 439209ff23fSmrg nm=(pll->reference_freq * 40000.0)/(1.0*I2C_CLOCK_FREQ); 440209ff23fSmrg break; 441209ff23fSmrg case CHIP_FAMILY_R300: 442209ff23fSmrg case CHIP_FAMILY_R200: 443209ff23fSmrg if(info->MM_TABLE_valid && (RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type==TUNER_TYPE_MT2032)){ 444209ff23fSmrg nm=(pll->reference_freq * 40000.0)/(4.0*I2C_CLOCK_FREQ); 445209ff23fSmrg break; 446209ff23fSmrg } 447209ff23fSmrg default: 448209ff23fSmrg nm=(pll->reference_freq * 10000.0)/(4.0*I2C_CLOCK_FREQ); 449209ff23fSmrg } 450209ff23fSmrg#else 451209ff23fSmrg nm=(pll->xclk * 40000.0)/(1.0*I2C_CLOCK_FREQ); 452209ff23fSmrg#endif 453209ff23fSmrg for(pPriv->radeon_N=1; pPriv->radeon_N<255; pPriv->radeon_N++) 454209ff23fSmrg if((pPriv->radeon_N * (pPriv->radeon_N-1)) > nm)break; 455209ff23fSmrg pPriv->radeon_M=pPriv->radeon_N-1; 456209ff23fSmrg pPriv->radeon_i2c_timing=2*pPriv->radeon_N; 457209ff23fSmrg 458209ff23fSmrg 459209ff23fSmrg#if 0 460209ff23fSmrg 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); 461209ff23fSmrg pPriv->radeon_M=0x32; 462209ff23fSmrg pPriv->radeon_N=0x33; 463209ff23fSmrg pPriv->radeon_i2c_timing=2*pPriv->radeon_N; 464209ff23fSmrg#endif 465209ff23fSmrg RADEONResetI2C(pScrn, pPriv); 466209ff23fSmrg 467209ff23fSmrg#if 0 /* I don't know whether standalone boards are supported with Radeons */ 468209ff23fSmrg /* looks like none of them have AMC connectors anyway */ 469209ff23fSmrg if(!info->MM_TABLE_valid)RADEON_read_eeprom(pPriv); 470209ff23fSmrg#endif 471209ff23fSmrg 472209ff23fSmrg if(!xf86LoadSubModule(pScrn,"fi1236")) 473209ff23fSmrg { 474209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize fi1236 driver\n"); 475209ff23fSmrg } 476209ff23fSmrg else 477209ff23fSmrg { 478209ff23fSmrg if(pPriv->fi1236 == NULL) 479209ff23fSmrg { 480209ff23fSmrg pPriv->fi1236 = xf86_Detect_FI1236(pPriv->i2c, FI1236_ADDR_1); 481209ff23fSmrg } 482209ff23fSmrg if(pPriv->fi1236 == NULL) 483209ff23fSmrg { 484209ff23fSmrg pPriv->fi1236 = xf86_Detect_FI1236(pPriv->i2c, FI1236_ADDR_2); 485209ff23fSmrg } 486209ff23fSmrg } 487209ff23fSmrg if(pPriv->fi1236 != NULL) 488209ff23fSmrg { 489209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected %s device at 0x%02x\n", 490209ff23fSmrg RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].name, 491209ff23fSmrg FI1236_ADDR(pPriv->fi1236)); 492209ff23fSmrg if(info->MM_TABLE_valid)xf86_FI1236_set_tuner_type(pPriv->fi1236, RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type); 493209ff23fSmrg else { 494209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MM_TABLE not found (standalone board ?), forcing tuner type to NTSC\n"); 495209ff23fSmrg xf86_FI1236_set_tuner_type(pPriv->fi1236, TUNER_TYPE_FI1236); 496209ff23fSmrg } 497209ff23fSmrg } 498209ff23fSmrg 499209ff23fSmrg if(info->MM_TABLE_valid && (RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type==TUNER_TYPE_MT2032)){ 500209ff23fSmrg if(!xf86LoadSubModule(pScrn,"tda9885")) 501209ff23fSmrg { 502209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize tda9885 driver\n"); 503209ff23fSmrg } 504209ff23fSmrg else 505209ff23fSmrg { 506209ff23fSmrg if(pPriv->tda9885 == NULL) 507209ff23fSmrg { 508209ff23fSmrg pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_1); 509209ff23fSmrg } 510209ff23fSmrg if(pPriv->tda9885 == NULL) 511209ff23fSmrg { 512209ff23fSmrg pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_2); 513209ff23fSmrg } 514209ff23fSmrg if(pPriv->tda9885 != NULL) 515209ff23fSmrg { 516209ff23fSmrg RADEON_TDA9885_Init(pPriv); 517209ff23fSmrg } 518209ff23fSmrg } 519209ff23fSmrg } 520209ff23fSmrg 521209ff23fSmrg if(info->MM_TABLE_valid && ((RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type==TUNER_TYPE_FM1216ME) 522209ff23fSmrg || (RADEON_tuners[info->MM_TABLE.tuner_type & 0x1f].type==TUNER_TYPE_FI1236W))) 523209ff23fSmrg { 524209ff23fSmrg if(!xf86LoadSubModule(pScrn,"tda9885")) 525209ff23fSmrg { 526209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize tda9885 driver\n"); 527209ff23fSmrg } 528209ff23fSmrg else 529209ff23fSmrg { 530209ff23fSmrg if(pPriv->tda9885 == NULL) 531209ff23fSmrg { 532209ff23fSmrg pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_1); 533209ff23fSmrg } 534209ff23fSmrg if(pPriv->tda9885 == NULL) 535209ff23fSmrg { 536209ff23fSmrg pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_2); 537209ff23fSmrg } 538209ff23fSmrg if(pPriv->tda9885 != NULL) 539209ff23fSmrg { 540209ff23fSmrg RADEON_TDA9885_Init(pPriv); 541209ff23fSmrg pPriv->fi1236->afc_source = (void*)pPriv->tda9885; 542209ff23fSmrg } 543209ff23fSmrg } 544209ff23fSmrg } 545209ff23fSmrg 546209ff23fSmrg if(!xf86LoadSubModule(pScrn,"uda1380")) 547209ff23fSmrg { 548209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize uda1380 driver\n"); 549209ff23fSmrg } 550209ff23fSmrg else 551209ff23fSmrg { 552209ff23fSmrg if(pPriv->uda1380 == NULL) 553209ff23fSmrg { 554209ff23fSmrg pPriv->uda1380 = xf86_Detect_uda1380(pPriv->i2c, UDA1380_ADDR_1); 555209ff23fSmrg } 556209ff23fSmrg if(pPriv->uda1380 == NULL) 557209ff23fSmrg { 558209ff23fSmrg pPriv->uda1380 = xf86_Detect_uda1380(pPriv->i2c, UDA1380_ADDR_2); 559209ff23fSmrg } 560209ff23fSmrg if(pPriv->uda1380 != NULL) 561209ff23fSmrg { 562209ff23fSmrg xf86_uda1380_init(pPriv->uda1380); 563209ff23fSmrg } 564209ff23fSmrg } 565209ff23fSmrg 566209ff23fSmrg 567209ff23fSmrg if(!xf86LoadSubModule(pScrn,"msp3430")) 568209ff23fSmrg { 569209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize msp3430 driver\n"); 570209ff23fSmrg } 571209ff23fSmrg else 572209ff23fSmrg { 573209ff23fSmrg if(pPriv->msp3430 == NULL) 574209ff23fSmrg { 575209ff23fSmrg pPriv->msp3430 = xf86_DetectMSP3430(pPriv->i2c, MSP3430_ADDR_1); 576209ff23fSmrg } 577209ff23fSmrg if(pPriv->msp3430 == NULL) 578209ff23fSmrg { 579209ff23fSmrg pPriv->msp3430 = xf86_DetectMSP3430(pPriv->i2c, MSP3430_ADDR_2); 580209ff23fSmrg } 581209ff23fSmrg#if 0 /* this would confuse bt829 with msp3430 */ 582209ff23fSmrg if(pPriv->msp3430 == NULL) 583209ff23fSmrg { 584209ff23fSmrg pPriv->msp3430 = xf86_DetectMSP3430(pPriv->i2c, MSP3430_ADDR_3); 585209ff23fSmrg } 586209ff23fSmrg#endif 587209ff23fSmrg } 588209ff23fSmrg if(pPriv->msp3430 != NULL) 589209ff23fSmrg { 590209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected MSP3430 at 0x%02x\n", 591209ff23fSmrg MSP3430_ADDR(pPriv->msp3430)); 592209ff23fSmrg pPriv->msp3430->standard = MSP3430_NTSC; 593209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 594209ff23fSmrg xf86_ResetMSP3430(pPriv->msp3430); 595209ff23fSmrg xf86_InitMSP3430(pPriv->msp3430); 596209ff23fSmrg xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume)); 597209ff23fSmrg } 598209ff23fSmrg 599209ff23fSmrg#if 0 /* put this back when saa7114 driver is ready */ 600209ff23fSmrg if(!xf86LoadSubModule(pScrn,"saa7114")) 601209ff23fSmrg { 602209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to initialize saa7114 driver\n"); 603209ff23fSmrg } 604209ff23fSmrg else 605209ff23fSmrg { 606209ff23fSmrg if(pPriv->saa7114 == NULL) 607209ff23fSmrg { 608209ff23fSmrg pPriv->saa7114 = xf86_DetectSAA7114(pPriv->i2c, SAA7114_ADDR_1); 609209ff23fSmrg } 610209ff23fSmrg if(pPriv->saa7114 == NULL) 611209ff23fSmrg { 612209ff23fSmrg pPriv->saa7114 = xf86_DetectSAA7114(pPriv->i2c, SAA7114_ADDR_2); 613209ff23fSmrg } 614209ff23fSmrg } 615209ff23fSmrg if(pPriv->saa7114 != NULL) 616209ff23fSmrg { 617209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected SAA7114 at 0x%02x\n", 618209ff23fSmrg pPriv->saa7114->d.SlaveAddr); 619209ff23fSmrg xf86_InitSAA7114(pPriv->saa7114); 620209ff23fSmrg } 621209ff23fSmrg#endif 622209ff23fSmrg 623209ff23fSmrg} 624209ff23fSmrg 625209ff23fSmrgstatic void RADEON_TDA9885_Init(RADEONPortPrivPtr pPriv) 626209ff23fSmrg{ 627209ff23fSmrgTDA9885Ptr t=pPriv->tda9885; 628209ff23fSmrgt->sound_trap=0; 629209ff23fSmrgt->auto_mute_fm=1; /* ? */ 630209ff23fSmrgt->carrier_mode=0; /* ??? */ 631209ff23fSmrgt->modulation=2; /* negative FM */ 632209ff23fSmrgt->forced_mute_audio=0; 633209ff23fSmrgt->port1=1; 634209ff23fSmrgt->port2=1; 635209ff23fSmrgt->top_adjustment=0x10; 636209ff23fSmrgt->deemphasis=1; 637209ff23fSmrgt->audio_gain=0; 638209ff23fSmrgt->minimum_gain=0; 639209ff23fSmrgt->gating=0; 640209ff23fSmrgt->vif_agc=1; /* set to 1 ? - depends on design */ 641209ff23fSmrgt->gating=0; 642209ff23fSmrg} 643