aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/grande_download.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/grande_download.c')
-rwxr-xr-xdrivers/input/touchscreen/grande_download.c1943
1 files changed, 1943 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/grande_download.c b/drivers/input/touchscreen/grande_download.c
new file mode 100755
index 0000000..b768bea
--- /dev/null
+++ b/drivers/input/touchscreen/grande_download.c
@@ -0,0 +1,1943 @@
+//------------------------------------------------------------------
+//
+// MELFAS Firmware download base code v6 For MCS5080 2008/11/04
+//
+//------------------------------------------------------------------
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+#include <plat/gpio-cfg.h>
+#include <asm/gpio.h>
+#include <mach/gpio-midas.h>
+#include "grande_download.h"
+
+#define _3_TOUCH_SDA_28V GPIO_3_TOUCH_SDA
+#define _3_TOUCH_SCL_28V GPIO_3_TOUCH_SCL
+#define _3_GPIO_TOUCH_EN GPIO_3_TOUCH_EN
+#define _3_GPIO_TOUCH_INT GPIO_3_TOUCH_INT
+
+
+//============================================================
+//
+// Static variables & functions
+//
+//============================================================
+
+#define MCS5000_CHIP 0x93
+#define MCS5080_CHIP 0x3
+
+static UINT8 MCS_VERSION;
+
+//---------------------------------
+// Downloading functions
+//---------------------------------
+static int mcsdl_download(const UINT8 *pData, const UINT16 nLength);
+static int mcsdl_download_5000(const UINT8 *pData, const UINT16 nLength);
+static int mcsdl_enter_download_mode(void);
+static void mcsdl_write_download_mode_signal(void);
+
+static int mcsdl_i2c_erase_flash(void);
+static int mcsdl_i2c_erase_flash_5000(void);
+static int mcsdl_i2c_prepare_erase_flash(void);
+static int mcsdl_i2c_read_flash( UINT8 *pBuffer, UINT16 nAddr_start, UINT8 cLength);
+static int mcsdl_i2c_prepare_program(void);
+static int mcsdl_i2c_program_info(void);
+static int mcsdl_i2c_program_flash( UINT8 *pData, UINT16 nAddr_start, UINT8 cLength );
+static int mcsdl_i2c_program_flash_5000( UINT8 *pData, UINT16 nAddr_start, UINT8 cLength );
+
+//-----------------------------------------
+// Download enable command on Protocol
+//-----------------------------------------
+#if MELFAS_USE_PROTOCOL_COMMAND_FOR_DOWNLOAD
+void melfas_send_download_enable_command(void);
+#endif
+
+struct i2c_touchkey_driver {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct work_struct work;
+};
+extern struct i2c_touchkey_driver *touchkey_driver;
+static spinlock_t spinlock;
+#define I2C_M_WR 0 /* for i2c */
+#define uart_printf printk
+
+
+
+//---------------------------------
+// I2C Functions
+//---------------------------------
+static BOOLEAN _i2c_read_( UINT8 slave_addr, UINT8 *pData, UINT8 cLength);
+static BOOLEAN _i2c_write_(UINT8 slave_addr, UINT8 *pData, UINT8 cLength);
+
+//---------------------------------
+// Delay functions
+//---------------------------------
+static void mcsdl_delay(UINT32 nCount);
+
+//---------------------------------
+// For debugging display
+//---------------------------------
+#if MELFAS_ENABLE_DBG_PRINT
+static void mcsdl_print_result(int nRet);
+#endif
+
+
+//////I2C
+
+#define EXT_I2C_SCL_HIGH TKEY_I2C_SCL_SET_HIGH();
+#define EXT_I2C_SCL_LOW TKEY_I2C_SCL_SET_LOW();
+#define EXT_I2C_SDA_HIGH TKEY_I2C_SDA_SET_HIGH();
+#define EXT_I2C_SDA_LOW TKEY_I2C_SDA_SET_LOW();
+
+static void SCLH_SDAH(u32 delay)
+{
+ EXT_I2C_SCL_HIGH;
+ EXT_I2C_SDA_HIGH;
+ udelay(delay);
+}
+
+static void SCLH_SDAL(u32 delay)
+{
+ EXT_I2C_SCL_HIGH;
+ EXT_I2C_SDA_LOW;
+ udelay(delay);
+}
+
+static void SCLL_SDAH(u32 delay)
+{
+ EXT_I2C_SCL_LOW;
+ EXT_I2C_SDA_HIGH;
+ udelay(delay);
+}
+
+static void SCLL_SDAL(u32 delay)
+{
+ EXT_I2C_SCL_LOW;
+ EXT_I2C_SDA_LOW;
+ udelay(delay);
+}
+
+static void EXT_I2C_LOW(u32 delay)
+{
+ SCLL_SDAL(delay);
+ SCLH_SDAL(delay);
+ SCLH_SDAL(delay);
+ SCLL_SDAL(delay);
+}
+
+static void EXT_I2C_HIGH(u32 delay)
+{
+ SCLL_SDAH(delay);
+ SCLH_SDAH(delay);
+ SCLH_SDAH(delay);
+ SCLL_SDAH(delay);
+}
+
+static void EXT_I2C_START(u32 delay)
+{
+ SCLH_SDAH(delay);
+ SCLH_SDAL(delay);
+ udelay(delay);
+ SCLL_SDAL(delay);
+}
+
+static void EXT_I2C_RESTART(u32 delay)
+{
+ SCLL_SDAH(delay);
+ SCLH_SDAH(delay);
+ SCLH_SDAL(delay);
+ udelay(delay);
+ SCLL_SDAL(delay);
+}
+
+static void EXT_I2C_END(u32 delay)
+{
+ SCLL_SDAL(delay);
+ SCLH_SDAL(delay);
+ udelay(delay);
+ SCLH_SDAH(delay);
+}
+
+static void EXT_I2C_ACK(u32 delay)
+{
+ u32 ack;
+
+ EXT_I2C_SCL_LOW;
+ udelay(delay);
+
+ /* SDA -> Input */
+ TKEY_I2C_SDA_SET_INPUT();
+
+ EXT_I2C_SCL_HIGH;
+ udelay(delay);
+ ack = gpio_get_value(_3_TOUCH_SDA_28V);
+ EXT_I2C_SCL_HIGH;
+ udelay(delay);
+
+ /* SDA -> Onput Low */
+ TKEY_I2C_SDA_SET_LOW();
+
+ EXT_I2C_SCL_LOW;
+ udelay(delay);
+
+ if (ack)
+ printk("EXT_I2C(%d) -> No ACK\n", ack);
+}
+
+static void EXT_I2C_NACK(u32 delay)
+{
+ EXT_I2C_HIGH(delay);
+}
+
+static void EXT_I2C_SEND_ACK(u32 delay)
+{
+ u32 ack;
+
+ EXT_I2C_SCL_LOW;
+ udelay(delay);
+
+ /* SDA -> Input */
+ TKEY_I2C_SDA_SET_INPUT();
+ udelay(delay);
+ ack = gpio_get_value(_3_TOUCH_SDA_28V);
+
+ /* SDA -> Onput Low */
+ TKEY_I2C_SDA_SET_LOW();
+
+ EXT_I2C_SCL_HIGH;
+// udelay(delay);
+// ack = gpio_get_value(_3_TOUCH_SDA_28V);
+// EXT_I2C_SCL_HIGH;
+ udelay(delay);
+
+ EXT_I2C_SCL_LOW;
+ udelay(delay);
+
+}
+
+#define EXT_I2C_DELAY 3
+//============================================================
+//
+// Porting section 6. I2C function calling
+//
+// Connect baseband i2c function
+//
+// Warning 1. !!!! Burst mode is not supported. Transfer 1 byte Only.
+//
+// Every i2c packet has to
+// " START > Slave address > One byte > STOP " at download mode.
+//
+// Warning 2. !!!! Check return value of i2c function.
+//
+// _i2c_read_(), _i2c_write_() must return
+// TRUE (1) if success,
+// FALSE(0) if failed.
+//
+// If baseband i2c function returns different value, convert return value.
+// ex> baseband_return = baseband_i2c_read( slave_addr, pData, cLength );
+// return ( baseband_return == BASEBAND_RETURN_VALUE_SUCCESS );
+//
+//
+// Warning 3. !!!! Check Slave address
+//
+// Slave address is '0x7F' at download mode. ( Diffrent with Normal touch working mode )
+// '0x7F' is original address,
+// If shift << 1 bit, It becomes '0xFE'
+//
+//============================================================
+
+static BOOLEAN _i2c_read_( UINT8 SlaveAddr, UINT8 *pData, UINT8 cLength)
+{
+#if 1
+ u32 i;
+ int delay_count = 10000;
+
+ //ext_i2c_channel = Channel;
+
+ EXT_I2C_START(EXT_I2C_DELAY);
+/*
+ for (i = 8; i > 1; i--) {
+ if ((SlaveAddr >> (i - 1)) & 0x1)
+ EXT_I2C_HIGH(EXT_I2C_DELAY);
+ else
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+ }
+
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+
+ EXT_I2C_ACK(EXT_I2C_DELAY);
+
+ for (i = 8; i > 0; i--) {
+ if ((WordAddr >> (i - 1)) & 0x1)
+ EXT_I2C_HIGH(EXT_I2C_DELAY);
+ else
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+ }
+
+ EXT_I2C_ACK(EXT_I2C_DELAY);
+
+ EXT_I2C_RESTART(EXT_I2C_DELAY);
+*/
+ SlaveAddr = SlaveAddr <<1;
+ for (i = 8; i > 1; i--) {
+ if ((SlaveAddr >> (i - 1)) & 0x1)
+ EXT_I2C_HIGH(EXT_I2C_DELAY);
+ else
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+ }
+
+ EXT_I2C_HIGH(EXT_I2C_DELAY);
+
+ EXT_I2C_ACK(EXT_I2C_DELAY);
+
+ udelay(60);
+ TKEY_I2C_SDA_SET_INPUT();
+ TKEY_I2C_SCL_SET_INPUT();
+ //while(!gpio_get_value(_3_TOUCH_SCL_28V));
+ delay_count = 100000;
+ while(delay_count--)
+ {
+ if(gpio_get_value(_3_TOUCH_SCL_28V))
+ break;
+ udelay(1);
+ }
+ //udelay(EXT_I2C_DELAY);
+ while(cLength--)
+ {
+ *pData = 0;
+ for (i = 8; i > 0; i--) {
+ //EXT_I2C_SCL_LOW;
+ udelay(EXT_I2C_DELAY);
+ EXT_I2C_SCL_HIGH;
+ udelay(EXT_I2C_DELAY);
+ *pData |= (!!(gpio_get_value(_3_TOUCH_SDA_28V)) << (i - 1));
+ EXT_I2C_SCL_HIGH;
+ udelay(EXT_I2C_DELAY);
+ EXT_I2C_SCL_LOW;
+ udelay(EXT_I2C_DELAY);
+ }
+
+ if(cLength)
+ {
+ EXT_I2C_SEND_ACK(EXT_I2C_DELAY);
+ udelay(60);
+ pData++;
+ TKEY_I2C_SDA_SET_INPUT();
+ TKEY_I2C_SCL_SET_INPUT();
+ //while(!gpio_get_value(_3_TOUCH_SCL_28V));
+ delay_count = 100000;
+ while(delay_count--)
+ {
+ if(gpio_get_value(_3_TOUCH_SCL_28V))
+ break;
+ udelay(1);
+ }
+ }
+ else
+ EXT_I2C_NACK(EXT_I2C_DELAY);
+ }
+
+ EXT_I2C_END(EXT_I2C_DELAY);
+
+ return (TRUE );
+#else
+
+ BOOLEAN bRet;
+ int err;
+ #if USE_BASEBAND_I2C_FUNCTION
+ struct i2c_msg msg[1];
+ if( (touchkey_driver->client == NULL) || (!touchkey_driver->client->adapter) )
+ {
+ return -ENODEV;
+ }
+
+ msg->addr = MCSDL_I2C_SLAVE_ADDR_ORG;
+ msg->flags = I2C_M_RD;
+ msg->len = cLength;
+ msg->buf = pData;
+ err = i2c_transfer(touchkey_driver->client->adapter, msg, 1);
+
+ if (err < 0)
+ {
+ printk("%s %d i2c transfer error\n", __func__, __LINE__);/* add by inter.park */
+ return FALSE;
+ }
+
+ #else
+
+ bRet = FALSE;
+
+ #endif
+
+ return (TRUE );
+#endif
+}
+
+static BOOLEAN _i2c_write_(UINT8 SlaveAddr, UINT8 *pData, UINT8 cLength)
+{
+#if 1
+ u32 i;
+ //ext_i2c_channel = Channel;
+
+ EXT_I2C_START(EXT_I2C_DELAY);
+/*
+ for (i = 8; i > 1; i--) {
+ if ((SlaveAddr >> (i - 1)) & 0x1)
+ EXT_I2C_HIGH(EXT_I2C_DELAY);
+ else
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+ }
+
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+
+ EXT_I2C_ACK(EXT_I2C_DELAY);
+*/ SlaveAddr = SlaveAddr <<1;
+ for (i = 8; i > 0; i--) {
+ if ((SlaveAddr >> (i - 1)) & 0x1)
+ EXT_I2C_HIGH(EXT_I2C_DELAY);
+ else
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+ }
+
+ EXT_I2C_ACK(EXT_I2C_DELAY);
+
+ udelay(500); //for i2c test
+
+
+ for (i = 8; i > 0; i--) {
+ if ((*pData >> (i - 1)) & 0x1)
+ EXT_I2C_HIGH(EXT_I2C_DELAY);
+ else
+ EXT_I2C_LOW(EXT_I2C_DELAY);
+ }
+
+ EXT_I2C_ACK(EXT_I2C_DELAY);
+
+ EXT_I2C_END(EXT_I2C_DELAY);
+
+ return (TRUE );
+#else
+ BOOLEAN bRet;
+ int err;
+
+ #if USE_BASEBAND_I2C_FUNCTION
+
+ struct i2c_msg msg[1];
+ if( (touchkey_driver->client == NULL) || (!touchkey_driver->client->adapter) )
+ {
+ return -ENODEV;
+ }
+
+ msg->addr = MCSDL_I2C_SLAVE_ADDR_ORG;
+ msg->flags = I2C_M_WR;
+ msg->len = cLength;
+ msg->buf = pData;
+ err = i2c_transfer(touchkey_driver->client->adapter, msg, 1);
+
+ if (err < 0)
+ {
+ printk("%s %d i2c transfer error\n", __func__, __LINE__);/* add by inter.park */
+ return FALSE;
+ }
+ #else
+
+ bRet = FALSE;
+
+ #endif
+
+ return (TRUE);
+#endif
+}
+
+//----------------------------------
+// Download enable command
+//----------------------------------
+#if MELFAS_USE_PROTOCOL_COMMAND_FOR_DOWNLOAD
+
+void melfas_send_download_enable_command(void)
+{
+ // TO DO : Fill this up
+
+}
+
+#endif
+
+
+//============================================================
+//
+// Include MELFAS Binary source code File ( ex> MELFAS_FIRM_bin.c)
+//
+// Warning!!!!
+// .c file included at next must not be inserted to Souce project.
+// Just #include One file. !!
+//
+//============================================================
+//#include "MCS5080_SAMPLE_FIRMWARE_R01_V00_bin.c"
+//#include "MMH_SVESTA_R00_V02_bin.c" //1 include bin file
+#define BINARY_FIRMWARE_VERSION 0x01
+#include "MCH_SW889_R01_V01_bin.c"
+
+//============================================================
+//
+// main Download furnction
+//
+//============================================================
+//#define IRQ_TOUCH_INT S3C_GPIOINT(J4,1)
+//#define IRQ_TOUCH_INT IRQ_GPIOINT
+#define IRQ_TOUCH_INT gpio_to_irq(GPIO_3_TOUCH_INT)
+
+void get_touchkey_data(UINT8 *data, UINT8 length)
+{
+ _i2c_read_(TOUCHKEY_ADDRESS, data, length);
+}
+
+int mcsdl_download_binary_data(UINT8 chip_ver)
+{
+ int ret = 0;
+ MCS_VERSION = chip_ver;
+
+ #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
+
+ //------------------------
+ // Run Download
+ //------------------------
+
+ if(MCS_VERSION==MCS5000_CHIP) //MCS-5000
+ {
+ ret = mcsdl_download_5000( (const UINT8*) MELFAS_binary, (const UINT16)MELFAS_binary_nLength );
+ }
+ else if(MCS_VERSION==MCS5080_CHIP) //MCS-5080
+ {
+ ret = mcsdl_download( (const UINT8*) MELFAS_binary, (const UINT16)MELFAS_binary_nLength );
+ }
+ else
+ uart_printf("Touchkey IC module is old, can't update!");
+
+ MELFAS_DISABLE_WATCHDOG_TIMER_RESET(); // Roll-back Baseband touch interrupt ISR.
+ MELFAS_ROLLBACK_WATCHDOG_TIMER_RESET(); // Roll-back Baseband watchdog timer
+
+ #if MELFAS_ENABLE_DBG_PRINT
+
+ //------------------------
+ // Show result
+ //------------------------
+
+ mcsdl_print_result( ret );
+
+ #endif
+
+
+ gpio_direction_output(_3_GPIO_TOUCH_EN, 1);
+ mdelay(100);
+ s3c_gpio_setpull(_3_GPIO_TOUCH_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(EXYNOS4212_GPJ1(0), S3C_GPIO_SFN(0xf));
+ irq_set_irq_type(IRQ_TOUCH_INT, IRQ_TYPE_EDGE_FALLING);
+
+ return ( ret == MCSDL_RET_SUCCESS );
+}
+
+
+
+int mcsdl_download_binary_file(UINT8 *pData, UINT16 nBinary_length)
+{
+ UINT8 data[3];
+ int ret;
+
+ //UINT8 *pData = NULL;
+ //UINT16 nBinary_length =0;
+
+ //==================================================
+ //
+ // Porting section 7. File process
+ //
+ // 1. Read '.bin file'
+ // 2. Run mcsdl_download_binary_data();
+ //
+ //==================================================
+
+ #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_FIRM.bin", "rb" ) == NULL ){
+ return MCSDL_RET_FILE_ACCESS_FAILED;
+ }
+
+ //------------------------------
+ // Get Binary Size
+ //------------------------------
+
+ fseek( fp, 0, SEEK_END );
+
+ nBinary_length = (UINT16)ftell(fp);
+
+ //------------------------------
+ // Memory allocation
+ //------------------------------
+
+ pData = (UINT8*)malloc( (INT)nBinary_length );
+
+ if( pData == NULL ){
+
+ return MCSDL_RET_FILE_ACCESS_FAILED;
+ }
+
+ //------------------------------
+ // Read binary file
+ //------------------------------
+
+ fseek( fp, 0, SEEK_SET );
+
+ nRead = fread( pData, 1, (INT)nBinary_length, fp ); // Read binary file
+
+ if( nRead != (INT)nBinary_length ){
+
+ fclose(fp); // Close file
+
+ if( pData != NULL ) // free memory alloced.
+ free(pData);
+
+ return MCSDL_RET_FILE_ACCESS_FAILED;
+ }
+
+ //------------------------------
+ // Close file
+ //------------------------------
+
+ fclose(fp);
+
+ #endif
+
+ if( pData != NULL && nBinary_length > 0 && nBinary_length < 14*1024 ){
+
+ MELFAS_DISABLE_BASEBAND_ISR(); // Disable Baseband touch interrupt ISR.
+ MELFAS_DISABLE_WATCHDOG_TIMER_RESET(); // Disable Baseband watchdog timer
+
+ ret = mcsdl_download( (const UINT8 *)pData, (const UINT16)nBinary_length );
+
+ MELFAS_DISABLE_WATCHDOG_TIMER_RESET(); // Roll-back Baseband touch interrupt ISR.
+ MELFAS_ROLLBACK_WATCHDOG_TIMER_RESET(); // Roll-back Baseband watchdog timer
+
+ }else{
+
+ ret = MCSDL_RET_WRONG_PARAMETER;
+ }
+
+ #if MELFAS_ENABLE_DBG_PRINT
+
+ mcsdl_print_result( ret );
+
+ #endif
+
+ #if 0
+ if( pData != NULL ) // free memory alloced.
+ free(pData);
+ #endif
+
+ _i2c_read_(TOUCHKEY_ADDRESS, data, 3 );
+ printk("%s F/W version: 0x%x, Module version:0x%x\n",__FUNCTION__, data[1],data[2]);
+
+ return ( ret == MCSDL_RET_SUCCESS );
+
+}
+
+//------------------------------------------------------------------
+//
+// Download function
+//
+//------------------------------------------------------------------
+
+static int mcsdl_download(const UINT8 *pData, const UINT16 nLength )
+{
+ int i;
+ int nRet;
+
+ UINT8 cLength;
+ UINT16 nStart_address=0;
+
+ UINT8 buffer[MELFAS_TRANSFER_LENGTH];
+ UINT8 *pOriginal_data;
+
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("Starting MCS-5080 download...\n");
+ #endif
+
+ //--------------------------------------------------------------
+ //
+ // Enter Download mode
+ //
+ //--------------------------------------------------------------
+ nRet = mcsdl_enter_download_mode();
+
+ if( nRet != MCSDL_RET_SUCCESS )
+ goto MCSDL_DOWNLOAD_FINISH;
+
+ mdelay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+ //--------------------------------------------------------------
+ //
+ // Check H/W Revision
+ //
+ // Don't download firmware, if Module H/W revision does not match.
+ //
+ //--------------------------------------------------------------
+ #if MELFAS_DISABLE_DOWNLOAD_IF_MODULE_VERSION_DOES_NOT_MATCH
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("Checking module revision...\n");
+ #endif
+
+ pOriginal_data = (UINT8 *)pData;
+
+ nRet = mcsdl_i2c_read_flash( buffer, MCSDL_ADDR_MODULE_REVISION, 4 );
+
+ if( nRet != MCSDL_RET_SUCCESS )
+ goto MCSDL_DOWNLOAD_FINISH;
+
+ if( (pOriginal_data[MCSDL_ADDR_MODULE_REVISION+1] != buffer[1])
+ || (pOriginal_data[MCSDL_ADDR_MODULE_REVISION+2] != buffer[2]) ){
+
+ nRet = MCSDL_RET_WRONG_MODULE_REVISION;
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+
+ mdelay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+ #endif
+
+ //--------------------------------------------------------------
+ //
+ // Erase Flash
+ //
+ //--------------------------------------------------------------
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("Erasing...\n");
+ #endif
+
+ nRet = mcsdl_i2c_prepare_erase_flash();
+
+ if( nRet != MCSDL_RET_SUCCESS ){
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+
+ mdelay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+ nRet = mcsdl_i2c_erase_flash();
+
+ if( nRet != MCSDL_RET_SUCCESS ){
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+
+ mdelay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+
+ //--------------------------------------------------------------
+ //
+ // Verify erase
+ //
+ //--------------------------------------------------------------
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("Verify Erasing...\n");
+ #endif
+
+ nRet = mcsdl_i2c_read_flash( buffer, 0x00, 16 );
+
+ if( nRet != MCSDL_RET_SUCCESS )
+ goto MCSDL_DOWNLOAD_FINISH;
+
+
+ for(i=0; i<16; i++){
+
+ if( buffer[i] != 0xFF ){
+
+ nRet = MCSDL_RET_ERASE_VERIFY_FAILED;
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+ }
+
+ mdelay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+
+ //--------------------------------------------------------------
+ //
+ // Prepare for Program flash.
+ //
+ //--------------------------------------------------------------
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("Program information...\n");
+ #endif
+
+ nRet = mcsdl_i2c_prepare_program();
+
+ if( nRet != MCSDL_RET_SUCCESS )
+ goto MCSDL_DOWNLOAD_FINISH;
+
+
+ mdelay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+
+ //--------------------------------------------------------------
+ //
+ // Program flash
+ //
+ //--------------------------------------------------------------
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("Program flash... ");
+ #endif
+
+ pOriginal_data = (UINT8 *)pData;
+
+ nStart_address = 0;
+ cLength = MELFAS_TRANSFER_LENGTH;
+
+ for( nStart_address = 0; nStart_address < nLength; nStart_address+=cLength ){
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("#");
+ #endif
+
+ if( ( nLength - nStart_address ) < MELFAS_TRANSFER_LENGTH ){
+ cLength = (UINT8)(nLength - nStart_address);
+
+ cLength += (cLength%2); // For odd length.
+ }
+
+ nRet = mcsdl_i2c_program_flash( pOriginal_data, nStart_address, cLength );
+
+ if( nRet != MCSDL_RET_SUCCESS ){
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("Program flash failed position : 0x%x / nRet : 0x%x ", nStart_address, nRet);
+ #endif
+
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+
+ pOriginal_data += cLength;
+
+ mcsdl_delay(MCSDL_DELAY_500US); // Delay '500 usec'
+
+ }
+
+
+ //--------------------------------------------------------------
+ //
+ // Verify flash
+ //
+ //--------------------------------------------------------------
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("\n");
+ uart_printf("Verify flash... ");
+ #endif
+
+ pOriginal_data = (UINT8 *) pData;
+
+ nStart_address = 0;
+
+ cLength = MELFAS_TRANSFER_LENGTH;
+
+ for( nStart_address = 0; nStart_address < nLength; nStart_address+=cLength ){
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("#");
+ #endif
+
+ if( ( nLength - nStart_address ) < MELFAS_TRANSFER_LENGTH ){
+ cLength = (UINT8)(nLength - nStart_address);
+
+ cLength += (cLength%2); // For odd length.
+ }
+
+ //--------------------
+ // Read flash
+ //--------------------
+ nRet = mcsdl_i2c_read_flash( buffer, nStart_address, cLength );
+
+ //--------------------
+ // Comparing
+ //--------------------
+
+ for(i=0; i<(int)cLength; i++){
+
+
+ if( buffer[i] != pOriginal_data[i] ){
+
+ #if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ uart_printf("0x%04X : 0x%02X - 0x%02X\n", nStart_address, pOriginal_data[i], buffer[i] );
+ #endif
+
+ nRet = MCSDL_RET_PROGRAM_VERIFY_FAILED;
+ goto MCSDL_DOWNLOAD_FINISH;
+
+ }
+ }
+
+ pOriginal_data += cLength;
+
+
+ mcsdl_delay(MCSDL_DELAY_500US); // Delay '500 usec'
+ }
+
+ uart_printf("\n");
+
+ nRet = MCSDL_RET_SUCCESS;
+
+
+MCSDL_DOWNLOAD_FINISH :
+
+ mdelay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+ //---------------------------
+ // Reset command
+ //---------------------------
+ buffer[0] = MCSDL_ISP_CMD_RESET;
+
+ _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG, buffer, 1 );
+
+ TKEY_INTR_SET_INPUT();
+
+ mcsdl_delay(MCSDL_DELAY_45MS);
+
+ return nRet;
+}
+
+//------------------------------------------------------------------
+//
+// Download function for MCS-5000
+//
+//------------------------------------------------------------------
+
+static int mcsdl_download_5000(const UINT8 *pData, const UINT16 nLength )
+{
+ int i;
+ int nRet;
+
+ UINT16 nCurrent=0;
+ UINT8 cLength;
+
+ UINT8 buffer[MELFAS_TRANSFER_LENGTH];
+
+ UINT8 *pBuffer;
+
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("Starting MCS-5000 download...\n");
+ #endif
+
+ //--------------------------------------------------------------
+ //
+ // Enter Download mode
+ //
+ //--------------------------------------------------------------
+ nRet = mcsdl_enter_download_mode();
+
+ if( nRet != MCSDL_RET_SUCCESS )
+ goto MCSDL_DOWNLOAD_FINISH;
+
+
+ mcsdl_delay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+
+ //--------------------------------------------------------------
+ //
+ // Erase Flash
+ //
+ //--------------------------------------------------------------
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("Erasing...\n");
+ #endif
+
+ nRet = mcsdl_i2c_erase_flash_5000();
+
+ if( nRet != MCSDL_RET_SUCCESS ){
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+
+ mcsdl_delay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+
+ //---------------------------
+ //
+ // Verify erase
+ //
+ //---------------------------
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("Verify Erasing...\n");
+ #endif
+
+ nRet = mcsdl_i2c_read_flash( buffer, 0x00, 16 );
+
+ if( nRet != MCSDL_RET_SUCCESS )
+ goto MCSDL_DOWNLOAD_FINISH;
+
+ for(i=0; i<16; i++){
+
+ if( buffer[i] != 0xFF ){
+
+ nRet = MCSDL_RET_ERASE_VERIFY_FAILED;
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+ }
+
+ mcsdl_delay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+
+ //-------------------------------
+ //
+ // Program flash information
+ //
+ //-------------------------------
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("Program information...\n");
+ #endif
+
+ nRet = mcsdl_i2c_program_info();
+
+ if( nRet != MCSDL_RET_SUCCESS )
+ goto MCSDL_DOWNLOAD_FINISH;
+
+
+ mcsdl_delay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+
+ //-------------------------------
+ // Program flash
+ //-------------------------------
+
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("Program flash... ");
+ #endif
+
+ pBuffer = (UINT8 *)pData;
+ nCurrent = 0;
+ cLength = MELFAS_TRANSFER_LENGTH;
+
+ while( nCurrent < nLength ){
+
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("#");
+ #endif
+
+ if( ( nLength - nCurrent ) < MELFAS_TRANSFER_LENGTH ){
+ cLength = (UINT8)(nLength - nCurrent);
+ }
+
+ nRet = mcsdl_i2c_program_flash_5000( pBuffer, nCurrent, cLength );
+
+ if( nRet != MCSDL_RET_SUCCESS ){
+
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("Program flash failed position : 0x%x / nRet : 0x%x ", nCurrent, nRet);
+ #endif
+
+ goto MCSDL_DOWNLOAD_FINISH;
+ }
+
+ pBuffer += cLength;
+ nCurrent += (UINT16)cLength;
+
+ mcsdl_delay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+ }
+
+
+ //-------------------------------
+ //
+ // Verify flash
+ //
+ //-------------------------------
+
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("\n");
+ uart_printf("Verify flash... ");
+ #endif
+
+ pBuffer = (UINT8 *) pData;
+
+ nCurrent = 0;
+
+ cLength = MELFAS_TRANSFER_LENGTH;
+
+ while( nCurrent < nLength ){
+
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("#");
+ #endif
+
+ if( ( nLength - nCurrent ) < MELFAS_TRANSFER_LENGTH ){
+ cLength = (UINT8)(nLength - nCurrent);
+ }
+
+ //--------------------
+ // Read flash
+ //--------------------
+ nRet = mcsdl_i2c_read_flash( buffer, nCurrent, cLength );
+
+ //--------------------
+ // Comparing
+ //--------------------
+ for(i=0; i<(int)cLength; i++){
+
+ if( buffer[i] != pBuffer[i] ){
+
+ #ifdef MELFAS_ENABLE_DBG_PRINT
+ uart_printf("0x%04X : 0x%02X - 0x%02X\n", nCurrent, pBuffer[i], buffer[i] );
+ #endif
+
+ nRet = MCSDL_RET_PROGRAM_VERIFY_FAILED;
+ goto MCSDL_DOWNLOAD_FINISH;
+
+ }
+ }
+
+ pBuffer += cLength;
+ nCurrent += (UINT16)cLength;
+
+ mcsdl_delay(MCSDL_DELAY_1MS); // Delay '1 msec'
+ }
+
+ uart_printf("\n");
+
+ nRet = MCSDL_RET_SUCCESS;
+
+
+MCSDL_DOWNLOAD_FINISH :
+
+ mcsdl_delay(MCSDL_DELAY_1MS); // Delay '1 msec'
+
+ //---------------------------
+ // Reset command
+ //---------------------------
+ buffer[0] = MCSDL_ISP_CMD_RESET;
+
+ _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, buffer, 1 );
+
+ mcsdl_delay(MCSDL_DELAY_45MS);
+
+ TKEY_INTR_SET_INPUT();
+
+
+ return nRet;
+
+}
+
+
+//------------------------------------------------------------------
+//
+// Enter Download mode ( MDS ISP or I2C ISP )
+//
+//------------------------------------------------------------------
+static int mcsdl_enter_download_mode(void)
+{
+ BOOLEAN bRet;
+ int nRet = MCSDL_RET_ENTER_DOWNLOAD_MODE_FAILED;
+
+ UINT8 cData=0;
+
+ //--------------------------------------------
+ // Tkey module reset
+ //--------------------------------------------
+
+ TKEY_VDD_SET_LOW();
+
+ TKEY_CE_SET_LOW();
+ TKEY_CE_SET_OUTPUT();
+
+ TKEY_I2C_CLOSE();
+
+ TKEY_INTR_SET_LOW();
+ TKEY_INTR_SET_OUTPUT();
+
+ TKEY_RESETB_SET_LOW();
+ TKEY_RESETB_SET_OUTPUT();
+
+ mcsdl_delay(MCSDL_DELAY_45MS); // Delay for VDD LOW Stable
+ mcsdl_delay(MCSDL_DELAY_45MS);
+
+ TKEY_VDD_SET_HIGH();
+ TKEY_CE_SET_HIGH();
+ TKEY_I2C_SDA_SET_HIGH();
+
+ mdelay(45); // Delay '45 msec'
+
+ //-------------------------------
+ // Write 1st signal
+ //-------------------------------
+ mcsdl_write_download_mode_signal();
+
+ mcsdl_delay(MCSDL_DELAY_25MS); // Delay '25 msec'
+
+ //-------------------------------
+ // Check response
+ //-------------------------------
+
+ if(MCS_VERSION==MCS5080_CHIP)
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG, &cData, 1 );
+ else
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, &cData, 1 );
+
+ if( bRet != TRUE || cData != MCSDL_I2C_SLAVE_READY_STATUS ){
+
+ uart_printf("mcsdl_enter_download_mode() returns - ret : 0x%x & cData : 0x%x\n", nRet, cData);
+ goto MCSDL_ENTER_DOWNLOAD_MODE_FINISH;
+ }
+
+ nRet = MCSDL_RET_SUCCESS;
+
+ //-----------------------------------
+ // Entering MDS ISP mode finished.
+ //-----------------------------------
+
+MCSDL_ENTER_DOWNLOAD_MODE_FINISH:
+
+ return nRet;
+}
+
+//--------------------------------------------
+//
+// Write ISP Mode entering signal
+//
+//--------------------------------------------
+static void mcsdl_write_download_mode_signal(void)
+{
+ int i;
+
+ UINT8 enter_code[14] = { 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1 };
+ if(MCS_VERSION==MCS5000_CHIP)
+ {
+ enter_code[10] = 0;
+ enter_code[12] = 0;
+ }
+
+ //---------------------------
+ // ISP mode signal 0
+ //---------------------------
+
+ for(i=0; i<14; i++){
+
+ if( enter_code[i] ) {
+
+ TKEY_RESETB_SET_HIGH();
+ TKEY_INTR_SET_HIGH();
+
+ }else{
+
+ TKEY_RESETB_SET_LOW();
+ TKEY_INTR_SET_LOW();
+ }
+
+ TKEY_I2C_SCL_SET_HIGH(); mcsdl_delay(MCSDL_DELAY_15US);
+ TKEY_I2C_SCL_SET_LOW();
+
+ TKEY_RESETB_SET_LOW();
+ TKEY_INTR_SET_LOW();
+
+ mcsdl_delay(MCSDL_DELAY_100US);
+
+ }
+
+ TKEY_I2C_SCL_SET_HIGH();
+
+ mcsdl_delay(MCSDL_DELAY_100US);
+
+ TKEY_INTR_SET_HIGH();
+ TKEY_RESETB_SET_HIGH();
+}
+
+
+//--------------------------------------------
+//
+// Prepare Erase flash
+//
+//--------------------------------------------
+static int mcsdl_i2c_prepare_erase_flash(void)
+{
+ int nRet = MCSDL_RET_PREPARE_ERASE_FLASH_FAILED;
+
+ UINT8 i;
+ BOOLEAN bRet;
+
+ UINT8 i2c_buffer[4] = { MCSDL_ISP_CMD_ERASE_TIMING,
+ MCSDL_ISP_ERASE_TIMING_VALUE_0,
+ MCSDL_ISP_ERASE_TIMING_VALUE_1,
+ MCSDL_ISP_ERASE_TIMING_VALUE_2 };
+ UINT8 ucTemp;
+
+ //-----------------------------
+ // Send Erase Setting code
+ //-----------------------------
+
+ for(i=0; i<4; i++){
+
+ bRet = _i2c_write_(MCSDL_I2C_SLAVE_ADDR_ORG, &i2c_buffer[i], 1 );
+
+ if( !bRet )
+ goto MCSDL_I2C_PREPARE_ERASE_FLASH_FINISH;
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+ }
+
+ //-----------------------------
+ // Read Result
+ //-----------------------------
+
+ mcsdl_delay(MCSDL_DELAY_500US); // Delay 500usec
+
+ bRet = _i2c_read_(MCSDL_I2C_SLAVE_ADDR_ORG, &ucTemp, 1 );
+
+ if( bRet && ucTemp == MCSDL_ISP_ACK_PREPARE_ERASE_DONE ){
+
+ nRet = MCSDL_RET_SUCCESS;
+
+ }
+
+
+MCSDL_I2C_PREPARE_ERASE_FLASH_FINISH :
+
+ return nRet;
+
+}
+
+
+//--------------------------------------------
+//
+// Erase flash
+//
+//--------------------------------------------
+static int mcsdl_i2c_erase_flash(void)
+{
+ int nRet = MCSDL_RET_ERASE_FLASH_FAILED;
+
+ UINT8 i;
+ BOOLEAN bRet;
+
+ UINT8 i2c_buffer[1] = { MCSDL_ISP_CMD_ERASE};
+ UINT8 ucTemp;
+
+ //-----------------------------
+ // Send Erase code
+ //-----------------------------
+
+ for(i=0; i<1; i++){
+
+ bRet = _i2c_write_(MCSDL_I2C_SLAVE_ADDR_ORG, &i2c_buffer[i], 1 );
+
+ if( !bRet )
+ goto MCSDL_I2C_ERASE_FLASH_FINISH;
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+ }
+
+ //-----------------------------
+ // Read Result
+ //-----------------------------
+
+ mcsdl_delay(MCSDL_DELAY_45MS); // Delay 45ms
+
+
+ bRet = _i2c_read_(MCSDL_I2C_SLAVE_ADDR_ORG, &ucTemp, 1 );
+
+ if( bRet && ucTemp == MCSDL_ISP_ACK_ERASE_DONE ){
+
+ nRet = MCSDL_RET_SUCCESS;
+
+ }
+
+
+MCSDL_I2C_ERASE_FLASH_FINISH :
+
+ return nRet;
+
+}
+
+
+//--------------------------------------------
+//
+// Erase flash for MCS-5000
+//
+//--------------------------------------------
+static int mcsdl_i2c_erase_flash_5000(void)
+{
+ int nRet = MCSDL_RET_ERASE_FLASH_FAILED;
+
+ UINT8 i;
+ BOOLEAN bRet;
+
+ UINT8 i2c_buffer[4] = { MCSDL_ISP_CMD_ERASE,
+ MCSDL_ISP_PROGRAM_TIMING_VALUE_3,
+ MCSDL_ISP_PROGRAM_TIMING_VALUE_4,
+ MCSDL_ISP_PROGRAM_TIMING_VALUE_5 };
+
+ //-----------------------------
+ // Send Erase code
+ //-----------------------------
+
+ for(i=0; i<4; i++){
+
+ bRet = _i2c_write_(MCSDL_I2C_SLAVE_ADDR_ORG_5000, &i2c_buffer[i], 1 );
+
+ if( !bRet )
+ goto MCSDL_I2C_ERASE_FLASH_FINISH;
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+ }
+
+ //-----------------------------
+ // Read Result
+ //-----------------------------
+
+ mcsdl_delay(MCSDL_DELAY_45MS); // Delay 45ms
+
+
+ bRet = _i2c_read_(MCSDL_I2C_SLAVE_ADDR_ORG_5000, i2c_buffer, 1 );
+
+ if( bRet && i2c_buffer[0] == MCSDL_ISP_ACK_ERASE_DONE ){
+
+ nRet = MCSDL_RET_SUCCESS;
+
+ }
+
+
+MCSDL_I2C_ERASE_FLASH_FINISH :
+
+ return nRet;
+
+}
+
+
+//--------------------------------------------
+//
+// Read flash
+//
+//--------------------------------------------
+static int mcsdl_i2c_read_flash( UINT8 *pBuffer, UINT16 nAddr_start, UINT8 cLength)
+{
+ int nRet = MCSDL_RET_READ_FLASH_FAILED;
+
+ int i;
+ BOOLEAN bRet;
+ UINT8 cmd[4];
+ UINT8 ucTemp;
+
+ //-----------------------------------------------------------------------------
+ // Send Read Flash command [ Read code - address high - address low - size ]
+ //-----------------------------------------------------------------------------
+
+ cmd[0] = MCSDL_ISP_CMD_READ_FLASH;
+ cmd[1] = (UINT8)((nAddr_start >> 8 ) & 0xFF);
+ cmd[2] = (UINT8)((nAddr_start ) & 0xFF);
+ cmd[3] = cLength;
+
+ for(i=0; i<4; i++){
+
+ if(MCS_VERSION==MCS5080_CHIP)
+ bRet = _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG, &cmd[i], 1 );
+ else
+ bRet = _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, &cmd[i], 1 );
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_READ_FLASH_FINISH;
+
+ }
+
+ //----------------------------------
+ // Read 'Result of command'
+ //----------------------------------
+ if(MCS_VERSION==MCS5080_CHIP)
+ {
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG, &ucTemp, 1 );
+
+ if( !bRet || ucTemp != MCSDL_MDS_ACK_READ_FLASH){
+
+ goto MCSDL_I2C_READ_FLASH_FINISH;
+ }
+ }
+
+ //----------------------------------
+ // Read Data [ pCmd[3] == Size ]
+ //----------------------------------
+ for(i=0; i<(int)cmd[3]; i++){
+
+ mcsdl_delay(MCSDL_DELAY_100US); // Delay about 100us
+
+ if(MCS_VERSION==MCS5080_CHIP)
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG, pBuffer++, 1 );
+ else
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, pBuffer++, 1 );
+
+ if( bRet == FALSE && i!=(int)(cmd[3]-1) )
+ goto MCSDL_I2C_READ_FLASH_FINISH;
+ }
+
+ nRet = MCSDL_RET_SUCCESS;
+
+
+MCSDL_I2C_READ_FLASH_FINISH :
+
+ return nRet;
+}
+
+
+//--------------------------------------------
+//
+// Program information
+//
+//--------------------------------------------
+static int mcsdl_i2c_program_info(void)
+{
+
+ int nRet = MCSDL_RET_PREPARE_PROGRAM_FAILED;
+
+ int i;
+ int j;
+ BOOLEAN bRet;
+
+ UINT8 i2c_buffer[5] = { MCSDL_ISP_CMD_PROGRAM_INFORMATION,
+ MCSDL_ISP_PROGRAM_TIMING_VALUE_2,
+ 0x00, // High addr
+ 0x00, // Low addr
+ 0x00 }; // Data
+
+ UINT8 info_data[] = { 0x78, 0x00, 0xC0, 0xD4, 0x01 };
+
+ //------------------------------------------------------
+ // Send information signal for programming flash
+ //------------------------------------------------------
+ for(i=0; i<5; i++){
+
+ i2c_buffer[3] = 0x08 + i; // Low addr
+ i2c_buffer[4] = info_data[i]; // Program data
+
+ for(j=0; j<5; j++){
+
+ bRet = _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, &i2c_buffer[j], 1 );
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_PROGRAM_INFO_FINISH;
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+ }
+
+ mcsdl_delay(MCSDL_DELAY_500US); // delay about 500us
+
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, &i2c_buffer[4], 1 );
+
+ if( bRet == FALSE || i2c_buffer[4] != MCSDL_I2C_ACK_PROGRAM_INFORMATION )
+ goto MCSDL_I2C_PROGRAM_INFO_FINISH;
+
+ mcsdl_delay(MCSDL_DELAY_100US); // delay about 100us
+
+ }
+
+ nRet = MCSDL_RET_SUCCESS;
+
+MCSDL_I2C_PROGRAM_INFO_FINISH :
+
+ return nRet;
+
+}
+
+
+//--------------------------------------------
+//
+// Prepare Program
+//
+//--------------------------------------------
+static int mcsdl_i2c_prepare_program(void)
+{
+
+ int nRet = MCSDL_RET_PREPARE_PROGRAM_FAILED;
+
+ int i;
+ BOOLEAN bRet;
+
+ UINT8 i2c_buffer[5] = { MCSDL_ISP_CMD_PROGRAM_TIMING,
+ MCSDL_ISP_PROGRAM_TIMING_VALUE_0,
+ MCSDL_ISP_PROGRAM_TIMING_VALUE_1,
+ MCSDL_ISP_PROGRAM_TIMING_VALUE_2
+ };
+
+ //------------------------------------------------------
+ // Write Program timing information
+ //------------------------------------------------------
+ for(i=0; i<4; i++){
+
+ bRet = _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG, &i2c_buffer[i], 1 );
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_PREPARE_PROGRAM_FINISH;
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+ }
+
+ mcsdl_delay(MCSDL_DELAY_500US); // delay about 500us
+
+ //------------------------------------------------------
+ // Read command's result
+ //------------------------------------------------------
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG, &i2c_buffer[4], 1 );
+
+ if( bRet == FALSE || i2c_buffer[4] != MCSDL_I2C_ACK_PREPARE_PROGRAM)
+ goto MCSDL_I2C_PREPARE_PROGRAM_FINISH;
+
+ mcsdl_delay(MCSDL_DELAY_100US); // delay about 100us
+
+ nRet = MCSDL_RET_SUCCESS;
+
+MCSDL_I2C_PREPARE_PROGRAM_FINISH :
+
+ return nRet;
+
+}
+
+//--------------------------------------------
+//
+// Program Flash
+//
+//--------------------------------------------
+
+static int mcsdl_i2c_program_flash(UINT8 * pData, UINT16 nAddr_start,
+ UINT8 cLength)
+{
+ int nRet = MCSDL_RET_PROGRAM_FLASH_FAILED;
+
+ int i;
+ BOOLEAN bRet;
+ UINT8 cData;
+ UINT8 cmd[4];
+
+ //-----------------------------
+ // Send Read code
+ //-----------------------------
+
+ cmd[0] = MCSDL_ISP_CMD_PROGRAM_FLASH;
+ cmd[1] = (UINT8)((nAddr_start >> 8 ) & 0xFF);
+ cmd[2] = (UINT8)((nAddr_start ) & 0xFF);
+ cmd[3] = cLength;
+
+ for(i=0; i<4; i++){
+
+ bRet = _i2c_write_(MCSDL_I2C_SLAVE_ADDR_ORG, &cmd[i], 1 );
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_PROGRAM_FLASH_FINISH;
+
+ }
+ //-----------------------------
+ // Check command result
+ //-----------------------------
+
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG, &cData, 1 );
+
+ if( bRet == FALSE || cData != MCSDL_MDS_ACK_PROGRAM_FLASH ){
+
+ goto MCSDL_I2C_PROGRAM_FLASH_FINISH;
+ }
+
+
+ //-----------------------------
+ // Program Data
+ //-----------------------------
+
+ mcsdl_delay(MCSDL_DELAY_150US); // Delay about 150us
+
+ for(i=0; i<(int)cmd[3]; i+=2){
+
+
+ bRet = _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG, &pData[i+1], 1 );
+
+ mcsdl_delay(MCSDL_DELAY_150US); // Delay about 150us
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_PROGRAM_FLASH_FINISH;
+
+
+ bRet = _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG, &pData[i], 1 );
+
+ mcsdl_delay(MCSDL_DELAY_150US); // Delay about 150us
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_PROGRAM_FLASH_FINISH;
+
+ }
+
+
+ nRet = MCSDL_RET_SUCCESS;
+
+MCSDL_I2C_PROGRAM_FLASH_FINISH :
+
+ return nRet;
+}
+
+//--------------------------------------------
+//
+// Program Flash for MCS-5000
+//
+//--------------------------------------------
+
+static int mcsdl_i2c_program_flash_5000( UINT8 *pData, UINT16 nAddr_start, UINT8 cLength )
+{
+ int nRet = MCSDL_RET_PROGRAM_FLASH_FAILED;
+
+ int i;
+ BOOLEAN bRet;
+ UINT8 cData;
+
+ UINT8 cmd[4];
+
+ //-----------------------------
+ // Send Read code
+ //-----------------------------
+
+ cmd[0] = MCSDL_ISP_CMD_PROGRAM_FLASH;
+ cmd[1] = (UINT8)((nAddr_start >> 8 ) & 0xFF);
+ cmd[2] = (UINT8)((nAddr_start ) & 0xFF);
+ cmd[3] = cLength;
+
+ for(i=0; i<4; i++){
+
+ bRet = _i2c_write_(MCSDL_I2C_SLAVE_ADDR_ORG_5000, &cmd[i], 1 );
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_PROGRAM_FLASH_FINISH;
+
+ }
+
+ //-----------------------------
+ // Program Data
+ //-----------------------------
+
+ mcsdl_delay(MCSDL_DELAY_500US); // Delay about 500us
+
+ for(i=0; i<(int)(cmd[3]); i++){
+
+
+ bRet = _i2c_write_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, &pData[i], 1 );
+
+ mcsdl_delay(MCSDL_DELAY_500US); // Delay about 500us
+
+ if( bRet == FALSE )
+ goto MCSDL_I2C_PROGRAM_FLASH_FINISH;
+ }
+
+ //-----------------------------
+ // Get result
+ //-----------------------------
+
+ bRet = _i2c_read_( MCSDL_I2C_SLAVE_ADDR_ORG_5000, &cData, 1 );
+
+ if( bRet == FALSE || cData != MCSDL_MDS_ACK_PROGRAM_FLASH )
+ goto MCSDL_I2C_PROGRAM_FLASH_FINISH;
+
+ nRet = MCSDL_RET_SUCCESS;
+
+MCSDL_I2C_PROGRAM_FLASH_FINISH :
+
+ return nRet;
+}
+
+
+//============================================================
+//
+// Delay Function
+//
+//============================================================
+static void mcsdl_delay(UINT32 nCount)
+{
+
+ #if 1
+
+ udelay(nCount); //1 Baseband delay function
+
+ #else
+
+ UINT32 i;
+
+ for(i=0;i<nCount;i++){
+
+ }
+
+ #endif
+}
+
+
+//============================================================
+//
+// Debugging print functions.
+//
+// Change uart_printf() to Baseband printing function
+//
+//============================================================
+
+#if MELFAS_ENABLE_DBG_PRINT
+
+static void mcsdl_print_result(int nRet)
+{
+ if( nRet == MCSDL_RET_SUCCESS ){
+
+ uart_printf(" MELFAS Firmware downloading SUCCESS.\n");
+
+ }else{
+
+ uart_printf(" MELFAS Firmware downloading FAILED : ");
+
+ switch( nRet ){
+
+ case MCSDL_RET_SUCCESS : uart_printf("MCSDL_RET_SUCCESS\n" ); break;
+ case MCSDL_RET_ENTER_DOWNLOAD_MODE_FAILED : uart_printf("MCSDL_RET_ENTER_ISP_MODE_FAILED\n" ); break;
+ case MCSDL_RET_ERASE_FLASH_FAILED : uart_printf("MCSDL_RET_ERASE_FLASH_FAILED\n" ); break;
+ case MCSDL_RET_READ_FLASH_FAILED : uart_printf("MCSDL_RET_READ_FLASH_FAILED\n" ); break;
+ case MCSDL_RET_READ_EEPROM_FAILED : uart_printf("MCSDL_RET_READ_EEPROM_FAILED\n" ); break;
+ case MCSDL_RET_READ_INFORMAION_FAILED : uart_printf("MCSDL_RET_READ_INFORMAION_FAILED\n" ); break;
+ case MCSDL_RET_PROGRAM_FLASH_FAILED : uart_printf("MCSDL_RET_PROGRAM_FLASH_FAILED\n" ); break;
+ case MCSDL_RET_PROGRAM_EEPROM_FAILED : uart_printf("MCSDL_RET_PROGRAM_EEPROM_FAILED\n" ); break;
+ case MCSDL_RET_PREPARE_PROGRAM_FAILED : uart_printf("MCSDL_RET_PROGRAM_INFORMAION_FAILED\n" ); break;
+ case MCSDL_RET_PROGRAM_VERIFY_FAILED : uart_printf("MCSDL_RET_PROGRAM_VERIFY_FAILED\n" ); break;
+
+ case MCSDL_RET_WRONG_MODE_ERROR : uart_printf("MCSDL_RET_WRONG_MODE_ERROR\n" ); break;
+ case MCSDL_RET_WRONG_SLAVE_SELECTION_ERROR : uart_printf("MCSDL_RET_WRONG_SLAVE_SELECTION_ERROR\n" ); break;
+ case MCSDL_RET_COMMUNICATION_FAILED : uart_printf("MCSDL_RET_COMMUNICATION_FAILED\n" ); break;
+ case MCSDL_RET_READING_HEXFILE_FAILED : uart_printf("MCSDL_RET_READING_HEXFILE_FAILED\n" ); break;
+ case MCSDL_RET_WRONG_PARAMETER : uart_printf("MCSDL_RET_WRONG_PARAMETER\n" ); break;
+ case MCSDL_RET_FILE_ACCESS_FAILED : uart_printf("MCSDL_RET_FILE_ACCESS_FAILED\n" ); break;
+ case MCSDL_RET_MELLOC_FAILED : uart_printf("MCSDL_RET_MELLOC_FAILED\n" ); break;
+ case MCSDL_RET_WRONG_MODULE_REVISION : uart_printf("MCSDL_RET_WRONG_MODULE_REVISION\n" ); break;
+
+ default : uart_printf("UNKNOWN ERROR. [0x%02X].\n", nRet ); break;
+ }
+
+ uart_printf("\n");
+ }
+
+}
+
+#endif
+
+//============================================================
+//
+// Porting section 4-1. Delay function
+//
+// For initial testing of delay and gpio control
+//
+// You can confirm GPIO control and delay time by calling this function.
+//
+//============================================================
+
+#if MELFAS_ENABLE_DELAY_TEST
+
+
+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
+
+ TKEY_I2C_SET_OUTPUT();
+ TKEY_CE_SET_OUTPUT();
+ TKEY_INTR_SET_OUTPUT();
+ TKEY_RESETB_SET_OUTPUT();
+
+ //--------------------------------
+ // Repeating 'nCount' times
+ //--------------------------------
+
+
+ for( i=0; i<nCount; i++ ){
+
+ TKEY_I2C_SET_HIGH(); // NORMAL
+ TKEY_VDD_SET_HIGH();
+ TKEY_CE_SET_HIGH();
+ TKEY_RESETB_SET_HIGH();
+
+ mcsdl_delay(MCSDL_DELAY_15US);
+
+ TKEY_VDD_SET_LOW(); // VDD & CE LOW
+ TKEY_CE_SET_LOW();
+ TKEY_I2C_SCL_SET_LOW(); // SCL LOW
+
+ mcsdl_delay(MCSDL_DELAY_100US)
+
+ TKEY_VDD_SET_HIGH(); // VDD & CE HIGH
+ TKEY_CE_SET_HIGH();
+ TKEY_I2C_SCL_SET_HIGH(); // SCL HIGH
+
+
+ TKEY_INTR_SET_LOW(); // INTR & RESETB LOW
+ TKEY_RESETB_SET_LOW();
+ TKEY_I2C_SCL_SET_LOW(); // SCL LOW
+
+ mcsdl_delay(MCSDL_DELAY_500US);
+
+ TKEY_INTR_SET_HIGH(); // INTR & RESETB HIGH
+ TKEY_RESETB_SET_HIGH();
+ TKEY_I2C_SCL_SET_HIGH(); // SCL HIGH
+
+ TKEY_I2C_SCL_SET_LOW(); // SCL LOW
+
+ mdelay(MCSDL_DELAY_1MS);
+
+ TKEY_I2C_SCL_SET_HIGH(); // SCL HIGH
+
+ TKEY_I2C_SDA_SET_LOW(); // SDA LOW
+
+ mcsdl_delay(MCSDL_DELAY_25MS);
+
+ TKEY_I2C_SDA_SET_HIGH(); // SDA HIGH
+ TKEY_I2C_SCL_SET_LOW(); // SCL LOW
+
+ mcsdl_delay(MCSDL_DELAY_45MS);
+
+ TKEY_I2C_SCL_SET_HIGH(); // SCL HIGH
+ }
+
+
+ TKEY_INTR_SET_INPUT();
+
+ MELFAS_DISABLE_WATCHDOG_TIMER_RESET(); // Roll-back Baseband touch interrupt ISR.
+ MELFAS_ROLLBACK_WATCHDOG_TIMER_RESET(); // Roll-back Baseband watchdog timer
+}
+
+
+#endif