blob: 29642be594de972f5ad75ccea86a8ee6a0bda932 [file] [log] [blame]
//--------------------------------------------------------
//
//
// Melfas MCS8000 Series Download base v1.0 2010.04.05
//
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include "mcs8000_download.h"
//============================================================
//
// Include MELFAS Binary code File ( ex> MELFAS_FIRM_bin.c)
//
// Warning!!!!
// Please, don't add binary.c file into project
// Just #include here !!
//
//============================================================
UINT16 binary_nLength;
UINT8 *binary;
/******************************************/
UINT16 Firmware_Data_nLength_HW0 =
#if defined(CONFIG_TOUCHSCREEN_MMS128_COOPERVE)
0x7328;
#elif defined(CONFIG_TOUCHSCREEN_MMS128_TASSVE)
0x7704;
#endif
UINT16 Firmware_Data_nLength_HW1 =
#if defined(CONFIG_TOUCHSCREEN_MMS128_COOPERVE)
0x7458;
#elif defined(CONFIG_TOUCHSCREEN_MMS128_TASSVE)
0x00;
#endif
/******************************************/
UINT8 Firmware_Data_HW0[]=
{
#if defined(CONFIG_TOUCHSCREEN_MMS128_COOPERVE)
#include "MCS8000_bin_cooperve09_hw00.c"
#elif defined(CONFIG_TOUCHSCREEN_MMS128_TASSVE)
#include "MCS8000_bin_tassve_hw00.c"
#endif
};
UINT8 Firmware_Data_HW1[]=
{
#if defined(CONFIG_TOUCHSCREEN_MMS128_COOPERVE)
#include "MCS8000_bin_cooperve10_hw01.c"
#elif defined(CONFIG_TOUCHSCREEN_MMS128_TASSVE)
NULL
#endif
};
/******************************************/
void mcsdl_select_binary_data(int hw_ver)
{
if (hw_ver==0x00)
{
binary_nLength = Firmware_Data_nLength_HW0;
binary = Firmware_Data_HW0;
}
else if(hw_ver==0x01)
{
binary_nLength = Firmware_Data_nLength_HW1;
binary = Firmware_Data_HW1;
}
}
UINT8 ucVerifyBuffer[MELFAS_TRANSFER_LENGTH]; // You may melloc *ucVerifyBuffer instead of this
//---------------------------------
// Downloading functions
//---------------------------------
//static int mcsdl_download(const UINT8 *pData, const UINT16 nLength, INT8 IdxNum);
static int mcsdl_download(UINT8 *pData, UINT16 nLength, INT8 IdxNum);
static void mcsdl_set_ready(void);
static void mcsdl_reboot_mcs(void);
static int mcsdl_erase_flash(INT8 IdxNum);
static int mcsdl_program_flash(UINT8 *pDataOriginal, UINT16 unLength, INT8 IdxNum);
static void mcsdl_program_flash_part(UINT8 *pData);
static int mcsdl_verify_flash(UINT8 *pData, UINT16 nLength, INT8 IdxNum);
static void mcsdl_read_flash(UINT8 *pBuffer);
static int mcsdl_read_flash_from(UINT8 *pBuffer, UINT16 unStart_addr, UINT16 unLength, INT8 IdxNum);
static void mcsdl_select_isp_mode(UINT8 ucMode);
static void mcsdl_unselect_isp_mode(void);
static void mcsdl_read_32bits(UINT8 *pData);
static void mcsdl_write_bits(UINT32 wordData, int nBits);
static void mcsdl_scl_toggle_twice(void);
//---------------------------------
// For debugging display
//---------------------------------
#if MELFAS_ENABLE_DBG_PRINT
static void mcsdl_print_result(int nRet);
#endif
//----------------------------------
// Download enable command
//----------------------------------
#if MELFAS_USE_PROTOCOL_COMMAND_FOR_DOWNLOAD
void melfas_send_download_enable_command(void)
{
// TO DO : Fill this up
}
#endif
//============================================================
//
// Main Download furnction
//
// 1. Run mcsdl_download( pBinary[IdxNum], nBinary_length[IdxNum], IdxNum);
// IdxNum : 0 (Master Chip Download)
// IdxNum : 1 (2Chip Download)
//
//
//============================================================
int mcsdl_download_binary_data(INT32 hw_ver)
{
int nRet;
#if MELFAS_USE_PROTOCOL_COMMAND_FOR_DOWNLOAD
melfas_send_download_enable_command();
mcsdl_delay(MCSDL_DELAY_100US);
#endif
MELFAS_DISABLE_BASEBAND_ISR(); // Disable Baseband touch interrupt ISR.
MELFAS_DISABLE_WATCHDOG_TIMER_RESET(); // Disable Baseband watchdog timer
mcsdl_select_binary_data(hw_ver);
//------------------------
// Run Download
//------------------------
#if 1 //0905 SEC
nRet = mcsdl_download((const UINT8*) binary, (const UINT16)binary_nLength , 0);
#if MELFAS_2CHIP_DOWNLOAD_ENABLE
nRet = mcsdl_download((const UINT8*) binary, (const UINT16)binary_nLength, 1); // Slave Binary data download
#endif
#else
nRet = mcsdl_download((const UINT8*) MELFAS_binary, (const UINT16)MELFAS_binary_nLength , 0);
#if MELFAS_2CHIP_DOWNLOAD_ENABLE
nRet = mcsdl_download((const UINT8*) MELFAS_binary_2, (const UINT16)MELFAS_binary_nLength_2, 1); // Slave Binary data download
#endif
#endif
MELFAS_ROLLBACK_BASEBAND_ISR(); // Roll-back Baseband touch interrupt ISR.
MELFAS_ROLLBACK_WATCHDOG_TIMER_RESET(); // Roll-back Baseband watchdog timer
return (nRet == MCSDL_RET_SUCCESS);
}
int mcsdl_download_binary_file(void)
{
int nRet;
int i;
UINT8 *pBinary[2] = {NULL, NULL};
UINT16 nBinary_length[2] = {0, 0};
UINT8 IdxNum = MELFAS_2CHIP_DOWNLOAD_ENABLE;
//==================================================
//
// 1. Read '.bin file'
// 2. *pBinary[0] : Binary data(Master)
// *pBinary[1] : Binary data(Slave)
// nBinary_length[0] : Firmware size(Master)
// nBinary_length[1] : Firmware size(Slave)
// 3. Run mcsdl_download( pBinary[IdxNum], nBinary_length[IdxNum], IdxNum);
// IdxNum : 0 (Master Chip Download)
// IdxNum : 1 (2Chip Download)
//
//==================================================
#if 0
// TO DO : File Process & Get file Size(== Binary size)
// This is just a simple sample
FILE *fp;
INT nRead;
//------------------------------
// Open a file
//------------------------------
if (fopen(fp, "MELFAS_FIRMWARE.bin", "rb") == NULL)
{
return MCSDL_RET_FILE_ACCESS_FAILED;
}
//------------------------------
// Get Binary Size
//------------------------------
fseek(fp, 0, SEEK_END);
nBinary_length = (UINT16)ftell(fp);
//------------------------------
// Memory allocation
//------------------------------
pBinary = (UINT8*)malloc((INT)nBinary_length);
if (pBinary == NULL)
{
return MCSDL_RET_FILE_ACCESS_FAILED;
}
//------------------------------
// Read binary file
//------------------------------
fseek(fp, 0, SEEK_SET);
nRead = fread(pBinary, 1, (INT)nBinary_length, fp); // Read binary file
if (nRead != (INT)nBinary_length)
{
fclose(fp); // Close file
if (pBinary != NULL) // free memory alloced.
free(pBinary);
return MCSDL_RET_FILE_ACCESS_FAILED;
}
//------------------------------
// Close file
//------------------------------
fclose(fp);
#endif
#if MELFAS_USE_PROTOCOL_COMMAND_FOR_DOWNLOAD
melfas_send_download_enable_command();
mcsdl_delay(MCSDL_DELAY_100US);
#endif
MELFAS_DISABLE_BASEBAND_ISR(); // Disable Baseband touch interrupt ISR.
MELFAS_DISABLE_WATCHDOG_TIMER_RESET(); // Disable Baseband watchdog timer
for (i = 0;i <= IdxNum;i++)
{
if (pBinary[i] != NULL && nBinary_length[i] > 0 && nBinary_length[i] < 32*1024)
{
//------------------------
// Run Download
//------------------------
nRet = mcsdl_download((const UINT8 *)pBinary[i], (const UINT16)nBinary_length[i], i);
}
else
{
nRet = MCSDL_RET_WRONG_BINARY;
}
}
MELFAS_ROLLBACK_BASEBAND_ISR(); // Roll-back Baseband touch interrupt ISR.
MELFAS_ROLLBACK_WATCHDOG_TIMER_RESET(); // Roll-back Baseband watchdog timer
#if MELFAS_ENABLE_DBG_PRINT
mcsdl_print_result(nRet);
#endif
return (nRet == MCSDL_RET_SUCCESS);
}
//------------------------------------------------------------------
//
// Download function
//
//------------------------------------------------------------------
//static int mcsdl_download(const UINT8 *pBianry, const UINT16 unLength, INT8 IdxNum)
static int mcsdl_download(UINT8 *pBianry, UINT16 unLength, INT8 IdxNum)
{
int i;
int nRet;
UINT8 Check_IC = 0xFF; // d.model
UINT8 readBuffer[32];
UINT8 writeBuffer[4];
UINT32 wordData;
//---------------------------------
// Check Binary Size
//---------------------------------
if (unLength >= MELFAS_FIRMWARE_MAX_SIZE)
{
nRet = MCSDL_RET_PROGRAM_SIZE_IS_WRONG;
goto MCSDL_DOWNLOAD_FINISH;
}
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" - Starting download...\n");
#endif
//---------------------------------
// Make it ready
//---------------------------------
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" > Ready\n");
#endif
mcsdl_set_ready();
mcsdl_delay(MCSDL_DELAY_1MS);
//--------------------------------------------------------------
// IC Information read from Flash
//--------------------------------------------------------------
#if 0
if (IdxNum == 0)
{
mcsdl_select_isp_mode(ISP_MODE_SERIAL_READ);
wordData = ((0x1F00 & 0x1FFF) << 1) | 0x0;
wordData <<= 14;
mcsdl_write_bits(wordData, 18);
mcsdl_read_flash(readBuffer);
MCSDL_GPIO_SDA_SET_LOW();
MCSDL_GPIO_SDA_SET_OUTPUT(0);
mcsdl_unselect_isp_mode();
//if (readBuffer[3] != 0xFF)
Check_IC = readBuffer[3];
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk("\IC Information :0x%02X, 0x%02X\n", readBuffer[3], Check_IC);
#endif
mcsdl_delay(MCSDL_DELAY_1MS);
}
#endif
//---------------------------------
// Erase Flash
//---------------------------------
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" > Erase\n");
#endif
nRet = mcsdl_erase_flash(IdxNum);
if (nRet != MCSDL_RET_SUCCESS)
goto MCSDL_DOWNLOAD_FINISH;
#if 0
mcsdl_delay(MCSDL_DELAY_1MS);
//--------------------------------------------------------------
// IC Information write
//--------------------------------------------------------------
if (IdxNum == 0)
{
mcsdl_select_isp_mode(ISP_MODE_SERIAL_WRITE);
wordData = ((0x1F00 & 0x1FFF) << 1) | 0x0 ;
wordData = wordData << 14;
mcsdl_write_bits(wordData, 18);
writeBuffer[0] = Check_IC;
writeBuffer[1] = 0xFF;
writeBuffer[2] = 0xFF;
writeBuffer[3] = 0xFF;
mcsdl_program_flash_part(writeBuffer);
//---------------------------------------------
// Tail
//---------------------------------------------
MCSDL_GPIO_SDA_SET_HIGH();
mcsdl_delay(MCSDL_DELAY_40US);
for (i = 0; i < 6; i++)
{
if (i == 2)
{
mcsdl_delay(MCSDL_DELAY_20US);
}
else if (i == 3)
{
mcsdl_delay(MCSDL_DELAY_40US);
}
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_10US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_10US);
}
MCSDL_GPIO_SDA_SET_LOW();
mcsdl_unselect_isp_mode();
mcsdl_delay(MCSDL_DELAY_1MS);
}
#endif
//---------------------------------
// Program Flash
//---------------------------------
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" > Program ");
#endif
nRet = mcsdl_program_flash((UINT8*)pBianry, (UINT16)unLength, IdxNum);
if (nRet != MCSDL_RET_SUCCESS)
goto MCSDL_DOWNLOAD_FINISH;
mcsdl_delay(MCSDL_DELAY_1MS);
//---------------------------------
// Verify flash
//---------------------------------
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" > Verify ");
#endif
nRet = mcsdl_verify_flash((UINT8*)pBianry, (UINT16)unLength, IdxNum);
if( nRet != MCSDL_RET_SUCCESS ) {
nRet = mcsdl_verify_flash( (UINT8*)pBianry, (UINT16)unLength, IdxNum );
if( nRet != MCSDL_RET_SUCCESS ) {
nRet = mcsdl_verify_flash( (UINT8*)pBianry, (UINT16)unLength, IdxNum );
if( nRet != MCSDL_RET_SUCCESS )
goto MCSDL_DOWNLOAD_FINISH;
}
}
mcsdl_delay(MCSDL_DELAY_1MS);
nRet = MCSDL_RET_SUCCESS;
MCSDL_DOWNLOAD_FINISH :
#if MELFAS_ENABLE_DBG_PRINT
mcsdl_print_result(nRet); // Show result
#endif
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" > Rebooting\n");
printk(" - Fin.\n\n");
#endif
mcsdl_reboot_mcs();
return nRet;
}
//------------------------------------------------------------------
//
// Sub functions
//
//------------------------------------------------------------------
static int mcsdl_erase_flash(INT8 IdxNum)
{
int i;
UINT8 readBuffer[32];
int eraseCompareValue = 0xFF;
//----------------------------------------
// Do erase
//----------------------------------------
if (IdxNum > 0)
{
mcsdl_select_isp_mode(ISP_MODE_NEXT_CHIP_BYPASS);
mcsdl_delay(MCSDL_DELAY_3US);
}
mcsdl_select_isp_mode(ISP_MODE_ERASE_FLASH);
mcsdl_unselect_isp_mode();
//----------------------------------------
// Check 'erased well'
//----------------------------------------
#if 0
mcsdl_read_flash_from(readBuffer, 0x0000, 16, IdxNum);
mcsdl_read_flash_from(&readBuffer[16], 0x7FF0, 16, IdxNum);
// Compare with '0xFF'
if (IdxNum > 0)
{
eraseCompareValue = 0x00;
}
for (i = 0; i < 32; i++)
{
if (readBuffer[i] != eraseCompareValue)
return MCSDL_RET_ERASE_FLASH_VERIFY_FAILED;
}
#endif
return MCSDL_RET_SUCCESS;
}
static int mcsdl_program_flash(UINT8 *pDataOriginal, UINT16 unLength, INT8 IdxNum)
{
int i;
UINT8 *pData;
UINT8 ucLength;
UINT16 addr;
UINT32 header;
addr = 0;
pData = pDataOriginal;
ucLength = MELFAS_TRANSFER_LENGTH;
while ((addr*4) < (int)unLength)
{
if ((unLength - (addr*4)) < MELFAS_TRANSFER_LENGTH)
{
ucLength = (UINT8)(unLength - (addr * 4));
}
//--------------------------------------
// Select ISP Mode
//--------------------------------------
mcsdl_delay(MCSDL_DELAY_40US);
if (IdxNum > 0)
{
mcsdl_select_isp_mode(ISP_MODE_NEXT_CHIP_BYPASS);
mcsdl_delay(MCSDL_DELAY_3US);
}
mcsdl_select_isp_mode(ISP_MODE_SERIAL_WRITE);
//---------------------------------------------
// Header
// Address[13ibts] <<1
//---------------------------------------------
header = ((addr & 0x1FFF) << 1) | 0x0 ;
header = header << 14;
mcsdl_write_bits(header, 18); //Write 18bits
//---------------------------------
// Writing
//---------------------------------
//addr += (UINT16)ucLength;
addr += 1;
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk("#");
#endif
mcsdl_program_flash_part(pData);
pData += ucLength;
//---------------------------------------------
// Tail
//---------------------------------------------
MCSDL_GPIO_SDA_SET_HIGH();
mcsdl_delay(MCSDL_DELAY_40US);
for (i = 0; i < 6; i++)
{
if (i == 2)
{
mcsdl_delay(MCSDL_DELAY_20US);
}
else if (i == 3)
{
mcsdl_delay(MCSDL_DELAY_40US);
}
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_10US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_10US);
}
MCSDL_GPIO_SDA_SET_LOW();
mcsdl_unselect_isp_mode();
mcsdl_delay(MCSDL_DELAY_300US);
}
return MCSDL_RET_SUCCESS;
}
static void mcsdl_program_flash_part(UINT8 *pData)
{
int i;
UINT32 data;
//---------------------------------
// Body
//---------------------------------
data = (UINT32)pData[0] << 0;
data |= (UINT32)pData[1] << 8;
data |= (UINT32)pData[2] << 16;
data |= (UINT32)pData[3] << 24;
mcsdl_write_bits(data, 32);
}
static int mcsdl_verify_flash(UINT8 *pDataOriginal, UINT16 unLength, INT8 IdxNum)
{
int i, j;
int nRet;
UINT8 *pData;
UINT8 ucLength;
UINT16 addr;
UINT32 wordData;
addr = 0;
pData = (UINT8 *) pDataOriginal;
ucLength = MELFAS_TRANSFER_LENGTH;
while ((addr*4) < (int)unLength)
{
if ((unLength - (addr*4)) < MELFAS_TRANSFER_LENGTH)
{
ucLength = (UINT8)(unLength - (addr * 4));
}
// start ADD DELAY
mcsdl_delay(MCSDL_DELAY_40US);
//--------------------------------------
// Select ISP Mode
//--------------------------------------
if (IdxNum > 0)
{
mcsdl_select_isp_mode(ISP_MODE_NEXT_CHIP_BYPASS);
mcsdl_delay(MCSDL_DELAY_3US);
}
mcsdl_select_isp_mode(ISP_MODE_SERIAL_READ);
//---------------------------------------------
// Header
// Address[13ibts] <<1
//---------------------------------------------
wordData = ((addr & 0x1FFF) << 1) | 0x0;
wordData <<= 14;
mcsdl_write_bits(wordData, 18);
addr += 1;
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk("#");
#endif
//--------------------
// Read flash
//--------------------
mcsdl_read_flash(ucVerifyBuffer);
MCSDL_GPIO_SDA_SET_LOW();
MCSDL_GPIO_SDA_SET_OUTPUT(0);
//--------------------
// Comparing
//--------------------
if (IdxNum == 0)
{
for (j = 0; j < (int)ucLength; j++)
{
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" %02X", ucVerifyBuffer[j]);
#endif
if (ucVerifyBuffer[j] != pData[j])
{
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk("\n [Error] Address : 0x%04X : 0x%02X - 0x%02X\n", addr, pData[j], ucVerifyBuffer[j]);
#endif
nRet = MCSDL_RET_PROGRAM_VERIFY_FAILED;
goto MCSDL_VERIFY_FLASH_FINISH;
}
}
}
else // slave
{
for (j = 0; j < (int)ucLength; j++)
{
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" %02X", ucVerifyBuffer[j]);
#endif
if ((0xff - ucVerifyBuffer[j]) != pData[j])
{
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk("\n [Error] Address : 0x%04X : 0x%02X - 0x%02X\n", addr, pData[j], ucVerifyBuffer[j]);
#endif
nRet = MCSDL_RET_PROGRAM_VERIFY_FAILED;
goto MCSDL_VERIFY_FLASH_FINISH;
}
}
}
pData += ucLength;
mcsdl_unselect_isp_mode();
}
nRet = MCSDL_RET_SUCCESS;
MCSDL_VERIFY_FLASH_FINISH:
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk("\n");
#endif
mcsdl_unselect_isp_mode();
return nRet;
}
static void mcsdl_read_flash(UINT8 *pBuffer)
{
int i;
MCSDL_GPIO_SCL_SET_LOW();
MCSDL_GPIO_SDA_SET_LOW();
mcsdl_delay(MCSDL_DELAY_40US);
for (i = 0; i < 6; i++)
{
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_10US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_10US);
}
mcsdl_read_32bits(pBuffer);
}
static int mcsdl_read_flash_from(UINT8 *pBuffer, UINT16 unStart_addr, UINT16 unLength, INT8 IdxNum)
{
int i;
int j;
UINT8 ucLength;
UINT16 addr;
UINT32 wordData;
if (unLength >= MELFAS_FIRMWARE_MAX_SIZE)
{
return MCSDL_RET_PROGRAM_SIZE_IS_WRONG;
}
addr = 0;
ucLength = MELFAS_TRANSFER_LENGTH;
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
printk(" %04X : ", unStart_addr);
#endif
for (i = 0; i < (int)unLength; i += (int)ucLength)
{
addr = (UINT16)i;
if (IdxNum > 0)
{
mcsdl_select_isp_mode(ISP_MODE_NEXT_CHIP_BYPASS);
mcsdl_delay(MCSDL_DELAY_3US);
}
mcsdl_select_isp_mode(ISP_MODE_SERIAL_READ);
wordData = (((unStart_addr + addr) & 0x1FFF) << 1) | 0x0;
wordData <<= 14;
mcsdl_write_bits(wordData, 18);
if ((unLength - addr) < MELFAS_TRANSFER_LENGTH)
{
ucLength = (UINT8)(unLength - addr);
}
//--------------------
// Read flash
//--------------------
mcsdl_read_flash(&pBuffer[addr]);
#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
for (j = 0; j < (int)ucLength; j++)
{
printk("%02X ", pBuffer[j]);
}
#endif
mcsdl_unselect_isp_mode();
}
return MCSDL_RET_SUCCESS;
}
static void mcsdl_set_ready(void)
{
//--------------------------------------------
// Tkey module reset
//--------------------------------------------
MCSDL_VDD_SET_LOW(); // power
//MCSDL_CE_SET_LOW();
//MCSDL_CE_SET_OUTPUT();
MCSDL_GPIO_SDA_SET_LOW();
MCSDL_GPIO_SDA_SET_OUTPUT(0);
MCSDL_GPIO_SCL_SET_LOW();
MCSDL_GPIO_SCL_SET_OUTPUT(0);
MCSDL_RESETB_SET_LOW();
MCSDL_RESETB_SET_OUTPUT(0);
mcsdl_delay(MCSDL_DELAY_25MS); // Delay for Stable VDD
MCSDL_VDD_SET_HIGH();
//MCSDL_CE_SET_HIGH();
MCSDL_GPIO_SCL_SET_LOW();
MCSDL_GPIO_SDA_SET_HIGH();
mcsdl_delay(MCSDL_DELAY_40MS); // Delay '30 msec'
}
static void mcsdl_reboot_mcs(void)
{
MCSDL_VDD_SET_LOW();
//MCSDL_CE_SET_LOW();
//MCSDL_CE_SET_OUTPUT();
MCSDL_GPIO_SDA_SET_HIGH();
MCSDL_GPIO_SDA_SET_OUTPUT(1);
MCSDL_GPIO_SCL_SET_HIGH();
MCSDL_GPIO_SCL_SET_OUTPUT(1);
MCSDL_RESETB_SET_LOW();
MCSDL_RESETB_SET_OUTPUT(0);
mcsdl_delay(MCSDL_DELAY_25MS); // Delay for Stable VDD
MCSDL_VDD_SET_HIGH();
//MCSDL_CE_SET_HIGH();
MCSDL_RESETB_SET_HIGH();
MCSDL_RESETB_SET_OUTPUT(0);
MCSDL_RESETB_SET_INPUT();
MCSDL_GPIO_SDA_SET_HIGH();
MCSDL_GPIO_SDA_SET_OUTPUT(1);
MCSDL_GPIO_SDA_SET_INPUT();
MCSDL_GPIO_SCL_SET_HIGH();
MCSDL_GPIO_SCL_SET_OUTPUT(1);
MCSDL_GPIO_SCL_SET_INPUT();
mcsdl_delay(MCSDL_DELAY_30MS); // Delay '25 msec'
}
//--------------------------------------------
//
// Write ISP Mode entering signal
//
//--------------------------------------------
static void mcsdl_select_isp_mode(UINT8 ucMode)
{
int i;
UINT8 enteringCodeMassErase[16] = { 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 };
UINT8 enteringCodeSerialWrite[16] = { 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1 };
UINT8 enteringCodeSerialRead[16] = { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1 };
UINT8 enteringCodeNextChipBypass[16] = { 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 };
UINT8 *pCode;
//------------------------------------
// Entering ISP mode : Part 1
//------------------------------------
if (ucMode == ISP_MODE_ERASE_FLASH) pCode = enteringCodeMassErase;
else if (ucMode == ISP_MODE_SERIAL_WRITE) pCode = enteringCodeSerialWrite;
else if (ucMode == ISP_MODE_SERIAL_READ) pCode = enteringCodeSerialRead;
else if (ucMode == ISP_MODE_NEXT_CHIP_BYPASS) pCode = enteringCodeNextChipBypass;
MCSDL_RESETB_SET_LOW();
MCSDL_GPIO_SCL_SET_LOW();
MCSDL_GPIO_SDA_SET_HIGH();
for (i = 0; i < 16; i++)
{
if (pCode[i] == 1)
MCSDL_RESETB_SET_HIGH();
else
MCSDL_RESETB_SET_LOW();
mcsdl_delay(MCSDL_DELAY_3US);
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_3US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_3US);
}
MCSDL_RESETB_SET_LOW();
//---------------------------------------------------
// Entering ISP mode : Part 2 - Only Mass Erase
//---------------------------------------------------
mcsdl_delay(MCSDL_DELAY_7US);
MCSDL_GPIO_SCL_SET_LOW();
MCSDL_GPIO_SDA_SET_HIGH();
if (ucMode == ISP_MODE_ERASE_FLASH)
{
mcsdl_delay(MCSDL_DELAY_7US);
for (i = 0; i < 4; i++)
{
if (i == 2) mcsdl_delay(MCSDL_DELAY_25MS);
else if (i == 3) mcsdl_delay(MCSDL_DELAY_150US);
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_3US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_7US);
}
}
MCSDL_GPIO_SDA_SET_LOW();
}
static void mcsdl_unselect_isp_mode(void)
{
int i;
MCSDL_RESETB_SET_LOW();
mcsdl_delay(MCSDL_DELAY_3US);
for (i = 0; i < 10; i++)
{
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_3US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_3US);
}
}
static void mcsdl_read_32bits(UINT8 *pData)
{
int i, j;
MCSDL_GPIO_SCL_SET_LOW();
MCSDL_GPIO_SDA_SET_LOW();
MCSDL_GPIO_SDA_SET_INPUT();
for (i = 3; i >= 0; i--)
{
pData[i] = 0;
for (j = 0; j < 8; j++)
{
pData[i] <<= 1;
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_1US);
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_1US);
if (MCSDL_GPIO_SDA_IS_HIGH())
pData[i] |= 0x01;
}
}
MCSDL_GPIO_SDA_SET_LOW();
MCSDL_GPIO_SDA_SET_OUTPUT(0);
}
static void mcsdl_write_bits(UINT32 wordData, int nBits)
{
int i;
MCSDL_GPIO_SCL_SET_LOW();
MCSDL_GPIO_SDA_SET_LOW();
for (i = 0; i < nBits; i++)
{
if (wordData & 0x80000000) {MCSDL_GPIO_SDA_SET_HIGH();}
else {MCSDL_GPIO_SDA_SET_LOW();}
mcsdl_delay(MCSDL_DELAY_3US);
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_3US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_3US);
wordData <<= 1;
}
}
static void mcsdl_scl_toggle_twice(void)
{
MCSDL_GPIO_SDA_SET_HIGH();
MCSDL_GPIO_SDA_SET_OUTPUT(1);
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_20US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_20US);
MCSDL_GPIO_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_20US);
MCSDL_GPIO_SCL_SET_LOW(); mcsdl_delay(MCSDL_DELAY_20US);
}
//============================================================
//
// Delay Function
//
//============================================================
void mcsdl_delay(UINT32 nCount)
{
switch (nCount)
{
case MCSDL_DELAY_1US : {udelay(1); break;}
case MCSDL_DELAY_2US : {udelay(2); break;}
case MCSDL_DELAY_3US : {udelay(3); break;}
case MCSDL_DELAY_5US : {udelay(5); break;}
case MCSDL_DELAY_7US : {udelay(7); break;}
case MCSDL_DELAY_10US : {udelay(10); break;}
case MCSDL_DELAY_15US : {udelay(15); break;}
case MCSDL_DELAY_20US : {udelay(20); break;}
case MCSDL_DELAY_40US : {udelay(40); break;}
case MCSDL_DELAY_70US : {udelay(70); break;}
case MCSDL_DELAY_100US : {udelay(100); break;}
case MCSDL_DELAY_150US : {udelay(150); break;}
case MCSDL_DELAY_300US : {udelay(300); break;}
case MCSDL_DELAY_500US : {udelay(500); break;}
case MCSDL_DELAY_800US : {udelay(800); break;}
case MCSDL_DELAY_1MS : {msleep(1); break;}
case MCSDL_DELAY_5MS : {msleep(5); break;}
case MCSDL_DELAY_10MS : {msleep(10); break;}
case MCSDL_DELAY_25MS : {msleep(25); break;}
case MCSDL_DELAY_30MS : {msleep(30); break;}
case MCSDL_DELAY_40MS : {msleep(40); break;}
case MCSDL_DELAY_45MS : {msleep(45); break;}
case MCSDL_DELAY_60MS : {msleep(60); break;}
case MCSDL_DELAY_100MS : {mdelay(100); break;}
default : {break;}
}// Please, Use your delay function
}
//============================================================
//
// Debugging print functions.
//
//============================================================
#ifdef MELFAS_ENABLE_DBG_PRINT
static void mcsdl_print_result(int nRet)
{
if (nRet == MCSDL_RET_SUCCESS)
{
printk(" > MELFAS Firmware downloading SUCCESS.\n");
}
else
{
printk(" > MELFAS Firmware downloading FAILED : ");
switch (nRet)
{
case MCSDL_RET_SUCCESS : printk("MCSDL_RET_SUCCESS\n"); break;
case MCSDL_RET_ERASE_FLASH_VERIFY_FAILED : printk("MCSDL_RET_ERASE_FLASH_VERIFY_FAILED\n"); break;
case MCSDL_RET_PROGRAM_VERIFY_FAILED : printk("MCSDL_RET_PROGRAM_VERIFY_FAILED\n"); break;
case MCSDL_RET_PROGRAM_SIZE_IS_WRONG : printk("MCSDL_RET_PROGRAM_SIZE_IS_WRONG\n"); break;
case MCSDL_RET_VERIFY_SIZE_IS_WRONG : printk("MCSDL_RET_VERIFY_SIZE_IS_WRONG\n"); break;
case MCSDL_RET_WRONG_BINARY : printk("MCSDL_RET_WRONG_BINARY\n"); break;
case MCSDL_RET_READING_HEXFILE_FAILED : printk("MCSDL_RET_READING_HEXFILE_FAILED\n"); break;
case MCSDL_RET_FILE_ACCESS_FAILED : printk("MCSDL_RET_FILE_ACCESS_FAILED\n"); break;
case MCSDL_RET_MELLOC_FAILED : printk("MCSDL_RET_MELLOC_FAILED\n"); break;
case MCSDL_RET_WRONG_MODULE_REVISION : printk("MCSDL_RET_WRONG_MODULE_REVISION\n"); break;
default : printk("UNKNOWN ERROR. [0x%02X].\n", nRet); break;
}
printk("\n");
}
}
#endif
#if MELFAS_ENABLE_DELAY_TEST
//============================================================
//
// For initial testing of delay and gpio control
//
// You can confirm GPIO control and delay time by calling this function.
//
//============================================================
void mcsdl_delay_test(INT32 nCount)
{
INT16 i;
MELFAS_DISABLE_BASEBAND_ISR(); // Disable Baseband touch interrupt ISR.
MELFAS_DISABLE_WATCHDOG_TIMER_RESET(); // Disable Baseband watchdog timer
//--------------------------------
// Repeating 'nCount' times
//--------------------------------
//MCSDL_SET_GPIO_I2C();
MCSDL_GPIO_SCL_SET_OUTPUT(0);
MCSDL_GPIO_SDA_SET_OUTPUT(0);
MCSDL_RESETB_SET_OUTPUT(0);
MCSDL_GPIO_SCL_SET_HIGH();
for (i = 0; i < nCount; i++)
{
#if 1
MCSDL_GPIO_SCL_SET_LOW();
mcsdl_delay(MCSDL_DELAY_20US);
MCSDL_GPIO_SCL_SET_HIGH();
mcsdl_delay(MCSDL_DELAY_100US);
#elif 0
MCSDL_GPIO_SCL_SET_LOW();
mcsdl_delay(MCSDL_DELAY_500US);
MCSDL_GPIO_SCL_SET_HIGH();
mcsdl_delay(MCSDL_DELAY_1MS);
#else
MCSDL_GPIO_SCL_SET_LOW();
mcsdl_delay(MCSDL_DELAY_25MS);
TKEY_INTR_SET_LOW();
mcsdl_delay(MCSDL_DELAY_45MS);
TKEY_INTR_SET_HIGH();
#endif
}
MCSDL_GPIO_SCL_SET_HIGH();
MELFAS_ROLLBACK_BASEBAND_ISR(); // Roll-back Baseband touch interrupt ISR.
MELFAS_ROLLBACK_WATCHDOG_TIMER_RESET(); // Roll-back Baseband watchdog timer
}
#endif