/* * drivers/input/keyboard/epaper.c * AUO epaper Interface on S3C2416 in Qisda eBook * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */ #include "epaper.h" #ifdef EPAPER_BOOT_CODE #include #include #include #else //KERNEL #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif #define S3C_EPAPER_QISDA_DEBUG #ifdef S3C_EPAPER_QISDA_DEBUG #ifdef EPAPER_BOOT_CODE #define DPRINTK(x...) //Be careful of code size if printf too much #else //KERNEL #define DPRINTK(x...) printk("S3C-Epaper-qisda " x) #endif #else #define DPRINTK(x...) /* !!!! */ #endif #ifdef EPAPER_BOOT_CODE #define rGPCCON GPCCON #define rGPCDAT GPCDAT #define rGPDCON GPDCON #define rGPDDAT GPDDAT #define rGPCUDP GPCPU #define rGPDUDP GPDPU #define rGPLDAT GPLDAT #define rGPLCON GPLCON #define rGPLUDP GPLPU #define rGPBCON GPBCON #define rGPBDAT GPBDAT #define rGPGCON GPGCON #define rGPGDAT GPGDAT #define rGPECON GPECON #define rGPEDAT GPEDAT #define rGPFCON GPFCON #define rGPFDAT GPFDAT #define rVIDCON0 VIDCON0 //VIDEO CONTROL REGTISTER 0 #define rSYSIFCON0 SYSIFCON0 //SYSTEM INTERFACE MAIN LDI #define rSYSIFCON1 SYSIFCON1 //SYSTEM INTERFACE SUB LDI #define rSIFCCON0 SIFCCON0 //SYSTEM INTERFACE COMMAND CONTROL #define rSIFCCON1 SIFCCON1 //SYSTEM IF COMMAND DATA WRITE CONTROL #define rSIFCCON2 SIFCCON2 #else //KERNEL #define rGPCCON S3C2410_GPCCON #define rGPCDAT S3C2410_GPCDAT #define rGPDCON S3C2410_GPDCON #define rGPDDAT S3C2410_GPDDAT #define rGPCUDP S3C2410_GPCUP #define rGPDUDP S3C2410_GPDUP #define rGPLDAT S3C2410_GPLDAT #define rGPLCON S3C2410_GPLCON #define rGPLUDP S3C2410_GPLUP #define rGPBCON S3C2410_GPBCON #define rGPBDAT S3C2410_GPBDAT #define rGPBUDP S3C2410_GPBUP #define rGPGCON S3C2410_GPGCON #define rGPGDAT S3C2410_GPGDAT #define rGPECON S3C2410_GPECON #define rGPEDAT S3C2410_GPEDAT #define rGPFCON S3C2410_GPFCON #define rGPFDAT S3C2410_GPFDAT #define rTCFG0 S3C2410_TCFG0 //Configures the two 8-bit presclers #define rTCFG1 S3C2410_TCFG1 //5-MUX & DMA mode selecton #define rTCNTB3 S3C2410_TCNTB(3) //Timer 3 count buffer #define rTCMPB3 S3C2410_TCMPB(3) //Timer 3 compare buffer #define rTCON S3C2410_TCON //Timer control #define rVIDCON0 S3C_VIDCON0 //VIDEO CONTROL REGTISTER 0 #define rSYSIFCON0 S3C_SYSIFCON0 //SYSTEM INTERFACE MAIN LDI #define rSYSIFCON1 S3C_SYSIFCON1 //SYSTEM INTERFACE SUB LDI #define rSIFCCON0 S3C_SIFCCON0 //SYSTEM INTERFACE COMMAND CONTROL #define rSIFCCON1 S3C_SIFCCON1 //SYSTEM IF COMMAND DATA WRITE CONTROL #define rSIFCCON2 S3C_SIFCCON2 #endif #define VIDCON0_S_CPU_IF_MAIN (2<<22) #define VIDCON0_S_RGB_PAR (0<<13) #define VIDCON0_S_VCLK_GATING_OFF (1<<5) #define VIDCON0_S_CLKDIR_DIVIDED (1<<4) #define VIDCON0_S_CLKSEL_HCLK (0<<2) #define VIDCON0_CLKVAL_F_SHIFT (6) #define VIDCON0_ENVID_ENABLE (1<<1) #define VIDCON0_ENVID_F_ENABLE (1<<0) #define SYS_WR_CON (1<<6) #define SYS_OE_CON (1<<7) #define rWTCON S3C2410_WTCON //Watch-dog timer mode #define rWTDAT S3C2410_WTDAT //Watch-dog timer data #define rWTCNT S3C2410_WTCNT //Watch-dog timer count #define LCD_DELAY_1MS 18000 #define BUSY_WAIT_TIMEOUT (40*5) //panel time out = 1s //#ifdef EPAPER_BOOT_CODE /* Bookeen's Position */ #define PROGRESS_BAR_X (32) #define PROGRESS_BAR_Y (767) #define PROGRESS_BAR_W (567 - 32) #define PROGRESS_BAR_H (784 - 767) #define PROGRESS_BAR_FRAME_LINE_W 8 //#endif //Global var /* BAN 20090408 update for WE freq*/ static int delayLoopCount = 150;//2M /* BAN 20090408 update for WE freq*/ //Ivan start static int partial_update_mode = PARTIAL_DSP_MODE_0; static int h_resolution = 800; static int v_resolution = 600; static int gRotateDegree = 0; //Ivan end #ifdef EPAPER_BOOT_CODE //extern unsigned short Loading_Data[]; #else extern unsigned short shutdown[]; EXPORT_SYMBOL(Epaper_Shutdown_Logo); EXPORT_SYMBOL(Epaper_Get_Partial_Update_Mode); EXPORT_SYMBOL(Epaper_Power); EXPORT_SYMBOL(Epaper_Draw_Point); #endif /* 1. loops = 1 --> 25ns 2. loops = 75 --> 1 us 3. loops = 100000 --> 1ms */ static inline void nDelay(unsigned long loops) //in ns { __asm__ volatile ("1:\n" "subs %0, %1, #1\n" "bne 1b":"=r" (loops):"0"(loops)); } static void __mDelay(unsigned long mTime) { unsigned long cnt=0; for(cnt=0;cntpanel is BUSY\n"); return 0; } #elif defined(CONFIG_QISDA_E600_EVT2) || defined(CONFIG_QISDA_E600_DVT1) tmp = __raw_readl(rGPLDAT); if((tmp & (1<<13))==0) { DPRINTK("<= BAN =>panel is BUSY\n"); return 0; } #elif defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1) || defined(CONFIG_QISDA_QD060N00_DVT1_1) || defined(CONFIG_QISDA_QD090B00_EVT1) tmp = __raw_readl(rGPBDAT); if((tmp & (1<<2))==0) { DPRINTK("<= BAN =>panel is BUSY\n"); return 0; } #endif return 1; } int is_Epaper_Write_Ready(void) { unsigned long tmp; int iBusyCnt=0; int i=0; #if defined(CONFIG_QISDA_E600_EVT0) tmp = __raw_readl(rGPGDAT); while((tmp & (1<<5))==0) { DPRINTK("<= BAN =>panel is BUSY\n"); //msleep(100); for(i=0; i<20; i++) __mDelay(1); iBusyCnt ++; if(iBusyCnt>= BUSY_WAIT_TIMEOUT) { DPRINTK("<= BAN =>Panel Disp Fail: BUSY time out\n"); return 0; } tmp = __raw_readl(rGPGDAT); } #elif defined(CONFIG_QISDA_E600_EVT2) || defined(CONFIG_QISDA_E600_DVT1) tmp = __raw_readl(rGPLDAT); while((tmp & (1<<13))==0) { DPRINTK("<= BAN =>panel is BUSY\n"); //msleep(100); for(i=0; i<20; i++) __mDelay(1); iBusyCnt ++; if(iBusyCnt>= BUSY_WAIT_TIMEOUT) { DPRINTK("<= BAN =>Panel Disp Fail: BUSY time out\n"); return 0; } tmp = __raw_readl(rGPLDAT); } #elif defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1) || defined(CONFIG_QISDA_QD060N00_DVT1_1) || defined(CONFIG_QISDA_QD090B00_EVT1) tmp = __raw_readl(rGPBDAT); while((tmp & (1<<2))==0) { DPRINTK("<= BAN =>panel is BUSY\n"); //msleep(100); for(i=0; i<20; i++) __mDelay(1); iBusyCnt ++; if(iBusyCnt>= BUSY_WAIT_TIMEOUT) { DPRINTK("<= BAN =>Panel Disp Fail: BUSY time out\n"); return 0; } tmp = __raw_readl(rGPBDAT); } #endif return 1; } int is_Epaper_Write_Ready_Wait(unsigned long waitTime) //ms { unsigned long tmp; int iBusyCnt=0; int i=0; #if defined(CONFIG_QISDA_E600_EVT0) tmp = __raw_readl(rGPGDAT); while((tmp & (1<<5))==0) { DPRINTK("<= BAN =>panel is BUSY\n"); //msleep(100); for(i=0; i<20; i++) __mDelay(1); iBusyCnt ++; if(iBusyCnt>= (waitTime/20)) { DPRINTK("<= BAN =>Panel Disp Fail: BUSY time out\n"); return 0; } tmp = __raw_readl(rGPGDAT); } #elif defined(CONFIG_QISDA_E600_EVT2) || defined(CONFIG_QISDA_E600_DVT1) tmp = __raw_readl(rGPLDAT); while((tmp & (1<<13))==0) { DPRINTK("<= BAN =>panel is BUSY\n"); //msleep(100); for(i=0; i<20; i++) __mDelay(1); iBusyCnt ++; if(iBusyCnt>= (waitTime/20)) { DPRINTK("<= BAN =>Panel Disp Fail: BUSY time out\n"); return 0; } tmp = __raw_readl(rGPLDAT); } #elif defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1) || defined(CONFIG_QISDA_QD060N00_DVT1_1) || defined(CONFIG_QISDA_QD090B00_EVT1) tmp = __raw_readl(rGPBDAT); while((tmp & (1<<2))==0) { //DPRINTK("<= BAN =>panel is BUSY\n"); //msleep(100); for(i=0; i<20; i++) __mDelay(1); iBusyCnt ++; if(iBusyCnt>= (waitTime/20)) { DPRINTK("<= BAN =>Panel Disp Fail: BUSY time out\n"); return 0; } tmp = __raw_readl(rGPBDAT); } #endif return 1; } static inline void s3c2416_i80_write(int data) { int tmp; tmp = __raw_readl(rSIFCCON0); // nWE enable tmp |= SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); __raw_writel(data, rSIFCCON1); //rSIFCCON1 = CMD; nDelay(25); tmp = __raw_readl(rSIFCCON0); // nWE disable tmp &= ~SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); } static inline void s3c2416_i80_write_Rotate(int data) { int tmp; tmp = __raw_readl(rSIFCCON0); // nWE enable tmp |= SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); //__uDelay(1); nDelay(25); //down to 1.5M __raw_writel(data, rSIFCCON1); //rSIFCCON1 = CMD; tmp = __raw_readl(rSIFCCON0); // nWE disable tmp &= ~SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); } static inline void s3c2416_i80_write_HandWriting(int data) { int tmp; tmp = __raw_readl(rSIFCCON0); // nWE enable tmp |= SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); nDelay(15); //down to 2M __raw_writel(data, rSIFCCON1); //rSIFCCON1 = CMD; tmp = __raw_readl(rSIFCCON0); // nWE disable tmp &= ~SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); } static inline void s3c2416_i80_write_Rotate_HandWriting(int data) { int tmp; __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nWE enable tmp |= SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); __uDelay(1); __raw_writel(data, rSIFCCON1); //rSIFCCON1 = CMD; tmp = __raw_readl(rSIFCCON0); // nWE disable tmp &= ~SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); } static inline void s3c2416_i80_write_LUT(int data) { int tmp; __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nWE enable tmp |= SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); __uDelay(1); __raw_writel(data, rSIFCCON1); //rSIFCCON1 = CMD; __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nWE disable tmp &= ~SYS_WR_CON; __raw_writel(tmp, rSIFCCON0); } static inline void s3c2416_i80_read(unsigned short* data) { int tmp; __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nRD enable tmp |= SYS_OE_CON; __raw_writel(tmp, rSIFCCON0); //__mDelay(1); //Ivan : must do __uDelay(1); *data = __raw_readl(rSIFCCON2); //CMD = rSIFCCON2; __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nRD disable tmp &= ~SYS_OE_CON; __raw_writel(tmp, rSIFCCON0); } static void DISP_CMD_OUT(unsigned short CMD, unsigned short* pdata, int data_length) { unsigned long tmp; unsigned long cnt; int ret = 0; tmp = __raw_readl(rSYSIFCON0); //polarity of RS, set 1 for normal access tmp |= (1<<2); __raw_writel(tmp, rSYSIFCON0); tmp = __raw_readl(rSIFCCON0); // command mode enable tmp |= (1<<0); __raw_writel(tmp, rSIFCCON0); tmp = __raw_readl(rSIFCCON0); // nCS0(Main) enable tmp |= (1<<8); __raw_writel(tmp, rSIFCCON0); __uDelay(1); tmp = __raw_readl(rSIFCCON0); // RS low tmp &= ~(1<<1); __raw_writel(tmp, rSIFCCON0); __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nWE enable tmp |= (1<<6); __raw_writel(tmp, rSIFCCON0); __uDelay(1); __raw_writel(CMD, rSIFCCON1); //rSIFCCON1 = CMD; __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nWE disable tmp &= ~(1<<6); __raw_writel(tmp, rSIFCCON0); __uDelay(1); tmp = __raw_readl(rSIFCCON0); // RS Hi tmp |= (1<<1); __raw_writel(tmp, rSIFCCON0); __uDelay(1); if(data_length > 0) { switch(CMD) { case AUO_EPAPER_CMD_INIT: { s3c2416_i80_write(*pdata); break; } case AUO_EPAPER_CMD_LUT_START: { for(cnt=0;cntAUO_EPAPER_CMD_PARTIALDISP, region=(%d(%d,%d) %d X %d)\n",partial_update_mode, REGION.X,REGION.Y,REGION.W,REGION.H); __uDelay(1); //MOD + X current_mode = ((unsigned short)partial_update_mode )<<12; /*if(partial_update_mode == PARTIAL_DSP_MODE_4) current_mode |= 0x8000; //Set "Write"*/ s3c2416_i80_write(current_mode|REGION.X); //Y s3c2416_i80_write(REGION.Y); //W s3c2416_i80_write(REGION.W); //H s3c2416_i80_write(REGION.H); if((partial_update_mode == PARTIAL_DSP_MODE_4)||(partial_update_mode == PARTIAL_DSP_MODE_4_W)) { if(gRotateDegree!=0) { DPRINTK("\nHand writing + Rotate"); for(cnt=0; cnt<(REGION.W*REGION.H/4); cnt++) { s3c2416_i80_write_Rotate_HandWriting((unsigned short)pdata[cnt]); //rSIFCCON1 = CMD; } } else { DPRINTK("\nHand writing"); for(cnt=0; cnt<(REGION.W*REGION.H/4); cnt++) { s3c2416_i80_write_HandWriting((unsigned short)pdata[cnt]); //rSIFCCON1 = CMD; } } } else if(gRotateDegree!=0) { DPRINTK("\nRotate"); for(cnt=0; cnt<(REGION.W*REGION.H/4); cnt++) { s3c2416_i80_write_Rotate((unsigned short)pdata[cnt]); //rSIFCCON1 = CMD; } } else { DPRINTK("\nnormal"); for(cnt=0; cnt<(REGION.W*REGION.H/4); cnt++) { s3c2416_i80_write((unsigned short)pdata[cnt]); //rSIFCCON1 = CMD; } } break; } case AUO_EPAPER_CMD_STOP: break; default: DPRINTK("unkonwn command\n"); break; } /* BAN 20090406 + for test panel*/ // STOP tmp = __raw_readl(rSIFCCON0); //rSIFCCON0 &= ~(1<<1); // RS low tmp &= ~(1<<1); // RS low __raw_writel(tmp, rSIFCCON0); __uDelay(1); s3c2416_i80_write(AUO_EPAPER_CMD_STOP); __uDelay(1); tmp = __raw_readl(rSIFCCON0); // RS Hi tmp |= (1<<1); __raw_writel(tmp, rSIFCCON0); __uDelay(1); tmp = __raw_readl(rSIFCCON0); // nCS0(Main) disable tmp &= ~(1<<8); __raw_writel(tmp, rSIFCCON0); tmp = __raw_readl(rSIFCCON0); // command mode disable tmp &= ~(1<<0); __raw_writel(tmp, rSIFCCON0); } void Epaper_SetLcdPort(void) { unsigned long tmp; DPRINTK("I80 Init \n"); // set gpio for lcd tmp =__raw_readl(rGPCCON); //tmp = (tmp & ~(0xffff03ff))|(0xaaaa02aa); tmp = (tmp & ~(0xffff033f))|(0xaaaa022a); //Do not config SYS_CS1(GPC3) __raw_writel(tmp, rGPCCON); #if defined(CONFIG_QISDA_E600_EVT0) DPRINTK("\nCONFIG_QISDA_E600_EVT0\n"); __raw_writel(0xaaaaaaaa, rGPDCON); #elif defined(CONFIG_QISDA_E600_EVT2) || defined(CONFIG_QISDA_E600_DVT1) || defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1) || defined(CONFIG_QISDA_QD060N00_DVT1_1) || defined(CONFIG_QISDA_QD090B00_EVT1) DPRINTK("\nCONFIG_QISDA_E600_EVT2 || CONFIG_QISDA_E600_DVT1 || CONFIG_QISDA_AS090B00_EVT1 || CONFIG_QISDA_AS090B00_EVT1_1 || CONFIG_QISDA_QD060N00_DVT1_1 || CONFIG_QISDA_QD090B00_EVT1\n"); tmp =__raw_readl(rGPDCON); //tmp=0x40000 tmp = (tmp & ~(0x0CFFFF))|(0x04AAAA); __raw_writel(tmp, rGPDCON); // GPD9 is RST_N #endif __raw_writel(0, rGPCUDP); //rGPCUDP = 0; __raw_writel(0, rGPDUDP); //rGPDUDP = 0; #if 1 { tmp = __raw_readl(rVIDCON0); //rVIDCON0 = rVIDCON0 & ~(0x3<<22) | (0x2<<22); tmp = (tmp & ~(0x3<<22)) | (0x2<<22) | (0x30 <I80 Write\n"); DISP_DATA_OUT(tFrame.u16EpaperCommand,tFrame.pFrameData,tFrame.tFrameRange); return DISP_SUCCESS; } void Epaper_Set_Partial_Update_Mode(int mode) { partial_update_mode = mode; } int Epaper_Get_Partial_Update_Mode(void) { return partial_update_mode; } void Epaper_Enter_Standby_Mode(int isEnter) { //unsigned long tmp; if(isEnter) { //send 0x0001 to T-CON to enter standby mode DISP_CMD_OUT(AUO_EPAPER_CMD_STANDBY, NULL, 0); } else { //send 0x0002 to T-CON to leave standby mode DISP_CMD_OUT(AUO_EPAPER_CMD_WAKEUP, NULL, 0); } } void Epaper_Enter_Sleep_Mode(int isEnter) { unsigned long tmp; if(isEnter) { #if defined(CONFIG_QISDA_E600_EVT0) || defined(CONFIG_QISDA_E600_EVT2) || defined(CONFIG_QISDA_E600_DVT1) //Set SLP_N to low to enter sleep mode tmp = __raw_readl(rGPEDAT); tmp &= ~(1<<11); __raw_writel(tmp, rGPEDAT); #elif defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1) || defined(CONFIG_QISDA_QD060N00_DVT1_1) || defined(CONFIG_QISDA_QD090B00_EVT1) tmp = __raw_readl(rGPBDAT); tmp &= ~(1<<1); __raw_writel(tmp, rGPBDAT); #endif } else { #if defined(CONFIG_QISDA_E600_EVT0) || defined(CONFIG_QISDA_E600_EVT2) || defined(CONFIG_QISDA_E600_DVT1) //Set SLP_N to high to leave sleep mode tmp = __raw_readl(rGPEDAT); tmp |= (1<<11); __raw_writel(tmp, rGPEDAT); #elif defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1) || defined(CONFIG_QISDA_QD060N00_DVT1_1) || defined(CONFIG_QISDA_QD090B00_EVT1) tmp = __raw_readl(rGPBDAT); tmp |= (1<<1); __raw_writel(tmp, rGPBDAT); #endif } } void Epaper_Power(int isEnable) { unsigned long tmp; if(isEnable) { tmp = __raw_readl(rGPBDAT); tmp |= (1<<3); __raw_writel(tmp, rGPBDAT); } else { tmp = __raw_readl(rGPBDAT); tmp &= ~(1<<3); __raw_writel(tmp, rGPBDAT); } } void Epaper_Read_R_TEMP(unsigned short* val0, unsigned short* val1, unsigned short* val2, unsigned short* val3) { //unsigned long tmp; unsigned short val[4]; memset(val, 0x0, 8); DISP_DATA_IN(AUO_EPAPER_CMD_TEMPER, val, 4); *val0 = val[0]; *val1 = val[1]; *val2 = val[2]; *val3 = val[3]; } void Epaper_Display_Refresh(void) { DISP_CMD_OUT(AUO_EPAPER_CMD_REFRESH, NULL, 0); } int Epaper_Init(int h_Res, int v_Res, int rotation, int data_inverse, int inputdata_arrangement, int outputdata_arrangement,int UD, int SHL) { unsigned short u16InitPara=0; if(is_Epaper_Write_Ready()) { h_resolution = h_Res; v_resolution = v_Res; //TEMP_AVE_EN u16InitPara = u16InitPara | (1<<13); //M23_FILTER //ROT gRotateDegree = rotation; if(rotation == 0) { } else if(rotation == 90) u16InitPara = u16InitPara | (1<<10); else if(rotation == 180) u16InitPara = u16InitPara | (2<<10); else if(rotation == 270) u16InitPara = u16InitPara | (3<<10); else { } //DI //BN //CHDA //RES if(h_resolution==1024 && v_resolution==768) u16InitPara = u16InitPara | (1<<2); else if(h_resolution==800 && v_resolution==600) { } else { } //UD //SHL u16InitPara = u16InitPara | 1; DISP_CMD_OUT(AUO_EPAPER_CMD_INIT, &u16InitPara, 1); DPRINTK("\nInit size=%d, Init data =0x%x\n", sizeof(unsigned short),u16InitPara); return 0; } return -1; /* T_INIT init_Para; T_DISPLAY_REGION empty_REGION; if(is_Epaper_Write_Ready()) { h_resolution = h_Res; v_resolution = v_Res; init_Para.u16Reserve1 = 0; gRotateDegree = rotation; if(rotation == 0) init_Para.ROT = 0; else if(rotation == 90) init_Para.ROT = 1; else if(rotation == 180) init_Para.ROT = 2; else if(rotation == 270) init_Para.ROT = 3; else init_Para.ROT = 0; init_Para.DI = 0; init_Para.BN = 0; init_Para.CHDA = 0; if(h_resolution==1024 && v_resolution==768) init_Para.RES = 1; else if(h_resolution==800 && v_resolution==600) init_Para.RES = 0; else init_Para.RES = 0; init_Para.UD = 0; init_Para.SHL = 1; DISP_CMD_OUT(AUO_EPAPER_CMD_INIT, &init_Para, 1); DPRINTK("\nInit data =0x%x", init_Para); return 0; } return -1; */ } //u32LUTLength: length in (unsigned short) int Epaper_Update_LUT(unsigned short* u16LUT, unsigned long u32LUTLength) { //unsigned long cnt=0; if(is_Epaper_Write_Ready_Wait(10000)) { DISP_CMD_OUT(AUO_EPAPER_CMD_LUT_START, u16LUT, u32LUTLength); return 0; } else return -1; } //u32LUTLength: length in (unsigned short) void Epaper_Read_LUT(unsigned short* u16LUT, unsigned long u32LUTLength) { DISP_DATA_IN(AUO_EPAPER_CMD_LUT_READ, u16LUT, u32LUTLength); } void Epaper_Reset(void) { DISP_CMD_OUT(AUO_EPAPER_CMD_RESET, NULL, 0); } #include /* [MTR] Add generic command function */ enum InfoLevel { INFO_ERROR = 0, INFO_WARNING, INFO_NORMAL, INFO_DEBUG, INFO_VERBOSE, }; //#define EPAPER_DEBUG //#define VERBOSE_LEVEL INFO_VERBOSE #ifndef VERBOSE_LEVEL #define VERBOSE_LEVEL INFO_WARNING #endif #ifdef EPAPER_DEBUG static int _dbgFL = 0; #define FUNC_IN() do { int i; _dbgFL++; printk(KERN_ERR "+"); for (i = 0; i < _dbgFL; i++) printk("-"); printk(">> %s() >>\n", __func__); } while(0) #define FUNC_OUT() do { int i; printk(KERN_ERR "+"); for (i = 0; i < _dbgFL; i++) printk("-"); printk("<< %s() <<\n", __func__); _dbgFL--; } while(0) #define FUNC_OUTR(val) do { int i; printk(KERN_ERR "+"); for (i = 0; i < _dbgFL; i++) printk("-"); printk("<< %s() = %d <<\n", __func__, val); _dbgFL--; } while(0) #define INFOL(level, s) do { if (level <= VERBOSE_LEVEL) { int i; printk(KERN_ERR "+"); for (i = 0; i < _dbgFL; i++) printk("-"); printk("||%s:%s(): ", __FILE__, __func__); printk s; printk("\n"); } } while(0) #define INFO(s) do { int i; printk(KERN_ERR "+"); for (i = 0; i < _dbgFL; i++) printk("-"); printk("||%s:%s(): ", __FILE__, __func__); printk s; printk("\n"); } while(0) #else #define FUNC_IN() do {} while(0) #define FUNC_OUT() do {} while(0) #define FUNC_OUTR(val) do {} while(0) #define INFOL(level, s) do { if (level <= VERBOSE_LEVEL) { printk("<%d>%s:%s(): ", level, __FILE__, __func__); printk s; printk("\n"); } } while(0) #define INFO(s) do { printk("%s:%s(): ", __FILE__, __func__); printk s; printk("\n"); } while(0) #endif //#define GET_COMMAND_PARAM_NUM(command) ((command >> 20) & 0x0F) //#define GET_COMMAND_HAVE_DATA(command) ((command >> 28) & 0x01) //#define GET_COMMAND_NEED_WAIT(command) ((command >> 29) & 0x01) /* On the i80 port, * i80 TCON * ----------- * RS -> D/C * CS0 -> CSEL * nWE -> HWE * OE -> HRD */ static inline void _InitI80Interface(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSYSIFCON0); //polarity of RS, set 1 for normal access tmp |= (1<<2); __raw_writel(tmp, rSYSIFCON0); tmp = __raw_readl(rSIFCCON0); // command mode enable tmp |= (1<<0); __raw_writel(tmp, rSIFCCON0); FUNC_OUT(); } static inline void _DeinitI80Interface(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // command mode disable tmp &= ~(1<<0); __raw_writel(tmp, rSIFCCON0); FUNC_OUT(); } static inline void _SetWriteToData(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // RS high -> D/nC set Data mode tmp |= (1<<1); __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } static inline void _SetWriteToCommand(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // RS low -> D/nC set Command mode tmp &= ~(1<<1); __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } static inline void _EnableWrite(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // nWE -> HWE enable tmp |= (1<<6); __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } static inline void _DisableWrite(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // nWE -> HWE disable tmp &= ~(1<<6); __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } static inline void _EnableRead(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // nRD enable tmp |= SYS_OE_CON; __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } static inline void _DisableRead(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // nRD disable tmp &= ~SYS_OE_CON; __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } static inline void _SelectChip(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // Chip Select tmp |= (1<<8); __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } static inline void _UnselectChip(void) { unsigned long tmp; FUNC_IN(); tmp = __raw_readl(rSIFCCON0); // nCS0(Main) enable tmp &= ~(1<<8); __raw_writel(tmp, rSIFCCON0); __uDelay(1); FUNC_OUT(); } int Epaper_sendCommandStart(sAUOCommand *cmd) { FUNC_IN(); INFOL(INFO_VERBOSE,("cmd #%08lX", cmd->cmd)); /* First: verify that the K1900 is ready */ INFOL(INFO_VERBOSE, ("/* First: verify that the K1900 is ready */")); if (GET_COMMAND_NEED_WAIT(cmd->cmd) != 0x00) { INFOL(INFO_VERBOSE, ("Wait for non BUSY...")); is_Epaper_Write_Ready(); } /* Second: init the i80 interface */ INFOL(INFO_VERBOSE, ("/* Second: init the i80 interface */")); _InitI80Interface(); /* Third: Select the chip and set to Command mode */ INFOL(INFO_VERBOSE, ("/* Third: Select the chip and set to Command mode */")); _SelectChip(); _SetWriteToCommand(); /* Fourth: Send command */ INFOL(INFO_VERBOSE, ("/* Fourth: Send command */")); s3c2416_i80_write(cmd->cmd); /* This function already manage HWE, * no need to do it here. */ /* Sixth: If parameters is needed, send them */ INFOL(INFO_VERBOSE, ("/* Sixth: If parameters is needed, send them */")); if (GET_COMMAND_PARAM_NUM(cmd->cmd) > 0) { int i, paramNumbers = GET_COMMAND_PARAM_NUM(cmd->cmd); INFOL(INFO_VERBOSE, ("YES! We have %d parameters", paramNumbers)); _SetWriteToData(); for (i = 0; i < paramNumbers; i++) { s3c2416_i80_write(cmd->params[i]); } } FUNC_OUT(); return 0; } int Epaper_sendData(unsigned short *buffer, unsigned long bufferLen) { /* Seventh: Send data if needed */ unsigned long i; FUNC_IN(); INFOL(INFO_VERBOSE, ("Bufferlen: %ld", bufferLen)); _SetWriteToData(); for (i = 0; i < bufferLen; i++) { s3c2416_i80_write(buffer[i]); } FUNC_OUT(); return 0; } int Epaper_sendCommandEnd(sAUOCommand *cmd) { FUNC_IN(); /* Eighth: Close all */ _UnselectChip(); _DeinitI80Interface(); FUNC_OUT(); return 0; } /* [/MTR] */