Hi Tylor, On Oct 17 2023, Tylor Yang wrote: > The hx83102j is a TDDI IC (Touch with Display Driver). The > IC using SPI to transferring HID packet to host CPU. The IC also > report HID report descriptor for driver to register HID device. > The driver is designed as a framework for future expansion and > hx83102j is the first case. Each hx_spi_hid_hx8xxxxx modules are > mutual exclusive, it should be initiate one at a time. > > This driver takes a position similar to i2c-hid, it initialize > and control the touch IC below and register HID to upper hid-core. > When touch ic report an interrupt, it receive the data from IC > and report as HID input to hid-core. Let hid-core dispatch input > to registered hid-protocol and report to related input sub-system. > > This driver also provide advanced functions by hidraw interface: > - runtime firmware update > - debug functions, such as reg r/w > - self test for touch panel > > Due to patch size is too big, separate into 3 part. This is part 2. This is just wrong. A commit message is supposed to reflect what's in the code and why. Here you just copied/pasted the same commit message on all 3 patches, which means the information here is useless. I just don't know why you added 3260 lines to hx_ic_core.c, and I don't even want to know. I'm not sending the same email to 4/4, but the same comment applies to it. Please read the docs, watch talks from maintainers on how to submit a patch series, and/or try to get a mentor, because this really isn't the proper way to submit patches. Cheers, Benjamin > > Signed-off-by: Tylor Yang <tylor_yang@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx> > --- > drivers/hid/hx-hid/hx_ic_core.c | 3260 +++++++++++++++++++++++++++++++ > 1 file changed, 3260 insertions(+) > create mode 100644 drivers/hid/hx-hid/hx_ic_core.c > > diff --git a/drivers/hid/hx-hid/hx_ic_core.c b/drivers/hid/hx-hid/hx_ic_core.c > new file mode 100644 > index 000000000000..f1a53a5b8ccf > --- /dev/null > +++ b/drivers/hid/hx-hid/hx_ic_core.c > @@ -0,0 +1,3260 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Himax Driver Code for Common IC to simulate HID > + * > + * Copyright (C) 2023 Himax Corporation. > + * > + * This software is licensed under the terms of the GNU General Public > + * License version 2, as published by the Free Software Foundation, and > + * may be copied, distributed, and modified under those terms. > + * > + * 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. > + */ > + > +#include "hx_ic_core.h" > +#include "hx_plat.h" > +#include "hx_hid.h" > + > +/* CORE_IC */ > +/* IC side start*/ > +static void himax_mcu_burst_enable(struct himax_ts_data *ts, > + u8 auto_add_4_byte) > +{ > + u8 tmp_data[DATA_LEN_4]; > + int ret; > + > + /*I("Entering");*/ > + tmp_data[0] = IC_GET_VAL(data_conti); > + > + ret = himax_bus_write(ts, IC_GET_VAL(addr_conti), NULL, tmp_data, 1); > + if (ret < 0) { > + E("bus access fail!"); > + return; > + } > + > + tmp_data[0] = (IC_GET_VAL(data_incr4) | auto_add_4_byte); > + > + ret = himax_bus_write(ts, IC_GET_VAL(addr_incr4), NULL, tmp_data, 1); > + if (ret < 0) { > + E("bus access fail!"); > + return; > + } > +} > + > +static int himax_mcu_register_read(struct himax_ts_data *ts, u8 *addr, > + u8 *buf, u32 len) > +{ > + int ret = -1; > + > + mutex_lock(&ts->reg_lock); > + > + if (memcmp(addr, FLASH_GET_ARRAY(addr_spi200_data), 4) == 0) > + g_core_fp.fp_burst_enable(ts, 0); > + else if (len > DATA_LEN_4) > + g_core_fp.fp_burst_enable(ts, 1); > + else > + g_core_fp.fp_burst_enable(ts, 0); > + > + ret = himax_bus_write(ts, IC_GET_VAL(addr_ahb_addr_byte_0), addr, NULL, 4); > + if (ret < 0) { > + E("bus access fail!"); > + mutex_unlock(&ts->reg_lock); > + return BUS_FAIL; > + } > + > + ret = himax_bus_write(ts, IC_GET_VAL(addr_ahb_access_direction), NULL, > + IC_GET_ARRAY(data_ahb_access_direction_read), 1); > + if (ret < 0) { > + E("bus access fail!"); > + mutex_unlock(&ts->reg_lock); > + return BUS_FAIL; > + } > + > + ret = himax_bus_read(ts, IC_GET_VAL(addr_ahb_rdata_byte_0), buf, len); > + if (ret < 0) { > + E("bus access fail!"); > + mutex_unlock(&ts->reg_lock); > + return BUS_FAIL; > + } > + > + mutex_unlock(&ts->reg_lock); > + > + return NO_ERR; > +} > + > +static int himax_mcu_reg_read(struct himax_ts_data *ts, struct hx_reg_t *addr, > + struct data_pack_t *data) > +{ > + return g_core_fp.fp_register_read(ts, > + addr->data.byte, data->data.byte, data->len); > +} > + > +static int himax_mcu_register_write(struct himax_ts_data *ts, u8 *addr, > + u8 *val, u32 len) > +{ > + int ret = -1; > + const u32 max_trans_sz = 4 * 1024; > + int i = 0; > + u32 orig_addr = 0; > + union hx_dword_data_t temp_addr = {0}; > + u32 temp_len = 0; > + > + mutex_lock(&ts->reg_lock); > + > + if (memcmp(addr, FLASH_GET_ARRAY(addr_spi200_data), 4) == 0) > + g_core_fp.fp_burst_enable(ts, 0); > + else if (len > DATA_LEN_4) > + g_core_fp.fp_burst_enable(ts, 1); > + else > + g_core_fp.fp_burst_enable(ts, 0); > + > + if (len > max_trans_sz) { > + orig_addr = le32_to_cpup((__le32 *)addr); > + for (i = 0; i < len; i += max_trans_sz) { > + if ((len - i) > max_trans_sz) > + temp_len = max_trans_sz; > + else > + temp_len = len % max_trans_sz; > + temp_addr.dword = cpu_to_le32(orig_addr + i); > + ret = himax_bus_write(ts, IC_GET_VAL(addr_ahb_addr_byte_0), > + temp_addr.byte, val + i, temp_len + ADDR_LEN_4); > + if (ret < 0) { > + E("xfer fail!"); > + mutex_unlock(&ts->reg_lock); > + return BUS_FAIL; > + } > + } > + } else { > + ret = himax_bus_write(ts, IC_GET_VAL(addr_ahb_addr_byte_0), addr, val, > + len + ADDR_LEN_4); > + if (ret < 0) { > + E("xfer fail!"); > + mutex_unlock(&ts->reg_lock); > + return BUS_FAIL; > + } > + } > + > + mutex_unlock(&ts->reg_lock); > + > + return NO_ERR; > +} > + > +static int himax_mcu_reg_write(struct himax_ts_data *ts, > + struct hx_reg_t *addr, struct data_pack_t *data) > +{ > + return g_core_fp.fp_register_write(ts, > + addr->data.byte, data->data.byte, data->len); > +} > + > +static int himax_write_read_reg(struct himax_ts_data *ts, u8 *tmp_addr, > + u8 *tmp_data, u8 hb, u8 lb) > +{ > + u16 retry = 0; > + union hx_dword_data_t r_data = {0}; > + union hx_dword_data_t t_addr = {0}; > + union hx_dword_data_t t_data = {0}; > + > + memcpy(t_addr.byte, tmp_addr, ADDR_LEN_4); > + memcpy(t_data.byte, tmp_data, DATA_LEN_4); > + > + while (retry++ < 40) { /* ceil[16.6*2] */ > + g_core_fp.fp_register_read(ts, t_addr.byte, r_data.byte, DATA_LEN_4); > + D("Read handshake = 0x%08X:0x%08X", le32_to_cpu(t_addr.dword), > + le32_to_cpu(r_data.dword)); > + if (r_data.byte[1] == lb && r_data.byte[0] == hb) > + break; > + else if (r_data.byte[1] == hb && r_data.byte[0] == lb) > + return NO_ERR; > + > + g_core_fp.fp_register_write(ts, t_addr.byte, t_data.byte, DATA_LEN_4); > + D("Write handshake = 0x%08X:0x%08X", le32_to_cpu(t_addr.dword), > + le32_to_cpu(t_data.dword)); > + usleep_range(1000, 1100); > + } > + > + if (retry >= 40) > + goto FAIL; > + > + retry = 0; > + while (retry++ < 200) { /* self test item might take long time */ > + g_core_fp.fp_register_read(ts, t_addr.byte, r_data.byte, DATA_LEN_4); > + if (r_data.byte[1] == hb && r_data.byte[0] == lb) > + return NO_ERR; > + > + D("wait data ready %d times, handshake = 0x%08X:0x%08X", retry, > + le32_to_cpu(t_addr.dword), le32_to_cpu(r_data.dword)); > + usleep_range(10000, 10100); > + } > + > +FAIL: > + E("failed to handshaking with DSRAM"); > + E("addr = 0x%02X%02X%02X%02X; data = 0x%02X%02X%02X%02X", > + tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0], > + tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]); > + E("target = %02X%02X; r_data = %02X%02X", > + hb, lb, r_data.byte[1], r_data.byte[0]); > + > + return HX_RW_REG_FAIL; > +} > + > +static void himax_mcu_interface_on(struct himax_ts_data *ts) > +{ > + u8 tmp_data[DATA_LEN_4]; > + u8 tmp_data2[DATA_LEN_4]; > + int cnt = 0; > + int ret = 0; > + > + /* Read a dummy register to wake up BUS.*/ > + ret = himax_bus_read(ts, IC_GET_VAL(addr_ahb_rdata_byte_0), tmp_data, > + DATA_LEN_4); > + if (ret < 0) {/* to knock BUS*/ > + E("bus access fail!"); > + return; > + } > + > + do { > + tmp_data[0] = IC_GET_VAL(data_conti); > + > + ret = himax_bus_write(ts, IC_GET_VAL(addr_conti), NULL, tmp_data, 1); > + if (ret < 0) { > + E("bus access fail!"); > + return; > + } > + > + tmp_data[0] = IC_GET_VAL(data_incr4); > + > + ret = himax_bus_write(ts, IC_GET_VAL(addr_incr4), NULL, tmp_data, 1); > + if (ret < 0) { > + E("bus access fail!"); > + return; > + } > + > + /*Check cmd*/ > + himax_bus_read(ts, IC_GET_VAL(addr_conti), tmp_data, 1); > + himax_bus_read(ts, IC_GET_VAL(addr_incr4), tmp_data2, 1); > + > + if (tmp_data[0] == IC_GET_VAL(data_conti) && > + tmp_data2[0] == IC_GET_VAL(data_incr4)) > + break; > + > + usleep_range(1000, 1100); > + } while (++cnt < 10); > + > + if (cnt > 0) > + I("Polling burst mode: %d times", cnt); > +} > + > +static void himax_mcu_sense_on(struct himax_ts_data *ts, u8 flash_mode) > +{ > + u8 tmp_data[DATA_LEN_4]; > + int retry = 0; > + int ret = 0; > + > + I("Enter"); > + ts->notouch_frame = ts->ic_notouch_frame; > + g_core_fp.fp_interface_on(ts); > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_ctrl_fw_isr), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + usleep_range(10000, 11000); > + if (!flash_mode) { > + g_core_fp.fp_ic_reset(ts, false, false); > + } else { > + do { > + g_core_fp.fp_register_read(ts, > + FW_GET_ARRAY(addr_flag_reset_event), > + tmp_data, DATA_LEN_4); > + I("Read status from IC = %X,%X", tmp_data[0], tmp_data[1]); > + } while ((tmp_data[1] != 0x01 || > + tmp_data[0] != 0x00) && > + retry++ < 5); > + > + if (retry >= 5) { > + E("Fail"); > + g_core_fp.fp_ic_reset(ts, false, false); > + } else { > + I("OK and Read status from IC = %X,%X", > + tmp_data[0], tmp_data[1]); > + /* reset code*/ > + tmp_data[0] = 0x00; > + > + ret = himax_bus_write(ts, IC_GET_VAL(adr_i2c_psw_lb), NULL, > + tmp_data, 1); > + if (ret < 0) { > + E("cmd=%x bus access fail!", > + IC_GET_VAL(adr_i2c_psw_lb)); > + } > + ret = himax_bus_write(ts, IC_GET_VAL(adr_i2c_psw_ub), NULL, > + tmp_data, 1); > + if (ret < 0) { > + E("cmd=%x bus access fail!", > + IC_GET_VAL(adr_i2c_psw_ub)); > + } > + } > + } > +} > + > +static bool himax_mcu_sense_off(struct himax_ts_data *ts, bool check_en) > +{ > + u8 cnt = 0; > + u8 tmp_data[DATA_LEN_4]; > + int ret = 0; > + > + do { > + tmp_data[0] = IC_GET_VAL(data_i2c_psw_lb); > + tmp_data[1] = IC_GET_VAL(data_i2c_psw_ub); > + > + ret = himax_bus_write(ts, IC_GET_VAL(adr_i2c_psw_lb), NULL, tmp_data, > + 2); > + if (ret < 0) { > + E("bus access fail!"); > + return false; > + } > + > + g_core_fp.fp_register_read(ts, IC_GET_ARRAY(addr_cs_central_state), > + tmp_data, ADDR_LEN_4); > + I("Check enter_save_mode data[0]=%X", tmp_data[0]); > + > + if (tmp_data[0] == 0x0C) { > + g_core_fp.fp_register_write(ts, IC_GET_ARRAY(addr_tcon_on_rst), > + IC_GET_ARRAY(data_rst), DATA_LEN_4); > + usleep_range(1000, 1100); > + > + g_core_fp.fp_register_write(ts, IC_GET_ARRAY(addr_adc_on_rst), > + IC_GET_ARRAY(data_rst), DATA_LEN_4); > + usleep_range(1000, 1100); > + tmp_data[3] = IC_GET_ARRAY(data_rst)[3]; > + tmp_data[2] = IC_GET_ARRAY(data_rst)[2]; > + tmp_data[1] = IC_GET_ARRAY(data_rst)[1]; > + tmp_data[0] = IC_GET_ARRAY(data_rst)[0] | 0x01; > + g_core_fp.fp_register_write(ts, IC_GET_ARRAY(addr_adc_on_rst), > + tmp_data, DATA_LEN_4); > + goto TRUE_END; > + } else { > + /* usleep_range(10000, 10001); */ > + g_core_fp.fp_ic_reset(ts, false, false); > + } > + } while (cnt++ < 15); > + > + return false; > +TRUE_END: > + return true; > +} > + > +#define WIP_PRT_LOG "retry:%d, bf[0]=%d, bf[1]=%d,bf[2]=%d, bf[3]=%d" > +static bool himax_mcu_wait_wip(struct himax_ts_data *ts, int timing) > +{ > + u8 tmp_data[DATA_LEN_4]; > + int retry_cnt = 0; > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_trans_fmt), > + FLASH_GET_ARRAY(data_spi200_trans_fmt), DATA_LEN_4); > + tmp_data[0] = 0x01; > + > + do { > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_1), DATA_LEN_4); > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_1), DATA_LEN_4); > + memset(tmp_data, 0xFF, DATA_LEN_4); > + g_core_fp.fp_register_read(ts, FLASH_GET_ARRAY(addr_spi200_data), > + tmp_data, 4); > + > + if ((tmp_data[0] & 0x01) == 0x00) > + return true; > + > + retry_cnt++; > + > + if (tmp_data[0] != 0x00 || > + tmp_data[1] != 0x00 || > + tmp_data[2] != 0x00 || > + tmp_data[3] != 0x00) > + I(WIP_PRT_LOG, > + retry_cnt, tmp_data[0], > + tmp_data[1], tmp_data[2], tmp_data[3]); > + > + if (retry_cnt > 100) { > + E("Wait wip error!"); > + return false; > + } > + > + usleep_range(timing * 1000, timing * 1000 + 1); > + } while ((tmp_data[0] & 0x01) == 0x01); > + > + return true; > +} > + > +/*power saving level*/ > +static void himax_mcu_init_psl(struct himax_ts_data *ts) > +{ > + g_core_fp.fp_register_write(ts, IC_GET_ARRAY(addr_psl), > + IC_GET_ARRAY(data_rst), IC_GET_SZ(data_rst)); > + I("power saving level reset OK!"); > +} > + > +static void himax_mcu_resume_ic_action(struct himax_ts_data *ts) > +{ > + /* Nothing to do */ > +} > + > +static void himax_mcu_suspend_ic_action(struct himax_ts_data *ts) > +{ > + /* Nothing to do */ > +} > + > +static void himax_mcu_power_on_init(struct himax_ts_data *ts) > +{ > + union hx_dword_data_t tmp_data = { .byte = {0x01, 0x00, 0x00, 0x00} }; > + u8 retry = 0; > + > + /*RawOut select initial*/ > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_raw_out_sel), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + /*DSRAM func initial*/ > + g_core_fp.fp_assign_sorting_mode(ts, FW_GET_ARRAY(data_clear)); > + /*N frame initial*/ > + /* reset N frame back to default value 1 for normal mode */ > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_set_frame_addr), > + tmp_data.byte, 4); > + /*FW reload done initial*/ > + g_core_fp.fp_register_write(ts, > + DRV_GET_ARRAY(addr_fw_define_2nd_flash_reload), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + > + g_core_fp.fp_sense_on(ts, 0x00); > + > + I("waiting for FW reload data"); > + > + while (retry++ < 30) { > + g_core_fp.fp_register_read(ts, > + DRV_GET_ARRAY(addr_fw_define_2nd_flash_reload), tmp_data.byte, > + DATA_LEN_4); > + > + /* use all 4 bytes to compare */ > + if (le32_to_cpu(tmp_data.dword) == 0x72C0) { > + I("FW reload done"); > + break; > + } > + I("wait FW reload %d times", retry); > + g_core_fp.fp_read_FW_status(ts); > + usleep_range(10000, 11000); > + } > +} > + > +/* IC side end*/ > +/* CORE_IC */ > + > +/* CORE_FW */ > +/* FW side start*/ > +static void himax_mcu_system_reset(struct himax_ts_data *ts) > +{ > + int ret = 0; > + u8 tmp_data[DATA_LEN_4]; > + int retry = 0; > + > + g_core_fp.fp_interface_on(ts); > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_ctrl_fw_isr), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + do { > + /* reset code*/ > + /** > + * I2C_password[7:0] set Enter safe mode : 0x31 ==> 0x27 > + */ > + tmp_data[0] = IC_GET_VAL(data_i2c_psw_lb); > + > + ret = himax_bus_write(ts, IC_GET_VAL(adr_i2c_psw_lb), NULL, tmp_data, > + 1); > + if (ret < 0) > + E("bus access fail!"); > + > + /** > + * I2C_password[15:8] set Enter safe mode :0x32 ==> 0x95 > + */ > + tmp_data[0] = IC_GET_VAL(data_i2c_psw_ub); > + > + ret = himax_bus_write(ts, IC_GET_VAL(adr_i2c_psw_ub), NULL, tmp_data, > + 1); > + if (ret < 0) > + E("bus access fail!"); > + > + /** > + * I2C_password[7:0] set Enter safe mode : 0x31 ==> 0x00 > + */ > + tmp_data[0] = 0x00; > + > + ret = himax_bus_write(ts, IC_GET_VAL(adr_i2c_psw_lb), NULL, tmp_data, > + 1); > + if (ret < 0) > + E("bus access fail!"); > + > + usleep_range(10000, 11000); > + > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_flag_reset_event), > + tmp_data, DATA_LEN_4); > + I("Read status from IC = %X,%X", tmp_data[0], tmp_data[1]); > + } while ((tmp_data[1] != 0x02 || tmp_data[0] != 0x00) && retry++ < 5); > +} > + > +static int himax_mcu_calculate_crc_with_ap(const unsigned char *FW_content, > + int CRC_from_FW, int len) > +{ > + int i, j, length = 0; > + int fw_data; > + int fw_data_2; > + int CRC = 0xFFFFFFFF; > + int polynomial = 0x82F63B78; > + > + length = len / 4; > + > + for (i = 0; i < length; i++) { > + fw_data = FW_content[i * 4]; > + > + for (j = 1; j < 4; j++) { > + fw_data_2 = FW_content[i * 4 + j]; > + fw_data += (fw_data_2) << (8 * j); > + } > + CRC = fw_data ^ CRC; > + for (j = 0; j < 32; j++) { > + if ((CRC % 2) != 0) > + CRC = ((CRC >> 1) & 0x7FFFFFFF) ^ polynomial; > + else > + CRC = (((CRC >> 1) & 0x7FFFFFFF)); > + } > + } > + > + return CRC; > +} > + > +static u32 himax_mcu_check_crc(struct himax_ts_data *ts, > + u8 *start_addr, int reload_length) > +{ > + u32 result = 0; > + union { > + u8 byte[4]; > + u16 word[2]; > + u32 dword; > + } tmp_data = {0}; > + int cnt = 0, ret = 0; > + int length = reload_length / DATA_LEN_4; > + > + ret = g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_reload_addr_from), > + start_addr, DATA_LEN_4); > + if (ret < NO_ERR) { > + E("bus access fail!"); > + return HW_CRC_FAIL; > + } > + > + tmp_data.word[1] = 0x0099; > + tmp_data.word[1] = cpu_to_le16(tmp_data.word[1]); > + tmp_data.word[0] = length; > + tmp_data.word[0] = cpu_to_le16(tmp_data.word[0]); > + ret = g_core_fp.fp_register_write(ts, > + FW_GET_ARRAY(addr_reload_addr_cmd_beat), tmp_data.byte, DATA_LEN_4); > + if (ret < NO_ERR) { > + E("bus access fail!"); > + return HW_CRC_FAIL; > + } > + tmp_data.word[0] = 0x0000; > + > + ret = g_core_fp.fp_register_read(ts, > + FW_GET_ARRAY(addr_reload_addr_cmd_beat), tmp_data.byte, DATA_LEN_4); > + > + if (le16_to_cpu(tmp_data.word[0]) != length) { > + E("Flash content is Wrong"); > + return HW_CRC_FAIL; > + } > + > + cnt = 0; > + > + do { > + ret = g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_reload_status), > + tmp_data.byte, DATA_LEN_4); > + if (ret < NO_ERR) { > + E("bus access fail!"); > + return HW_CRC_FAIL; > + } > + > + if ((tmp_data.byte[0] & 0x01) != 0x01) { > + ret = g_core_fp.fp_register_read(ts, > + FW_GET_ARRAY(addr_reload_crc32_result), tmp_data.byte, > + DATA_LEN_4); > + if (ret < NO_ERR) { > + E("bus access fail!"); > + return HW_CRC_FAIL; > + } > + I("data[3]=%X,data[2]=%X,data[1]=%X,data[0]=%X", > + tmp_data.byte[3], > + tmp_data.byte[2], > + tmp_data.byte[1], > + tmp_data.byte[0]); > + result = tmp_data.dword; > + goto END; > + } else { > + I("Waiting for HW ready!"); > + usleep_range(1000, 1100); > + if (cnt >= 100) > + g_core_fp.fp_read_FW_status(ts); > + } > + > + } while (cnt++ < 100); > +END: > + return result; > +} > + > +static void himax_mcu_set_reload_cmd(u8 *write_data, int idx, > + u32 cmd_from, u32 cmd_to, u32 cmd_beat) > +{ > + int index = idx * 12; > + int i; > + > + for (i = 3; i >= 0; i--) { > + write_data[index + i] = (cmd_from >> (8 * i)); > + write_data[index + 4 + i] = (cmd_to >> (8 * i)); > + write_data[index + 8 + i] = (cmd_beat >> (8 * i)); > + } > +} > + > +static bool himax_mcu_program_reload(void) > +{ > + return true; > +} > + > +static void himax_mcu_usb_detect_set(struct himax_ts_data *ts, > + const u8 *cable_config) > +{ > + struct hx_reg_t tmp_reg; > + struct hx_reg_t back_reg; > + u8 retry_cnt = 0; > + > + do { > + if (cable_config[1] == 0x01) { > + WORD_REG(tmp_reg, fw_func_handshaking_pwd); > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_usb_detect), > + REG_GET_ARRAY(tmp_reg), REG_GET_SZ(tmp_reg)); > + WORD_REG(back_reg, fw_func_handshaking_pwd); > + I("USB detect status IN!"); > + } else { > + WORD_REG(tmp_reg, fw_data_safe_mode_release_pw_reset); > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_usb_detect), > + REG_GET_ARRAY(tmp_reg), REG_GET_SZ(tmp_reg)); > + WORD_REG(back_reg, fw_data_safe_mode_release_pw_reset); > + I("USB detect status OUT!"); > + } > + > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_usb_detect), > + REG_GET_ARRAY(tmp_reg), REG_GET_SZ(tmp_reg)); > + /*I("tmp_data[0]=%d, USB detect=%d, retry_cnt=%d", > + * tmp_data[0], cable_config[1], retry_cnt); > + */ > + retry_cnt++; > + } while ((REG_GET_ARRAY(tmp_reg)[3] != REG_GET_ARRAY(back_reg)[3] || > + REG_GET_ARRAY(tmp_reg)[2] != REG_GET_ARRAY(back_reg)[2] || > + REG_GET_ARRAY(tmp_reg)[1] != REG_GET_ARRAY(back_reg)[1] || > + REG_GET_ARRAY(tmp_reg)[0] != REG_GET_ARRAY(back_reg)[0]) && > + retry_cnt < HIMAX_REG_RETRY_TIMES); > +} > + > +#define PRT_DATA "[3]=0x%02X, [2]=0x%02X, [1]=0x%02X, [0]=0x%02X" > +static void himax_mcu_diag_register_set(struct himax_ts_data *ts, > + u8 diag_command) > +{ > + u8 tmp_data[DATA_LEN_4]; > + u8 back_data[DATA_LEN_4]; > + u8 cnt = 50; > + > + tmp_data[0] = diag_command; > + I("diag_command = %d, tmp_data[0] = %X", diag_command, tmp_data[0]); > + g_core_fp.fp_interface_on(ts); > + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; > + do { > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_raw_out_sel), > + tmp_data, DATA_LEN_4); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_raw_out_sel), back_data, > + DATA_LEN_4); > + I(PRT_DATA, back_data[3], back_data[2], back_data[1], back_data[0]); > + cnt--; > + } while (tmp_data[0] != back_data[0] && cnt > 0); > +} > + > +static int himax_mcu_diag_register_get(struct himax_ts_data *ts, > + u32 *diag_value) > +{ > + int ret = 0; > + union hx_dword_data_t *tmp_data = (union hx_dword_data_t *)diag_value; > + > + if (tmp_data) { > + ret = g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_raw_out_sel), > + tmp_data->byte, DATA_LEN_4); > + } else { > + E("diag_value is NULL"); > + ret = -EINVAL; > + } > + > + return ret; > +} > + > +#define PRT_TMP_DATA "[0]=0x%2X,[1]=0x%2X, [2]=0x%2X,[3]=0x%2X" > +static void himax_mcu_idle_mode(struct himax_ts_data *ts, int disable) > +{ > + int retry = 20; > + u8 tmp_data[DATA_LEN_4]; > + u8 switch_cmd = 0x00; > + > + I("entering"); > + > + do { > + I("now %d times!", retry); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_fw_mode_status), > + tmp_data, DATA_LEN_4); > + > + if (disable) > + switch_cmd = FW_GET_ARRAY(data_idle_dis_pwd)[0]; > + else > + switch_cmd = FW_GET_ARRAY(data_idle_en_pwd)[0]; > + > + tmp_data[0] = switch_cmd; > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_fw_mode_status), > + tmp_data, DATA_LEN_4); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_fw_mode_status), > + tmp_data, DATA_LEN_4); > + > + I(PRT_TMP_DATA, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]); > + > + retry--; > + usleep_range(10000, 11000); > + } while ((tmp_data[0] != switch_cmd) && retry > 0); > + > + I("setting OK!"); > +} > + > +static void himax_mcu_reload_disable(struct himax_ts_data *ts, int disable) > +{ > + I("entering"); > + > + if (disable) { /*reload disable*/ > + g_core_fp.fp_register_write(ts, > + DRV_GET_ARRAY(addr_fw_define_flash_reload), > + DRV_GET_ARRAY(data_fw_define_flash_reload_dis), > + DATA_LEN_4); > + } else { /*reload enable*/ > + g_core_fp.fp_register_write(ts, > + DRV_GET_ARRAY(addr_fw_define_flash_reload), > + DRV_GET_ARRAY(data_fw_define_flash_reload_en), > + DATA_LEN_4); > + } > + > + I("setting OK!"); > +} > + > +static int himax_mcu_read_ic_trigger_type(struct himax_ts_data *ts) > +{ > + u8 tmp_data[DATA_LEN_4]; > + int trigger_type = false; > + > + g_core_fp.fp_register_read(ts, DRV_GET_ARRAY(addr_fw_define_int_is_edge), > + tmp_data, DATA_LEN_4); > + > + if ((tmp_data[1] & 0x01) == 1) > + trigger_type = true; > + > + return trigger_type; > +} > + > +/* Please call this function after FW finish reload done */ > +static void himax_mcu_read_FW_ver(struct himax_ts_data *ts) > +{ > + u8 data[12] = {0}; > + > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_fw_ver_addr), data, > + DATA_LEN_4); > + ts->ic_data->vendor_panel_ver = data[0]; > + ts->ic_data->vendor_fw_ver = data[1] << 8 | data[2]; > + I("PANEL_VER : %X", ts->ic_data->vendor_panel_ver); > + I("FW_VER : %X", ts->ic_data->vendor_fw_ver); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_fw_cfg_addr), data, > + DATA_LEN_4); > + ts->ic_data->vendor_config_ver = data[2] << 8 | data[3]; > + /*I("CFG_VER : %X",ts->ic_data->vendor_config_ver);*/ > + ts->ic_data->vendor_touch_cfg_ver = data[2]; > + I("TOUCH_VER : %X", ts->ic_data->vendor_touch_cfg_ver); > + ts->ic_data->vendor_display_cfg_ver = data[3]; > + I("DISPLAY_VER : %X", ts->ic_data->vendor_display_cfg_ver); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_fw_vendor_addr), data, > + DATA_LEN_4); > + ts->ic_data->vendor_cid_maj_ver = data[2]; > + ts->ic_data->vendor_cid_min_ver = data[3]; > + I("CID_VER : %X", (ts->ic_data->vendor_cid_maj_ver << 8 > + | ts->ic_data->vendor_cid_min_ver)); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_cus_info), data, 12); > + memcpy(ts->ic_data->vendor_cus_info, data, 12); > + I("Cusomer ID = %s", ts->ic_data->vendor_cus_info); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_proj_info), data, 12); > + memcpy(ts->ic_data->vendor_proj_info, data, 12); > + I("Project ID = %s", ts->ic_data->vendor_proj_info); > + hx_hid_update_info(ts); > +} > + > +static bool himax_mcu_read_event_stack(struct himax_ts_data *ts, u8 *buf, > + u32 length) > +{ > + u8 cmd[DATA_LEN_4]; > + struct time_var t_start, t_end, t_delta; > + int len = length; > + int i2c_speed = 0; > + int ret = 0; > + > + /* AHB_I2C Burst Read Off */ > + cmd[0] = FW_GET_VAL(data_ahb_dis); > + > + ret = himax_bus_write(ts, FW_GET_VAL(addr_ahb_addr), NULL, cmd, 1); > + if (ret < 0) { > + E("bus access fail!"); > + return 0; > + } > + if (ts->debug_log_level & BIT(2)) > + time_func(&t_start); > + > + himax_bus_read(ts, FW_GET_VAL(addr_event_addr), buf, length); > + > + if (ts->debug_log_level & BIT(2)) { > + time_func(&t_end); > + t_delta.tv_nsec = (t_end.tv_sec * 1000000000 + t_end.tv_nsec) > + - (t_start.tv_sec * 1000000000 + t_start.tv_nsec); > + > + i2c_speed = (len * 9 * 1000000 > + / (int)t_delta.tv_nsec) * 13 / 10; > + ts->bus_speed = (int)i2c_speed; > + } > + > + /* AHB_I2C Burst Read On */ > + cmd[0] = FW_GET_VAL(data_ahb_en); > + > + ret = himax_bus_write(ts, FW_GET_VAL(addr_ahb_addr), NULL, cmd, 1); > + if (ret < 0) { > + E("bus access fail!"); > + return 0; > + } > + > + return 1; > +} > + > +static void himax_mcu_return_event_stack(struct himax_ts_data *ts) > +{ > + int retry = 20, i; > + u8 tmp_data[DATA_LEN_4]; > + > + I("entering"); > + > + do { > + I("now %d times!", retry); > + > + for (i = 0; i < DATA_LEN_4; i++) > + tmp_data[i] = SRAM_GET_ARRAY(addr_rawdata_end)[i]; > + > + g_core_fp.fp_register_write(ts, SRAM_GET_ARRAY(addr_rawdata_addr), > + tmp_data, DATA_LEN_4); > + g_core_fp.fp_register_read(ts, SRAM_GET_ARRAY(addr_rawdata_addr), > + tmp_data, DATA_LEN_4); > + retry--; > + usleep_range(10000, 11000); > + } while ((tmp_data[1] != SRAM_GET_ARRAY(addr_rawdata_end)[1] && > + tmp_data[0] != SRAM_GET_ARRAY(addr_rawdata_end)[0]) && > + retry > 0); > + > + I("End of setting!"); > +} > + > +static bool himax_mcu_calculate_checksum(struct himax_ts_data *ts, > + bool change_iref, u32 size) > +{ > + u32 CRC_result = 0xFFFFFFFF; > + u8 i; > + u8 tmp_data[DATA_LEN_4]; > + > + I("Now size=%d", size); > + for (i = 0; i < DATA_LEN_4; i++) > + tmp_data[i] = SRAM_GET_ARRAY(addr_rawdata_end)[i]; > + > + CRC_result = g_core_fp.fp_check_crc(ts, tmp_data, size); > + usleep_range(50000, 50001); > + > + if (CRC_result != 0) > + I("CRC Fail=%d", CRC_result); > + > + return (CRC_result == 0) ? true : false; > +} > + > +static u32 dbg_reg_ary[4] = {fw_addr_fw_dbg_msg_addr, > + fw_addr_chk_fw_status, fw_addr_chk_dd_status, fw_addr_flag_reset_event}; > + > +static void himax_mcu_read_FW_status(struct himax_ts_data *ts) > +{ > + u8 len = 0; > + u8 i = 0; > + struct hx_reg_t addr_reg; > + u8 data[4] = {0}; > + > + len = (u8)(sizeof(dbg_reg_ary) / sizeof(u32)); > + > + for (i = 0; i < len; i++) { > + WORD_REG(addr_reg, dbg_reg_ary[i]); > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(addr_reg), > + data, DATA_LEN_4); > + > + I("reg[0-3] : 0x%08X = 0x%02X, 0x%02X, 0x%02X, 0x%02X", > + dbg_reg_ary[i], data[0], data[1], data[2], data[3]); > + } > +} > + > +static void himax_mcu_irq_switch(struct himax_ts_data *ts, int switch_on) > +{ > + if (switch_on) { > + if (ts->use_irq) > + himax_int_enable(ts, switch_on); > + else > + hrtimer_start(&ts->timer, ktime_set(1, 0), > + HRTIMER_MODE_REL); > + } else { > + if (ts->use_irq) { > + himax_int_enable(ts, switch_on); > + } else { > + hrtimer_cancel(&ts->timer); > + cancel_work_sync(&ts->work); > + } > + } > +} > + > +static int himax_mcu_assign_sorting_mode(struct himax_ts_data *ts, > + u8 *tmp_data_in) > +{ > + u8 retry = 0; > + union hx_dword_data_t rdata = {0}; > + u32 sorting_addr = FW_GET_VAL(addr_sorting_mode_en); > + union hx_dword_data_t *tmp_data = (union hx_dword_data_t *)tmp_data_in; > + > + I("addr: 0x%08X, write: 0x%08X", > + sorting_addr, le32_to_cpu(tmp_data->dword)); > + > + while (retry++ < 3) { > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_sorting_mode_en), > + tmp_data->byte, DATA_LEN_4); > + usleep_range(1000, 1100); > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_sorting_mode_en), > + rdata.byte, DATA_LEN_4); > + > + if (rdata.dword == tmp_data->dword) { > + I("success to write sorting mode"); > + return NO_ERR; > + } > + E("fail to write sorting mode"); > + } > + > + return BUS_FAIL; > +} > + > +static int himax_mcu_check_sorting_mode(struct himax_ts_data *ts, > + u8 *tmp_data_in) > +{ > + int ret = NO_ERR; > + u32 sorting_addr = FW_GET_VAL(addr_sorting_mode_en); > + union hx_dword_data_t *tmp_data = (union hx_dword_data_t *)tmp_data_in; > + > + ret = g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_sorting_mode_en), > + tmp_data->byte, DATA_LEN_4); > + I("addr: 0x%08X, Now is:0x%08X", > + sorting_addr, le32_to_cpu(tmp_data->dword)); > + if (tmp_data->dword == 0xFFFFFFFF) { > + ret = BUS_FAIL; > + I("All 0xFF, Fail!"); > + } > + > + return ret; > +} > + > +static u8 himax_mcu_read_DD_status(struct himax_ts_data *ts, > + u8 *cmd_set, u8 *tmp_data) > +{ > + int cnt = 0; > + u8 req_size = cmd_set[0]; > + > + cmd_set[3] = FW_GET_ARRAY(data_dd_request)[0]; > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_dd_handshak_addr), > + cmd_set, DATA_LEN_4); > + I("cmd set[0]=0x%2X,set[1]=0x%2X,set[2]=0x%2X,set[3]=0x%2X", > + cmd_set[0], cmd_set[1], cmd_set[2], cmd_set[3]); > + > + /* Doing hand shaking 0xAA -> 0xBB */ > + for (cnt = 0; cnt < 100; cnt++) { > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_dd_handshak_addr), > + tmp_data, DATA_LEN_4); > + usleep_range(10000, 11000); > + > + if (tmp_data[3] == FW_GET_ARRAY(data_dd_ack)[0]) { > + I("Data ready goto moving data"); > + goto FINALIZE; > + } else { > + if (cnt >= 99) { > + I("Data not ready in FW"); > + return FW_NOT_READY; > + } > + } > + } > +FINALIZE: > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_dd_data_addr), tmp_data, > + req_size); > + return NO_ERR; > +} > + > +static void hx_clr_fw_reord_dd_sts(struct himax_ts_data *ts) > +{ > + union hx_dword_data_t tmp_data = {0}; > + > + g_core_fp.fp_register_read(ts, IC_GET_ARRAY(addr_cs_central_state), > + tmp_data.byte, ADDR_LEN_4); > + I("Check enter_save_mode data[0]=%02X", tmp_data.byte[0]); > + > + if (tmp_data.byte[0] == 0x0C) { > + I("Enter safe mode, OK!"); > + } else { > + E("It doen't enter safe mode, please check it again"); > + return; > + } > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_clr_fw_record_dd_sts), > + tmp_data.byte, DATA_LEN_4); > + I("Before Write :Now 10007FCC=0x%08X", > + le32_to_cpu(tmp_data.dword)); > + usleep_range(10000, 10001); > + > + tmp_data.byte[2] = 0x00; > + tmp_data.byte[3] = 0x00; > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_clr_fw_record_dd_sts), > + tmp_data.byte, DATA_LEN_4); > + usleep_range(10000, 10001); > + > + g_core_fp.fp_register_read(ts, FW_GET_ARRAY(addr_clr_fw_record_dd_sts), > + tmp_data.byte, DATA_LEN_4); > + I("After Write :Now 10007FCC=0x%08X", > + le32_to_cpu(tmp_data.dword)); > +} > + > +static void hx_ap_notify_fw_sus(struct himax_ts_data *ts, int suspend) > +{ > + int retry = 0; > + int read_sts = 0; > + union hx_dword_data_t read_tmp = {0}; > + union hx_dword_data_t addr_tmp = {0}; > + union hx_dword_data_t data_tmp = {0}; > + > + addr_tmp.dword = FW_GET_VAL(addr_ap_notify_fw_sus); > + > + if (suspend) { > + I("Suspend mode!"); > + data_tmp.dword = FW_GET_VAL(data_ap_notify_fw_sus_en); > + } else { > + I("Non-Suspend mode!"); > + data_tmp.dword = FW_GET_VAL(data_ap_notify_fw_sus_dis); > + } > + > + I("R%08XH<-0x%08X", addr_tmp.dword, data_tmp.dword); > + addr_tmp.dword = cpu_to_le32(addr_tmp.dword); > + data_tmp.dword = cpu_to_le32(data_tmp.dword); > + do { > + g_core_fp.fp_register_write(ts, addr_tmp.byte, data_tmp.byte, > + sizeof(data_tmp.byte)); > + usleep_range(1000, 1001); > + read_sts = g_core_fp.fp_register_read(ts, addr_tmp.byte, read_tmp.byte, > + sizeof(read_tmp.byte)); > + I("read bus status=%d", read_sts); > + I("Now retry=%d, data=0x%08X", retry, > + le32_to_cpu(read_tmp.dword)); > + } while ((retry++ < 10) && (read_sts != NO_ERR) && > + (read_tmp.dword != data_tmp.dword)); > +} > + > +/* FW side end*/ > +/* CORE_FW */ > + > +/* CORE_FLASH */ > +/* FLASH side start*/ > +static void himax_mcu_chip_erase(struct himax_ts_data *ts) > +{ > + g_core_fp.fp_interface_on(ts); > + > + /* Reset power saving level */ > + if (g_core_fp.fp_init_psl) > + g_core_fp.fp_init_psl(ts); > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_trans_fmt), > + FLASH_GET_ARRAY(data_spi200_trans_fmt), DATA_LEN_4); > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_2), DATA_LEN_4); > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_2), DATA_LEN_4); > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_3), DATA_LEN_4); > + usleep_range(2000000, 2000001); > + > + if (!g_core_fp.fp_wait_wip(ts, 100)) > + E("Chip_Erase Fail"); > + else > + I("Chip_Erase Success"); > +} > + > +static bool himax_mcu_block_erase(struct himax_ts_data *ts, int start_addr, > + int length) > +{ > + u32 page_prog_start = 0; > + u32 block_size = 0x10000; > + > + DEF_WORD_DATA(tmp_data); > + > + g_core_fp.fp_interface_on(ts); > + > + g_core_fp.fp_init_psl(ts); > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_trans_fmt), > + FLASH_GET_ARRAY(data_spi200_trans_fmt), DATA_LEN_4); > + > + for (page_prog_start = start_addr; > + page_prog_start < start_addr + length; > + page_prog_start = page_prog_start + block_size) { > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_2), DATA_LEN_4); > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_2), DATA_LEN_4); > + > + VAL_SET(tmp_data, page_prog_start); > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_addr), > + tmp_data.data.byte, DATA_LEN_4); > + > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_3), DATA_LEN_4); > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_4), DATA_LEN_4); > + usleep_range(1000000, 1000001); > + > + if (!g_core_fp.fp_wait_wip(ts, 100)) { > + E("Erase Fail"); > + return false; > + } > + } > + > + I("END"); > + return true; > +} > + > +static bool himax_mcu_sector_erase(int start_addr) > +{ > + return true; > +} > + > +static bool himax_mcu_flash_programming(struct himax_ts_data *ts, > + u8 *FW_content, int fw_size) > +{ > + int page_prog_start = 0; > + union hx_dword_data_t tmp_data = {0}; > + int ret = 0; > + /* 4 bytes for padding*/ > + g_core_fp.fp_interface_on(ts); > + > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_fmt), > + FLASH_GET_ARRAY(data_spi200_trans_fmt), DATA_LEN_4); > + > + for (page_prog_start = 0; page_prog_start < fw_size; > + page_prog_start += FLASH_RW_MAX_LEN) { > + /* ===Flash Write Enable ===*/ > + > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_2), DATA_LEN_4); > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_2), DATA_LEN_4); > + > + /* ===WEL Write Control ===*/ > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_6), DATA_LEN_4); > + > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_1), DATA_LEN_4); > + > + g_core_fp.fp_register_read(ts, FLASH_GET_ARRAY(addr_spi200_data), > + tmp_data.byte, DATA_LEN_4); > + > + /* === Check WEL Fail ===*/ > + if (((tmp_data.byte[0] & 0x02) >> 1) == 0) { > + I("SPI 0x8000002c = %d, Check WEL Fail", > + tmp_data.byte[0]); > + return false; > + } > + > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_2), DATA_LEN_4); > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_2), DATA_LEN_4); > + > + /*Programmable size = 1 page = 256 bytes,*/ > + /*word_number = 256 byte / 4 = 64*/ > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_trans_ctrl), > + FLASH_GET_ARRAY(data_spi200_trans_ctrl_4), DATA_LEN_4); > + > + /* Flash start address 1st : 0x0000_0000*/ > + tmp_data.dword = cpu_to_le32(page_prog_start); > + g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_addr), tmp_data.byte, DATA_LEN_4); > + > + ret = g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_data), > + &FW_content[page_prog_start], 16); > + if (ret < 0) { > + E("bus access fail!"); > + return false; > + } > + > + g_core_fp.fp_register_write(ts, FLASH_GET_ARRAY(addr_spi200_cmd), > + FLASH_GET_ARRAY(data_spi200_cmd_6), DATA_LEN_4); > + > + ret = g_core_fp.fp_register_write(ts, > + FLASH_GET_ARRAY(addr_spi200_data), > + &FW_content[page_prog_start + 16], 240); > + if (ret < 0) { > + E("bus access fail!"); > + return false; > + } > + > + if (!g_core_fp.fp_wait_wip(ts, 1)) { > + E("Flash_Programming Fail"); > + return false; > + } > + } > + return true; > +} > + > +static void himax_mcu_flash_page_write(u8 *write_addr, int length, > + u8 *write_data) > +{ > +} > + > +static void himax_flash_speed_set(struct himax_ts_data *ts, u8 speed) > +{ > + struct hx_reg_t reg_addr; > + struct hx_reg_t reg_data; > + > + reg_data.data.word = 0; > + reg_data.data.byte[1] = 0x02; /*extand cs high to 100ns*/ > + reg_data.data.byte[0] = speed; > + WORD_REG(reg_addr, flash_clk_setup_addr); > + g_core_fp.fp_register_write(ts, REG_GET_ARRAY(reg_addr), > + REG_GET_ARRAY(reg_data), 4); > +} > + > +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_32k > + (struct himax_ts_data *ts, unsigned char *fw, > + int len, bool change_iref) > +{ > + /* Not use */ > + return 0; > +} > + > +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_60k > + (struct himax_ts_data *ts, unsigned char *fw, > + int len, bool change_iref) > +{ > + /* Not use */ > + return 0; > +} > + > +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_64k > + (struct himax_ts_data *ts, unsigned char *fw, > + int len, bool change_iref) > +{ > + int burn_firmware_success = 0; > + int counter = 0; > + > + if (len != FW_SIZE_64k) { > + E("The file size is not 64K bytes"); > + return false; > + } > + > + g_core_fp.fp_ic_reset(ts, false, false); > + for (counter = 0; counter < 3; counter++) { > + g_core_fp.fp_sense_off(ts, true); > + himax_flash_speed_set(ts, HX_FLASH_SPEED_12p5M); > + g_core_fp.fp_block_erase(ts, 0x00, FW_SIZE_64k); > + if (g_core_fp.fp_flash_programming(ts, fw, FW_SIZE_64k) == false) { > + g_core_fp.fp_ic_reset(ts, false, false); > + continue; > + } > + > + if (g_core_fp.fp_check_crc(ts, FW_GET_ARRAY(addr_program_reload_from), > + FW_SIZE_64k) == 0) { > + burn_firmware_success = 1; > + break; > + } > + } > + /*RawOut select initial*/ > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_raw_out_sel), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + /*DSRAM func initial*/ > + g_core_fp.fp_assign_sorting_mode(ts, FW_GET_ARRAY(data_clear)); > + g_core_fp.fp_ic_reset(ts, false, false); > + > + return burn_firmware_success; > +} > + > +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_124k > + (struct himax_ts_data *ts, unsigned char *fw, > + int len, bool change_iref) > +{ > + /* Not use */ > + return 0; > +} > + > +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_128k > + (struct himax_ts_data *ts, unsigned char *fw, > + int len, bool change_iref) > +{ > + int burn_firmware_success = 0; > + int counter = 0; > + > + if (len != FW_SIZE_128k) { > + E("The file size is not 128K bytes"); > + return false; > + } > + > + g_core_fp.fp_ic_reset(ts, false, false); > + for (counter = 0; counter < 3; counter++) { > + g_core_fp.fp_sense_off(ts, true); > + himax_flash_speed_set(ts, HX_FLASH_SPEED_12p5M); > + g_core_fp.fp_block_erase(ts, 0x00, FW_SIZE_128k); > + if (g_core_fp.fp_flash_programming(ts, fw, FW_SIZE_128k) == false) { > + g_core_fp.fp_ic_reset(ts, false, false); > + continue; > + } > + > + if (g_core_fp.fp_check_crc(ts, FW_GET_ARRAY(addr_program_reload_from), > + FW_SIZE_128k) == 0) { > + burn_firmware_success = 1; > + break; > + } > + } > + /*RawOut select initial*/ > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_raw_out_sel), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + /*DSRAM func initial*/ > + g_core_fp.fp_assign_sorting_mode(ts, FW_GET_ARRAY(data_clear)); > + > + return burn_firmware_success; > +} > + > +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_255k > + (struct himax_ts_data *ts, unsigned char *fw, > + int len, bool change_iref) > +{ > + int burn_firmware_success = 0; > + int counter = 0; > + > + if (len != FW_SIZE_255k) { > + E("The file size is not 255K bytes"); > + return false; > + } > + > + g_core_fp.fp_ic_reset(ts, false, false); > + for (counter = 0; counter < 3; counter++) { > + g_core_fp.fp_sense_off(ts, true); > + himax_flash_speed_set(ts, HX_FLASH_SPEED_12p5M); > + g_core_fp.fp_block_erase(ts, 0x00, FW_SIZE_255k); > + if (g_core_fp.fp_flash_programming(ts, fw, FW_SIZE_255k) == false) { > + g_core_fp.fp_ic_reset(ts, false, false); > + continue; > + } > + if (g_core_fp.fp_check_crc(ts, FW_GET_ARRAY(addr_program_reload_from), > + FW_SIZE_255k) == 0) { > + burn_firmware_success = 1; > + break; > + } > + } > + /*RawOut select initial*/ > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_raw_out_sel), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + /*DSRAM func initial*/ > + g_core_fp.fp_assign_sorting_mode(ts, FW_GET_ARRAY(data_clear)); > + > + return burn_firmware_success; > +} > + > +static void himax_mcu_flash_dump_func > + (struct himax_ts_data *ts, u8 local_flash_command, > + int flash_size, u8 *flash_buffer) > +{ > + struct hx_reg_t tmp_addr; > + int page_prog_start = 0; > + > + g_core_fp.fp_sense_off(ts, true); > + > + for (page_prog_start = 0; page_prog_start < flash_size; > + page_prog_start += 128) { > + WORD_REG(tmp_addr, page_prog_start); > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + flash_buffer + page_prog_start, 128); > + } > + > + g_core_fp.fp_sense_on(ts, 0x01); > +} > + > +static bool himax_mcu_flash_lastdata_check(struct himax_ts_data *ts, > + u32 size) > +{ > + struct hx_reg_t tmp_addr; > + /* 64K - 0x80, which is the address of > + * the last 128bytes in 64K, default value > + */ > + u32 start_addr = 0xFFFFFFFF; > + u32 temp_addr = 0; > + u32 flash_page_len = 0x80; > + u8 flash_tmp_buffer[128]; > + > + if (size < flash_page_len) { > + E("flash size is wrong, terminated"); > + E("flash size = %08X; flash page len = %08X", > + size, flash_page_len); > + goto FAIL; > + } > + > + /* In order to match other size of fw */ > + start_addr = size - flash_page_len; > + I("Now size is %d, the start_addr is 0x%08X", > + size, start_addr); > + for (temp_addr = start_addr; temp_addr < (start_addr + flash_page_len); > + temp_addr = temp_addr + flash_page_len) { > + /*I("temp_addr=%d,tmp_addr[0]=0x%2X, tmp_addr[1]=0x%2X, > + * tmp_addr[2]=0x%2X,tmp_addr[3]=0x%2X", > + * temp_addr,tmp_addr[0], tmp_addr[1], > + * tmp_addr[2],tmp_addr[3]); > + */ > + WORD_REG(tmp_addr, temp_addr); > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + &flash_tmp_buffer[0], flash_page_len); > + } > + > + I("FLASH[%08X] ~ FLASH[%08X] = %02X%02X%02X%02X", size - 4, size - 1, > + flash_tmp_buffer[flash_page_len - 4], > + flash_tmp_buffer[flash_page_len - 3], > + flash_tmp_buffer[flash_page_len - 2], > + flash_tmp_buffer[flash_page_len - 1]); > + > + if (!flash_tmp_buffer[flash_page_len - 4] && > + !flash_tmp_buffer[flash_page_len - 3] && > + !flash_tmp_buffer[flash_page_len - 2] && > + !flash_tmp_buffer[flash_page_len - 1]) { > + I("Fail, Last four Bytes are all 0x00:"); > + goto FAIL; > + } else if (flash_tmp_buffer[flash_page_len - 4] == 0xFF && > + (flash_tmp_buffer[flash_page_len - 3] == 0xFF) && > + (flash_tmp_buffer[flash_page_len - 2] == 0xFF) && > + (flash_tmp_buffer[flash_page_len - 1] == 0xFF)) { > + I("Fail, Last four Bytes are all 0xFF:"); > + goto FAIL; > + } else { > + return 0; > + } > + > +FAIL: > + return 1; > +} > + > +static bool hx_bin_desc_data_get(struct himax_ts_data *ts, > + u32 addr, u8 *flash_buf, > + const u8 *fw_all_data) > +{ > + u8 data_sz = 0x10; > + u32 i = 0, j = 0; > + u16 chk_end = 0; > + u16 chk_sum = 0; > + u32 map_code = 0; > + unsigned long flash_addr = 0; > + u32 hid_table_addr = 0; > + union { > + u8 *buf; > + u32 *word; > + } map_data; > + > + for (i = 0; i < FW_PAGE_SZ; i = i + data_sz) { > + for (j = i; j < (i + data_sz); j++) { > + chk_end |= flash_buf[j]; > + chk_sum += flash_buf[j]; > + } > + if (!chk_end) { /*1. Check all zero*/ > + I("End in %X", i + addr); > + return false; > + } else if (chk_sum % 0x100) { /*2. Check sum*/ > + I("chk sum failed in %X", i + addr); > + } else { /*3. get data*/ > + map_data.buf = &flash_buf[i]; > + map_code = le32_to_cpup(map_data.word); > + map_data.buf = &flash_buf[i + 4]; > + flash_addr = le32_to_cpup(map_data.word); > + switch (map_code) { > + case FW_CID: > + WORD_REG(g_core_regs.flash_ver_info.addr_cid_ver_major, > + flash_addr); > + WORD_REG(g_core_regs.flash_ver_info.addr_cid_ver_minor, > + flash_addr + 1); > + I("CID_VER in %X", FLASH_VER_GET_VAL(addr_cid_ver_major)); > + memcpy(&ts->fw_bin_desc, &fw_all_data > + [flash_addr - sizeof(ts->hid_info.fw_bin_desc.passwd)], > + sizeof(struct hx_bin_desc_t)); > + break; > + case FW_VER: > + WORD_REG(g_core_regs.flash_ver_info.addr_fw_ver_major, > + flash_addr); > + WORD_REG(g_core_regs.flash_ver_info.addr_fw_ver_minor, > + flash_addr + 1); > + I("FW_VER in %X", FLASH_VER_GET_VAL(addr_fw_ver_major)); > + break; > + case CFG_VER: > + WORD_REG(g_core_regs.flash_ver_info.addr_cfg_ver_major, > + flash_addr); > + WORD_REG(g_core_regs.flash_ver_info.addr_cfg_ver_minor, > + flash_addr + 1); > + I("CFG_VER in = %08X", FLASH_VER_GET_VAL(addr_cfg_ver_major)); > + break; > + case TP_CONFIG_TABLE: > + WORD_REG(g_core_regs.flash_ver_info.addr_cfg_table, > + flash_addr); > + I("CONFIG_TABLE in %X", FLASH_VER_GET_VAL(addr_cfg_table)); > + break; > + case HID_TABLE: > + WORD_REG(g_core_regs.flash_ver_info.addr_hid_table, > + flash_addr); > + I("HID_TABLE in %X", FLASH_VER_GET_VAL(addr_hid_table)); > + hid_table_addr = FLASH_VER_GET_VAL(addr_hid_table); > + WORD_REG(g_core_regs.flash_ver_info.addr_hid_desc, > + hid_table_addr); > + I("HID_DESC in %X", FLASH_VER_GET_VAL(addr_hid_desc)); > + WORD_REG(g_core_regs.flash_ver_info.addr_hid_rd_desc, > + (hid_table_addr + 24)); > + I("HID_RD_DESC in %X", FLASH_VER_GET_VAL(addr_hid_rd_desc)); > + break; > + } > + } > + chk_end = 0; > + chk_sum = 0; > + } > + > + return true; > +} > + > +static bool hx_mcu_bin_desc_get(unsigned char *fw, struct himax_ts_data *ts, > + u32 max_sz) > +{ > + u32 addr_t = 0; > + unsigned char *fw_buf = NULL; > + bool keep_on_flag = false; > + bool bin_desc_flag = false; > + > + do { > + fw_buf = &fw[addr_t]; > + > + /*Check bin is with description table or not*/ > + if (!bin_desc_flag) { > + if (fw_buf[0x00] == 0x00 && fw_buf[0x01] == 0x00 && > + fw_buf[0x02] == 0x00 && fw_buf[0x03] == 0x00 && > + fw_buf[0x04] == 0x00 && fw_buf[0x05] == 0x00 && > + fw_buf[0x06] == 0x00 && fw_buf[0x07] == 0x00 && > + fw_buf[0x0E] == 0x87) > + bin_desc_flag = true; > + } > + if (!bin_desc_flag) { > + I("fw_buf[0x00] = %2X, fw_buf[0x0E] = %2X", > + fw_buf[0x00], fw_buf[0x0E]); > + I("No description table"); > + break; > + } > + > + /*Get related data*/ > + keep_on_flag = hx_bin_desc_data_get(ts, addr_t, fw_buf, fw); > + if (FLASH_VER_GET_VAL(addr_hid_table) >= ts->hxfw->size || > + (FLASH_VER_GET_VAL(addr_hid_rd_desc) + > + ts->hid_rd_data.rd_length) >= ts->hxfw->size) { > + W("hid_table_addr = %d, ts->hxfw->size = %lu!", > + FLASH_VER_GET_VAL(addr_hid_table), ts->hxfw->size); > + W("hid_rd_desc_addr = %d, rd_len = %d, ts->hxfw->size = %lu!", > + FLASH_VER_GET_VAL(addr_hid_rd_desc), > + ts->hid_rd_data.rd_length, > + ts->hxfw->size); > + WORD_REG(g_core_regs.flash_ver_info.addr_hid_table, 0); > + WORD_REG(g_core_regs.flash_ver_info.addr_hid_desc, 0); > + WORD_REG(g_core_regs.flash_ver_info.addr_hid_rd_desc, 0); > + } > + > + addr_t = addr_t + FW_PAGE_SZ; > + } while (max_sz > addr_t && keep_on_flag); > + > + return bin_desc_flag; > +} > + > +static int hx_mcu_diff_overlay_flash(struct himax_ts_data *ts) > +{ > + int rslt = 0; > + int diff_val = 0; > + > + diff_val = (ts->ic_data->vendor_fw_ver); > + I("Now fw ID is 0x%04X", diff_val); > + diff_val = (diff_val >> 12); > + I("Now diff value=0x%04X", diff_val); > + > + if (diff_val == 1) > + I("Now size should be 128K!"); > + else > + I("Now size should be 64K!"); > + rslt = diff_val; > + return rslt; > +} > + > +/* FLASH side end*/ > +/* CORE_FLASH */ > + > +/* CORE_SRAM */ > +/* SRAM side start*/ > +static void himax_mcu_sram_write(struct himax_ts_data *ts, u8 *fw_content) > +{ > +} > + > +static bool himax_mcu_sram_verify(struct himax_ts_data *ts, u8 *fw_file, > + int fw_size) > +{ > + return true; > +} > + > +static bool himax_mcu_get_DSRAM_data(struct himax_ts_data *ts, > + u8 *info_data, bool dsram_flag) > +{ > + unsigned int i = 0; > + struct hx_reg_t tmp_addr; > + union hx_dword_data_t tmp_data = {0}; > + unsigned int max_bus_size = MAX_I2C_TRANS_SZ; > + const u32 x_num = ts->ic_data->HX_RX_NUM; > + const u32 y_num = ts->ic_data->HX_TX_NUM; > + unsigned int total_size = (x_num * y_num + x_num + y_num) * 2 + 4; > + unsigned int remain_size; > + u32 retry = 0; > + unsigned int addr = 0; > + u8 *temp_info_data = NULL; /*max mkey size = 8*/ > + u32 checksum = 0; > + s32 fw_run_flag = -1; > + > +#if defined(BUS_R_DLEN) > + max_bus_size = BUS_R_DLEN; > +#endif > + > + if (strcmp(ts->chip_name, HX83121A_ID) == 0) { > + if (max_bus_size > 4096) > + max_bus_size = 4096; > + } > + > + temp_info_data = kcalloc((total_size + 8), sizeof(u8), GFP_KERNEL); > + if (!temp_info_data) { > + E("Failed to allocate memory"); > + return false; > + } > + /* 1. Read number of MKey R100070E8H to determin data size */ > + /* m_key_num = g_hx_ic_data->HX_BT_NUM; */ > + /* I("m_key_num=%d", m_key_num); */ > + /* total_size += m_key_num * 2; */ > + > + /* 2. Start DSRAM Rawdata and Wait Data Ready */ > + tmp_data.dword = SRAM_GET_VAL(passwrd_start); > + tmp_data.dword = cpu_to_le32(tmp_data.dword); > + fw_run_flag = himax_write_read_reg(ts, SRAM_GET_ARRAY(addr_rawdata_addr), > + tmp_data.byte, > + SRAM_GET_ARRAY(passwrd_end)[1], > + SRAM_GET_ARRAY(passwrd_end)[0]); > + > + if (fw_run_flag < 0) { > + E("Data NOT ready => bypass"); > + kfree(temp_info_data); > + return false; > + } > + > + /* 3. Read RawData */ > + while (retry++ < 5) { > + remain_size = total_size; > + while (remain_size > 0) { > + i = total_size - remain_size; > + addr = sram_adr_rawdata_addr + i; > + > + WORD_REG(tmp_addr, addr); > + > + if (remain_size >= max_bus_size) { > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + &temp_info_data[i], max_bus_size); > + remain_size -= max_bus_size; > + } else { > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + &temp_info_data[i], remain_size); > + remain_size = 0; > + } > + } > + > + /* 5. Data Checksum Check */ > + /* 2 is meaning PASSWORD NOT included */ > + checksum = 0; > + for (i = 2; i < total_size; i += 2) > + checksum += temp_info_data[i + 1] << 8 | temp_info_data[i]; > + > + if (checksum % 0x10000 != 0) { > + E("check_sum_cal fail=%08X", checksum); > + > + } else { > + memcpy(info_data, temp_info_data, > + total_size * sizeof(u8)); > + break; > + } > + } > + > + /* 4. FW stop outputing */ > + tmp_data.dword = 0; > + tmp_data.byte[3] = temp_info_data[3]; > + tmp_data.byte[2] = temp_info_data[2]; > + g_core_fp.fp_register_write(ts, SRAM_GET_ARRAY(addr_rawdata_addr), > + tmp_data.byte, DATA_LEN_4); > + > + kfree(temp_info_data); > + if (retry >= 5) > + return false; > + else > + return true; > +} > + > +/* SRAM side end*/ > +/* CORE_SRAM */ > + > +/* CORE_DRIVER */ > +static void himax_mcu_init_ic(struct himax_ts_data *ts) > +{ > + I("use default incell init."); > +} > + > +static void himax_suspend_proc(struct himax_ts_data *ts, bool suspended) > +{ > + I("himax suspend."); > +} > + > +static void himax_resume_proc(struct himax_ts_data *ts, bool suspended) > +{ > + int result = 0; > + > + I("himax resume."); > + if (!ts->ic_data->has_flash) { > + if (g_core_fp.fp_0f_op_file_dirly) { > + result = g_core_fp.fp_0f_op_file_dirly(g_fw_boot_upgrade_name, > + ts); > + if (result) > + E("update FW fail, code[%d]!!", result); > + else > + ts->resume_success = true; > + } > + } else { > + if (g_core_fp.fp_resend_cmd_func) { > + g_core_fp.fp_resend_cmd_func(ts, suspended); > + ts->resume_success = true; > + } > + } > + > + if (g_core_fp.fp_ap_notify_fw_sus && result == 0) > + g_core_fp.fp_ap_notify_fw_sus(ts, 0); > +} > + > +static void himax_mcu_pin_reset(struct himax_ts_data *ts) > +{ > + const int rst_low_period_s = RST_LOW_PERIOD_S; > + const int rst_low_period_e = RST_LOW_PERIOD_E; > + int rst_high_period_s; > + int rst_high_period_e; > + > + I("Now reset the Touch chip."); > + if (!ts->ic_data->has_flash) { > + rst_high_period_s = RST_HIGH_PERIOD_ZF_S; > + rst_high_period_e = RST_HIGH_PERIOD_ZF_E; > + } else { > + rst_high_period_s = RST_HIGH_PERIOD_S; > + rst_high_period_e = RST_HIGH_PERIOD_E; > + } > + himax_rst_gpio_set(ts->rst_gpio, 0); > + usleep_range(rst_low_period_s, rst_low_period_e); > + himax_rst_gpio_set(ts->rst_gpio, 1); > + usleep_range(rst_high_period_s, rst_high_period_e); > +} > + > +static void himax_mcu_ic_reset(struct himax_ts_data *ts, u8 loadconfig, > + u8 int_off) > +{ > + I("status: loadconfig=%d,int_off=%d", loadconfig, int_off); > + > + if (ts->rst_gpio >= 0) { > + if (int_off) > + g_core_fp.fp_irq_switch(ts, 0); > + > + g_core_fp.fp_pin_reset(ts); > + > + if (int_off) > + g_core_fp.fp_irq_switch(ts, 1); > + } > +} > + > +static u8 himax_mcu_tp_info_check(struct himax_ts_data *ts) > +{ > + union hx_dword_data_t addr; > + char data[DATA_LEN_4] = {0}; > + u32 rx_num; > + u32 tx_num; > + u32 bt_num; > + u32 max_pt; > + u32 y_res; > + u32 x_res; > + u8 int_is_edge; > + u8 stylus_func; > + u8 stylus_id_v2; > + u8 stylus_ratio; > + > + g_core_fp.fp_register_read(ts, > + DRV_GET_ARRAY(addr_fw_define_rxnum_txnum), data, DATA_LEN_4); > + rx_num = data[2]; > + tx_num = data[3]; > + > + g_core_fp.fp_register_read(ts, > + DRV_GET_ARRAY(addr_fw_define_maxpt_xyrvs), data, DATA_LEN_4); > + max_pt = data[0]; > + > + g_core_fp.fp_register_read(ts, > + DRV_GET_ARRAY(addr_fw_define_x_y_res), data, DATA_LEN_4); > + y_res = be16_to_cpup((u16 *)&data[0]); > + x_res = be16_to_cpup((u16 *)&data[2]); > + /* I("rx_num=%d, tx_num=%d, max_pt=%d, y_res=%d, x_res=%d", > + * rx_num, tx_num, max_pt, y_res, x_res); > + */ > + > + g_core_fp.fp_register_read(ts, > + DRV_GET_ARRAY(addr_fw_define_int_is_edge), data, DATA_LEN_4); > + if ((data[1] & 0x01) == 1) > + int_is_edge = true; > + else > + int_is_edge = false; > + > + /*1. Read number of MKey R100070E8H to determin data size*/ > + g_core_fp.fp_register_read(ts, SRAM_GET_ARRAY(addr_mkey), data, > + DATA_LEN_4); > + bt_num = data[0] & 0x03; > + ts->ic_data->HX_BT_NUM = bt_num; > + > + addr.dword = 0x1000719C; > + addr.dword = cpu_to_le32(addr.dword); > + > + g_core_fp.fp_register_read(ts, addr.byte, data, DATA_LEN_4); > + stylus_func = data[3]; > + ts->ic_data->HX_STYLUS_FUNC = stylus_func; > + > + ts->ic_data->HX_RX_NUM = rx_num; > + > + ts->ic_data->HX_TX_NUM = tx_num; > + > + ts->ic_data->HX_X_RES = x_res; > + ts->ic_data->HX_Y_RES = y_res; > + ts->ic_data->HX_MAX_PT = max_pt; > + ts->ic_data->HX_INT_IS_EDGE = int_is_edge; > + > + if (ts->ic_data->HX_STYLUS_FUNC) { > + addr.dword = 0x100071FC; > + addr.dword = cpu_to_le32(addr.dword); > + g_core_fp.fp_register_read(ts, addr.byte, data, DATA_LEN_4); > + stylus_id_v2 = data[2];/* 0x100071FE 0=off 1=on */ > + stylus_ratio = data[3]; > + /* 0x100071FF 0=ratio_1 10=ratio_10 */ > + ts->ic_data->HX_STYLUS_ID_V2 = stylus_id_v2; > + ts->ic_data->HX_STYLUS_RATIO = stylus_ratio; > + } > + > + I("TOUCH_INFO updated"); > + > + return 0; > +} > + > +static void himax_mcu_touch_information(struct himax_ts_data *ts) > +{ > + if (ts->ic_data->HX_RX_NUM == 0xFFFFFFFF) > + ts->ic_data->HX_RX_NUM = FIX_HX_RX_NUM; > + > + if (ts->ic_data->HX_TX_NUM == 0xFFFFFFFF) > + ts->ic_data->HX_TX_NUM = FIX_HX_TX_NUM; > + > + if (ts->ic_data->HX_BT_NUM == 0xFFFFFFFF) > + ts->ic_data->HX_BT_NUM = FIX_HX_BT_NUM; > + > + if (ts->ic_data->HX_MAX_PT == 0xFFFFFFFF) > + ts->ic_data->HX_MAX_PT = FIX_HX_MAX_PT; > + > + if (ts->ic_data->HX_INT_IS_EDGE == 0xFF) > + ts->ic_data->HX_INT_IS_EDGE = FIX_HX_INT_IS_EDGE; > + > + if (ts->ic_data->HX_STYLUS_FUNC == 0xFF) > + ts->ic_data->HX_STYLUS_FUNC = FIX_HX_STYLUS_FUNC; > + > + if (ts->ic_data->HX_STYLUS_ID_V2 == 0xFF) > + ts->ic_data->HX_STYLUS_ID_V2 = FIX_HX_STYLUS_ID_V2; > + > + if (ts->ic_data->HX_STYLUS_RATIO == 0xFF) > + ts->ic_data->HX_STYLUS_RATIO = FIX_HX_STYLUS_RATIO; > + > + I("HX_RX_NUM = %d,HX_TX_NUM = %d", > + ts->ic_data->HX_RX_NUM, ts->ic_data->HX_TX_NUM); > + I("HX_MAX_PT = %d", ts->ic_data->HX_MAX_PT); > + I("HX_INT_IS_EDGE = %d,HX_STYLUS_FUNC = %d", > + ts->ic_data->HX_INT_IS_EDGE, ts->ic_data->HX_STYLUS_FUNC); > + I("HX_STYLUS_ID_V2 = %d,HX_STYLUS_RATIO = %d", > + ts->ic_data->HX_STYLUS_ID_V2, ts->ic_data->HX_STYLUS_RATIO); > +} > + > +static void himax_mcu_calc_touch_data_size(struct himax_ts_data *ts) > +{ > + ts->x_channel = ts->ic_data->HX_RX_NUM; > + ts->y_channel = ts->ic_data->HX_TX_NUM; > + ts->n_finger_support = ts->ic_data->HX_MAX_PT; > +} > + > +static int himax_mcu_get_touch_data_size(void) > +{ > + return HIMAX_TOUCH_DATA_SIZE; > +} > + > +static int himax_mcu_hand_shaking(void) > +{ > + /* 0:Running, 1:Stop, 2:I2C Fail */ > + int result = 0; > + return result; > +} > + > +static int himax_mcu_determin_diag_rawdata(int diag_command) > +{ > + return diag_command % 10; > +} > + > +static int himax_mcu_determin_diag_storage(int diag_command) > +{ > + return diag_command / 10; > +} > + > +static int himax_mcu_cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, > + int raw_cnt_max) > +{ > + int raw_data_len; > + /* rawdata checksum is 2 bytes */ > + if (raw_cnt_rmd != 0x00) > + raw_data_len = MAX_I2C_TRANS_SZ > + - ((HX_MAX_PT + raw_cnt_max + 3) * 4) - 2; > + else > + raw_data_len = MAX_I2C_TRANS_SZ > + - ((HX_MAX_PT + raw_cnt_max + 2) * 4) - 2; > + > + return raw_data_len; > +} > + > +static bool himax_mcu_diag_check_sum(struct himax_ts_data *ts) > +{ > + u16 check_sum_cal = 0; > + int i; > + > + /* Check 128th byte CRC */ > + for (i = 0, check_sum_cal = 0; > + i < (ts->touch_all_size > + - ts->touch_info_size); > + i += 2) { > + check_sum_cal += (ts->hx_rawdata_buf[i + 1] > + * FLASH_RW_MAX_LEN > + + ts->hx_rawdata_buf[i]); > + } > + > + if (check_sum_cal % HX64K != 0) { > + I("fail = %2X", check_sum_cal); > + return 0; > + } > + > + return 1; > +} > + > +static int himax_mcu_ic_excp_recovery > + (struct himax_ts_data *ts, > + u32 hx_excp_event, > + u32 hx_zero_event, > + u32 length) > +{ > + int ret_val = NO_ERR; > + > + if (hx_excp_event == length) { > + ts->excp_zero_event_count = 0; > + ret_val = HX_EXCP_EVENT; > + } else if (hx_zero_event == length) { > + if (ts->excp_zero_event_count > 5) { > + ts->excp_zero_event_count = 0; > + I("EXCEPTION event checked - ALL Zero."); > + ret_val = HX_EXCP_EVENT; > + } else { > + ts->excp_zero_event_count++; > + I("ALL Zero event is %d times.", > + ts->excp_zero_event_count); > + ret_val = HX_ZERO_EVENT_COUNT; > + } > + } > + > + return ret_val; > +} > + > +static void himax_mcu_excp_ic_reset(struct himax_ts_data *ts) > +{ > + ts->excp_reset_active = 0; > + himax_mcu_pin_reset(ts); > + I("reset!"); > +} > + > +static void himax_mcu_resend_cmd_func(struct himax_ts_data *ts, bool suspended) > +{ > + himax_cable_detect_func(ts, true); > +} > + > +/* CORE_DRIVER */ > + > +static int hx_turn_on_mp_func(struct himax_ts_data *ts, int on) > +{ > + int rslt = 0; > + int retry = 3; > + struct hx_reg_t tmp_addr; > + struct hx_reg_t tmp_data; > + u8 tmp_read[4] = {0}; > + > + if (strcmp(HX83102D_ID, ts->chip_name) == 0) { > + WORD_REG(tmp_addr, fw_addr_ctrl_mpap_ovl); > + if (on) { > + I("Turn on MPAP mode!"); > + WORD_REG(tmp_data, fw_data_ctrl_mpap_ovl_on); > + do { > + g_core_fp.fp_register_write(ts, REG_GET_ARRAY(tmp_addr), > + REG_GET_ARRAY(tmp_data), REG_GET_SZ(tmp_data)); > + usleep_range(10000, 10001); > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + tmp_read, 4); > + > + I("read2=0x%02X,read1=0x%02X,read0=0x%02X", > + tmp_read[2], tmp_read[1], > + tmp_read[0]); > + > + retry--; > + } while (((retry > 0) && > + (tmp_read[2] != REG_GET_ARRAY(tmp_data)[2] && > + tmp_read[1] != REG_GET_ARRAY(tmp_data)[1] && > + tmp_read[0] != REG_GET_ARRAY(tmp_data)[0]))); > + } else { > + I("Turn off MPAP mode!"); > + WORD_REG(tmp_data, fw_data_clear); > + do { > + g_core_fp.fp_register_write(ts, REG_GET_ARRAY(tmp_addr), > + REG_GET_ARRAY(tmp_data), REG_GET_SZ(tmp_data)); > + usleep_range(10000, 10001); > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + tmp_read, sizeof(tmp_read)); > + > + I("read2=0x%02X,read1=0x%02X,read0=0x%02X", > + tmp_read[2], tmp_read[1], tmp_read[0]); > + > + retry--; > + } while ((retry > 0) && > + (tmp_read[2] != REG_GET_ARRAY(tmp_data)[2] && > + tmp_read[1] != REG_GET_ARRAY(tmp_data)[1] && > + tmp_read[0] != REG_GET_ARRAY(tmp_data)[0])); > + } > + } else { > + I("Nothing to be done!"); > + } > + > + return rslt; > +} > + > +static void hx_dis_rload_0f(struct himax_ts_data *ts, int disable) > +{ > + /*Disable Flash Reload*/ > + g_core_fp.fp_register_write(ts, > + DRV_GET_ARRAY(addr_fw_define_flash_reload), > + ZF_GET_ARRAY(data_dis_flash_reload), DATA_LEN_4); > +} > + > +static void himax_mcu_clean_sram_0f(struct himax_ts_data *ts, u8 *addr, > + int write_len, int type) > +{ > + int total_read_times = 0; > + int max_bus_size = MAX_I2C_TRANS_SZ; > + int total_size_temp = 0; > + int address = 0; > + int i = 0; > + > + u8 fix_data = 0x00; > + union hx_dword_data_t tmp_addr; > + u8 tmp_data[MAX_I2C_TRANS_SZ] = {0}; > + > + I("Entering"); > + > + total_size_temp = write_len; > + > + tmp_addr.dword = le32_to_cpup((__le32 *)addr); > + I("addr = 0x%08X", tmp_addr.dword); > + > + switch (type) { > + case 0: > + fix_data = 0x00; > + break; > + case 1: > + fix_data = 0xAA; > + break; > + case 2: > + fix_data = 0xBB; > + break; > + } > + > + for (i = 0; i < MAX_I2C_TRANS_SZ; i++) > + tmp_data[i] = fix_data; > + > + I("total size=%d", total_size_temp); > + > + if (total_size_temp % max_bus_size == 0) > + total_read_times = total_size_temp / max_bus_size; > + else > + total_read_times = total_size_temp / max_bus_size + 1; > + > + tmp_addr.dword = cpu_to_le32(tmp_addr.dword); > + for (i = 0; i < (total_read_times); i++) { > + I("[log]write %d time start!", i); > + if (total_size_temp >= max_bus_size) { > + g_core_fp.fp_register_write(ts, tmp_addr.byte, tmp_data, > + max_bus_size); > + total_size_temp = total_size_temp - max_bus_size; > + } else { > + I("last total_size_temp=%d", total_size_temp); > + g_core_fp.fp_register_write(ts, tmp_addr.byte, tmp_data, > + total_size_temp % max_bus_size); > + } > + address = ((i + 1) * max_bus_size); > + tmp_addr.dword = cpu_to_le32(address); > + > + usleep_range(10000, 11000); > + } > + > + I("END"); > +} > + > +static void himax_mcu_write_sram_0f(struct himax_ts_data *ts, > + u8 *addr, const u8 *data, u32 len) > +{ > + int max_bus_size = MAX_I2C_TRANS_SZ; > + u32 remain_len = 0; > + u32 address = 0; > + u32 i; > + struct hx_reg_t tmp_addr; > + > + I("Entering - total write size = %d", len); > + > +#if defined(BUS_W_DLEN) > + max_bus_size = BUS_W_DLEN - ADDR_LEN_4; > +#endif > + > + if (strcmp(ts->chip_name, HX83121A_ID) == 0) { > + if (max_bus_size > 4096) > + max_bus_size = 4096; > + } > + > + remain_len = len; > + address = le32_to_cpup((__le32 *)addr); > + > + while (remain_len > 0) { > + i = len - remain_len; > + WORD_REG(tmp_addr, address + i); > + > + if (remain_len > max_bus_size) { > + g_core_fp.fp_register_write(ts, REG_GET_ARRAY(tmp_addr), > + (u8 *)data + i, max_bus_size); > + remain_len -= max_bus_size; > + } else { > + g_core_fp.fp_register_write(ts, REG_GET_ARRAY(tmp_addr), > + (u8 *)data + i, remain_len); > + remain_len = 0; > + } > + } > + > + I("End"); > +} > + > +static int himax_sram_write_crc_check(struct himax_ts_data *ts, > + u8 *addr, const u8 *data, u32 len) > +{ > + int retry = 0; > + int crc = -1; > + > + do { > + g_core_fp.fp_write_sram_0f(ts, addr, data, len); > + crc = g_core_fp.fp_check_crc(ts, addr, len); > + retry++; > + I("HW CRC %s in %d time", > + (crc == 0) ? "OK" : "Fail", retry); > + } while (crc != 0 && retry < 3); > + > + return crc; > +} > + > +static int code_overlay(struct zf_info *info, const struct firmware *fw, > + struct himax_ts_data *ts, int type) > +{ > + int ret = 0; > + int retry = 0; > + union hx_dword_data_t tmp_addr = { .dword = 0x10007FFC }; > + union hx_dword_data_t rdata = {0}; > + u8 code_idx_t = 0; > + union hx_dword_data_t code_sdata = {0}; > + > + /* ovl_idx[0] - sorting */ > + /* ovl_idx[1] - gesture */ > + /* ovl_idx[2] - border */ > + > + code_idx_t = ts->ovl_idx[0]; > + code_sdata.dword = ovl_sorting_reply; > + > + if (type == 0) { > + code_idx_t = ts->ovl_idx[2]; > + code_sdata.dword = ovl_border_reply; > + } > + if (code_idx_t == 0 || info[code_idx_t].write_size == 0) { > + E("wrong code overlay section[%d, %d]!", > + code_idx_t, info[code_idx_t].write_size); > + ret = FW_NOT_READY; > + goto ALOC_CFG_BUF_FAIL; > + } > + > + I("upgrade code overlay section[%d]", code_idx_t); > + if (himax_sram_write_crc_check(ts, info[code_idx_t].sram_addr, > + &fw->data[info[code_idx_t].fw_addr], > + info[code_idx_t].write_size) != 0) { > + E("code overlay HW CRC FAIL"); > + code_sdata.dword = ovl_fault; > + ret = 2; > + } > + > + retry = 0; > + tmp_addr.dword = cpu_to_le32(tmp_addr.dword); > + code_sdata.dword = cpu_to_le32(code_sdata.dword); > + do { > + g_core_fp.fp_register_write(ts, tmp_addr.byte, code_sdata.byte, > + DATA_LEN_4); > + usleep_range(1000, 1100); > + g_core_fp.fp_register_read(ts, tmp_addr.byte, rdata.byte, > + DATA_LEN_4); > + retry++; > + } while ((code_sdata.dword != rdata.dword) && > + (retry < HIMAX_REG_RETRY_TIMES)); > + > + if (retry >= HIMAX_REG_RETRY_TIMES) > + E("fail code rpl data = 0x%08X", rdata.dword); > + > +ALOC_CFG_BUF_FAIL: > + return ret; > +} > + > +static int alg_overlay(struct himax_ts_data *ts, u8 alg_idx_t, > + struct zf_info *info, const struct firmware *fw) > +{ > + int ret = 0; > + int retry = 0; > + union hx_dword_data_t tmp_addr = { .dword = 0x10007FFC }; > + union hx_dword_data_t rdata = {0}; > + u8 i = 0; > + union hx_dword_data_t alg_sdata = { .dword = 0xA55A5AA5 }; > + union hx_dword_data_t data = { .dword = 0x00000001 }; > + > + if (alg_idx_t == 0 || info[alg_idx_t].write_size == 0) { > + E("wrong alg overlay section[%d, %d]!", > + alg_idx_t, info[alg_idx_t].write_size); > + ret = FW_NOT_READY; > + goto ALOC_CFG_BUF_FAIL; > + } > + > + // clear handshaking to 0xA55A5AA5 > + > + retry = 0; > + tmp_addr.dword = cpu_to_le32(tmp_addr.dword); > + alg_sdata.dword = cpu_to_le32(alg_sdata.dword); > + do { > + g_core_fp.fp_register_write(ts, tmp_addr.byte, alg_sdata.byte, > + DATA_LEN_4); > + usleep_range(1000, 1100); > + g_core_fp.fp_register_read(ts, tmp_addr.byte, rdata.byte, > + DATA_LEN_4); > + } while ((rdata.dword != alg_sdata.dword) && > + retry++ < HIMAX_REG_RETRY_TIMES); > + > + if (retry > HIMAX_REG_RETRY_TIMES) { > + E("init handshaking data FAIL[0x%08X]!!", > + le32_to_cpu(rdata.dword)); > + } > + > + alg_sdata.dword = ovl_alg_reply; > + > + g_core_fp.fp_reload_disable(ts, 0); > + > + /*Rawout Sel initial*/ > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_raw_out_sel), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + /*DSRAM func initial*/ > + g_core_fp.fp_assign_sorting_mode(ts, FW_GET_ARRAY(data_clear)); > + /* reset N frame back to default for normal mode */ > + g_core_fp.fp_register_write(ts, FW_GET_ARRAY(addr_set_frame_addr), > + data.byte, 4); > + /*FW reload done initial*/ > + g_core_fp.fp_register_write(ts, > + DRV_GET_ARRAY(addr_fw_define_2nd_flash_reload), > + FW_GET_ARRAY(data_clear), FW_GET_SZ(data_clear)); > + > + g_core_fp.fp_sense_on(ts, 0x00); > + > + retry = 0; > + do { > + usleep_range(3000, 3100); > + g_core_fp.fp_register_read(ts, tmp_addr.byte, rdata.byte, DATA_LEN_4); > + } while ((rdata.dword != ovl_alg_request) && retry++ < 30); > + > + if (retry > 30) { > + E("fail req data = 0x%08X", le32_to_cpu(rdata.dword)); > + /* monitor FW status for debug */ > + for (i = 0; i < 10; i++) { > + usleep_range(10000, 10100); > + g_core_fp.fp_register_read(ts, tmp_addr.byte, rdata.byte, > + DATA_LEN_4); > + I("req data = 0x%08X", le32_to_cpu(rdata.dword)); > + g_core_fp.fp_read_FW_status(ts); > + } > + ret = 3; > + goto BURN_OVL_FAIL; > + } > + > + I("upgrade alg overlay section[%d]", alg_idx_t); > + > + if (himax_sram_write_crc_check(ts, info[alg_idx_t].sram_addr, > + &fw->data[info[alg_idx_t].fw_addr], > + info[alg_idx_t].write_size) != 0) { > + E("Alg Overlay HW CRC FAIL"); > + ret = 2; > + } > + > + retry = 0; > + do { > + g_core_fp.fp_register_write(ts, tmp_addr.byte, alg_sdata.byte, > + DATA_LEN_4); > + usleep_range(1000, 1100); > + g_core_fp.fp_register_read(ts, tmp_addr.byte, rdata.byte, DATA_LEN_4); > + } while ((alg_sdata.dword != rdata.dword) && > + retry++ < HIMAX_REG_RETRY_TIMES); > + > + if (retry > HIMAX_REG_RETRY_TIMES) { > + E("fail rpl data = 0x%08X", le32_to_cpu(rdata.dword)); > + // maybe need to reset > + } else { > + I("waiting for FW reload data"); > + > + retry = 0; > + while (retry++ < 30) { > + g_core_fp.fp_register_read(ts, > + DRV_GET_ARRAY(addr_fw_define_2nd_flash_reload), > + data.byte, DATA_LEN_4); > + > + /* use all 4 bytes to compare */ > + if (le32_to_cpu(data.dword) == 0x72C0) { > + I("FW reload done"); > + break; > + } > + I("wait FW reload %d times", retry); > + g_core_fp.fp_read_FW_status(ts); > + usleep_range(10000, 11000); > + } > + } > + > +BURN_OVL_FAIL: > +ALOC_CFG_BUF_FAIL: > + return ret; > +} > + > +int himax_zf_part_info(const struct firmware *fw, struct himax_ts_data *ts, > + int type) > +{ > + u32 table_addr = FLASH_VER_GET_VAL(addr_cfg_table); > + int pnum = 0; > + int ret = 0; > + u8 buf[16]; > + struct zf_info *info; > + u8 sram_min[4]; > + int cfg_sz = 0; > + int cfg_crc_sw = 0; > + int cfg_crc_hw = 0; > + s32 i = 0; > + int i_max = 0; > + int i_min = 0; > + u32 dsram_base = 0xFFFFFFFF; > + u32 dsram_max = 0; > + int retry = 0; > + int allovlidx = 0; > + s32 alg_idx_t = 0; > + s32 j = 0; > + bool has_code_overlay = false; > + > + ts->has_alg_overlay = false; > + > + /* 1. initial check */ > + if (g_core_fp._en_hw_crc) > + g_core_fp._en_hw_crc(ts, 1); > + pnum = fw->data[table_addr + 12]; > + if (pnum < 2) { > + E("partition number is not correct"); > + return FW_NOT_READY; > + } > + > + info = kcalloc(pnum, sizeof(struct zf_info), GFP_KERNEL); > + if (!info) { > + E("memory allocation fail[info]!!"); > + return 1; > + } > + memset(info, 0, pnum * sizeof(struct zf_info)); > + if (!ts->ovl_idx) { > + ts->ovl_idx = kcalloc(ovl_section_num, sizeof(u8), GFP_KERNEL); > + if (!ts->ovl_idx) { > + E("memory allocation fail[ovl_idx]!!"); > + ret = 1; > + goto ALOC_CFG_BUF_FAIL; > + } > + } > + memset(ts->ovl_idx, 0, ovl_section_num); > + > + /* 2. record partition information */ > + memcpy(buf, &fw->data[table_addr], 16); > + memcpy(info[0].sram_addr, buf, 4); > + info[0].write_size = le32_to_cpup((u32 *)&buf[4]); > + info[0].fw_addr = le32_to_cpup((u32 *)&buf[8]); > + I("[%d]SRAM addr=%08X, fw_addr=%08X, write_size=%d", > + 0, info[0].cfg_addr, info[0].fw_addr, > + info[0].write_size); > + > + for (i = 1; i < pnum; i++) { > + memcpy(buf, &fw->data[i * 0x10 + table_addr], 16); > + > + memcpy(info[i].sram_addr, buf, 4); > + info[i].write_size = le32_to_cpup((u32 *)&buf[4]); > + info[i].fw_addr = le32_to_cpup((u32 *)&buf[8]); > + info[i].cfg_addr = le32_to_cpup((u32 *)&info[i].sram_addr[0]); > + > + if (info[i].cfg_addr % 4 != 0) > + info[i].cfg_addr -= (info[i].cfg_addr % 4); > + > + I("[%d]SRAM addr=%08X, fw_addr=%08X, write_size=%d", > + i, info[i].cfg_addr, info[i].fw_addr, > + info[i].write_size); > + > + /* alg overlay section */ > + if ((buf[15] == 0x77 && buf[14] == 0x88)) { > + I("find alg overlay section in index %d", i); > + /* record index of alg overlay section */ > + allovlidx |= 1 << i; > + alg_idx_t = i; > + ts->has_alg_overlay = true; > + continue; > + } > + > + /* code overlay section */ > + if ((buf[15] == 0x55 && buf[14] == 0x66) || > + le32_to_cpup((u32 *)&buf[0]) == 0x20008CE0) { > + I("find code overlay section in index %d", i); > + has_code_overlay = true; > + /* record index of code overlay section */ > + allovlidx |= 1 << i; > + if (buf[15] == 0x55 && buf[14] == 0x66) { > + /* current mechanism */ > + j = buf[13]; > + if (j < ovl_section_num) > + ts->ovl_idx[j] = i; > + } else { > + /* previous mechanism */ > + if (j < ovl_section_num) > + ts->ovl_idx[j++] = i; > + } > + continue; > + } > + > + if (dsram_base > info[i].cfg_addr) { > + dsram_base = info[i].cfg_addr; > + i_min = i; > + } > + if (dsram_max < info[i].cfg_addr) { > + dsram_max = info[i].cfg_addr; > + i_max = i; > + } > + } > + > + /* 3. prepare data to update */ > + for (i = 0; i < ADDR_LEN_4; i++) > + sram_min[i] = (info[i_min].cfg_addr >> (8 * i)) & 0xFF; > + > + D("dsram_max: %d, dsram_base: %d, write_size: %d", > + dsram_max, dsram_base, info[i_max].write_size); > + cfg_sz = (dsram_max - dsram_base) + info[i_max].write_size; > + if (cfg_sz % 16 != 0) > + cfg_sz = cfg_sz + 16 - (cfg_sz % 16); > + > + I("cfg_sz = %d!, dsram_base = %X, dsram_max = %X", > + cfg_sz, dsram_base, dsram_max); > + /* config size should be smaller than DSRAM size */ > + if (cfg_sz > ts->chip_max_dsram_size) { > + E("config size error[%d, %d]!!", > + cfg_sz, ts->chip_max_dsram_size); > + ret = LENGTH_FAIL; > + goto ALOC_CFG_BUF_FAIL; > + } > + > + memset(ts->zf_update_cfg_buffer, 0x00, > + ts->chip_max_dsram_size * sizeof(u8)); > + > + for (i = 1; i < pnum; i++) { > + /* overlay section */ > + if (allovlidx & (1 << i)) { > + I("skip overlay section %d", i); > + continue; > + } > + > + memcpy(&ts->zf_update_cfg_buffer[info[i].cfg_addr - dsram_base], > + &fw->data[info[i].fw_addr], info[i].write_size); > + } > + > + /* 4. write to sram */ > + /* FW entity */ > + if (himax_sram_write_crc_check(ts, info[0].sram_addr, > + &fw->data[info[0].fw_addr], info[0].write_size) != 0) { > + E("HW CRC FAIL"); > + ret = 2; > + goto BURN_SRAM_FAIL; > + } > + > + cfg_crc_sw = g_core_fp.fp_calculate_crc_with_ap(ts->zf_update_cfg_buffer, > + 0, cfg_sz); > + do { > + g_core_fp.fp_write_sram_0f(ts, sram_min, ts->zf_update_cfg_buffer, > + cfg_sz); > + cfg_crc_hw = g_core_fp.fp_check_crc(ts, sram_min, cfg_sz); > + if (cfg_crc_hw != cfg_crc_sw) { > + E("Cfg CRC FAIL,HWCRC=%X,SWCRC=%X,retry=%d", > + cfg_crc_hw, cfg_crc_sw, retry); > + } > + } while (cfg_crc_hw != cfg_crc_sw && retry++ < 3); > + > + if (retry > 3) { > + ret = 2; > + goto BURN_SRAM_FAIL; > + } > + > + /*write back system config*/ > + if (type == 0) > + g_core_fp.fp_resend_cmd_func(ts, ts->suspended); > + > + if (ts->has_alg_overlay) > + ret = alg_overlay(ts, alg_idx_t, info, fw); > + if (has_code_overlay) > + ret = code_overlay(info, fw, ts, type); > + > +BURN_SRAM_FAIL: > +ALOC_CFG_BUF_FAIL: > + kfree(info); > + > + return ret; > +/* ret = 1, memory allocation fail > + * = 2, crc fail > + * = 3, flow control error > + */ > +} > + > +int himax_mcu_firmware_update_0f(const struct firmware *fw, > + struct himax_ts_data *ts, int type) > +{ > + int ret = 0; > + bool bret; > + > + I("Entering - total FW size=%d", (int)fw->size); > + > + g_core_fp.fp_register_write(ts, ZF_GET_ARRAY(addr_system_reset), > + ZF_GET_ARRAY(data_system_reset), 4); > + > + bret = g_core_fp.fp_sense_off(ts, false); > + if (!bret) { > + E("sense off fail"); > + return -1; > + } > + > + if ((int)fw->size > HX64K) { > + ret = himax_zf_part_info(fw, ts, type); > + } else { > + /* first 48K */ > + ret = himax_sram_write_crc_check > + (ts, ZF_GET_ARRAY(data_sram_start_addr), &fw->data[0], HX_48K_SZ); > + if (ret != 0) > + E("HW CRC FAIL - Main SRAM 48K"); > + > + /*config info*/ > + if (!ts->ic_data->has_flash) { > + ret = himax_sram_write_crc_check(ts, ZF_GET_ARRAY(data_cfg_info), > + &fw->data[0xc000], 128); > + if (ret != 0) > + E("Config info CRC Fail!"); > + } else { > + g_core_fp.fp_clean_sram_0f(ts, ZF_GET_ARRAY(data_cfg_info), > + 128, 2); > + } > + > + if (!ts->ic_data->has_flash) { > + ret = himax_sram_write_crc_check(ts, ZF_GET_ARRAY(data_fw_cfg_1), > + &fw->data[0xc0fe], 528); > + if (ret != 0) > + E("FW config 1 CRC Fail!"); > + } else { > + g_core_fp.fp_clean_sram_0f(ts, ZF_GET_ARRAY(data_fw_cfg_1), > + 528, 1); > + } > + > + if (!ts->ic_data->has_flash) { > + ret = himax_sram_write_crc_check(ts, ZF_GET_ARRAY(data_fw_cfg_3), > + &fw->data[0xca00], 128); > + if (ret != 0) > + E("FW config 3 CRC Fail!"); > + } else { > + g_core_fp.fp_clean_sram_0f(ts, ZF_GET_ARRAY(data_fw_cfg_3), > + 128, 2); > + } > + > + /*ADC config*/ > + if (!ts->ic_data->has_flash) { > + ret = himax_sram_write_crc_check(ts, ZF_GET_ARRAY(data_adc_cfg_1), > + &fw->data[0xd640], 1200); > + if (ret != 0) > + E("ADC config 1 CRC Fail!"); > + } else { > + g_core_fp.fp_clean_sram_0f(ts, ZF_GET_ARRAY(data_adc_cfg_1), > + 1200, 2); > + } > + > + if (!ts->ic_data->has_flash) { > + ret = himax_sram_write_crc_check(ts, ZF_GET_ARRAY(data_adc_cfg_2), > + &fw->data[0xd320], 800); > + if (ret != 0) > + E("ADC config 2 CRC Fail!"); > + } else { > + g_core_fp.fp_clean_sram_0f(ts, ZF_GET_ARRAY(data_adc_cfg_2), > + 800, 2); > + } > + > + /*mapping table*/ > + if (!ts->ic_data->has_flash) { > + ret = himax_sram_write_crc_check(ts, ZF_GET_ARRAY(data_map_table), > + &fw->data[0xe000], 1536); > + if (ret != 0) > + E("Mapping table CRC Fail!"); > + } else { > + g_core_fp.fp_clean_sram_0f(ts, ZF_GET_ARRAY(data_map_table), > + 1536, 2); > + } > + } > + > + I("End"); > + > + return ret; > +} > + > +int hx_0f_op_file_dirly(char *file_name, struct himax_ts_data *ts) > +{ > + const struct firmware *fw = NULL; > + int reqret = -1; > + int ret = -1; > + int type = 0; /* FW type: 0, normal; 1, MPAP */ > + > + if (ts->zf_update_flag) { > + W("Other thread is updating now!"); > + return ret; > + } > + ts->zf_update_flag = true; > + I("Preparing to update %s!", file_name); > + > + reqret = request_firmware(&fw, file_name, ts->dev); > + if (reqret < 0) { > + ret = reqret; > + E("request firmware fail, code[%d]!!", ret); > + goto END; > + } > + > + if (strcmp(file_name, MPAP_FWNAME) == 0) > + type = 1; > + > + ret = g_core_fp.fp_firmware_update_0f(fw, ts, type); > + > + if (reqret >= 0) > + release_firmware(fw); > + > + if (ret < 0) > + goto END; > + > + if (!ts->has_alg_overlay) { > + if (type == 1) > + g_core_fp.fp_turn_on_mp_func(ts, 1); > + else > + g_core_fp.fp_turn_on_mp_func(ts, 0); > + g_core_fp.fp_reload_disable(ts, 0); > + g_core_fp.fp_power_on_init(ts); > + } > + > +END: > + ts->zf_update_flag = false; > + > + I("END"); > + return ret; > +} > + > +static int himax_mcu_0f_excp_check(void) > +{ > + return NO_ERR; > +} > + > +void himax_mcu_read_sram_0f(struct himax_ts_data *ts, > + const struct firmware *fw_entry, > + u8 *addr, int start_index, int read_len) > +{ > + int total_read_times = 0; > + int max_bus_size = MAX_I2C_TRANS_SZ; > + int total_size_temp = 0; > + int total_size = 0; > + int address = 0; > + int i = 0, j = 0; > + int not_same = 0; > + struct hx_reg_t in_addr = { .data = {0}, .len = 4 }; > + struct hx_reg_t tmp_addr = { .data = {0}, .len = 4 }; > + u8 *temp_info_data = NULL; > + int *not_same_buff = NULL; > + > + I("Entering"); > + PTR_SET(in_addr, addr, 4); > + total_size = read_len; > + total_size_temp = read_len; > + > + if (read_len > 2048) > + max_bus_size = 2048; > + else > + max_bus_size = read_len; > + > + if (total_size % max_bus_size == 0) > + total_read_times = total_size / max_bus_size; > + else > + total_read_times = total_size / max_bus_size + 1; > + > + I("total size=%d, bus size=%d, read time=%d", > + total_size, max_bus_size, total_read_times); > + > + memcpy(REG_GET_ARRAY(tmp_addr), addr, 4); > + I("addr[3]=0x%2X,addr[2]=0x%2X,addr[1]=0x%2X,addr[0]=0x%2X", > + REG_GET_ARRAY(tmp_addr)[3], REG_GET_ARRAY(tmp_addr)[2], > + REG_GET_ARRAY(tmp_addr)[1], REG_GET_ARRAY(tmp_addr)[0]); > + > + temp_info_data = kcalloc(total_size, sizeof(u8), GFP_KERNEL); > + if (!temp_info_data) { > + E("Failed to allocate temp_info_data"); > + goto err_malloc_temp_info_data; > + } > + > + not_same_buff = kcalloc(total_size, sizeof(int), GFP_KERNEL); > + if (!not_same_buff) { > + E("Failed to allocate not_same_buff"); > + goto err_malloc_not_same_buff; > + } > + > + for (i = 0; i < (total_read_times); i++) { > + if (total_size_temp >= max_bus_size) { > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + &temp_info_data[i * max_bus_size], max_bus_size); > + total_size_temp = total_size_temp - max_bus_size; > + } else { > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + &temp_info_data[i * max_bus_size], > + total_size_temp % max_bus_size); > + } > + > + address = ((i + 1) * max_bus_size); > + WORD_REG(tmp_addr, address + REG_GET_VAL(in_addr)); > + } > + I("READ Start, start_index = %d", start_index); > + > + j = start_index; > + for (i = 0; i < read_len; i++, j++) { > + if (fw_entry->data[j] != temp_info_data[i]) { > + not_same++; > + not_same_buff[i] = 1; > + } > + > + I("0x%2.2X, ", temp_info_data[i]); > + > + if (i > 0 && i % 16 == 15) > + pr_info("\n"); > + } > + I("READ END,Not Same count=%d", not_same); > + > + if (not_same != 0) { > + j = start_index; > + for (i = 0; i < read_len; i++, j++) { > + if (not_same_buff[i] == 1) > + I("bin=[%d] 0x%2.2X", i, fw_entry->data[j]); > + } > + for (i = 0; i < read_len; i++, j++) { > + if (not_same_buff[i] == 1) > + I("sram=[%d] 0x%2.2X", i, temp_info_data[i]); > + } > + } > + I("READ END, Not Same count=%d", not_same); > + > + kfree(not_same_buff); > +err_malloc_not_same_buff: > + kfree(temp_info_data); > +err_malloc_temp_info_data: > + return; > +} > + > +void himax_mcu_read_all_sram(struct himax_ts_data *ts, u8 *addr, > + int read_len) > +{ > + int total_read_times = 0; > + int max_bus_size = MAX_I2C_TRANS_SZ; > + int total_size_temp = 0; > + int total_size = 0; > + int address = 0; > + int i = 0; > + struct hx_reg_t tmp_addr = { .data = {0}, .len = 4 }; > + u8 *temp_info_data; > + > + I("Entering"); > + > + total_size = read_len; > + total_size_temp = read_len; > + > + if (total_size % max_bus_size == 0) > + total_read_times = total_size / max_bus_size; > + else > + total_read_times = total_size / max_bus_size + 1; > + > + I("total size=%d", total_size); > + > + PTR_SET(tmp_addr, addr, 4); > + I("addr[3]=0x%2X,addr[2]=0x%2X,addr[1]=0x%2X,addr[0]=0x%2X", > + REG_GET_ARRAY(tmp_addr)[3], REG_GET_ARRAY(tmp_addr)[2], > + REG_GET_ARRAY(tmp_addr)[1], REG_GET_ARRAY(tmp_addr)[0]); > + > + temp_info_data = kcalloc(total_size, sizeof(u8), GFP_KERNEL); > + if (!temp_info_data) { > + E("Failed to allocate temp_info_data"); > + return; > + } > + > + for (i = 0; i < (total_read_times); i++) { > + if (total_size_temp >= max_bus_size) { > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + &temp_info_data[i * max_bus_size], max_bus_size); > + total_size_temp = total_size_temp - max_bus_size; > + } else { > + g_core_fp.fp_register_read(ts, REG_GET_ARRAY(tmp_addr), > + &temp_info_data[i * max_bus_size], > + total_size_temp % max_bus_size); > + } > + > + address = ((i + 1) * max_bus_size); > + WORD_REG(tmp_addr, address + REG_GET_VAL(tmp_addr)); > + } > + I("addr[3]=0x%2X,addr[2]=0x%2X,addr[1]=0x%2X,addr[0]=0x%2X", > + REG_GET_ARRAY(tmp_addr)[3], REG_GET_ARRAY(tmp_addr)[2], > + REG_GET_ARRAY(tmp_addr)[1], REG_GET_ARRAY(tmp_addr)[0]); > + > + kfree(temp_info_data); > + > + I("END"); > +} > + > +void himax_mcu_firmware_read_0f(struct himax_ts_data *ts, > + const struct firmware *fw_entry, int type) > +{ > + u8 tmp_addr[4]; > + > + I("Entering"); > + if (type == 0) { /* first 48K */ > + g_core_fp.fp_read_sram_0f(ts, fw_entry, > + ZF_GET_ARRAY(data_sram_start_addr), > + 0, > + HX_48K_SZ); > + g_core_fp.fp_read_all_sram(ts, tmp_addr, 0xC000); > + } else { /*last 16k*/ > + g_core_fp.fp_read_sram_0f(ts, fw_entry, ZF_GET_ARRAY(data_cfg_info), > + 0xC000, 132); > + > + /*FW config*/ > + g_core_fp.fp_read_sram_0f(ts, fw_entry, ZF_GET_ARRAY(data_fw_cfg_1), > + 0xC0FE, 484); > + g_core_fp.fp_read_sram_0f(ts, fw_entry, ZF_GET_ARRAY(data_fw_cfg_2), > + 0xC9DE, 36); > + g_core_fp.fp_read_sram_0f(ts, fw_entry, ZF_GET_ARRAY(data_fw_cfg_3), > + 0xCA00, 72); > + > + /*ADC config*/ > + > + g_core_fp.fp_read_sram_0f(ts, fw_entry, ZF_GET_ARRAY(data_adc_cfg_1), > + 0xD630, 1188); > + g_core_fp.fp_read_sram_0f(ts, fw_entry, ZF_GET_ARRAY(data_adc_cfg_2), > + 0xD318, 792); > + > + /*mapping table*/ > + g_core_fp.fp_read_sram_0f(ts, fw_entry, ZF_GET_ARRAY(data_map_table), > + 0xE000, 1536); > + > + /* set n frame=0*/ > + g_core_fp.fp_read_sram_0f(ts, fw_entry, > + FW_GET_ARRAY(addr_set_frame_addr), 0xC30C, 4); > + } > + > + I("END"); > +} > + > +void himax_ic_reg_init(struct himax_core_command_regs *reg_data) > +{ > + I("Entering!"); > +/* CORE_IC -start- */ > + BYTE_REG(reg_data->ic_op.addr_ahb_addr_byte_0, ic_adr_ahb_addr_byte_0); > + BYTE_REG(reg_data->ic_op.addr_ahb_rdata_byte_0, ic_adr_ahb_rdata_byte_0); > + BYTE_REG(reg_data->ic_op.addr_ahb_access_direction, ic_adr_ahb_access_direction); > + BYTE_REG(reg_data->ic_op.addr_conti, ic_adr_conti); > + BYTE_REG(reg_data->ic_op.addr_incr4, ic_adr_incr4); > + BYTE_REG(reg_data->ic_op.adr_i2c_psw_lb, ic_adr_i2c_psw_lb); > + BYTE_REG(reg_data->ic_op.adr_i2c_psw_ub, ic_adr_i2c_psw_ub); > + BYTE_REG(reg_data->ic_op.data_ahb_access_direction_read, ic_cmd_ahb_access_direction_read); > + BYTE_REG(reg_data->ic_op.data_conti, ic_cmd_conti); > + BYTE_REG(reg_data->ic_op.data_incr4, ic_cmd_incr4); > + BYTE_REG(reg_data->ic_op.data_i2c_psw_lb, ic_cmd_i2c_psw_lb); > + BYTE_REG(reg_data->ic_op.data_i2c_psw_ub, ic_cmd_i2c_psw_ub); > + WORD_REG(reg_data->ic_op.addr_tcon_on_rst, ic_adr_tcon_on_rst); > + WORD_REG(reg_data->ic_op.addr_adc_on_rst, ic_addr_adc_on_rst); > + WORD_REG(reg_data->ic_op.addr_psl, ic_adr_psl); > + WORD_REG(reg_data->ic_op.addr_cs_central_state, ic_adr_cs_central_state); > + WORD_REG(reg_data->ic_op.data_rst, ic_cmd_rst); > + WORD_REG(reg_data->ic_op.adr_osc_en, ic_adr_osc_en); > + WORD_REG(reg_data->ic_op.adr_osc_pw, ic_adr_osc_pw); > +/* CORE_IC -end- */ > +/* CORE_FW -start- */ > + WORD_REG(reg_data->fw_op.addr_system_reset, fw_addr_system_reset); > + WORD_REG(reg_data->fw_op.addr_ctrl_fw_isr, fw_addr_ctrl_fw); > + WORD_REG(reg_data->fw_op.addr_flag_reset_event, fw_addr_flag_reset_event); > + WORD_REG(reg_data->fw_op.addr_hsen_enable, fw_addr_hsen_enable); > + WORD_REG(reg_data->fw_op.addr_program_reload_from, > + fw_addr_program_reload_from); > + WORD_REG(reg_data->fw_op.addr_program_reload_to, > + fw_addr_program_reload_to); > + WORD_REG(reg_data->fw_op.addr_program_reload_page_write, > + fw_addr_program_reload_page_write); > + WORD_REG(reg_data->fw_op.addr_raw_out_sel, fw_addr_raw_out_sel); > + WORD_REG(reg_data->fw_op.addr_reload_status, fw_addr_reload_status); > + WORD_REG(reg_data->fw_op.addr_reload_crc32_result, > + fw_addr_reload_crc32_result); > + WORD_REG(reg_data->fw_op.addr_reload_addr_from, fw_addr_reload_addr_from); > + WORD_REG(reg_data->fw_op.addr_reload_addr_cmd_beat, > + fw_addr_reload_addr_cmd_beat); > + WORD_REG(reg_data->fw_op.addr_selftest_addr_en, fw_addr_selftest_addr_en); > + WORD_REG(reg_data->fw_op.addr_criteria_addr, fw_addr_criteria_addr); > + WORD_REG(reg_data->fw_op.addr_set_frame_addr, fw_addr_set_frame_addr); > + WORD_REG(reg_data->fw_op.addr_selftest_result_addr, > + fw_addr_selftest_result_addr); > + WORD_REG(reg_data->fw_op.addr_sorting_mode_en, fw_addr_sorting_mode_en); > + WORD_REG(reg_data->fw_op.addr_fw_mode_status, fw_addr_fw_mode_status); > + WORD_REG(reg_data->fw_op.addr_icid_addr, fw_addr_icid_addr); > + WORD_REG(reg_data->fw_op.addr_fw_ver_addr, fw_addr_fw_ver_addr); > + WORD_REG(reg_data->fw_op.addr_fw_cfg_addr, fw_addr_fw_cfg_addr); > + WORD_REG(reg_data->fw_op.addr_fw_vendor_addr, fw_addr_fw_vendor_addr); > + WORD_REG(reg_data->fw_op.addr_cus_info, fw_addr_cus_info); > + WORD_REG(reg_data->fw_op.addr_proj_info, fw_addr_proj_info); > + WORD_REG(reg_data->fw_op.addr_fw_state_addr, fw_addr_fw_state_addr); > + WORD_REG(reg_data->fw_op.addr_fw_dbg_msg_addr, fw_addr_fw_dbg_msg_addr); > + WORD_REG(reg_data->fw_op.addr_chk_fw_status, fw_addr_chk_fw_status); > + WORD_REG(reg_data->fw_op.addr_dd_handshak_addr, fw_addr_dd_handshak_addr); > + WORD_REG(reg_data->fw_op.addr_dd_data_addr, fw_addr_dd_data_addr); > + WORD_REG(reg_data->fw_op.addr_clr_fw_record_dd_sts, > + fw_addr_clr_fw_record_dd_sts); > + WORD_REG(reg_data->fw_op.addr_ap_notify_fw_sus, fw_addr_ap_notify_fw_sus); > + WORD_REG(reg_data->fw_op.data_ap_notify_fw_sus_en, > + fw_data_ap_notify_fw_sus_en); > + WORD_REG(reg_data->fw_op.data_ap_notify_fw_sus_dis, > + fw_data_ap_notify_fw_sus_dis); > + WORD_REG(reg_data->fw_op.data_system_reset, fw_data_system_reset); > + WORD_REG(reg_data->fw_op.data_safe_mode_release_pw_active, > + fw_data_safe_mode_release_pw_active); > + WORD_REG(reg_data->fw_op.data_safe_mode_release_pw_reset, > + fw_data_safe_mode_release_pw_reset); > + WORD_REG(reg_data->fw_op.data_clear, fw_data_clear); > + WORD_REG(reg_data->fw_op.data_fw_stop, fw_data_fw_stop); > + WORD_REG(reg_data->fw_op.data_program_reload_start, > + fw_data_program_reload_start); > + WORD_REG(reg_data->fw_op.data_program_reload_compare, > + fw_data_program_reload_compare); > + WORD_REG(reg_data->fw_op.data_program_reload_break, > + fw_data_program_reload_break); > + WORD_REG(reg_data->fw_op.data_selftest_request, fw_data_selftest_request); > + BYTE_REG(reg_data->fw_op.data_criteria_aa_top, fw_data_criteria_aa_top); > + BYTE_REG(reg_data->fw_op.data_criteria_aa_bot, fw_data_criteria_aa_bot); > + BYTE_REG(reg_data->fw_op.data_criteria_key_top, fw_data_criteria_key_top); > + BYTE_REG(reg_data->fw_op.data_criteria_key_bot, fw_data_criteria_key_bot); > + BYTE_REG(reg_data->fw_op.data_criteria_avg_top, fw_data_criteria_avg_top); > + BYTE_REG(reg_data->fw_op.data_criteria_avg_bot, fw_data_criteria_avg_bot); > + WORD_REG(reg_data->fw_op.data_set_frame, fw_data_set_frame); > + BYTE_REG(reg_data->fw_op.data_selftest_ack_hb, fw_data_selftest_ack_hb); > + BYTE_REG(reg_data->fw_op.data_selftest_ack_lb, fw_data_selftest_ack_lb); > + BYTE_REG(reg_data->fw_op.data_selftest_pass, fw_data_selftest_pass); > + BYTE_REG(reg_data->fw_op.data_normal_cmd, fw_data_normal_cmd); > + BYTE_REG(reg_data->fw_op.data_normal_status, fw_data_normal_status); > + BYTE_REG(reg_data->fw_op.data_sorting_cmd, fw_data_sorting_cmd); > + BYTE_REG(reg_data->fw_op.data_sorting_status, fw_data_sorting_status); > + BYTE_REG(reg_data->fw_op.data_dd_request, fw_data_dd_request); > + BYTE_REG(reg_data->fw_op.data_dd_ack, fw_data_dd_ack); > + BYTE_REG(reg_data->fw_op.data_idle_dis_pwd, fw_data_idle_dis_pwd); > + BYTE_REG(reg_data->fw_op.data_idle_en_pwd, fw_data_idle_en_pwd); > + BYTE_REG(reg_data->fw_op.data_rawdata_ready_hb, fw_data_rawdata_ready_hb); > + BYTE_REG(reg_data->fw_op.data_rawdata_ready_lb, fw_data_rawdata_ready_lb); > + BYTE_REG(reg_data->fw_op.addr_ahb_addr, fw_addr_ahb_addr); > + BYTE_REG(reg_data->fw_op.data_ahb_dis, fw_data_ahb_dis); > + BYTE_REG(reg_data->fw_op.data_ahb_en, fw_data_ahb_en); > + BYTE_REG(reg_data->fw_op.addr_event_addr, fw_addr_event_addr); > + WORD_REG(reg_data->fw_op.addr_usb_detect, fw_usb_detect_addr); > +/* CORE_FW -end- */ > +/* CORE_FLASH -start- */ > + WORD_REG(reg_data->flash_op.addr_spi200_trans_fmt, > + flash_addr_spi200_trans_fmt); > + WORD_REG(reg_data->flash_op.addr_spi200_trans_ctrl, > + flash_addr_spi200_trans_ctrl); > + WORD_REG(reg_data->flash_op.addr_spi200_fifo_rst, > + flash_addr_spi200_fifo_rst); > + WORD_REG(reg_data->flash_op.addr_spi200_flash_speed, > + flash_addr_spi200_flash_speed); > + WORD_REG(reg_data->flash_op.addr_spi200_rst_status, > + flash_addr_spi200_rst_status); > + WORD_REG(reg_data->flash_op.addr_spi200_cmd, flash_addr_spi200_cmd); > + WORD_REG(reg_data->flash_op.addr_spi200_addr, flash_addr_spi200_addr); > + WORD_REG(reg_data->flash_op.addr_spi200_data, flash_addr_spi200_data); > + WORD_REG(reg_data->flash_op.addr_spi200_bt_num, flash_addr_spi200_bt_num); > + WORD_REG(reg_data->flash_op.data_spi200_trans_fmt, > + flash_data_spi200_trans_fmt); > + WORD_REG(reg_data->flash_op.data_spi200_txfifo_rst, > + flash_data_spi200_txfifo_rst); > + WORD_REG(reg_data->flash_op.data_spi200_rxfifo_rst, > + flash_data_spi200_rxfifo_rst); > + WORD_REG(reg_data->flash_op.data_spi200_trans_ctrl_1, > + flash_data_spi200_trans_ctrl_1); > + WORD_REG(reg_data->flash_op.data_spi200_trans_ctrl_2, > + flash_data_spi200_trans_ctrl_2); > + WORD_REG(reg_data->flash_op.data_spi200_trans_ctrl_3, > + flash_data_spi200_trans_ctrl_3); > + WORD_REG(reg_data->flash_op.data_spi200_trans_ctrl_4, > + flash_data_spi200_trans_ctrl_4); > + WORD_REG(reg_data->flash_op.data_spi200_trans_ctrl_5, > + flash_data_spi200_trans_ctrl_5); > + WORD_REG(reg_data->flash_op.data_spi200_trans_ctrl_6, > + flash_data_spi200_trans_ctrl_6); > + WORD_REG(reg_data->flash_op.data_spi200_trans_ctrl_7, > + flash_data_spi200_trans_ctrl_7); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_1, flash_data_spi200_cmd_1); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_2, flash_data_spi200_cmd_2); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_3, flash_data_spi200_cmd_3); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_4, flash_data_spi200_cmd_4); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_5, flash_data_spi200_cmd_5); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_6, flash_data_spi200_cmd_6); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_7, flash_data_spi200_cmd_7); > + WORD_REG(reg_data->flash_op.data_spi200_cmd_8, flash_data_spi200_cmd_8); > + WORD_REG(reg_data->flash_op.data_spi200_addr, flash_data_spi200_addr); > +/* CORE_FLASH -end- */ > +/* CORE_SRAM */ > + /* sram start*/ > + WORD_REG(reg_data->sram_op.addr_mkey, sram_adr_mkey); > + WORD_REG(reg_data->sram_op.addr_rawdata_addr, sram_adr_rawdata_addr); > + WORD_REG(reg_data->sram_op.addr_rawdata_end, sram_adr_rawdata_end); > + HALF_REG(reg_data->sram_op.passwrd_start, sram_passwrd_start); > + HALF_REG(reg_data->sram_op.passwrd_end, sram_passwrd_end); > + /* sram end*/ > +/* CORE_SRAM */ > +/* CORE_DRIVER -start- */ > + WORD_REG(reg_data->driver_op.addr_fw_define_flash_reload, > + driver_addr_fw_define_flash_reload); > + WORD_REG(reg_data->driver_op.addr_fw_define_2nd_flash_reload, > + driver_addr_fw_define_2nd_flash_reload); > + WORD_REG(reg_data->driver_op.addr_fw_define_int_is_edge, > + driver_addr_fw_define_int_is_edge); > + WORD_REG(reg_data->driver_op.addr_fw_define_rxnum_txnum, > + driver_addr_fw_define_rxnum_txnum); > + WORD_REG(reg_data->driver_op.addr_fw_define_maxpt_xyrvs, > + driver_addr_fw_define_maxpt_xyrvs); > + WORD_REG(reg_data->driver_op.addr_fw_define_x_y_res, > + driver_addr_fw_define_x_y_res); > + BYTE_REG(reg_data->driver_op.data_df_rx, driver_data_df_rx); > + BYTE_REG(reg_data->driver_op.data_df_tx, driver_data_df_tx); > + BYTE_REG(reg_data->driver_op.data_df_pt, driver_data_df_pt); > + WORD_REG(reg_data->driver_op.data_fw_define_flash_reload_dis, > + driver_data_fw_define_flash_reload_dis); > + WORD_REG(reg_data->driver_op.data_fw_define_flash_reload_en, > + driver_data_fw_define_flash_reload_en); > + WORD_REG(reg_data->driver_op.data_fw_define_rxnum_txnum_maxpt_sorting, > + driver_data_fw_define_rxnum_txnum_maxpt_sorting); > + WORD_REG(reg_data->driver_op.data_fw_define_rxnum_txnum_maxpt_normal, > + driver_data_fw_define_rxnum_txnum_maxpt_normal); > +/* CORE_DRIVER -end- */ > + WORD_REG(reg_data->zf_op.data_dis_flash_reload, zf_data_dis_flash_reload); > + WORD_REG(reg_data->zf_op.addr_system_reset, zf_addr_system_reset); > + BYTE_REG(reg_data->zf_op.data_system_reset, zf_data_system_reset); > + WORD_REG(reg_data->zf_op.data_sram_start_addr, zf_data_sram_start_addr); > + WORD_REG(reg_data->zf_op.data_cfg_info, zf_data_cfg_info); > + WORD_REG(reg_data->zf_op.data_fw_cfg_1, zf_data_fw_cfg_1); > + WORD_REG(reg_data->zf_op.data_fw_cfg_2, zf_data_fw_cfg_2); > + WORD_REG(reg_data->zf_op.data_fw_cfg_3, zf_data_fw_cfg_3); > + WORD_REG(reg_data->zf_op.data_adc_cfg_1, zf_data_adc_cfg_1); > + WORD_REG(reg_data->zf_op.data_adc_cfg_2, zf_data_adc_cfg_2); > + WORD_REG(reg_data->zf_op.data_adc_cfg_3, zf_data_adc_cfg_3); > + WORD_REG(reg_data->zf_op.data_map_table, zf_data_map_table); > + WORD_REG(reg_data->zf_op.addr_sts_chk, zf_addr_sts_chk); > + BYTE_REG(reg_data->zf_op.data_activ_sts, zf_data_activ_sts); > + WORD_REG(reg_data->zf_op.addr_activ_relod, zf_addr_activ_relod); > + BYTE_REG(reg_data->zf_op.data_activ_in, zf_data_activ_in); > +} > + > +/* CORE_INIT */ > +/* init start */ > +void himax_ic_fp_init(void) > +{ > +/* CORE_IC */ > + g_core_fp.fp_burst_enable = himax_mcu_burst_enable; > + g_core_fp.fp_register_read = himax_mcu_register_read; > + g_core_fp.fp_reg_read = himax_mcu_reg_read; > + /* > + * g_core_fp.fp_flash_write_burst = himax_mcu_flash_write_burst; > + */ > + /* > + * g_core_fp.fp_flash_write_burst_length = > + * himax_mcu_flash_write_burst_length; > + */ > + g_core_fp.fp_register_write = himax_mcu_register_write; > + g_core_fp.fp_reg_write = himax_mcu_reg_write; > + g_core_fp.fp_interface_on = himax_mcu_interface_on; > + g_core_fp.fp_sense_on = himax_mcu_sense_on; > + g_core_fp.fp_sense_off = himax_mcu_sense_off; > + g_core_fp.fp_wait_wip = himax_mcu_wait_wip; > + g_core_fp.fp_init_psl = himax_mcu_init_psl; > + g_core_fp.fp_resume_ic_action = himax_mcu_resume_ic_action; > + g_core_fp.fp_suspend_ic_action = himax_mcu_suspend_ic_action; > + g_core_fp.fp_power_on_init = himax_mcu_power_on_init; > +/* CORE_IC */ > +/* CORE_FW */ > + g_core_fp.fp_system_reset = himax_mcu_system_reset; > + g_core_fp.fp_calculate_crc_with_ap = himax_mcu_calculate_crc_with_ap; > + g_core_fp.fp_check_crc = himax_mcu_check_crc; > + g_core_fp.fp_set_reload_cmd = himax_mcu_set_reload_cmd; > + g_core_fp.fp_program_reload = himax_mcu_program_reload; > + g_core_fp.fp_usb_detect_set = himax_mcu_usb_detect_set; > + g_core_fp.fp_diag_register_set = himax_mcu_diag_register_set; > + g_core_fp.fp_diag_register_get = himax_mcu_diag_register_get; > + g_core_fp.fp_idle_mode = himax_mcu_idle_mode; > + g_core_fp.fp_reload_disable = himax_mcu_reload_disable; > + g_core_fp.fp_read_ic_trigger_type = himax_mcu_read_ic_trigger_type; > + g_core_fp.fp_read_FW_ver = himax_mcu_read_FW_ver; > + g_core_fp.fp_read_event_stack = himax_mcu_read_event_stack; > + g_core_fp.fp_return_event_stack = himax_mcu_return_event_stack; > + g_core_fp.fp_calculate_checksum = himax_mcu_calculate_checksum; > + g_core_fp.fp_read_FW_status = himax_mcu_read_FW_status; > + g_core_fp.fp_irq_switch = himax_mcu_irq_switch; > + g_core_fp.fp_assign_sorting_mode = himax_mcu_assign_sorting_mode; > + g_core_fp.fp_check_sorting_mode = himax_mcu_check_sorting_mode; > + g_core_fp.fp_read_DD_status = himax_mcu_read_DD_status; > + g_core_fp.fp_clr_fw_reord_dd_sts = hx_clr_fw_reord_dd_sts; > + g_core_fp.fp_ap_notify_fw_sus = hx_ap_notify_fw_sus; > +/* CORE_FW */ > +/* CORE_FLASH */ > + g_core_fp.fp_chip_erase = himax_mcu_chip_erase; > + g_core_fp.fp_block_erase = himax_mcu_block_erase; > + g_core_fp.fp_sector_erase = himax_mcu_sector_erase; > + g_core_fp.fp_flash_programming = himax_mcu_flash_programming; > + g_core_fp.fp_flash_page_write = himax_mcu_flash_page_write; > + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_32k = > + himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_32k; > + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_60k = > + himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_60k; > + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_64k = > + himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_64k; > + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_124k = > + himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_124k; > + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_128k = > + himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_128k; > + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_255k = > + himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_255k; > + g_core_fp.fp_flash_dump_func = himax_mcu_flash_dump_func; > + g_core_fp.fp_flash_lastdata_check = himax_mcu_flash_lastdata_check; > + g_core_fp.fp_bin_desc_get = hx_mcu_bin_desc_get; > + g_core_fp.fp_diff_overlay_flash = hx_mcu_diff_overlay_flash; > +/* CORE_FLASH */ > +/* CORE_SRAM */ > + g_core_fp.fp_sram_write = himax_mcu_sram_write; > + g_core_fp.fp_sram_verify = himax_mcu_sram_verify; > + g_core_fp.fp_get_DSRAM_data = himax_mcu_get_DSRAM_data; > +/* CORE_SRAM */ > +/* CORE_DRIVER */ > + g_core_fp.fp_chip_init = himax_mcu_init_ic; > + g_core_fp.fp_pin_reset = himax_mcu_pin_reset; > + g_core_fp.fp_ic_reset = himax_mcu_ic_reset; > + g_core_fp.fp_tp_info_check = himax_mcu_tp_info_check; > + g_core_fp.fp_touch_information = himax_mcu_touch_information; > + g_core_fp.fp_calc_touch_data_size = himax_mcu_calc_touch_data_size; > + g_core_fp.fp_get_touch_data_size = himax_mcu_get_touch_data_size; > + g_core_fp.fp_hand_shaking = himax_mcu_hand_shaking; > + g_core_fp.fp_determin_diag_rawdata = himax_mcu_determin_diag_rawdata; > + g_core_fp.fp_determin_diag_storage = himax_mcu_determin_diag_storage; > + g_core_fp.fp_cal_data_len = himax_mcu_cal_data_len; > + g_core_fp.fp_diag_check_sum = himax_mcu_diag_check_sum; > + g_core_fp.fp_ic_excp_recovery = himax_mcu_ic_excp_recovery; > + g_core_fp.fp_excp_ic_reset = himax_mcu_excp_ic_reset; > + g_core_fp.fp_resend_cmd_func = himax_mcu_resend_cmd_func; > +/* CORE_DRIVER */ > + g_core_fp.fp_turn_on_mp_func = hx_turn_on_mp_func; > + g_core_fp.fp_reload_disable = hx_dis_rload_0f; > + g_core_fp.fp_clean_sram_0f = himax_mcu_clean_sram_0f; > + g_core_fp.fp_write_sram_0f = himax_mcu_write_sram_0f; > + g_core_fp.fp_write_sram_0f_crc = himax_sram_write_crc_check; > + g_core_fp.fp_firmware_update_0f = himax_mcu_firmware_update_0f; > + g_core_fp.fp_0f_op_file_dirly = hx_0f_op_file_dirly; > + g_core_fp.fp_0f_excp_check = himax_mcu_0f_excp_check; > + g_core_fp.fp_read_sram_0f = himax_mcu_read_sram_0f; > + g_core_fp.fp_read_all_sram = himax_mcu_read_all_sram; > + g_core_fp.fp_firmware_read_0f = himax_mcu_firmware_read_0f; > + g_core_fp.fp_suspend_proc = himax_suspend_proc; > + g_core_fp.fp_resume_proc = himax_resume_proc; > +} > -- > 2.25.1 >