blob: 1a22879291ff6e64c5ca0f62c60f7a5351077402 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/* Himax Android Driver Sample Code for incell ic core functions
*
* Copyright (C) 2019 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 "himax_ic_core.h"
struct himax_core_command_operation *g_core_cmd_op;
struct ic_operation *pic_op;
EXPORT_SYMBOL(pic_op);
struct fw_operation *pfw_op;
EXPORT_SYMBOL(pfw_op);
struct flash_operation *pflash_op;
EXPORT_SYMBOL(pflash_op);
struct sram_operation *psram_op;
struct driver_operation *pdriver_op;
EXPORT_SYMBOL(pdriver_op);
#if defined(HX_ZERO_FLASH)
struct zf_operation *pzf_op;
EXPORT_SYMBOL(pzf_op);
#if defined(HX_CODE_OVERLAY)
uint8_t *ovl_idx;
EXPORT_SYMBOL(ovl_idx);
#endif
#endif
#define Arr4_to_Arr4(A, B) {\
A[3] = B[3];\
A[2] = B[2];\
A[1] = B[1];\
A[0] = B[0];\
}
int HX_TOUCH_INFO_POINT_CNT;
void (*himax_mcu_cmd_struct_free)(void);
static uint8_t *g_internal_buffer;
uint32_t 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};
/* CORE_IC */
/* IC side start*/
static void himax_mcu_burst_enable(uint8_t auto_add_4_byte)
{
uint8_t tmp_data[DATA_LEN_4];
int ret;
/*I("%s,Entering\n", __func__);*/
tmp_data[0] = pic_op->data_conti[0];
ret = himax_bus_write(pic_op->addr_conti[0], tmp_data, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return;
}
tmp_data[0] = (pic_op->data_incr4[0] | auto_add_4_byte);
ret = himax_bus_write(pic_op->addr_incr4[0], tmp_data, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return;
}
}
static int himax_mcu_register_read(uint8_t *addr, uint8_t *buf, uint32_t len)
{
uint8_t tmp_data[DATA_LEN_4];
int i = 0;
int address = 0;
int ret = 0;
int max_bus_size = 0;
#if defined(HX_ZERO_FLASH)
max_bus_size = (len > HX_MAX_READ_SZ - 4) ? (HX_MAX_READ_SZ - 4) : len;
#else
max_bus_size = FLASH_RW_MAX_LEN;
#endif
if (len > max_bus_size) {
E("%s: read len over %d!\n", __func__, max_bus_size);
return LENGTH_FAIL;
}
if (len > DATA_LEN_4)
g_core_fp.fp_burst_enable(1);
else
g_core_fp.fp_burst_enable(0);
address = (addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0];
i = address;
tmp_data[0] = (uint8_t)i;
tmp_data[1] = (uint8_t)(i >> 8);
tmp_data[2] = (uint8_t)(i >> 16);
tmp_data[3] = (uint8_t)(i >> 24);
ret = himax_bus_write(pic_op->addr_ahb_addr_byte_0[0], tmp_data,
DATA_LEN_4);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return BUS_FAIL;
}
tmp_data[0] = pic_op->data_ahb_access_direction_read[0];
ret = himax_bus_write(pic_op->addr_ahb_access_direction[0], tmp_data,
1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return BUS_FAIL;
}
ret = himax_bus_read(pic_op->addr_ahb_rdata_byte_0[0], buf, len);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return BUS_FAIL;
}
if (len > DATA_LEN_4)
g_core_fp.fp_burst_enable(0);
return NO_ERR;
}
static int himax_mcu_flash_write_burst_lenth(uint8_t *reg_byte,
uint8_t *write_data, uint32_t length)
{
uint8_t *data_byte;
int ret = 0;
if (!g_internal_buffer) {
E("%s: internal buffer not initialized!\n", __func__);
return MEM_ALLOC_FAIL;
}
data_byte = g_internal_buffer;
/* assign addr 4bytes */
memcpy(data_byte, reg_byte, ADDR_LEN_4);
/* assign data n bytes */
memcpy(data_byte + ADDR_LEN_4, write_data, length);
ret = himax_bus_write(pic_op->addr_ahb_addr_byte_0[0], data_byte,
length + ADDR_LEN_4);
if (ret < 0) {
E("%s: xfer fail!\n", __func__);
return BUS_FAIL;
}
return NO_ERR;
}
static int himax_mcu_register_write(uint8_t *addr, uint8_t *val, uint32_t len)
{
int address;
uint8_t tmp_addr[4];
uint8_t *tmp_data;
int total_read_times = 0;
uint32_t max_bus_size = MAX_I2C_TRANS_SZ;
uint32_t total_size_temp = 0;
unsigned int i = 0;
int ret = 0;
total_size_temp = len;
#if defined(HX_ZERO_FLASH)
max_bus_size = (len > HX_MAX_WRITE_SZ) ? HX_MAX_WRITE_SZ : len;
#endif
tmp_addr[3] = addr[3];
tmp_addr[2] = addr[2];
tmp_addr[1] = addr[1];
tmp_addr[0] = addr[0];
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;
if (len > DATA_LEN_4)
g_core_fp.fp_burst_enable(1);
else
g_core_fp.fp_burst_enable(0);
for (i = 0; i < total_read_times; i++) {
if (total_size_temp >= max_bus_size) {
tmp_data = val + (i * max_bus_size);
ret = himax_mcu_flash_write_burst_lenth(tmp_addr,
tmp_data, max_bus_size);
if (ret < 0) {
I("%s: bus access fail!\n", __func__);
return BUS_FAIL;
}
total_size_temp = total_size_temp - max_bus_size;
} else {
tmp_data = val + (i * max_bus_size);
ret = himax_mcu_flash_write_burst_lenth(tmp_addr,
tmp_data, total_size_temp);
if (ret < 0) {
I("%s: bus access fail!\n", __func__);
return BUS_FAIL;
}
}
address = ((i+1) * max_bus_size);
tmp_addr[0] = addr[0] + (uint8_t)((address) & 0x00FF);
if (tmp_addr[0] < addr[0]) {
tmp_addr[1] = addr[1] +
(uint8_t)((address>>8) & 0x00FF) + 1;
} else {
tmp_addr[1] = addr[1] +
(uint8_t)((address>>8) & 0x00FF);
}
udelay(100);
}
return NO_ERR;
}
static int himax_write_read_reg(uint8_t *tmp_addr, uint8_t *tmp_data,
uint8_t hb, uint8_t lb)
{
uint16_t retry = 0;
uint8_t r_data[ADDR_LEN_4] = {0};
while (retry++ < 40) { /* ceil[16.6*2] */
g_core_fp.fp_register_read(tmp_addr, r_data, DATA_LEN_4);
if (r_data[1] == lb && r_data[0] == hb)
break;
else if (r_data[1] == hb && r_data[0] == lb)
return NO_ERR;
g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
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(tmp_addr, r_data, DATA_LEN_4);
if (r_data[1] == hb && r_data[0] == lb)
return NO_ERR;
I("%s: wait data ready %d times\n", __func__, retry);
usleep_range(10000, 10100);
}
FAIL:
E("%s: failed to handshaking with DSRAM\n", __func__);
E("%s: addr = %02X%02X%02X%02X; data = %02X%02X%02X%02X",
__func__, 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("%s: target = %02X%02X; r_data = %02X%02X\n",
__func__, hb, lb, r_data[1], r_data[0]);
return HX_RW_REG_FAIL;
}
static void himax_mcu_interface_on(void)
{
uint8_t tmp_data[DATA_LEN_4];
uint8_t tmp_data2[DATA_LEN_4];
int cnt = 0;
int ret = 0;
/* Read a temp register to wake up BUS. */
ret = himax_bus_read(pic_op->addr_ahb_rdata_byte_0[0], tmp_data,
DATA_LEN_4);
if (ret < 0) {/* to knock BUS*/
E("%s: bus access fail!\n", __func__);
return;
}
do {
tmp_data[0] = pic_op->data_conti[0];
ret = himax_bus_write(pic_op->addr_conti[0], tmp_data, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return;
}
tmp_data[0] = pic_op->data_incr4[0];
ret = himax_bus_write(pic_op->addr_incr4[0], tmp_data, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return;
}
/*Check cmd*/
himax_bus_read(pic_op->addr_conti[0], tmp_data, 1);
himax_bus_read(pic_op->addr_incr4[0], tmp_data2, 1);
if (tmp_data[0] == pic_op->data_conti[0]
&& tmp_data2[0] == pic_op->data_incr4[0])
break;
usleep_range(1000, 1100);
} while (++cnt < 10);
if (cnt > 0)
I("%s:Polling burst mode: %d times\n", __func__, cnt);
}
#define WIP_PRT_LOG "%s: retry:%d, bf[0]=%d, bf[1]=%d,bf[2]=%d, bf[3]=%d\n"
static bool himax_mcu_wait_wip(int Timing)
{
uint8_t tmp_data[DATA_LEN_4];
int retry_cnt = 0;
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_fmt,
pflash_op->data_spi200_trans_fmt, DATA_LEN_4);
tmp_data[0] = 0x01;
do {
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_ctrl,
pflash_op->data_spi200_trans_ctrl_1, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_cmd,
pflash_op->data_spi200_cmd_1, DATA_LEN_4);
tmp_data[0] = tmp_data[1] = tmp_data[2] = tmp_data[3] = 0xFF;
g_core_fp.fp_register_read(pflash_op->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,
__func__, retry_cnt, tmp_data[0],
tmp_data[1], tmp_data[2], tmp_data[3]);
if (retry_cnt > 100) {
E("%s: Wait wip error!\n", __func__);
return false;
}
msleep(Timing);
} while ((tmp_data[0] & 0x01) == 0x01);
return true;
}
static bool himax_mcu_sense_on(uint8_t FlashMode)
{
uint8_t tmp_data[DATA_LEN_4];
int retry = 0;
int ret = 0;
bool rc = true;
I("Enter %s\n", __func__);
private_ts->notouch_frame = private_ts->ic_notouch_frame;
g_core_fp.fp_interface_on();
g_core_fp.fp_register_write(pfw_op->addr_ctrl_fw_isr,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
/*msleep(20);*/
usleep_range(10000, 11000);
if (!FlashMode) {
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
g_core_fp.fp_system_reset();
#endif
} else {
do {
g_core_fp.fp_register_read(
pfw_op->addr_flag_reset_event,
tmp_data, DATA_LEN_4);
I("%s:Read status from IC = %X,%X\n", __func__,
tmp_data[0], tmp_data[1]);
} while ((tmp_data[1] != 0x01
|| tmp_data[0] != 0x00)
&& retry++ < 5);
if (retry >= 5) {
E("%s: Fail:\n", __func__);
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
g_core_fp.fp_system_reset();
#endif
} else {
I("%s:OK and Read status from IC = %X,%X\n",
__func__, tmp_data[0], tmp_data[1]);
/* reset code*/
tmp_data[0] = 0x00;
ret = himax_bus_write(pic_op->adr_i2c_psw_lb[0],
tmp_data, 1);
if (ret < 0) {
E("%s: cmd=%x bus access fail!\n",
__func__,
pic_op->adr_i2c_psw_lb[0]);
rc = false;
}
ret = himax_bus_write(pic_op->adr_i2c_psw_ub[0],
tmp_data, 1);
if (ret < 0) {
E("%s: cmd=%x bus access fail!\n",
__func__,
pic_op->adr_i2c_psw_ub[0]);
rc = false;
}
}
}
return rc;
}
static bool himax_mcu_sense_off(bool check_en)
{
uint8_t cnt = 0;
uint8_t tmp_data[DATA_LEN_4];
int ret = 0;
do {
tmp_data[0] = pic_op->data_i2c_psw_lb[0];
ret = himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return false;
}
tmp_data[0] = pic_op->data_i2c_psw_ub[0];
ret = himax_bus_write(pic_op->adr_i2c_psw_ub[0], tmp_data, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return false;
}
g_core_fp.fp_register_read(pic_op->addr_cs_central_state,
tmp_data, ADDR_LEN_4);
I("%s: Check enter_save_mode data[0]=%X\n", __func__,
tmp_data[0]);
if (tmp_data[0] == 0x0C) {
g_core_fp.fp_register_write(pic_op->addr_tcon_on_rst,
pic_op->data_rst, DATA_LEN_4);
usleep_range(1000, 1100);
tmp_data[3] = pic_op->data_rst[3];
tmp_data[2] = pic_op->data_rst[2];
tmp_data[1] = pic_op->data_rst[1];
tmp_data[0] = pic_op->data_rst[0] | 0x01;
g_core_fp.fp_register_write(pic_op->addr_tcon_on_rst,
tmp_data, DATA_LEN_4);
g_core_fp.fp_register_write(pic_op->addr_adc_on_rst,
pic_op->data_rst, DATA_LEN_4);
usleep_range(1000, 1100);
tmp_data[3] = pic_op->data_rst[3];
tmp_data[2] = pic_op->data_rst[2];
tmp_data[1] = pic_op->data_rst[1];
tmp_data[0] = pic_op->data_rst[0] | 0x01;
g_core_fp.fp_register_write(pic_op->addr_adc_on_rst,
tmp_data, DATA_LEN_4);
goto TRUE_END;
} else {
/*msleep(10);*/
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
g_core_fp.fp_system_reset();
#endif
}
} while (cnt++ < 15);
return false;
TRUE_END:
return true;
}
/*power saving level*/
static void himax_mcu_init_psl(void)
{
g_core_fp.fp_register_write(pic_op->addr_psl, pic_op->data_rst,
sizeof(pic_op->data_rst));
I("%s: power saving level reset OK!\n", __func__);
}
static void himax_mcu_resume_ic_action(void)
{
/* Nothing to do */
}
static void himax_mcu_suspend_ic_action(void)
{
/* Nothing to do */
}
static void himax_mcu_power_on_init(void)
{
uint8_t tmp_data[4] = {0x01, 0x00, 0x00, 0x00};
uint8_t retry = 0;
/*RawOut select initial*/
g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
/*DSRAM func initial*/
g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear);
/*N frame initial*/
/* reset N frame back to default value 1 for normal mode */
g_core_fp.fp_register_write(pfw_op->addr_set_frame_addr, tmp_data, 4);
/*FW reload done initial*/
g_core_fp.fp_register_write(pdriver_op->addr_fw_define_2nd_flash_reload,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
g_core_fp.fp_sense_on(0x00);
I("%s: waiting for FW reload data\n", __func__);
while (retry++ < 30) {
g_core_fp.fp_register_read(
pdriver_op->addr_fw_define_2nd_flash_reload, tmp_data,
DATA_LEN_4);
/* use all 4 bytes to compare */
if ((tmp_data[3] == 0x00 && tmp_data[2] == 0x00 &&
tmp_data[1] == 0x72 && tmp_data[0] == 0xC0)) {
I("%s: FW reload done\n", __func__);
break;
}
I("%s: wait FW reload %d times\n", __func__, retry);
g_core_fp.fp_read_FW_status();
usleep_range(10000, 11000);
}
}
/* IC side end*/
/* CORE_IC */
/* CORE_FW */
/* FW side start*/
static void diag_mcu_parse_raw_data(struct himax_report_data *hx_touch_data,
int mul_num, int self_num, uint8_t diag_cmd,
int32_t *mutual_data, int32_t *self_data)
{
int RawDataLen_word;
int index = 0;
int temp1, temp2, i;
if (hx_touch_data->hx_rawdata_buf[0]
== pfw_op->data_rawdata_ready_lb[0]
&& hx_touch_data->hx_rawdata_buf[1]
== pfw_op->data_rawdata_ready_hb[0]
&& hx_touch_data->hx_rawdata_buf[2] > 0
&& hx_touch_data->hx_rawdata_buf[3] == diag_cmd) {
RawDataLen_word = hx_touch_data->rawdata_size / 2;
index = (hx_touch_data->hx_rawdata_buf[2] - 1)
* RawDataLen_word;
/* I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n",index,
* buf[56], buf[57], buf[58], buf[59], mul_num, self_num);
* I("RawDataLen=%d , RawDataLen_word=%d ,
* hx_touch_info_size=%d\n",
* RawDataLen, RawDataLen_word, hx_touch_info_size);
*/
for (i = 0; i < RawDataLen_word; i++) {
temp1 = index + i;
if (temp1 < mul_num) { /*mutual*/
mutual_data[index + i] =
((int8_t)hx_touch_data->
hx_rawdata_buf[i * 2 + 4 + 1]) * 256
+ hx_touch_data->
hx_rawdata_buf[i * 2 + 4];
} else { /*self*/
temp1 = i + index;
temp2 = self_num + mul_num;
if (temp1 >= temp2)
break;
self_data[i + index - mul_num] =
(((int8_t)hx_touch_data->
hx_rawdata_buf[i * 2 + 4 + 1]) << 8)
+ hx_touch_data->
hx_rawdata_buf[i * 2 + 4];
}
}
}
}
static void himax_mcu_system_reset(void)
{
#if defined(HX_PON_PIN_SUPPORT)
g_core_fp.fp_register_write(pfw_op->addr_system_reset,
pfw_op->data_system_reset, sizeof(pfw_op->data_system_reset));
#else
int ret = 0;
uint8_t tmp_data[DATA_LEN_4];
int retry = 0;
g_core_fp.fp_interface_on();
g_core_fp.fp_register_write(pfw_op->addr_ctrl_fw_isr,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
do {
/* reset code*/
/**
* I2C_password[7:0] set Enter safe mode : 0x31 ==> 0x27
*/
tmp_data[0] = pic_op->data_i2c_psw_lb[0];
ret = himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1);
if (ret < 0)
E("%s: bus access fail!\n", __func__);
/**
* I2C_password[15:8] set Enter safe mode :0x32 ==> 0x95
*/
tmp_data[0] = pic_op->data_i2c_psw_ub[0];
ret = himax_bus_write(pic_op->adr_i2c_psw_ub[0], tmp_data, 1);
if (ret < 0)
E("%s: bus access fail!\n", __func__);
/**
* I2C_password[7:0] set Enter safe mode : 0x31 ==> 0x00
*/
tmp_data[0] = 0x00;
ret = himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1);
if (ret < 0)
E("%s: bus access fail!\n", __func__);
usleep_range(10000, 11000);
g_core_fp.fp_register_read(pfw_op->addr_flag_reset_event,
tmp_data, DATA_LEN_4);
I("%s:Read status from IC = %X,%X\n", __func__,
tmp_data[0], tmp_data[1]);
} while ((tmp_data[1] != 0x02 || tmp_data[0] != 0x00) && retry++ < 5);
#endif
}
static int himax_mcu_Calculate_CRC_with_AP(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 uint32_t himax_mcu_check_CRC(uint8_t *start_addr, int reload_length)
{
uint32_t result = 0;
uint8_t tmp_data[DATA_LEN_4];
int cnt = 0, ret = 0;
int length = reload_length / DATA_LEN_4;
ret = g_core_fp.fp_register_write(pfw_op->addr_reload_addr_from,
start_addr, DATA_LEN_4);
if (ret < NO_ERR) {
E("%s: bus access fail!\n", __func__);
return HW_CRC_FAIL;
}
tmp_data[3] = 0x00;
tmp_data[2] = 0x99;
tmp_data[1] = (length >> 8);
tmp_data[0] = length;
ret = g_core_fp.fp_register_write(pfw_op->addr_reload_addr_cmd_beat,
tmp_data, DATA_LEN_4);
if (ret < NO_ERR) {
E("%s: bus access fail!\n", __func__);
return HW_CRC_FAIL;
}
cnt = 0;
do {
ret = g_core_fp.fp_register_read(pfw_op->addr_reload_status,
tmp_data, DATA_LEN_4);
if (ret < NO_ERR) {
E("%s: bus access fail!\n", __func__);
return HW_CRC_FAIL;
}
if ((tmp_data[0] & 0x01) != 0x01) {
ret = g_core_fp.fp_register_read(
pfw_op->addr_reload_crc32_result, tmp_data,
DATA_LEN_4);
if (ret < NO_ERR) {
E("%s: bus access fail!\n", __func__);
return HW_CRC_FAIL;
}
I("%s:data[3]=%X,data[2]=%X,data[1]=%X,data[0]=%X\n",
__func__,
tmp_data[3],
tmp_data[2],
tmp_data[1],
tmp_data[0]);
result = ((tmp_data[3] << 24)
+ (tmp_data[2] << 16)
+ (tmp_data[1] << 8)
+ tmp_data[0]);
goto END;
} else {
I("Waiting for HW ready!\n");
usleep_range(1000, 1100);
if (cnt >= 100)
g_core_fp.fp_read_FW_status();
}
} while (cnt++ < 100);
END:
return result;
}
static void himax_mcu_set_reload_cmd(uint8_t *write_data, int idx,
uint32_t cmd_from, uint32_t cmd_to, uint32_t 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;
}
#if defined(HX_ULTRA_LOW_POWER)
static int himax_mcu_ulpm_in(void)
{
uint8_t tmp_data[4];
int rtimes = 0;
int ret = 0;
I("%s:entering\n", __func__);
/* 34 -> 11 */
do {
if (rtimes > 10) {
I("%s:1/7 retry over 10 times!\n", __func__);
return false;
}
ret = himax_bus_write(pfw_op->addr_ulpm_34[0],
pfw_op->data_ulpm_11, 1);
if (ret < 0) {
I("%s: spi write fail!\n", __func__);
continue;
}
ret = himax_bus_read(pfw_op->addr_ulpm_34[0], tmp_data, 1);
if (ret < 0) {
I("%s: spi read fail!\n", __func__);
continue;
}
I("%s:retry times %d,addr=0x34,correct 0x11=current 0x%2.2X\n",
__func__, rtimes, tmp_data[0]);
rtimes++;
} while (tmp_data[0] != pfw_op->data_ulpm_11[0]);
rtimes = 0;
/* 34 -> 11 */
do {
if (rtimes > 10) {
I("%s:2/7 retry over 10 times!\n", __func__);
return false;
}
ret = himax_bus_write(pfw_op->addr_ulpm_34[0],
pfw_op->data_ulpm_11, 1);
if (ret < 0) {
I("%s: spi write fail!\n", __func__);
continue;
}
ret = himax_bus_read(pfw_op->addr_ulpm_34[0], tmp_data, 1);
if (ret < 0) {
I("%s: spi read fail!\n", __func__);
continue;
}
I("%s:retry times %d,addr=0x34,correct 0x11=current 0x%2.2X\n",
__func__, rtimes, tmp_data[0]);
rtimes++;
} while (tmp_data[0] != pfw_op->data_ulpm_11[0]);
/* 33 -> 33 */
rtimes = 0;
do {
if (rtimes > 10) {
I("%s:3/7 retry over 10 times!\n", __func__);
return false;
}
ret = himax_bus_write(pfw_op->addr_ulpm_33[0],
pfw_op->data_ulpm_33, 1);
if (ret < 0) {
I("%s: spi write fail!\n", __func__);
continue;
}
ret = himax_bus_read(pfw_op->addr_ulpm_33[0], tmp_data, 1);
if (ret < 0) {
I("%s: spi read fail!\n", __func__);
continue;
}
I("%s:retry times %d,addr=0x33,correct 0x33=current 0x%2.2X\n",
__func__, rtimes, tmp_data[0]);
rtimes++;
} while (tmp_data[0] != pfw_op->data_ulpm_33[0]);
/* 34 -> 22 */
rtimes = 0;
do {
if (rtimes > 10) {
I("%s:4/7 retry over 10 times!\n", __func__);
return false;
}
ret = himax_bus_write(pfw_op->addr_ulpm_34[0],
pfw_op->data_ulpm_22, 1);
if (ret < 0) {
I("%s: spi write fail!\n", __func__);
continue;
}
ret = himax_bus_read(pfw_op->addr_ulpm_34[0], tmp_data, 1);
if (ret < 0) {
I("%s: spi read fail!\n", __func__);
continue;
}
I("%s:retry times %d,addr=0x34,correct 0x22=current 0x%2.2X\n",
__func__, rtimes, tmp_data[0]);
rtimes++;
} while (tmp_data[0] != pfw_op->data_ulpm_22[0]);
/* 33 -> AA */
rtimes = 0;
do {
if (rtimes > 10) {
I("%s:5/7 retry over 10 times!\n", __func__);
return false;
}
ret = himax_bus_write(pfw_op->addr_ulpm_33[0],
pfw_op->data_ulpm_aa, 1);
if (ret < 0) {
I("%s: spi write fail!\n", __func__);
continue;
}
ret = himax_bus_read(pfw_op->addr_ulpm_33[0], tmp_data, 1);
if (ret < 0) {
I("%s: spi read fail!\n", __func__);
continue;
}
I("%s:retry times %d,addr=0x33, correct 0xAA=current 0x%2.2X\n",
__func__, rtimes, tmp_data[0]);
rtimes++;
} while (tmp_data[0] != pfw_op->data_ulpm_aa[0]);
/* 33 -> 33 */
rtimes = 0;
do {
if (rtimes > 10) {
I("%s:6/7 retry over 10 times!\n", __func__);
return false;
}
ret = himax_bus_write(pfw_op->addr_ulpm_33[0],
pfw_op->data_ulpm_33, 1);
if (ret < 0) {
I("%s: spi write fail!\n", __func__);
continue;
}
ret = himax_bus_read(pfw_op->addr_ulpm_33[0], tmp_data, 1);
if (ret < 0) {
I("%s: spi read fail!\n", __func__);
continue;
}
I("%s:retry times %d,addr=0x33,correct 0x33=current 0x%2.2X\n",
__func__, rtimes, tmp_data[0]);
rtimes++;
} while (tmp_data[0] != pfw_op->data_ulpm_33[0]);
/* 33 -> AA */
rtimes = 0;
do {
if (rtimes > 10) {
I("%s:7/7 retry over 10 times!\n", __func__);
return false;
}
ret = himax_bus_write(pfw_op->addr_ulpm_33[0],
pfw_op->data_ulpm_aa, 1);
if (ret < 0) {
I("%s: spi write fail!\n", __func__);
continue;
}
ret = himax_bus_read(pfw_op->addr_ulpm_33[0], tmp_data, 1);
if (ret < 0) {
I("%s: spi read fail!\n", __func__);
continue;
}
I("%s:retry times %d,addr=0x33,correct 0xAA=current 0x%2.2X\n",
__func__, rtimes, tmp_data[0]);
rtimes++;
} while (tmp_data[0] != pfw_op->data_ulpm_aa[0]);
I("%s:END\n", __func__);
return true;
}
static int himax_mcu_black_gest_ctrl(bool enable)
{
int ret = 0;
I("%s:enable=%d, ts->is_suspended=%d\n", __func__,
enable, private_ts->suspended);
if (private_ts->suspended) {
if (enable) {
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
I("%s: Please enable TP reset define\n", __func__);
#endif
} else {
g_core_fp.fp_ulpm_in();
}
} else {
g_core_fp.fp_sense_on(0);
}
return ret;
}
#endif
static void himax_mcu_set_SMWP_enable(uint8_t SMWP_enable, bool suspended)
{
uint8_t tmp_data[DATA_LEN_4];
uint8_t back_data[DATA_LEN_4];
uint8_t retry_cnt = 0;
do {
if (SMWP_enable) {
himax_parse_assign_cmd(fw_func_handshaking_pwd,
tmp_data, 4);
g_core_fp.fp_register_write(pfw_op->addr_smwp_enable,
tmp_data, DATA_LEN_4);
himax_parse_assign_cmd(fw_func_handshaking_pwd,
back_data, 4);
} else {
himax_parse_assign_cmd(
fw_data_safe_mode_release_pw_reset,
tmp_data,
4);
g_core_fp.fp_register_write(pfw_op->addr_smwp_enable,
tmp_data, DATA_LEN_4);
himax_parse_assign_cmd(
fw_data_safe_mode_release_pw_reset,
back_data,
4);
}
g_core_fp.fp_register_read(pfw_op->addr_smwp_enable, tmp_data,
DATA_LEN_4);
/*I("%s: tmp_data[0]=%d, SMWP_enable=%d, retry_cnt=%d\n",
* __func__, tmp_data[0],SMWP_enable,retry_cnt);
*/
retry_cnt++;
} while ((tmp_data[3] != back_data[3]
|| tmp_data[2] != back_data[2]
|| tmp_data[1] != back_data[1]
|| tmp_data[0] != back_data[0])
&& retry_cnt < HIMAX_REG_RETRY_TIMES);
}
static void himax_mcu_set_HSEN_enable(uint8_t HSEN_enable, bool suspended)
{
uint8_t tmp_data[DATA_LEN_4];
uint8_t back_data[DATA_LEN_4];
uint8_t retry_cnt = 0;
do {
if (HSEN_enable) {
himax_parse_assign_cmd(fw_func_handshaking_pwd,
tmp_data, 4);
g_core_fp.fp_register_write(pfw_op->addr_hsen_enable,
tmp_data, DATA_LEN_4);
himax_parse_assign_cmd(fw_func_handshaking_pwd,
back_data, 4);
} else {
himax_parse_assign_cmd(
fw_data_safe_mode_release_pw_reset,
tmp_data,
4);
g_core_fp.fp_register_write(pfw_op->addr_hsen_enable,
tmp_data, DATA_LEN_4);
himax_parse_assign_cmd(
fw_data_safe_mode_release_pw_reset,
back_data,
4);
}
g_core_fp.fp_register_read(pfw_op->addr_hsen_enable, tmp_data,
DATA_LEN_4);
/*I("%s: tmp_data[0]=%d, HSEN_enable=%d, retry_cnt=%d\n",
* __func__, tmp_data[0],HSEN_enable,retry_cnt);
*/
retry_cnt++;
} while ((tmp_data[3] != back_data[3]
|| tmp_data[2] != back_data[2]
|| tmp_data[1] != back_data[1]
|| tmp_data[0] != back_data[0])
&& retry_cnt < HIMAX_REG_RETRY_TIMES);
}
static void himax_mcu_usb_detect_set(uint8_t *cable_config)
{
uint8_t tmp_data[DATA_LEN_4];
uint8_t back_data[DATA_LEN_4];
uint8_t retry_cnt = 0;
do {
if (cable_config[1] == 0x01) {
himax_parse_assign_cmd(fw_func_handshaking_pwd,
tmp_data, 4);
g_core_fp.fp_register_write(pfw_op->addr_usb_detect,
tmp_data, DATA_LEN_4);
himax_parse_assign_cmd(fw_func_handshaking_pwd,
back_data, 4);
I("%s: USB detect status IN!\n", __func__);
} else {
himax_parse_assign_cmd(
fw_data_safe_mode_release_pw_reset,
tmp_data,
4);
g_core_fp.fp_register_write(pfw_op->addr_usb_detect,
tmp_data, DATA_LEN_4);
himax_parse_assign_cmd(
fw_data_safe_mode_release_pw_reset,
back_data,
4);
I("%s: USB detect status OUT!\n", __func__);
}
g_core_fp.fp_register_read(pfw_op->addr_usb_detect, tmp_data,
DATA_LEN_4);
/*I("%s: tmp_data[0]=%d, USB detect=%d, retry_cnt=%d\n",
* __func__, tmp_data[0],cable_config[1] ,retry_cnt);
*/
retry_cnt++;
} while ((tmp_data[3] != back_data[3]
|| tmp_data[2] != back_data[2]
|| tmp_data[1] != back_data[1]
|| tmp_data[0] != back_data[0])
&& retry_cnt < HIMAX_REG_RETRY_TIMES);
}
#define PRT_DATA "%s:[3]=0x%2X, [2]=0x%2X, [1]=0x%2X, [0]=0x%2X\n"
static void himax_mcu_diag_register_set(uint8_t diag_command,
uint8_t storage_type, bool is_dirly)
{
uint8_t tmp_data[DATA_LEN_4];
uint8_t back_data[DATA_LEN_4];
uint8_t cnt = 50;
if (diag_command > 0 && storage_type % 8 > 0 && !is_dirly)
tmp_data[0] = diag_command + 0x08;
else
tmp_data[0] = diag_command;
I("diag_command = %d, tmp_data[0] = %X\n", diag_command, tmp_data[0]);
g_core_fp.fp_interface_on();
tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00;
do {
g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel,
tmp_data, DATA_LEN_4);
g_core_fp.fp_register_read(pfw_op->addr_raw_out_sel, back_data,
DATA_LEN_4);
I(PRT_DATA, __func__,
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_chip_self_test(struct seq_file *s, void *v)
{
uint8_t tmp_data[FLASH_WRITE_BURST_SZ];
uint8_t self_test_info[20];
int pf_value = 0x00;
uint8_t test_result_id = 0;
int i;
memset(tmp_data, 0x00, sizeof(tmp_data));
g_core_fp.fp_interface_on();
g_core_fp.fp_sense_off(true);
g_core_fp.fp_burst_enable(1);
g_core_fp.fp_register_write(pfw_op->addr_selftest_addr_en,
pfw_op->data_selftest_request, DATA_LEN_4);
/*Set criteria 0x10007F1C [0,1]=aa/up,down=, [2-3]=key/up,down,
* [4-5]=avg/up,down
*/
tmp_data[0] = pfw_op->data_criteria_aa_top[0];
tmp_data[1] = pfw_op->data_criteria_aa_bot[0];
tmp_data[2] = pfw_op->data_criteria_key_top[0];
tmp_data[3] = pfw_op->data_criteria_key_bot[0];
tmp_data[4] = pfw_op->data_criteria_avg_top[0];
tmp_data[5] = pfw_op->data_criteria_avg_bot[0];
tmp_data[6] = 0x00;
tmp_data[7] = 0x00;
g_core_fp.fp_register_write(pfw_op->addr_criteria_addr,
tmp_data, FLASH_WRITE_BURST_SZ);
g_core_fp.fp_register_write(pfw_op->addr_set_frame_addr,
pfw_op->data_set_frame, DATA_LEN_4);
/*Disable IDLE Mode*/
g_core_fp.fp_idle_mode(1);
/*Diable Flash Reload*/
g_core_fp.fp_reload_disable(1);
/*start selftest // leave safe mode*/
g_core_fp.fp_sense_on(0x01);
/*Hand shaking*/
for (i = 0; i < 1000; i++) {
g_core_fp.fp_register_read(pfw_op->addr_selftest_addr_en,
tmp_data, 4);
I("%s:data0=0x%2X,data1=0x%2X,data2=0x%2X,data3=0x%2X cnt=%d\n",
__func__,
tmp_data[0],
tmp_data[1],
tmp_data[2],
tmp_data[3],
i);
usleep_range(10000, 11000);
if (tmp_data[1] == pfw_op->data_selftest_ack_hb[0]
&& tmp_data[0] == pfw_op->data_selftest_ack_lb[0]) {
I("%s Data ready goto moving data\n", __func__);
break;
}
}
g_core_fp.fp_sense_off(true);
msleep(20);
/**
* Read test result ==> bit[2][1][0] = [key][AA][avg] => 0xF = PASS
*/
g_core_fp.fp_register_read(pfw_op->addr_selftest_result_addr,
self_test_info, 20);
test_result_id = self_test_info[0];
I("%s: check test result, test_result_id=%x, test_result=%x\n",
__func__, test_result_id, self_test_info[0]);
I("raw top 1 = %d\n", self_test_info[3] * 256 + self_test_info[2]);
I("raw top 2 = %d\n", self_test_info[5] * 256 + self_test_info[4]);
I("raw top 3 = %d\n", self_test_info[7] * 256 + self_test_info[6]);
I("raw last 1 = %d\n", self_test_info[9] * 256 + self_test_info[8]);
I("raw last 2 = %d\n", self_test_info[11] * 256 + self_test_info[10]);
I("raw last 3 = %d\n", self_test_info[13] * 256 + self_test_info[12]);
I("raw key 1 = %d\n", self_test_info[15] * 256 + self_test_info[14]);
I("raw key 2 = %d\n", self_test_info[17] * 256 + self_test_info[16]);
I("raw key 3 = %d\n", self_test_info[19] * 256 + self_test_info[18]);
if (test_result_id == pfw_op->data_selftest_pass[0]) {
I("[Himax]: self-test pass\n");
seq_puts(s, "Self_Test Pass:\n");
pf_value = 0x0;
} else {
E("[Himax]: self-test fail\n");
seq_puts(s, "Self_Test Fail:\n");
/* E("[Himax]: bank_avg = %d, bank_max = %d,%d,%d, bank_min =
* %d,%d,%d, key = %d,%d,%d\n",
* tmp_data[1], tmp_data[2],
* tmp_data[3], tmp_data[4],
* tmp_data[5], tmp_data[6],
* tmp_data[7], tmp_data[8],
* tmp_data[9], tmp_data[10]);
*/
pf_value = 0x1;
}
/*Enable IDLE Mode*/
g_core_fp.fp_idle_mode(0);
#if !defined(HX_ZERO_FLASH)
/* Enable Flash Reload //recovery*/
g_core_fp.fp_reload_disable(0);
#endif
g_core_fp.fp_sense_on(0x00);
msleep(120);
return pf_value;
}
#define PRT_TMP_DATA "%s:[0]=0x%2X,[1]=0x%2X, [2]=0x%2X,[3]=0x%2X\n"
static void himax_mcu_idle_mode(int disable)
{
int retry = 20;
uint8_t tmp_data[DATA_LEN_4];
uint8_t switch_cmd = 0x00;
I("%s:entering\n", __func__);
do {
I("%s,now %d times!\n", __func__, retry);
g_core_fp.fp_register_read(pfw_op->addr_fw_mode_status,
tmp_data, DATA_LEN_4);
if (disable)
switch_cmd = pfw_op->data_idle_dis_pwd[0];
else
switch_cmd = pfw_op->data_idle_en_pwd[0];
tmp_data[0] = switch_cmd;
g_core_fp.fp_register_write(pfw_op->addr_fw_mode_status,
tmp_data, DATA_LEN_4);
g_core_fp.fp_register_read(pfw_op->addr_fw_mode_status,
tmp_data, DATA_LEN_4);
I(PRT_TMP_DATA,
__func__,
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("%s: setting OK!\n", __func__);
}
static void himax_mcu_reload_disable(int disable)
{
I("%s:entering\n", __func__);
if (disable) { /*reload disable*/
g_core_fp.fp_register_write(
pdriver_op->addr_fw_define_flash_reload,
pdriver_op->data_fw_define_flash_reload_dis,
DATA_LEN_4);
} else { /*reload enable*/
g_core_fp.fp_register_write(
pdriver_op->addr_fw_define_flash_reload,
pdriver_op->data_fw_define_flash_reload_en,
DATA_LEN_4);
}
I("%s: setting OK!\n", __func__);
}
static bool himax_mcu_check_chip_version(void)
{
uint8_t tmp_data[DATA_LEN_4];
uint8_t ret_data = false;
int i = 0;
for (i = 0; i < 5; i++) {
g_core_fp.fp_register_read(pfw_op->addr_icid_addr, tmp_data,
DATA_LEN_4);
I("%s:Read driver IC ID = %X,%X,%X\n", __func__,
tmp_data[3], tmp_data[2], tmp_data[1]);
if ((tmp_data[3] == 0x83)
&& (tmp_data[2] == 0x10)
&& (tmp_data[1] == 0x2a)) {
strlcpy(private_ts->chip_name,
HX_83102A_SERIES_PWON, 30);
ret_data = true;
goto END;
} else {
ret_data = false;
E("%s:Read driver ID register Fail:\n", __func__);
}
}
END:
return ret_data;
}
static int himax_mcu_read_ic_trigger_type(void)
{
uint8_t tmp_data[DATA_LEN_4];
int trigger_type = false;
g_core_fp.fp_register_read(pdriver_op->addr_fw_define_int_is_edge,
tmp_data, DATA_LEN_4);
if ((tmp_data[1] & 0x01) == 1)
trigger_type = true;
return trigger_type;
}
static int himax_mcu_read_i2c_status(void)
{
return i2c_error_count;
}
/* Please call this function after FW finish reload done */
static void himax_mcu_read_FW_ver(void)
{
uint8_t data[12] = {0};
g_core_fp.fp_register_read(pfw_op->addr_fw_ver_addr, data, DATA_LEN_4);
ic_data->vendor_panel_ver = data[0];
ic_data->vendor_fw_ver = data[1] << 8 | data[2];
I("PANEL_VER : %X\n", ic_data->vendor_panel_ver);
I("FW_VER : %X\n", ic_data->vendor_fw_ver);
g_core_fp.fp_register_read(pfw_op->addr_fw_cfg_addr, data, DATA_LEN_4);
ic_data->vendor_config_ver = data[2] << 8 | data[3];
/*I("CFG_VER : %X\n",ic_data->vendor_config_ver);*/
ic_data->vendor_touch_cfg_ver = data[2];
I("TOUCH_VER : %X\n", ic_data->vendor_touch_cfg_ver);
ic_data->vendor_display_cfg_ver = data[3];
I("DISPLAY_VER : %X\n", ic_data->vendor_display_cfg_ver);
g_core_fp.fp_register_read(pfw_op->addr_fw_vendor_addr, data,
DATA_LEN_4);
ic_data->vendor_cid_maj_ver = data[2];
ic_data->vendor_cid_min_ver = data[3];
I("CID_VER : %X\n", (ic_data->vendor_cid_maj_ver << 8
| ic_data->vendor_cid_min_ver));
g_core_fp.fp_register_read(pfw_op->addr_cus_info, data, 12);
memcpy(ic_data->vendor_cus_info, data, 12);
I("Cusomer ID = %s\n", ic_data->vendor_cus_info);
g_core_fp.fp_register_read(pfw_op->addr_proj_info, data, 12);
memcpy(ic_data->vendor_proj_info, data, 12);
I("Project ID = %s\n", ic_data->vendor_proj_info);
}
static bool himax_mcu_read_event_stack(uint8_t *buf, uint8_t length)
{
#if defined(KERNEL_VER_ABOVE_5_10)
struct timespec64 t_start, t_end, t_delta;
#else
struct timespec t_start, t_end, t_delta;
#endif
uint8_t cmd[DATA_LEN_4];
int len = length;
int i2c_speed = 0;
int ret = 0;
/* AHB_I2C Burst Read Off */
cmd[0] = pfw_op->data_ahb_dis[0];
ret = himax_bus_write(pfw_op->addr_ahb_addr[0], cmd, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return 0;
}
if (private_ts->debug_log_level & BIT(2))
#if defined(KERNEL_VER_ABOVE_5_10)
ktime_get_ts64(&t_start);
#else
getnstimeofday(&t_start);
#endif
himax_bus_read(pfw_op->addr_event_addr[0], buf, length);
if (private_ts->debug_log_level & BIT(2)) {
#if defined(KERNEL_VER_ABOVE_5_10)
ktime_get_ts64(&t_end);
#else
getnstimeofday(&t_end);
#endif
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;
private_ts->bus_speed = (int)i2c_speed;
}
/* AHB_I2C Burst Read On */
cmd[0] = pfw_op->data_ahb_en[0];
ret = himax_bus_write(pfw_op->addr_ahb_addr[0], cmd, 1);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return 0;
}
return 1;
}
static void himax_mcu_return_event_stack(void)
{
int retry = 20, i;
uint8_t tmp_data[DATA_LEN_4];
I("%s:entering\n", __func__);
do {
I("now %d times!\n", retry);
for (i = 0; i < DATA_LEN_4; i++)
tmp_data[i] = psram_op->addr_rawdata_end[i];
g_core_fp.fp_register_write(psram_op->addr_rawdata_addr,
tmp_data, DATA_LEN_4);
g_core_fp.fp_register_read(psram_op->addr_rawdata_addr,
tmp_data, DATA_LEN_4);
retry--;
usleep_range(10000, 11000);
} while ((tmp_data[1] != psram_op->addr_rawdata_end[1]
&& tmp_data[0] != psram_op->addr_rawdata_end[0])
&& retry > 0);
I("%s: End of setting!\n", __func__);
}
static bool himax_mcu_calculateChecksum(bool change_iref, uint32_t size)
{
uint32_t CRC_result = 0xFFFFFFFF;
uint8_t i;
uint8_t tmp_data[DATA_LEN_4];
I("%s:Now size=%d\n", __func__, size);
for (i = 0; i < DATA_LEN_4; i++)
tmp_data[i] = psram_op->addr_rawdata_end[i];
CRC_result = g_core_fp.fp_check_CRC(tmp_data, size);
msleep(50);
if (CRC_result != 0)
I("%s: CRC Fail=%d\n", __func__, CRC_result);
return (CRC_result == 0) ? true : false;
}
static void himax_mcu_read_FW_status(void)
{
uint8_t len = 0;
uint8_t i = 0;
uint8_t addr[4] = {0};
uint8_t data[4] = {0};
len = (uint8_t)(sizeof(dbg_reg_ary)/sizeof(uint32_t));
for (i = 0; i < len; i++) {
himax_parse_assign_cmd(dbg_reg_ary[i], addr, 4);
g_core_fp.fp_register_read(addr, data, DATA_LEN_4);
I("reg[0-3] : 0x%08X = 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
dbg_reg_ary[i], data[0], data[1], data[2], data[3]);
}
}
static void himax_mcu_irq_switch(int switch_on)
{
if (switch_on) {
if (private_ts->use_irq)
himax_int_enable(switch_on);
else
hrtimer_start(&private_ts->timer, ktime_set(1, 0),
HRTIMER_MODE_REL);
} else {
if (private_ts->use_irq)
himax_int_enable(switch_on);
else {
hrtimer_cancel(&private_ts->timer);
cancel_work_sync(&private_ts->work);
}
}
}
static int himax_mcu_assign_sorting_mode(uint8_t *tmp_data)
{
I("%s:addr: 0x%02X%02X%02X%02X, write to:0x%02X%02X%02X%02X\n",
__func__,
pfw_op->addr_sorting_mode_en[3],
pfw_op->addr_sorting_mode_en[2],
pfw_op->addr_sorting_mode_en[1],
pfw_op->addr_sorting_mode_en[0],
tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]);
g_core_fp.fp_register_write(pfw_op->addr_sorting_mode_en,
tmp_data, DATA_LEN_4);
return NO_ERR;
}
static int himax_mcu_check_sorting_mode(uint8_t *tmp_data)
{
int ret = NO_ERR;
ret = g_core_fp.fp_register_read(pfw_op->addr_sorting_mode_en, tmp_data,
DATA_LEN_4);
I("%s:addr: 0x%02X%02X%02X%02X, Now is:0x%02X%02X%02X%02X\n",
__func__,
pfw_op->addr_sorting_mode_en[3],
pfw_op->addr_sorting_mode_en[2],
pfw_op->addr_sorting_mode_en[1],
pfw_op->addr_sorting_mode_en[0],
tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]);
if (tmp_data[3] == 0xFF
&& tmp_data[2] == 0xFF
&& tmp_data[1] == 0xFF
&& tmp_data[0] == 0xFF) {
ret = BUS_FAIL;
I("%s, All 0xFF, Fail!\n", __func__);
}
return ret;
}
static uint8_t himax_mcu_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data)
{
int cnt = 0;
uint8_t req_size = cmd_set[0];
cmd_set[3] = pfw_op->data_dd_request[0];
g_core_fp.fp_register_write(pfw_op->addr_dd_handshak_addr,
cmd_set, DATA_LEN_4);
I("%s:cmd set[0]=0x%2X,set[1]=0x%2X,set[2]=0x%2X,set[3]=0x%2X\n",
__func__, 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(pfw_op->addr_dd_handshak_addr,
tmp_data, DATA_LEN_4);
usleep_range(10000, 11000);
if (tmp_data[3] == pfw_op->data_dd_ack[0]) {
I("%s Data ready goto moving data\n", __func__);
goto FINALIZE;
} else {
if (cnt >= 99) {
I("%s Data not ready in FW\n", __func__);
return FW_NOT_READY;
}
}
}
FINALIZE:
g_core_fp.fp_register_read(pfw_op->addr_dd_data_addr, tmp_data,
req_size);
return NO_ERR;
}
static void hx_clr_fw_reord_dd_sts(void)
{
uint8_t tmp_data[DATA_LEN_4] = {0};
g_core_fp.fp_register_read(pic_op->addr_cs_central_state, tmp_data,
ADDR_LEN_4);
I("%s: Check enter_save_mode data[0]=%02X\n", __func__, tmp_data[0]);
if (tmp_data[0] == 0x0C) {
I("%s: Enter safe mode, OK!\n", __func__);
} else {
E("%s: It doen't enter safe mode, please check it again\n",
__func__);
return;
}
g_core_fp.fp_register_read(pfw_op->addr_clr_fw_record_dd_sts, tmp_data,
DATA_LEN_4);
I("%s,Before Write :Now 10007FCC=0x%02X%02X%02X%02X\n",
__func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);
usleep_range(10000, 10001);
tmp_data[2] = 0x00;
tmp_data[3] = 0x00;
g_core_fp.fp_register_write(pfw_op->addr_clr_fw_record_dd_sts,
tmp_data, DATA_LEN_4);
usleep_range(10000, 10001);
g_core_fp.fp_register_read(pfw_op->addr_clr_fw_record_dd_sts, tmp_data,
DATA_LEN_4);
I("%s,After Write :Now 10007FCC=0x%02X%02X%02X%02X\n",
__func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);
}
static void hx_ap_notify_fw_sus(int suspend)
{
int retry = 0;
int read_sts = 0;
uint8_t read_tmp[DATA_LEN_4] = {0};
uint8_t addr_tmp[DATA_LEN_4] = {0};
uint8_t data_tmp[DATA_LEN_4] = {0};
Arr4_to_Arr4(addr_tmp, pfw_op->addr_ap_notify_fw_sus);
if (suspend) {
I("%s,Suspend mode!\n", __func__);
Arr4_to_Arr4(data_tmp, pfw_op->data_ap_notify_fw_sus_en);
} else {
I("%s,NonSuspend mode!\n", __func__);
Arr4_to_Arr4(data_tmp, pfw_op->data_ap_notify_fw_sus_dis);
}
I("%s: R%02X%02X%02X%02XH<-0x%02X%02X%02X%02X\n",
__func__,
addr_tmp[3], addr_tmp[2], addr_tmp[1], addr_tmp[0],
data_tmp[3], data_tmp[2], data_tmp[1], data_tmp[0]);
do {
g_core_fp.fp_register_write(addr_tmp, data_tmp,
sizeof(data_tmp));
usleep_range(1000, 1001);
read_sts = g_core_fp.fp_register_read(addr_tmp, read_tmp,
sizeof(read_tmp));
I("%s: read bus status=%d\n", __func__, read_sts);
I("%s: Now retry=%d, data=0x%02X%02X%02X%02X\n",
__func__, retry,
read_tmp[3], read_tmp[2], read_tmp[1], read_tmp[0]);
} while ((retry++ < 10) && (read_sts != NO_ERR) &&
(read_tmp[3] != data_tmp[3] && read_tmp[2] != data_tmp[2] &&
read_tmp[1] != data_tmp[1] && read_tmp[0] != data_tmp[0]));
}
/* FW side end*/
/* CORE_FW */
/* CORE_FLASH */
/* FLASH side start*/
static void himax_mcu_chip_erase(void)
{
g_core_fp.fp_interface_on();
/* Reset power saving level */
if (g_core_fp.fp_init_psl != NULL)
g_core_fp.fp_init_psl();
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_fmt,
pflash_op->data_spi200_trans_fmt, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_ctrl,
pflash_op->data_spi200_trans_ctrl_2, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_cmd,
pflash_op->data_spi200_cmd_2, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_cmd,
pflash_op->data_spi200_cmd_3, DATA_LEN_4);
msleep(2000);
if (!g_core_fp.fp_wait_wip(100))
E("%s: Chip_Erase Fail\n", __func__);
}
static bool himax_mcu_block_erase(int start_addr, int length)
{
uint32_t page_prog_start = 0;
uint32_t block_size = 0x10000;
uint8_t tmp_data[4] = {0};
g_core_fp.fp_interface_on();
g_core_fp.fp_init_psl();
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_fmt,
pflash_op->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(pflash_op->addr_spi200_trans_ctrl,
pflash_op->data_spi200_trans_ctrl_2, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_cmd,
pflash_op->data_spi200_cmd_2, DATA_LEN_4);
tmp_data[3] = (page_prog_start >> 24)&0xFF;
tmp_data[2] = (page_prog_start >> 16)&0xFF;
tmp_data[1] = (page_prog_start >> 8)&0xFF;
tmp_data[0] = page_prog_start&0xFF;
g_core_fp.fp_register_write(pflash_op->addr_spi200_addr,
tmp_data, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_ctrl,
pflash_op->data_spi200_trans_ctrl_3, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_cmd,
pflash_op->data_spi200_cmd_4, DATA_LEN_4);
msleep(1000);
if (!g_core_fp.fp_wait_wip(100)) {
E("%s:Erase Fail\n", __func__);
return false;
}
}
I("%s:END\n", __func__);
return true;
}
static bool himax_mcu_sector_erase(int start_addr)
{
return true;
}
static void himax_mcu_flash_programming(uint8_t *FW_content, int FW_Size)
{
int page_prog_start = 0, i = 0, j = 0, k = 0;
int program_length = PROGRAM_SZ;
uint8_t tmp_data[DATA_LEN_4];
uint8_t buring_data[FLASH_RW_MAX_LEN];
int ret = 0;
/* 4 bytes for padding*/
g_core_fp.fp_interface_on();
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_fmt,
pflash_op->data_spi200_trans_fmt, DATA_LEN_4);
for (page_prog_start = 0; page_prog_start < FW_Size;
page_prog_start += FLASH_RW_MAX_LEN) {
g_core_fp.fp_register_write(pflash_op->addr_spi200_trans_ctrl,
pflash_op->data_spi200_trans_ctrl_2, DATA_LEN_4);
g_core_fp.fp_register_write(pflash_op->addr_spi200_cmd,
pflash_op->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(pflash_op->addr_spi200_trans_ctrl,
pflash_op->data_spi200_trans_ctrl_4, DATA_LEN_4);
/* Flash start address 1st : 0x0000_0000*/
if (page_prog_start < 0x100) {
tmp_data[3] = 0x00;
tmp_data[2] = 0x00;
tmp_data[1] = 0x00;
tmp_data[0] = (uint8_t)page_prog_start;
} else if (page_prog_start >= 0x100
&& page_prog_start < 0x10000) {
tmp_data[3] = 0x00;
tmp_data[2] = 0x00;
tmp_data[1] = (uint8_t)(page_prog_start >> 8);
tmp_data[0] = (uint8_t)page_prog_start;
} else if (page_prog_start >= 0x10000
&& page_prog_start < 0x1000000) {
tmp_data[3] = 0x00;
tmp_data[2] = (uint8_t)(page_prog_start >> 16);
tmp_data[1] = (uint8_t)(page_prog_start >> 8);
tmp_data[0] = (uint8_t)page_prog_start;
}
g_core_fp.fp_register_write(pflash_op->addr_spi200_addr,
tmp_data, DATA_LEN_4);
for (i = 0; i < ADDR_LEN_4; i++)
buring_data[i] = pflash_op->addr_spi200_data[i];
for (i = page_prog_start, j = 0;
i < 16 + page_prog_start;
i++, j++) {
buring_data[j + ADDR_LEN_4] = FW_content[i];
}
ret = himax_bus_write(pic_op->addr_ahb_addr_byte_0[0],
buring_data, ADDR_LEN_4 + 16);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return;
}
g_core_fp.fp_register_write(pflash_op->addr_spi200_cmd,
pflash_op->data_spi200_cmd_6, DATA_LEN_4);
for (j = 0; j < 5; j++) {
for (i = (page_prog_start + 16 + (j * 48)), k = 0;
i < (page_prog_start + 16 + (j * 48)) + program_length;
i++, k++)
buring_data[k + ADDR_LEN_4] = FW_content[i];
ret = himax_bus_write(pic_op->addr_ahb_addr_byte_0[0],
buring_data, program_length + ADDR_LEN_4);
if (ret < 0) {
E("%s: bus access fail!\n", __func__);
return;
}
}
if (!g_core_fp.fp_wait_wip(1))
E("%s:Flash_Programming Fail\n", __func__);
}
}
static void himax_mcu_flash_page_write(uint8_t *write_addr, int length,
uint8_t *write_data)
{
}
static void himax_flash_speed_set(uint8_t speed)
{
uint8_t tmp_addr[4];
uint8_t tmp_data[4];
himax_parse_assign_cmd(flash_clk_setup_addr, tmp_addr, 4);
himax_parse_assign_cmd((uint32_t)speed, tmp_data, 4);
g_core_fp.fp_register_write(tmp_addr, tmp_data, 4);
}
static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_32k(unsigned char *fw,
int len, bool change_iref)
{
/* Not use */
return 0;
}
static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_60k(unsigned char *fw,
int len, bool change_iref)
{
/* Not use */
return 0;
}
static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_64k(unsigned char *fw,
int len, bool change_iref)
{
int burnFW_success = 0;
if (len != FW_SIZE_64k) {
E("%s: The file size is not 64K bytes\n", __func__);
return false;
}
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
g_core_fp.fp_system_reset();
#endif
g_core_fp.fp_sense_off(true);
himax_flash_speed_set(HX_FLASH_SPEED_12p5M);
g_core_fp.fp_block_erase(0x00, FW_SIZE_64k);
g_core_fp.fp_flash_programming(fw, FW_SIZE_64k);
if (g_core_fp.fp_check_CRC(pfw_op->addr_program_reload_from,
FW_SIZE_64k) == 0)
burnFW_success = 1;
/*RawOut select initial*/
g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
/*DSRAM func initial*/
g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear);
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
/*System reset*/
g_core_fp.fp_system_reset();
#endif
return burnFW_success;
}
static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_124k(unsigned char *fw,
int len, bool change_iref)
{
/* Not use */
return 0;
}
static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_128k(unsigned char *fw,
int len, bool change_iref)
{
int burnFW_success = 0;
if (len != FW_SIZE_128k) {
E("%s: The file size is not 128K bytes\n", __func__);
return false;
}
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
g_core_fp.fp_system_reset();
#endif
g_core_fp.fp_sense_off(true);
himax_flash_speed_set(HX_FLASH_SPEED_12p5M);
g_core_fp.fp_block_erase(0x00, FW_SIZE_128k);
g_core_fp.fp_flash_programming(fw, FW_SIZE_128k);
if (g_core_fp.fp_check_CRC(pfw_op->addr_program_reload_from,
FW_SIZE_128k) == 0)
burnFW_success = 1;
/*RawOut select initial*/
g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
/*DSRAM func initial*/
g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear);
/*#if defined(HX_RST_PIN_FUNC)
* g_core_fp.fp_ic_reset(false, false);
*#else
* //System reset
* g_core_fp.fp_system_reset();
*#endif
*/
return burnFW_success;
}
static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_255k(unsigned char *fw,
int len, bool change_iref)
{
int burnFW_success = 0;
if (len != FW_SIZE_255k) {
E("%s: The file size is not 255K bytes\n", __func__);
return false;
}
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_ic_reset(false, false);
#else
g_core_fp.fp_system_reset();
#endif
g_core_fp.fp_sense_off(true);
himax_flash_speed_set(HX_FLASH_SPEED_12p5M);
g_core_fp.fp_block_erase(0x00, FW_SIZE_255k);
g_core_fp.fp_flash_programming(fw, FW_SIZE_255k);
if (g_core_fp.fp_check_CRC(pfw_op->addr_program_reload_from,
FW_SIZE_255k) == 0)
burnFW_success = 1;
/*RawOut select initial*/
g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
/*DSRAM func initial*/
g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear);
/*#if defined(HX_RST_PIN_FUNC)
* g_core_fp.fp_ic_reset(false, false);
*#else
* //System reset
* g_core_fp.fp_system_reset();
*#endif
*/
return burnFW_success;
}
static void himax_mcu_flash_dump_func(uint8_t local_flash_command,
int Flash_Size, uint8_t *flash_buffer)
{
uint8_t tmp_addr[DATA_LEN_4];
uint8_t buffer[256];
int page_prog_start = 0;
g_core_fp.fp_sense_off(true);
g_core_fp.fp_burst_enable(1);
for (page_prog_start = 0; page_prog_start < Flash_Size;
page_prog_start += 128) {
tmp_addr[0] = page_prog_start % 0x100;
tmp_addr[1] = (page_prog_start >> 8) % 0x100;
tmp_addr[2] = (page_prog_start >> 16) % 0x100;
tmp_addr[3] = page_prog_start / 0x1000000;
himax_mcu_register_read(tmp_addr, buffer, 128);
memcpy(&flash_buffer[page_prog_start], buffer, 128);
}
g_core_fp.fp_burst_enable(0);
g_core_fp.fp_sense_on(0x01);
}
static bool himax_mcu_flash_lastdata_check(uint32_t size)
{
uint8_t tmp_addr[4];
/* 64K - 0x80, which is the address of
* the last 128bytes in 64K, default value
*/
uint32_t start_addr = 0xFFFFFFFF;
uint32_t temp_addr = 0;
uint32_t flash_page_len = 0x80;
uint8_t flash_tmp_buffer[128];
if (size < flash_page_len) {
E("%s: flash size is wrong, terminated\n", __func__);
E("%s: flash size = %08X; flash page len = %08X\n", __func__,
size, flash_page_len);
goto FAIL;
}
/* In order to match other size of fw */
start_addr = size - flash_page_len;
I("%s: Now size is %d, the start_addr is 0x%08X\n",
__func__, 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\n",
* temp_addr,tmp_addr[0], tmp_addr[1],
* tmp_addr[2],tmp_addr[3]);
*/
tmp_addr[0] = temp_addr % 0x100;
tmp_addr[1] = (temp_addr >> 8) % 0x100;
tmp_addr[2] = (temp_addr >> 16) % 0x100;
tmp_addr[3] = temp_addr / 0x1000000;
g_core_fp.fp_register_read(tmp_addr, &flash_tmp_buffer[0],
flash_page_len);
}
I("FLASH[%08X] ~ FLASH[%08X] = %02X%02X%02X%02X\n", 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:\n");
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:\n");
goto FAIL;
} else {
return 0;
}
FAIL:
return 1;
}
static bool hx_bin_desc_data_get(uint32_t addr, uint8_t *flash_buf)
{
uint8_t data_sz = 0x10;
uint32_t i = 0, j = 0;
uint16_t chk_end = 0;
uint16_t chk_sum = 0;
uint32_t map_code = 0;
unsigned long flash_addr = 0;
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("%s: End in %X\n", __func__, i + addr);
return false;
} else if (chk_sum % 0x100) { /*2. Check sum*/
I("%s: chk sum failed in %X\n", __func__, i + addr);
} else { /*3. get data*/
map_code = flash_buf[i] + (flash_buf[i + 1] << 8)
+ (flash_buf[i + 2] << 16) + (flash_buf[i + 3] << 24);
flash_addr = flash_buf[i + 4] + (flash_buf[i + 5] << 8)
+ (flash_buf[i + 6] << 16) + (flash_buf[i + 7] << 24);
switch (map_code) {
case FW_CID:
CID_VER_MAJ_FLASH_ADDR = flash_addr;
CID_VER_MIN_FLASH_ADDR = flash_addr + 1;
I("%s: CID_VER in %lX\n", __func__,
CID_VER_MAJ_FLASH_ADDR);
break;
case FW_VER:
FW_VER_MAJ_FLASH_ADDR = flash_addr;
FW_VER_MIN_FLASH_ADDR = flash_addr + 1;
I("%s: FW_VER in %lX\n", __func__,
FW_VER_MAJ_FLASH_ADDR);
break;
case CFG_VER:
CFG_VER_MAJ_FLASH_ADDR = flash_addr;
CFG_VER_MIN_FLASH_ADDR = flash_addr + 1;
I("%s: CFG_VER in = %08lX\n", __func__,
CFG_VER_MAJ_FLASH_ADDR);
break;
case TP_CONFIG_TABLE:
CFG_TABLE_FLASH_ADDR = flash_addr;
I("%s: CONFIG_TABLE in %X\n",
__func__, CFG_TABLE_FLASH_ADDR);
break;
}
}
chk_end = 0;
chk_sum = 0;
}
return true;
}
static bool hx_mcu_bin_desc_get(unsigned char *fw, uint32_t max_sz)
{
uint32_t addr_t = 0;
unsigned char *fw_buf = NULL;
bool keep_on_flag = false;
bool g_bin_desc_flag = false;
do {
fw_buf = &fw[addr_t];
/*Check bin is with description table or not*/
if (!g_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)
g_bin_desc_flag = true;
}
if (!g_bin_desc_flag) {
I("%s: fw_buf[0x00] = %2X, fw_buf[0x0E] = %2X\n",
__func__, fw_buf[0x00], fw_buf[0x0E]);
I("%s: No description table\n", __func__);
break;
}
/*Get related data*/
keep_on_flag = hx_bin_desc_data_get(addr_t, fw_buf);
addr_t = addr_t + FW_PAGE_SZ;
} while (max_sz > addr_t && keep_on_flag);
return g_bin_desc_flag;
}
static int hx_mcu_diff_overlay_flash(void)
{
int rslt = 0;
int diff_val = 0;
diff_val = (ic_data->vendor_fw_ver);
I("%s:Now fw ID is 0x%04X\n", __func__, diff_val);
diff_val = (diff_val >> 12);
I("%s:Now diff value=0x%04X\n", __func__, diff_val);
if (diff_val == 1)
I("%s:Now size should be 128K!\n", __func__);
else
I("%s:Now size should be 64K!\n", __func__);
rslt = diff_val;
return rslt;
}
/* FLASH side end*/
/* CORE_FLASH */
/* CORE_SRAM */
/* SRAM side start*/
static void himax_mcu_sram_write(uint8_t *FW_content)
{
}
static bool himax_mcu_sram_verify(uint8_t *FW_File, int FW_Size)
{
return true;
}
static bool himax_mcu_get_DSRAM_data(uint8_t *info_data, bool DSRAM_Flag)
{
unsigned int i = 0;
unsigned char tmp_addr[ADDR_LEN_4];
unsigned char tmp_data[DATA_LEN_4];
unsigned int max_bus_size = MAX_I2C_TRANS_SZ;
uint8_t x_num = ic_data->HX_RX_NUM;
uint8_t y_num = ic_data->HX_TX_NUM;
/*int m_key_num = 0;*/
unsigned int total_size = (x_num * y_num + x_num + y_num) * 2 + 4;
unsigned int data_size = (x_num * y_num + x_num + y_num) * 2;
unsigned int remain_size;
uint8_t retry = 0;
/*int mutual_data_size = x_num * y_num * 2;*/
unsigned int addr = 0;
uint8_t *temp_info_data = NULL; /*max mkey size = 8*/
uint32_t checksum = 0;
int fw_run_flag = -1;
#if defined(HX_ZERO_FLASH)
max_bus_size = HX_MAX_READ_SZ - ADDR_LEN_4;
#endif
temp_info_data = kcalloc((total_size + 8), sizeof(uint8_t), GFP_KERNEL);
if (temp_info_data == NULL) {
E("%s, Failed to allocate memory\n", __func__);
return false;
}
/* 1. Read number of MKey R100070E8H to determin data size */
/* m_key_num = ic_data->HX_BT_NUM; */
/* I("%s,m_key_num=%d\n",__func__ ,m_key_num); */
/* total_size += m_key_num * 2; */
/* 2. Start DSRAM Rawdata and Wait Data Ready */
tmp_data[3] = 0x00;
tmp_data[2] = 0x00;
tmp_data[1] = psram_op->passwrd_start[1];
tmp_data[0] = psram_op->passwrd_start[0];
fw_run_flag = himax_write_read_reg(psram_op->addr_rawdata_addr,
tmp_data,
psram_op->passwrd_end[1],
psram_op->passwrd_end[0]);
if (fw_run_flag < 0) {
E("%s: Data NOT ready => bypass\n", __func__);
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;
tmp_addr[3] = (uint8_t)((addr >> 24) & 0x00FF);
tmp_addr[2] = (uint8_t)((addr >> 16) & 0x00FF);
tmp_addr[1] = (uint8_t)((addr >> 8) & 0x00FF);
tmp_addr[0] = (uint8_t)((addr) & 0x00FF);
if (remain_size >= max_bus_size) {
g_core_fp.fp_register_read(tmp_addr,
&temp_info_data[i], max_bus_size);
remain_size -= max_bus_size;
} else {
g_core_fp.fp_register_read(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("%s: check_sum_cal fail=%08X\n", __func__, checksum);
} else {
memcpy(info_data, &temp_info_data[4],
data_size * sizeof(uint8_t));
break;
}
}
/* 4. FW stop outputing */
tmp_data[3] = temp_info_data[3];
tmp_data[2] = temp_info_data[2];
tmp_data[1] = 0x00;
tmp_data[0] = 0x00;
g_core_fp.fp_register_write(psram_op->addr_rawdata_addr, tmp_data,
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(void)
{
I("%s: use default incell init.\n", __func__);
}
#if defined(HX_RST_PIN_FUNC)
static void himax_mcu_pin_reset(void)
{
I("%s: Now reset the Touch chip.\n", __func__);
himax_rst_gpio_set(private_ts->rst_gpio, 0);
usleep_range(RST_LOW_PERIOD_S, RST_LOW_PERIOD_E);
himax_rst_gpio_set(private_ts->rst_gpio, 1);
usleep_range(RST_HIGH_PERIOD_S, RST_HIGH_PERIOD_E);
}
static bool himax_mcu_ic_reset(uint8_t loadconfig, uint8_t int_off)
{
struct himax_ts_data *ts = private_ts;
HX_HW_RESET_ACTIVATE = 0;
I("%s,status: loadconfig=%d,int_off=%d\n", __func__,
loadconfig, int_off);
if (ts->rst_gpio >= 0) {
if (int_off)
g_core_fp.fp_irq_switch(0);
g_core_fp.fp_pin_reset();
/* if (loadconfig) */
/* g_core_fp.fp_reload_config(); */
if (int_off)
g_core_fp.fp_irq_switch(1);
} else {
return false;
}
return true;
}
#endif
static uint8_t himax_mcu_tp_info_check(void)
{
char addr[DATA_LEN_4] = {0};
char data[DATA_LEN_4] = {0};
uint32_t rx_num;
uint32_t tx_num;
uint32_t bt_num;
uint32_t max_pt;
uint8_t int_is_edge;
uint8_t stylus_func;
uint8_t err_cnt = 0;
g_core_fp.fp_register_read(pdriver_op->addr_fw_define_rxnum_txnum, data,
DATA_LEN_4);
rx_num = data[2];
tx_num = data[3];
g_core_fp.fp_register_read(pdriver_op->addr_fw_define_maxpt_xyrvs, data,
DATA_LEN_4);
max_pt = data[0];
g_core_fp.fp_register_read(pdriver_op->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(psram_op->addr_mkey, data, DATA_LEN_4);
bt_num = data[0] & 0x03;
addr[3] = 0x10;
addr[2] = 0x00;
addr[1] = 0x71;
addr[0] = 0x9C;
g_core_fp.fp_register_read(addr, data, DATA_LEN_4);
stylus_func = data[3];
if (ic_data->HX_RX_NUM != rx_num) {
err_cnt++;
W("%s: RX_NUM, Set = %d ; FW = %d", __func__,
ic_data->HX_RX_NUM, rx_num);
}
if (ic_data->HX_TX_NUM != tx_num) {
err_cnt++;
W("%s: TX_NUM, Set = %d ; FW = %d", __func__,
ic_data->HX_TX_NUM, tx_num);
}
if (ic_data->HX_BT_NUM != bt_num) {
err_cnt++;
W("%s: BT_NUM, Set = %d ; FW = %d", __func__,
ic_data->HX_BT_NUM, bt_num);
}
if (ic_data->HX_MAX_PT != max_pt) {
err_cnt++;
W("%s: MAX_PT, Set = %d ; FW = %d", __func__,
ic_data->HX_MAX_PT, max_pt);
}
if (ic_data->HX_INT_IS_EDGE != int_is_edge) {
err_cnt++;
W("%s: INT_IS_EDGE, Set = %d ; FW = %d", __func__,
ic_data->HX_INT_IS_EDGE, int_is_edge);
}
if (ic_data->HX_STYLUS_FUNC != stylus_func) {
err_cnt++;
W("%s: STYLUS_FUNC, Set = %d ; FW = %d", __func__,
ic_data->HX_STYLUS_FUNC, stylus_func);
}
if (err_cnt > 0)
W("FIX_TOUCH_INFO does NOT match to FW information\n");
else
I("FIX_TOUCH_INFO is OK\n");
return err_cnt;
}
static void himax_mcu_touch_information(void)
{
if (ic_data->HX_RX_NUM == 0xFFFFFFFF)
ic_data->HX_RX_NUM = FIX_HX_RX_NUM;
if (ic_data->HX_TX_NUM == 0xFFFFFFFF)
ic_data->HX_TX_NUM = FIX_HX_TX_NUM;
if (ic_data->HX_BT_NUM == 0xFFFFFFFF)
ic_data->HX_BT_NUM = FIX_HX_BT_NUM;
if (ic_data->HX_MAX_PT == 0xFFFFFFFF)
ic_data->HX_MAX_PT = FIX_HX_MAX_PT;
if (ic_data->HX_INT_IS_EDGE == 0xFF)
ic_data->HX_INT_IS_EDGE = FIX_HX_INT_IS_EDGE;
if (ic_data->HX_STYLUS_FUNC == 0xFF)
ic_data->HX_STYLUS_FUNC = FIX_HX_STYLUS_FUNC;
ic_data->HX_Y_RES = private_ts->pdata->screenHeight;
ic_data->HX_X_RES = private_ts->pdata->screenWidth;
I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d\n", __func__,
ic_data->HX_RX_NUM, ic_data->HX_TX_NUM);
I("%s:HX_MAX_PT=%d\n", __func__, ic_data->HX_MAX_PT);
I("%s:HX_Y_RES=%d,HX_X_RES =%d\n", __func__,
ic_data->HX_Y_RES, ic_data->HX_X_RES);
I("%s:HX_INT_IS_EDGE =%d,HX_STYLUS_FUNC = %d\n", __func__,
ic_data->HX_INT_IS_EDGE, ic_data->HX_STYLUS_FUNC);
}
static void himax_mcu_calcTouchDataSize(void)
{
struct himax_ts_data *ts_data = private_ts;
ts_data->x_channel = ic_data->HX_RX_NUM;
ts_data->y_channel = ic_data->HX_TX_NUM;
ts_data->nFinger_support = ic_data->HX_MAX_PT;
HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4;
if ((ic_data->HX_MAX_PT % 4) == 0)
HX_TOUCH_INFO_POINT_CNT +=
(ic_data->HX_MAX_PT / 4) * 4;
else
HX_TOUCH_INFO_POINT_CNT +=
((ic_data->HX_MAX_PT / 4) + 1) * 4;
if (himax_report_data_init())
E("%s: allocate data fail\n", __func__);
}
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 RawDataLen;
/* rawdata checksum is 2 bytes */
if (raw_cnt_rmd != 0x00)
RawDataLen = MAX_I2C_TRANS_SZ
- ((HX_MAX_PT + raw_cnt_max + 3) * 4) - 2;
else
RawDataLen = MAX_I2C_TRANS_SZ
- ((HX_MAX_PT + raw_cnt_max + 2) * 4) - 2;
return RawDataLen;
}
static bool himax_mcu_diag_check_sum(struct himax_report_data *hx_touch_data)
{
uint16_t check_sum_cal = 0;
int i;
/* Check 128th byte CRC */
for (i = 0, check_sum_cal = 0;
i < (hx_touch_data->touch_all_size
- hx_touch_data->touch_info_size);
i += 2) {
check_sum_cal += (hx_touch_data->hx_rawdata_buf[i + 1]
* FLASH_RW_MAX_LEN
+ hx_touch_data->hx_rawdata_buf[i]);
}
if (check_sum_cal % HX64K != 0) {
I("%s fail=%2X\n", __func__, check_sum_cal);
return 0;
}
return 1;
}
static void himax_mcu_diag_parse_raw_data(
struct himax_report_data *hx_touch_data,
int mul_num, int self_num, uint8_t diag_cmd,
int32_t *mutual_data, int32_t *self_data)
{
diag_mcu_parse_raw_data(hx_touch_data, mul_num, self_num,
diag_cmd, mutual_data, self_data);
}
#if defined(HX_EXCP_RECOVERY)
static int himax_mcu_ic_excp_recovery(uint32_t hx_excp_event,
uint32_t hx_zero_event, uint32_t length)
{
int ret_val = NO_ERR;
if (hx_excp_event == length) {
g_zero_event_count = 0;
ret_val = HX_EXCP_EVENT;
} else if (hx_zero_event == length) {
if (g_zero_event_count > 5) {
g_zero_event_count = 0;
I("EXCEPTION event checked - ALL Zero.\n");
ret_val = HX_EXCP_EVENT;
} else {
g_zero_event_count++;
I("ALL Zero event is %d times.\n",
g_zero_event_count);
ret_val = HX_ZERO_EVENT_COUNT;
}
}
return ret_val;
}
static void himax_mcu_excp_ic_reset(void)
{
HX_EXCP_RESET_ACTIVATE = 0;
#if defined(HX_RST_PIN_FUNC)
himax_mcu_pin_reset();
#else
himax_mcu_system_reset();
#endif
I("%s:\n", __func__);
}
#endif
#if defined(HX_TP_PROC_GUEST_INFO)
char *g_checksum_str = "check sum fail";
/* char *g_guest_info_item[] = {
* "projectID",
* "CGColor",
* "BarCode",
* "Reserve1",
* "Reserve2",
* "Reserve3",
* "Reserve4",
* "Reserve5",
* "VCOM",
* "Vcom-3Gar",
* NULL
* };
*/
static int himax_guest_info_get_status(void)
{
return g_guest_info_data->g_guest_info_ongoing;
}
static void himax_guest_info_set_status(int setting)
{
g_guest_info_data->g_guest_info_ongoing = setting;
}
static int himax_guest_info_read(uint32_t start_addr,
uint8_t *flash_tmp_buffer)
{
uint32_t temp_addr = 0;
uint8_t tmp_addr[4];
uint32_t flash_page_len = 0x1000;
/* uint32_t checksum = 0x00; */
int result = -1;
I("%s:Reading guest info in start_addr = 0x%08X !\n", __func__,
start_addr);
tmp_addr[0] = start_addr % 0x100;
tmp_addr[1] = (start_addr >> 8) % 0x100;
tmp_addr[2] = (start_addr >> 16) % 0x100;
tmp_addr[3] = start_addr / 0x1000000;
I("addr[0]=0x%2X,addr[1]=0x%2X,addr[2]=0x%2X,addr[3]=0x%2X\n",
tmp_addr[0], tmp_addr[1],
tmp_addr[2], tmp_addr[3]);
result = g_core_fp.fp_check_CRC(tmp_addr, flash_page_len);
I("Checksum = 0x%8X\n", result);
if (result != 0)
goto END_FUNC;
for (temp_addr = start_addr;
temp_addr < (start_addr + flash_page_len);
temp_addr = temp_addr + 128) {
/* I("temp_addr=%d,tmp_addr[0]=0x%2X,tmp_addr[1]=0x%2X,
* tmp_addr[2]=0x%2X,tmp_addr[3]=0x%2X\n",
* temp_addr,tmp_addr[0],tmp_addr[1],
* tmp_addr[2],tmp_addr[3]);
*/
tmp_addr[0] = temp_addr % 0x100;
tmp_addr[1] = (temp_addr >> 8) % 0x100;
tmp_addr[2] = (temp_addr >> 16) % 0x100;
tmp_addr[3] = temp_addr / 0x1000000;
g_core_fp.fp_register_read(tmp_addr,
&flash_tmp_buffer[temp_addr - start_addr], 128);
/* memcpy(&flash_tmp_buffer[temp_addr - start_addr],
* buffer,128);
*/
}
END_FUNC:
return result;
}
static int hx_read_guest_info(void)
{
/* uint8_t tmp_addr[4]; */
uint32_t panel_info_addr = HX_GUEST_INFO_FLASH_SADDR;
uint32_t info_len;
uint32_t flash_page_len = 0x1000;/*4k*/
uint8_t *flash_tmp_buffer = NULL;
/* uint32_t temp_addr = 0; */
uint8_t temp_str[128];
int i = 0;
unsigned int custom_info_temp = 0;
int checksum = 0;
himax_guest_info_set_status(1);
flash_tmp_buffer = kcalloc(HX_GUEST_INFO_SIZE * flash_page_len,
sizeof(uint8_t), GFP_KERNEL);
if (flash_tmp_buffer == NULL) {
I("%s: Memory allocate fail!\n", __func__);
return MEM_ALLOC_FAIL;
}
g_core_fp.fp_sense_off(true);
/* g_core_fp.fp_burst_enable(1); */
for (custom_info_temp = 0;
custom_info_temp < HX_GUEST_INFO_SIZE;
custom_info_temp++) {
checksum = himax_guest_info_read(panel_info_addr
+ custom_info_temp
* flash_page_len,
&flash_tmp_buffer[custom_info_temp * flash_page_len]);
if (checksum != 0) {
E("%s:Checksum Fail! g_checksum_str len=%d\n", __func__,
(int)strlen(g_checksum_str));
memcpy(&g_guest_info_data->
g_guest_str_in_format[custom_info_temp][0],
g_checksum_str, (int)strlen(g_checksum_str));
memcpy(&g_guest_info_data->
g_guest_str[custom_info_temp][0],
g_checksum_str, (int)strlen(g_checksum_str));
continue;
}
info_len = flash_tmp_buffer[custom_info_temp * flash_page_len]
+ (flash_tmp_buffer[custom_info_temp
* flash_page_len + 1] << 8)
+ (flash_tmp_buffer[custom_info_temp
* flash_page_len + 2] << 16)
+ (flash_tmp_buffer[custom_info_temp
* flash_page_len + 3] << 24);
I("Now custom_info_temp = %d\n", custom_info_temp);
I("Now size_buff[0]=0x%02X,[1]=0x%02X,[2]=0x%02X,[3]=0x%02X\n",
flash_tmp_buffer[custom_info_temp*flash_page_len],
flash_tmp_buffer[custom_info_temp*flash_page_len + 1],
flash_tmp_buffer[custom_info_temp*flash_page_len + 2],
flash_tmp_buffer[custom_info_temp*flash_page_len + 3]);
I("Now total length=%d\n", info_len);
g_guest_info_data->g_guest_data_len[custom_info_temp] =
info_len;
I("Now custom_info_id [0]=%d,[1]=%d,[2]=%d,[3]=%d\n",
flash_tmp_buffer[custom_info_temp*flash_page_len + 4],
flash_tmp_buffer[custom_info_temp*flash_page_len + 5],
flash_tmp_buffer[custom_info_temp*flash_page_len + 6],
flash_tmp_buffer[custom_info_temp*flash_page_len + 7]);
g_guest_info_data->g_guest_data_type[custom_info_temp] =
flash_tmp_buffer[custom_info_temp * flash_page_len
+ 7];
/* if(custom_info_temp < 3) { */
if (info_len > 128) {
I("%s: info_len=%d\n", __func__, info_len);
info_len = 128;
}
for (i = 0; i < info_len; i++)
temp_str[i] = flash_tmp_buffer[custom_info_temp
* flash_page_len
+ HX_GUEST_INFO_LEN_SIZE
+ HX_GUEST_INFO_ID_SIZE
+ i];
I("g_guest_info_data->g_guest_str_in_format[%d]size=%d\n",
custom_info_temp, info_len);
memcpy(&g_guest_info_data->
g_guest_str_in_format[custom_info_temp][0],
temp_str, info_len);
/*}*/
for (i = 0; i < 128; i++)
temp_str[i] = flash_tmp_buffer[custom_info_temp
* flash_page_len
+ i];
I("g_guest_info_data->g_guest_str[%d] size = %d\n",
custom_info_temp, 128);
memcpy(&g_guest_info_data->g_guest_str[custom_info_temp][0],
temp_str, 128);
/*if(custom_info_temp == 0)
*{
* for ( i = 0; i< 256 ; i++) {
* if(i % 16 == 0 && i > 0)
* I("\n");
* I("g_guest_info_data->g_guest_str[%d][%d]
= 0x%02X", custom_info_temp, i,
g_guest_info_data->g_guest_str[
custom_info_temp][i]);
* }
*}
*/
}
/* himax_burst_enable(private_ts->client, 0); */
g_core_fp.fp_sense_on(0x01);
kfree(flash_tmp_buffer);
himax_guest_info_set_status(0);
return NO_ERR;
}
#endif
/* CORE_DRIVER */
#if defined(HX_SMART_WAKEUP)\
|| defined(HX_HIGH_SENSE)\
|| defined(HX_USB_DETECT_GLOBAL)
static void himax_mcu_resend_cmd_func(bool suspended)
{
#if defined(HX_SMART_WAKEUP) || defined(HX_HIGH_SENSE)
struct himax_ts_data *ts = private_ts;
#endif
#if defined(HX_SMART_WAKEUP)
g_core_fp.fp_set_SMWP_enable(ts->SMWP_enable, suspended);
#endif
#if defined(HX_HIGH_SENSE)
g_core_fp.fp_set_HSEN_enable(ts->HSEN_enable, suspended);
#endif
#if defined(HX_USB_DETECT_GLOBAL)
himax_cable_detect_func(true);
#endif
}
#endif
int hx_turn_on_mp_func(int on)
{
int rslt = 0;
int retry = 3;
uint8_t tmp_addr[4] = {0};
uint8_t tmp_data[4] = {0};
uint8_t tmp_read[4] = {0};
/* char *tmp_chipname = private_ts->chip_name; */
if (strcmp(HX_83102D_SERIES_PWON, private_ts->chip_name) == 0) {
himax_parse_assign_cmd(fw_addr_ctrl_mpap_ovl, tmp_addr,
sizeof(tmp_addr));
if (on) {
I("%s : Turn on MPAP mode!\n", __func__);
himax_parse_assign_cmd(fw_data_ctrl_mpap_ovl_on,
tmp_data, sizeof(tmp_data));
do {
g_core_fp.fp_register_write(tmp_addr, tmp_data,
4);
usleep_range(10000, 10001);
g_core_fp.fp_register_read(tmp_addr, tmp_read,
4);
I("%s:read2=0x%02X,read1=0x%02X,read0=0x%02X\n",
__func__, tmp_read[2], tmp_read[1],
tmp_read[0]);
retry--;
} while (((retry > 0)
&& (tmp_read[2] != tmp_data[2]
&& tmp_read[1] != tmp_data[1]
&& tmp_read[0] != tmp_data[0])));
} else {
I("%s : Turn off MPAP mode!\n", __func__);
himax_parse_assign_cmd(fw_data_clear, tmp_data,
sizeof(tmp_data));
do {
g_core_fp.fp_register_write(tmp_addr, tmp_data,
4);
usleep_range(10000, 10001);
g_core_fp.fp_register_read(tmp_addr, tmp_read,
4);
I("%s:read2=0x%02X,read1=0x%02X,read0=0x%02X\n",
__func__, tmp_read[2], tmp_read[1],
tmp_read[0]);
retry--;
} while ((retry > 0)
&& (tmp_read[2] != tmp_data[2]
&& tmp_read[1] != tmp_data[1]
&& tmp_read[0] != tmp_data[0]));
}
} else {
I("%s Nothing to be done!\n", __func__);
}
return rslt;
}
#if defined(HX_ZERO_FLASH)
int G_POWERONOF = 1;
EXPORT_SYMBOL(G_POWERONOF);
void hx_dis_rload_0f(int disable)
{
/*Diable Flash Reload*/
g_core_fp.fp_register_write(pdriver_op->addr_fw_define_flash_reload,
pzf_op->data_dis_flash_reload, DATA_LEN_4);
}
void himax_mcu_clean_sram_0f(uint8_t *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;
uint8_t fix_data = 0x00;
uint8_t tmp_addr[4];
uint8_t tmp_data[MAX_I2C_TRANS_SZ] = {0};
I("%s, Entering\n", __func__);
max_bus_size = (write_len > HX_MAX_WRITE_SZ)
? HX_MAX_WRITE_SZ : write_len;
total_size_temp = write_len;
g_core_fp.fp_burst_enable(1);
tmp_addr[3] = addr[3];
tmp_addr[2] = addr[2];
tmp_addr[1] = addr[1];
tmp_addr[0] = addr[0];
I("%s:addr[3]=0x%2X,addr[2]=0x%2X,addr[1]=0x%2X,addr[0]=0x%2X\n",
__func__,
tmp_addr[3],
tmp_addr[2],
tmp_addr[1],
tmp_addr[0]);
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("%s, total size=%d\n", __func__, 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;
for (i = 0; i < (total_read_times); i++) {
I("[log]write %d time start!\n", i);
if (total_size_temp >= max_bus_size) {
g_core_fp.fp_register_write(tmp_addr, tmp_data,
max_bus_size);
total_size_temp = total_size_temp - max_bus_size;
} else {
I("last total_size_temp=%d\n", total_size_temp);
g_core_fp.fp_register_write(tmp_addr, tmp_data,
total_size_temp % max_bus_size);
}
address = ((i+1) * max_bus_size);
tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF);
tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF);
usleep_range(10000, 11000);
}
I("%s, END\n", __func__);
}
void himax_mcu_write_sram_0f(uint8_t *addr, const uint8_t *data, uint32_t len)
{
int total_read_times = 0;
int max_bus_size = MAX_I2C_TRANS_SZ;
int total_size_temp = 0;
int address = 0;
int i = 0;
uint8_t tmp_addr[4];
uint8_t *tmp_data;
total_size_temp = len;
I("%s, Entering - total write size=%d\n", __func__, total_size_temp);
max_bus_size = (len > HX_MAX_WRITE_SZ)
? HX_MAX_WRITE_SZ : len;
g_core_fp.fp_burst_enable(1);
tmp_addr[3] = addr[3];
tmp_addr[2] = addr[2];
tmp_addr[1] = addr[1];
tmp_addr[0] = addr[0];
I("%s, write addr = 0x%02X%02X%02X%02X\n", __func__,
tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
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;
for (i = 0; i < (total_read_times); i++) {
if (total_size_temp >= max_bus_size) {
tmp_data = (uint8_t *)(data + i*max_bus_size);
g_core_fp.fp_register_write(tmp_addr, tmp_data,
max_bus_size);
total_size_temp = total_size_temp - max_bus_size;
} else {
tmp_data = (uint8_t *)(data + i*max_bus_size);
I("last total_size_temp=%d\n",
total_size_temp % max_bus_size);
g_core_fp.fp_register_write(tmp_addr, tmp_data,
total_size_temp % max_bus_size);
}
address = ((i+1) * max_bus_size);
tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF);
if (tmp_addr[0] < addr[0])
tmp_addr[1] = addr[1]
+ (uint8_t) ((address>>8) & 0x00FF) + 1;
else
tmp_addr[1] = addr[1]
+ (uint8_t) ((address>>8) & 0x00FF);
udelay(100);
}
I("%s, End\n", __func__);
/* kfree(tmp_data); */
}
int himax_sram_write_crc_check(uint8_t *addr, const uint8_t *data, uint32_t len)
{
int retry = 0;
int crc = -1;
do {
g_core_fp.fp_write_sram_0f(addr, data, len);
crc = g_core_fp.fp_check_CRC(addr, len);
retry++;
I("%s, HW CRC %s in %d time\n", __func__,
(crc == 0) ? "OK" : "Fail", retry);
} while (crc != 0 && retry < 3);
return crc;
}
int himax_zf_part_info(const struct firmware *fw, int type)
{
uint32_t table_addr = CFG_TABLE_FLASH_ADDR;
int pnum = 0;
int ret = 0;
uint8_t buf[16];
struct zf_info *info;
uint8_t *cfg_buf;
uint8_t sram_min[4];
int cfg_sz = 0;
int cfg_crc_sw = 0;
int cfg_crc_hw = 0;
uint8_t i = 0;
int i_max = 0;
int i_min = 0;
uint32_t dsram_base = 0xFFFFFFFF;
uint32_t dsram_max = 0;
int retry = 0;
#if defined(HX_ALG_OVERLAY) || defined(HX_CODE_OVERLAY)
uint8_t tmp_addr[4] = {0xFC, 0x7F, 0x00, 0x10};
uint8_t rdata[4] = {0};
int allovlidx = 0;
#endif
#if defined(HX_ALG_OVERLAY)
uint8_t alg_sdata[4] = {0xA5, 0x5A, 0x5A, 0xA5};
uint8_t alg_idx_t = 0;
uint8_t data[4] = {0x01, 0x00, 0x00, 0x00};
#endif
#if defined(HX_CODE_OVERLAY)
uint8_t code_sdata[4] = {0};
uint8_t code_idx_t = 0;
uint8_t j = 0;
#endif
/* 1. initial check */
pnum = fw->data[table_addr + 12];
if (pnum < 2) {
E("%s: partition number is not correct\n", __func__);
return FW_NOT_READY;
}
info = kcalloc(pnum, sizeof(struct zf_info), GFP_KERNEL);
if (info == NULL) {
E("%s: memory allocation fail[info]!!\n", __func__);
return 1;
}
memset(info, 0, pnum * sizeof(struct zf_info));
#if defined(HX_CODE_OVERLAY)
if (ovl_idx == NULL) {
ovl_idx = kzalloc(ovl_section_num, GFP_KERNEL);
if (ovl_idx == NULL) {
E("%s, ovl_idx alloc failed!\n", __func__);
return 1;
}
} else {
memset(ovl_idx, 0, ovl_section_num);
}
#endif
/* 2. record partition information */
memcpy(buf, &fw->data[table_addr], 16);
memcpy(info[0].sram_addr, buf, 4);
info[0].write_size = buf[7] << 24 | buf[6] << 16 | buf[5] << 8 | buf[4];
info[0].fw_addr = buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8];
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 = buf[7] << 24 | buf[6] << 16
| buf[5] << 8 | buf[4];
info[i].fw_addr = buf[11] << 24 | buf[10] << 16
| buf[9] << 8 | buf[8];
info[i].cfg_addr = info[i].sram_addr[0];
info[i].cfg_addr += info[i].sram_addr[1] << 8;
info[i].cfg_addr += info[i].sram_addr[2] << 16;
info[i].cfg_addr += info[i].sram_addr[3] << 24;
if (info[i].cfg_addr % 4 != 0)
info[i].cfg_addr -= (info[i].cfg_addr % 4);
I("%s,[%d]SRAM addr=%08X, fw_addr=%08X, write_size=%d\n",
__func__, i, info[i].cfg_addr, info[i].fw_addr,
info[i].write_size);
#if defined(HX_ALG_OVERLAY)
/* alg overlay section */
if ((buf[15] == 0x77 && buf[14] == 0x88)) {
I("%s: find alg overlay section in index %d\n",
__func__, i);
/* record index of alg overlay section */
allovlidx |= 1<<i;
alg_idx_t = i;
continue;
}
#endif
#if defined(HX_CODE_OVERLAY)
/* code overlay section */
if ((buf[15] == 0x55 && buf[14] == 0x66)
|| (buf[3] == 0x20 && buf[2] == 0x00
&& buf[1] == 0x8C && buf[0] == 0xE0)) {
I("%s: find code overlay section in index %d\n",
__func__, i);
/* 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)
ovl_idx[j] = i;
} else {
/* previous mechanism */
if (j < ovl_section_num)
ovl_idx[j++] = i;
}
continue;
}
#endif
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 */
#if defined(HX_ALG_OVERLAY)
if (alg_idx_t == 0 || info[alg_idx_t].write_size == 0) {
E("%s: wrong alg overlay section[%d, %d]!\n", __func__,
alg_idx_t, info[alg_idx_t].write_size);
ret = FW_NOT_READY;
goto ALOC_CFG_BUF_FAIL;
}
#endif
#if defined(HX_CODE_OVERLAY)
/* ovl_idx[0] - sorting */
/* ovl_idx[1] - gesture */
/* ovl_idx[2] - border */
code_idx_t = ovl_idx[0];
code_sdata[0] = ovl_sorting_reply;
if (type == 0) {
#if defined(HX_SMART_WAKEUP)
if (private_ts->suspended && private_ts->SMWP_enable) {
code_idx_t = ovl_idx[1];
code_sdata[0] = ovl_gesture_reply;
} else {
code_idx_t = ovl_idx[2];
code_sdata[0] = ovl_border_reply;
}
#else
code_idx_t = ovl_idx[2];
code_sdata[0] = ovl_border_reply;
#endif
}
if (code_idx_t == 0 || info[code_idx_t].write_size == 0) {
E("%s: wrong code overlay section[%d, %d]!\n", __func__,
code_idx_t, info[code_idx_t].write_size);
ret = FW_NOT_READY;
goto ALOC_CFG_BUF_FAIL;
}
#endif
for (i = 0; i < ADDR_LEN_4; i++)
sram_min[i] = (info[i_min].cfg_addr>>(8*i)) & 0xFF;
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("%s, cfg_sz = %d!, dsram_base = %X, dsram_max = %X\n", __func__,
cfg_sz, dsram_base, dsram_max);
/* config size should be smaller than DSRAM size */
if (cfg_sz > DSRAM_SIZE) {
E("%s: config size error[%d, %d]!!\n", __func__,
cfg_sz, DSRAM_SIZE);
ret = LENGTH_FAIL;
goto ALOC_CFG_BUF_FAIL;
}
cfg_buf = kcalloc(cfg_sz, sizeof(uint8_t), GFP_KERNEL);
if (cfg_buf == NULL) {
E("%s: memory allocation fail[cfg_buf]!!\n", __func__);
ret = 1;
goto ALOC_CFG_BUF_FAIL;
}
for (i = 1; i < pnum; i++) {
#if defined(HX_ALG_OVERLAY) || defined(HX_CODE_OVERLAY)
/* overlay section */
if (allovlidx & (1<<i)) {
I("%s: skip overlay section %d\n", __func__, i);
continue;
}
#endif
memcpy(&cfg_buf[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(info[0].sram_addr,
&fw->data[info[0].fw_addr], info[0].write_size) != 0) {
E("%s: HW CRC FAIL\n", __func__);
ret = 2;
goto BURN_SRAM_FAIL;
}
cfg_crc_sw = g_core_fp.fp_Calculate_CRC_with_AP(cfg_buf, 0, cfg_sz);
do {
g_core_fp.fp_write_sram_0f(sram_min, cfg_buf, cfg_sz);
cfg_crc_hw = g_core_fp.fp_check_CRC(sram_min, cfg_sz);
if (cfg_crc_hw != cfg_crc_sw) {
E("Cfg CRC FAIL,HWCRC=%X,SWCRC=%X,retry=%d\n",
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) {
#if defined(HX_SMART_WAKEUP) || defined(HX_HIGH_SENSE) \
|| defined(HX_USB_DETECT_GLOBAL)
g_core_fp.fp_resend_cmd_func(private_ts->suspended);
#endif
}
#if defined(HX_ALG_OVERLAY)
// clear handshaking to 0xA55A5AA5
retry = 0;
do {
g_core_fp.fp_register_write(tmp_addr, alg_sdata, DATA_LEN_4);
usleep_range(1000, 1100);
g_core_fp.fp_register_read(tmp_addr, rdata, DATA_LEN_4);
} while ((rdata[0] != alg_sdata[0]
|| rdata[1] != alg_sdata[1]
|| rdata[2] != alg_sdata[2]
|| rdata[3] != alg_sdata[3])
&& retry++ < HIMAX_REG_RETRY_TIMES);
if (retry > HIMAX_REG_RETRY_TIMES) {
E("%s: init handshaking data FAIL[%02X%02X%02X%02X]!!\n",
__func__, rdata[0], rdata[1], rdata[2], rdata[3]);
}
alg_sdata[3] = ovl_alg_reply;
alg_sdata[2] = ovl_alg_reply;
alg_sdata[1] = ovl_alg_reply;
alg_sdata[0] = ovl_alg_reply;
g_core_fp.fp_reload_disable(0);
/*g_core_fp.fp_power_on_init();*/
/*Rawout Sel initial*/
g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
/*DSRAM func initial*/
g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear);
/* reset N frame back to default for normal mode */
g_core_fp.fp_register_write(pfw_op->addr_set_frame_addr, data, 4);
/*FW reload done initial*/
g_core_fp.fp_register_write(pdriver_op->addr_fw_define_2nd_flash_reload,
pfw_op->data_clear, sizeof(pfw_op->data_clear));
g_core_fp.fp_sense_on(0x00);
retry = 0;
do {
usleep_range(3000, 3100);
g_core_fp.fp_register_read(tmp_addr, rdata, DATA_LEN_4);
} while ((rdata[0] != ovl_alg_request
|| rdata[1] != ovl_alg_request
|| rdata[2] != ovl_alg_request
|| rdata[3] != ovl_alg_request)
&& retry++ < 30);
if (retry > 30) {
E("%s: fail req data = 0x%02X%02X%02X%02X\n", __func__,
rdata[0], rdata[1], rdata[2], rdata[3]);
/* monitor FW status for debug */
for (i = 0; i < 10; i++) {
usleep_range(10000, 10100);
g_core_fp.fp_register_read(tmp_addr, rdata, DATA_LEN_4);
I("%s: req data = 0x%02X%02X%02X%02X\n",
__func__, rdata[0], rdata[1], rdata[2],
rdata[3]);
g_core_fp.fp_read_FW_status();
}
ret = 3;
goto BURN_OVL_FAIL;
}
I("%s: upgrade alg overlay section[%d]\n", __func__, alg_idx_t);
if (himax_sram_write_crc_check(info[alg_idx_t].sram_addr,
&fw->data[info[alg_idx_t].fw_addr], info[alg_idx_t].write_size) != 0) {
E("%s: Alg Overlay HW CRC FAIL\n", __func__);
ret = 2;
}
#endif
#if defined(HX_CODE_OVERLAY)
I("%s: upgrade code overlay section[%d]\n", __func__, code_idx_t);
if (himax_sram_write_crc_check(info[code_idx_t].sram_addr,
&fw->data[info[code_idx_t].fw_addr],
info[code_idx_t].write_size) != 0) {
E("%s: code overlay HW CRC FAIL\n", __func__);
code_sdata[0] = ovl_fault;
ret = 2;
}
retry = 0;
do {
g_core_fp.fp_register_write(tmp_addr, code_sdata, DATA_LEN_4);
usleep_range(1000, 1100);
g_core_fp.fp_register_read(tmp_addr, rdata, DATA_LEN_4);
retry++;
} while ((code_sdata[3] != rdata[3]
|| code_sdata[2] != rdata[2]
|| code_sdata[1] != rdata[1]
|| code_sdata[0] != rdata[0])
&& retry < HIMAX_REG_RETRY_TIMES);
if (retry >= HIMAX_REG_RETRY_TIMES) {
E("%s: fail code rpl data = 0x%02X%02X%02X%02X\n",
__func__, rdata[0], rdata[1], rdata[2], rdata[3]);
}
#endif
#if defined(HX_ALG_OVERLAY)
retry = 0;
do {
g_core_fp.fp_register_write(tmp_addr, alg_sdata, DATA_LEN_4);
usleep_range(1000, 1100);
g_core_fp.fp_register_read(tmp_addr, rdata, DATA_LEN_4);
} while ((alg_sdata[3] != rdata[3]
|| alg_sdata[2] != rdata[2]
|| alg_sdata[1] != rdata[1]
|| alg_sdata[0] != rdata[0])
&& retry++ < HIMAX_REG_RETRY_TIMES);
if (retry > HIMAX_REG_RETRY_TIMES) {
E("%s: fail rpl data = 0x%02X%02X%02X%02X\n", __func__,
rdata[0], rdata[1], rdata[2], rdata[3]);
// maybe need to reset
} else {
I("%s: waiting for FW reload data", __func__);
retry = 0;
while (retry++ < 30) {
g_core_fp.fp_register_read(
pdriver_op->addr_fw_define_2nd_flash_reload,
data, DATA_LEN_4);
/* use all 4 bytes to compare */
if ((data[3] == 0x00 && data[2] == 0x00 &&
data[1] == 0x72 && data[0] == 0xC0)) {
I("%s: FW reload done\n", __func__);
break;
}
I("%s: wait FW reload %d times\n", __func__, retry);
g_core_fp.fp_read_FW_status();
usleep_range(10000, 11000);
}
}
#endif
#if defined(HX_ALG_OVERLAY)
BURN_OVL_FAIL:
#endif
BURN_SRAM_FAIL:
kfree(cfg_buf);
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, int type)
{
int ret = 0;
I("%s,Entering - total FW size=%d\n", __func__, (int)fw->size);
g_core_fp.fp_register_write(pzf_op->addr_system_reset,
pzf_op->data_system_reset, 4);
g_core_fp.fp_sense_off(false);
if ((int)fw->size > HX64K) {
ret = himax_zf_part_info(fw, type);
} else {
/* first 48K */
ret = himax_sram_write_crc_check(pzf_op->data_sram_start_addr,
&fw->data[0], HX_48K_SZ);
if (ret != 0)
E("%s, HW CRC FAIL - Main SRAM 48K\n", __func__);
/*config info*/
if (G_POWERONOF == 1) {
ret = himax_sram_write_crc_check(pzf_op->data_cfg_info,
&fw->data[0xC000], 128);
if (ret != 0)
E("Config info CRC Fail!\n");
} else {
g_core_fp.fp_clean_sram_0f(pzf_op->data_cfg_info,
128, 2);
}
if (G_POWERONOF == 1) {
ret = himax_sram_write_crc_check(pzf_op->data_fw_cfg_1,
&fw->data[0xC0FE], 528);
if (ret != 0)
E("FW config 1 CRC Fail!\n");
} else {
g_core_fp.fp_clean_sram_0f(pzf_op->data_fw_cfg_1,
528, 1);
}
if (G_POWERONOF == 1) {
ret = himax_sram_write_crc_check(pzf_op->data_fw_cfg_3,
&fw->data[0xCA00], 128);
if (ret != 0)
E("FW config 3 CRC Fail!\n");
} else {
g_core_fp.fp_clean_sram_0f(pzf_op->data_fw_cfg_3,
128, 2);
}
/*ADC config*/
if (G_POWERONOF == 1) {
ret = himax_sram_write_crc_check(pzf_op->data_adc_cfg_1,
&fw->data[0xD640], 1200);
if (ret != 0)
E("ADC config 1 CRC Fail!\n");
} else {
g_core_fp.fp_clean_sram_0f(pzf_op->data_adc_cfg_1,
1200, 2);
}
if (G_POWERONOF == 1) {
ret = himax_sram_write_crc_check(pzf_op->data_adc_cfg_2,
&fw->data[0xD320], 800);
if (ret != 0)
E("ADC config 2 CRC Fail!\n");
} else {
g_core_fp.fp_clean_sram_0f(pzf_op->data_adc_cfg_2,
800, 2);
}
/*mapping table*/
if (G_POWERONOF == 1) {
ret = himax_sram_write_crc_check(pzf_op->data_map_table,
&fw->data[0xE000], 1536);
if (ret != 0)
E("Mapping table CRC Fail!\n");
} else {
g_core_fp.fp_clean_sram_0f(pzf_op->data_map_table,
1536, 2);
}
}
I("%s, End\n", __func__);
return ret;
}
int hx_0f_op_file_dirly(char *file_name)
{
const struct firmware *fw = NULL;
int ret = -1;
int type = 0; /* FW type: 0, normal; 1, MPAP */
if (g_f_0f_updat == 1) {
W("%s: Other thread is updating now!\n", __func__);
return ret;
}
g_f_0f_updat = 1;
I("%s: Preparing to update %s!\n", __func__, file_name);
ret = request_firmware(&fw, file_name, private_ts->dev);
if (ret < 0) {
#if defined(__EMBEDDED_FW__)
fw = &g_embedded_fw;
I("%s: Not find FW in userspace, use embedded FW(size:%zu)\n",
__func__, g_embedded_fw.size);
#else
E("%s: request firmware fail, code[%d]!!\n", __func__, ret);
goto END;
#endif
}
if (strcmp(file_name, MPAP_FWNAME) == 0)
type = 1;
ret = g_core_fp.fp_firmware_update_0f(fw, type);
release_firmware(fw);
if (ret < 0)
goto END;
#if !defined(HX_ALG_OVERLAY)
if (type == 1)
g_core_fp.fp_turn_on_mp_func(1);
else
g_core_fp.fp_turn_on_mp_func(0);
g_core_fp.fp_reload_disable(0);
g_core_fp.fp_power_on_init();
#endif
END:
g_f_0f_updat = 0;
I("%s: END\n", __func__);
return ret;
}
static int himax_mcu_0f_excp_check(void)
{
return NO_ERR;
}
#if defined(HX_0F_DEBUG)
void himax_mcu_read_sram_0f(const struct firmware *fw_entry,
uint8_t *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;
uint8_t tmp_addr[4];
uint8_t *temp_info_data = NULL;
int *not_same_buff = NULL;
I("%s, Entering\n", __func__);
/*g_core_fp.fp_burst_enable(1);*/
total_size = read_len;
total_size_temp = read_len;
#if defined(HX_SPI_OPERATION)
if (read_len > 2048)
max_bus_size = 2048;
else
max_bus_size = read_len;
#else
if (read_len > 240)
max_bus_size = 240;
else
max_bus_size = read_len;
#endif
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("%s, total size=%d, bus size=%d, read time=%d\n",
__func__,
total_size,
max_bus_size,
total_read_times);
tmp_addr[3] = addr[3];
tmp_addr[2] = addr[2];
tmp_addr[1] = addr[1];
tmp_addr[0] = addr[0];
I("%s,addr[3]=0x%2X,addr[2]=0x%2X,addr[1]=0x%2X,addr[0]=0x%2X\n",
__func__,
tmp_addr[3],
tmp_addr[2],
tmp_addr[1],
tmp_addr[0]);
temp_info_data = kcalloc(total_size, sizeof(uint8_t), GFP_KERNEL);
if (temp_info_data == NULL) {
E("%s, Failed to allocate temp_info_data\n", __func__);
goto err_malloc_temp_info_data;
}
not_same_buff = kcalloc(total_size, sizeof(int), GFP_KERNEL);
if (not_same_buff == NULL) {
E("%s, Failed to allocate not_same_buff\n", __func__);
goto err_malloc_not_same_buff;
}
g_core_fp.fp_burst_enable(1);
for (i = 0; i < (total_read_times); i++) {
if (total_size_temp >= max_bus_size) {
g_core_fp.fp_register_read(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(tmp_addr,
&temp_info_data[i*max_bus_size],
total_size_temp % max_bus_size);
}
address = ((i+1) * max_bus_size);
tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF);
if (tmp_addr[0] < addr[0])
tmp_addr[1] = addr[1]
+ (uint8_t) ((address>>8) & 0x00FF) + 1;
else
tmp_addr[1] = addr[1]
+ (uint8_t) ((address>>8) & 0x00FF);
/*msleep (10);*/
}
I("%s,READ Start, start_index = %d\n", __func__, 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("%s,READ END,Not Same count=%d\n", __func__, 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\n", 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\n", i, temp_info_data[i]);
}
}
I("%s,READ END, Not Same count=%d\n", __func__, 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(uint8_t *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 file *fn; */
/* struct filename *vts_name; */
uint8_t tmp_addr[4];
uint8_t *temp_info_data;
I("%s, Entering\n", __func__);
/*g_core_fp.fp_burst_enable(1);*/
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("%s, total size=%d\n", __func__, total_size);
tmp_addr[3] = addr[3];
tmp_addr[2] = addr[2];
tmp_addr[1] = addr[1];
tmp_addr[0] = addr[0];
I("%s:addr[3]=0x%2X,addr[2]=0x%2X,addr[1]=0x%2X,addr[0]=0x%2X\n",
__func__,
tmp_addr[3],
tmp_addr[2],
tmp_addr[1],
tmp_addr[0]);
temp_info_data = kcalloc(total_size, sizeof(uint8_t), GFP_KERNEL);
if (temp_info_data == NULL) {
E("%s, Failed to allocate temp_info_data\n", __func__);
return;
}
g_core_fp.fp_burst_enable(1);
for (i = 0; i < (total_read_times); i++) {
if (total_size_temp >= max_bus_size) {
g_core_fp.fp_register_read(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(tmp_addr,
&temp_info_data[i*max_bus_size],
total_size_temp % max_bus_size);
}
address = ((i+1) * max_bus_size);
tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF);
tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF);
/*msleep (10);*/
}
I("%s,addr[3]=0x%2X,addr[2]=0x%2X,addr[1]=0x%2X,addr[0]=0x%2X\n",
__func__,
tmp_addr[3],
tmp_addr[2],
tmp_addr[1],
tmp_addr[0]);
/*for(i = 0;i<read_len;i++)
*{
* I("0x%2.2X, ", temp_info_data[i]);
*
* if (i > 0 && i%16 == 15)
* printk("\n");
*}
*/
kfree(temp_info_data);
I("%s, END\n", __func__);
}
void himax_mcu_firmware_read_0f(const struct firmware *fw_entry, int type)
{
uint8_t tmp_addr[4];
I("%s, Entering\n", __func__);
if (type == 0) { /* first 48K */
g_core_fp.fp_read_sram_0f(fw_entry,
pzf_op->data_sram_start_addr,
0,
HX_48K_SZ);
g_core_fp.fp_read_all_sram(tmp_addr, 0xC000);
} else { /*last 16k*/
g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_cfg_info,
0xC000, 132);
/*FW config*/
g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_fw_cfg_1,
0xC0FE, 484);
g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_fw_cfg_2,
0xC9DE, 36);
g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_fw_cfg_3,
0xCA00, 72);
/*ADC config*/
g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_adc_cfg_1,
0xD630, 1188);
g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_adc_cfg_2,
0xD318, 792);
/*mapping table*/
g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_map_table,
0xE000, 1536);
/* set n frame=0*/
g_core_fp.fp_read_sram_0f(fw_entry, pfw_op->addr_set_frame_addr,
0xC30C, 4);
}
I("%s, END\n", __func__);
}
#endif
#if defined(HX_CODE_OVERLAY)
int himax_mcu_0f_overlay(int ovl_type, int mode)
{
return NO_ERR;
}
#endif
#endif
/* CORE_INIT */
/* init start */
static void himax_mcu_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_flash_write_burst = himax_mcu_flash_write_burst;
*/
/*
* g_core_fp.fp_flash_write_burst_lenth =
* himax_mcu_flash_write_burst_lenth;
*/
g_core_fp.fp_register_write = himax_mcu_register_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;
#if defined(HX_ULTRA_LOW_POWER)
g_core_fp.fp_ulpm_in = himax_mcu_ulpm_in;
g_core_fp.fp_black_gest_ctrl = himax_mcu_black_gest_ctrl;
#endif
g_core_fp.fp_set_SMWP_enable = himax_mcu_set_SMWP_enable;
g_core_fp.fp_set_HSEN_enable = himax_mcu_set_HSEN_enable;
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_chip_self_test = himax_mcu_chip_self_test;
g_core_fp.fp_idle_mode = himax_mcu_idle_mode;
g_core_fp.fp_reload_disable = himax_mcu_reload_disable;
g_core_fp.fp_check_chip_version = himax_mcu_check_chip_version;
g_core_fp.fp_read_ic_trigger_type = himax_mcu_read_ic_trigger_type;
g_core_fp.fp_read_i2c_status = himax_mcu_read_i2c_status;
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_calculateChecksum = himax_mcu_calculateChecksum;
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._clr_fw_reord_dd_sts = hx_clr_fw_reord_dd_sts;
g_core_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._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;
#if defined(HX_RST_PIN_FUNC)
g_core_fp.fp_pin_reset = himax_mcu_pin_reset;
g_core_fp.fp_ic_reset = himax_mcu_ic_reset;
#endif
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_calcTouchDataSize;
/*g_core_fp.fp_reload_config = himax_mcu_reload_config;*/
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_diag_parse_raw_data = himax_mcu_diag_parse_raw_data;
#if defined(HX_EXCP_RECOVERY)
g_core_fp.fp_ic_excp_recovery = himax_mcu_ic_excp_recovery;
g_core_fp.fp_excp_ic_reset = himax_mcu_excp_ic_reset;
#endif
#if defined(HX_SMART_WAKEUP)\
|| defined(HX_HIGH_SENSE)\
|| defined(HX_USB_DETECT_GLOBAL)
g_core_fp.fp_resend_cmd_func = himax_mcu_resend_cmd_func;
#endif
#if defined(HX_TP_PROC_GUEST_INFO)
g_core_fp.guest_info_get_status = himax_guest_info_get_status;
g_core_fp.read_guest_info = hx_read_guest_info;
#endif
/* CORE_DRIVER */
g_core_fp.fp_turn_on_mp_func = hx_turn_on_mp_func;
#if defined(HX_ZERO_FLASH)
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;
#if defined(HX_0F_DEBUG)
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;
#endif
#if defined(HX_CODE_OVERLAY)
g_core_fp.fp_0f_overlay = himax_mcu_0f_overlay;
#endif
#endif
}
void himax_mcu_in_cmd_struct_free(void)
{
pic_op = NULL;
pfw_op = NULL;
pflash_op = NULL;
psram_op = NULL;
pdriver_op = NULL;
kfree(g_internal_buffer);
g_internal_buffer = NULL;
#if defined(HX_ZERO_FLASH)
kfree(g_core_cmd_op->zf_op);
g_core_cmd_op->zf_op = NULL;
#endif
kfree(g_core_cmd_op->driver_op);
g_core_cmd_op->driver_op = NULL;
kfree(g_core_cmd_op->sram_op);
g_core_cmd_op->sram_op = NULL;
kfree(g_core_cmd_op->flash_op);
g_core_cmd_op->flash_op = NULL;
kfree(g_core_cmd_op->fw_op);
g_core_cmd_op->fw_op = NULL;
kfree(g_core_cmd_op->ic_op);
g_core_cmd_op->ic_op = NULL;
kfree(g_core_cmd_op);
g_core_cmd_op = NULL;
I("%s: release completed\n", __func__);
}
int himax_mcu_in_cmd_struct_init(void)
{
int err = 0;
I("%s: Entering!\n", __func__);
himax_mcu_cmd_struct_free = himax_mcu_in_cmd_struct_free;
g_core_cmd_op = kzalloc(sizeof(struct himax_core_command_operation),
GFP_KERNEL);
if (g_core_cmd_op == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_fail;
}
g_core_cmd_op->ic_op = kzalloc(sizeof(struct ic_operation), GFP_KERNEL);
if (g_core_cmd_op->ic_op == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_ic_op_fail;
}
g_core_cmd_op->fw_op = kzalloc(sizeof(struct fw_operation), GFP_KERNEL);
if (g_core_cmd_op->fw_op == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_fw_op_fail;
}
g_core_cmd_op->flash_op = kzalloc(sizeof(struct flash_operation),
GFP_KERNEL);
if (g_core_cmd_op->flash_op == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_flash_op_fail;
}
g_core_cmd_op->sram_op = kzalloc(sizeof(struct sram_operation),
GFP_KERNEL);
if (g_core_cmd_op->sram_op == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_sram_op_fail;
}
g_core_cmd_op->driver_op = kzalloc(sizeof(struct driver_operation),
GFP_KERNEL);
if (g_core_cmd_op->driver_op == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_driver_op_fail;
}
pic_op = g_core_cmd_op->ic_op;
pfw_op = g_core_cmd_op->fw_op;
pflash_op = g_core_cmd_op->flash_op;
psram_op = g_core_cmd_op->sram_op;
pdriver_op = g_core_cmd_op->driver_op;
#if defined(HX_ZERO_FLASH)
g_core_cmd_op->zf_op = kzalloc(sizeof(struct zf_operation),
GFP_KERNEL);
if (g_core_cmd_op->zf_op == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_zf_op_fail;
}
pzf_op = g_core_cmd_op->zf_op;
#endif
/* command[2] + address[4] + data[] */
g_internal_buffer = kzalloc(sizeof(uint8_t)*(HX_MAX_WRITE_SZ+6),
GFP_KERNEL);
if (g_internal_buffer == NULL) {
err = -ENOMEM;
goto err_g_core_cmd_op_g_internal_buffer_fail;
}
himax_mcu_fp_init();
return NO_ERR;
err_g_core_cmd_op_g_internal_buffer_fail:
#if defined(HX_ZERO_FLASH)
kfree(g_core_cmd_op->zf_op);
g_core_cmd_op->zf_op = NULL;
err_g_core_cmd_op_zf_op_fail:
#endif
kfree(g_core_cmd_op->driver_op);
g_core_cmd_op->driver_op = NULL;
err_g_core_cmd_op_driver_op_fail:
kfree(g_core_cmd_op->sram_op);
g_core_cmd_op->sram_op = NULL;
err_g_core_cmd_op_sram_op_fail:
kfree(g_core_cmd_op->flash_op);
g_core_cmd_op->flash_op = NULL;
err_g_core_cmd_op_flash_op_fail:
kfree(g_core_cmd_op->fw_op);
g_core_cmd_op->fw_op = NULL;
err_g_core_cmd_op_fw_op_fail:
kfree(g_core_cmd_op->ic_op);
g_core_cmd_op->ic_op = NULL;
err_g_core_cmd_op_ic_op_fail:
kfree(g_core_cmd_op);
g_core_cmd_op = NULL;
err_g_core_cmd_op_fail:
return err;
}
EXPORT_SYMBOL(himax_mcu_in_cmd_struct_init);
void himax_mcu_in_cmd_init(void)
{
I("%s: Entering!\n", __func__);
/* CORE_IC */
himax_parse_assign_cmd(ic_adr_ahb_addr_byte_0,
pic_op->addr_ahb_addr_byte_0,
sizeof(pic_op->addr_ahb_addr_byte_0));
himax_parse_assign_cmd(ic_adr_ahb_rdata_byte_0,
pic_op->addr_ahb_rdata_byte_0,
sizeof(pic_op->addr_ahb_rdata_byte_0));
himax_parse_assign_cmd(ic_adr_ahb_access_direction,
pic_op->addr_ahb_access_direction,
sizeof(pic_op->addr_ahb_access_direction));
himax_parse_assign_cmd(ic_adr_conti, pic_op->addr_conti,
sizeof(pic_op->addr_conti));
himax_parse_assign_cmd(ic_adr_incr4, pic_op->addr_incr4,
sizeof(pic_op->addr_incr4));
himax_parse_assign_cmd(ic_adr_i2c_psw_lb, pic_op->adr_i2c_psw_lb,
sizeof(pic_op->adr_i2c_psw_lb));
himax_parse_assign_cmd(ic_adr_i2c_psw_ub, pic_op->adr_i2c_psw_ub,
sizeof(pic_op->adr_i2c_psw_ub));
himax_parse_assign_cmd(ic_cmd_ahb_access_direction_read,
pic_op->data_ahb_access_direction_read,
sizeof(pic_op->data_ahb_access_direction_read));
himax_parse_assign_cmd(ic_cmd_conti, pic_op->data_conti,
sizeof(pic_op->data_conti));
himax_parse_assign_cmd(ic_cmd_incr4, pic_op->data_incr4,
sizeof(pic_op->data_incr4));
himax_parse_assign_cmd(ic_cmd_i2c_psw_lb, pic_op->data_i2c_psw_lb,
sizeof(pic_op->data_i2c_psw_lb));
himax_parse_assign_cmd(ic_cmd_i2c_psw_ub, pic_op->data_i2c_psw_ub,
sizeof(pic_op->data_i2c_psw_ub));
himax_parse_assign_cmd(ic_adr_tcon_on_rst, pic_op->addr_tcon_on_rst,
sizeof(pic_op->addr_tcon_on_rst));
himax_parse_assign_cmd(ic_addr_adc_on_rst, pic_op->addr_adc_on_rst,
sizeof(pic_op->addr_adc_on_rst));
himax_parse_assign_cmd(ic_adr_psl, pic_op->addr_psl,
sizeof(pic_op->addr_psl));
himax_parse_assign_cmd(ic_adr_cs_central_state,
pic_op->addr_cs_central_state,
sizeof(pic_op->addr_cs_central_state));
himax_parse_assign_cmd(ic_cmd_rst, pic_op->data_rst,
sizeof(pic_op->data_rst));
himax_parse_assign_cmd(ic_adr_osc_en, pic_op->adr_osc_en,
sizeof(pic_op->adr_osc_en));
himax_parse_assign_cmd(ic_adr_osc_pw, pic_op->adr_osc_pw,
sizeof(pic_op->adr_osc_pw));
/* CORE_IC */
/* CORE_FW */
himax_parse_assign_cmd(fw_addr_system_reset,
pfw_op->addr_system_reset,
sizeof(pfw_op->addr_system_reset));
himax_parse_assign_cmd(fw_addr_ctrl_fw,
pfw_op->addr_ctrl_fw_isr,
sizeof(pfw_op->addr_ctrl_fw_isr));
himax_parse_assign_cmd(fw_addr_flag_reset_event,
pfw_op->addr_flag_reset_event,
sizeof(pfw_op->addr_flag_reset_event));
himax_parse_assign_cmd(fw_addr_hsen_enable,
pfw_op->addr_hsen_enable,
sizeof(pfw_op->addr_hsen_enable));
himax_parse_assign_cmd(fw_addr_smwp_enable,
pfw_op->addr_smwp_enable,
sizeof(pfw_op->addr_smwp_enable));
himax_parse_assign_cmd(fw_addr_program_reload_from,
pfw_op->addr_program_reload_from,
sizeof(pfw_op->addr_program_reload_from));
himax_parse_assign_cmd(fw_addr_program_reload_to,
pfw_op->addr_program_reload_to,
sizeof(pfw_op->addr_program_reload_to));
himax_parse_assign_cmd(fw_addr_program_reload_page_write,
pfw_op->addr_program_reload_page_write,
sizeof(pfw_op->addr_program_reload_page_write));
himax_parse_assign_cmd(fw_addr_raw_out_sel,
pfw_op->addr_raw_out_sel,
sizeof(pfw_op->addr_raw_out_sel));
himax_parse_assign_cmd(fw_addr_reload_status,
pfw_op->addr_reload_status,
sizeof(pfw_op->addr_reload_status));
himax_parse_assign_cmd(fw_addr_reload_crc32_result,
pfw_op->addr_reload_crc32_result,
sizeof(pfw_op->addr_reload_crc32_result));
himax_parse_assign_cmd(fw_addr_reload_addr_from,
pfw_op->addr_reload_addr_from,
sizeof(pfw_op->addr_reload_addr_from));
himax_parse_assign_cmd(fw_addr_reload_addr_cmd_beat,
pfw_op->addr_reload_addr_cmd_beat,
sizeof(pfw_op->addr_reload_addr_cmd_beat));
himax_parse_assign_cmd(fw_addr_selftest_addr_en,
pfw_op->addr_selftest_addr_en,
sizeof(pfw_op->addr_selftest_addr_en));
himax_parse_assign_cmd(fw_addr_criteria_addr,
pfw_op->addr_criteria_addr,
sizeof(pfw_op->addr_criteria_addr));
himax_parse_assign_cmd(fw_addr_set_frame_addr,
pfw_op->addr_set_frame_addr,
sizeof(pfw_op->addr_set_frame_addr));
himax_parse_assign_cmd(fw_addr_selftest_result_addr,
pfw_op->addr_selftest_result_addr,
sizeof(pfw_op->addr_selftest_result_addr));
himax_parse_assign_cmd(fw_addr_sorting_mode_en,
pfw_op->addr_sorting_mode_en,
sizeof(pfw_op->addr_sorting_mode_en));
himax_parse_assign_cmd(fw_addr_fw_mode_status,
pfw_op->addr_fw_mode_status,
sizeof(pfw_op->addr_fw_mode_status));
himax_parse_assign_cmd(fw_addr_icid_addr,
pfw_op->addr_icid_addr,
sizeof(pfw_op->addr_icid_addr));
himax_parse_assign_cmd(fw_addr_fw_ver_addr,
pfw_op->addr_fw_ver_addr,
sizeof(pfw_op->addr_fw_ver_addr));
himax_parse_assign_cmd(fw_addr_fw_cfg_addr,
pfw_op->addr_fw_cfg_addr,
sizeof(pfw_op->addr_fw_cfg_addr));
himax_parse_assign_cmd(fw_addr_fw_vendor_addr,
pfw_op->addr_fw_vendor_addr,
sizeof(pfw_op->addr_fw_vendor_addr));
himax_parse_assign_cmd(fw_addr_cus_info,
pfw_op->addr_cus_info,
sizeof(pfw_op->addr_cus_info));
himax_parse_assign_cmd(fw_addr_proj_info,
pfw_op->addr_proj_info,
sizeof(pfw_op->addr_proj_info));
himax_parse_assign_cmd(fw_addr_fw_state_addr,
pfw_op->addr_fw_state_addr,
sizeof(pfw_op->addr_fw_state_addr));
himax_parse_assign_cmd(fw_addr_fw_dbg_msg_addr,
pfw_op->addr_fw_dbg_msg_addr,
sizeof(pfw_op->addr_fw_dbg_msg_addr));
himax_parse_assign_cmd(fw_addr_chk_fw_status,
pfw_op->addr_chk_fw_status,
sizeof(pfw_op->addr_chk_fw_status));
himax_parse_assign_cmd(fw_addr_dd_handshak_addr,
pfw_op->addr_dd_handshak_addr,
sizeof(pfw_op->addr_dd_handshak_addr));
himax_parse_assign_cmd(fw_addr_dd_data_addr,
pfw_op->addr_dd_data_addr,
sizeof(pfw_op->addr_dd_data_addr));
himax_parse_assign_cmd(fw_addr_clr_fw_record_dd_sts,
pfw_op->addr_clr_fw_record_dd_sts,
sizeof(pfw_op->addr_clr_fw_record_dd_sts));
himax_parse_assign_cmd(fw_addr_ap_notify_fw_sus,
pfw_op->addr_ap_notify_fw_sus,
sizeof(pfw_op->addr_ap_notify_fw_sus));
himax_parse_assign_cmd(fw_data_ap_notify_fw_sus_en,
pfw_op->data_ap_notify_fw_sus_en,
sizeof(pfw_op->data_ap_notify_fw_sus_en));
himax_parse_assign_cmd(fw_data_ap_notify_fw_sus_dis,
pfw_op->data_ap_notify_fw_sus_dis,
sizeof(pfw_op->data_ap_notify_fw_sus_dis));
himax_parse_assign_cmd(fw_data_system_reset,
pfw_op->data_system_reset,
sizeof(pfw_op->data_system_reset));
himax_parse_assign_cmd(fw_data_safe_mode_release_pw_active,
pfw_op->data_safe_mode_release_pw_active,
sizeof(pfw_op->data_safe_mode_release_pw_active));
himax_parse_assign_cmd(fw_data_clear,
pfw_op->data_clear,
sizeof(pfw_op->data_clear));
himax_parse_assign_cmd(fw_data_clear,
pfw_op->data_clear,
sizeof(pfw_op->data_clear));
himax_parse_assign_cmd(fw_data_fw_stop,
pfw_op->data_fw_stop,
sizeof(pfw_op->data_fw_stop));
himax_parse_assign_cmd(fw_data_safe_mode_release_pw_reset,
pfw_op->data_safe_mode_release_pw_reset,
sizeof(pfw_op->data_safe_mode_release_pw_reset));
himax_parse_assign_cmd(fw_data_program_reload_start,
pfw_op->data_program_reload_start,
sizeof(pfw_op->data_program_reload_start));
himax_parse_assign_cmd(fw_data_program_reload_compare,
pfw_op->data_program_reload_compare,
sizeof(pfw_op->data_program_reload_compare));
himax_parse_assign_cmd(fw_data_program_reload_break,
pfw_op->data_program_reload_break,
sizeof(pfw_op->data_program_reload_break));
himax_parse_assign_cmd(fw_data_selftest_request,
pfw_op->data_selftest_request,
sizeof(pfw_op->data_selftest_request));
himax_parse_assign_cmd(fw_data_criteria_aa_top,
pfw_op->data_criteria_aa_top,
sizeof(pfw_op->data_criteria_aa_top));
himax_parse_assign_cmd(fw_data_criteria_aa_bot,
pfw_op->data_criteria_aa_bot,
sizeof(pfw_op->data_criteria_aa_bot));
himax_parse_assign_cmd(fw_data_criteria_key_top,
pfw_op->data_criteria_key_top,
sizeof(pfw_op->data_criteria_key_top));
himax_parse_assign_cmd(fw_data_criteria_key_bot,
pfw_op->data_criteria_key_bot,
sizeof(pfw_op->data_criteria_key_bot));
himax_parse_assign_cmd(fw_data_criteria_avg_top,
pfw_op->data_criteria_avg_top,
sizeof(pfw_op->data_criteria_avg_top));
himax_parse_assign_cmd(fw_data_criteria_avg_bot,
pfw_op->data_criteria_avg_bot,
sizeof(pfw_op->data_criteria_avg_bot));
himax_parse_assign_cmd(fw_data_set_frame,
pfw_op->data_set_frame,
sizeof(pfw_op->data_set_frame));
himax_parse_assign_cmd(fw_data_selftest_ack_hb,
pfw_op->data_selftest_ack_hb,
sizeof(pfw_op->data_selftest_ack_hb));
himax_parse_assign_cmd(fw_data_selftest_ack_lb,
pfw_op->data_selftest_ack_lb,
sizeof(pfw_op->data_selftest_ack_lb));
himax_parse_assign_cmd(fw_data_selftest_pass,
pfw_op->data_selftest_pass,
sizeof(pfw_op->data_selftest_pass));
himax_parse_assign_cmd(fw_data_normal_cmd,
pfw_op->data_normal_cmd,
sizeof(pfw_op->data_normal_cmd));
himax_parse_assign_cmd(fw_data_normal_status,
pfw_op->data_normal_status,
sizeof(pfw_op->data_normal_status));
himax_parse_assign_cmd(fw_data_sorting_cmd,
pfw_op->data_sorting_cmd,
sizeof(pfw_op->data_sorting_cmd));
himax_parse_assign_cmd(fw_data_sorting_status,
pfw_op->data_sorting_status,
sizeof(pfw_op->data_sorting_status));
himax_parse_assign_cmd(fw_data_dd_request,
pfw_op->data_dd_request,
sizeof(pfw_op->data_dd_request));
himax_parse_assign_cmd(fw_data_dd_ack,
pfw_op->data_dd_ack,
sizeof(pfw_op->data_dd_ack));
himax_parse_assign_cmd(fw_data_idle_dis_pwd,
pfw_op->data_idle_dis_pwd,
sizeof(pfw_op->data_idle_dis_pwd));
himax_parse_assign_cmd(fw_data_idle_en_pwd,
pfw_op->data_idle_en_pwd,
sizeof(pfw_op->data_idle_en_pwd));
himax_parse_assign_cmd(fw_data_rawdata_ready_hb,
pfw_op->data_rawdata_ready_hb,
sizeof(pfw_op->data_rawdata_ready_hb));
himax_parse_assign_cmd(fw_data_rawdata_ready_lb,
pfw_op->data_rawdata_ready_lb,
sizeof(pfw_op->data_rawdata_ready_lb));
himax_parse_assign_cmd(fw_addr_ahb_addr,
pfw_op->addr_ahb_addr,
sizeof(pfw_op->addr_ahb_addr));
himax_parse_assign_cmd(fw_data_ahb_dis,
pfw_op->data_ahb_dis,
sizeof(pfw_op->data_ahb_dis));
himax_parse_assign_cmd(fw_data_ahb_en,
pfw_op->data_ahb_en,
sizeof(pfw_op->data_ahb_en));
himax_parse_assign_cmd(fw_addr_event_addr,
pfw_op->addr_event_addr,
sizeof(pfw_op->addr_event_addr));
himax_parse_assign_cmd(fw_usb_detect_addr,
pfw_op->addr_usb_detect,
sizeof(pfw_op->addr_usb_detect));
#if defined(HX_ULTRA_LOW_POWER)
himax_parse_assign_cmd(fw_addr_ulpm_33, pfw_op->addr_ulpm_33,
sizeof(pfw_op->addr_ulpm_33));
himax_parse_assign_cmd(fw_addr_ulpm_34, pfw_op->addr_ulpm_34,
sizeof(pfw_op->addr_ulpm_34));
himax_parse_assign_cmd(fw_data_ulpm_11, pfw_op->data_ulpm_11,
sizeof(pfw_op->data_ulpm_11));
himax_parse_assign_cmd(fw_data_ulpm_22, pfw_op->data_ulpm_22,
sizeof(pfw_op->data_ulpm_22));
himax_parse_assign_cmd(fw_data_ulpm_33, pfw_op->data_ulpm_33,
sizeof(pfw_op->data_ulpm_33));
himax_parse_assign_cmd(fw_data_ulpm_aa, pfw_op->data_ulpm_aa,
sizeof(pfw_op->data_ulpm_aa));
#endif
/* CORE_FW */
/* CORE_FLASH */
himax_parse_assign_cmd(flash_addr_spi200_trans_fmt,
pflash_op->addr_spi200_trans_fmt,
sizeof(pflash_op->addr_spi200_trans_fmt));
himax_parse_assign_cmd(flash_addr_spi200_trans_ctrl,
pflash_op->addr_spi200_trans_ctrl,
sizeof(pflash_op->addr_spi200_trans_ctrl));
himax_parse_assign_cmd(flash_addr_spi200_fifo_rst,
pflash_op->addr_spi200_fifo_rst,
sizeof(pflash_op->addr_spi200_fifo_rst));
himax_parse_assign_cmd(flash_addr_spi200_flash_speed,
pflash_op->addr_spi200_flash_speed,
sizeof(pflash_op->addr_spi200_flash_speed));
himax_parse_assign_cmd(flash_addr_spi200_rst_status,
pflash_op->addr_spi200_rst_status,
sizeof(pflash_op->addr_spi200_rst_status));
himax_parse_assign_cmd(flash_addr_spi200_cmd,
pflash_op->addr_spi200_cmd,
sizeof(pflash_op->addr_spi200_cmd));
himax_parse_assign_cmd(flash_addr_spi200_addr,
pflash_op->addr_spi200_addr,
sizeof(pflash_op->addr_spi200_addr));
himax_parse_assign_cmd(flash_addr_spi200_data,
pflash_op->addr_spi200_data,
sizeof(pflash_op->addr_spi200_data));
himax_parse_assign_cmd(flash_addr_spi200_bt_num,
pflash_op->addr_spi200_bt_num,
sizeof(pflash_op->addr_spi200_bt_num));
himax_parse_assign_cmd(flash_data_spi200_trans_fmt,
pflash_op->data_spi200_trans_fmt,
sizeof(pflash_op->data_spi200_trans_fmt));
himax_parse_assign_cmd(flash_data_spi200_txfifo_rst,
pflash_op->data_spi200_txfifo_rst,
sizeof(pflash_op->data_spi200_txfifo_rst));
himax_parse_assign_cmd(flash_data_spi200_rxfifo_rst,
pflash_op->data_spi200_rxfifo_rst,
sizeof(pflash_op->data_spi200_rxfifo_rst));
himax_parse_assign_cmd(flash_data_spi200_trans_ctrl_1,
pflash_op->data_spi200_trans_ctrl_1,
sizeof(pflash_op->data_spi200_trans_ctrl_1));
himax_parse_assign_cmd(flash_data_spi200_trans_ctrl_2,
pflash_op->data_spi200_trans_ctrl_2,
sizeof(pflash_op->data_spi200_trans_ctrl_2));
himax_parse_assign_cmd(flash_data_spi200_trans_ctrl_3,
pflash_op->data_spi200_trans_ctrl_3,
sizeof(pflash_op->data_spi200_trans_ctrl_3));
himax_parse_assign_cmd(flash_data_spi200_trans_ctrl_4,
pflash_op->data_spi200_trans_ctrl_4,
sizeof(pflash_op->data_spi200_trans_ctrl_4));
himax_parse_assign_cmd(flash_data_spi200_trans_ctrl_5,
pflash_op->data_spi200_trans_ctrl_5,
sizeof(pflash_op->data_spi200_trans_ctrl_5));
himax_parse_assign_cmd(flash_data_spi200_trans_ctrl_6,
pflash_op->data_spi200_trans_ctrl_6,
sizeof(pflash_op->data_spi200_trans_ctrl_6));
himax_parse_assign_cmd(flash_data_spi200_trans_ctrl_7,
pflash_op->data_spi200_trans_ctrl_7,
sizeof(pflash_op->data_spi200_trans_ctrl_7));
himax_parse_assign_cmd(flash_data_spi200_cmd_1,
pflash_op->data_spi200_cmd_1,
sizeof(pflash_op->data_spi200_cmd_1));
himax_parse_assign_cmd(flash_data_spi200_cmd_2,
pflash_op->data_spi200_cmd_2,
sizeof(pflash_op->data_spi200_cmd_2));
himax_parse_assign_cmd(flash_data_spi200_cmd_3,
pflash_op->data_spi200_cmd_3,
sizeof(pflash_op->data_spi200_cmd_3));
himax_parse_assign_cmd(flash_data_spi200_cmd_4,
pflash_op->data_spi200_cmd_4,
sizeof(pflash_op->data_spi200_cmd_4));
himax_parse_assign_cmd(flash_data_spi200_cmd_5,
pflash_op->data_spi200_cmd_5,
sizeof(pflash_op->data_spi200_cmd_5));
himax_parse_assign_cmd(flash_data_spi200_cmd_6,
pflash_op->data_spi200_cmd_6,
sizeof(pflash_op->data_spi200_cmd_6));
himax_parse_assign_cmd(flash_data_spi200_cmd_7,
pflash_op->data_spi200_cmd_7,
sizeof(pflash_op->data_spi200_cmd_7));
himax_parse_assign_cmd(flash_data_spi200_cmd_8,
pflash_op->data_spi200_cmd_8,
sizeof(pflash_op->data_spi200_cmd_8));
himax_parse_assign_cmd(flash_data_spi200_addr,
pflash_op->data_spi200_addr,
sizeof(pflash_op->data_spi200_addr));
/* CORE_FLASH */
/* CORE_SRAM */
/* sram start*/
himax_parse_assign_cmd(sram_adr_mkey,
psram_op->addr_mkey,
sizeof(psram_op->addr_mkey));
himax_parse_assign_cmd(sram_adr_rawdata_addr,
psram_op->addr_rawdata_addr,
sizeof(psram_op->addr_rawdata_addr));
himax_parse_assign_cmd(sram_adr_rawdata_end,
psram_op->addr_rawdata_end,
sizeof(psram_op->addr_rawdata_end));
himax_parse_assign_cmd(sram_passwrd_start,
psram_op->passwrd_start,
sizeof(psram_op->passwrd_start));
himax_parse_assign_cmd(sram_passwrd_end,
psram_op->passwrd_end,
sizeof(psram_op->passwrd_end));
/* sram end*/
/* CORE_SRAM */
/* CORE_DRIVER */
himax_parse_assign_cmd(driver_addr_fw_define_flash_reload,
pdriver_op->addr_fw_define_flash_reload,
sizeof(pdriver_op->addr_fw_define_flash_reload));
himax_parse_assign_cmd(driver_addr_fw_define_2nd_flash_reload,
pdriver_op->addr_fw_define_2nd_flash_reload,
sizeof(pdriver_op->addr_fw_define_2nd_flash_reload));
himax_parse_assign_cmd(driver_addr_fw_define_int_is_edge,
pdriver_op->addr_fw_define_int_is_edge,
sizeof(pdriver_op->addr_fw_define_int_is_edge));
himax_parse_assign_cmd(driver_addr_fw_define_rxnum_txnum,
pdriver_op->addr_fw_define_rxnum_txnum,
sizeof(pdriver_op->addr_fw_define_rxnum_txnum));
himax_parse_assign_cmd(driver_addr_fw_define_maxpt_xyrvs,
pdriver_op->addr_fw_define_maxpt_xyrvs,
sizeof(pdriver_op->addr_fw_define_maxpt_xyrvs));
himax_parse_assign_cmd(driver_addr_fw_define_x_y_res,
pdriver_op->addr_fw_define_x_y_res,
sizeof(pdriver_op->addr_fw_define_x_y_res));
himax_parse_assign_cmd(driver_data_df_rx,
pdriver_op->data_df_rx,
sizeof(pdriver_op->data_df_rx));
himax_parse_assign_cmd(driver_data_df_tx,
pdriver_op->data_df_tx,
sizeof(pdriver_op->data_df_tx));
himax_parse_assign_cmd(driver_data_df_pt,
pdriver_op->data_df_pt,
sizeof(pdriver_op->data_df_pt));
himax_parse_assign_cmd(driver_data_fw_define_flash_reload_dis,
pdriver_op->data_fw_define_flash_reload_dis,
sizeof(pdriver_op->data_fw_define_flash_reload_dis));
himax_parse_assign_cmd(driver_data_fw_define_flash_reload_en,
pdriver_op->data_fw_define_flash_reload_en,
sizeof(pdriver_op->data_fw_define_flash_reload_en));
himax_parse_assign_cmd(
driver_data_fw_define_rxnum_txnum_maxpt_sorting,
pdriver_op->data_fw_define_rxnum_txnum_maxpt_sorting,
sizeof(pdriver_op->data_fw_define_rxnum_txnum_maxpt_sorting));
himax_parse_assign_cmd(
driver_data_fw_define_rxnum_txnum_maxpt_normal,
pdriver_op->data_fw_define_rxnum_txnum_maxpt_normal,
sizeof(pdriver_op->data_fw_define_rxnum_txnum_maxpt_normal));
/* CORE_DRIVER */
#if defined(HX_ZERO_FLASH)
himax_parse_assign_cmd(zf_data_dis_flash_reload,
pzf_op->data_dis_flash_reload,
sizeof(pzf_op->data_dis_flash_reload));
himax_parse_assign_cmd(zf_addr_system_reset,
pzf_op->addr_system_reset,
sizeof(pzf_op->addr_system_reset));
himax_parse_assign_cmd(zf_data_system_reset,
pzf_op->data_system_reset,
sizeof(pzf_op->data_system_reset));
himax_parse_assign_cmd(zf_data_sram_start_addr,
pzf_op->data_sram_start_addr,
sizeof(pzf_op->data_sram_start_addr));
himax_parse_assign_cmd(zf_data_cfg_info,
pzf_op->data_cfg_info,
sizeof(pzf_op->data_cfg_info));
himax_parse_assign_cmd(zf_data_fw_cfg_1,
pzf_op->data_fw_cfg_1,
sizeof(pzf_op->data_fw_cfg_1));
himax_parse_assign_cmd(zf_data_fw_cfg_2,
pzf_op->data_fw_cfg_2,
sizeof(pzf_op->data_fw_cfg_2));
himax_parse_assign_cmd(zf_data_fw_cfg_3,
pzf_op->data_fw_cfg_3,
sizeof(pzf_op->data_fw_cfg_3));
himax_parse_assign_cmd(zf_data_adc_cfg_1,
pzf_op->data_adc_cfg_1,
sizeof(pzf_op->data_adc_cfg_1));
himax_parse_assign_cmd(zf_data_adc_cfg_2,
pzf_op->data_adc_cfg_2,
sizeof(pzf_op->data_adc_cfg_2));
himax_parse_assign_cmd(zf_data_adc_cfg_3,
pzf_op->data_adc_cfg_3,
sizeof(pzf_op->data_adc_cfg_3));
himax_parse_assign_cmd(zf_data_map_table,
pzf_op->data_map_table,
sizeof(pzf_op->data_map_table));
/* himax_parse_assign_cmd(zf_data_mode_switch,
* pzf_op->data_mode_switch,
* sizeof(pzf_op->data_mode_switch));
*/
himax_parse_assign_cmd(zf_addr_sts_chk,
pzf_op->addr_sts_chk,
sizeof(pzf_op->addr_sts_chk));
himax_parse_assign_cmd(zf_data_activ_sts,
pzf_op->data_activ_sts,
sizeof(pzf_op->data_activ_sts));
himax_parse_assign_cmd(zf_addr_activ_relod,
pzf_op->addr_activ_relod,
sizeof(pzf_op->addr_activ_relod));
himax_parse_assign_cmd(zf_data_activ_in,
pzf_op->data_activ_in,
sizeof(pzf_op->data_activ_in));
#endif
}
EXPORT_SYMBOL(himax_mcu_in_cmd_init);
/* init end*/
/* CORE_INIT */