aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/mms100_ISP_download.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/mms100_ISP_download.c')
-rw-r--r--drivers/input/touchscreen/mms100_ISP_download.c1267
1 files changed, 1267 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/mms100_ISP_download.c b/drivers/input/touchscreen/mms100_ISP_download.c
new file mode 100644
index 0000000..799ec37
--- /dev/null
+++ b/drivers/input/touchscreen/mms100_ISP_download.c
@@ -0,0 +1,1267 @@
+/*
+*--------------------------------------------------------
+*
+*
+* Melfas MMS100 Series Download base v1.7 2011.09.23
+*
+*/
+#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 <linux/fcntl.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/uaccess.h>
+#include <linux/fs.h>
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/syscalls.h>
+
+#include "mms100_ISP_download.h"
+#include "MMS100_ISC_Initial.h"
+/*
+*============================================================
+*
+* Include MELFAS Binary code File ( ex> MELFAS_FIRM_bin.c)
+*
+* Warning!!!!
+* Please, don't add binary.c file into project
+* Just #include here !!
+*
+*============================================================
+*/
+
+#include "465_SMD_V61.c"
+#include "M0_D2_C1_V74.c"
+#define MELFAS_FW1 "/sdcard/midas_firmware.bin"
+
+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,
+ struct melfas_tsi_platform_data *ts_data);
+
+static void mcsdl_set_ready(struct melfas_tsi_platform_data *ts_data);
+static void mcsdl_reboot_mcs(struct melfas_tsi_platform_data *ts_data);
+
+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);
+
+#if defined(CONFIG_MACH_C1CTC) || defined(CONFIG_MACH_M0_CHNOPEN) ||\
+ defined(CONFIG_MACH_M0_CMCC) || defined(CONFIG_MACH_M0_CTC)
+extern unsigned int lcdtype;
+#endif
+/*
+*---------------------------------
+* Delay functions
+*---------------------------------
+*/
+void mcsdl_delay(UINT32 nCount);
+
+/*
+*---------------------------------
+* 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 mms100_ISP_download_binary_data(int dl_mode,
+ struct melfas_tsi_platform_data *ts_data)
+{
+ int nRet = 0;
+ int retry_cnt = 0;
+
+#if 0
+#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 */
+
+#endif
+
+ /*
+ *------------------------
+ * Run Download
+ *------------------------
+ */
+
+ for (retry_cnt = 0; retry_cnt < 5; retry_cnt++) {
+ if (dl_mode == 0x01) { /*MELFAS_ISP_DOWNLOAD */
+
+#if defined(CONFIG_MACH_C1CTC) || defined(CONFIG_MACH_M0_CHNOPEN) || \
+ defined(CONFIG_MACH_M0_CTC)
+ if (lcdtype == 0x20) {
+ nRet =
+ mcsdl_download((const UINT8*)MELFAS_binary_4_65,
+ (const UINT16)MELFAS_binary_nLength_4_65,
+ 0, ts_data);
+
+ printk(KERN_DEBUG "<MELFAS> lcdtype is 4.8. ISP firmware update with 4.65 firmware\n");
+ } else {
+ nRet =
+ mcsdl_download((const UINT8*)MELFAS_binary,
+ (const UINT16)MELFAS_binary_nLength,
+ 0, ts_data);
+
+ printk(KERN_DEBUG "<MELFAS> lcdtype is 4.65. ISP firmware update with 4.8 firmware\n");
+ }
+#elif defined(CONFIG_MACH_M0_CMCC)
+ if (lcdtype == 0x20) {
+ nRet =
+ mcsdl_download((const UINT8*)MELFAS_binary,
+ (const UINT16)MELFAS_binary_nLength,
+ 0, ts_data);
+
+ printk(KERN_DEBUG "<MELFAS> lcdtype is 4.8. ISP firmware update with 4.8 firmware\n");
+ } else {
+ nRet =
+ mcsdl_download((const UINT8*)MELFAS_binary_4_65,
+ (const UINT16)MELFAS_binary_nLength_4_65,
+ 0, ts_data);
+
+ printk(KERN_DEBUG "<MELFAS> lcdtype is 4.65. ISP firmware update with 4.65 firmware\n");
+ }
+#else
+
+#if defined(CONFIG_MACH_M0)
+ if (system_rev == 2 || system_rev >= 5)
+#else
+ if (system_rev == 2 || system_rev >= 4)
+#endif
+ nRet =
+ mcsdl_download((const UINT8 *)MELFAS_binary,
+ (const UINT16)MELFAS_binary_nLength,
+ 0, ts_data);
+ else
+ nRet =
+ mcsdl_download((const UINT8 *)MELFAS_binary_4_65,
+ (const UINT16)MELFAS_binary_nLength_4_65,
+ 0, ts_data);
+#endif
+ }
+ else { /*MELFAS_ISC_DOWNLOAD */
+
+ nRet = mcsdl_download((const UINT8 *)
+ MELFAS_MMS100_Initial_binary,
+ (const UINT16)
+ MELFAS_MMS100_Initial_nLength, 0,
+ ts_data);
+ }
+#if MELFAS_2CHIP_DOWNLOAD_ENABLE
+ if (!nRet) {
+ if (dl_mode == 0x01) /*MELFAS_ISP_DOWNLOAD */
+ nRet = mcsdl_download((const UINT8 *)MELFAS_binary, (const UINT16)MELFAS_binary_nLength, 1, ts_data); /* Slave Binary data download */
+ else /*MELFAS_ISC_DOWNLOAD */
+ nRet = mcsdl_download((const UINT8 *)
+ MELFAS_MMS100_Initial_binary, (const UINT16)
+ MELFAS_MMS100_Initial_nLength, 1, ts_data);
+ }
+#endif
+ if (!nRet)
+ break;
+ }
+
+ MELFAS_ROLLBACK_BASEBAND_ISR(); /* Roll-back Baseband touch interrupt ISR. */
+ MELFAS_ROLLBACK_WATCHDOG_TIMER_RESET(); /* Roll-back Baseband watchdog timer */
+
+ fw_error:
+ if (nRet) {
+ mcsdl_erase_flash(0);
+ mcsdl_erase_flash(1);
+ }
+ return nRet;
+}
+
+int mms100_ISP_download_binary_file(struct melfas_tsi_platform_data *ts_data)
+{
+ 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(Core + Private Custom)
+ * *pBinary[1] : Binary data(Public Custom)
+ * nBinary_length[0] : Firmware size(Core + Private Custom)
+ * nBinary_length[1] : Firmware size(Public Custom)
+ * 3. Run mcsdl_download( pBinary[IdxNum], nBinary_length[IdxNum], IdxNum);
+ * IdxNum : 0 (Master Chip Download)
+ * IdxNum : 1 (2Chip Download)
+ *
+ *==================================================
+ */
+#if 1
+
+ int nRet = 0;
+ /*int retry_cnt = 0; */
+ long fw1_size = 0;
+ unsigned char *fw_data1;
+ struct file *filp;
+ loff_t pos;
+ int ret = 0;
+ mm_segment_t oldfs;
+ /*spinlock_t lock; */
+
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ filp = filp_open(MELFAS_FW1, O_RDONLY, 0);
+ if (IS_ERR(filp)) {
+ pr_err("[TSP]file open error:%d\n", (s32) filp);
+ return -1;
+ }
+
+ fw1_size = filp->f_path.dentry->d_inode->i_size;
+ pr_info("[TSP]Size of the file : %ld(bytes)\n", fw1_size);
+
+ fw_data1 = kmalloc(fw1_size, GFP_KERNEL);
+ memset(fw_data1, 0, fw1_size);
+
+ pos = 0;
+ memset(fw_data1, 0, fw1_size);
+ ret = vfs_read(filp, (char __user *)fw_data1, fw1_size, &pos);
+
+ if (ret != fw1_size) {
+ pr_err("[TSP]Failed to read file %s (ret = %d)\n", MELFAS_FW1,
+ ret);
+ kfree(fw_data1);
+ filp_close(filp, current->files);
+ return -1;
+ }
+
+ filp_close(filp, current->files);
+
+ set_fs(oldfs);
+
+#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[0] != NULL && nBinary_length[0] > 0
+ && nBinary_length[0] < MELFAS_FIRMWARE_MAX_SIZE) {
+ /*
+ *------------------------
+ * Run Download
+ *------------------------
+ */
+ nRet =
+ mcsdl_download((const UINT8 *)pBinary[0],
+ (const UINT16)nBinary_length[0], i,
+ ts_data);
+ } 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
+ kfree(fw_data1);
+
+ return (nRet == MCSDL_RET_SUCCESS);
+
+}
+
+/*
+*------------------------------------------------------------------
+*
+* Download function
+*
+*------------------------------------------------------------------
+*/
+static int mcsdl_download(const UINT8 * pBianry, const UINT16 unLength,
+ INT8 IdxNum, struct melfas_tsi_platform_data *ts_data)
+{
+ int nRet;
+ /*
+ *---------------------------------
+ * 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("<melfas> - Starting download...\n");
+#endif
+
+ /*
+ *---------------------------------
+ * Make it ready
+ *---------------------------------
+ */
+#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ printk("<melfas> > Ready\n");
+#endif
+
+ mcsdl_set_ready(ts_data);
+
+ /*
+ *---------------------------------
+ * Erase Flash
+ *---------------------------------
+ */
+#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ printk("<melfas> > Erase\n");
+#endif
+
+ nRet = mcsdl_erase_flash(IdxNum);
+
+ if (nRet != MCSDL_RET_SUCCESS)
+ goto MCSDL_DOWNLOAD_FINISH;
+ /*
+ *---------------------------------
+ * Program Flash
+ *---------------------------------
+ */
+#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ printk("<melfas> > Program ");
+#endif
+
+/* if(IdxNum > 0)
+ mcsdl_set_ready();
+*/
+
+ nRet =
+ mcsdl_program_flash((UINT8 *) pBianry, (UINT16) unLength, IdxNum);
+ if (nRet != MCSDL_RET_SUCCESS)
+ goto MCSDL_DOWNLOAD_FINISH;
+ /*
+ *---------------------------------
+ * Verify flash
+ *---------------------------------
+ */
+#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ printk("<melfas> > Verify ");
+#endif
+ nRet = mcsdl_verify_flash((UINT8 *) pBianry, (UINT16) unLength, IdxNum);
+ if (nRet != MCSDL_RET_SUCCESS)
+ goto MCSDL_DOWNLOAD_FINISH;
+
+ 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("<melfas> > Rebooting\n");
+ printk("<melfas> - Fin.\n\n");
+#endif
+
+ mcsdl_reboot_mcs(ts_data);
+
+ 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'
+ *----------------------------------------
+ */
+/*start ADD DELAY*/
+ mcsdl_read_flash_from(readBuffer, 0x0000, 16, IdxNum);
+ mcsdl_read_flash_from(&readBuffer[16], 0x7FF0, 16, IdxNum);
+ /*end ADD DELAY */
+ if (IdxNum > 0) {
+ eraseCompareValue = 0x00;
+ }
+ /* Compare with '0xFF' */
+ for (i = 0; i < 32; i++) {
+ if (readBuffer[i] != eraseCompareValue)
+ return MCSDL_RET_ERASE_FLASH_VERIFY_FAILED;
+ }
+
+ 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;
+
+/*kang*/
+
+ while ((addr * 4) < (int)unLength) {
+ if ((unLength - (addr * 4)) < MELFAS_TRANSFER_LENGTH) {
+ ucLength = (UINT8) (unLength - (addr * 4));
+ }
+ /*
+ *--------------------------------------
+ * Select ISP Mode
+ *--------------------------------------
+ */
+
+ /* start ADD DELAY */
+ mcsdl_delay(MCSDL_DELAY_40US);
+ /*end ADD DELAY */
+ 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] <<
+ *---------------------------------------------
+ */
+ header = ((addr & 0x1FFF) << 1) | 0x0;
+ header = header << 14;
+
+ /*Write 18bits */
+ mcsdl_write_bits(header, 18);
+ /*start ADD DELAY */
+ /*end ADD DELAY */
+
+ /*
+ *---------------------------------
+ * 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();
+/*kang*/
+ 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();
+/*start ADD DELAY*/
+ mcsdl_delay(MCSDL_DELAY_300US);
+/*end ADD DELAY*/
+
+ }
+
+ 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();
+
+ }
+
+#if MELFAS_ENABLE_DBG_PROGRESS_PRINT
+ /*printk("\n"); */
+#endif
+
+ return MCSDL_RET_SUCCESS;
+
+}
+
+static void mcsdl_set_ready(struct melfas_tsi_platform_data *ts_data)
+{
+ /*
+ *--------------------------------------------
+ * Tkey module reset
+ *--------------------------------------------
+ */
+
+ ts_data->power(0); /*MCSDL_VDD_SET_LOW(); * power */
+ /*MCSDL_CE_SET_LOW(); */
+ /*MCSDL_CE_SET_OUTPUT(); */
+
+ MCSDL_SET_GPIO_I2C();
+
+ MCSDL_GPIO_SDA_SET_LOW();
+ MCSDL_GPIO_SDA_SET_OUTPUT(0);
+
+ MCSDL_GPIO_SCL_SET_LOW();
+ MCSDL_GPIO_SCL_SET_OUTPUT(1);
+
+ MCSDL_RESETB_SET_LOW();
+ MCSDL_RESETB_SET_OUTPUT(0);
+
+ /* mcsdl_delay(MCSDL_DELAY_25MS); * Delay for Stable VDD */
+ msleep(500);
+ ts_data->power(1); /*MCSDL_VDD_SET_HIGH(); */
+ /*MCSDL_CE_SET_HIGH(); */
+
+ MCSDL_GPIO_SCL_SET_LOW();
+ MCSDL_GPIO_SDA_SET_HIGH();
+ /*mcsdl_delay(MCSDL_DELAY_40MS); */
+ msleep(500);
+ /* Delay '30 msec' */
+
+}
+
+static void mcsdl_reboot_mcs(struct melfas_tsi_platform_data *ts_data)
+{
+ ts_data->power(0); /*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 */
+
+ ts_data->power(1); /*MCSDL_VDD_SET_HIGH(); */
+ /*MCSDL_CE_SET_HIGH(); */
+
+ MCSDL_RESETB_SET_HIGH();
+ MCSDL_RESETB_SET_INPUT();
+ MCSDL_GPIO_SCL_SET_INPUT();
+ MCSDL_GPIO_SDA_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 *pCode;
+
+ 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 };
+
+ pCode = enteringCodeMassErase;
+
+ /*
+ *------------------------------------
+ * 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();
+
+/*start add delay for INT*/
+ mcsdl_delay(MCSDL_DELAY_3US);
+/*end delay for INT*/
+
+ 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_GPIO_SDA_SET_HIGH(); */
+ /* MCSDL_GPIO_SDA_SET_OUTPUT(1); */
+
+ 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_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 : {mdelay(1); break;}*/
+/* case MCSDL_DELAY_5MS : {mdelay(5); break;}*/
+/* case MCSDL_DELAY_10MS : {mdelay(10); break;}*/
+ case MCSDL_DELAY_25MS:{
+ mdelay(25);
+ break;
+ }
+ case MCSDL_DELAY_30MS:{
+ mdelay(30);
+ break;
+ }
+ case MCSDL_DELAY_40MS:{
+ mdelay(40);
+ break;
+ }
+/* case MCSDL_DELAY_45MS : {mdelay(45); break;}*/
+ case MCSDL_DELAY_60MS:{
+ mdelay(60);
+ break;
+ }
+ case MCSDL_DELAY_100MS:
+ {
+ mdelay(100);
+ break;
+ }
+ case MCSDL_DELAY_500MS:{
+ mdelay(60);
+ 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;
+ }
+
+ }
+
+}
+
+#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