#include #include #include #include #include #include #include #include #include #include #include "edid.h" #include #include #include #include #include #define SiS365_patch 1 #if 0 #define DisableEdidOutsideUpdate 0 #else #define DisableEdidOutsideUpdate 1 //2009.08.31 close all EDID update outside mechanism #endif EDID_DEV EdidDev,*pEdidDev=NULL; static INT32 fmode=0; static UINT8 HDMI_UpdateOK=0, VGA_UpdateOK=0; extern INT32 spi_write_flash(void *flashaddr, void *dramaddr, ULONG size); extern void GPIOWriteFun(UINT8 index, UINT8 value); extern void GPIOOpenDrainWriteFun(UINT8 index, UINT8 value); //extern INT32 tv_SetEDIDstate(UINT8 bDefault); void *mtmp=NULL; #if !DisableEdidOutsideUpdate//2009.08.31 close all EDID update outside mechanism static void HwI2CWriteEnable(void){ if ((*(volatile UINT8 *)0xbe000002)>=0x38){ //if after 338 (*(volatile UINT32 *)Slave_ModeSel)|=SlaveW_Protect; // if ((*(volatile UINT8 *)0xbe000005)==0x11){ // 338 A1 chip only (*(volatile UINT32 *)Slave0_CTRL)|=r_i2c_wr_ena; // } } } #endif static void HwI2CWriteDisable(void){ if ((*(volatile UINT8 *)0xbe000002)>=0x38){ //if after 338 (*(volatile UINT32 *)Slave_ModeSel)&=~(SlaveW_Protect); // if ((*(volatile UINT8 *)0xbe000005)==0x11){ // 338 A1 chip only (*(volatile UINT32 *)Slave0_CTRL)&=~(r_i2c_wr_ena); // } } } #if !DisableEdidOutsideUpdate static void ReadChipDatatoShadow(void){ INT32 j=0; UINT32 tmp0, tmp1, tmp2; #if SiS365_patch for(j=0;j<0xa0;j++){ MmioWriteFun(Slave_MMIO_Raddr,j+0x100); //2010.05.10, SiS365 hw bug1, it can be patched by set 0xbe060040[8] and clear it when read 0xbe060044 MmioWriteFun(Slave_MMIO_Raddr,j); while(1){ //2010.05.10, Software reserve patch tmp0=MmioReadFun(Slave_MMIO_Rdata); tmp1=MmioReadFun(Slave_MMIO_Rdata); if(tmp0!=tmp1){ printk(KERN_EMERG "%08x != %08x\n", tmp0, tmp1); } else{ break; } } MmioWriteFun(HDMIA_SHADOWADDR+j*4,tmp0); } MmioWriteFun(Slave_MMIO_Raddr, 0x100); //2010.05.12, SiS365 hw bug2, set 0xbe060040[8] always to prevent hw EDID I2C stop reset index bug #else for(j=0;j<0xa0;j++){ MmioWriteFun(Slave_MMIO_Raddr,j+0x100); MmioWriteFun(HDMIA_SHADOWADDR+j*4,MmioReadFun(Slave_MMIO_Rdata)); } #endif } static void EdidOutsideUpdateInitFunction(void){ /* Firstly, copy data from SRAM to Shadow, HDMIA, HDMIB, VGA */ ReadChipDatatoShadow(); /* Secondly, also copy data to mtmp, for compare usage */ memcpy((void *)mtmp, (void *)HDMIA_SHADOWADDR, 640); } #endif void EDID_FMODE(INT32 Enable){ if((Enable == 1)&&(fmode == 1)){ //fix UMF bug 2009.09.23 printk(KERN_EMERG "UMF double call FMODE ERROR\n"); return; } fmode=Enable; #if 0 if(fmode){ GPIOWriteFun(3, 0); } else{ GPIOWriteFun(3, 1); } #endif #if 0 if(fmode){ GPIOOpenDrainWriteFun(16, 0); } else{ GPIOOpenDrainWriteFun(16, 1); } #endif #if DisableEdidOutsideUpdate //2009.08.31 close all EDID update outside mechanism if(fmode){ HDMI_UpdateOK=0; VGA_UpdateOK=0; } else{ } DBG_MSG1(DBGCFG_EDID, "EDID_FMODE:%d\n",Enable); #else //old code if(fmode){ //I2C Slaver Write Enable EdidOutsideUpdateInitFunction(); HwI2CWriteEnable(); HDMI_UpdateOK=0; VGA_UpdateOK=0; schedule_delayed_work(&pEdidDev->EdidWork,HZ); #if 0 GPIOWriteFun(20, 0); #endif } else{ //I2C Slaver Write Disable HwI2CWriteDisable(); cancel_delayed_work(&pEdidDev->EdidWork); #if 0 GPIOWriteFun(20, 1); #endif } DBG_MSG1(DBGCFG_EDID, "EDID_FMODE:%d\n",Enable); #endif } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8) long Slave1IoctlFun(struct file *pFile,UINT32 cmd, ULONG arg){ #else static INT32 Slave1IoctlFun(struct inode *inode, struct file *pFile,UINT32 cmd, ULONG arg){ #endif INT32 retval; //UINT8 Status; DBG_MSG1(DBGCFG_EDID, "Slave1IoctlFun"); if (_IOC_TYPE(cmd) != SIS_IOC_MAGIC) { DBG_MSG1(DBGCFG_EDID, "Invalid command"); return -ENOTTY; } retval = 0; //Status = 0; switch(cmd) { default: DBG_MSG1(DBGCFG_EDID, "Invalid Command"); retval = -ENOTTY; break; } return retval; } static void ReInitHDMIEDID(void){ INT32 i; UINT32 Data; spi_read_flash(mtmp,(void *)SPI_EDID_FLASHADDR,0x280); //read from flash for(i=0;i<0x20;i++) { Data = MmioReadFun(mtmp+i*4); MmioWriteByteFun(Slave_MMIO_Waddr,i); MmioWriteFun(Slave_MMIO_Wdata,Data); MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1); } for(i=0;i<0x40;i++) { Data = MmioReadFun(mtmp+0x100+i*4); MmioWriteByteFun(Slave_MMIO_Waddr,i+0x40); MmioWriteFun(Slave_MMIO_Wdata,Data); MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1); } } static void ReInitAllEDID(void){ INT32 i; UINT32 Data; spi_read_flash(mtmp,(void *)SPI_EDID_FLASHADDR,0x280); //read from flash for(i=0;i<0x20;i++) //HDMI A upper part { Data = MmioReadFun(mtmp+i*4); MmioWriteByteFun(Slave_MMIO_Waddr,i); MmioWriteFun(Slave_MMIO_Wdata,Data); MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1); } for(i=0;i<0x20;i++) //HDMI B upper part { Data = MmioReadFun(mtmp+i*4); MmioWriteByteFun(Slave_MMIO_Waddr,i+0x40); MmioWriteFun(Slave_MMIO_Wdata,Data); MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1); } for(i=0;i<0x20;i++) //VGA part { Data = MmioReadFun(mtmp+i*4+0x200); MmioWriteByteFun(Slave_MMIO_Waddr,i+0x80); MmioWriteFun(Slave_MMIO_Wdata,Data); MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1); } } static UINT8 EdidHdmiAUpPartCheckSum(void){ UINT8 CheckSum; UINT32 i,j; i=0x0; //HDMIA:up part for(j=0,CheckSum=0x0;j<127;j++){ CheckSum-=RB(HDMIA_SHADOWADDR+i+j); //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum); } //printk(KERN_EMERG "HdmiAUpPartCheckSum:%x\n",CheckSum); return CheckSum; } static UINT8 EdidHdmiADownPartCheckSum(void){ UINT8 CheckSum; UINT32 i,j; i=0x80; //HDMIA:down part for(j=0,CheckSum=0x0;j<127;j++){ CheckSum-=RB(HDMIA_SHADOWADDR+i+j); //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum); } //printk(KERN_EMERG "EdidHdmiADownPartCheckSum:%x\n",CheckSum); return CheckSum; } static UINT8 EdidHdmiBUpPartCheckSum(void){ UINT8 CheckSum; UINT32 i,j; i=0x100; //HDMIA:up part for(j=0,CheckSum=0x0;j<127;j++){ CheckSum-=RB(HDMIA_SHADOWADDR+i+j); //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum); } //printk(KERN_EMERG "HdmiAUpPartCheckSum:%x\n",CheckSum); return CheckSum; } #if !DisableEdidOutsideUpdate static UINT8 EdidHdmiBDownPartCheckSum(void){ UINT8 CheckSum; UINT32 i,j; i=0x180; //HDMIA:down part for(j=0,CheckSum=0x0;j<127;j++){ CheckSum-=RB(HDMIA_SHADOWADDR+i+j); //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum); } //printk(KERN_EMERG "EdidHdmiADownPartCheckSum:%x\n",CheckSum); return CheckSum; } #endif static UINT8 EdidVGAPartCheckSum(void){ UINT8 CheckSum; UINT32 i,j; i=0x200; //VGA: part for(j=0,CheckSum=0x0;j<127;j++){ CheckSum-=RB(HDMIA_SHADOWADDR+i+j); //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum); } //printk(KERN_EMERG "EdidVGAPartCheckSum:%x\n",CheckSum); return CheckSum; } UINT8 ComputEDIDCheckSum(void){ UINT8 CheckSum; //printk(KERN_EMERG "ComputEDIDCheckSum\n"); ReInitHDMIEDID(); //reload shadow from flash //printk(KERN_EMERG "EdidHdmiAUpPartCheckSum\n"); CheckSum=EdidHdmiAUpPartCheckSum(); if(CheckSum!=RB(HDMIA_SHADOWADDR+127)) return 1; //printk(KERN_EMERG "EdidHdmiADownPartCheckSum\n"); CheckSum=EdidHdmiADownPartCheckSum(); if(CheckSum!=RB(HDMIA_SHADOWADDR+0x80+127)) return 2; //printk(KERN_EMERG "EdidVGAPartCheckSum\n"); CheckSum=EdidVGAPartCheckSum(); if(CheckSum!=RB(HDMIA_SHADOWADDR+0x200+127)) return 3; //printk(KERN_EMERG "ComputEDIDCheckSum Done\n"); return 0; //ok } EXPORT_SYMBOL(ComputEDIDCheckSum); INT32 EDID_WriteHDMI(UINT8 StartAddr, INT32 len, UINT8 *ptr){ INT32 i; //write data into ShadowA for( i=0; i < len; i++){ WB(HDMIA_SHADOWADDR+StartAddr+i, ptr[i]); } //check Header if((RB(HDMIA_SHADOWADDR)!=0x00)||(RB(HDMIA_SHADOWADDR+1)!=0xff)){ printk(KERN_EMERG "EDID_WriteHDMI Header Error !\n"); return -1; } //check checksum i = EdidHdmiAUpPartCheckSum(); //recompute HDMI A up part checksum WB(HDMIA_SHADOWADDR+0x7f, i); i = EdidHdmiADownPartCheckSum(); //recompute HDMI A down part checksum WB(HDMIA_SHADOWADDR+0xff, i); if(spi_write_flash((void*)SPI_EDID_FLASHADDR,(void*)(HDMIA_SHADOWADDR),0x100)==0){ //copy shadowA to flashA printk(KERN_EMERG "EDID_WriteHDMI Write flash fail !!\n"); return -1; } ReInitAllEDID(); //printk(KERN_EMERG "EDID_WriteHDMI OK!\n"); return 0; } EXPORT_SYMBOL(EDID_WriteHDMI); INT32 EDID_WriteVGA(UINT8 StartAddr, INT32 len, UINT8 *ptr){ INT32 i; //write data into Shadow VGA for( i=0; i < len; i++){ WB(VGA_SHADOWADDR+StartAddr+i, ptr[i]); } //check Header if((RB(VGA_SHADOWADDR)!=0x00)||(RB(VGA_SHADOWADDR+1)!=0xff)){ printk(KERN_EMERG "EDID_WriteVGA Header Error !\n"); return -1; } //check checksum i= EdidVGAPartCheckSum(); //recompute VGA checksum WB(VGA_SHADOWADDR+0x7f, i); if(spi_write_flash((void*)SPI_EDID_FLASHADDR+0x200, (void*)(VGA_SHADOWADDR),0x80)==0){ //copy VGA to flash printk(KERN_EMERG "EDID_WriteVGA Write flash fail !!\n"); return -1; } ReInitAllEDID(); //printk(KERN_EMERG "EDID_WriteVGA OK!\n"); return 0; } EXPORT_SYMBOL(EDID_WriteVGA); void EDID_ReadHDMI(UINT8 StartAddr, INT32 len, UINT8 *ptr){ INT32 i; for( i=0; i < len; i++){ ptr[i] = RB(SPI_EDID_FLASHADDR+StartAddr+i); } } EXPORT_SYMBOL(EDID_ReadHDMI); void EDID_ReadVGA(UINT8 StartAddr, INT32 len, UINT8 *ptr){ INT32 i; for( i=0; i < len; i++){ ptr[i] = RB(SPI_EDID_FLASHADDR+0x200+StartAddr+i); } } EXPORT_SYMBOL(EDID_ReadVGA); INT32 EDID_URupdate(UINT8 *SN){ UINT8 tmp[2]; UINT32 tmpi,i; #if !DisableEdidOutsideUpdate cancel_delayed_work(&pEdidDev->EdidWork); //stop EDID work first #endif /* 911QQ2UY99999 _ 2009@11 __ 11 @10 ______ 5 @0c-0x0f 32 @0a-0b fix ______________ 13 byte @from 5f to 6b */ tmp[0]=(SN[0]-'0')+10; //base on 1990, so 2009 = 19 WB(HDMIB_SHADOWADDR+0x11, tmp[0]); //write year WB(VGA_SHADOWADDR+0x11, tmp[0]); DBG_MSG1(DBGCFG_EDID, "Year:%d", tmp[0]); tmp[0]=(SN[1]-'0')*10+(SN[2]-'0'); WB(HDMIB_SHADOWADDR+0x10, tmp[0]); //write week WB(VGA_SHADOWADDR+0x10, tmp[0]); DBG_MSG1(DBGCFG_EDID, "week:%d", tmp[0]); tmpi=(SN[8]-'0')*10000+(SN[9]-'0')*1000+(SN[10]-'0')*100+(SN[11]-'0')*10+(SN[12]-'0'); tmp[0]=(tmpi&0x000000ff); WB(HDMIB_SHADOWADDR+0xc, tmp[0]); //write SN WB(VGA_SHADOWADDR+0xc, tmp[0]); tmp[0]=(tmpi&0x0000ff00)>>8; WB(HDMIB_SHADOWADDR+0xd, tmp[0]); //write SN WB(VGA_SHADOWADDR+0xd, tmp[0]); tmp[0]=(tmpi&0x00ff0000)>>16; WB(HDMIB_SHADOWADDR+0xe, tmp[0]); //write SN WB(VGA_SHADOWADDR+0xe, tmp[0]); tmp[0]=(tmpi&0xff000000)>>24; WB(HDMIB_SHADOWADDR+0xf, tmp[0]); //write SN WB(VGA_SHADOWADDR+0xf, tmp[0]); DBG_MSG1(DBGCFG_EDID, "SN:%d", tmpi); for(i=0x4d;i<=0x59;i++){ //write Monitor SN 13 byte WB(HDMIB_SHADOWADDR+i, SN[i-0x4d]); WB(VGA_SHADOWADDR+i, SN[i-0x4d]); } WB(HDMIB_SHADOWADDR+0x4b, 0xff); //write 0x4b fix value 0xff WB(VGA_SHADOWADDR+0x4b,0xff); WB(HDMIB_SHADOWADDR+0x4c, 0x0); //write 0x4c fix value 0x00 WB(VGA_SHADOWADDR+0x4c,0x0); tmp[0]=EdidHdmiBUpPartCheckSum(); //recompute HDMI B up part checksum WB(HDMIB_SHADOWADDR+0x7f, tmp[0]); tmp[0]=EdidVGAPartCheckSum(); //recompute VGA part checksum WB(VGA_SHADOWADDR+0x7f, tmp[0]); if(spi_write_flash((void*)SPI_EDID_FLASHADDR,(void*)(HDMIB_SHADOWADDR),0x80)==0){ //copy shadowB to flashA DBG_MSG1(DBGCFG_EDID, "HDMI Edid write flash fail !"); return 1; } else{ //wirte ok! DBG_MSG1(DBGCFG_EDID, "HDMI Edid UpdateOK !"); HDMI_UpdateOK=1; } if(spi_write_flash((void*)(SPI_EDID_FLASHADDR+0x200),(void*)(VGA_SHADOWADDR),0x80)==0){ //copy shadowB to flashA DBG_MSG1(DBGCFG_EDID, "VGA Edid write flash fail !"); return 1; } else{ //wirte ok! DBG_MSG1(DBGCFG_EDID, "VGA Edid UpdateOK !"); VGA_UpdateOK=1; } if((VGA_UpdateOK==1)&&(HDMI_UpdateOK==1)){ HwI2CWriteDisable(); ReInitAllEDID(); #if 0 ReInitSwitch(); printk(KERN_EMERG "ReInitSwitch\n"); #endif DBG_MSG1(DBGCFG_EDID, "EDID update disable !"); //printk(KERN_EMERG "EDID update disable\n"); fmode=0; //tv_SetEDIDstate(1); //callback UMF #if 0 notice_EdidUpdateOk(); #endif } return 0; } EXPORT_SYMBOL(EDID_URupdate); #if !DisableEdidOutsideUpdate static void Edid2FlashFun(void *Context){ //UINT8 *mFlash, *mTmp; UINT32 i,j; UINT16 IntReg; // UINT16 tmpvalue; // UINT8 SNTmp[13]; //Serial Number Temp UINT8 CheckSumTmp=0; IntReg = MmioReadWordFun(Slave_IntStatus); //if((IntReg&0xFFF)!=0){ MmioWriteByteFun(IntClearReg,MmioReadByteFun(IntClearReg)|0x7); /* read Chip data to shadow */ ReadChipDatatoShadow(); #if 0//debug0507 for(i=0;i<0x100;i+=4){ if(i%16==0) printk("\n"); printk("%08x ",MmioReadFun(HDMIB_SHADOWADDR+i)); } for(i=0;i<0x100;i+=4){ if(MmioReadFun(mtmp+i)!=MmioReadFun(HDMIB_SHADOWADDR+i)){ printk("\nHDMI Diff %x\n ",i); } } for(i=0x0;i<0x80;i+=4){ if(MmioReadFun(mtmp+0x200+i)!=MmioReadFun(VGA_SHADOWADDR+i)){ printk("\nVGA Diff %x\n ",i); } } memcpy((mtmp),HDMIB_SHADOWADDR,0x100); memcpy((mtmp+0x200),VGA_SHADOWADDR,0x80); HDMI_UpdateOK=1; #endif //compare HDMI A for(i=0x0;i<0x100;i+=4){ if(MmioReadFun(mtmp+i)!=MmioReadFun(HDMIA_SHADOWADDR+i)){ printk(KERN_EMERG "HDMIA diff i %x mtmp:%x Sha:%x",i,MmioReadFun(mtmp+i),MmioReadFun(HDMIA_SHADOWADDR+i)); mdelay(100); //delay until i2c write finish //read again ReadChipDatatoShadow(); /* additional check checksum */ CheckSumTmp=EdidHdmiAUpPartCheckSum(); if(CheckSumTmp!=RB(HDMIA_SHADOWADDR+0x7f)){ printk(KERN_EMERG "HDMIA UpPart Edid CheckSum Error!\n!"); break;//goto _EdidUpDate_end; } CheckSumTmp=EdidHdmiADownPartCheckSum(); if(CheckSumTmp!=RB(HDMIA_SHADOWADDR+0xff)){ printk(KERN_EMERG "HDMIA DownPart Edid CheckSum Error!\n!"); break;//goto _EdidUpDate_end; } if( (RB(HDMIA_SHADOWADDR)!=0x00)||(RB(HDMIA_SHADOWADDR+1)!=0xff)){ printk(KERN_EMERG "HDMIA Edid Header Error!\n!"); break;//goto _EdidUpDate_end; } /* additional check checksum */ if(spi_write_flash((void*)(SPI_EDID_FLASHADDR),(void*)HDMIA_SHADOWADDR,0x100)!=0){ EdidOutsideUpdateInitFunction(); printk(KERN_EMERG "HDMIA_UpdateOK !\n"); //HDMI_UpdateOK=1; }else{ //fail printk(KERN_EMERG "Edid write flash fail !\n"); } //ReInitHDMIEDID(); break; //end for loop } } //compare HDMI B for(i=0x0;i<0x100;i+=4){ //compare HDMI B upper part if(MmioReadFun(mtmp+0x100+i)!=MmioReadFun(HDMIB_SHADOWADDR+i)){ printk(KERN_EMERG "HDMIB diff i %x mtmp:%x Sha:%x",i,MmioReadFun(mtmp+0x100+i),MmioReadFun(HDMIB_SHADOWADDR+i)); mdelay(100); //delay until i2c write finish //read again ReadChipDatatoShadow(); /* additional check checksum */ CheckSumTmp=EdidHdmiBUpPartCheckSum(); if(CheckSumTmp!=RB(HDMIB_SHADOWADDR+0x7f)){ printk(KERN_EMERG "HDMIB UpPart Edid CheckSum Error!\n!"); break;//goto _EdidUpDate_end; } CheckSumTmp=EdidHdmiBDownPartCheckSum(); if(CheckSumTmp!=RB(HDMIB_SHADOWADDR+0xff)){ printk(KERN_EMERG "HDMIB DownPart Edid CheckSum Error!\n!"); break;//goto _EdidUpDate_end; } if( (RB(HDMIB_SHADOWADDR)!=0x00)||(RB(HDMIB_SHADOWADDR+1)!=0xff)){ printk(KERN_EMERG "HDMIB Edid Header Error!\n!"); break;//goto _EdidUpDate_end; } /* additional check checksum */ if(spi_write_flash((void*)(SPI_EDID_FLASHADDR),(void*)HDMIB_SHADOWADDR,0x100)!=0){ printk(KERN_EMERG "HDMIB_UpdateOK !\n"); EdidOutsideUpdateInitFunction(); //HDMI_UpdateOK=1; }else{ //fail printk(KERN_EMERG "Edid write flash fail !\n"); } //ReInitHDMIEDID(); break; //end for loop } } for(i=0x0;i<0x80;i+=4){ //parsing VGA if(MmioReadFun(mtmp+0x200+i)!=MmioReadFun(VGA_SHADOWADDR+i)){ //if diff printk(KERN_EMERG "VGA diff i %x mtmp:%x Sha:%x",i,MmioReadFun(mtmp+0x200+i),MmioReadFun(VGA_SHADOWADDR+i)); mdelay(100); //delay until i2c write finish //read again ReadChipDatatoShadow(); /* additional check checksum */ CheckSumTmp=EdidVGAPartCheckSum(); if(CheckSumTmp!=RB(VGA_SHADOWADDR+0x7f)){ printk(KERN_EMERG "VGA Edid CheckSum Error!\n!"); break;//goto _EdidUpDate_end; } if( (RB(VGA_SHADOWADDR)!=0x00)||(RB(VGA_SHADOWADDR+1)!=0xff)){ printk(KERN_EMERG "VGA Edid Header Error!\n!"); break;//goto _EdidUpDate_end; } /* additional check checksum */ if(spi_write_flash((void*)(SPI_EDID_FLASHADDR+0x200),(void*)VGA_SHADOWADDR,0x80)!=0){ EdidOutsideUpdateInitFunction(); printk(KERN_EMERG "VGA_UpdateOK !\n"); //VGA_UpdateOK=1; }else{ //fail printk(KERN_EMERG "Edid write flash fail !\n"); } break; //end for loop } } _EdidUpDate_end: //printk(KERN_EMERG "%x EDID IntStatus!\n",*(volatile UINT16 *)Slave_IntStatus); DBG_MSG1(DBGCFG_EDID, "%x EDID IntStatus!\n",*(volatile UINT16 *)Slave_IntStatus); if(fmode){ schedule_delayed_work(&pEdidDev->EdidWork,HZ); } } #endif static INT32 Slave1OpenFun(struct inode *inode, struct file *pFile) { DBG_MSG1(DBGCFG_EDID, "Slave1OpenFun"); pFile->private_data = pEdidDev; return 0; } static INT32 Slave1CloseFun(struct inode *inode, struct file *pFile) { DBG_MSG1(DBGCFG_EDID, "Slave1CloseFun"); return 0; } static struct file_operations Slave1Fops = { .owner = THIS_MODULE, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8) .unlocked_ioctl=Slave1IoctlFun, #else .ioctl = Slave1IoctlFun, #endif .open = Slave1OpenFun, .release = Slave1CloseFun, }; INT32 __init Slave1Init(void) { INT32 result=0; dev_t devno; UINT32 Data; //CUSTIMIZATION_TABLEPTR pCustom = (volatile CUSTIMIZATION_TABLEPTR)SPI_OPTIONDATA_SHADOWADDR; //UINT8 EEpromEnable; DBG_MSG1(DBGCFG_EDID, "Edid Init"); #if 0 if(spi_CheckCustom()) EEpromEnable = pCustom->EDIDEepromEnable; else EEpromEnable = 0; #endif // TODO: What is CPU1 ISR 60 do ? // Disable CPU1 ISR 60 DBG_MSG1(DBGCFG_EDID, "Disable CPU1 ISR 60"); Data = MmioReadFun(0xBE01010C); Data &= ~0x10000000; MmioWriteFun(0xBE01010C,Data); pEdidDev = &EdidDev; memset(pEdidDev,0,sizeof(EDID_DEV)); /* move to bootrom */ /* if((EEpromEnable&0x7)==0x7) { DebugPrint("EEPROM Enable, Slave Disable"); MmioWriteFun(S0_CONTROL,0x00000000); MmioWriteFun(S1_CONTROL,0x00000000); MmioWriteFun(S2_CONTROL,0x00000000); return 0; } for(i=0;i<0x40;i++) { Data = MmioReadFun(HDMIA_SHADOWADDR+i*4); MmioWriteByteFun(0xBE070034,i); MmioWriteFun(0xBE070038,Data); MmioWriteByteFun(0xBE07002C,MmioReadByteFun(0xBE07002C)|1); } for(i=0;i<0x40;i++) { Data = MmioReadFun(HDMIB_SHADOWADDR+i*4); MmioWriteByteFun(0xBE070034,i+0x40); MmioWriteFun(0xBE070038,Data); MmioWriteByteFun(0xBE07002C,MmioReadByteFun(0xBE07002C)|1); } for(i=0;i<0x20;i++) { Data = MmioReadFun(VGA_SHADOWADDR+i*4); MmioWriteByteFun(0xBE070034,i+0x80); MmioWriteFun(0xBE070038,Data); MmioWriteByteFun(0xBE07002C,MmioReadByteFun(0xBE07002C)|1); } Data = 0x000800D0; if((EEpromEnable&0x1)==0) { MmioWriteFun(S0_CONTROL,Data); } else { MmioWriteFun(S0_CONTROL,0x00000000); DebugPrint("EEPROM Enable, Slave0 Disable"); } if((EEpromEnable&0x2)==0) { MmioWriteFun(S1_CONTROL,Data); } else { MmioWriteFun(S1_CONTROL,0x00000000); DebugPrint("EEPROM Enable, Slave1 Disable"); } if((EEpromEnable&0x4)==0) { MmioWriteFun(S2_CONTROL,Data); } else { MmioWriteFun(S2_CONTROL,0x00000000); DebugPrint("EEPROM Enable, Slave2 Disable"); } */ #if 1 mtmp = (void *)kmalloc(0x280, GFP_KERNEL); #else mtmp = (void *)drv_kmalloc(0x280, GFP_KERNEL, MODULEID_EDID); #endif if(mtmp==NULL) return 0; #if !DisableEdidOutsideUpdate INIT_DELAYED_WORK(&pEdidDev->EdidWork, (void *)Edid2FlashFun); #endif devno = MKDEV(I2C_DEV_MAJOR, 2); // I2C_DEV_MAJOR=91 cdev_init(&pEdidDev->cdev, &Slave1Fops); pEdidDev->cdev.owner = THIS_MODULE; #if 0 //B0 //if ((*(volatile UINT8 *)0xbe000005)>=0x20){ // B0 chip set_vi_handler(SLAVE_IRQ_FINAL,slave_dispatch); result = request_irq(SLAVE_IRQ_FINAL,Slave1InterruptFun,SA_SHIRQ,"edid",pEdidDev); if(result) { DBG_MSG1(DBGCFG_EDID, "request_irq fault"); } /* enable INT only in FMode to fix frequently INT problem*/ (*(volatile UINT16*)(0xbe010104))&=~EDID_HostINTmask; //} #endif result = cdev_add(&pEdidDev->cdev, devno, 1); #if 0 GPIOWriteFun(20, 1); #endif #if SiS365_patch MmioWriteFun(Slave_MMIO_Raddr, 0x100); //2010.05.12, SiS365 hw bug2, set 0xbe060040[8] always to prevent hw EDID I2C stop reset index bug #endif //EDID_FMODE(1); //ComputEDIDCheckSum(); //ReInitSwitch(); //ReInitHDMIA(); return result; } void __exit Slave1Exit(void) { DBG_MSG1(DBGCFG_EDID, "EdidExit"); fmode=0; #if !DisableEdidOutsideUpdate cancel_delayed_work(&pEdidDev->EdidWork); #endif if(mtmp!=NULL) #if 1 kfree(mtmp); #else drv_kfree(mtmp, MODULEID_EDID); #endif } #ifndef INIT_BY_KMF module_init (Slave1Init); module_exit (Slave1Exit); #endif