summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/cyttsp_ldr.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/cyttsp_ldr.h')
-rwxr-xr-xdrivers/input/touchscreen/cyttsp_ldr.h333
1 files changed, 333 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/cyttsp_ldr.h b/drivers/input/touchscreen/cyttsp_ldr.h
new file mode 100755
index 00000000000..95db89d0d13
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp_ldr.h
@@ -0,0 +1,333 @@
+/*
+ * Source for:
+ * Cypress TrueTouch(TM) Standard Product touchscreen driver.
+ *
+ * Copyright (C) 2009-2011 Cypress Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Cypress reserves the right to make changes without further notice
+ * to the materials described herein. Cypress does not assume any
+ * liability arising out of the application described herein.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com
+ *
+ */
+/*
+ ************************************************************************
+ * Compiled image bootloader functions
+ ************************************************************************
+ */
+#include "cyttsp_fw.h"
+#define CY_BL_PAGE_SIZE 16
+#define CY_BL_NUM_PAGES 5
+#define CY_MAX_DATA_LEN (CY_BL_PAGE_SIZE * 2)
+
+/* Timeout timer */
+static int cyttsp_check_polling(struct cyttsp *ts)
+{
+ return ts->platform_data->use_timer;
+}
+
+static void cyttsp_to_timer(unsigned long handle)
+{
+ struct cyttsp *ts = (struct cyttsp *)handle;
+
+ DBG(printk(KERN_INFO"%s: TTSP timeout timer event!\n", __func__);)
+ ts->to_timeout = true;
+ return;
+}
+
+static void cyttsp_setup_to_timer(struct cyttsp *ts)
+{
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+ setup_timer(&ts->to_timer, cyttsp_to_timer, (unsigned long) ts);
+}
+
+static void cyttsp_kill_to_timer(struct cyttsp *ts)
+{
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+ del_timer(&ts->to_timer);
+}
+
+static void cyttsp_start_to_timer(struct cyttsp *ts, int ms)
+{
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+ ts->to_timeout = false;
+ mod_timer(&ts->to_timer, jiffies + ms);
+}
+
+static bool cyttsp_timeout(struct cyttsp *ts)
+{
+ if (cyttsp_check_polling(ts))
+ return false;
+ else
+ return ts->to_timeout;
+}
+
+static void cyttsp_set_bl_ready(struct cyttsp *ts, bool set)
+{
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+ ts->bl_ready = set;
+ DBG(printk(KERN_INFO"%s: bl_ready=%d\n", __func__, (int)ts->bl_ready);)
+}
+
+static bool cyttsp_check_bl_ready(struct cyttsp *ts)
+{
+ if (cyttsp_check_polling(ts))
+ return true;
+ else
+ return ts->bl_ready;
+}
+
+static bool cyttsp_bl_err_status(struct cyttsp *ts)
+{
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+ return (((ts->bl_data.bl_status == 0x10) &&
+ (ts->bl_data.bl_error == 0x20)) ||
+ ((ts->bl_data.bl_status == 0x11) &&
+ (ts->bl_data.bl_error == 0x20)));
+}
+
+static bool cyttsp_wait_bl_ready(struct cyttsp *ts,
+ int pre_delay, int loop_delay, int max_try,
+ bool (*done)(struct cyttsp *ts))
+{
+ int tries;
+ bool rdy = false, tmo = false;
+
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+ DBG(printk(KERN_INFO"%s: pre-dly=%d loop-dly=%d, max-try=%d\n",
+ __func__, pre_delay, loop_delay, max_try);)
+
+ tries = 0;
+ ts->bl_data.bl_file = 0;
+ ts->bl_data.bl_status = 0;
+ ts->bl_data.bl_error = 0;
+ if (cyttsp_check_polling(ts)) {
+ msleep(pre_delay);
+ do {
+ msleep(abs(loop_delay));
+ cyttsp_load_bl_regs(ts);
+ } while (!done(ts) &&
+ tries++ < max_try);
+ DBG(printk(KERN_INFO"%s: polling mode tries=%d\n",
+ __func__, tries);)
+ } else {
+ cyttsp_start_to_timer(ts, abs(loop_delay) * max_try);
+ while (!rdy && !tmo) {
+ rdy = cyttsp_check_bl_ready(ts);
+ tmo = cyttsp_timeout(ts);
+ if (loop_delay < 0)
+ udelay(abs(loop_delay));
+ else
+ msleep(abs(loop_delay));
+ tries++;
+ }
+ DBG2(printk(KERN_INFO"%s: irq mode tries=%d rdy=%d tmo=%d\n",
+ __func__, tries, (int)rdy, (int)tmo);)
+ cyttsp_load_bl_regs(ts);
+ }
+
+ if (tries >= max_try || tmo)
+ return true; /* timeout */
+ else
+ return false;
+}
+
+static int cyttsp_wr_blk_chunks(struct cyttsp *ts, u8 cmd,
+ u8 length, const u8 *values)
+{
+ int retval = 0;
+ int block = 1;
+ bool timeout;
+
+ u8 dataray[CY_MAX_DATA_LEN];
+
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+
+ /* first page already includes the bl page offset */
+ memcpy(dataray, values, CY_BL_PAGE_SIZE + 1);
+ cyttsp_set_bl_ready(ts, false);
+ retval = ttsp_write_block_data(ts, cmd, CY_BL_PAGE_SIZE + 1, dataray);
+ values += CY_BL_PAGE_SIZE + 1;
+ length -= CY_BL_PAGE_SIZE + 1;
+ if (retval)
+ return retval;
+
+ /* remaining blocks require bl page offset stuffing */
+ while (length && (block < CY_BL_NUM_PAGES) && !(retval < 0)) {
+ dataray[0] = CY_BL_PAGE_SIZE * block;
+ timeout = cyttsp_wait_bl_ready(ts,
+ 1, -100, 100, cyttsp_bl_err_status);
+ if (timeout)
+ return -EIO;
+ memcpy(&dataray[1], values, length >= CY_BL_PAGE_SIZE ?
+ CY_BL_PAGE_SIZE : length);
+ cyttsp_set_bl_ready(ts, false);
+ retval = ttsp_write_block_data(ts, cmd,
+ length >= CY_BL_PAGE_SIZE ?
+ CY_BL_PAGE_SIZE + 1 : length + 1, dataray);
+ values += CY_BL_PAGE_SIZE;
+ length = length >= CY_BL_PAGE_SIZE ?
+ length - CY_BL_PAGE_SIZE : 0;
+ block++;
+ }
+
+ return retval;
+}
+
+static int cyttsp_load_app(struct cyttsp *ts)
+{
+ int retval = 0;
+ int rec;
+ bool timeout;
+
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+
+ printk(KERN_INFO "%s: "
+ "load file - tver=0x%02X%02X a_id=0x%02X%02X aver=0x%02X%02X\n",
+ __func__,
+ cyttsp_fw_tts_verh, cyttsp_fw_tts_verl,
+ cyttsp_fw_app_idh, cyttsp_fw_app_idl,
+ cyttsp_fw_app_verh, cyttsp_fw_app_verl);
+
+ /* download new TTSP Application to the Bootloader */
+ rec = 0;
+
+ /* send bootload initiation command */
+ printk(KERN_INFO"%s: Send BL Enter\n", __func__);
+ cyttsp_set_bl_ready(ts, false);
+ retval = ttsp_write_block_data(ts, CY_REG_BASE,
+ cyttsp_fw[rec].Length, cyttsp_fw[rec].Block);
+ rec++;
+ if (retval)
+ return retval;
+ timeout = cyttsp_wait_bl_ready(ts, 1, 100, 100, cyttsp_bl_err_status);
+ DBG(printk(KERN_INFO "%s: BL ENTER f=%02X s=%02X e=%02X t=%d\n",
+ __func__,
+ ts->bl_data.bl_file, ts->bl_data.bl_status,
+ ts->bl_data.bl_error, timeout);)
+ if (timeout)
+ goto loader_exit;
+
+ /* send bootload firmware load blocks */
+ printk(KERN_INFO"%s: Send BL Blocks\n", __func__);
+ while (cyttsp_fw[rec].Command == CY_BL_WRITE_BLK) {
+ DBG2(printk(KERN_INFO "%s:"
+ "BL DNLD Rec=% 3d Len=% 3d Addr=%04X\n",
+ __func__,
+ cyttsp_fw[rec].Record, cyttsp_fw[rec].Length,
+ cyttsp_fw[rec].Address);
+ )
+ retval = cyttsp_wr_blk_chunks(ts, CY_REG_BASE,
+ cyttsp_fw[rec].Length, cyttsp_fw[rec].Block);
+ if (retval < 0) {
+ DBG(printk(KERN_INFO "%s:"
+ "BL fail Rec=%3d retval=%d\n",
+ __func__,
+ cyttsp_fw[rec].Record, retval);
+ )
+ break;
+ } else {
+ cyttsp_wait_bl_ready(ts, 10, 1, 1000,
+ cyttsp_bl_err_status);
+ DBG(printk(KERN_INFO "%s: BL _LOAD "
+ "f=%02X s=%02X e=%02X\n",
+ __func__,
+ ts->bl_data.bl_file, ts->bl_data.bl_status,
+ ts->bl_data.bl_error);)
+ }
+ rec++;
+ }
+ if (retval < 0)
+ goto loader_exit;
+
+ /* send bootload terminate command */
+ printk(KERN_INFO"%s: Send BL Terminate\n", __func__);
+ cyttsp_set_bl_ready(ts, false);
+ retval = ttsp_write_block_data(ts, CY_REG_BASE,
+ cyttsp_fw[rec].Length, cyttsp_fw[rec].Block);
+ if (retval < 0)
+ goto loader_exit;
+ else
+ cyttsp_wait_bl_ready(ts, 1, 100, 100, cyttsp_bl_err_status);
+
+loader_exit:
+ /* reset TTSP Device back to bootloader mode */
+ retval = cyttsp_soft_reset(ts);
+
+ return retval;
+}
+
+static int cyttsp_loader(struct cyttsp *ts)
+{
+ int retval;
+
+ DBG(printk(KERN_INFO"%s: Enter\n", __func__);)
+
+ retval = cyttsp_load_bl_regs(ts);
+ if (retval < 0)
+ return retval;
+
+ printk(KERN_INFO "%s:"
+ "blttsp=0x%02X%02X flttsp=0x%02X%02X force=%d\n",
+ __func__,
+ ts->bl_data.ttspver_hi, ts->bl_data.ttspver_lo,
+ cyttsp_fw_tts_verh, cyttsp_fw_tts_verl,
+ ts->platform_data->use_force_fw_update);
+ printk(KERN_INFO "%s:"
+ "blappid=0x%02X%02X flappid=0x%02X%02X\n",
+ __func__,
+ ts->bl_data.appid_hi, ts->bl_data.appid_lo,
+ cyttsp_fw_app_idh, cyttsp_fw_app_idl);
+ printk(KERN_INFO "%s:"
+ "blappver=0x%02X%02X flappver=0x%02X%02X\n",
+ __func__,
+ ts->bl_data.appver_hi, ts->bl_data.appver_lo,
+ cyttsp_fw_app_verh, cyttsp_fw_app_verl);
+ printk(KERN_INFO "%s:"
+ "blcid=0x%02X%02X%02X flcid=0x%02X%02X%02X\n",
+ __func__,
+ ts->bl_data.cid_0, ts->bl_data.cid_1, ts->bl_data.cid_2,
+ cyttsp_fw_cid_0, cyttsp_fw_cid_1, cyttsp_fw_cid_2);
+
+ if (CY_DIFF(ts->bl_data.ttspver_hi, cyttsp_fw_tts_verh) ||
+ CY_DIFF(ts->bl_data.ttspver_lo, cyttsp_fw_tts_verl) ||
+ CY_DIFF(ts->bl_data.appid_hi, cyttsp_fw_app_idh) ||
+ CY_DIFF(ts->bl_data.appid_lo, cyttsp_fw_app_idl) ||
+ CY_DIFF(ts->bl_data.appver_hi, cyttsp_fw_app_verh) ||
+ CY_DIFF(ts->bl_data.appver_lo, cyttsp_fw_app_verl) ||
+ CY_DIFF(ts->bl_data.cid_0, cyttsp_fw_cid_0) ||
+ CY_DIFF(ts->bl_data.cid_1, cyttsp_fw_cid_1) ||
+ CY_DIFF(ts->bl_data.cid_2, cyttsp_fw_cid_2) ||
+ ts->platform_data->use_force_fw_update) {
+ /* load new app into TTSP Device */
+ cyttsp_setup_to_timer(ts);
+ ts->platform_data->power_state = CY_LDR_STATE;
+ retval = cyttsp_load_app(ts);
+ cyttsp_kill_to_timer(ts);
+
+ } else {
+ /* firmware file is a match with firmware in the TTSP device */
+ DBG(printk(KERN_INFO "%s: FW matches - no loader\n", __func__);)
+ }
+
+ if (retval < 0)
+ return retval;
+
+ return retval;
+}
+