#include #include #include #include #include #include #include #include #include "ir9561.h" #include #include #include #include #include #include #ifdef CONFIG_SUPPORT_IR_INI #include #endif #define _DRIVER_INCLUDE #include "ir_map.h" IR_IOC_IOData AndroidDataBuf; IRdatas irdatas; IRdatas irdatas2; UINT8 rpt_cnt=0, first_rpt=1, singleKey=0; UINT8 tmp_irCmd=0xFF, tmp_irAddress=0,tmp_irAddress_=0; UINT8 ir_timer_flag =0; struct timer_list IR_ContiTimer; IR_IOC_IOData* datBuf; IR_Hardware_Parameter ir_parameter; IRDEVPTR pIRDev; UINT8 IRProtocolNum, IRProtocolNum2; spinlock_t IR_lock; ULONG IR_irq_flag; ULONG IR_protocol_selection_value; void (*IR_ISRCallBackFun)(UINT8* mmiobase, IR_IOC_IOData* dataBuf)=NULL; //******************************************************************** //* //* Misc Interface //* //******************************************************************** static inline void SetMMIO_DWORD(UINT8* mmiobase, ULONG dwIndex, ULONG dwData) { writel(dwData, mmiobase+dwIndex); } #ifdef CONFIG_AUTO_USB_STORE_IRSEQ static inline void SetMMIO_DWORD_MASK(UINT8* mmiobase, ULONG dwIndex, ULONG dwData, ULONG dwMask) { ULONG dwRes, dwValue; dwRes = readl(mmiobase+dwIndex); dwValue = ((dwData & dwMask) | (dwRes & ~dwMask)); writel(dwValue, mmiobase+dwIndex); } #endif static inline ULONG GetMMIO_DWORD(UINT8* mmiobase, ULONG dwIndex) { ULONG dwRes; dwRes = readl(mmiobase+dwIndex); return dwRes; } //********************************************************** //* //* Device Opreation //* //********************************************************** static void IR_conti_routine(ULONG dumy) { spin_lock_irqsave(&IR_lock, IR_irq_flag); if(IRProtocolNum == Sharp || IRProtocolNum == Sharp2) //#if defined(IR_PROTOCOL_SHARP) { if (singleKey) { singleKey = 0; datBuf->Databuf[datBuf->Length].ContinueKey = SINGLE_KEY_END; // single end DBG_MSG1(DBGCFG_IR, "[IR]reg_single_end received\n"); } else { first_rpt = 1; rpt_cnt = 0; datBuf->Databuf[datBuf->Length].ContinueKey = CONTINUE_KEY_START_END; // continue end DBG_MSG1(DBGCFG_IR, "[IR]reg_rpt_end received\n"); } tmp_irCmd = 0xFF; } else if(IRProtocolNum == Toshiba || IRProtocolNum == TC9012) //#elif defined(IR_PROTOCOL_TOSHIBA) { ir_timer_flag = 0; if ( singleKey == 1 ) { singleKey = 0; datBuf->Databuf[datBuf->Length].ContinueKey = SINGLE_KEY_END; // single end DBG_MSG1(DBGCFG_IR, "[IR]Single_end received!!\n"); } else { datBuf->Databuf[datBuf->Length].ContinueKey = CONTINUE_KEY_START_END; // continue end DBG_MSG1(DBGCFG_IR, "[IR]reg_rpt_end received!!\n"); } rpt_cnt = 0; } else //#else { singleKey = 0; datBuf->Databuf[datBuf->Length].ContinueKey = SINGLE_KEY_END; // single end DBG_MSG1(DBGCFG_IR, "[IR]reg_single_end received (timeout) %d\n", datBuf->Databuf[datBuf->Length].ContinueKey); } //#endif datBuf->Databuf[datBuf->Length].Command = tmp_irCmd; datBuf->Databuf[datBuf->Length].Address = tmp_irAddress; datBuf->Databuf[datBuf->Length].Address_ = tmp_irAddress_; datBuf->Length++; spin_unlock_irqrestore(&IR_lock, IR_irq_flag); } void init_IR_cont_timer(int ContiKeyDelaytime) { // initial timer, Key_conti_routine * 0.01 (sec) init_timer(&IR_ContiTimer); IR_ContiTimer.expires = jiffies + ContiKeyDelaytime*HZ/1000; //Continue Key shot after ContiKeyDelaytime ms IR_ContiTimer.data = 0; IR_ContiTimer.function = IR_conti_routine; add_timer(&IR_ContiTimer); } #ifdef CONFIG_DVD_COMBO INT32 SEND_DVD_IR_COMBO( UINT8 ir_protocol, UINT32 ir_keycode ) { *(volatile UINT32 *)(0xa0000028) = ir_protocol; *(volatile UINT32 *)(0xa000002c) = ir_keycode; DBG_MSG1(DBGCFG_IR, "ir protocol:0x%08x\tkeycode:0x%08x\n", (unsigned int)(*(volatile UINT32 *)(0xa0000028)), (unsigned int)(*(volatile UINT32 *)(0xa000002c)) ); *(volatile ULONG *)(0xbe01011c) |= 0x00080000; // trigger interrupt 51 return 0; } EXPORT_SYMBOL(SEND_DVD_IR_COMBO); #endif void sisir_toshiba_ParseData(UINT8* mmiobase, IR_IOC_IOData* dataBuf) { volatile UINT32 IR_Data, IR_Custom, IR_bit_len, tmp_data, tmp_Custom, i; datBuf = dataBuf; IR_Data = irdatas.Value & 0xffff; IR_Custom = GetMMIO_DWORD(mmiobase, 0x54); //read from IR decoder recevied custom code IR_Custom = IR_Custom & 0x1ffff; IR_bit_len = (GetMMIO_DWORD(mmiobase, 0x50) & 0x3f00) >> 8; //read from IR decoder recevied bit length DBG_MSG1(DBGCFG_IR, "[IR]IR_ISR\tIR_len:%d\treg0C:0x%08x\treg54:0x%08x\n", IR_bit_len, IR_Data, IR_Custom); IR_Data = IR_Data >> 1; if ( (IR_Custom & 0x1 ) == 1 ) { IR_Data = IR_Data | 0x8000; } IR_Custom = IR_Custom >> 1; tmp_data = 0; tmp_Custom = 0; DBG_MSG1(DBGCFG_IR, "[IR]0\tIR:%08x\ttmpData:%08x\tIR_Custom:%08x\n", IR_Data, tmp_data, IR_Custom); for ( i=0;i<7;i++ ) { if ( IR_Data & 0x8000 ) { tmp_data = tmp_data | 0x8000; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x8000 ) { tmp_data = tmp_data | 0x8000; } for ( i=0;i<15; i++ ) { if ( IR_Custom & 0x8000 ) { tmp_Custom = tmp_Custom | 0x8000; } tmp_Custom = tmp_Custom >> 1; IR_Custom = IR_Custom << 1; } if ( IR_Custom & 0x8000 ) { tmp_Custom = tmp_Custom | 0x8000; } DBG_MSG1(DBGCFG_IR, "[IR]1\tIR:%08x\ttmp:%08x\ttmp_Custom:%08x\n", IR_Data, tmp_data, tmp_Custom); //IR_Data = tmp_data; if ( IR_bit_len == 33) { // Single start if ( (singleKey == 1) || (rpt_cnt != 0) ) { if ( ir_timer_flag ) { del_timer(&IR_ContiTimer); } if ( singleKey == 1 ) { DBG_MSG1(DBGCFG_IR, "[IR]2nd reg_single_sts received!!\n"); datBuf->Databuf[datBuf->Length].ContinueKey = SINGLE_KEY_END; // single end } else { DBG_MSG1(DBGCFG_IR, "[IR]reg_single_sts received during repeat!!\n"); datBuf->Databuf[datBuf->Length].ContinueKey = CONTINUE_KEY_START_END; // continue end } datBuf->Databuf[datBuf->Length].Command = tmp_irCmd; datBuf->Databuf[datBuf->Length].Address = tmp_irAddress; datBuf->Databuf[datBuf->Length].Address_ = tmp_irAddress_; datBuf->Length++; } else { DBG_MSG1(DBGCFG_IR, "[IR]1st reg_single_sts received!!\n"); } tmp_irCmd = dataBuf->Databuf[dataBuf->Length].Command = (unsigned char)(tmp_data >> 8); tmp_irAddress = dataBuf->Databuf[dataBuf->Length].Address = (unsigned char)(tmp_Custom >> 8); tmp_irAddress_ = dataBuf->Databuf[dataBuf->Length].Address_ = (unsigned char)(tmp_Custom);; DBG_MSG1(DBGCFG_IR, "[IR]Single Start Address Address_ Cmd: %x,%x, %x!!\n", tmp_irAddress, tmp_irAddress_, tmp_irCmd); dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_HEAD; dataBuf->Length++; singleKey = 1; rpt_cnt = 0; init_IR_cont_timer(150); // 150 ms ir_timer_flag = 1; } else if ( IR_bit_len == 2 ) { DBG_MSG1(DBGCFG_IR, "[IR]repeat key received!!\n"); if ( ir_timer_flag == 1 ) { del_timer(&IR_ContiTimer); } if ( rpt_cnt == 0xff ) { rpt_cnt = 1; } rpt_cnt ++; if ( (rpt_cnt == 4) && (singleKey == 1) ) { singleKey = 0; dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START; dataBuf->Length++; DBG_MSG1(DBGCFG_IR, "[IR][IR]Continue_key_start\n"); } init_IR_cont_timer(150); // 150 ms ir_timer_flag = 1; } } void sisir_TC9012_ParseData(UINT8* mmiobase, IR_IOC_IOData* dataBuf) { volatile UINT32 IR_Data,IR_bit_len, tmp_data, i; datBuf = dataBuf; IR_Data = ((GetMMIO_DWORD(mmiobase, 0x0c)>>8) & 0xfe); tmp_data = 0; for ( i=0;i<6;i++ ) { if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } dataBuf->Databuf[dataBuf->Length].Command = (unsigned char)((tmp_data) | ((GetMMIO_DWORD(mmiobase, 0x54)& 0x1))); IR_Data = (GetMMIO_DWORD(mmiobase, 0x54)>>9)& 0xff; tmp_data = 0; for ( i=0;i<7;i++ ) { if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } dataBuf->Databuf[dataBuf->Length].Address = (unsigned char)(tmp_data); IR_Data = (GetMMIO_DWORD(mmiobase, 0x54)>>1)& 0xff; tmp_data = 0; for ( i=0;i<7;i++ ) { if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } dataBuf->Databuf[dataBuf->Length].Address_ = (unsigned char)(tmp_data); IR_bit_len = (GetMMIO_DWORD(mmiobase, 0x50) & 0x3f00) >> 8; //read from IR decoder recevied bit length DBG_MSG1(DBGCFG_IR, "[IR]1\tTC9012 Add:%08x\tAdd_:%08x\tCmd:%08x\n", dataBuf->Databuf[dataBuf->Length].Address, dataBuf->Databuf[dataBuf->Length].Address_, dataBuf->Databuf[dataBuf->Length].Command); //IR_Data = tmp_data; if ( IR_bit_len == 33) { // Single start if ( (singleKey == 1) || (rpt_cnt != 0) ) { if ( ir_timer_flag ) { del_timer(&IR_ContiTimer); } if ( singleKey == 1 ) { DBG_MSG1(DBGCFG_IR, "[IR]2nd reg_single_sts received!!\n"); datBuf->Databuf[datBuf->Length].ContinueKey = SINGLE_KEY_END; // single end } else { DBG_MSG1(DBGCFG_IR, "[IR]reg_single_sts received during repeat!!\n"); datBuf->Databuf[datBuf->Length].ContinueKey = CONTINUE_KEY_START_END; // continue end } datBuf->Databuf[datBuf->Length].Command = tmp_irCmd; datBuf->Databuf[datBuf->Length].Address = tmp_irAddress; datBuf->Databuf[datBuf->Length].Address_ = tmp_irAddress_; datBuf->Length++; } else { DBG_MSG1(DBGCFG_IR, "[IR]1st reg_single_sts received!!\n"); } tmp_irCmd = dataBuf->Databuf[dataBuf->Length].Command; tmp_irAddress = dataBuf->Databuf[dataBuf->Length].Address; tmp_irAddress_ = dataBuf->Databuf[dataBuf->Length].Address_; DBG_MSG1(DBGCFG_IR, "[IR]Single Start Address Address_ Cmd: %x,%x, %x!!\n", tmp_irAddress, tmp_irAddress_, tmp_irCmd); dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_HEAD; dataBuf->Length++; singleKey = 1; rpt_cnt = 0; init_IR_cont_timer(150); // 150 ms ir_timer_flag = 1; } else if ( IR_bit_len == 2 ) { DBG_MSG1(DBGCFG_IR, "[IR]repeat key received!!\n"); if ( ir_timer_flag == 1 ) { del_timer(&IR_ContiTimer); } if ( rpt_cnt == 0xff ) { rpt_cnt = 1; } rpt_cnt ++; if ( (rpt_cnt == 4) && (singleKey == 1) ) { singleKey = 0; dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START; dataBuf->Length++; DBG_MSG1(DBGCFG_IR, "[IR][IR]Continue_key_start\n"); } init_IR_cont_timer(150); // 150 ms ir_timer_flag = 1; } } void sisir_ParseData(UINT8 IRProtocolNum,UINT8* mmiobase) { #if defined(IR_PROTOCOL_TOSHIBA2) volatile UINT32 IR_Data, IR_Custom, IR_bit_len, tmp_data, tmp_Custom, i; #endif #if defined(IR_PROTOCOL_PANASONIC) volatile UINT8 IR_Data, tmp_data, i; #endif if(IRProtocolNum == Phillips) { /* Set 0 (RC-5)*/ // addr = 0xbe08000c[12:8] data = 0xbe08000c[5:0] datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x0c) & 0x3f; datBuf->Databuf[datBuf->Length].Address = GetMMIO_DWORD(mmiobase, 0x0d) & 0x1f; datBuf->Databuf[datBuf->Length].Address_ = 0; } else if(IRProtocolNum == Sony) { /* Sony SIRC Protocol */ // addr = 0xbe08000c[15:8] data = 0xbe08000c[7:0] datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x0c); datBuf->Databuf[datBuf->Length].Address = GetMMIO_DWORD(mmiobase, 0x0d); datBuf->Databuf[datBuf->Length].Address_ = 0; } else if(IRProtocolNum == JVC) { #if 0 /* Set 3 (X-sat protocol)*/ // addr = [0xbe080056[6:0] : 0xbe080055[7]] data = 0xbe080057 datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x57); datBuf->Databuf[datBuf->Length].Address = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x56) << 1) | (GetMMIO_DWORD(mmiobase, 0x55) >> 7)); datBuf->Databuf[datBuf->Length].Address_ = 0; #endif // addr = [0xbe08000c[15:8] data = 0xbe08000c[7:0] datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x0c); datBuf->Databuf[datBuf->Length].Address = GetMMIO_DWORD(mmiobase, 0x0d); datBuf->Databuf[datBuf->Length].Address_ = 0; } else if(IRProtocolNum == Sharp) { /* Set 3 (Sharp protocol)*/ // addr = 0xbe080056[5:1], data = 0xbe080057[5:0] : 0xbe080056[7:6] if ( (GetMMIO_DWORD(mmiobase, 0x57) & 0xc0) == 0x40 ) { datBuf->Databuf[datBuf->Length].Command = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x56)>>6) | ((GetMMIO_DWORD(mmiobase, 0x57)&0x3f)<<2)); } else { datBuf->Databuf[datBuf->Length].Command = (UINT8) (~((GetMMIO_DWORD(mmiobase, 0x56)>>6) | ((GetMMIO_DWORD(mmiobase, 0x57)&0x3f)<<2))); } datBuf->Databuf[datBuf->Length].Address = (GetMMIO_DWORD(mmiobase, 0x56)>>1) &0x1f; datBuf->Databuf[datBuf->Length].Address_ = 0; } else if(IRProtocolNum == Phillips_RC6) { datBuf->Databuf[datBuf->Length].Command = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x0c)) & 0xff) ; datBuf->Databuf[datBuf->Length].Address = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x0c)>>8)); datBuf->Databuf[datBuf->Length].Address_ = 0; } else if(IRProtocolNum == RCA) { /* Set 7 (RCA) */ /*datBuf->Databuf[datBuf->Length].Command = ((*(UINT8 *)(0xbe080054) & 0x0f)<<4) | ((*(UINT8 *)(0xbe08000d) & 0xf0)>>4); datBuf->Databuf[datBuf->Length].Address = (*(UINT8 *)(0xbe080054)) >> 4; datBuf->Databuf[datBuf->Length].Address_ = *(UINT8 *)(0xbe08000d) & 0x0f;*/ datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x0c); datBuf->Databuf[datBuf->Length].Address = (GetMMIO_DWORD(mmiobase, 0x54)) >> 4; datBuf->Databuf[datBuf->Length].Address_ = 0; } else if(IRProtocolNum == X_SAT) { /* X-Sat/Mitsubishi protocol */ // addr = 0xbe08000c[15:9] [29], data = 0xbe08000c[7:0] datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x57); datBuf->Databuf[datBuf->Length].Address = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x56) << 1) | (GetMMIO_DWORD(mmiobase, 0x55) >> 7)); //datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x0c); //datBuf->Databuf[datBuf->Length].Address = (((GetMMIO_DWORD(mmiobase, 0x0f) & 0x20) << 2) | ((GetMMIO_DWORD(mmiobase, 0x0d) >> 1)& 0x7f)) & 0xff; datBuf->Databuf[datBuf->Length].Address_ = 0; } #if defined(IR_PROTOCOL_TOSHIBA2) else if(IRProtocolNum == Toshiba2) { IR_bit_len = (GetMMIO_DWORD(mmiobase, 0x50) & 0x3f00) >> 8; //read from IR decoder recevied bit length IR_Data = irdatas.Value & 0xffff; IR_Custom = GetMMIO_DWORD(mmiobase, 0x54); //read from IR decoder recevied custom code DBG_MSG1(DBGCFG_IR, "[IR]IR_ISR\tIR_len:%d\treg0C:0x%08x\treg54:0x%08x\n", IR_bit_len, IR_Data, IR_Custom); if(IR_bit_len == 33) { IR_Custom = IR_Custom & 0x1ffff; } else if(IR_bit_len == 37) { IR_Data = (IR_Custom << 16) | IR_Data; IR_Data = (IR_Data >> 4) & 0xffff; IR_Custom = (IR_Custom >> 4) & 0x1ffff; } DBG_MSG1(DBGCFG_IR, "[IR]IR_ISR\tIR_len:%d\treg0C:0x%08x\treg54:0x%08x\n", IR_bit_len, IR_Data, IR_Custom); IR_Data = IR_Data >> 1; if ( (IR_Custom & 0x1 ) == 1 ) { IR_Data = IR_Data | 0x8000; } IR_Custom = IR_Custom >> 1; tmp_data = 0; tmp_Custom = 0; DBG_MSG1(DBGCFG_IR, "[IR]0\tIR:%08x\ttmpData:%08x\tIR_Custom:%08x\n", IR_Data, tmp_data, IR_Custom); for ( i=0;i<7;i++ ) { if ( IR_Data & 0x8000 ) { tmp_data = tmp_data | 0x8000; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x8000 ) { tmp_data = tmp_data | 0x8000; } for ( i=0;i<15; i++ ) { if ( IR_Custom & 0x8000 ) { tmp_Custom = tmp_Custom | 0x8000; } tmp_Custom = tmp_Custom >> 1; IR_Custom = IR_Custom << 1; } if ( IR_Custom & 0x8000 ) { tmp_Custom = tmp_Custom | 0x8000; } DBG_MSG1(DBGCFG_IR, "[IR]1\tIR:%08x\ttmp:%08x\ttmp_Custom:%08x\n", IR_Data, tmp_data, tmp_Custom); datBuf->Databuf[datBuf->Length].Command = tmp_irCmd = (unsigned char)(tmp_data >> 8); datBuf->Databuf[datBuf->Length].Address = tmp_irAddress = (unsigned char)(tmp_Custom >> 8); datBuf->Databuf[datBuf->Length].Address_ = tmp_irAddress_ = (unsigned char)(tmp_Custom);; DBG_MSG1(DBGCFG_IR, "[IR]Single Start Address Address_ Cmd: %x,%x, %x!!\n", tmp_irAddress, tmp_irAddress_, tmp_irCmd); } #endif else if(IRProtocolNum == Konka) { //addr = 0c[15:8], cmd = [7:0] datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x0c); datBuf->Databuf[datBuf->Length].Address = GetMMIO_DWORD(mmiobase, 0x0d); datBuf->Databuf[datBuf->Length].Address_ = 0; } #if defined(IR_PROTOCOL_PANASONIC) else if(IRProtocolNum == Panasonic) { //addr = 54[9:12], addr_:54[1:8], data = 0c[9:15],0c[29] IR_Data = (((GetMMIO_DWORD(mmiobase, 0x0f) & 0x20) << 2) | ((GetMMIO_DWORD(mmiobase, 0x0d) >> 1)& 0x7f)) & 0xff; tmp_data = 0; for ( i=0;i<7;i++ ) { if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } datBuf->Databuf[datBuf->Length].Command = (unsigned char)(tmp_data);//((*(UINT8 *)(0xbe08000f) & 0x20) << 2) | (*(UINT8 *)(0xbe08000d) >> 1); //DBG_MSG1(DBGCFG_IR, "Command=%x=========\n",datBuf->Databuf[datBuf->Length].Command); IR_Data = ((GetMMIO_DWORD(mmiobase, 0x55) >> 1) & 0xf) & 0xf; tmp_data = 0; for ( i=0;i<3;i++ ) { if ( IR_Data & 0x8 ) { tmp_data = tmp_data | 0x8; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x8 ) { tmp_data = tmp_data | 0x8; } datBuf->Databuf[datBuf->Length].Address = (unsigned char)(tmp_data);//((*(UINT8 *)(0xbe080055)) >> 1) & 0xf; //DBG_MSG1(DBGCFG_IR, "Address=%x=========\n",datBuf->Databuf[datBuf->Length].Address); IR_Data = ((GetMMIO_DWORD(mmiobase, 0x55)&0x1)<<7 |(GetMMIO_DWORD(mmiobase, 0x54) >> 1)) & 0xff; tmp_data = 0; for ( i=0;i<7;i++ ) { if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } tmp_data = tmp_data >> 1; IR_Data = IR_Data << 1; } if ( IR_Data & 0x80 ) { tmp_data = tmp_data | 0x80; } datBuf->Databuf[datBuf->Length].Address_ = (unsigned char)(tmp_data);//(*(UINT8 *)(0xbe080055)&0x1)<<7 |(*(UINT8 *)(0xbe080054) >> 1);// | (*(UINT8 *)(0xbe08000f)&0x80); //DBG_MSG1(DBGCFG_IR, "Address_=%x=========\n",datBuf->Databuf[datBuf->Length].Address_); } #endif else if(IRProtocolNum == Sharp2) { // addr = 0xbe080057[7:0], add_ = 0xbe080056[7:0] , data = 0xbe08000c[15:8] datBuf->Databuf[datBuf->Length].Command = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x0c)>>8)); datBuf->Databuf[datBuf->Length].Address = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x57))); datBuf->Databuf[datBuf->Length].Address_ = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x56))); } else if(IRProtocolNum == Phillips_RC6_6A) { datBuf->Databuf[datBuf->Length].Command = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x0c)) & 0xff) ; datBuf->Databuf[datBuf->Length].Address = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x54)>>8)); datBuf->Databuf[datBuf->Length].Address_ = (UINT8) ((GetMMIO_DWORD(mmiobase, 0x54) & 0xff)); } else { datBuf->Databuf[datBuf->Length].Command = GetMMIO_DWORD(mmiobase, 0x0c); datBuf->Databuf[datBuf->Length].Address = GetMMIO_DWORD(mmiobase, 0x0d); datBuf->Databuf[datBuf->Length].Address_ = GetMMIO_DWORD(mmiobase, 0x55); } } void sisir_isrfun(UINT8* mmiobase, UINT8* mmiobase2, IR_IOC_IOData* dataBuf) { #if 0 UINT32 SecondSingle = 0; #endif #if 0//defined(IR_PROTOCOL_TOSHIBA) || defined(IR_PROTOCOL_TOSHIBA2) // TOSHIBA protocol only volatile UINT32 IR_Data, IR_Custom, IR_bit_len, tmp_data, tmp_Custom, i; #endif datBuf = dataBuf; if(mmiobase == NULL) { DBG_MSG1(DBGCFG_IR, "\n\n\n ERR IR Receive an Int Status without Init\n\n\n"); return; } if(mmiobase2 == NULL) { DBG_MSG1(DBGCFG_IR, "\n\n\n ERR IR2 Receive an Int Status without Init\n\n\n"); return; } irdatas.Value= GetMMIO_DWORD(mmiobase, 0x0c); //read from IR decoder recevied data irdatas2.Value= GetMMIO_DWORD(mmiobase2, 0x0c); //read from IR decoder recevied data //#if defined(IR_PROTOCOL_TOSHIBA) // TOSHIBA protocol only if(IRProtocolNum == Toshiba && irdatas.Reg.reg_intr_sts)// || IRProtocolNum2 == Toshiba) { sisir_toshiba_ParseData(mmiobase, dataBuf); SetMMIO_DWORD(mmiobase, 0x0c, irdatas.Value); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) return; } else if(IRProtocolNum2 == Toshiba && irdatas2.Reg.reg_intr_sts) { sisir_toshiba_ParseData(mmiobase2, dataBuf); SetMMIO_DWORD(mmiobase2, 0x0c, irdatas2.Value); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) return; } else if(IRProtocolNum == TC9012 && irdatas.Reg.reg_intr_sts)// || IRProtocolNum2 == Toshiba) { sisir_TC9012_ParseData(mmiobase, dataBuf); SetMMIO_DWORD(mmiobase, 0x0c, irdatas.Value); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) return; } else if(IRProtocolNum2 == TC9012 && irdatas2.Reg.reg_intr_sts) { sisir_TC9012_ParseData(mmiobase2, dataBuf); SetMMIO_DWORD(mmiobase2, 0x0c, irdatas2.Value); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) return; } else { if(irdatas.Reg.reg_intr_sts == 0 && irdatas2.Reg.reg_intr_sts == 0) { DBG_MSG1(DBGCFG_IR, "\n\n\n ERR IR triggered an Int without reg_intr_sts\n\n\n"); } else { DBG_MSG1(DBGCFG_IR, "\nsisir_isrfun ==>\n"); // ir 1 if(irdatas.Reg.reg_intr_sts) { DBG_MSG1(DBGCFG_IR, "\n ir 1 datas ==>\n"); if(dataBuf->Length >= (30 - 2)) { DBG_MSG1(DBGCFG_IR, "\n\n\n IR data buffer full\n\n\n"); dataBuf->Length = 0; } if(irdatas.Reg.reg_rpt_start_sts) { DBG_MSG1(DBGCFG_IR, " reg_rpt_start_sts received\n"); rpt_cnt = 0; first_rpt = 0; dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START; dataBuf->Length++; } if(irdatas.Reg.reg_rpt_end_sts) { DBG_MSG1(DBGCFG_IR, " reg_rpt_end received\n"); if ( first_rpt == 1 ) { DBG_MSG1(DBGCFG_IR, " reg_single_end received\n"); dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = SINGLE_KEY_END; // single end dataBuf->Length++; } else { DBG_MSG1(DBGCFG_IR, " reg_rpt_end_sts received\n"); dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START_END; dataBuf->Length++; } } if(irdatas.Reg.reg_single_sts) { if ( ir_timer_flag ) { del_timer(&IR_ContiTimer); ir_timer_flag = 0; } if ( singleKey == 1 ) { DBG_MSG1(DBGCFG_IR, " 2nd \tCMD:%x\n", tmp_irCmd); datBuf->Databuf[datBuf->Length].Command = tmp_irCmd; datBuf->Databuf[datBuf->Length].Address = tmp_irAddress; datBuf->Databuf[datBuf->Length].Address_ = tmp_irAddress_; datBuf->Databuf[datBuf->Length].ContinueKey = SINGLE_KEY_END; // single end datBuf->Length++; } sisir_ParseData(IRProtocolNum, mmiobase); #if defined(IR_PROTOCOL_SHARP)|| defined(IR_PROTOCOL_SHARP2) if ( tmp_irCmd == dataBuf->Databuf[dataBuf->Length].Command ) { if ( first_rpt ) { rpt_cnt = rpt_cnt + 1; } if ( rpt_cnt > 10 ) { singleKey = 0; first_rpt = 0; rpt_cnt = 0; dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START; dataBuf->Length++; DBG_MSG1(DBGCFG_IR, " reg_rpt_sts received %d\n", rpt_cnt); } } else { tmp_irCmd = datBuf->Databuf[datBuf->Length].Command; tmp_irAddress = datBuf->Databuf[datBuf->Length].Address; tmp_irAddress_ = datBuf->Databuf[datBuf->Length].Address_; DBG_MSG1(DBGCFG_IR, "Single int\nAddr Addr_: %x,%x\nCMD: %x\n", tmp_irAddress, tmp_irAddress_, tmp_irCmd); dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_HEAD; dataBuf->Length++; rpt_cnt = 0; first_rpt = 1; singleKey = 1; } init_IR_cont_timer(150); // 150 ms ir_timer_flag = 1; DBG_MSG1(DBGCFG_IR, "IR Receive : 0x%08x\tIR reg54:0x%08x\n<==\n", (UINT32)irdatas.Value, (UINT32)*(ULONG *)(0xbe080054)); SetMMIO_DWORD(mmiobase, 0x0c, (*(unsigned int *)(0xbe08000c))); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) return; #else tmp_irCmd = datBuf->Databuf[datBuf->Length].Command; tmp_irAddress = datBuf->Databuf[datBuf->Length].Address; tmp_irAddress_ = datBuf->Databuf[datBuf->Length].Address_; DBG_MSG1(DBGCFG_IR, "Single int\nAddr Addr_: %x,%x\nCMD: %x\n", tmp_irAddress, tmp_irAddress_, tmp_irCmd); dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_HEAD; dataBuf->Databuf[dataBuf->Length].Protocol = IRProtocolNum; dataBuf->Length++; rpt_cnt = 0; first_rpt = 1; singleKey = 1; #endif } DBG_MSG1(DBGCFG_IR, "IR Receive : 0x%08x\tIR reg54:0x%08x\n<==\n", (unsigned int)(irdatas.Value), (unsigned int)(*(ULONG *)(0xbe080054))); DBG_MSG1(DBGCFG_IR, "\n ir 1 datas <==\n"); } // ir 2 else if(irdatas2.Reg.reg_intr_sts) { DBG_MSG1(DBGCFG_IR, "\n ir 2 datas ==>\n"); if(dataBuf->Length >= (30 - 2)) { DBG_MSG1(DBGCFG_IR, "\n\n\n IR2 data buffer full\n\n\n"); dataBuf->Length = 0; } if(irdatas2.Reg.reg_rpt_start_sts) { DBG_MSG1(DBGCFG_IR, "22 reg_rpt_start_sts received\n"); rpt_cnt = 0; first_rpt = 0; dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START; dataBuf->Length++; } if(irdatas2.Reg.reg_rpt_end_sts) { DBG_MSG1(DBGCFG_IR, "222 reg_rpt_end received\n"); if ( first_rpt == 1 ) { DBG_MSG1(DBGCFG_IR, "222 reg_single_end received\n"); dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = SINGLE_KEY_END; // single end dataBuf->Length++; } else { DBG_MSG1(DBGCFG_IR, "222 reg_rpt_end_sts received\n"); dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START_END; dataBuf->Length++; } } if(irdatas2.Reg.reg_single_sts) { if ( ir_timer_flag ) { del_timer(&IR_ContiTimer); ir_timer_flag = 0; } if ( singleKey == 1 ) { DBG_MSG1(DBGCFG_IR, "222 2nd \tCMD:%x\n", tmp_irCmd); datBuf->Databuf[datBuf->Length].Command = tmp_irCmd; datBuf->Databuf[datBuf->Length].Address = tmp_irAddress; datBuf->Databuf[datBuf->Length].Address_ = tmp_irAddress_; datBuf->Databuf[datBuf->Length].ContinueKey = SINGLE_KEY_END; // single end datBuf->Length++; } sisir_ParseData(IRProtocolNum2, mmiobase2); #if defined(IR_PROTOCOL_SHARP)|| defined(IR_PROTOCOL_SHARP2) if ( tmp_irCmd == dataBuf->Databuf[dataBuf->Length].Command ) { if ( first_rpt ) { rpt_cnt = rpt_cnt + 1; } if ( rpt_cnt > 10 ) { singleKey = 0; first_rpt = 0; rpt_cnt = 0; dataBuf->Databuf[dataBuf->Length].Command = tmp_irCmd; dataBuf->Databuf[dataBuf->Length].Address = tmp_irAddress; dataBuf->Databuf[dataBuf->Length].Address_= tmp_irAddress_; dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_START; dataBuf->Length++; DBG_MSG1(DBGCFG_IR, "222 reg_rpt_sts received %d\n", rpt_cnt); } } else { tmp_irCmd = datBuf->Databuf[datBuf->Length].Command; tmp_irAddress = datBuf->Databuf[datBuf->Length].Address; tmp_irAddress_ = datBuf->Databuf[datBuf->Length].Address_; DBG_MSG1(DBGCFG_IR, "222Single int\nAddr Addr_: %x,%x\nCMD: %x ,CMDCMD: %x\n", tmp_irAddress, tmp_irAddress_, tmp_irCmd, datBuf->Databuf[datBuf->Length].Command); dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_HEAD; dataBuf->Length++; rpt_cnt = 0; first_rpt = 1; singleKey = 1; } init_IR_cont_timer(150); // 150 ms ir_timer_flag = 1; DBG_MSG1(DBGCFG_IR, "222IR Receive : 0x%08x\tIR reg54:0x%08x\n<==\n", (UINT32)irdatas2.Value, (UINT32)*(ULONG *)(0xbe080554)); SetMMIO_DWORD(mmiobase2, 0x0c, (*(unsigned int *)(0xbe08050c))); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) return; #else tmp_irCmd = datBuf->Databuf[datBuf->Length].Command; tmp_irAddress = datBuf->Databuf[datBuf->Length].Address; tmp_irAddress_ = datBuf->Databuf[datBuf->Length].Address_; DBG_MSG1(DBGCFG_IR, "222Single int\nAddr Addr_: %x,%x\nCMD: %x\n", tmp_irAddress, tmp_irAddress_, tmp_irCmd); dataBuf->Databuf[dataBuf->Length].ContinueKey = CONTINUE_KEY_HEAD; dataBuf->Databuf[dataBuf->Length].Protocol = IRProtocolNum2; dataBuf->Length++; rpt_cnt = 0; first_rpt = 1; singleKey = 1; #endif } DBG_MSG1(DBGCFG_IR, "222IR Receive : 0x%08x\tIR reg54:0x%08x\n<==\n", (unsigned int)(irdatas2.Value), (unsigned int)(*(ULONG *)(0xbe080554))); DBG_MSG1(DBGCFG_IR, "\n ir 2 datas <==\n"); } } // 20100407 Magic modify for single end if ( (dataBuf->Length > 0) && ( dataBuf->Databuf[dataBuf->Length-1].ContinueKey == CONTINUE_KEY_HEAD ) && (rpt_cnt==0) && irdatas.Reg.reg_intr_sts) { if(IRProtocolNum == NEC_SAMSUNG || IRProtocolNum2 == NEC_SAMSUNG) init_IR_cont_timer(350); // 350 ms else init_IR_cont_timer(285); // 285 ms ir_timer_flag = 1; } else { singleKey = 0; if ( ir_timer_flag ) { del_timer(&IR_ContiTimer); } } SetMMIO_DWORD(mmiobase, 0x0c, irdatas.Value); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) SetMMIO_DWORD(mmiobase2, 0x0c, irdatas2.Value); // Clear reg_intr_sts (reg_intr_sts is Write-1-Clear) return; } } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8)) long sisir_ioctl(struct file *file, unsigned int cmd, ULONG arg) #else int sisir_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ULONG arg) #endif { IRDEVPTR pir = (IRDEVPTR)(file->private_data); switch(cmd) { case IR_IOC_Get_Data: //DBG_MSG1(DBGCFG_IR, "sisir_ioctl IR_IOC_Get_Data\n"); //spin_lock_irqsave(&IR_lock, IR_irq_flag); disable_irq(IRQ_IR); if (copy_to_user((void *)arg, &pir->dataBuf, sizeof(IR_IOC_IOData))) { //spin_unlock_irqrestore(&IR_lock, IR_irq_flag); enable_irq(IRQ_IR); return -EFAULT; } pir->dataBuf.Length=0; //spin_unlock_irqrestore(&IR_lock, IR_irq_flag); enable_irq(IRQ_IR); break; #if 0 case IR_IOC_Get_Protocol: if (copy_to_user((void *)arg, &IRProtocolNum, sizeof(IR_CODING))) { return -EFAULT; } break; #endif #ifdef UI case IR_IOC_Set_Protocol: if (copy_from_user( &IRProtocolNum, (void *)arg,sizeof(IR_CODING))) { return -EFAULT; } //sisir_initfun(IRProtocolNum); break; #endif #ifdef CONFIG_AUTO_USB_STORE_IRSEQ case IR_IOC_Set_Data: { PMessage pMessage = &pir->userMessage; IR_IOC_IOData* tbuf; //DBG_MSG1(DBGCFG_IR, "sisir_ioctl IR_IOC_Set_Data\n"); if (copy_from_user(pMessage, (void *)arg, sizeof(Message))) { DBG_MSG1(DBGCFG_IR, "IR_IOC_Set_Data copy failed\n"); return -EFAULT; } tbuf = &pIRDev->dataBuf; if(tbuf->Length>=30) { DBG_MSG1(DBGCFG_IR, "data buffer full\n"); tbuf->Length=0; } memcpy(&tbuf->Databuf[tbuf->Length],pMessage,sizeof(Message)); tbuf->Length++; if (pMessage->ContinueKey == CONTINUE_KEY_HEAD) { DBG_MSG1(DBGCFG_IR, "1. This is CONTINUE_KEY_HEAD.\nAddr = 0x%02x, Cmd = 0x%02x\n", pMessage->Address,pMessage->Command); } else if (pMessage->ContinueKey == CONTINUE_KEY_START_END) { DBG_MSG1(DBGCFG_IR, "2. This is CONTINUE_KEY_START_END.\nAddr = 0x%02x, Cmd = 0x%02x\n", pMessage->Address,pMessage->Command); } else if (pMessage->ContinueKey == CONTINUE_KEY_START) { DBG_MSG1(DBGCFG_IR, "3. This is CONTINUE_KEY_START.\nAddr = 0x%02x, Cmd = 0x%02x\n", pMessage->Address,pMessage->Command); } else if (pMessage->ContinueKey == CONTINUE_KEY_END) { DBG_MSG1(DBGCFG_IR, "4. This is CONTINUE_KEY_END.\nAddr = 0x%02x, Cmd = 0x%02x\n", pMessage->Address,pMessage->Command); } memset(pMessage,0,sizeof(Message)); break; } case IR_IOC_EnableIR: IRHardwareEnableFun(); break; case IR_IOC_DisableIR: IRHardwareDisableFun(); break; #endif #if 0 case IR_IOC_Get_AndroidData: //wait_event_interruptible(wq, dataBuf.Length!=0); //no data in buff //spin_lock_irqsave(&IR_lock, IR_irq_flag); disable_irq(IRQ_IR); if (copy_to_user((void *)arg, &AndroidDataBuf, sizeof(IR_IOC_IOData))) { //spin_unlock_irqrestore(&IR_lock, IR_irq_flag); enable_irq(IRQ_IR); return -EFAULT; } AndroidDataBuf.Length=0; //spin_unlock_irqrestore(&IR_lock, IR_irq_flag); enable_irq(IRQ_IR); break; case IR_IOC_ClsAndroid: break; #endif } return 0; } #ifdef CONFIG_AUTO_USB_STORE_IRSEQ void IRHardwareEnableFun(void) { UINT8 *mmiobase = (UINT8*)MMIOBASE_IR; //ULONG W_Data = 0; DBG_MSG1(DBGCFG_IR, "IRHwEn\n"); SetMMIO_DWORD_MASK(mmiobase, 0x4, IR_protocol_selection_value, 0xFF); /*Enable IR global interrupt */ SetMMIO_DWORD(mmiobase, 0x8, (( GetMMIO_DWORD(mmiobase, 0x08) )|0x00010000)); } void IRHardwareDisableFun(void) { UINT8 *mmiobase = (UINT8*)MMIOBASE_IR; //ULONG W_Data = 0; DBG_MSG1(DBGCFG_IR, "IRHwDisable\n"); IR_protocol_selection_value = GetMMIO_DWORD(mmiobase, 0x04); SetMMIO_DWORD_MASK(mmiobase, 0x4, 0x0, 0xFF); /*disable IR global interrupt */ SetMMIO_DWORD(mmiobase, 0x8, (( GetMMIO_DWORD(mmiobase, 0x08) )&0xFFFEFFFF)); } #endif int sisir_open(struct inode *inode, struct file *file) { unsigned int minor = MINOR(inode->i_rdev); //DBG_MSG1(DBGCFG_IR, "sisir_open ==>"); if(minor>=SISIR_DEV_NUM) { DBG_MSG1(DBGCFG_IR, "sisir_open <== 0"); return -ENODEV; } file->private_data = pIRDev; //DBG_MSG1(DBGCFG_IR, "sisir_open <=="); return 0; } static struct file_operations sisir_fops= { owner: THIS_MODULE, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8)) .unlocked_ioctl = sisir_ioctl, #else ioctl: sisir_ioctl, #endif // mmap: sisir_mmap, open: sisir_open, // release: sisir_release, }; #if defined(CONFIG_SUPPORT_IR_INI) || defined(CONFIG_SUPPORT_LOAD_KERNEL_FROM_USB) || defined(CONFIG_SUPPORT_IR_FAC_REMOTE) #define OP_IR_Protocol_reg 0x88930324 /* 0xbe080004 */ #define OP_IR_Interrupt_en_reg 0x000f0000 /* 0xbe080008 */ #define OP_IR_Interrupt_staus 0x00000000 /* 0xbe08000c */ #define OP_IR_MinSpaceBetweenPacket 0x01b001b0 /* 0xbe080010 */ #define OP_IR_Max_Min_Symbol 0x01250046 /* 0xbe080014 */ #define OP_IR_Max_Min_Short_Mark 0x00490023 /* 0xbe080018 */ #define OP_IR_Max_Min_Short_Space 0x00490023 /* 0xbe08001c */ #define OP_IR_Max_Min_Long_Mark 0x00dd006a /* 0xbe080020 */ #define OP_IR_Max_Min_Head_Mark 0x04900232 /* 0xbe080024 */ #define OP_IR_Max_Min_Head_Space 0x02490119 /* 0xbe080028 */ #define OP_IR_REG_2C 0x00000000 /* 0xbe08002c */ #define OP_IR_Max_Min_Repeat_Space 0x0125008d /* 0xbe080030 */ #define OP_IR_Extra_Decode_Option 0x00000002 /* 0xbe080034 */ #define OP_IR_REG_38 0x00000000 /* 0xbe080038 */ #define OP_IR_WatchDog_Timeout 0x00000000 /* 0xbe08003c (unused now) */ #define OP_IR_Repeat_Threshold 0x00020102 /* 0xbe080040 */ #define OP_IR_Packet_Timeout_Threshold 0x16022d60 /* 0xbe080044 */ #define OP_IR_Key_Press_Counter 0x00000000 /* 0xbe080048 */ #define OP_IR_Protocol_Type_Option 0x00b02009 /* 0xbe08004c */ #define OP_IR_Internal_Counter 0x00000000 /* 0xbe080050 */ #define OP_IR_Bit47_to_Bit16 0x00000000 /* 0xbe080054 */ #define OP_IR_Receiver_Signal 0x00000000 /* 0xbe080058 */ #define OP_IR_Power_Code_Option 0x00000003 /* 0xbe08005c */ #define OP_IR_Power_Code_A_Low_Channel 0x906fa25d /* 0xbe080060 */ #define OP_IR_Power_Code_A_High_Channel 0x00000000 /* 0xbe080064 */ #define OP_IR_Power_Code_B_Low_Channel 0x00000000 /* 0xbe080068 */ #define OP_IR_Power_Code_B_High_Channel 0x00000000 /* 0xbe08006c */ #define OP_IR_Power_Code_C_Low_Channel 0x00000000 /* 0xbe080070 */ #define OP_IR_Power_Code_C_High_Channel 0x00000000 /* 0xbe080074 */ #define OP_IR_Power_Code_D_Low_Channel 0x00000000 /* 0xbe080078 */ #define OP_IR_Power_Code_D_High_Channel 0x00000000 /* 0xbe08007c */ #define OP_IR_Max_Min_Long1_MarkSpace 0x00000000 /* 0xbe080080 */ #define OP_IR_Max_Min_Long2_MarkSpace 0x00000000 /* 0xbe080084 */ UINT32 irNecTable[33] = { \ OP_IR_Protocol_reg, \ OP_IR_Interrupt_en_reg, \ OP_IR_Interrupt_staus, \ OP_IR_MinSpaceBetweenPacket, \ OP_IR_Max_Min_Symbol, \ OP_IR_Max_Min_Short_Mark, \ OP_IR_Max_Min_Short_Space, \ OP_IR_Max_Min_Long_Mark, \ OP_IR_Max_Min_Head_Mark, \ OP_IR_Max_Min_Head_Space, \ OP_IR_REG_2C, \ OP_IR_Max_Min_Repeat_Space, \ OP_IR_Extra_Decode_Option, \ OP_IR_REG_38, \ OP_IR_WatchDog_Timeout, \ OP_IR_Repeat_Threshold, \ OP_IR_Packet_Timeout_Threshold, \ OP_IR_Key_Press_Counter, \ OP_IR_Protocol_Type_Option, \ OP_IR_Internal_Counter, \ OP_IR_Bit47_to_Bit16, \ OP_IR_Receiver_Signal, \ OP_IR_Power_Code_Option, \ OP_IR_Power_Code_A_Low_Channel, \ OP_IR_Power_Code_A_High_Channel, \ OP_IR_Power_Code_B_Low_Channel, \ OP_IR_Power_Code_B_High_Channel, \ OP_IR_Power_Code_C_Low_Channel, \ OP_IR_Power_Code_C_High_Channel, \ OP_IR_Power_Code_D_Low_Channel, \ OP_IR_Power_Code_D_High_Channel, \ OP_IR_Max_Min_Long1_MarkSpace, \ OP_IR_Max_Min_Long2_MarkSpace, \ }; #endif void sisir_initfun( void ) { ULONG i; #if defined(CONFIG_SUPPORT_IR_INI) || defined(CONFIG_SUPPORT_LOAD_KERNEL_FROM_USB) || defined (CONFIG_SUPPORT_IR_FAC_REMOTE) UINT8 bootType = 0; #endif CUSTIMIZATION_TABLEPTR pCustTAB = (volatile CUSTIMIZATION_TABLEPTR)SPI_OPTIONDATA_SHADOWADDR; *(volatile ULONG *)(0xbe080008) &= ~(1<<16); //reset IR *(volatile ULONG *)(0xbe080508) &= ~(1<<16); //reset IR 2 udelay(10); //DBG_MSG1(DBGCFG_IR, "sisir_init ==>"); //if(pCustTAB->IRCommandType > 7) pCustTAB->IRCommandType = 1; //default setting = Nec #ifdef CONFIG_SUPPORT_IR_INI bootType = *(UINT8*)(0xbe000088+0x3)>>4; if(bootType == BootType_AC_SPECIAL_FILE) { IRProtocolNum= Nec; // fill the initial settings but disable the IR first (to clear its status) SetMMIO_DWORD(pIRDev->mmio_vbase, 0x04, (irNecTable[0] & ~(0x1f))); // disable the protocol (receiving) enable bit first, and SetMMIO_DWORD(pIRDev->mmio_vbase, 0x08, (irNecTable[1] & ~(0x1f << 16))); // then disable the interrupt enable bit for ( i=0;i<33;i++ ) { SetMMIO_DWORD(pIRDev->mmio_vbase, (i+1)*4, irNecTable[i]); //DBG_MSG1(DBGCFG_IR, "AC reg add=%x===%d=\n",irNecTable[i], __LINE__); } IR_protocol_selection_value = irNecTable[0]; //default protocol vaule for IRHardwareEnableFun } else #endif { #if defined (CONFIG_SUPPORT_LOAD_KERNEL_FROM_USB) bootType = (*(UINT8*)(0xbe0f0523) & 0x40) >>6; //0xbe0f0523[6] #elif defined (CONFIG_SUPPORT_IR_FAC_REMOTE) bootType = (*(UINT8*)(0xbe0f0523) & 0x80) >>7; //0xbe0f0523[7] #endif #if defined(CONFIG_SUPPORT_LOAD_KERNEL_FROM_USB) || defined(CONFIG_SUPPORT_IR_FAC_REMOTE) //printk("bootType = %d, reg0xbe0f0523:%lx \n\n",bootType, *(volatile ULONG *)(0xbe0f0523)); if(bootType == true) { IRProtocolNum= Nec; // fill the initial settings but disable the IR first (to clear its status) SetMMIO_DWORD(pIRDev->mmio_vbase, 0x04, (irNecTable[0] & ~(0x1f))); // disable the protocol (receiving) enable bit first, and SetMMIO_DWORD(pIRDev->mmio_vbase, 0x08, (irNecTable[1] & ~(0x1f << 16))); // then disable the interrupt enable bit for ( i=0;i<33;i++ ) { SetMMIO_DWORD(pIRDev->mmio_vbase, (i+1)*4, irNecTable[i]); //DBG_MSG1(DBGCFG_IR, "AC reg add=%x===%d=\n",irNecTable[i], __LINE__); } IR_protocol_selection_value = irNecTable[0]; //default protocol vaule for IRHardwareEnableFun } else #endif { IRProtocolNum =pCustTAB->IRCommandType; //ir_parameter.code; // fill the initial settings but disable the IR first (to clear its status) SetMMIO_DWORD(pIRDev->mmio_vbase, 0x04, (pCustTAB->pIR_Set[0] & ~(0x1f))); // disable the protocol (receiving) enable bit first, and SetMMIO_DWORD(pIRDev->mmio_vbase, 0x08, (pCustTAB->pIR_Set[1] & ~(0x1f << 16))); // then disable the interrupt enable bit for ( i=0;i<33;i++ ) { SetMMIO_DWORD(pIRDev->mmio_vbase, (i+1)*4, pCustTAB->pIR_Set[i]); //DBG_MSG1(DBGCFG_IR, "reg add=%x===%d=\n",pCustTAB->pIR_Set[i], __LINE__); } IR_protocol_selection_value = pCustTAB->pIR_Set[0]; //default protocol vaule for IRHardwareEnableFun IRProtocolNum2= pCustTAB->IR2CommandType; // fill the initial settings but disable the IR first (to clear its status) SetMMIO_DWORD(pIRDev->mmio_vbase2, 0x04, (pCustTAB->pIR2_Set[0] & ~(0x1f))); // disable the protocol (receiving) enable bit first, and SetMMIO_DWORD(pIRDev->mmio_vbase2, 0x08, (pCustTAB->pIR2_Set[1] & ~(0x1f << 16))); // then disable the interrupt enable bit for ( i=0;i<33;i++ ) { SetMMIO_DWORD(pIRDev->mmio_vbase2, (i+1)*4, pCustTAB->pIR2_Set[i]); //DBG_MSG1(DBGCFG_IR, "AC reg add=%x===%d=\n",irNecTable[i], __LINE__); } //IR_protocol_selection_value = irNecTable[0]; //default protocol vaule for IRHardwareEnableFun //printk("IRProtocolNum=%d, IRProtocolNum2=%d-----------\n\n",IRProtocolNum, IRProtocolNum2); } } #if IR_Auto_Test memset(&pIRDev->userMessage,0,sizeof(Message)); #endif //DBG_MSG1(DBGCFG_IR, "sisir_init code %d<== ",IRProtocolNum); } static irqreturn_t IR_ISR(int irq, void* dev_id, struct pt_regs *regs) { sisir_isrfun(pIRDev->mmio_vbase, pIRDev->mmio_vbase2, &pIRDev->dataBuf); return IRQ_HANDLED; } static void mips_ir_dispatch(struct pt_regs *regs) { do_IRQ(IRQ_IR); } static struct irqaction ir_irqaction = { .handler = (irq_handler_t)&IR_ISR, .flags = IRQF_DISABLED, .name = "ir", }; #ifndef INIT_BY_KMF static int __init IRInit(void) #else int IRInit(void) #endif { int err,devno; #if 1 pIRDev = (IRDEVPTR)kmalloc(sizeof(IRDEV), GFP_KERNEL); #else pIRDev = (IRDEVPTR)drv_kmalloc(sizeof(IRDEV), GFP_KERNEL, MODULEID_IR); #endif memset(pIRDev, 0, sizeof(IRDEV)); //DBG_MSG1(DBGCFG_IR, "[IR] ========>IRInit"); pIRDev->mmio_vbase = (UINT8*)MMIOBASE_IR; pIRDev->mmio_vbase2 = (UINT8*)MMIOBASE_IR2; pIRDev->irq = IRQ_IR; // init variable rpt_cnt = 0; first_rpt = 1; singleKey = 0; tmp_irCmd = 0xff; tmp_irAddress = 0; tmp_irAddress_= 0; ir_timer_flag = 0; // set_vi_handler(IRQ_IR, (vi_handler_t)mips_ir_dispatch); setup_irq(IRQ_IR, &ir_irqaction); ////////////////////////////////////////////// devno = MKDEV(SISIR_DEV_MAJOR, 0); cdev_init(&pIRDev->cdev, &sisir_fops); pIRDev->cdev.owner = THIS_MODULE; err = cdev_add(&pIRDev->cdev, devno, 1); if(err) { DBG_MSG1(DBGCFG_IR, "IRInit Failed\n"); return -EIO; } pIRDev->dataBuf.Length = 0; #if IR_Auto_Test IR_protocol_selection_value = GetMMIO_DWORD((UINT8*)MMIOBASE_IR, 0x04); #endif // To init spin lock spin_lock_init(&IR_lock); sisir_initfun(); #ifdef CONFIG_DVD_COMBO { #define c0count_per_msec_reg 0xbe000040 #if (CONFIG_CHIPID != 0x533) #if (CONFIG_CHIPID == 0x131) int PREPLL = ((*(UINT8 *)0xbe000107 +1)*24000) ; int CPUPLL = PREPLL / ((*(UINT8 *)0xbe000108 & 0x7f) + 1); if ((*(unsigned char *)0xbe000105)&0x10) CPUPLL = CPUPLL/2; if ((*(unsigned char *)0xbe0001bd)&0x04) CPUPLL = CPUPLL/2; #elif (CONFIG_CHIPID == 0x8506) || (CONFIG_CHIPID == 0x6710) int CPUPLL = drv_get_device_clock(CPUACLK)/1000; #else int MEMPLL = ((*(UINT8 *)0xbe0001a4 +1)*24576) / ((*(UINT8 *)0xbe0001a5 & 0x1f)+1); int CPUPLL = MEMPLL / ((*(UINT8 *)0xbe000108 & 0x7f) + 1); #endif #else int cpu_pll = ((*(UINT8 *)0xbe0001b8 +1)*24576) / ((*(UINT8 *)0xbe0001b9 & 0x01)+1); int CPUPLL = cpu_pll / ((*(UINT8 *)0xbe000108 & 0x7f) + 1); #endif *(volatile ULONG *)c0count_per_msec_reg = CPUPLL/2; //c0count_per_msec_reg *(volatile ULONG *)(0xbe010104) |= 0x00080000; // enable software interrupt 51 } #endif //DBG_MSG1(DBGCFG_IR, "[IR] IRInit <======== \n"); return 0; } #ifndef INIT_BY_KMF module_init (IRInit); module_exit (IRExit); #endif MODULE_LICENSE("Dual BSD/GPL");