1.首先了解一下6866这个芯片的功能是将HDMI转成LVDS
知道这一步,就要知道如何实现

将 .bin 文件复制到ETC路径

然后加载.bin文件会在nt6866的驱动中下载到芯片内
\sdk\kernel\drivers\video\rockchip\hdmi\rockchip-hdmi-core.c
+ #ifdef CONFIG_NT68661
+ return ;
+ #endif

\sdk\kernel\drivers\video\rockchip\hdmi\rockchip-hdmi-lcdc.c
+ #ifdef CONFIG_NT68661
+ struct rk_screen * rk_get_screen(void);
+ #endif
int hdmi_find_best_mode(struct hdmi *hdmi, int vic)
{
struct list_head *pos, *head = &hdmi->edid.modelist;
struct display_modelist *modelist = NULL;
int found = 0;
+ #if CONFIG_NT68661
+ struct rk_screen *screen=NULL;
+
+
+ screen=rk_get_screen();
+
+ printk("x=%d y=%d \n",screen->mode.xres,screen->mode.yres);
+
+ printk("screen->face=%d screen->lvds_format=%d \n",screen->face,screen->lvds_format);
+
+ if(screen->mode.xres==1920&&screen->mode.yres==1080) return HDMI_1920X1080P_60HZ;
+ else if(screen->mode.xres==1366&&screen->mode.yres==768) return (HDMI_VIDEO_DMT | 6);
+ else if(screen->mode.xres==1280&&screen->mode.yres==1024) return (HDMI_VIDEO_DMT | 4);
+
+ return HDMI_1920X1080P_60HZ;// (HDMI_VIDEO_DMT | 4);
+ #else



// sdk\kernel\drivers\char\nt68661.c
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/fb.h>
#include <linux/rk_fb.h>
typedef unsigned char Bit;
typedef unsigned char Bool;
typedef unsigned char Byte;
typedef unsigned short Word;
typedef unsigned long ULong;
#define LOG_TAG "nt68661"
#if 1 //def GSL_DEBUG
#define debug(fmt, x...) printk("%s: %s() line: %d "fmt, LOG_TAG, __FUNCTION__, __LINE__, ##x);
#else
#define print_info(fmt, args...)
#endif
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define TARGET0 BIT7
#define NACK 1
#define ACK 0
#define FAIL 0
#define OK 1
#define EMPTY 2
typedef union{
unsigned long l;
Byte b[4];
}Union4;
typedef union{
Word w;
Byte b[2]; //0:H, 1:L
}Union2;
#define VERSION 17
#define OSC_CLK 12000000//unit Mhz
#define LOW_MCU_CLK OSC_CLK*1
#define MID_MCU_CLK OSC_CLK*3
#define HI_MCU_CLK OSC_CLK*8
#define LOW_SPEED 1
#define MID_SPEED 3
#define HI_SPEED 8
// FE2P mode
#define NORMAL_MODE 0
#define FE2P_MODE 1
#define DIRECT_FE2P_MODE 2
#define true 1
#define false 0
// En Name Id Pg CPUCLK IICSPD SpcCmd NewProg Umb Fe2p 60k CoP ExtFlash
typedef struct{
Byte En;
Byte Name[15];
Word Id;
Word page;
Byte CpuClk;
Byte IICSpeed;
Byte SpcCmd;
Byte NewProg;
Byte Umb;
Byte Fe2p;
Byte s60k;
Byte coP;
Byte ExtFlash;
}MCU_DEF;
typedef struct{
Byte En;
Byte ID1;
Byte ID2;
Byte ID3;
Byte FE2P;
Byte ByteWrite;
Byte SE_Code;
Byte CE_Code;
Word Page;
Byte SE_Time;
Word CE_Time;
Byte Name[23];
}FLASH_DEF;
extern const Byte McuRegTab[];
extern const FLASH_DEF FlashIDTable[];
extern const MCU_DEF McuTypeTable[];
#define _tNOVATEK 0
#define _tFE2P 1
#define _tBLOCK_SAVE 2
#define _tENTER_ISP 3
#define _tCHIP_ERASE 4
#define _tBLCOK_ERASE 5
#define _tPROGRAM 6
#define _tEXIT_ISP 7
#define _tSOURCE_ISP 8
#define _tTARGET_FAIL 9
#define _tPROGRAM_START 10
#define _tPROGRAM_END 11
#define _tCHECK_SUM 12
#define _tFLASH_NAME 13
#define _tSOURCE_READ 14
#define _tFE2P_SUM 15
#define _tPASS 3
#define _tFAIL 4
#define _tON 1
#define _tOFF 2
#define _tFAIL_CH 5
#define _tCHECKSUM 6
#define _tFE2PSUM 7
#define comChipErase 0x1E
#define comBlockErase 0x2D //new NT68631A
#define comWritePage24M 0x3C
#define comGetPage 0x4B
#define comWriteOne 0x5A
#define comGetDirect 0x69
#define comSetRegSRAM 0x78
#define comGetRegSRAM 0x87
#define comGetIntRAM 0x96
#define comGetPageNew 0x4A //new NT68670&NT68631A
#define comGetCheckSum 0x36 //new NT68670&NT68631A
#define comSetExtendAddr 0x0f //new NT68670
#define comGetVersion 0x11 //new NT68670&NT68631A
#define comMultiFunc 0x99
#define comSPICmd 0x53
extern Byte pFail; //For Message process
extern FLASH_DEF Flash; //Flash Information
extern Byte McuGear; //MCY clock ratio
extern Word Timer; //System Timer
extern Word MaxPages; //Max programming pages
extern Byte Fe2pMode; // For FE2P Mode
extern Word DirFE2P_Offset;
Byte MultiID;
extern Word SPageSum; //Source Page checksum
extern Byte Buffer[512];
extern Word McuId;
extern Bit ErrorFlag;
Word usSPICmdBufAddr;
Byte ucSPI_BackUpBuf[7] = {0};
extern ULong WpDefine;
extern Byte Wp_PortE;
extern Byte Wp_PortF;
extern ULong Wp_PortG_J;
extern ULong Wp_PortK_M;
#if 1
#define SDA_PIN 7
#define SCL_PIN 6
#else
#define SDA_PIN 84
#define SCL_PIN 85
#endif
#define SET_SCL_H gpio_set_value(SCL_PIN,1)
#define SET_SCL_L gpio_set_value(SCL_PIN,0)
#define SET_SDA_H gpio_set_value(SDA_PIN,1)
#define SET_SDA_L gpio_set_value(SDA_PIN,0)
#define GET_SDA() gpio_get_value(SDA_PIN)
#define GET_SCL() gpio_get_value(SCL_PIN)
#define SET_SDA_INPUT gpio_direction_input(SDA_PIN)
#define SET_SCL_INPUT gpio_direction_input(SCL_PIN)
#define SET_SDA_OUTPUT {gpio_direction_output(SDA_PIN,1);SET_SDA_H;}
#define SET_SCL_OUTPUT gpio_direction_output(SCL_PIN,1)
Byte pFail; //For Message process
Byte McuGear; //MCU clock ratio
Byte Bypass; //ByPass Compare
Word Timer; //System Timer
Word MaxPages; //Max Flash pages
Word CodePages; // f/w programming pages
Word FlashOffset; // start page of Flash
Word SPageSum; //Source Page checksum
Word McuId;
Byte Fe2pMode; // For FE2P Mode
Word DirFE2P_Offset;
Word DirFE2P_Length;
#define TOTAL_PAGE_SIZE 200
Byte BinFilePageBuffer[512] ;// 1024pages for 4M flash
FLASH_DEF Flash;
Bit ErrorFlag;
// please define the WP here(according bit set 1)
ULong WpDefine=0x02000000;
Byte Wp_PortE;
Byte Wp_PortF;
ULong Wp_PortG_J;
ULong Wp_PortK_M;
// Dual F/W
Bit DualFwEnable;
extern void Sleep(Word T);
extern void Sdelay(void);
extern void PulseDelay();
extern void T_CheckIIC(void);
extern void T_IIC_Start(void);
extern void T_IIC_Stop(void);
extern Byte T_IIC_Tx(Byte Data);
extern unsigned char T_IIC_Rx(Bit Ack);
extern void T_WaitSCL(void);
extern void T_HandShake(Word Timeout);
extern void T_ISPMode(Bit On);
extern void T_ISPStatusReply();
extern Byte T_GetPageData(Byte PageNo);
extern Byte T_ChipErase(void);
extern Byte T_ChipEraseReply(void);
extern Byte T_WritePagedata(Byte Pg);
extern void T_WritePageDataReply(void);
extern void T_SetRegSRAM(Byte AddrH,Byte AddrL,Byte Data);
extern void T_SetRegSRAMReply();
extern Byte T_GetCheckSum(Byte PageNo);
extern Byte T_GetCheckSumReply(void);
extern Bit T_GetMcuInformation(Word id);
extern Byte T_BlockErase(Byte From,Byte To);
extern Byte T_BlockEraseReply();
extern Byte T_SpiCommand(Byte *Data,Byte WLen,Byte RLen);
extern void T_GetVersion(void);
extern void T_GetRegSRAM(Byte AddrH,Byte AddrL);
extern unsigned long T_GetRegSRAMReply(void);
extern void Cmd_T_EnterIsp(void);
extern void Cmd_T_Erase(void);
extern void Cmd_T_Program(Byte Pg);
extern void Cmd_T_GetCheckSum(Byte Pg);
extern void Cmd_T_BlockErase();
extern Byte Cmd_T_SetExntend(Word Pg);
extern void Cmd_T_SendSpecialCommand();
extern void Cmd_T_WP_Enable(void);
extern void Cmd_T_BlockProtect(Bit Wp);
extern Bool CheckOverLap(Word PageNo);
extern void Fn68390ProgramEnable(Bit En);
extern void WpEnable(void);
extern void FnEraseIDSector(void);
extern Bit FnUpdateIDSector(void);
void Cmd_T_GetFlashID();
extern Word DirFE2P_Length;
extern Bit DualFwEnable,ErrorFlag;
extern Byte SearchFlashID(Byte *mcuFlashID);
void Cmd_T_BlockProtect0(void);
const MCU_DEF McuTypeTable[]={
// En Name Id Pg CPUCLK IICSPD SpcCmd NewProg Umb Fe2p 60k CoP ExtFlash
{true,"NT68360 ", 0xA536,256,0x50 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68169 ", 0xA569,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68661 ", 0xA561,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68850 ", 0xA585,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68770 ", 0xA577,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68655 ", 0xA555,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68150 ", 0xA515,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68370 ", 0xA537,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,true, true},
{true,"NT68790 ", 0xA790,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68658 ", 0xA658,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68380 ", 0xA380,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,true, true},
{true,"NT68390 ", 0xA390,256,0x40 ,HI_SPEED ,0x02 ,true ,true ,true ,false,true, true},
{true,"NT68810 ", 0xA810,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68870 ", 0xA870,256,0x30 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
{true,"NT68400 ", 0xA400,256,0x40 ,HI_SPEED ,0x02 ,true ,true, true, false,false,true},
{true,"NT68450 ", 0xA450,256,0x40 ,HI_SPEED ,0x02 ,true ,true ,true ,false,false,true},
};
const FLASH_DEF FlashIDTable[]={
// En ID1 ID2 ID3 FE2P BYTE SE CE PAGE SE_T CE_T NAME
{true ,0x55,0xaa,0x00,false,false,0xd7,0xc7,256 ,0 ,100 ,"Embeded/Unknown Flash "},
{true ,0x9d,0x7f,0x7c,true ,false,0xd7,0xc7,256 ,70 ,100 ,"PMC Pm25LV010A 128KB "},
{true ,0x9d,0x7f,0x7d,true ,false,0xd7,0xc7,512 ,70 ,100 ,"PMC Pm25LV020A 256KB "},
{true ,0x9d,0x7f,0x7e,true ,false,0xd7,0xc7,1024,300 ,3000 ,"PMC Pm25LV040A 512KB "}, // modify SE_T, CE_T to be compatible with Pm25LQ040B because their flash ID are the same.
{true ,0x9d,0x7f,0x10,true ,false,0xd7,0xc7,256 ,70 ,100 ,"PMC_Pm25LD010C 128KB "},
{true ,0x9d,0x7f,0x11,true ,false,0xd7,0xc7,512 ,70 ,100 ,"PMC_Pm25LD020C 256KB "},
{true ,0x9d,0x7f,0x12,true ,false,0xd7,0xc7,1024,70 ,100 ,"PMC_Pm25LD040C 512KB "},
{true ,0x9d,0x40,0x11,true ,false,0xd7,0xc7,256,300 ,1500 ,"ISSI IS25LQ010B 1MB"},
{true ,0x9d,0x60,0x14,true ,false,0xd7,0xc7,2048,300 ,6000 ,"ISSI IS25LP080D 1MB"},
{true ,0xc2,0x20,0x11,true ,false,0x20,0xc7,256 ,120 ,2000,"MXIC MX25L1005 128K "},
{true ,0xc2,0x20,0x12,true ,false,0x20,0xc7,512 ,120 ,3000,"MXIC MX25L2005 256K "},
{true ,0xc2,0x20,0x13,true ,false,0x20,0xc7,1024,120 ,5000,"MXIC MX25L4005A 512K "},
{true ,0xc2,0x20,0x14,true ,false,0x20,0xc7,2048,300 ,15000,"MXIC MX25L8006E 1MB "},
{true ,0xc2,0x20,0x15,true ,false,0x20,0xc7,4096,300 ,30000,"MXIC MX25L1606E 2MB "},
{true ,0xc2,0x20,0x17,true ,false,0x20,0xc7,2048,300 ,80000,"MXIC MX25L6406E 8MB "}, // page set to 2048 means only read first 2048 pages, don't care other pages.
{true ,0xc2,0x23,0x11,true ,false,0x20,0xc7, 256,240 , 2300,"MXIC MX25V1035F 128KB "},
{true ,0xc2,0x23,0x12,true ,false,0x20,0xc7, 512,240 , 9000,"MXIC MX25V2035F 256KB "},
{true ,0xc2,0x23,0x13,true ,false,0x20,0xc7,1024,240 , 9000,"MXIC MX25V4035F 512KB "},
{true ,0xc2,0x23,0x14,true ,false,0x20,0xc7,2048,240 ,18000,"MXIC MX25V8035F 1MB "},
{true ,0xc2,0x23,0x15,true ,false,0x20,0xc7,4096,240 ,38000,"MXIC MX25V1635F 2MB "},
{true ,0xbf,0x49,0xff,true ,true ,0x20,0xc7,256 ,70 ,100 ,"SST SST25VF010A 128K "},
{true ,0xbf,0x43,0xff,true ,true ,0x20,0xc7,512 ,70 ,100 ,"SST SST25VF020 256K "},
{true ,0xbf,0x44,0xff,true ,true ,0x20,0xc7,1024,70 ,100 ,"SST SST25LF040 512K "},
{true ,0xbf,0x8c,0xff,true ,true ,0x20,0xc7,512 ,30 ,60 ,"SST SST25VF020B 256K "},
{true ,0xbf,0x8e,0xff,true ,true ,0x20,0xc7,2048 ,30 ,60 ,"PCT/SST 25VF080B 1MB "},
{true ,0xef,0x11,0xff,true ,false,0x20,0xc7,256 ,150 ,3000,"WINBOND W25X10 128K "},
{true ,0xef,0x10,0xff,true ,false,0x20,0xc7,512 ,150 ,3000,"WINBOND W25X20 256K "},
{true ,0xef,0x12,0xff,true ,false,0x20,0xc7,1024,150 ,5000,"WINBOND W25X40 512K "},
{true ,0xef,0x40,0x12,true ,false,0x20,0xc7,512 ,300 ,2000,"WINBOND W25Q20CL 256K"},
{true ,0xef,0x40,0x13,true ,false,0x20,0xc7,1024,300 ,5000,"WINBOND W25Q40CL 512K"},
{true ,0xef,0x40,0x14,true ,false,0x20,0xc7,2048,400 ,8000,"WINBOND W25Q80BV 1MB "},
{true ,0xef,0x70,0x14,true ,false,0x20,0xc7,2048,400 ,10000,"WINBOND W25Q80JV 1MB"},
{true ,0xef,0x40,0x15,true ,false,0x20,0xc7,4096,400 ,10000,"WINBOND W25Q16CL/DV 2MB"},
{true ,0xef,0x70,0x15,true ,false,0x20,0xc7,4096,400 ,25000,"WINBOND W25Q16JV 2MB"},
{true ,0xef,0x40,0x16,true ,false,0x20,0xc7,4096,400 ,50000,"WINBOND W25Q32FV 4MB"},
{true ,0x00,0x10,0x10,false,false,0xd8,0xc7,256 ,100 ,3000,"ST M25P10 128K "},
{true ,0x00,0x11,0x11,false,false,0xd8,0xc7,512 ,100 ,3000,"ST M25P20 256K "},
{true ,0x00,0x12,0x12,false,false,0xd8,0xc7,1024,100 ,5000,"ST M25P40 512K "},
{true ,0x20,0x20,0x12,false,false,0xd8,0xc7,512 ,100 ,6000,"NUMONYX M25P20 256K "},
{true ,0x20,0x10,0x11,false,false,0xd8,0xc7,256 ,100 ,3000,"NUMONYX/ST M25P10 128K"},
{true ,0x37,0x11,0x30,true ,false,0x20,0xc7,256 ,120 ,2000,"AMIC A25L010A(B) 128K"},
{true ,0x37,0x12,0x30,true ,false,0x20,0xc7,512 ,120 ,4000,"AMIC A25L020A(B) 256K"},
{true ,0x37,0x13,0x30,true ,false,0x20,0xc7,1024,120 ,6000,"AMIC A25L040A(B) 512K"},
{true ,0x1c,0x11,0x31,true ,false,0x20,0xc7,256 ,300 ,3000,"EON EN25F10 128K "},
{true ,0x1c,0x12,0x31,true ,false,0x20,0xc7,512 ,300 ,4000,"EON EN25F20 256K "},
{true ,0x1c,0x13,0x31,true ,false,0x20,0xc7,1024,300 ,6000,"EON EN25F40 512K "},
{true ,0x1c,0x32,0xff,false,false,0xd8,0xc7,1024,300 ,6000,"EON EN25B40 512K "},
{true ,0x1c,0x13,0x30,false,false,0x20,0xc7,1024,300 ,7500,"EON EN25Q40A 512K "},
{true ,0x1c,0x14,0x30,false,false,0x20,0xc7,2048,300 ,15000,"EON EN25Q80B 1MB "},
{true ,0x1c,0x15,0x70,true ,false,0x20,0xc7,4096,300 ,30000,"EON EN25QH16A 2MB "},
{true ,0x8c,0x30,0x12,true ,true ,0x20,0xc7,512, 200 ,4000,"ESMT F25L02PA 256K "},
{true ,0x8c,0x30,0x13,true ,true ,0x20,0xc7,1024,200 ,4000,"ESMT F25L04PA 512K "},
{true ,0x8c,0x30,0x14,true ,true ,0x20,0xc7,2048,200 ,5000,"ESMT F25L08PT 1024K "},
{true ,0x8c,0x31,0x12,true ,true ,0x20,0xc7,512, 200 ,4000,"ESMT F25L02PTA 256K "},
{true ,0x8c,0x31,0x13,true ,true ,0x20,0xc7,1024,200 ,4000,"ESMT F25L04PTA 512K "},
{true ,0x8c,0x31,0x14,true ,true ,0x20,0xc7,2048,200 ,5000,"ESMT F25L08PTA 1024K "},
{true ,0x8c,0x40,0x14,true ,true ,0x20,0xc7,2048,400 ,20000,"ESMT F25L08QA 1024K "},
{true ,0xc8,0x40,0x11,true ,false,0x20,0xc7,256, 500 ,2000,"GIGA GD25Q10 128K "},
{true ,0xc8,0x40,0x12,true ,false,0x20,0xc7,512, 500 ,5000,"GIGA GD25Q20 256K "},
{true ,0xc8,0x41,0x12,true ,false,0x20,0xc7,512, 500 ,4000,"GIGA GD25M21 256K "},
{true ,0xc8,0x40,0x13,true ,false,0x20,0xc7,1024,500 ,11250, "GIGA 25Q40/41B/40C 512K"},
{true ,0xc8,0x41,0x13,true ,false,0x20,0xc7,1024,400 ,5000, "GIGA GD25M41 512K "},
{true ,0xc8,0x40,0x14,true ,false,0x20,0xc7,2048, 300 ,10000,"GIGA GD25Q80C 1MB "},
{true ,0xc8,0x40,0x15,true ,false,0x20,0xc7,4096, 300 ,20000,"GIGA GD25Q16C 2MB "},
{true ,0xd5,0x30,0x13,true ,false,0x20,0xc7,1024,200 ,7500,"NANTRONICS N25S40 512k"},
{true ,0xa1,0x31,0x13,true ,false,0x20,0xc7,1024,300 ,10000,"FUDAN FM25F04 512k "},
{true ,0xa1,0x31,0x12,true ,false,0x20,0xc7,512 ,300 ,5000,"FUDAN FM25F02 256k "},
{true ,0xa1,0x31,0x11,true ,false,0x20,0xc7,256 ,300 ,4000, "FUDAN FM25F01 128k "},
{true ,0xa1,0x40,0x12,true ,false,0x20,0xc7,512,300 ,2500,"FUDAN FM25Q02 256k "},
{true ,0xa1,0x40,0x13,true ,false,0x20,0xc7,1024 ,300 ,5000,"FUDAN FM25Q04 512k "},
{true ,0xa1,0x40,0x14,true ,false,0x20,0xc7,2048 ,300 ,32000, "FUDAN FM25Q08 1MB "},
{true ,0xa1,0x40,0x15,true ,false,0x20,0xc7,4096 ,300 ,20000, "FUDAN FM25Q16 2MB "},
{true ,0xe0,0x40,0x15,true ,false,0x20,0xc7,1024 ,300 ,25000,"BergMicro BG25Q40 512k"},
{true ,0xe0,0x40,0x12,true ,false,0x20,0xc7,512 ,300 ,5000,"BergMicro BG25Q20 256k"},
{true ,0xe0,0x40,0x11,true ,false,0x20,0xc7,256 ,300 ,5000,"BergMicro BG25Q10 128k"},
{true ,0x1f,0x01,0x86,true ,false,0x20,0xc7,4096 ,300 ,20000,"adesto AT25SF161 2MB "},
{true ,0x5e,0x60,0x12,true ,false,0x20,0xc7,512 ,300 ,5000,"ZB25VQ20 256KB "},
{true ,0x5e,0x60,0x13,true ,false,0x20,0xc7,1024 ,300 ,5000,"ZB25VQ40 512KB "},
{true ,0x68,0x40,0x12,true ,false,0x20,0xc7,512 ,300 ,30000,"BoHong BH25D20A 256KB "},
{true ,0x68,0x40,0x13,true ,false,0x20,0xc7,1024 ,300 ,30000,"BoHong BH25D40A 512KB "},
{false,0xff,0xff,0xff,false,false,0xff,0 ,0 ,0 ,0 ,"END OF TABLE "},
};
void Sleep(Word T) //delay 100uS
{
Word i,j,k;
if(McuGear == LOW_SPEED)
k = 3;
else
if(McuGear == MID_SPEED)
k = 12;
else
k = 32;
for(j=0;j<T;j++) udelay(100);
}
void Sdelay()
{
//Byte i;
// for(i=0;i<2;i++);
udelay(2);
}
void PulseDelay()
{
//Byte i;
//for(i=0;i<4;i++);
udelay(7);
}
void T_IIC_Start(void)
{
SET_SDA_L;//TSDA &= 0x7f;
PulseDelay();
SET_SCL_L;//TSCL &= 0x7f;
PulseDelay();
}
void T_IIC_Stop(void)
{
SET_SDA_L;//TSDA &= 0x7f;
PulseDelay();
SET_SCL_H;//TSCL |= 0x80;
PulseDelay();
SET_SDA_H;//TSDA |= 0x80;
PulseDelay();
}
Byte T_IIC_Tx(Byte Data)
{ //subroutine total time 630us
Byte AckLoop,Ack;
Byte i;
for(i=0;i<8;i++)
{
SET_SCL_L;//TSCL &= 0x7f;
udelay(5);
if(Data & BIT7)
SET_SDA_H;//TSDA |= 0x80;
else
SET_SDA_L;//TSDA &= 0x7f;
SET_SCL_H;//TSCL |= 0x80;
// TSCL = 0xff;
Data <<= 1;
udelay(5);
}
//
SET_SCL_L;//TSCL &= 0x7f;
udelay(2);
SET_SDA_H;//TSDA |= 0x80;
SET_SCL_H;//TSCL |= 0x80;
//RDSDA |= 0x80; //Input
SET_SDA_INPUT;
udelay(2);
for(AckLoop=0;AckLoop<40;AckLoop++) //300uS
{
udelay(5);
Ack = GET_SDA();//TSDA;//TSDA & 0x80;
// Ack &= ~pFail; //check ack & bypass fail channel
if(Ack == 0x00)
break;
}
SET_SDA_OUTPUT;
udelay(2);
//RDSDA &= 0x7f; //Output
SET_SCL_L;//TSCL &= 0x7f;
PulseDelay();
// send_asc("ack=",Ack);
return Ack; //return success=0 / failure=1
}
unsigned char T_IIC_Rx(Bit Ack)
{
Byte Temp,D1;
Byte i;
SET_SCL_L;//TSCL &= 0x0f;
SET_SDA_H;//TSDA |= 0xf0;
// RDSDA |= 0xf0;
SET_SDA_INPUT;
for(i=0;i<8;i++)
{
D1 <<= 1;
SET_SCL_L;//TSCL &= 0x7f;
udelay(5);
SET_SCL_H;//TSCL |= 0x80;
udelay(5);
Temp =GET_SDA() ;// TSDA;
//Temp = TSDA;
//Temp = TSDA;
if(Temp==1)
D1++;
}
//RDSDA &= 0x7f;
SET_SDA_OUTPUT;
SET_SCL_L;//TSCL &= 0x7f;
udelay(2);
if(Ack == ACK)
SET_SDA_L;//TSDA &= 0x7f;
else
SET_SDA_H;//TSDA |= 0x80;
SET_SCL_H;//TSCL |= 0x80;
SET_SCL_H;//TSCL |= 0x80;
SET_SCL_H;//TSCL |= 0x80;
udelay(2);
SET_SCL_L;//TSCL &= 0x7f;
udelay(2);
return D1;
}
void T_WaitSCL(void) //wait SCL all HI
{
Word i;
Byte Ck;
SET_SCL_H;//TSCL |= 0x80;
PulseDelay();
// RDSCL |= 0x80;
//for(i=0;i<1500;i++) //10ms
SET_SCL_INPUT;
for(i=0;i<1500;i++) //10ms
{
udelay(2);
Ck = GET_SCL();//TSCL;//TSCL & 0x80;
Ck |= pFail;
if(Ck == 1)//0x80)
break;
}
//RDSCL &= 0x7f;
SET_SCL_OUTPUT;
}
void T_HandShake(Word Timeout) //unit 1mS
{
Timer = Timeout*10; //timer count down
Sleep(3); //delay 300us
SET_SCL_INPUT;
while(Timer > 0)
{
if(GET_SCL()== 1) break; //Wait SCL == Hi
if(Timer>0) Timer--;
Sleep(1);
}
SET_SCL_OUTPUT;
if(Timer == 0){
ErrorFlag = 1;
debug("t shake error \n");
}
}
void send_sync(){
int i;
SET_SDA_OUTPUT;
SET_SCL_OUTPUT;
for(i=0;i<10;i++) {
SET_SDA_L;
PulseDelay();
SET_SCL_L;
PulseDelay();
PulseDelay();
SET_SCL_H;
PulseDelay();
SET_SDA_H;
PulseDelay();
}
mdelay(5);
udelay(400);
//for(i=0;i<5000;i++);
for(i=0;i<10;i++) {
SET_SDA_L;
PulseDelay();
SET_SCL_L;
PulseDelay();
PulseDelay();
PulseDelay();
PulseDelay();
SET_SCL_H;
PulseDelay();
SET_SDA_H;
PulseDelay();
}
}
void T_ISPMode(Bit On)
{
char ret;
T_IIC_Start();
ret=T_IIC_Tx(0x04);
T_WaitSCL(); //wait SCL go hi or delay >10uS
//
T_IIC_Start();
ret=T_IIC_Tx(0x34);
T_WaitSCL(); //wait SCL go hi or delay >10uS
//
T_IIC_Start();
ret=T_IIC_Tx(0x06);
T_WaitSCL(); //wait SCL go hi or delay >10uS
//
T_IIC_Start();
if(On)
T_IIC_Tx(0x36);
else
T_IIC_Tx(0x3c);
T_IIC_Stop();
}
void T_ISPStatusReply()
{
Byte ID_H,ID_L;
Byte d1,d2;
T_IIC_Start();
T_IIC_Tx(0x6f);
udelay(200);
//PulseDelay(); //delay >100uS for stability
d1=T_IIC_Rx(ACK);
ID_H = T_IIC_Rx(ACK);
ID_L = T_IIC_Rx(ACK);
d2=T_IIC_Rx(NACK);
T_IIC_Stop();
McuId = ID_H;
McuId <<= 8;
McuId |= ID_L;
debug("McuId==d1=%x d2=%x d3=%x d4=%x \n",d1,ID_H,ID_L,d2);
// debug("McuId===%x \n",McuId);
//send_int16("id=",McuId);
}
EXPORT_SYMBOL(T_ISPStatusReply);
Byte T_GetPageData(Byte PageNo)
{
Byte Ack,CheckSum;
T_IIC_Start();
Ack = T_IIC_Tx(0x6e);
T_IIC_Tx(0x02);
T_IIC_Tx(0x4b);
T_IIC_Tx(PageNo);
CheckSum = 0x6e^0x02^0x4b^PageNo;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
return Ack;
}
Byte T_ChipErase(void)
{
Byte Ack,CheckSum;
T_IIC_Start();
Ack = T_IIC_Tx(0x6e);
T_IIC_Tx(0x07);
T_IIC_Tx(comChipErase);
T_IIC_Tx(0xaa);
T_IIC_Tx(0x55);
T_IIC_Tx(0xcc);
T_IIC_Tx(0x33);
T_IIC_Tx(0xe2);
T_IIC_Tx(0x1d);
CheckSum = 0x6e^0x07^comChipErase^0xaa^0x55^0xcc^0x33^0xe2^0x1d;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
return Ack;
}
Byte T_ChipEraseReply(void)
{
Byte ReplyCode;
T_IIC_Start();
T_IIC_Tx(0x6f);
//PulseDelay(); //delay > 100us
Sleep(2);
T_IIC_Rx(ACK); //length, no used
ReplyCode = T_IIC_Rx(ACK); //status
T_IIC_Rx(NACK); //Checksum, no used
T_IIC_Stop();
debug("lizz T_ChipEraseReply=%x \n",ReplyCode);
if((ReplyCode^comChipErase) != 0xff)
ErrorFlag = 1;
return 0;
}
Byte T_BlockErase(Byte From,Byte To)
{
Byte Ack,CheckSum;
T_IIC_Start();
Ack = T_IIC_Tx(0x6e);
T_IIC_Tx(0x09);
T_IIC_Tx(comBlockErase);
T_IIC_Tx(0xaa);
T_IIC_Tx(0x55);
T_IIC_Tx(0xcc);
T_IIC_Tx(0x33);
T_IIC_Tx(0xe2);
T_IIC_Tx(0x1d);
T_IIC_Tx(From);
T_IIC_Tx(To);
CheckSum = 0x6e^0x09^comBlockErase^0xaa^0x55^0xcc^0x33^0xe2^0x1d^From^To;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
return Ack;
}
Byte T_BlockEraseReply(void)
{
Byte ReplyCode;
T_IIC_Start();
T_IIC_Tx(0x6f);
udelay(100);
//PulseDelay(); //delay > 100us
T_IIC_Rx(ACK); //length, no used
ReplyCode = T_IIC_Rx(ACK); //status
T_IIC_Rx(NACK); //Checksum, no used
T_IIC_Stop();
debug("T_BlockEraseReply==%x \n",ReplyCode);
if((ReplyCode^comBlockErase) != 0xff)
ErrorFlag = 1;
return 0;
}
Byte T_WritePagedata(Byte Pg)
{
Byte Ack,CheckSum;
Word i;
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x00);
T_IIC_Tx(comWritePage24M);
T_IIC_Tx(Pg);
T_IIC_Tx(0xf0);
T_IIC_Tx(0x0f);
T_IIC_Tx(0x6e);
T_IIC_Tx(0x91);
T_IIC_Tx(0x13);
T_IIC_Tx(0xec);
CheckSum = 0x6e^0x00^comWritePage24M^Pg^0xf0^0x0f^0x6e^0x91^0x13^0xec;
for(i=0;i<512;i++)
{
T_IIC_Tx(BinFilePageBuffer[i]);
CheckSum ^= BinFilePageBuffer[i];
}
T_IIC_Tx(CheckSum);
T_IIC_Stop();
return Ack;
}
void T_WritePageDataReply(void)
{
Byte ReplyCode;//Dummy,;
T_IIC_Start();
T_IIC_Tx(0x6f);
//PulseDelay(); //delay > 100us
Sleep(2);
T_IIC_Rx(ACK); //length
ReplyCode = T_IIC_Rx(ACK); //status
T_IIC_Rx(NACK); //Checksum
T_IIC_Stop();
//debug("T_WritePageDataReply=%x \n",ReplyCode);
if((ReplyCode^comWritePage24M) != 0xff)
ErrorFlag = 1;
}
void T_SetRegSRAM(Byte AddrH,Byte AddrL,Byte Data)
{
Byte CheckSum;
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x04);
T_IIC_Tx(comSetRegSRAM); //OP code = 0x78
T_IIC_Tx(AddrH);
T_IIC_Tx(AddrL);
T_IIC_Tx(Data);
CheckSum = 0x6e^0x04^comSetRegSRAM^AddrH^AddrL^Data;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
}
void T_SetRegSRAMReply()
{
Byte ReplyCode;
T_IIC_Start();
T_IIC_Tx(0x6f);
Sleep(1);//PulseDelay(); //delay >100uS for stability
T_IIC_Rx(ACK);
ReplyCode = T_IIC_Rx(ACK);
T_IIC_Rx(NACK);
T_IIC_Stop();
//debug("ReplyCode=%x \n",ReplyCode);
if((ReplyCode^comSetRegSRAM) != 0xff)
ErrorFlag = 1;
}
void T_GetVersion(void) //for Get Flash ID
{
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x01);
T_IIC_Tx(comGetVersion);
T_IIC_Tx(0x6e^0x01^0x11);
T_IIC_Stop();
}
void T_GetRegSRAM(Byte AddrH,Byte AddrL)
{
Byte CheckSum;
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x03);
T_IIC_Tx(comGetRegSRAM);
T_IIC_Tx(AddrH);
T_IIC_Tx(AddrL);
CheckSum = 0x6e^0x03^comGetRegSRAM^AddrH^AddrL;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
}
unsigned long T_GetRegSRAMReply(void)
{
Byte Status;
unsigned long Data;
T_IIC_Start();
T_IIC_Tx(0x6f);
//PulseDelay();
//PulseDelay();
Sleep(1);
T_IIC_Rx(ACK);
Status = T_IIC_Rx(ACK);
Data = T_IIC_Rx(ACK);
T_IIC_Rx(NACK);
T_IIC_Stop();
// debug("Status==%x \n",Status);
if((Status^comGetRegSRAM) != 0xff)
pFail |= TARGET0;
return Data;
}
Byte T_MultiFunc(Byte Data)
{
Byte ack;
T_IIC_Start();
ack = T_IIC_Tx(0x6e);
T_IIC_Tx(0x02);
T_IIC_Tx(comMultiFunc);
T_IIC_Tx(Data);
T_IIC_Tx(0x6E^0x02^comMultiFunc^Data);
T_IIC_Stop();
return ack;
}
void Cmd_T_EnterIsp(void)
{
Byte i;
send_sync();
for(i=0;i<1;i++)
{
T_ISPMode(1); //enter ISP mode
Sleep(1); //sleep >100us
T_ISPMode(1);
Sleep(100); //sleep >5ms
T_ISPStatusReply();
}
if(!ErrorFlag)
Cmd_T_SendSpecialCommand();
debug("ErrorFlag1==%x \n",ErrorFlag);
if(!ErrorFlag)
Cmd_T_GetFlashID();
debug("ErrorFlag2==%x \n",ErrorFlag);
if(!ErrorFlag)
WpEnable();
debug("ErrorFlag3==%x \n",ErrorFlag);
if(!ErrorFlag)
Cmd_T_BlockProtect(0);
debug("ErrorFlag4==%x \n",ErrorFlag);
//Cmd_T_BlockProtect0();
}
EXPORT_SYMBOL(Cmd_T_EnterIsp);
void SetSectorErasePage(Bool page)
{
if(page)
MultiID |= 0x08;
else
MultiID &= ~0x08;
T_MultiFunc(MultiID);
T_HandShake(10);
}
void BlockErase(Byte StartBlock, Byte EndBlock)
{
Byte TimeOutBlocks;
TimeOutBlocks = EndBlock-StartBlock;
if (TimeOutBlocks == 0)
TimeOutBlocks = 1; // this means only erase 1 sector, so we delay at least 1 sector time
debug("liz blockerase s=%d end=%d \n",StartBlock,EndBlock);
T_BlockErase(StartBlock,EndBlock);
Sleep(10*Flash.SE_Time*TimeOutBlocks);
T_BlockEraseReply();
}
void Cmd_T_Erase(void)
{
Word i, BlkStart, BlkEnd;
debug("Cmd_T_Erase=id=%x \n",McuId);
if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450)
Fn68390ProgramEnable(true);
debug("Fe2pMode==%x \n",Fe2pMode);
if (Fe2pMode == FE2P_MODE) {
debug("t1---\n");
for (i=0;i<Flash.Page/8;i+=16) //each block = 4k
{
BlkStart = i;
BlkEnd = (i+16)-2; //with FE2P, do not erase 60~64K
if (Flash.Page >= 4096) {
if (BlkStart < 256)
SetSectorErasePage(0);
else
SetSectorErasePage(1);
}
BlockErase(BlkStart,BlkEnd);
if (ErrorFlag)
break;
}
}
else if (Fe2pMode == DIRECT_FE2P_MODE) {
debug("t2---\n");
if (Flash.Page >= 4096) {
if (DirFE2P_Offset >= 256) {
//Erase first half 8M of 16M flash.
SetSectorErasePage(0);
BlockErase(0,255);
//Erase from 8M to DirFE2P_Offset.
SetSectorErasePage(1);
BlockErase(0,DirFE2P_Offset-1-256);
if (DirFE2P_Length) {
//Erase from DirFE2P_Offset+DirFE2P_Length to Flash End.
BlkStart = DirFE2P_Offset+DirFE2P_Length-256;
}
else {
//Erase from DirFE2P_Offset+4 to Flash End.
BlkStart = DirFE2P_Offset+4-256;
}
BlkEnd = Flash.Page/8 -1-256;
if(BlkEnd > BlkStart)
BlockErase(BlkStart,BlkEnd);
}
else {
//Erase from 0 to DirFE2P_Offset.
SetSectorErasePage(0);
BlockErase(0,DirFE2P_Offset-1);
if (DirFE2P_Length) {
BlkStart = DirFE2P_Offset+DirFE2P_Length; // DirFE2P_Length unit is 4k.
}
else {
BlkStart = DirFE2P_Offset+4;
}
BlockErase(BlkStart,255);
//Erase second half 8M of 16M flash.
SetSectorErasePage(1);
BlockErase(0,255);
}
}
else {
BlockErase(0,DirFE2P_Offset-1); //Erase all Flash data address < Offset
if (DirFE2P_Length) {
BlkStart = DirFE2P_Offset+DirFE2P_Length; // DirFE2P_Length unit is 4k.
}
else {
BlkStart = DirFE2P_Offset+4;
}
BlkEnd = Flash.Page/8 -1;
if (BlkEnd > BlkStart)
BlockErase(BlkStart,BlkEnd); //Erase all Flash data address > Offset
}
}
else if (DualFwEnable) {
debug("t3-page--==%d\n",Flash.Page);
// only erase Bottom/second half flash.
if (Flash.Page >= 4096) {
debug("t3--1--\n");
SetSectorErasePage(1);
BlockErase(0,255);
}
else {
debug("t3--2--p=%d \n",Flash.Page);
BlkStart = (Flash.Page/8)/2; // Mcu.Page/8 = how many sectors.
BlkEnd = (Flash.Page/8)-1;
BlockErase(BlkStart,BlkEnd);
}
}
else {
debug("t4---\n");
T_ChipErase();
//6seconds M25P20 erase time max<6sec
//5seconds w25x40b erase time max<4sec
T_HandShake(Flash.CE_Time);
Sleep(300*10);
T_ChipEraseReply();
}
if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450)
Fn68390ProgramEnable(false);
}
void Cmd_T_Program(Byte Pg)
{
T_WritePagedata(Pg);
T_HandShake(200); //Handshake time out 200mS, W25x40b program time 3ms x 2pages(256bytes)
T_WritePageDataReply();
}
Byte T_GetCheckSum(Byte PageNo)
{
Byte CheckSum;
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x02);
T_IIC_Tx(comGetCheckSum);
T_IIC_Tx(PageNo);
CheckSum = 0x6e^0x02^comGetCheckSum^PageNo;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
return 0;
}
Byte T_GetCheckSumReply(void)
{
Byte ReplyCode,ChkH,ChkL;
T_IIC_Start();
T_IIC_Tx(0x6f);
Sleep(3);
//PulseDelay(); //delay >100us
T_IIC_Rx(ACK); //length
ReplyCode = T_IIC_Rx(ACK); //length
ChkH = T_IIC_Rx(ACK); //checksum from scaler msb
ChkL = T_IIC_Rx(ACK); //checksum from scaler lsb
T_IIC_Rx(NACK);
T_IIC_Stop();
//debug("SPageSum==%x chk=%x \n",SPageSum,(ChkH*0x100+ChkL));
if(SPageSum != (Word)(ChkH*0x100+ChkL))
ErrorFlag = 1;
//debug("T_GetCheckSumReply==%x \n",ReplyCode);
if((ReplyCode^comGetCheckSum)!=0xFF)
ErrorFlag = 1;
return 0;
}
void T_SetExtendAddr(Byte Block)
{
Byte CheckSum;
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x02);
T_IIC_Tx(comSetExtendAddr); //op code =0x0f
T_IIC_Tx(Block);
CheckSum = 0x6e^0x02^comSetExtendAddr^Block;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
}
Byte T_SetExtendAddrReply()
{
Byte ReplyCode;
T_IIC_Start();
T_IIC_Tx(0x6f);
//PulseDelay(); //delay >100us
Sleep(3);
T_IIC_Rx(ACK);
ReplyCode = T_IIC_Rx(ACK);
T_IIC_Rx(ACK);
T_IIC_Rx(NACK);
T_IIC_Stop();
if((ReplyCode^comSetExtendAddr)!=0xFF)
ErrorFlag = 1;
return 0;
}
void Cmd_T_GetCheckSum(Byte Pg)
{
// debug("page-sum=%d \n",Pg);
T_GetCheckSum(Pg);
T_HandShake(200); //handshake timeout 200ms
T_GetCheckSumReply();
}
Byte Cmd_T_SetExntend(Word Pg)
{
if ((Pg%256) == 0 && (Pg/256) <= 15)
{
T_SetExtendAddr(Pg>>8);
Sleep(3); //delay > 300us
T_SetExtendAddrReply();
}
return 0;
}
Byte T_SpiCommand(Byte *Data,Byte WLen,Byte RLen)
{
Byte i;
Byte Length,chksum;
char tp[7];
memcpy(tp,Data,7);
Length = (RLen<<4) | WLen;
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x09);
T_IIC_Tx(0x53);
chksum = 0x6e^0x09^0x53;
for(i=0;i<7;i++)
{
T_IIC_Tx(*Data);
chksum ^= *Data;
Data++;
}
T_IIC_Tx(Length);
chksum ^= Length;
T_IIC_Tx(chksum);
T_IIC_Stop();
//for(i=0;i<7;i++) debug("d=%x \n",tp[i]);
//debug("Length=%x chksum=%x \n",Length,chksum);
return 0;
}
Byte T_SpiCommandReply()
{
Byte ReplyCode;
T_IIC_Start();
T_IIC_Tx(0x6f);
//PulseDelay(); //delay >100us
Sleep(2);
T_IIC_Rx(ACK);
ReplyCode = T_IIC_Rx(ACK);
T_IIC_Rx(NACK);
T_IIC_Stop();
debug("T_SpiCommandReply=%x r222=%x \n",ReplyCode,(ReplyCode^comSPICmd));
if((ReplyCode^comSPICmd)!=0xFF)
ErrorFlag = 1;
return 0;
}
void Cmd_T_SendSpecialCommand()
{
Byte i,No,temp;
Union2 Ad,Dat;
const Word NT_Table[]={
0xf054,0x00,
0xf04f,0x11,
0xf050,0x90,
0xf053,0x83,
0x8b57,0xff,
0x8b04,0x00,
0x80d0,0x41,
0x8b46,0x00,
0xf022,0x00,
0xf024,0x00,
0xf067,0x20, // SE command
0xf04c,0x40, //set scaler speed
};
const Word NT68370_380Table[] = {
0xf0de,0x23,0xf071,0x01,0xf054,0x00,0xf04f,0x11,0xf050,0x94,0xf053,0x83, 0x8b57,0xff,0x8b04,0x00,0x80d0,0x41,0x8b46,0x00,0xf022,0x00,0xf024,0x00,
};
const Word NT810_870Table[] = {
0xf054,0x00,0xf04f,0x11,0xf050,0x90,0xf053,0x83, 0x8b57,0xff,0x8b04,0x00,0x80d0,0x41,0xf022,0x00,0xf024,0x00, // don't set 0xB46 = 0x00
0xf050,0x91,
0x8b3e,0xf2,
0x8b3f,0x51,
0x8b45,0x60,
};
const int NT68390_Table[]={
0xf0de,0x23,
0xf1e0,0x01, // power down USB COP
0xf1e6,0x01, // power down OSD COP
0xf1eb,0x01, // power down DPTX COP
0xf054,0x00,
0xf04f,0x11,
0xf053,0x83,
0xf022,0x00,
0xf024,0x00,
0xf067,0x20, // SE command
0xd904,0xf6,
0xd905,0xd1,
0xd908,0x05,
0xd909,0x61,
0xd90a,0xff,
0xd90b,0x84,
0xd90c,0x30,
0xf054,0x00,
//0xd929,0x04, // speed up
};
debug("lizz McuId==%x \n",McuId);
if (McuId == 0xa515) {
T_SetRegSRAM(0xf0,0x80,0x00);
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
}
if (McuId == 0xA390 || McuId == 0xA400 || McuId == 0xA450) {
for(i=0;i<(sizeof(NT68390_Table)/sizeof(Word));i+=2)
{
Ad.w = NT68390_Table[i];
Dat.w = NT68390_Table[i+1];
T_SetRegSRAM(Ad.b[0],Ad.b[1],Dat.b[1]); //ex. AD.b[0]=0xf0,AD.b[1]=0x54,Dat.b[1]=0x00
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
if(ErrorFlag)
return;
}
// set NT68400 clock speed
T_SetRegSRAM(0xF0, 0x4C, 0x40);
T_HandShake(5);
T_SetRegSRAMReply();
T_HandShake(10);
T_SetRegSRAM(0xD9, 0x29, 0x04);
T_HandShake(5);
T_SetRegSRAMReply();
Sleep(500); // T_HandShake(50);
}
else if (McuId == 0xa537 || McuId == 0xa380) {
for(i=0;i<(sizeof(NT68370_380Table)/sizeof(Word));i+=2)
{
Ad.w = NT68370_380Table[i];
Dat.w = NT68370_380Table[i+1];
T_SetRegSRAM(Ad.b[0],Ad.b[1],Dat.b[1]); //ex. AD.b[0]=0xf0,AD.b[1]=0x54,Dat.b[1]=0x00
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
if(ErrorFlag)
return;
}
}
else if (McuId == 0xa810 || McuId == 0xa870) {
for(i=0;i<(sizeof(NT810_870Table)/sizeof(Word));i+=2)
{
Ad.w = NT810_870Table[i];
Dat.w = NT810_870Table[i+1];
T_SetRegSRAM(Ad.b[0],Ad.b[1],Dat.b[1]); //ex. AD.b[0]=0xf0,AD.b[1]=0x54,Dat.b[1]=0x00
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
if(ErrorFlag)
return;
}
}
else {
for(i=0;i<(sizeof(NT_Table)/sizeof(Word));i+=2)
{
Ad.w = NT_Table[i];
Dat.w = NT_Table[i+1];
T_SetRegSRAM(Ad.b[0],Ad.b[1],Dat.b[1]); //ex. AD.b[0]=0xf0,AD.b[1]=0x54,Dat.b[1]=0x00
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
if(ErrorFlag)
return;
}
}
}
#if 0
void Cmd_T_BlockProtect(Bit Wp)
{
Byte i,Cmd[7],sta;
for(i=0;i<7;i++)
Cmd[i] = 0;
/*if(Flash.ByteWrite) //SST Only
Cmd[0] = 0x50;
else
Cmd[0] = 0x06;
if(Wp)
sta = 0x9c;
else
sta = 0;*/
if(Wp){
Cmd[0] =0xaa;
Cmd[1] =0xaa;
Cmd[2] =0xa0;
Cmd[3] =0x55;
}
else {
Cmd[0] =0xaa;
Cmd[1] =0x2c;
Cmd[2] =0x02;
Cmd[3] =0x02;
}
T_SpiCommand(Cmd,1,0); //WEN
T_HandShake(20); //timeout 20mS
T_SpiCommandReply();
//Cmd[0] = 0x01;
//Cmd[1] = sta;
if(Wp) Cmd[0] =0x06;
else Cmd[0] =0x55;
T_SpiCommand(Cmd,1,0); //WRSR
T_HandShake(20); //timeout 20mS
T_SpiCommandReply();
//Sleep(1200); //delay 120mS for Flash block protect time
T_HandShake(Flash.SE_Time); //120mS
}
void Cmd_T_BlockProtect0(void)
{
Byte i,Cmd[7],sta;
for(i=0;i<7;i++)
Cmd[i] = 0;
Cmd[0] =0x06;
Cmd[1] =0x2c;
Cmd[2] =0x02;
Cmd[3] =0x02;
T_SpiCommand(Cmd,1,0); //WEN
T_HandShake(20); //timeout 20mS
T_SpiCommandReply();
Cmd[0] = 0x01;
Cmd[1] = 0x00;
T_SpiCommand(Cmd,2,0); //WRSR
T_HandShake(20); //timeout 20mS
T_SpiCommandReply();
//Sleep(1200); //delay 120mS for Flash block protect time
T_HandShake(Flash.SE_Time); //120mS
}
#else
void Cmd_T_BlockProtect(Bit Wp)
{
Byte i,Cmd[7],sta;
for(i=0;i<7;i++)
Cmd[i] = 0;
if(Flash.ByteWrite) //SST Only
Cmd[0] = 0x50;
else
Cmd[0] = 0x06;
if(Wp)
sta = 0x9c;
else
sta = 0;
T_SpiCommand(Cmd,1,0); //WEN
T_HandShake(20); //timeout 20mS
T_SpiCommandReply();
Cmd[0] = 0x01;
Cmd[1] = sta;
T_SpiCommand(Cmd,2,0); //WRSR
T_HandShake(20); //timeout 20mS
T_SpiCommandReply();
Sleep(1200); //delay 120mS for Flash block protect time
T_HandShake(Flash.SE_Time); //120mS
}
#endif
EXPORT_SYMBOL(Cmd_T_BlockProtect);
void T_RunNewSPICmd(void)
{
Byte CheckSum;
T_IIC_Start();
T_IIC_Tx(0x6e);
T_IIC_Tx(0x01);
T_IIC_Tx(0x25);
CheckSum = 0x6e^0x01^0x25;
T_IIC_Tx(CheckSum);
T_IIC_Stop();
}
void T_RunNewSPICmdReply(void)
{
Byte Status;
T_IIC_Start();
T_IIC_Tx(0x6f);
// PulseDelay();
//PulseDelay();
Sleep(3);
T_IIC_Rx(ACK);
Status = T_IIC_Rx(ACK);
T_IIC_Rx(NACK);
T_IIC_Stop();
if((Status^0x25) != 0xff)
ErrorFlag = 1;
}
void FnSetSPICmdBufAndBackUpValue()
{
Byte Dat, tmp, i;
T_HandShake(10);
T_GetRegSRAM(0xa0,0x00);
T_HandShake(5);
Dat = T_GetRegSRAMReply();
tmp = Dat;
T_SetRegSRAM(0xa0,0x00,0xaa);
T_HandShake(5);
T_SetRegSRAMReply();
T_HandShake(10);
T_GetRegSRAM(0xa0,0x00);
T_HandShake(5);
Dat = T_GetRegSRAMReply();
if (Dat == 0xaa) {
T_SetRegSRAM(0xa0,0x00,0x55);
T_HandShake(5);
T_SetRegSRAMReply();
T_HandShake(100);
T_GetRegSRAM(0xa0,0x00);
T_HandShake(5);
Dat = T_GetRegSRAMReply();
if (Dat == 0x55) {
usSPICmdBufAddr = 0xa800;
}
else
usSPICmdBufAddr = 0x9800;
}
else {
usSPICmdBufAddr = 0x9800;
}
T_SetRegSRAM(0xa0,0x00,0x55);
T_HandShake(5);
T_SetRegSRAMReply();
T_HandShake(10);
// back up f0c0~f0c6
for (i=0; i<sizeof(ucSPI_BackUpBuf); i++) {
T_GetRegSRAM(0xf0,0xc0+i);
T_HandShake(5);
Dat = T_GetRegSRAMReply();
ucSPI_BackUpBuf[i] = Dat;
//printf("%x ",(Word)Dat);
}
}
void RestoreSPIRegValue()
{
Byte i;
for (i=0; i<sizeof(ucSPI_BackUpBuf); i++) {
T_SetRegSRAM(0xf0,0xc0+i,ucSPI_BackUpBuf[i]);
T_HandShake(5);
T_SetRegSRAMReply();
T_HandShake(10);
}
}
Bool CheckSpecialFlash(void)
{
Byte WrtCntTab[16] = {0};
Byte WData[16] = {0};
Byte WrtCntTabLength = 0;
Byte WDataLength = 0;
Word SPI_Cmd_Buf_Addr = usSPICmdBufAddr;
Word TmpAddr;
Word i;
Byte F0C0_value, dummy;
Byte RData[16] = {0};
Byte Id;
Byte fID[3];
Byte ret;
// Setup write count table and write data sequence according to different flash spec.
// WrtCntTabLength and WDataLength will accumulate automatically.
WrtCntTab[WrtCntTabLength++] = 1;
WrtCntTab[WrtCntTabLength++] = 3;
WData[WDataLength++] = 0x9f;
TmpAddr = SPI_Cmd_Buf_Addr;
F0C0_value = (WrtCntTabLength/2)<<4|0x03;
T_SetRegSRAM(0xf0,0xc0,F0C0_value);
T_HandShake(5);
T_SetRegSRAMReply();
T_SetRegSRAM(0xf0,0xc1,SPI_Cmd_Buf_Addr>>8);
T_HandShake(5);
T_SetRegSRAMReply();
dummy = SPI_Cmd_Buf_Addr&0xFF;
T_SetRegSRAM(0xf0,0xc2,dummy);
T_HandShake(5);
T_SetRegSRAMReply();
T_SetRegSRAM(0xf0,0xc3,SPI_Cmd_Buf_Addr>>8);
T_HandShake(5);
T_SetRegSRAMReply();
dummy = (SPI_Cmd_Buf_Addr + WrtCntTabLength)&0xFF;
T_SetRegSRAM(0xf0,0xc4,dummy);
T_HandShake(5);
T_SetRegSRAMReply();
T_SetRegSRAM(0xf0,0xc5,SPI_Cmd_Buf_Addr>>8);
T_HandShake(5);
T_SetRegSRAMReply();
dummy = (SPI_Cmd_Buf_Addr + WrtCntTabLength + WDataLength)&0xFF;
T_SetRegSRAM(0xf0,0xc6,dummy);
T_HandShake(5);
T_SetRegSRAMReply();
for (i=0; i<WrtCntTabLength; i++) {
T_SetRegSRAM((Byte)(TmpAddr>>8),(Byte)TmpAddr,WrtCntTab[i]);
T_HandShake(5);
T_SetRegSRAMReply();
TmpAddr++;
}
for (i=0; i<WDataLength; i++) {
T_SetRegSRAM((Byte)(TmpAddr>>8),(Byte)TmpAddr,WData[i]);
T_HandShake(5);
T_SetRegSRAMReply();
TmpAddr++;
}
// send New SPI Command.
T_RunNewSPICmd();
T_HandShake(100);
T_RunNewSPICmdReply();
T_HandShake(200);
for (i=0; i<sizeof(RData); i++) {
T_GetRegSRAM((Byte)((SPI_Cmd_Buf_Addr+i)>>8),(Byte)(SPI_Cmd_Buf_Addr+i));
T_HandShake(5);
RData[i] = T_GetRegSRAMReply();
//printf("RData[%d]=%x\r\n", (Word)i, (Word)RData[i]);
}
// Read return data and identify which flash
// W25Q16DV flash
fID[0] = RData[WrtCntTabLength + WDataLength];
fID[1] = RData[WrtCntTabLength + WDataLength+1];
fID[2] = RData[WrtCntTabLength + WDataLength+2];
debug("lizz flash id1===%x id2=%x id3=%x \n",fID[0],fID[1],fID[2]);
Id = SearchFlashID(fID);
if(Id != 0xff)
{
Flash = FlashIDTable[Id]; //default flash PMC010A W/O fe2p
debug("lizz flash=%s \n",Flash.Name);
MaxPages = Flash.Page;
T_SetRegSRAM(0xf0,0x67,Flash.SE_Code);
T_HandShake(5);
T_SetRegSRAMReply();
//MultiID = 0x04; //MX2026 CMD if use this flash
MultiID = 0x00;
if(Flash.ByteWrite && ErrorFlag == 0)
MultiID |= 0x02;
ret = T_MultiFunc(MultiID); //Byte Write
T_HandShake(5);
return true;
}
return false;
}
Byte SearchFlashID(Byte *mcuFlashID)
{
Byte i,j;
Byte m1,m2,m3;
for(i=0;i<128;i++)
{
m1 = 0;
m2 = 0;
m3 = 0;
if(FlashIDTable[i].ID1 == 0xff)
break;
for(j=0;j<3;j++)
{
if(mcuFlashID[j] == FlashIDTable[i].ID1 && !m1)
m1 = 1;
else
if(mcuFlashID[j] == FlashIDTable[i].ID2 && !m2)
m2 = 1;
else
if(mcuFlashID[j] == FlashIDTable[i].ID3 && !m3)
m3 = 1;
}
if(FlashIDTable[i].ID3 == 0xff)
m3 = 1;
if(m1 && m2 && m3)
return i;
}
return 0xff;
}
void Cmd_T_GetFlashID()
{
Byte SPI_ID_Tab[]={0x90,0x9f,0xab};
Byte i,l,Id;
Byte Data;
Byte fID[3];
Word ret;
debug("lizz Cmd_T_GetFlashID=\n");
Flash.En = 0;
// use new spi command to get flash id
FnSetSPICmdBufAndBackUpValue();
if (CheckSpecialFlash()) {
RestoreSPIRegValue();
return;
}
RestoreSPIRegValue();
debug("lizz Cmd_T_GetFlashID=2===\n");
for(l=0;l<3;l++)
{
T_SetRegSRAM(0xf0,0x68,SPI_ID_Tab[l]);
T_HandShake(5);
T_SetRegSRAMReply();
if(ErrorFlag)
{
return;
}
T_GetVersion();
T_HandShake(20); //delay 20mS
for(i=0;i<3;i++)
{
T_GetRegSRAM(0xf0,0x64+i);
T_HandShake(5);
Data = T_GetRegSRAMReply();
if(ErrorFlag)
{
return;
}
fID[i] = Data;
if(fID[0] == 0x00 || fID[0] == 0xff)
break;
}
Id = SearchFlashID(fID);
debug("flashid=%x \n",Id);
if(Id != 0xff)
{
Flash = FlashIDTable[Id]; //default flash PMC010A W/O fe2p
MaxPages = Flash.Page;
T_SetRegSRAM(0xf0,0x67,Flash.SE_Code);
T_HandShake(5);
T_SetRegSRAMReply();
//MultiID = 0x04; //MX2026 CMD if used.
MultiID = 0x00;
if(Flash.ByteWrite && ErrorFlag == 0)
MultiID |= 0x02;
T_MultiFunc(MultiID); //Byte Write
T_HandShake(5);
return;
}
}
}
Bool CheckOverLap(Word PageNo)
{
ULong i,Offset;
if(Fe2pMode == DIRECT_FE2P_MODE)
{
Offset = DirFE2P_Offset*4096;
if (DirFE2P_Length) {
if((PageNo*512) >= Offset && (PageNo*512)<(Offset+DirFE2P_Length*4096))
return true;
}
else {
if((PageNo*512) >= Offset && (PageNo*512)<(Offset+16384)) //FE2P area max 16K
return true;
}
}
else if (Fe2pMode == FE2P_MODE) {
for(i=0;i<1024;i+=128) //max 512k 8*64K banks
{
if(PageNo > 119+i && PageNo <128+i)
return true;
}
}
return false;
}
void Fn68390ProgramEnable(Bit En)
{
Byte ret;
T_GetRegSRAM(0xF0,0xDE);
T_HandShake(5); //wait SCL go High for 5mS
ret = T_GetRegSRAMReply();
Sleep(100);
if (En) {
ret &= ~0x02;
T_SetRegSRAM(0xF0,0xDE,ret);
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
Sleep(20);
}
else {
ret |= 0x02;
T_SetRegSRAM(0xF0,0xDE,ret);
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
Sleep(20);
}
}
void WpEnable(void)
{
const unsigned short McuAddr[][3]={
{0xf005,0xf000,0xf0b0}, //PA
{0xf006,0xf001,0xf0b1}, //PB
{0xf007,0xf002,0xf0b2}, //PC
{0xf008,0xf003,0xf0b3}, //PD
{0xf009,0xf004,0xf0b4}, //PE
{0xf011,0xf010,0xf0b5}, //PF
{0xf012,0xf013,0xf0b6}, //PG
{0xf114,0xf115,0xf130}, //PH
{0xf116,0xf117,0xf131}, //PI
{0xf118,0xf119,0xf132}, //PJ
{0xf11A,0xf11B,0xf133}, //PK
{0xf11C,0xf11D,0xf134}, //PL
{0xf11E,0xf11F,0xf135}, //PM
};
Byte temp;
Byte Mask;
int i,j;
for (i=0;i<13;i++) {
if (i >= 5 && i <= 6) { // PortF, PortG
if (McuId != 0xa537 && McuId != 0xa380 && McuId != 0xa390 && McuId != 0xA400 && McuId != 0xA450)
break;
}
else if (i >=7) { // PortH~M
if (McuId != 0xa390 && McuId != 0xA400 && McuId != 0xA450)
break;
}
switch(i) {
case 0:
Mask = WpDefine >> 24; //PA7-0
Mask &= 0xff;
break;
case 1:
Mask = WpDefine >> 16; //PB7-0
Mask &= 0xff;
break;
case 2:
Mask = WpDefine >> 8; //PC7-0
Mask &= 0xff;
break;
case 3:
Mask = (Byte)WpDefine; //PD7-0
Mask &= 0xff;
break;
case 4:
Mask = Wp_PortE;
Mask &= 0xff;
break;
case 5:
Mask = Wp_PortF;
Mask &= 0xff;
break;
case 6:
Mask = (Byte)Wp_PortG_J; //PG7-0
Mask &= 0xff;
break;
case 7:
Mask = Wp_PortG_J >> 8; //PH7-0
Mask &= 0xff;
break;
case 8:
Mask = Wp_PortG_J >> 16; //PI7-0
Mask &= 0xff;
break;
case 9:
Mask = Wp_PortG_J >> 24; //PJ7-0
Mask &= 0xff;
break;
case 10:
Mask = (Byte)Wp_PortK_M; //PK7-0
Mask &= 0xff;
break;
case 11:
Mask = Wp_PortK_M >> 8; //PL7-0
Mask &= 0xff;
break;
case 12:
Mask = Wp_PortK_M >> 16; //PM7-0
Mask &= 0xff;
break;
};
for (j=0;j<3;j++) {
T_GetRegSRAM(McuAddr[i][j]>>8,(Byte)McuAddr[i][j]);
T_HandShake(5); //wait SCL go High for 5mS
temp = T_GetRegSRAMReply();
Sleep(100);
if(j == 0) //Port direction
temp &= ~Mask;
else
if(j == 1) // Port Hi/Lo
{
temp |= Mask;
}
else
if(j == 2) //Port struct
temp |= Mask;
T_SetRegSRAM(McuAddr[i][j]>>8,(Byte)McuAddr[i][j],temp);
T_HandShake(5); //wait SCL go High for 5mS
T_SetRegSRAMReply();
Sleep(20);
}
}
}
void FnEraseIDSector(void)
{
Word SectorNo;
SectorNo = (0xEFF0/4096); // make ID string address as sector unit.
if (Flash.Page >= 4096) {
SetSectorErasePage(0);
BlockErase(SectorNo,SectorNo);
}
else {
BlockErase(SectorNo,SectorNo);
}
}
Bit FnUpdateIDSector(void)
{
Byte Data[512];
Word Checksum=0;
Word i,IDPageNo;
IDPageNo = (0xEFF0/512); // make ID string address as page unit.
//backup bin buffer then update data
for (i=0;i<512;i++) {
Data[i] = BinFilePageBuffer[i];
BinFilePageBuffer[i] = 0xff;
}
// copy ID to the buffer
BinFilePageBuffer[0x1F0] = 'D';
BinFilePageBuffer[0x1F1] = 'U';
BinFilePageBuffer[0x1F2] = 'A';
BinFilePageBuffer[0x1F3] = 'L';
BinFilePageBuffer[0x1F4] = 'F';
BinFilePageBuffer[0x1F5] = 'W';
// set flash bank number
BinFilePageBuffer[0x1F6] = Flash.Page/128;
// calculate checksum
for (i=0;i<512;i++) {
Checksum += BinFilePageBuffer[i];
}
SPageSum = Checksum;
Fn68390ProgramEnable(true);
Cmd_T_SetExntend(0);
if(ErrorFlag == 0)
{
Cmd_T_Program(IDPageNo);
if(ErrorFlag) {
Fn68390ProgramEnable(false);
// restore buffer
for (i=0;i<512;i++) {
BinFilePageBuffer[i] = Data[i];
}
return false;
}
Cmd_T_GetCheckSum(IDPageNo);
if(ErrorFlag) {
Fn68390ProgramEnable(false);
// restore buffer
for (i=0;i<512;i++) {
BinFilePageBuffer[i] = Data[i];
}
return false;
}
}
Fn68390ProgramEnable(false);
// restore buffer
for (i=0;i<512;i++) {
BinFilePageBuffer[i] = Data[i];
}
return true;
}
void exit_isp(void ){
Cmd_T_BlockProtect(1);
T_ISPMode(0); //exit ISP mode
}
EXPORT_SYMBOL(exit_isp);
struct rk_screen * rk_get_screen(void);
void ISP_Process(void)
{
Word Page,i;
Bit SkipPage;
ErrorFlag = 0;
// Must initial fe2p related settings
Fe2pMode = NORMAL_MODE;
DirFE2P_Offset = 0;
DirFE2P_Length = 0;
DualFwEnable =0;// 1; // if adopt dual f/w, need to set as 1, otherwise set as 0.
struct file *file = NULL;
char *path="/etc/1920.bin";
mm_segment_t old_fs;
ssize_t ret;
char *bin_buf;
bin_buf = kmalloc(128*1024, GFP_KERNEL);
//memset(eth_mac, 0, 6);
struct rk_screen *screen=NULL;
screen=rk_get_screen();
printk("x=%d y=%d \n",screen->mode.xres,screen->mode.yres);
printk("screen->face=%d screen->lvds_format=%d \n",screen->face,screen->lvds_format);
if(screen->mode.xres==1920&&screen->mode.yres==1080){
if(screen->face==1){ //6bit
path="/etc/1920-6bit.bin";
}
else {
if(screen->lvds_format==0) path="/etc/1920.bin";
else if(screen->lvds_format==1) path="/etc/1920-2.bin";
}
}
else if(screen->mode.xres==1366&&screen->mode.yres==768){
path="/etc/1366.bin";
}
else if(screen->mode.xres==1280&&screen->mode.yres==1024){
path="/etc/1280x1024.bin";
}
//file = filp_open("/system/etc/1920.bin", O_RDWR|O_CREAT,0644);
file = filp_open(path, O_RDWR|O_CREAT,0644);
if (IS_ERR(file))
{
printk("open failed.");
return -ENOENT;
}
old_fs = get_fs();
set_fs(get_ds());
file->f_op->llseek(file,0,0);
ret = file->f_op->read(file, bin_buf, 128*1024, &file->f_pos);
set_fs(old_fs);
if(ret > 0){
#if 0
int n;
printk("--start---\n");
for (n= 0;n< 128*1024;n++){
if(n%16==0) printk("%08x ",n);
printk("%02x ",bin_buf[n]);
if(n%16==15) printk("\n");
}
printk("--end---\n");
#endif
}
filp_close(file,NULL);
debug("lizz isp1111\n");
gpio_request(SCL_PIN, NULL);
gpio_request(SDA_PIN, NULL);
SET_SCL_L;//write_data(sda, 0);
udelay(6);
SET_SCL_L;//write_data(scl, 0);
udelay(14);
// stop
SET_SCL_H;//write_data(sda, 1);
udelay(6);
SET_SCL_H;//write_data(scl, 1);
udelay(20);
//Set HOST IIC to <=70KHz
Cmd_T_EnterIsp();
//Speed up HOST IIC to 300~400KHz
//send_asc("ErrorFlag==",ErrorFlag);
debug("ErrorFlag==%x \n",ErrorFlag);
if(ErrorFlag)
goto end;
debug("lizz isp222\n");
if (DualFwEnable)
FnEraseIDSector();
Cmd_T_Erase();
debug("lizz isp333\n");
debug("ErrorFlag5==%x \n",ErrorFlag);
if(ErrorFlag)
goto end;
MaxPages = Flash.Page;
if (DualFwEnable) {
CodePages = MaxPages/2;
FlashOffset = MaxPages/2;
}
else {
CodePages = MaxPages;
FlashOffset = 0;
}
//send_int16("McuId===",McuId);
debug("McuId==%x \n",McuId);
debug("lizz isp444\n");
if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450)
Fn68390ProgramEnable(true);
for(Page=FlashOffset;Page<(CodePages+FlashOffset);Page++) // 1024pages for 4M flash
{
int cnt=Page;
cnt%=256;
cnt*=512;
printk("Page=%d \n",Page);
memcpy(BinFilePageBuffer,bin_buf+cnt,512);
Cmd_T_SetExntend(Page);
if(ErrorFlag)
goto end;
SPageSum = 0; //bin file page checksum
SkipPage = 1;
for(i=0;i<512;i++)
{
//binFilePageBuffer is use for binary file page buffer, size is 512bytes
if(BinFilePageBuffer[i] != 0xff) //not empty
SkipPage = 0;
SPageSum += BinFilePageBuffer[i]; //calculate binary file page checksum
}
//debug("lizz isp555\n");
if (CheckOverLap(Page))
SkipPage = 1;
if(!SkipPage) //Bypass program?
Cmd_T_Program(Page);
if(ErrorFlag){
debug("Cmd_T_Program err \n");
goto end;
}
//debug("lizz isp666\n");
if(!SkipPage) //Bypass compare?
Cmd_T_GetCheckSum(Page);
if(ErrorFlag){
debug("Cmd_T_GetCheckSum err \n");
goto end;
}
}
debug("lizz isp777\n");
if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450)
Fn68390ProgramEnable(false);
debug("lizz isp888\n");
if (DualFwEnable) {
if (FnUpdateIDSector() == false)
goto end;
}
debug("lizz isp9999\n");
end:
kfree(bin_buf);
debug("lizz ispeeeeeeeeeee-end--\n");
Cmd_T_BlockProtect(1);
T_ISPMode(0); //exit ISP mode and reset
}
EXPORT_SYMBOL(ISP_Process);
\sdk\kernel\drivers\video\backlight\pwm_bl.c

sdk\kernel\drivers\char\ir_drv.c



本文介绍了如何在RK3128设备上配置Android7.1系统,结合NT6866芯片将HDMI信号转换为LVDS。主要涉及的步骤包括理解NT6866芯片功能,将.bin文件拷贝到系统ETC路径,并在rockchip-hdmi相关的驱动源码中加载文件,如rockchip-hdmi-core.c、rockchip-hdmi-lcdc.c和pwm_bl.c等。

5308

被折叠的 条评论
为什么被折叠?



