3214 lines
92 KiB
C
Executable file
3214 lines
92 KiB
C
Executable file
/*
|
|
* ILITEK Touch IC driver
|
|
*
|
|
* Copyright (C) 2011 ILI Technology Corporation.
|
|
*
|
|
* Author: Dicky Chiang <dicky_chiang@ilitek.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "ilitek_v3.h"
|
|
|
|
#if IS_ENABLED(CONFIG_PRIZE_HARDWARE_INFO)
|
|
#include "../../../misc/mediatek/prize/hardware_info/hardware_info.h"
|
|
extern struct hardware_info current_tp_info;
|
|
#endif
|
|
|
|
#define PROTOCL_VER_NUM 8
|
|
static struct ilitek_protocol_info protocol_info[PROTOCL_VER_NUM] = {
|
|
/* length -> fw, protocol, tp, key, panel, core, func, window, cdc, mp_info */
|
|
[0] = {PROTOCOL_VER_500, 4, 4, 14, 30, 5, 5, 2, 8, 3, 8},
|
|
[1] = {PROTOCOL_VER_510, 4, 3, 14, 30, 5, 5, 3, 8, 3, 8},
|
|
[2] = {PROTOCOL_VER_520, 4, 4, 14, 30, 5, 5, 3, 8, 3, 8},
|
|
[3] = {PROTOCOL_VER_530, 9, 4, 14, 30, 5, 5, 3, 8, 3, 8},
|
|
[4] = {PROTOCOL_VER_540, 9, 4, 14, 30, 5, 5, 3, 8, 15, 8},
|
|
[5] = {PROTOCOL_VER_550, 9, 4, 14, 30, 5, 5, 3, 8, 15, 14},
|
|
[6] = {PROTOCOL_VER_560, 9, 4, 14, 30, 5, 5, 3, 8, 15, 14},
|
|
[7] = {PROTOCOL_VER_570, 9, 4, 14, 30, 5, 5, 3, 8, 15, 14},
|
|
};
|
|
|
|
struct ilitek_ic_func_ctrl func_ctrl[FUNC_CTRL_NUM] = {
|
|
/* cmd[3] = cmd, func, ctrl */
|
|
/* rec_state 0:disable, 1: enable, 2: ignore record */
|
|
[0] = {"sense", {0x1, 0x1, 0x0}, 3, 0x0, 2, 0xFF},
|
|
[1] = {"sleep", {0x1, 0x2, 0x0}, 3, 0x0, 2, 0xFF},
|
|
[2] = {"glove", {0x1, 0x6, 0x0}, 3, 0x0, 0, 0xFF},
|
|
[3] = {"stylus", {0x1, 0x7, 0x0}, 3, 0x0, 0, 0xFF},
|
|
[4] = {"lpwg", {0x1, 0xA, 0x0}, 3, 0x0, 2, 0xFF},
|
|
[5] = {"proximity", {0x1, 0x10, 0x0}, 3, 0x0, 0, 0xFF},
|
|
[6] = {"plug", {0x1, 0x11, 0x0}, 3, 0x1, 0, 0xFF},
|
|
[7] = {"edge_palm", {0x1, 0x12, 0x0}, 3, 0x1, 0, 0xFF},
|
|
[8] = {"lock_point", {0x1, 0x13, 0x0}, 3, 0x0, 0, 0xFF},
|
|
[9] = {"active", {0x1, 0x14, 0x0}, 3, 0x0, 2, 0xFF},
|
|
[10] = {"idle", {0x1, 0x19, 0x0}, 3, 0x1, 0, 0xFF},
|
|
[11] = {"gesture_demo_en", {0x1, 0x16, 0x0}, 3, 0x0, 0, 0xFF},
|
|
[12] = {"tp_recore", {0x1, 0x18, 0x0}, 3, 0x0, 2, 0xFF},
|
|
[13] = {"knock_en", {0x1, 0xA, 0x8, 0x03, 0x0, 0x0}, 6, 0xFF, 0, 0xFF},
|
|
[14] = {"int_trigger", {0x1, 0x1B, 0x0}, 3, 0x0, 2, 0xFF},
|
|
[15] = {"ear_phone", {0x1, 0x17, 0x0}, 3, 0x0, 0, 0xFF},
|
|
[16] = {"knuckle", {0x1, 0xF, 0x0}, 3, 0x0, 0, 0xFF},
|
|
};
|
|
|
|
static int ili_check_polling_bist(u8 GroupNumIdx, u32 SramRsultStatus)
|
|
{
|
|
u32 Bist_Sram_Fail = 0xFFFFFFFF;
|
|
int CheckCount = 10, ret = 0;
|
|
u32 bist_done = 0, bist_fail = 0, bist_fail_bus = 0;
|
|
|
|
ili_ice_mode_write(0x46000, 0, 4);
|
|
|
|
ili_ice_mode_read(0x04600C, &bist_done, 1);
|
|
ili_ice_mode_read(0x04600D, &bist_fail, 1);
|
|
|
|
/* Check Clear MBist Status */
|
|
if (ilits->sram_para.check_failbus == ENABLE) {
|
|
ili_ice_mode_read(0x046010, &bist_fail_bus, sizeof(bist_fail_bus));
|
|
|
|
if (((bist_done & BIT(0)) != 0x00) || ((bist_fail & BIT(0)) != 0x01) || (bist_fail_bus != 0xFFFFFFFF)) {
|
|
ILI_ERR("Clear MBist Fail\n");
|
|
ILI_ERR("bist_done = 0x%X, bist_fail = 0x%X, bist_fail_bus = 0x%X\n", bist_done, bist_fail, bist_fail_bus);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (((bist_done & BIT(0)) != 0x00) || ((bist_fail & BIT(0)) != 0x01)) {
|
|
ILI_ERR("Clear MBist Fail\n");
|
|
ILI_ERR("bist_done = 0x%X, bist_fail = 0x%X\n", bist_done, bist_fail);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
ili_ice_mode_write(0x046000, 0x00000001, 4);
|
|
ili_ice_mode_write(0x046000, 0x00000101, 4);
|
|
|
|
while (CheckCount > 0) {
|
|
mdelay(2);
|
|
ili_ice_mode_read(0x04600C, &bist_done, 1);
|
|
|
|
if ((bist_done & BIT(0)) == 0x01) {
|
|
break;
|
|
}
|
|
CheckCount--;
|
|
}
|
|
|
|
if (CheckCount <= 0) {
|
|
ILI_ERR("Check Bist_Done TimeOut! bist_done = 0x%X\n", bist_done);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
ili_ice_mode_read(0x04600D, &bist_fail, 1);
|
|
|
|
if(ilits->sram_para.sram_group_en == ENABLE) {
|
|
ili_ice_mode_read(ilits->sram_para.read_addr, &Bist_Sram_Fail, 4);
|
|
|
|
if ((Bist_Sram_Fail & SramRsultStatus) > 0) {
|
|
ILI_ERR("Check Bist Fail Flag Fail!\n");
|
|
ILI_ERR("Bist Sram Fail Status = 0x%X, Sram Rsult Status = 0x%X\n", Bist_Sram_Fail, SramRsultStatus);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (ilits->sram_para.check_failbus == ENABLE) {
|
|
ili_ice_mode_read(0x046010, &bist_fail_bus, sizeof(bist_fail_bus));
|
|
|
|
if (((bist_fail & BIT(0)) != 0x00) || (bist_fail_bus != 0x00000000)) {
|
|
ILI_ERR("Check Bist Fail Flag Fail\n");
|
|
ILI_DBG("bist_fail = %d, bist_fail_bus = %d\n", bist_fail, bist_fail_bus);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
} else {
|
|
if ((bist_fail & BIT(0)) != 0x00) {
|
|
ILI_ERR("Check Bist Fail Flag Fail\n");
|
|
ILI_DBG("bist_fail = %d\n", bist_fail);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static void ili_sram_test(u32 MaxAddr, u32 MinAddr)
|
|
{
|
|
u32 SetValue;
|
|
|
|
/* Strat Sram Test */
|
|
ili_ice_mode_write_by_mode(0x40004, 0x00000001, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x40010, 0x00009878, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x40088, 0x00006B8A, 4, BOTH);
|
|
|
|
/* Set MinAddr */
|
|
ili_ice_mode_write_by_mode(0x46038, MinAddr, 2, BOTH);
|
|
|
|
/* March_LR */
|
|
SetValue = ((MaxAddr << 16) & 0xFFFF0000) | 0xFF00;
|
|
|
|
ili_ice_mode_write_by_mode(0x46000, 0x00010000, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x46004, SetValue, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x46014, 0xA4409800, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x46018, 0xB480F590, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x4601C, 0x9000F560, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x46020, 0x9280C460, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x46024, 0x0000, 2, BOTH);
|
|
}
|
|
|
|
static int ili_sram_by_partial_area_test(void)
|
|
{
|
|
int ret = 0;
|
|
u8 nSramNumIdx;
|
|
|
|
for(nSramNumIdx = 0; nSramNumIdx < ilits->sram_para.group_num; nSramNumIdx++) {
|
|
ILI_DBG("Sram Partial Area : %s\n", ilits->sram_para.strSramPartialArea[nSramNumIdx]);
|
|
|
|
ili_ice_mode_write_by_mode(ilits->sram_para.write_addr, ilits->sram_para.SramPartialAreaTest_en[nSramNumIdx], 4, BOTH);
|
|
ILI_DBG("Write Sram Partial Area En : 0x%X\n", ilits->sram_para.SramPartialAreaTest_en[nSramNumIdx]);
|
|
|
|
ili_sram_test(ilits->sram_para.MaxAddr, ilits->sram_para.MinAddr);
|
|
|
|
if (ili_check_polling_bist(nSramNumIdx, ilits->sram_para.SramResult[nSramNumIdx]) < 0) {
|
|
ILI_ERR("Check March_LR Bist Fail during partial area test\n");
|
|
ret = -1;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int ili_ic_cascade_polling_bist(void)
|
|
{
|
|
int retry = 10, ret = 0;
|
|
u32 bist_done = 0, bist_fail = 0, bist_fail_bus = 0;
|
|
u32 bist_slave_done = 0, bist_slave_fail = 0, bist_slave_fail_bus = 0;
|
|
u32 pen_bist_fail_bus = 0, pen_bist_slave_fail_bus = 0;
|
|
|
|
ili_ice_mode_write_by_mode(0x046000, 0x000000, 4, BOTH);
|
|
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
ilits->i2c_addr_change = SLAVE;
|
|
ili_ice_mode_read(0x04600C, &bist_slave_done, sizeof(bist_slave_done));
|
|
ili_ice_mode_read(0x04600D, &bist_slave_fail, sizeof(bist_slave_fail));
|
|
|
|
|
|
ilits->i2c_addr_change = MASTER;
|
|
ili_ice_mode_read(0x04600C, &bist_done, sizeof(bist_done));
|
|
ili_ice_mode_read(0x04600D, &bist_fail, sizeof(bist_fail));
|
|
|
|
if (ilits->sram_para.check_failbus == ENABLE) {
|
|
ilits->i2c_addr_change = SLAVE;
|
|
ili_ice_mode_read(0x046010, &bist_slave_fail_bus, sizeof(bist_slave_fail_bus));
|
|
ili_ice_mode_read(0x046048, &pen_bist_slave_fail_bus, sizeof(pen_bist_slave_fail_bus));
|
|
|
|
ilits->i2c_addr_change = MASTER;
|
|
ili_ice_mode_read(0x046010, &bist_fail_bus, sizeof(bist_fail_bus));
|
|
ili_ice_mode_read(0x046048, &pen_bist_fail_bus, sizeof(pen_bist_fail_bus));
|
|
|
|
if (((bist_done & BIT(0)) != 0x00) || ((bist_fail & BIT(0)) != 0x01) || (bist_fail_bus != 0xFFFFFFFF)
|
|
|| ((bist_slave_done & BIT(0)) != 0x00) || ((bist_slave_fail & BIT(0)) != 0x01)
|
|
|| (bist_slave_fail_bus != 0xFFFFFFFF)) {
|
|
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_done = 0x%X, bist_fail = 0x%X, bist_fail_bus = 0x%X\n", bist_done, bist_fail, bist_fail_bus);
|
|
ILI_ERR("bist_slave_done = 0x%X, bist_slave_fail = 0x%X, bist_slave_fail_bus = 0x%X\n", bist_slave_done, bist_slave_fail, bist_slave_fail_bus);
|
|
ILI_ERR("pen_bist_fail_bus = 0x%X, pen_bist_slave_fail_bus = 0x%X\n", pen_bist_fail_bus, pen_bist_slave_fail_bus);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (((bist_done & BIT(0)) != 0x00) || ((bist_fail & BIT(0)) != 0x01) || ((bist_slave_done & BIT(0)) != 0x00)
|
|
|| ((bist_slave_fail & BIT(0)) != 0x01)) {
|
|
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_done = 0x%X, bist_fail = 0x%X\n", bist_done, bist_fail);
|
|
ILI_ERR("bist_slave_done = 0x%X, bist_slave_fail = 0x%X\n", bist_slave_done, bist_slave_fail);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
ili_ice_mode_write_by_mode(0x046000, 0x00000001, 4, BOTH);
|
|
ili_ice_mode_write_by_mode(0x046000, 0x00000101, 4, BOTH);
|
|
|
|
while (retry > 0) {
|
|
mdelay(10);
|
|
ilits->i2c_addr_change = SLAVE;
|
|
ili_ice_mode_read(0x04600C, &bist_slave_done, sizeof(bist_slave_done));
|
|
|
|
ilits->i2c_addr_change = MASTER;
|
|
ili_ice_mode_read(0x04600C, &bist_done, sizeof(bist_done));
|
|
ILI_ERR("bist_done = 0x%X, bist_slave_done = 0x%X\n", bist_done, bist_slave_done);
|
|
|
|
|
|
if (((bist_done & BIT(0)) == 0x01) && ((bist_slave_done & BIT(0)) == 0x01)) {
|
|
break;
|
|
}
|
|
retry--;
|
|
}
|
|
|
|
if (retry <= 0) {
|
|
ILI_DBG("SRAM TEST FAIL\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
ilits->i2c_addr_change = SLAVE;
|
|
ili_ice_mode_read(0x04600D, &bist_slave_fail, sizeof(bist_slave_fail));
|
|
|
|
ilits->i2c_addr_change = MASTER;
|
|
ili_ice_mode_read(0x04600D, &bist_fail, sizeof(bist_fail));
|
|
|
|
if (ilits->sram_para.check_failbus == ENABLE) {
|
|
ilits->i2c_addr_change = SLAVE;
|
|
ili_ice_mode_read(0x046010, &bist_slave_fail_bus, sizeof(bist_slave_fail_bus));
|
|
ili_ice_mode_read(0x046048, &pen_bist_slave_fail_bus, sizeof(pen_bist_slave_fail_bus));
|
|
|
|
ilits->i2c_addr_change = MASTER;
|
|
ili_ice_mode_read(0x046010, &bist_fail_bus, sizeof(bist_fail_bus));
|
|
ili_ice_mode_read(0x046048, &pen_bist_fail_bus, sizeof(pen_bist_fail_bus));
|
|
|
|
if (((bist_fail & BIT(0)) != 0x00) || (bist_fail_bus != 0x00000000) || (((bist_slave_fail & BIT(24)) >> 24) != 0x00)
|
|
|| (bist_slave_fail_bus != 0x00000000)) {
|
|
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_fail = 0x%X, bist_fail_bus = 0x%X\n", bist_fail, bist_fail_bus);
|
|
ILI_ERR("bist_slave_fail = 0x%X, bist_slave_fail_bus = 0x%X\n", bist_slave_fail, bist_slave_fail_bus);
|
|
ILI_ERR("pen_bist_fail_bus = 0x%X, pen_bist_slave_fail_bus = 0x%X\n", pen_bist_fail_bus, pen_bist_slave_fail_bus);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (((bist_fail & BIT(0)) != 0x00) || (((bist_slave_fail & BIT(24)) >> 24) != 0x00)) {
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_fail = 0x%X, bist_slave_fail = 0x%X\n", bist_fail, bist_slave_fail);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
#elif (TDDI_INTERFACE == BUS_SPI)
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x04600C, &bist_done, sizeof(bist_done));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &bist_slave_done, sizeof(bist_slave_done));
|
|
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x04600D, &bist_fail, sizeof(bist_fail));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &bist_slave_fail, sizeof(bist_slave_fail));
|
|
|
|
if (ilits->sram_para.check_failbus == ENABLE) {
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x046010, &bist_fail_bus, sizeof(bist_fail_bus));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &bist_slave_fail_bus, sizeof(bist_slave_fail_bus));
|
|
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x046048, &pen_bist_fail_bus, sizeof(pen_bist_fail_bus));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &pen_bist_slave_fail_bus, sizeof(pen_bist_slave_fail_bus));
|
|
|
|
if (((bist_done & BIT(0)) != 0x00) || ((bist_fail & BIT(0)) != 0x01) || (bist_fail_bus != 0xFFFFFFFF)
|
|
|| (((bist_slave_done & BIT(24)) >> 24) != 0x00) || (((bist_slave_fail & BIT(24)) >> 24) != 0x01)
|
|
|| (bist_slave_fail_bus != 0xFFFFFFFF)) {
|
|
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_done = 0x%X, bist_fail = 0x%X, bist_fail_bus = 0x%X\n", bist_done, bist_fail, bist_fail_bus);
|
|
ILI_ERR("bist_slave_done = 0x%X, bist_slave_fail = 0x%X, bist_slave_fail_bus = 0x%X\n", bist_slave_done, bist_slave_fail, bist_slave_fail_bus);
|
|
ILI_ERR("pen_bist_fail_bus = 0x%X, pen_bist_slave_fail_bus = 0x%X\n", pen_bist_fail_bus, pen_bist_slave_fail_bus);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (((bist_done & BIT(0)) != 0x00) || ((bist_fail & BIT(0)) != 0x01) || (((bist_slave_done & BIT(24) >> 24)) != 0x00)
|
|
|| (((bist_slave_fail & BIT(24)) >> 24) != 0x01)) {
|
|
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_done = 0x%X, bist_fail = 0x%X\n", bist_done, bist_fail);
|
|
ILI_ERR("bist_slave_done = 0x%X, bist_slave_fail = 0x%X\n", bist_slave_done, bist_slave_fail);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
ili_ice_mode_write(0x046000, 0x00000001, 4);
|
|
ili_ice_mode_write(0x046000, 0x00000101, 4);
|
|
|
|
while (retry > 0) {
|
|
mdelay(10);
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x04600C, &bist_done, sizeof(bist_done));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &bist_slave_done, sizeof(bist_slave_done));
|
|
ILI_DBG("bist_done = 0x%X, bist_slave_done = 0x%X\n", bist_done, bist_slave_done);
|
|
|
|
if (((bist_done & BIT(0)) == 0x01) && (((bist_slave_done & BIT(24)) >> 24) == 0x01)) {
|
|
break;
|
|
}
|
|
retry--;
|
|
}
|
|
|
|
if (retry <= 0) {
|
|
ILI_DBG("SRAM TEST FAIL\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x04600D, &bist_fail, sizeof(bist_fail));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &bist_slave_fail, sizeof(bist_slave_fail));
|
|
|
|
if (ilits->sram_para.check_failbus == ENABLE) {
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x046010, &bist_fail_bus, sizeof(bist_fail_bus));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &bist_slave_fail_bus, sizeof(bist_slave_fail_bus));
|
|
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x046048, &pen_bist_fail_bus, sizeof(pen_bist_fail_bus));
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, &pen_bist_slave_fail_bus, sizeof(pen_bist_slave_fail_bus));
|
|
|
|
if (((bist_fail & BIT(0)) != 0x00) || (bist_fail_bus != 0x00000000) || (((bist_slave_fail & BIT(24)) >> 24) != 0x00)
|
|
|| (bist_slave_fail_bus != 0x00000000)) {
|
|
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_fail = 0x%X, bist_fail_bus = 0x%X\n", bist_fail, bist_fail_bus);
|
|
ILI_ERR("bist_slave_fail = 0x%X, bist_slave_fail_bus = 0x%X\n", bist_slave_fail, bist_slave_fail_bus);
|
|
ILI_ERR("pen_bist_fail_bus = 0x%X, pen_bist_slave_fail_bus = 0x%X\n", pen_bist_fail_bus, pen_bist_slave_fail_bus);
|
|
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (((bist_fail & BIT(0)) != 0x00) || (((bist_slave_fail & BIT(24)) >> 24) != 0x00)) {
|
|
ILI_ERR("SRAM TEST FAIL\n");
|
|
ILI_ERR("bist_fail = 0x%X, bist_slave_fail = 0x%X\n", bist_fail, bist_slave_fail);
|
|
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
int ili_tddi_ic_sram_test()
|
|
{
|
|
int ret = 0;
|
|
|
|
ili_ice_mode_write_by_mode(0x047003, 0x00, 1, BOTH);
|
|
ili_ice_mode_write_by_mode(0x04001C, 0x01, 1, BOTH);
|
|
ili_ice_mode_write_by_mode(0x071001, 0x02, 1, BOTH);
|
|
ili_ice_mode_write_by_mode(0x071005, 0x3C, 1, BOTH);
|
|
ili_ice_mode_write_by_mode(0x046003, 0x00, 1, BOTH);
|
|
ili_ice_mode_write_by_mode(0x046000, 0x010001, 3, BOTH);
|
|
ili_ice_mode_write_by_mode(0x046002, 0x00, 1, BOTH);
|
|
|
|
if (ilits->sram_para.sram_group_en == ENABLE) {
|
|
ret = ili_sram_by_partial_area_test();
|
|
goto out;
|
|
}
|
|
|
|
ili_sram_test(ilits->sram_para.MaxAddr, ilits->sram_para.MinAddr);
|
|
|
|
if (ilits->cascade_info_block.nNum != 0) {
|
|
ret = ili_ic_cascade_polling_bist();
|
|
} else {
|
|
ret = ili_check_polling_bist(false, false);
|
|
}
|
|
out:
|
|
#if (TDDI_INTERFACE == BUS_SPI)
|
|
if (ilits->cascade_info_block.nNum != 0) {
|
|
ili_core_spi_setup(SPI_CLK);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
#ifdef ROI
|
|
int ili_config_knuckle_roi_ctrl(cmd_types cmd)
|
|
{
|
|
int ret = 0;
|
|
switch (cmd) {
|
|
case CMD_DISABLE:
|
|
ILI_DBG("knuckle roi disbale\n");
|
|
ret = ili_ic_func_ctrl("knuckle", cmd);
|
|
break;
|
|
case CMD_ENABLE:
|
|
ILI_DBG("knuckle roi enable\n");
|
|
ret = ili_ic_func_ctrl("knuckle", cmd);
|
|
break;
|
|
case CMD_STATUS:
|
|
ILI_DBG("knuckle roi read status\n");
|
|
ret = ili_ic_func_ctrl("knuckle", cmd);
|
|
break;
|
|
case CMD_ROI_DATA:
|
|
ILI_DBG("knuckle roi read data\n");
|
|
ret = ili_ic_func_ctrl("knuckle", cmd);
|
|
break;
|
|
default:
|
|
ILI_ERR("knuckle roi unknown cmd: %d\n", cmd);
|
|
return -EINVAL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ili_config_get_knuckle_roi_status(void)
|
|
{
|
|
int ret = 0;
|
|
u8 roi_status = 0;
|
|
|
|
ret = ili_config_knuckle_roi_ctrl(CMD_STATUS);
|
|
if (ret) {
|
|
ILI_ERR("config to read roi status failed\n");
|
|
return ret;
|
|
}
|
|
|
|
msleep(1);
|
|
ret = ilits->wrapper(NULL, 0, &roi_status, sizeof(roi_status), OFF, OFF);
|
|
if (ret) {
|
|
ILI_ERR("read data failed\n");
|
|
return ret;
|
|
}
|
|
|
|
ILI_INFO("roi %s\n", roi_status ? "enable" : "disable");
|
|
|
|
return roi_status;
|
|
}
|
|
#endif
|
|
|
|
static int ilitek_tddi_ic_check_info(u32 pid, u32 id)
|
|
{
|
|
ILI_INFO("ILITEK CHIP found.\n");
|
|
|
|
ilits->chip->pid = pid;
|
|
|
|
ilits->chip->reset_key = TDDI_WHOLE_CHIP_RST_WITH_FLASH_KEY;
|
|
ilits->chip->wtd_key = 0x9881;
|
|
|
|
if (((pid & 0xFFFFFF00) == ILI9881N_AA) || ((pid & 0xFFFFFF00) == ILI9881O_AA)) {
|
|
ilits->chip->dma_reset = ENABLE;
|
|
} else {
|
|
ilits->chip->dma_reset = DISABLE;
|
|
}
|
|
|
|
ilits->chip->no_bk_shift = RAWDATA_NO_BK_SHIFT;
|
|
ilits->chip->max_count = 0x1FFFF;
|
|
return 0;
|
|
}
|
|
|
|
int ili_ice_mode_bit_mask_write(u32 addr, u32 mask, u32 value)
|
|
{
|
|
int ret = 0;
|
|
u32 data = 0;
|
|
|
|
if (ili_ice_mode_read(addr, &data, sizeof(u32)) < 0) {
|
|
ILI_ERR("Read data error\n");
|
|
return -1;
|
|
}
|
|
|
|
data &= (~mask);
|
|
data |= (value & mask);
|
|
|
|
ILI_DBG("mask value data = %x\n", data);
|
|
|
|
ret = ili_ice_mode_write(addr, data, sizeof(u32));
|
|
if (ret < 0)
|
|
ILI_ERR("Failed to re-write data in ICE mode, ret = %d\n", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ili_ice_mode_write(u32 addr, u32 data, int len)
|
|
{
|
|
int ret = 0, i;
|
|
u8 txbuf[64] = {0};
|
|
|
|
if (!atomic_read(&ilits->ice_stat)) {
|
|
ILI_ERR("ice mode not enabled\n");
|
|
return -1;
|
|
}
|
|
|
|
txbuf[0] = 0x25;
|
|
txbuf[1] = (char)((addr & 0x000000FF) >> 0);
|
|
txbuf[2] = (char)((addr & 0x0000FF00) >> 8);
|
|
txbuf[3] = (char)((addr & 0x00FF0000) >> 16);
|
|
|
|
for (i = 0; i < len; i++)
|
|
txbuf[i + 4] = (char)(data >> (8 * i));
|
|
|
|
ret = ilits->wrapper(txbuf, len + 4, NULL, 0, OFF, OFF);
|
|
if (ret < 0)
|
|
ILI_ERR("Failed to write data in ice mode, ret = %d\n", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ili_ice_mode_read(u32 addr, u32 *data, int len)
|
|
{
|
|
int ret = 0;
|
|
u8 rxbuf[4] = {0};
|
|
u8 txbuf[4] = {0};
|
|
|
|
if (len > sizeof(u32)) {
|
|
ILI_ERR("ice mode read lenght = %d, must less than or equal to 4 bytes\n", len);
|
|
len = 4;
|
|
}
|
|
|
|
if (!atomic_read(&ilits->ice_stat)) {
|
|
ILI_ERR("ice mode not enabled\n");
|
|
return -1;
|
|
}
|
|
|
|
txbuf[0] = 0x25;
|
|
txbuf[1] = (char)((addr & 0x000000FF) >> 0);
|
|
txbuf[2] = (char)((addr & 0x0000FF00) >> 8);
|
|
txbuf[3] = (char)((addr & 0x00FF0000) >> 16);
|
|
|
|
ret = ilits->wrapper(txbuf, sizeof(txbuf), NULL, 0, OFF, OFF);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
ret = ilits->wrapper(NULL, 0, rxbuf, len, OFF, OFF);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
*data = 0;
|
|
if (len == 1)
|
|
*data = rxbuf[0];
|
|
else if (len == 2)
|
|
*data = (rxbuf[0] | rxbuf[1] << 8);
|
|
else if (len == 3)
|
|
*data = (rxbuf[0] | rxbuf[1] << 8 | rxbuf[2] << 16);
|
|
else
|
|
*data = (rxbuf[0] | rxbuf[1] << 8 | rxbuf[2] << 16 | rxbuf[3] << 24);
|
|
|
|
out:
|
|
if (ret < 0)
|
|
ILI_ERR("Failed to read data in ice mode, ret = %d\n", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void ili_cascade_sync_ctrl(bool mode)
|
|
{
|
|
bool stop = false, backup_addr = MASTER;
|
|
u8 cmd[2] = {0};
|
|
|
|
if (ilits->skip_sync_cmd) {
|
|
ILI_INFO("skip cascade sync, sync_mode = %d\n", mode);
|
|
return;
|
|
}
|
|
|
|
backup_addr = ilits->i2c_addr_change;
|
|
ilits->i2c_addr_change = MASTER;
|
|
|
|
if (mode == stop) {
|
|
cmd[0] = 0x10;
|
|
cmd[1] = 0x10;
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0) {
|
|
ILI_ERR("Failed to stop Sync Cascade\n");
|
|
} else {
|
|
atomic_set(&ilits->stop_sync_stat, ENABLE);
|
|
ILI_DBG("Stop Sync Cascade, Set atomic sync stat = %d\n", atomic_read(&ilits->stop_sync_stat));
|
|
}
|
|
|
|
mdelay(1);
|
|
} else {
|
|
cmd[0] = 0x10;
|
|
cmd[1] = 0x11;
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0) {
|
|
ILI_ERR("Failed to start Sync Cascade\n");
|
|
} else {
|
|
atomic_set(&ilits->stop_sync_stat, DISABLE);
|
|
ILI_DBG("Start Sync Cascade, Set atomic sync stat = %d\n", atomic_read(&ilits->stop_sync_stat));
|
|
}
|
|
}
|
|
ilits->i2c_addr_change = backup_addr;
|
|
}
|
|
|
|
int ili_ice_mode_ctrl(bool enable, bool mcu)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd_open[4] = {0x25, 0x62, 0x10, 0x18};
|
|
u8 cmd_close[4] = {0x1B, 0x62, 0x10, 0x18};
|
|
|
|
if (enable) {
|
|
if (atomic_read(&ilits->ice_stat)) {
|
|
ILI_INFO("ice mode already enabled\n");
|
|
return 0;
|
|
}
|
|
|
|
/* Cascade Stop Sync */
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_CASCADE)
|
|
if (ilits->cascade_ctrl_mode == BOTH) {
|
|
if (ilits->i2c_addr_change == SLAVE && atomic_read(&ilits->stop_sync_stat) == DISABLE) {
|
|
ili_cascade_sync_ctrl(false);
|
|
}
|
|
} else {
|
|
if (atomic_read(&ilits->stop_sync_stat) == DISABLE) {
|
|
ili_cascade_sync_ctrl(false);
|
|
}
|
|
}
|
|
#elif (TDDI_INTERFACE == BUS_SPI && ENABLE_CASCADE)
|
|
if (atomic_read(&ilits->stop_sync_stat) == DISABLE) {
|
|
ili_cascade_sync_ctrl(false);
|
|
}
|
|
#endif
|
|
|
|
if (mcu)
|
|
cmd_open[0] = 0x1F;
|
|
|
|
atomic_set(&ilits->ice_stat, ENABLE);
|
|
|
|
if (ilits->wrapper(cmd_open, sizeof(cmd_open), NULL, 0, OFF, OFF) < 0) {
|
|
ILI_ERR("write ice mode cmd error\n");
|
|
atomic_set(&ilits->ice_stat, DISABLE);
|
|
}
|
|
ilits->pll_clk_wakeup = false;
|
|
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if (ilits->ice_flash_cs_ctrl && !mcu) {
|
|
if (ili_ice_mode_write(FLASH_BASED_ADDR, 0x1, 1) < 0)
|
|
ILI_ERR("Write cs high failed\n"); /* CS high */
|
|
if (ili_ice_mode_write(FLASH0_dual_mode, 0x0, 1) < 0)
|
|
ILI_ERR("Write daul mode close failed\n"); /* daul mode close */
|
|
} else {
|
|
ILI_INFO("ignore ice mode flash cs control\n");
|
|
}
|
|
#endif
|
|
} else {
|
|
if (!atomic_read(&ilits->ice_stat)) {
|
|
ILI_INFO("ice mode already disabled\n");
|
|
return 0;
|
|
}
|
|
#if (TDDI_INTERFACE == BUS_SPI && ENABLE_CASCADE && !ENABLE_SPICASCADE_V2)
|
|
/* Slave exit ice mode */
|
|
if (ili_mspi_write_slave_register(CONTROL_SLAVE_EXIT_ICE_ADDR, 0, 0) < 0) {
|
|
ILI_ERR("Disable Slave ICE mode Fail\n");
|
|
}
|
|
#endif
|
|
ret = ilits->wrapper(cmd_close, sizeof(cmd_close), NULL, 0, OFF, OFF);
|
|
if (ret < 0) {
|
|
ILI_ERR("Exit to ICE Mode failed !!\n");
|
|
atomic_set(&ilits->ice_stat, ENABLE);
|
|
} else {
|
|
atomic_set(&ilits->ice_stat, DISABLE);
|
|
#if (!ENABLE_CASCADE)
|
|
ilits->pll_clk_wakeup = true;
|
|
#endif
|
|
atomic_set(&ilits->ignore_report, END);
|
|
}
|
|
|
|
/* Cascade Start Sync */
|
|
#if ENABLE_CASCADE
|
|
if (atomic_read(&ilits->stop_sync_stat) == ENABLE) {
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if ((ilits->cascade_ctrl_mode == BOTH && ilits->i2c_addr_change == MASTER)
|
|
|| (ilits->cascade_ctrl_mode != BOTH)) {
|
|
ilits->pll_clk_wakeup = true;
|
|
ili_cascade_sync_ctrl(true);
|
|
}
|
|
#else
|
|
ilits->pll_clk_wakeup = true;
|
|
ili_cascade_sync_ctrl(true);
|
|
#endif
|
|
}
|
|
#endif
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_CASCADE)
|
|
if (atomic_read(&ilits->stop_sync_stat) == ENABLE) {
|
|
if ((ilits->cascade_ctrl_mode == BOTH && ilits->i2c_addr_change == MASTER)
|
|
|| (ilits->cascade_ctrl_mode != BOTH)) {
|
|
ilits->pll_clk_wakeup = true;
|
|
ili_cascade_sync_ctrl(true);
|
|
}
|
|
}
|
|
#elif (TDDI_INTERFACE == BUS_SPI && ENABLE_CASCADE)
|
|
if (atomic_read(&ilits->stop_sync_stat) == ENABLE) {
|
|
ilits->pll_clk_wakeup = true;
|
|
ili_cascade_sync_ctrl(true);
|
|
}
|
|
#endif
|
|
}
|
|
ILI_INFO("%s ICE mode, mcu on = %d\n", (enable ? "Enable" : "Disable"), mcu);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ili_ice_mode_ctrl_by_mode_spi(bool enable, bool mcu, int mode)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (ilits->cascade_info_block.nNum != 0) {
|
|
if (mode == BOTH && enable == ENABLE) {
|
|
ret = ili_set_bypass_mode(mcu);
|
|
} else {
|
|
ret = ili_ice_mode_ctrl(enable, mcu);
|
|
if (ret < 0) {
|
|
ILI_ERR("Failed to write ice mode\n");
|
|
}
|
|
}
|
|
} else {
|
|
ret = ili_ice_mode_ctrl(enable, mcu);
|
|
if (ret < 0) {
|
|
ILI_ERR("Failed to write ice mode\n");
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ili_ice_mode_ctrl_by_mode_i2c(bool enable, bool mcu, int mode)
|
|
{
|
|
int ret = 0;
|
|
if (ilits->cascade_info_block.nNum != 0) {
|
|
ili_ice_mode_ctrl_by_mode(enable, mcu, mode);
|
|
} else {
|
|
ret = ili_ice_mode_ctrl(enable, mcu);
|
|
if (ret < 0) {
|
|
ILI_ERR("Failed to write ice mode\n");
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ili_ice_mode_ctrl_by_mode(bool enable, bool mcu, int mode)
|
|
{
|
|
int ret = 0;
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_CASCADE)
|
|
ilits->cascade_ctrl_mode = mode;
|
|
switch (mode) {
|
|
case SLAVE:
|
|
case BOTH:
|
|
ilits->i2c_addr_change = SLAVE;
|
|
if (ili_ice_mode_ctrl(enable, mcu) < 0) {
|
|
ILI_ERR("Failed to write Slave ice mode\n");
|
|
ret = -1;
|
|
} else {
|
|
ILI_DBG("Slave %s ice mode\n", enable ? "Enable" : "Disable");
|
|
}
|
|
if (mode == SLAVE) {
|
|
ilits->i2c_addr_change = MASTER;
|
|
break;
|
|
} else {
|
|
if (enable == ENABLE)
|
|
atomic_set(&ilits->ice_stat, DISABLE);
|
|
else
|
|
atomic_set(&ilits->ice_stat, ENABLE);
|
|
}
|
|
case MASTER:
|
|
ilits->i2c_addr_change = MASTER;
|
|
if (ili_ice_mode_ctrl(enable, mcu) < 0) {
|
|
ILI_ERR("Failed to write Master ice mode\n");
|
|
ret = -1;
|
|
} else {
|
|
ILI_DBG("Master %s ice mode\n", enable ? "Enable" : "Disable");
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
ilits->cascade_ctrl_mode = MASTER;
|
|
#else
|
|
if (ili_ice_mode_ctrl(enable, mcu) < 0) {
|
|
ILI_ERR("Failed to write ice mode\n");
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int ili_ice_mode_write_by_mode(u32 addr, u32 data, int len, int mode)
|
|
{
|
|
int ret = 1;
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_CASCADE)
|
|
switch (mode) {
|
|
case SLAVE:
|
|
case BOTH:
|
|
ilits->i2c_addr_change = SLAVE;
|
|
if (ili_ice_mode_write(addr, data, len) < 0) {
|
|
ILI_ERR("Failed to write Slave, addr: 0x%X\n", addr);
|
|
ret = -1;
|
|
}
|
|
if (mode == SLAVE) {
|
|
ilits->i2c_addr_change = MASTER;
|
|
break;
|
|
}
|
|
case MASTER:
|
|
ilits->i2c_addr_change = MASTER;
|
|
if (ili_ice_mode_write(addr, data, len) < 0) {
|
|
ILI_ERR("Failed to write Master, addr: 0x%X\n", addr);
|
|
ret = -1;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
#else
|
|
#if (ENABLE_SPICASCADE_V2)
|
|
if (mode == SLAVE) {
|
|
ili_ice_slave_write_register(addr, data, len);
|
|
} else {
|
|
if (ili_ice_mode_write(addr, data, len) < 0) {
|
|
ILI_ERR("Failed to write addr: 0x%X\n", addr);
|
|
ret = -1;
|
|
}
|
|
}
|
|
#else
|
|
if (ili_ice_mode_write(addr, data, len) < 0) {
|
|
ILI_ERR("Failed to write addr: 0x%X\n", addr);
|
|
ret = -1;
|
|
}
|
|
#endif
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int ili_ice_mode_read_by_mode(u32 addr, u32 *data, int len, int mode)
|
|
{
|
|
int ret = 1;
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_CASCADE)
|
|
switch (mode) {
|
|
case SLAVE:
|
|
case BOTH:
|
|
ilits->i2c_addr_change = SLAVE;
|
|
if (ili_ice_mode_read(addr, data, len) < 0) {
|
|
ILI_ERR("Failed to read Slave, addr: 0x%x\n", addr);
|
|
ret = -1;
|
|
} else {
|
|
ILI_DBG("Slave [READ]:addr = 0x%06x, read = 0x%08x\n", addr, *data);
|
|
}
|
|
if (mode == SLAVE) {
|
|
ilits->i2c_addr_change = MASTER;
|
|
break;
|
|
}
|
|
case MASTER:
|
|
ilits->i2c_addr_change = MASTER;
|
|
if (ili_ice_mode_read(addr, data, len) < 0) {
|
|
ILI_ERR("Failed to read Master, addr: 0x%x\n", addr);
|
|
ret = -1;
|
|
} else {
|
|
ILI_DBG("Master [READ]:addr = 0x%06x, read = 0x%08x\n", addr, *data);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
#else
|
|
if (ili_ice_mode_read(addr, data, len) < 0) {
|
|
ILI_ERR("Failed to write addr: 0x%x\n", addr);
|
|
ret = -1;
|
|
} else {
|
|
ILI_DBG("[READ]:addr = 0x%06x, read = 0x%08x\n", addr, *data);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
static void ili_mspi_init(void)
|
|
{
|
|
if (ili_ice_mode_write(MSPI_REG, 0x01, 1) < 0)
|
|
ILI_ERR("Write MSPI_REG failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_TRIG_BY_DMA_ADDR, 0x101, 2) < 0)
|
|
ILI_ERR("Write MSPI_TRIG_BY_DMA_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_CLOCK_ADDR, 0x02, 1) < 0)
|
|
ILI_ERR("Write MSPI_CLOCK_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_CS_ADDR, 0x01, 1) < 0)
|
|
ILI_ERR("Write MSPI_CS_ADDR failed\n");
|
|
}
|
|
|
|
static void ili_dma_write_setting(void)
|
|
{
|
|
if (ili_ice_mode_write(DMA_ONE_CLEAR_ADDR, 0x02, 1) < 0)
|
|
ILI_ERR("Write DMA_ONE_CLEAR_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(SRC_ONE_ADDR, 0x308D0, 3) < 0)
|
|
ILI_ERR("Write SRC_ONE_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(SRC_ONE_SET_ADDR, 0x82000004, sizeof(u32)) < 0)
|
|
ILI_ERR("Write SRC_ONE_SET_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(SRC_TWO_EN_ADDR, 0x00, 1) < 0)
|
|
ILI_ERR("Write SRC_TWO_EN_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(DEST_ADDR, 0x6205C, 3) < 0)
|
|
ILI_ERR("Write DEST_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(DEST_SET_ADDR, 0x82000000, sizeof(u32)) < 0)
|
|
ILI_ERR("Write DEST_SET_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(TRIG_SEL_MSPI_ADDR, 0x0D, 1) < 0)
|
|
ILI_ERR("Write TRIG_SEL_MSPI_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(DMA_ONE_GROUP_ADDR, 0x00, 1) < 0)
|
|
ILI_ERR("Write DMA_ONE_GROUP_ADDR failed\n");
|
|
}
|
|
|
|
|
|
|
|
static void ili_trigger_mspi(void)
|
|
{
|
|
u8 BusyCnt = 50;
|
|
u32 BusyData;
|
|
|
|
if (ili_ice_mode_write(MSPI_CS_ADDR, 0x00, 1) < 0)
|
|
ILI_ERR("Write MSPI_CS_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_REG, 0x0F, 1) < 0)
|
|
ILI_ERR("Write MSPI_REG failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_TRIGGER_ADDR, 0x01, 1) < 0)
|
|
ILI_ERR("Write WRITE_BUF_ADDR failed\n");
|
|
|
|
/* Polling Done Flag */
|
|
while (BusyCnt > 0) {
|
|
if (ili_ice_mode_read(MSPI_DONE_FLAG_ADDR, &BusyData, 1) < 0)
|
|
ILI_ERR("Read MSPI_DONE_FLAG_ADDR failed\n");
|
|
|
|
if ( (BusyData & BIT(0)) == 0x01) {
|
|
break;
|
|
} else {
|
|
ILI_ERR("MSPI Busy : 0x%X\n", BusyData);
|
|
}
|
|
|
|
mdelay(1);
|
|
BusyCnt--;
|
|
}
|
|
|
|
if (ili_ice_mode_write(MSPI_DONE_FLAG_ADDR, 0x01, 1) < 0)
|
|
ILI_ERR("Read MSPI_DONE_FLAG_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_CS_ADDR, 0x01, 1) < 0)
|
|
ILI_ERR("Write MSPI_CS_ADDR failed\n");
|
|
}
|
|
|
|
void ili_mspi_set_slave_to_qual_mode(void)
|
|
{
|
|
u32 read_data, backup_mspi_init_en;
|
|
|
|
ili_mspi_init();
|
|
|
|
if (ili_ice_mode_read(MSPI_INIT_EN_ADDR, &backup_mspi_init_en, 1) < 0)
|
|
ILI_ERR("Read MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_INIT_EN_ADDR, backup_mspi_init_en & 0xFE, 1) < 0)
|
|
ILI_ERR("Write MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
ili_dma_write_setting();
|
|
|
|
/* Set Slave to Qual Mode */
|
|
if (ili_ice_mode_read(TRANSFER_CNT_ADDR, &read_data, sizeof(u32)) < 0)
|
|
ILI_ERR("Read TRANSFER_CNT_ADDR failed\n");
|
|
|
|
read_data = (read_data & 0xFFFC0000) + 0x18;
|
|
|
|
if (ili_ice_mode_write(TRANSFER_CNT_ADDR, read_data, sizeof(u32)) < 0)
|
|
ILI_ERR("Write TRANSFER_CNT_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(WRITE_BUF_SIZE_ADDR, &read_data, 2) < 0)
|
|
ILI_ERR("Read WRITE_BUF_SIZE_ADDR failed\n");
|
|
|
|
read_data = (read_data & 0xF800) + 0x18;
|
|
|
|
if (ili_ice_mode_write(WRITE_BUF_SIZE_ADDR, read_data, 2) < 0)
|
|
ILI_ERR("Write WRITE_BUF_SIZE_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(READ_BUF_SIZE_ADDR, &read_data, 2) < 0)
|
|
ILI_ERR("Read READ_BUF_SIZE_ADDR failed\n");
|
|
|
|
read_data = (read_data & 0xF800) + 0x00;
|
|
|
|
if (ili_ice_mode_write(READ_BUF_SIZE_ADDR, read_data, 2) < 0)
|
|
ILI_ERR("Write READ_BUF_SIZE_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(WRITE_BUF_ADDR, 0x40000040, sizeof(u32)) < 0)
|
|
ILI_ERR("Write WRITE_BUF_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(0x308D0, 0x4044000, sizeof(u32)) < 0)
|
|
ILI_ERR("Write failed\n");
|
|
|
|
if (ili_ice_mode_write(0x308D4, 0x4000, sizeof(u32)) < 0)
|
|
ILI_ERR("Write failed\n");
|
|
|
|
if (ili_ice_mode_write(0x308D8, 0x4000, sizeof(u32)) < 0)
|
|
ILI_ERR("Write failed\n");
|
|
|
|
if (ili_ice_mode_write(0x308DC, 0x40040000, sizeof(u32)) < 0)
|
|
ILI_ERR("Write failed\n");
|
|
|
|
if (ili_ice_mode_write(0x308E0, 0x40000000, sizeof(u32)) < 0)
|
|
ILI_ERR("Write failed\n");
|
|
|
|
ili_trigger_mspi();
|
|
|
|
/* Recovery Mspi int en */
|
|
if (ili_ice_mode_write(MSPI_INIT_EN_ADDR, backup_mspi_init_en, 1) < 0)
|
|
ILI_ERR("Write MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
ILI_INFO("Backup MSPI Init EN : 0x%X\n", backup_mspi_init_en);
|
|
}
|
|
|
|
#if ENABLE_SPICASCADE_V2
|
|
int ili_ice_slave_write_register(u32 addr, u32 data, int len)
|
|
{
|
|
int ret = 0;
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
|
|
ILI_INFO("[SLAVE write]:addr = 0x%06x, write = 0x%08x, len = %d byte\n", addr, data, len);
|
|
|
|
if (!ice)
|
|
ilits->ice_mode_ctrl(ENABLE, OFF, BOTH);
|
|
|
|
if (ili_ice_mode_write(MSPI_REG, 0x1, 1) < 0)
|
|
ILI_ERR("Write MSPI_REG failed\n");
|
|
|
|
if (ili_ice_mode_write(ICE_HEADER_REG, ICE_FAK_HEADER, 1) < 0)
|
|
ILI_ERR("Write ICE_HEADER_REG failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_REG, 0x0, 1) < 0)
|
|
ILI_ERR("Write MSPI_REG failed\n");
|
|
|
|
ilits->skip_sync_cmd = ENABLE;
|
|
ilits->ice_mode_ctrl(DISABLE, OFF, BOTH);
|
|
|
|
ilits->ice_mode_ctrl(ENABLE, OFF, BOTH);
|
|
ilits->skip_sync_cmd = DISABLE;
|
|
|
|
ret = ili_ice_mode_write(addr, data, len);
|
|
|
|
ilits->ice_mode_ctrl(DISABLE, OFF, BOTH);
|
|
|
|
ilits->ice_mode_ctrl(ENABLE, ON, BOTH);
|
|
|
|
if (ili_ice_mode_write(MSPI_REG, 0x1, 1) < 0)
|
|
ILI_ERR("Write MSPI_REG failed\n");
|
|
|
|
if (ili_ice_mode_write(ICE_HEADER_REG, ICE_HEADER, 1) < 0)
|
|
ILI_ERR("Write ICE_HEADER_REG failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_REG, 0x0, 1) < 0)
|
|
ILI_ERR("Write MSPI_REG failed\n");
|
|
|
|
ilits->ice_mode_ctrl(DISABLE, OFF, BOTH);
|
|
|
|
if (ice)
|
|
ilits->ice_mode_ctrl(ENABLE, OFF, BOTH);
|
|
|
|
return ret;
|
|
}
|
|
#else
|
|
int ili_mspi_write_slave_register(u32 addr, u32 data, int len)
|
|
{
|
|
int ret = 0;
|
|
u32 backup_mspi_init_en, write_data;
|
|
|
|
ili_mspi_init();
|
|
|
|
if (ili_ice_mode_read(MSPI_INIT_EN_ADDR, &backup_mspi_init_en, 1) < 0)
|
|
ILI_ERR("Read MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_INIT_EN_ADDR, backup_mspi_init_en & 0xFE, 1) < 0)
|
|
ILI_ERR("Write MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
ili_dma_write_setting();
|
|
|
|
if (ili_ice_mode_read(TRANSFER_CNT_ADDR, &write_data, sizeof(u32)) < 0)
|
|
ILI_ERR("Read TRANSFER_CNT_ADDR failed\n");
|
|
|
|
write_data = (write_data & 0xFFFC0000) + 5 + len;
|
|
|
|
if (ili_ice_mode_write(TRANSFER_CNT_ADDR, write_data, sizeof(u32)) < 0)
|
|
ILI_ERR("Write TRANSFER_CNT_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(WRITE_BUF_SIZE_ADDR, &write_data, 2) < 0)
|
|
ILI_ERR("Read WRITE_BUF_SIZE_ADDR failed\n");
|
|
|
|
write_data = (write_data & 0xF800) + 5 + len;
|
|
|
|
if (ili_ice_mode_write(WRITE_BUF_SIZE_ADDR, write_data, 2) < 0)
|
|
ILI_ERR("Write WRITE_BUF_SIZE_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(READ_BUF_SIZE_ADDR, &write_data, 2) < 0)
|
|
ILI_ERR("Read READ_BUF_SIZE_ADDR failed\n");
|
|
|
|
write_data = write_data & 0xF800;
|
|
|
|
if (ili_ice_mode_write(READ_BUF_SIZE_ADDR, write_data, 2) < 0)
|
|
ILI_ERR("Write READ_BUF_SIZE_ADDR failed\n");
|
|
|
|
if (addr == CONTROL_SLAVE_EXIT_ICE_ADDR) {
|
|
write_data = ((addr & 0xFF00) << 16) + ((addr & 0xFF) << 16) + (0x1B << 8) + 0x82;
|
|
} else {
|
|
write_data = ((addr & 0xFF00) << 16) + ((addr & 0xFF) << 16) + (0x25 << 8) + 0x82;
|
|
}
|
|
|
|
if (ili_ice_mode_write(WRITE_BUF_ADDR, write_data, sizeof(u32)) < 0)
|
|
ILI_ERR("Write WRITE_BUF_ADDR failed\n");
|
|
|
|
write_data = ((data & 0xFF0000) << 8) + ((data & 0xFF00) << 8) + ((data & 0xFF) << 8) + ((addr & 0xFF0000) >> 16);
|
|
|
|
if (ili_ice_mode_write(0x308D0, write_data, sizeof(u32)) < 0) {
|
|
ILI_ERR("Write failed\n");
|
|
ret = -1;
|
|
}
|
|
|
|
write_data = (data & 0xFF000000) >> 24;
|
|
|
|
if (ili_ice_mode_write(0x308D4, write_data, sizeof(u32)) < 0) {
|
|
ILI_ERR("Write failed\n");
|
|
ret = -1;
|
|
}
|
|
|
|
ili_trigger_mspi();
|
|
|
|
/* Recovery Mspi int en */
|
|
if (ili_ice_mode_write(MSPI_INIT_EN_ADDR, backup_mspi_init_en, 1) < 0)
|
|
ILI_ERR("Write MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void ili_dma_read_setting(void)
|
|
{
|
|
if (ili_ice_mode_write(DMA_ONE_CLEAR_ADDR, 0x02, 1) < 0)
|
|
ILI_ERR("Write DMA_ONE_CLEAR_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(SRC_ONE_ADDR, 0x62060, 3) < 0)
|
|
ILI_ERR("Write SRC_ONE_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(SRC_ONE_SET_ADDR, 0x80000000, sizeof(u32)) < 0)
|
|
ILI_ERR("Write SRC_ONE_SET_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(SRC_TWO_EN_ADDR, 0x00, 1) < 0)
|
|
ILI_ERR("Write SRC_TWO_EN_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(DEST_ADDR, 0x308D0, 3) < 0)
|
|
ILI_ERR("Write DEST_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(DEST_SET_ADDR, 0x80000001, sizeof(u32)) < 0)
|
|
ILI_ERR("Write DEST_SET_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(TRIG_SEL_MSPI_ADDR, 0x0E, 1) < 0)
|
|
ILI_ERR("Write DEST_SET_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(DMA_ONE_GROUP_ADDR, 0x00, 1) < 0)
|
|
ILI_ERR("Write DMA_ONE_GROUP_ADDR failed\n");
|
|
}
|
|
|
|
void ili_mspi_read_slave_register(u32 addr, u32 *data, int len)
|
|
{
|
|
u32 read_data, backup_mspi_init_en;
|
|
|
|
ili_mspi_write_slave_register(addr, 0, 0);
|
|
|
|
if (ili_ice_mode_read(MSPI_INIT_EN_ADDR, &backup_mspi_init_en, 1) < 0)
|
|
ILI_ERR("Read MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_write(MSPI_INIT_EN_ADDR, backup_mspi_init_en & 0xFE, 1) < 0)
|
|
ILI_ERR("Write MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
ili_dma_read_setting();
|
|
|
|
if (ili_ice_mode_write(WRITE_BUF_ADDR, 0x83, 1) < 0)
|
|
ILI_ERR("Write WRITE_BUF_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(TRANSFER_CNT_ADDR, &read_data, sizeof(u32)) < 0)
|
|
ILI_ERR("Read TRANSFER_CNT_ADDR failed\n");
|
|
|
|
read_data = (read_data & 0xFFFC0000) + len;
|
|
|
|
if (ili_ice_mode_write(TRANSFER_CNT_ADDR, read_data, sizeof(u32)) < 0)
|
|
ILI_ERR("Write TRANSFER_CNT_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(WRITE_BUF_SIZE_ADDR, &read_data, 2) < 0)
|
|
ILI_ERR("Read WRITE_BUF_SIZE_ADDR failed\n");
|
|
|
|
read_data = (read_data & 0xF800) + 0x01;
|
|
|
|
if (ili_ice_mode_write(WRITE_BUF_SIZE_ADDR, read_data, 2) < 0)
|
|
ILI_ERR("Write WRITE_BUF_SIZE_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(READ_BUF_SIZE_ADDR, &read_data, 2) < 0)
|
|
ILI_ERR("Read READ_BUF_SIZE_ADDR failed\n");
|
|
|
|
read_data = (read_data & 0xF800) + len;
|
|
|
|
if (ili_ice_mode_write(READ_BUF_SIZE_ADDR, read_data, 2) < 0)
|
|
ILI_ERR("Write READ_BUF_SIZE_ADDR failed\n");
|
|
|
|
ili_trigger_mspi();
|
|
|
|
/* Recovery Mspi int en */
|
|
if (ili_ice_mode_write(MSPI_INIT_EN_ADDR, backup_mspi_init_en, 1) < 0)
|
|
ILI_ERR("Write MSPI_INIT_EN_ADDR failed\n");
|
|
|
|
if (ili_ice_mode_read(0x308D0, data, len) < 0)
|
|
ILI_ERR("Read 0x308D0 failed\n");
|
|
}
|
|
#endif
|
|
|
|
void ili_spi_ms_register_read(u32 addr, u32 *data, int len, u8 msmode)
|
|
{
|
|
if (msmode == SLAVE) {
|
|
if (ili_ice_mode_write(MS_MISO_SEL_REG, 0x0, 1) < 0)
|
|
ILI_ERR("Write miso sel to slave failed\n");
|
|
ilits->spi_ms_mode = SLAVE;
|
|
} else {
|
|
if (ili_ice_mode_write(MS_MISO_SEL_REG, 0x1, 1) < 0)
|
|
ILI_ERR("Write miso sel to master failed\n");
|
|
ilits->spi_ms_mode = MASTER;
|
|
}
|
|
|
|
ili_ice_mode_read(addr, data, len);
|
|
|
|
ilits->spi_ms_mode = MASTER;
|
|
|
|
ILI_DBG("read %s addr = 0x%08x, read = 0x%08x\n", (msmode == MASTER) ? "MASTER" : "SLAVE", (u32)addr, (u32) *data);
|
|
}
|
|
|
|
void ili_spi_ice_mode_read(u32 addr, u32 *data, int len, u8 msmode)
|
|
{
|
|
#if ENABLE_SPICASCADE_V2
|
|
ili_spi_ms_register_read(addr, data, len, msmode);
|
|
#else
|
|
if (msmode == SLAVE) {
|
|
ILI_INFO("ili_mspi_read_slave_register\n");
|
|
ili_mspi_read_slave_register(addr, data, len);
|
|
} else {
|
|
ili_ice_mode_read(addr, data, len);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
int ili_set_bypass_mode(bool mcu)
|
|
{
|
|
#if (TDDI_INTERFACE == BUS_SPI)
|
|
if (atomic_read(&ilits->ice_stat)) {
|
|
ILI_INFO("ice mode already enabled\n");
|
|
return 0;
|
|
}
|
|
|
|
if (ili_ice_mode_ctrl(ENABLE, mcu) < 0) {
|
|
ILI_ERR("Failed to write ice mode\n");
|
|
}
|
|
|
|
/* set mspi 0 */
|
|
if (ili_ice_mode_write_by_mode(MSPI_REG, 0x00, 1, MASTER) < 0) {
|
|
ILI_ERR("Failed to write MSPI_REG in ice mode\n");
|
|
}
|
|
|
|
/* set s_to_q bit[1] = 1 */
|
|
ili_ice_mode_write(SINGLE_TO_QUAL_REG, 0x02, 1);
|
|
|
|
/* set slave ic to ice mode */
|
|
atomic_set(&ilits->ice_stat, DISABLE);
|
|
|
|
if (ili_ice_mode_ctrl(ENABLE, mcu) < 0) {
|
|
ILI_ERR("Failed to write ice mode\n");
|
|
}
|
|
|
|
ILI_INFO("Set ByPass Mode\n");
|
|
|
|
#if (ENABLE_SPICASCADE_V2)
|
|
if (ili_ice_mode_write_by_mode(CMD_MODE_EN_REG, 0x22, 1, BOTH) < 0) {
|
|
ILI_ERR("Failed to enable cmd mode\n");
|
|
}
|
|
#endif
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
|
|
void ili_wdt_reset_status( bool enter_ice, bool exit_ice)
|
|
{
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if (enter_ice) {
|
|
if (atomic_read(&ilits->ice_stat)) {
|
|
ILI_INFO("ice mode already enabled\n");
|
|
} else {
|
|
ili_ice_mode_ctrl_by_mode(ENABLE, OFF, BOTH);
|
|
}
|
|
}
|
|
#else
|
|
if (enter_ice) {
|
|
if (atomic_read(&ilits->ice_stat)) {
|
|
ILI_INFO("ice mode already enabled\n");
|
|
} else {
|
|
ilits->ice_mode_ctrl(ENABLE, OFF, BOTH);
|
|
}
|
|
}
|
|
#endif
|
|
if (ili_ice_mode_write_by_mode(WDT_ADDR, 0x01, 1, BOTH) > 0) {
|
|
ILI_INFO("Clear Master & Slave WDT Status\n");
|
|
}
|
|
|
|
if (exit_ice) {
|
|
if (!atomic_read(&ilits->ice_stat)) {
|
|
ILI_INFO("ice mode already disabled\n");
|
|
} else {
|
|
ilits->ice_mode_ctrl(DISABLE, OFF, BOTH);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ili_ic_edge_palm_para_init(void)
|
|
{
|
|
#if ENABLE_EDGE_PALM_PARA
|
|
int i;
|
|
|
|
ilits->edge_palm_para[0] = P5_X_EDGE_PLAM_CTRL_1;
|
|
ilits->edge_palm_para[1] = P5_X_EDGE_PALM_TUNING_PARA;
|
|
ilits->edge_palm_para[2] = (ZONE_A_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[3] = ZONE_A_W & 0xFF;
|
|
ilits->edge_palm_para[4] = (ZONE_B_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[5] = ZONE_B_W & 0xFF;
|
|
ilits->edge_palm_para[6] = (ZONE_A_ROTATION_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[7] = ZONE_A_ROTATION_W & 0xFF;
|
|
ilits->edge_palm_para[8] = (ZONE_B_ROTATION_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[9] = ZONE_B_ROTATION_W & 0xFF;
|
|
ilits->edge_palm_para[10] = (ZONE_C_WIDTH & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[11] = ZONE_C_WIDTH & 0xFF;
|
|
ilits->edge_palm_para[12] = (ZONE_C_HEIGHT & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[13] = ZONE_C_HEIGHT & 0xFF;
|
|
ilits->edge_palm_para[14] = (ZONE_C_HEIGHT_LITTLE & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[15] = ZONE_C_HEIGHT_LITTLE & 0xFF;
|
|
ilits->edge_palm_para[16] = (ZONE_A_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[17] = ZONE_A_W & 0xFF;
|
|
ilits->edge_palm_para[18] = (ZONE_B_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[19] = ZONE_B_W & 0xFF;
|
|
ilits->edge_palm_para[20] = (ZONE_A_ROTATION_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[21] = ZONE_A_ROTATION_W & 0xFF;
|
|
ilits->edge_palm_para[22] = (ZONE_B_ROTATION_W & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[23] = ZONE_B_ROTATION_W & 0xFF;
|
|
ilits->edge_palm_para[24] = (ZONE_C_WIDTH & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[25] = ZONE_C_WIDTH & 0xFF;
|
|
ilits->edge_palm_para[26] = (ZONE_C_HEIGHT & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[27] = ZONE_C_HEIGHT & 0xFF;
|
|
ilits->edge_palm_para[28] = (ZONE_C_HEIGHT_LITTLE & 0xFF00) >> 8;
|
|
ilits->edge_palm_para[29] = ZONE_C_HEIGHT_LITTLE & 0xFF;
|
|
ilits->edge_palm_para[30] = ili_calc_packet_checksum(ilits->edge_palm_para, P5_X_EDGE_PALM_PARA_LENGTH - 1);
|
|
|
|
for (i = 0; i < P5_X_EDGE_PALM_PARA_LENGTH; i++) {
|
|
ILI_DBG("edge_palm_para[%d] = 0x%2x\n", i, ilits->edge_palm_para[i]);
|
|
}
|
|
#endif
|
|
}
|
|
void ili_ic_send_edge_palm_para(void)
|
|
{
|
|
#if ENABLE_EDGE_PALM_PARA
|
|
int ret = 0;
|
|
|
|
ILI_INFO("send edge palm para\n");
|
|
|
|
ret = ilits->wrapper(ilits->edge_palm_para, P5_X_EDGE_PALM_PARA_LENGTH, NULL, 0, OFF, OFF);
|
|
if (ret < 0)
|
|
ILI_ERR("Write edge palm para function failed\n");
|
|
#endif
|
|
}
|
|
|
|
int ili_ic_func_ctrl_export(const char *name, int ctrl)
|
|
{
|
|
int i = 0, ret;
|
|
if (ERR_ALLOC_MEM(ilits)) {
|
|
ILI_ERR("Failed to allocate ts memory, ilits is NULL.\n");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
mutex_lock(&ilits->touch_mutex);
|
|
for (i = 0; i < FUNC_CTRL_NUM; i++) {
|
|
if (ipio_strcmp(name, func_ctrl[i].name) == 0) {
|
|
if (strlen(name) != strlen(func_ctrl[i].name))
|
|
continue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i >= FUNC_CTRL_NUM) {
|
|
ILI_ERR("Not found function ctrl, %s\n", name);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (ilits->protocol->ver == PROTOCOL_VER_500) {
|
|
ILI_ERR("Non support function ctrl with protocol v5.0\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (ilits->protocol->ver >= PROTOCOL_VER_560) {
|
|
if (ipio_strcmp(func_ctrl[i].name, "gesture") == 0 ||
|
|
ipio_strcmp(func_ctrl[i].name, "phone_cover_window") == 0) {
|
|
ILI_INFO("Non support %s function ctrl\n", func_ctrl[i].name);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
func_ctrl[i].cmd[2] = ctrl;
|
|
|
|
ILI_INFO("func = %s, len = %d, cmd = 0x%x, 0%x, 0x%x\n", func_ctrl[i].name, func_ctrl[i].len,
|
|
func_ctrl[i].cmd[0], func_ctrl[i].cmd[1], func_ctrl[i].cmd[2]);
|
|
|
|
ret = ilits->wrapper(func_ctrl[i].cmd, func_ctrl[i].len, NULL, 0, OFF, OFF);
|
|
if (ret < 0)
|
|
ILI_ERR("Write TP function failed\n");
|
|
|
|
if (func_ctrl[i].rec_state < 2) {
|
|
if (ctrl == func_ctrl[i].def_cmd)
|
|
func_ctrl[i].rec_state = DISABLE;
|
|
else
|
|
func_ctrl[i].rec_state = ENABLE;
|
|
|
|
func_ctrl[i].rec_cmd = ctrl;
|
|
}
|
|
|
|
ILI_DBG("record %s func cmd %d, rec_state %d\n", func_ctrl[i].name, func_ctrl[i].rec_cmd, func_ctrl[i].rec_state);
|
|
out:
|
|
mutex_unlock(&ilits->touch_mutex);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(ili_ic_func_ctrl_export);
|
|
|
|
|
|
int ili_ic_func_ctrl(const char *name, int ctrl)
|
|
{
|
|
int i = 0, ret;
|
|
|
|
for (i = 0; i < FUNC_CTRL_NUM; i++) {
|
|
if (ipio_strcmp(name, func_ctrl[i].name) == 0) {
|
|
if (strlen(name) != strlen(func_ctrl[i].name))
|
|
continue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i >= FUNC_CTRL_NUM) {
|
|
ILI_ERR("Not found function ctrl, %s\n", name);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (ilits->protocol->ver == PROTOCOL_VER_500) {
|
|
ILI_ERR("Non support function ctrl with protocol v5.0\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (ilits->protocol->ver >= PROTOCOL_VER_560) {
|
|
if (ipio_strcmp(func_ctrl[i].name, "gesture") == 0 ||
|
|
ipio_strcmp(func_ctrl[i].name, "phone_cover_window") == 0) {
|
|
ILI_INFO("Non support %s function ctrl\n", func_ctrl[i].name);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (ilits->chip->core_ver >= CORE_VER_1700) {
|
|
if (ipio_strcmp(func_ctrl[i].name, "sense") == 0) {
|
|
ILI_INFO("Non support %s function ctrl after core ver %x\n", func_ctrl[i].name, ilits->chip->core_ver);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
func_ctrl[i].cmd[2] = ctrl;
|
|
|
|
ILI_INFO("func = %s, len = %d, cmd = 0x%x, 0x%x, 0x%x\n", func_ctrl[i].name, func_ctrl[i].len,
|
|
func_ctrl[i].cmd[0], func_ctrl[i].cmd[1], func_ctrl[i].cmd[2]);
|
|
|
|
ret = ilits->wrapper(func_ctrl[i].cmd, func_ctrl[i].len, NULL, 0, OFF, OFF);
|
|
if (ret < 0)
|
|
ILI_ERR("Write TP function failed\n");
|
|
|
|
if (func_ctrl[i].rec_state < 2) {
|
|
if (ctrl == func_ctrl[i].def_cmd)
|
|
func_ctrl[i].rec_state = DISABLE;
|
|
else
|
|
func_ctrl[i].rec_state = ENABLE;
|
|
|
|
func_ctrl[i].rec_cmd = ctrl;
|
|
}
|
|
|
|
ILI_DBG("record %s func cmd %d, rec_state %d\n", func_ctrl[i].name, func_ctrl[i].rec_cmd, func_ctrl[i].rec_state);
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
void ili_ic_func_ctrl_reset(void)
|
|
{
|
|
int i = 0;
|
|
|
|
ili_ic_send_edge_palm_para();
|
|
|
|
for (i = 0; i < FUNC_CTRL_NUM; i++) {
|
|
if (func_ctrl[i].rec_state == ENABLE) {
|
|
ILI_DBG("reset func ctrl %s, record status = %d, cmd = %d\n", func_ctrl[i].name,
|
|
func_ctrl[i].rec_state, func_ctrl[i].rec_cmd);
|
|
if (ili_ic_func_ctrl(func_ctrl[i].name, func_ctrl[i].rec_cmd) < 0)
|
|
ILI_ERR("reset ic func ctrl %s failed\n", func_ctrl[i].name);
|
|
}
|
|
}
|
|
}
|
|
|
|
int ili_ic_code_reset(bool mcu)
|
|
{
|
|
int ret;
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
|
|
if (!ice) {
|
|
ilits->ice_mode_ctrl(ENABLE, mcu, BOTH);
|
|
}
|
|
|
|
ret = ili_ice_mode_write_by_mode(0x40040, 0xAE, 1, BOTH);
|
|
if (ret < 0)
|
|
ILI_ERR("ic code reset failed\n");
|
|
|
|
if (!ice) {
|
|
ilits->ice_mode_ctrl(DISABLE, mcu, BOTH);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ili_get_dma1_config(struct ilitek_dma_config *dma)
|
|
{
|
|
/* dma1 src1 address */
|
|
if (ili_ice_mode_read(0x072104, &dma->src_addr, 4) < 0)
|
|
ILI_ERR("read dma1 src1 address failed\n");
|
|
/* dma1 src1 format */
|
|
if (ili_ice_mode_read(0x072108, &dma->src_fmt, 4) < 0)
|
|
ILI_ERR("read dma1 src1 format failed\n");
|
|
/* dma1 dest address */
|
|
if (ili_ice_mode_read(0x072114, &dma->dest_addr, 4) < 0)
|
|
ILI_ERR("read dma1 src1 format failed\n");
|
|
/* dma1 dest format */
|
|
if (ili_ice_mode_read(0x072118, &dma->dest_fmt, 4) < 0)
|
|
ILI_ERR("read dma1 dest format failed\n");
|
|
/* Block size */
|
|
if (ili_ice_mode_read(0x07211C, &dma->block_size, 4) < 0)
|
|
ILI_ERR("read block size (%d) failed\n", dma->block_size);
|
|
ILI_DBG("dma.src_addr=0x%x, dma.src_fmt=0x%x, dma.dest_addr=0x%x, dma.dest_fmt=0x%x, dma.block_size=0x%x\n"
|
|
, dma->src_addr, dma->src_fmt, dma->dest_addr, dma->dest_fmt, dma->block_size);
|
|
}
|
|
|
|
void ili_set_dma1_config(struct ilitek_dma_config *dma)
|
|
{
|
|
ILI_DBG("dma.src_addr=0x%x, dma.src_fmt=0x%x, dma.dest_addr=0x%x, dma.dest_fmt=0x%x, dma.block_size=0x%x\n"
|
|
, dma->src_addr, dma->src_fmt, dma->dest_addr, dma->dest_fmt, dma->block_size);
|
|
/* dma1 src1 address */
|
|
if (ili_ice_mode_write(0x072104, dma->src_addr, 4) < 0)
|
|
ILI_ERR("Write dma1 src1 address failed\n");
|
|
/* dma1 src1 format */
|
|
if (ili_ice_mode_write(0x072108, dma->src_fmt, 4) < 0)
|
|
ILI_ERR("Write dma1 src1 format failed\n");
|
|
/* dma1 dest address */
|
|
if (ili_ice_mode_write(0x072114, dma->dest_addr, 4) < 0)
|
|
ILI_ERR("Write dma1 src1 format failed\n");
|
|
/* dma1 dest format */
|
|
if (ili_ice_mode_write(0x072118, dma->dest_fmt, 4) < 0)
|
|
ILI_ERR("Write dma1 dest format failed\n");
|
|
/* Block size*/
|
|
if (ili_ice_mode_write(0x07211C, dma->block_size, 4) < 0)
|
|
ILI_ERR("Write block size (%d) failed\n", dma->block_size);
|
|
/* Disable CRC calc settings */
|
|
if (ili_ice_mode_write(0x041014, 0x0, 4) < 0)
|
|
ILI_ERR("Write dma CRC calc settings failed\n");
|
|
/* Dma1 stop */
|
|
if (ili_ice_mode_write(0x072100, 0x02040000, 4) < 0)
|
|
ILI_ERR("Write dma1 stop failed\n");
|
|
/* clr int */
|
|
if (ili_ice_mode_write(0x048006, 0x2, 1) < 0)
|
|
ILI_ERR("Write clr int failed\n");
|
|
/* Dma1 start */
|
|
if (ili_ice_mode_write(0x072100, 0x01040000, 4) < 0)
|
|
ILI_ERR("Write dma1 start failed\n");
|
|
}
|
|
|
|
int ili_ic_whole_reset(bool mcu, bool withflash)
|
|
{
|
|
int ret = 0;
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
|
|
if (withflash)
|
|
ilits->chip->reset_key = TDDI_WHOLE_CHIP_RST_WITH_FLASH_KEY;
|
|
else
|
|
ilits->chip->reset_key = TDDI_WHOLE_CHIP_RST_WITHOUT_FLASH_KEY;
|
|
|
|
if (!ice) {
|
|
ilits->ice_mode_ctrl(ENABLE, mcu, BOTH);
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_CASCADE)
|
|
ili_ice_mode_ctrl_by_mode(ENABLE, mcu, BOTH);
|
|
#elif (TDDI_INTERFACE == BUS_SPI && ENABLE_CASCADE)
|
|
ili_set_bypass_mode(mcu);
|
|
#else
|
|
if (ili_ice_mode_ctrl(ENABLE, mcu) < 0)
|
|
ILI_ERR("Enable ice mode failed before chip reset\n");
|
|
#endif
|
|
}
|
|
|
|
if (!withflash)
|
|
ili_ice_mode_write_by_mode(ilits->chip->reset_addr, TDDI_WHOLE_CHIP_RST_WITHOUT_FLASH_PRE_KEY, sizeof(u32), BOTH);
|
|
|
|
ILI_INFO("ic whole reset key = 0x%x, edge_delay = %d, withflash = %d\n",
|
|
ilits->chip->reset_key, ilits->rst_edge_delay, withflash);
|
|
|
|
ret = ili_ice_mode_write_by_mode(ilits->chip->reset_addr, ilits->chip->reset_key, sizeof(u32), BOTH);
|
|
if (ret < 0) {
|
|
ILI_ERR("ic whole reset failed\n");
|
|
goto out;
|
|
}
|
|
|
|
/* Need accurate power sequence, do not change it to msleep */
|
|
mdelay(ilits->rst_edge_delay);
|
|
|
|
out:
|
|
if (!ice) {
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_CASCADE)
|
|
ili_ice_mode_ctrl_by_mode(DISABLE, mcu, BOTH);
|
|
#elif (TDDI_INTERFACE == BUS_SPI && ENABLE_CASCADE)
|
|
ili_ice_mode_ctrl_by_mode(DISABLE, mcu, BOTH);
|
|
#else
|
|
if (ili_ice_mode_ctrl(DISABLE, mcu) < 0)
|
|
ILI_ERR("Enable ice mode failed after chip reset\n");
|
|
#endif
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void ilitek_tddi_ic_cascade_wr_pack(int packet)
|
|
{
|
|
int ret = 0, retry = 100;
|
|
u32 reg_data = 0;
|
|
|
|
while (retry--) {
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if (ili_ice_mode_read_by_mode(0x73010, ®_data, sizeof(u8), ilits->slave_wr_ctrl) < 0)
|
|
ILI_ERR("Read 0x73010 error\n");
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x73010, ®_data, sizeof(reg_data));
|
|
ILI_DBG("check ok 0x73010 read Master 0x%X\n", reg_data);
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, ®_data, sizeof(reg_data));
|
|
ILI_DBG("check ok 0x62030 read Slave 0x%X\n", reg_data);
|
|
reg_data = (reg_data >> 24) & 0xFF;
|
|
} else {
|
|
if (ili_ice_mode_read(0x73010, ®_data, sizeof(u8)) < 0)
|
|
ILI_ERR("Read 0x73010 error\n");
|
|
}
|
|
#endif
|
|
if ((reg_data & 0x02) == 0) {
|
|
ILI_INFO("check ok 0x73010 read 0x%X retry = %d\n", reg_data, retry);
|
|
break;
|
|
}
|
|
|
|
mdelay(10);
|
|
}
|
|
|
|
if (retry <= 0)
|
|
ILI_INFO("check 0x73010 error read 0x%X\n", reg_data);
|
|
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
ret = ili_ice_mode_write_by_mode(0x73000, packet, 4, ilits->slave_wr_ctrl);
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
#if ENABLE_SPICASCADE_V2
|
|
ret = ili_ice_slave_write_register(0x73000, packet, 4);
|
|
#else
|
|
ret = ili_mspi_write_slave_register(0x73000, packet, 4);
|
|
#endif
|
|
/* set mspi 0 */
|
|
if (ili_ice_mode_write_by_mode(MSPI_REG, 0x00, 1, MASTER) < 0)
|
|
ILI_ERR("Failed to write MSPI_REG in ice mode\n");
|
|
} else {
|
|
ret = ili_ice_mode_write(0x73000, packet, 4);
|
|
}
|
|
#endif
|
|
if (ret < 0) {
|
|
ILI_ERR("Write %x at 0x73000 Fail\n", packet);
|
|
}
|
|
}
|
|
|
|
static u32 ilitek_tddi_ic_cascade_rd_pack(int packet)
|
|
{
|
|
int ret = 0, retry = 100;
|
|
u32 reg_data = 0;
|
|
|
|
ilitek_tddi_ic_cascade_wr_pack(packet);
|
|
|
|
while (retry--) {
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if (ili_ice_mode_read_by_mode(0x4800A, ®_data, sizeof(u8), ilits->slave_wr_ctrl) < 0)
|
|
ILI_ERR("Read 0x4800A error\n");
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x4800A, ®_data, sizeof(reg_data));
|
|
ILI_DBG("check ok 0x4800A read Master 0x%X\n", reg_data);
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, ®_data, sizeof(reg_data));
|
|
ILI_DBG("check ok 0x4800A read Slave 0x%X\n", reg_data);
|
|
reg_data = (reg_data >> 24) & 0xFF;
|
|
} else {
|
|
if (ili_ice_mode_read(0x4800A, ®_data, sizeof(u8)) < 0)
|
|
ILI_ERR("Read 0x4800A error\n");
|
|
}
|
|
#endif
|
|
|
|
if ((reg_data & 0x02) == 0x02) {
|
|
ILI_INFO("check ok 0x4800A read 0x%X retry = %d\n", reg_data, retry);
|
|
break;
|
|
}
|
|
mdelay(10);
|
|
}
|
|
|
|
if (retry <= 0)
|
|
ILI_INFO("check 0x4800A error read 0x%X\n", reg_data);
|
|
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
ret = ili_ice_mode_write_by_mode(0x4800A, 0x02, 1, ilits->slave_wr_ctrl);
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
#if ENABLE_SPICASCADE_V2
|
|
ret = ili_ice_slave_write_register(0x4800A, 0x02, 1);
|
|
#else
|
|
ret = ili_mspi_write_slave_register(0x4800A, 0x02, 1);
|
|
#endif
|
|
/* set mspi 0 */
|
|
if (ili_ice_mode_write_by_mode(MSPI_REG, 0x00, 1, MASTER) < 0)
|
|
ILI_ERR("Failed to write MSPI_REG in ice mode\n");
|
|
} else {
|
|
ret = ili_ice_mode_write(0x4800A, 0x02, 1);
|
|
}
|
|
#endif
|
|
if (ret < 0) {
|
|
ILI_ERR("Write 0x2 at 0x4800A Fail\n");
|
|
}
|
|
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if (ili_ice_mode_read_by_mode(0x73016, ®_data, sizeof(u8), ilits->slave_wr_ctrl) < 0)
|
|
ILI_ERR("Read 0x73016 error\n");
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
ili_ice_mode_write(READ_BACK_LOCK_REG, 0x01, 1);
|
|
ili_ice_mode_read(0x73016, ®_data, sizeof(reg_data));
|
|
ILI_DBG("check ok 0x73016 read Master 0x%X\n", reg_data);
|
|
ili_ice_mode_read(SLAVE_READ_BACK_WORD_REG, ®_data, sizeof(reg_data));
|
|
ILI_DBG("check ok 0x73016 read Slave 0x%X\n", reg_data);
|
|
reg_data = (reg_data >> 24) & 0xFF;
|
|
} else {
|
|
if (ili_ice_mode_read(0x73016, ®_data, sizeof(u8)) < 0)
|
|
ILI_ERR("Read 0x73016 error\n");
|
|
}
|
|
#endif
|
|
|
|
return reg_data;
|
|
}
|
|
|
|
void ili_ic_set_cascade_ddi_reg_onepage(u8 page, u8 reg, u8 data, bool mcu)
|
|
{
|
|
|
|
u32 setpage = 0x1FFFFF00 | page;
|
|
u32 setreg = 0x1F000100 | (reg << 16) | data;
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
u8 spiclk_num = 3;
|
|
|
|
ILI_INFO("setpage = 0x%X setreg = 0x%X\n", setpage, setreg);
|
|
|
|
if (ilits->slave_wr_ctrl) {
|
|
ili_core_spi_setup(spiclk_num);
|
|
}
|
|
|
|
if (!ice) {
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
ili_ice_mode_ctrl_by_mode(ENABLE, mcu, ilits->slave_wr_ctrl);
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
ilits->ice_mode_ctrl(ENABLE, mcu, BOTH);
|
|
} else {
|
|
ili_ice_mode_ctrl(ENABLE, mcu);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*TDI_WR_KEY*/
|
|
ilitek_tddi_ic_cascade_wr_pack(0x1FFF9527);
|
|
/*Switch to Page*/
|
|
ilitek_tddi_ic_cascade_wr_pack(setpage);
|
|
/* Page*/
|
|
ilitek_tddi_ic_cascade_wr_pack(setreg);
|
|
/*TDI_WR_KEY OFF*/
|
|
ilitek_tddi_ic_cascade_wr_pack(0x1FFF9500);
|
|
|
|
if (!ice) {
|
|
ilits->ice_mode_ctrl(DISABLE, mcu, ilits->slave_wr_ctrl);
|
|
}
|
|
|
|
if (ilits->slave_wr_ctrl) {
|
|
ili_core_spi_setup(SPI_CLK);
|
|
}
|
|
}
|
|
|
|
void ili_ic_get_cascade_ddi_reg_onepage(u8 page, u8 reg, u8 *data, bool mcu)
|
|
{
|
|
int ret = 0;
|
|
u32 setpage = 0x1FFFFF00 | page;
|
|
u32 setreg = 0x2F000100 | (reg << 16);
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
u8 spiclk_num = 3;
|
|
|
|
ILI_INFO("setpage = 0x%X setreg = 0x%X\n", setpage, setreg);
|
|
|
|
if (ilits->slave_wr_ctrl) {
|
|
ili_core_spi_setup(spiclk_num);
|
|
}
|
|
|
|
if (!ice) {
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if (ili_ice_mode_ctrl_by_mode(ENABLE, mcu, ilits->slave_wr_ctrl) < 0)
|
|
ILI_ERR("Enable ice mode failed before reading ddi reg\n");
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
ilits->ice_mode_ctrl(ENABLE, mcu, BOTH);
|
|
} else {
|
|
if (ili_ice_mode_ctrl(ENABLE, mcu) < 0)
|
|
ILI_ERR("Enable ice mode failed before reading ddi reg\n");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*TDI_WR_KEY*/
|
|
ilitek_tddi_ic_cascade_wr_pack(0x1FFF9527);
|
|
/*Set Read Page reg*/
|
|
ilitek_tddi_ic_cascade_wr_pack(setpage);
|
|
|
|
/*TDI_RD_KEY*/
|
|
ilitek_tddi_ic_cascade_wr_pack(0x1FFF9487);
|
|
|
|
/*( *( __IO uint8 *) (0x4800A) ) =0x2*/
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
ret = ili_ice_mode_write_by_mode(0x4800A, 0x02, 1, ilits->slave_wr_ctrl);
|
|
#else
|
|
if (ilits->slave_wr_ctrl) {
|
|
#if ENABLE_SPICASCADE_V2
|
|
ret = ili_ice_slave_write_register(0x4800A, 0x02, 1);
|
|
#else
|
|
ret = ili_mspi_write_slave_register(0x4800A, 0x02, 1);
|
|
#endif
|
|
/* set mspi 0 */
|
|
if (ili_ice_mode_write_by_mode(MSPI_REG, 0x00, 1, MASTER) < 0)
|
|
ILI_ERR("Failed to write MSPI_REG in ice mode\n");
|
|
} else {
|
|
ret = ili_ice_mode_write(0x4800A, 0x02, 1);
|
|
}
|
|
#endif
|
|
if (ret < 0) {
|
|
ILI_ERR("Write 0x2 at 0x4800A Fail\n");
|
|
}
|
|
|
|
*data = ilitek_tddi_ic_cascade_rd_pack(setreg);
|
|
ILI_INFO("check page = 0x%X, reg = 0x%X, read 0x%X\n", page, reg, *data);
|
|
|
|
/*TDI_RD_KEY OFF*/
|
|
ilitek_tddi_ic_cascade_wr_pack(0x1FFF9400);
|
|
/*TDI_WR_KEY OFF*/
|
|
ilitek_tddi_ic_cascade_wr_pack(0x1FFF9500);
|
|
|
|
if (!ice) {
|
|
ilits->ice_mode_ctrl(DISABLE, mcu, ilits->slave_wr_ctrl);
|
|
}
|
|
|
|
if (ilits->slave_wr_ctrl) {
|
|
ili_core_spi_setup(SPI_CLK);
|
|
}
|
|
}
|
|
|
|
static void ilitek_tddi_ic_wr_pack(int packet)
|
|
{
|
|
int retry = 100;
|
|
u32 reg_data = 0;
|
|
|
|
while (retry--) {
|
|
if (ili_ice_mode_read(0x73010, ®_data, sizeof(u8)) < 0)
|
|
ILI_ERR("Read 0x73010 error\n");
|
|
|
|
if ((reg_data & 0x02) == 0) {
|
|
ILI_INFO("check ok 0x73010 read 0x%X retry = %d\n", reg_data, retry);
|
|
break;
|
|
}
|
|
mdelay(10);
|
|
}
|
|
|
|
if (retry <= 0)
|
|
ILI_INFO("check 0x73010 error read 0x%X\n", reg_data);
|
|
|
|
if (ili_ice_mode_write(0x73000, packet, 4) < 0)
|
|
ILI_ERR("Write %x at 0x73000\n", packet);
|
|
}
|
|
|
|
static u32 ilitek_tddi_ic_rd_pack(int packet)
|
|
{
|
|
int retry = 100;
|
|
u32 reg_data = 0;
|
|
|
|
ilitek_tddi_ic_wr_pack(packet);
|
|
|
|
while (retry--) {
|
|
if (ili_ice_mode_read(0x4800A, ®_data, sizeof(u8)) < 0)
|
|
ILI_ERR("Read 0x4800A error\n");
|
|
|
|
if ((reg_data & 0x02) == 0x02) {
|
|
ILI_INFO("check ok 0x4800A read 0x%X retry = %d\n", reg_data, retry);
|
|
break;
|
|
}
|
|
mdelay(10);
|
|
}
|
|
if (retry <= 0)
|
|
ILI_INFO("check 0x4800A error read 0x%X\n", reg_data);
|
|
|
|
if (ili_ice_mode_write(0x4800A, 0x02, 1) < 0)
|
|
ILI_ERR("Write 0x2 at 0x4800A\n");
|
|
|
|
if (ili_ice_mode_read(0x73016, ®_data, sizeof(u8)) < 0)
|
|
ILI_ERR("Read 0x73016 error\n");
|
|
|
|
return reg_data;
|
|
}
|
|
|
|
void ili_ic_set_ddi_reg_onepage(u8 page, u8 reg, u8 data, bool mcu)
|
|
{
|
|
u32 setpage = 0x1FFFFF00 | page;
|
|
u32 setreg = 0x1F000100 | (reg << 16) | data;
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
|
|
ILI_INFO("setpage = 0x%X setreg = 0x%X\n", setpage, setreg);
|
|
|
|
if (!ice)
|
|
if (ili_ice_mode_ctrl(ENABLE, mcu) < 0)
|
|
ILI_ERR("Enable ice mode failed before writing ddi reg\n");
|
|
|
|
/*TDI_WR_KEY*/
|
|
ilitek_tddi_ic_wr_pack(0x1FFF9527);
|
|
/*Switch to Page*/
|
|
ilitek_tddi_ic_wr_pack(setpage);
|
|
/* Page*/
|
|
ilitek_tddi_ic_wr_pack(setreg);
|
|
/*TDI_WR_KEY OFF*/
|
|
ilitek_tddi_ic_wr_pack(0x1FFF9500);
|
|
|
|
if (!ice)
|
|
if (ili_ice_mode_ctrl(DISABLE, mcu) < 0)
|
|
ILI_ERR("Disable ice mode failed after writing ddi reg\n");
|
|
}
|
|
|
|
void ili_ic_get_ddi_reg_onepage(u8 page, u8 reg, u8 *data, bool mcu)
|
|
{
|
|
u32 setpage = 0x1FFFFF00 | page;
|
|
u32 setreg = 0x2F000100 | (reg << 16);
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
|
|
ILI_INFO("setpage = 0x%X setreg = 0x%X\n", setpage, setreg);
|
|
|
|
if (!ice)
|
|
if (ili_ice_mode_ctrl(ENABLE, mcu) < 0)
|
|
ILI_ERR("Enable ice mode failed before reading ddi reg\n");
|
|
|
|
/*TDI_WR_KEY*/
|
|
ilitek_tddi_ic_wr_pack(0x1FFF9527);
|
|
/*Set Read Page reg*/
|
|
ilitek_tddi_ic_wr_pack(setpage);
|
|
|
|
/*TDI_RD_KEY*/
|
|
ilitek_tddi_ic_wr_pack(0x1FFF9487);
|
|
/*( *( __IO uint8 *) (0x4800A) ) =0x2*/
|
|
if (ili_ice_mode_write(0x4800A, 0x02, 1) < 0)
|
|
ILI_ERR("Write 0x2 at 0x4800A\n");
|
|
|
|
*data = ilitek_tddi_ic_rd_pack(setreg);
|
|
ILI_INFO("check page = 0x%X, reg = 0x%X, read 0x%X\n", page, reg, *data);
|
|
|
|
/*TDI_RD_KEY OFF*/
|
|
ilitek_tddi_ic_wr_pack(0x1FFF9400);
|
|
/*TDI_WR_KEY OFF*/
|
|
ilitek_tddi_ic_wr_pack(0x1FFF9500);
|
|
|
|
if (!ice)
|
|
if (ili_ice_mode_ctrl(DISABLE, mcu) < 0)
|
|
ILI_ERR("Disable ice mode failed after reading ddi reg\n");
|
|
}
|
|
|
|
void ili_ic_get_pc_counter(int stat)
|
|
{
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
u32 pc = 0, pc_addr = ilits->chip->pc_counter_addr;
|
|
u32 latch = 0, latch_addr = ilits->chip->pc_latch_addr;
|
|
int ret = 0;
|
|
#if (TDDI_INTERFACE == BUS_SPI)
|
|
u32 mcu_state = 0;
|
|
#endif
|
|
|
|
ILI_DBG("stat = %d\n", stat);
|
|
|
|
if (ilits->cascade_info_block.nNum != 0) {
|
|
#if (TDDI_INTERFACE == BUS_SPI)
|
|
if (stat == DO_SPI_RECOVER)
|
|
mcu_state = OFF;
|
|
else
|
|
mcu_state = ON;
|
|
|
|
ili_cascade_rw_tp_reg(mcu_state, ILI_READ, pc_addr, 0, 0, &pc);
|
|
ili_cascade_rw_tp_reg(mcu_state, ILI_READ, latch_addr, 0, 0, &latch);
|
|
|
|
ilits->fw_pc = pc;
|
|
ilits->fw_latch = latch;
|
|
|
|
if (ilits->slave_wr_ctrl) {
|
|
ILI_ERR("Read Slave counter (addr: 0x%x) = 0x%x, latch (addr: 0x%x) = 0x%x\n",
|
|
pc_addr, ilits->fw_pc, latch_addr, ilits->fw_latch);
|
|
} else {
|
|
ILI_ERR("Read Master counter (addr: 0x%x) = 0x%x, latch (addr: 0x%x) = 0x%x\n",
|
|
pc_addr, ilits->fw_pc, latch_addr, ilits->fw_latch);
|
|
}
|
|
|
|
/* Avoid screen abnormal. */
|
|
if (stat == DO_SPI_RECOVER) {
|
|
atomic_set(&ilits->ice_stat, DISABLE);
|
|
return;
|
|
}
|
|
|
|
#elif (TDDI_INTERFACE == BUS_I2C)
|
|
if (ilits->slave_wr_ctrl) {
|
|
ilits->i2c_addr_change = SLAVE;
|
|
ILI_DBG("Change to Slave Address\n");
|
|
} else {
|
|
ilits->i2c_addr_change = MASTER;
|
|
ILI_DBG("Change to Master Address\n");
|
|
}
|
|
|
|
if (!ice) {
|
|
if (stat == DO_I2C_RECOVER)
|
|
ret = ili_ice_mode_ctrl_by_mode(ENABLE, OFF, ilits->slave_wr_ctrl);
|
|
else
|
|
ret = ili_ice_mode_ctrl_by_mode(ENABLE, ON, ilits->slave_wr_ctrl);
|
|
|
|
if (ret < 0)
|
|
ILI_ERR("Enable ice mode failed while reading pc counter\n");
|
|
}
|
|
|
|
ili_ice_mode_read_by_mode(pc_addr, &pc, sizeof(u32), ilits->slave_wr_ctrl);
|
|
ili_ice_mode_read_by_mode(latch_addr, &latch, sizeof(u32), ilits->slave_wr_ctrl);
|
|
|
|
ilits->fw_pc = pc;
|
|
ilits->fw_latch = latch;
|
|
|
|
if (ilits->slave_wr_ctrl) {
|
|
ILI_ERR("Read Slave counter (addr: 0x%x) = 0x%x, latch (addr: 0x%x) = 0x%x\n",
|
|
pc_addr, ilits->fw_pc, latch_addr, ilits->fw_latch);
|
|
} else {
|
|
ILI_ERR("Read Master counter (addr: 0x%x) = 0x%x, latch (addr: 0x%x) = 0x%x\n",
|
|
pc_addr, ilits->fw_pc, latch_addr, ilits->fw_latch);
|
|
}
|
|
|
|
if (!ice) {
|
|
if (ili_ice_mode_ctrl_by_mode(DISABLE, ON, ilits->slave_wr_ctrl) < 0)
|
|
ILI_ERR("Disable ice mode failed while reading pc counter\n");
|
|
}
|
|
#endif
|
|
} else {
|
|
if (!ice) {
|
|
if (stat == DO_SPI_RECOVER || stat == DO_I2C_RECOVER)
|
|
ret = ili_ice_mode_ctrl(ENABLE, OFF);
|
|
else
|
|
ret = ili_ice_mode_ctrl(ENABLE, ON);
|
|
|
|
if (ret < 0)
|
|
ILI_ERR("Enable ice mode failed while reading pc counter\n");
|
|
}
|
|
|
|
if (ili_ice_mode_read(pc_addr, &pc, sizeof(u32)) < 0)
|
|
ILI_ERR("Read pc conter error\n");
|
|
|
|
if (ili_ice_mode_read(latch_addr, &latch, sizeof(u32)) < 0)
|
|
ILI_ERR("Read pc latch error\n");
|
|
|
|
ilits->fw_pc = pc;
|
|
ilits->fw_latch = latch;
|
|
ILI_ERR("Read counter (addr: 0x%x) = 0x%x, latch (addr: 0x%x) = 0x%x\n",
|
|
pc_addr, ilits->fw_pc, latch_addr, ilits->fw_latch);
|
|
|
|
/* Avoid screen abnormal. */
|
|
if (stat == DO_SPI_RECOVER) {
|
|
atomic_set(&ilits->ice_stat, DISABLE);
|
|
return;
|
|
}
|
|
|
|
if (!ice) {
|
|
if (ili_ice_mode_ctrl(DISABLE, ON) < 0)
|
|
ILI_ERR("Disable ice mode failed while reading pc counter\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
int ili_ic_int_trigger_ctrl(bool level_trigger)
|
|
{
|
|
/* It's supported by fw, and the level will be kept at high until data was already prepared. */
|
|
if (ili_ic_func_ctrl("int_trigger", level_trigger) < 0) {
|
|
ILI_ERR("Write CMD error, set back to <%s> trigger\n", ilits->int_pulse ? "Level" : "Pulse");
|
|
return -1;
|
|
}
|
|
|
|
ilits->int_pulse = !level_trigger;
|
|
ILI_INFO("INT Trigger = %s\n", ilits->int_pulse ? "Pulse" : "Level");
|
|
return 0;
|
|
}
|
|
|
|
int ili_ic_check_int_level(bool level)
|
|
{
|
|
int timer = 3000;
|
|
int gpio = IRQ_GPIO_NUM; /* ilits->tp_int */
|
|
|
|
/*
|
|
* If callers have a trouble to use the gpio that is passed by vendors,
|
|
* please utlises a physical gpio number instead or call a help from them.
|
|
*/
|
|
|
|
while (--timer > 0) {
|
|
if (level) {
|
|
if (gpio_get_value(gpio)) {
|
|
ILI_DBG("INT high detected.\n");
|
|
return 0;
|
|
}
|
|
} else {
|
|
if (!gpio_get_value(gpio)) {
|
|
ILI_DBG("INT low detected.\n");;
|
|
return 0;
|
|
}
|
|
}
|
|
mdelay(1);
|
|
}
|
|
ILI_ERR("Error! INT level no detected.\n");
|
|
return -1;
|
|
}
|
|
|
|
int ili_ic_check_int_pulse(bool pulse)
|
|
{
|
|
if (!wait_event_interruptible_timeout(ilits->inq, !atomic_read(&ilits->cmd_int_check), msecs_to_jiffies(ilits->wait_int_timeout))) {
|
|
ILI_ERR("Error! INT pulse no detected. Timeout = %d ms\n", ilits->wait_int_timeout);
|
|
atomic_set(&ilits->cmd_int_check, DISABLE);
|
|
return -1;
|
|
}
|
|
ILI_DBG("INT pulse detected.\n");
|
|
return 0;
|
|
}
|
|
|
|
int ili_ic_check_busy(int count, int delay, bool irq)
|
|
{
|
|
u8 cmd[2] = {0};
|
|
u8 busy = 0, rby = 0;
|
|
|
|
cmd[0] = P5_X_READ_DATA_CTRL;
|
|
cmd[1] = P5_X_CDC_BUSY_STATE;
|
|
|
|
if (ilits->actual_tp_mode == P5_X_FW_AP_MODE)
|
|
rby = 0x41;
|
|
else if (ilits->actual_tp_mode == P5_X_FW_TEST_MODE)
|
|
rby = 0x51;
|
|
else {
|
|
ILI_ERR("Unknown TP mode (0x%x)\n", ilits->actual_tp_mode);
|
|
return -EINVAL;
|
|
}
|
|
|
|
ILI_INFO("read byte = %x, delay = %d\n", rby, delay);
|
|
|
|
do {
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0)
|
|
ILI_ERR("Write check busy cmd failed\n");
|
|
|
|
if (ilits->wrapper(&cmd[1], sizeof(u8), &busy, sizeof(u8), irq, OFF) < 0)
|
|
ILI_ERR("Read check busy failed\n");
|
|
|
|
ILI_DBG("busy = 0x%x\n", busy);
|
|
|
|
if (busy == rby) {
|
|
ILI_INFO("Check busy free\n");
|
|
return 0;
|
|
}
|
|
|
|
mdelay(delay);
|
|
} while (--count > 0);
|
|
|
|
ILI_ERR("Check busy (0x%x) timeout !\n", busy);
|
|
ili_ic_get_pc_counter(0);
|
|
|
|
if (ilits->cascade_info_block.nNum != 0) {
|
|
ilits->slave_wr_ctrl = 1;
|
|
ili_ic_get_pc_counter(0);
|
|
ilits->slave_wr_ctrl = 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int ili_ic_get_project_id(u8 *pdata, int size)
|
|
{
|
|
int i;
|
|
u32 tmp;
|
|
bool ice = atomic_read(&ilits->ice_stat);
|
|
|
|
if (!pdata) {
|
|
ILI_ERR("pdata is null\n");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
ILI_INFO("Read size = %d\n", size);
|
|
|
|
if (!ice)
|
|
if (ili_ice_mode_ctrl(ENABLE, OFF) < 0)
|
|
ILI_ERR("Enable ice mode failed while reading project id\n");
|
|
|
|
if (ili_ice_mode_write(0x041000, 0x0, 1) < 0)
|
|
ILI_ERR("Pull cs low failed\n");
|
|
if (ili_ice_mode_write(0x041004, 0x66aa55, 3) < 0)
|
|
ILI_ERR("Write key failed\n");
|
|
|
|
if (ili_ice_mode_write(0x041008, 0x03, 1) < 0)
|
|
ILI_ERR("Write 0x03 at 0x041008\n");
|
|
|
|
if (ili_ice_mode_write(0x041008, (RSV_BK_ST_ADDR & 0xFF0000) >> 16, 1) < 0)
|
|
ILI_ERR("Write address failed\n");
|
|
if (ili_ice_mode_write(0x041008, (RSV_BK_ST_ADDR & 0x00FF00) >> 8, 1) < 0)
|
|
ILI_ERR("Write address failed\n");
|
|
if (ili_ice_mode_write(0x041008, (RSV_BK_ST_ADDR & 0x0000FF), 1) < 0)
|
|
ILI_ERR("Write address failed\n");
|
|
|
|
for (i = 0; i < size; i++) {
|
|
if (ili_ice_mode_write(0x041008, 0xFF, 1) < 0)
|
|
ILI_ERR("Write dummy failed\n");
|
|
if (ili_ice_mode_read(0x41010, &tmp, sizeof(u8)) < 0)
|
|
ILI_ERR("Read project id error\n");
|
|
pdata[i] = tmp;
|
|
ILI_INFO("project_id[%d] = 0x%x\n", i, pdata[i]);
|
|
}
|
|
|
|
ili_flash_clear_dma();
|
|
|
|
if (ili_ice_mode_write(0x041000, 0x1, 1) < 0)
|
|
ILI_ERR("Pull cs high\n");
|
|
|
|
if (!ice)
|
|
if (ili_ice_mode_ctrl(DISABLE, OFF) < 0)
|
|
ILI_ERR("Disable ice mode failed while reading project id\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ili_ic_get_core_ver(void)
|
|
{
|
|
int i = 0, ret = 0;
|
|
u8 cmd[2] = {0}, buf[10] = {0};
|
|
|
|
ilits->protocol->core_ver_len = P5_X_CORE_VER_FOUR_LENGTH;
|
|
|
|
if (ilits->info_from_hex) {
|
|
buf[1] = ilits->fw_info[68];
|
|
buf[2] = ilits->fw_info[69];
|
|
buf[3] = ilits->fw_info[70];
|
|
buf[4] = ilits->fw_info[71];
|
|
goto out;
|
|
}
|
|
|
|
do {
|
|
if (i == 0) {
|
|
cmd[0] = P5_X_READ_DATA_CTRL;
|
|
cmd[1] = P5_X_GET_CORE_VERSION_NEW;
|
|
} else {
|
|
cmd[0] = P5_X_READ_DATA_CTRL;
|
|
cmd[1] = P5_X_GET_CORE_VERSION;
|
|
ilits->protocol->core_ver_len = P5_X_CORE_VER_THREE_LENGTH;
|
|
}
|
|
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0)
|
|
ILI_ERR("Write core ver cmd failed\n");
|
|
|
|
if (ilits->wrapper(&cmd[1], sizeof(u8), buf, ilits->protocol->core_ver_len, ON, OFF) < 0)
|
|
ILI_ERR("Write core ver (0x%x) failed\n", cmd[1]);
|
|
|
|
ILI_DBG("header = 0x%x\n", buf[0]);
|
|
|
|
if (buf[0] == P5_X_GET_CORE_VERSION ||
|
|
buf[0] == P5_X_GET_CORE_VERSION_NEW)
|
|
break;
|
|
|
|
} while (++i < 2);
|
|
|
|
if (buf[0] == P5_X_GET_CORE_VERSION)
|
|
buf[4] = 0;
|
|
|
|
if (i >= 2) {
|
|
ILI_ERR("Invalid header (0x%x)\n", buf[0]);
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
out:
|
|
ILI_INFO("Core version = %d.%d.%d.%d\n", buf[1], buf[2], buf[3], buf[4]);
|
|
ilits->chip->core_ver = buf[1] << 24 | buf[2] << 16 | buf[3] << 8 | buf[4];
|
|
return ret;
|
|
}
|
|
|
|
void ili_fw_uart_ctrl(u8 ctrl)
|
|
{
|
|
u8 cmd[4] = {0};
|
|
|
|
if (ctrl > 1) {
|
|
ILI_INFO("Unknown cmd, ignore\n");
|
|
return;
|
|
}
|
|
|
|
ILI_INFO("%s UART mode\n", ctrl ? "Enable" : "Disable");
|
|
|
|
cmd[0] = P5_X_I2C_UART;
|
|
cmd[1] = 0x3;
|
|
cmd[2] = 0;
|
|
cmd[3] = ctrl;
|
|
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0) {
|
|
ILI_INFO("Write fw uart cmd failed\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
int ili_ic_get_fw_ver(void)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd[2] = {0};
|
|
u8 buf[10] = {0};
|
|
|
|
if (ilits->info_from_hex) {
|
|
buf[1] = ilits->fw_info[48];
|
|
buf[2] = ilits->fw_info[49];
|
|
buf[3] = ilits->fw_info[50];
|
|
buf[4] = ilits->fw_info[51];
|
|
buf[5] = ilits->fw_mp_ver[0];
|
|
buf[6] = ilits->fw_mp_ver[1];
|
|
buf[7] = ilits->fw_mp_ver[2];
|
|
buf[8] = ilits->fw_mp_ver[3];
|
|
goto out;
|
|
}
|
|
|
|
cmd[0] = P5_X_READ_DATA_CTRL;
|
|
cmd[1] = P5_X_GET_FW_VERSION;
|
|
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0) {
|
|
ILI_ERR("Write pre cmd failed\n");
|
|
ret = -EINVAL;
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (ilits->wrapper(&cmd[1], sizeof(u8), buf, ilits->protocol->fw_ver_len, ON, OFF) < 0) {
|
|
ILI_ERR("Write fw version cmd failed\n");
|
|
ret = -EINVAL;
|
|
goto out;
|
|
}
|
|
|
|
if (buf[0] != P5_X_GET_FW_VERSION) {
|
|
ILI_ERR("Invalid firmware ver\n");
|
|
ret = -1;
|
|
}
|
|
|
|
out:
|
|
ILI_INFO("Firmware version = %d.%d.%d.%d\n", buf[1], buf[2], buf[3], buf[4]);
|
|
ILI_INFO("Firmware MP version = %d.%d.%d.%d\n", buf[5], buf[6], buf[7], buf[8]);
|
|
ilits->chip->fw_ver = buf[1] << 24 | buf[2] << 16 | buf[3] << 8 | buf[4];
|
|
ilits->chip->fw_mp_ver = buf[5] << 24 | buf[6] << 16 | buf[7] << 8 | buf[8];
|
|
#if IS_ENABLED(CONFIG_PRIZE_HARDWARE_INFO)
|
|
sprintf(current_tp_info.chip,"ILI9883,FW_VER:%d.%d.%d.%d",buf[1],buf[2],buf[3],buf[4]);
|
|
sprintf(current_tp_info.id, "0x%x",ilits->chip->id);
|
|
sprintf(current_tp_info.vendor,"ILITEK");
|
|
sprintf(current_tp_info.more,"720*1612");
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int ili_ic_get_panel_info(void)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd = P5_X_GET_PANEL_INFORMATION;
|
|
u8 buf[10] = {0};
|
|
u8 len = ilits->protocol->panel_info_len;
|
|
u8 data_type = P5_X_FW_SIGNAL_DATA_MODE;
|
|
|
|
if (ilits->info_from_hex && (ilits->chip->core_ver >= CORE_VER_1410)) {
|
|
buf[1] = ilits->fw_info[16];
|
|
buf[2] = ilits->fw_info[17];
|
|
buf[3] = ilits->fw_info[18];
|
|
buf[4] = ilits->fw_info[19];
|
|
ilits->panel_wid = buf[2] << 8 | buf[1];
|
|
ilits->panel_hei = buf[4] << 8 | buf[3];
|
|
ilits->trans_xy = (ilits->chip->core_ver >= CORE_VER_1430
|
|
&& (ilits->rib.nReportByPixel > 0)) ? ON : OFF;
|
|
goto out;
|
|
}
|
|
|
|
len = (ilits->chip->core_ver >= CORE_VER_1430) ? 6 : len;
|
|
|
|
ret = ilits->wrapper(&cmd, sizeof(cmd), buf, len, ON, OFF);
|
|
if (ret < 0)
|
|
ILI_ERR("Read panel info error\n");
|
|
|
|
if (buf[0] != cmd) {
|
|
ILI_INFO("Invalid panel info, use default resolution\n");
|
|
ilits->panel_wid = TOUCH_SCREEN_X_MAX;
|
|
ilits->panel_hei = TOUCH_SCREEN_Y_MAX;
|
|
ilits->trans_xy = OFF;
|
|
} else {
|
|
ilits->panel_wid = buf[1] << 8 | buf[2];
|
|
ilits->panel_hei = buf[3] << 8 | buf[4];
|
|
ilits->trans_xy = (ilits->chip->core_ver >= CORE_VER_1430) ? buf[5] : OFF;
|
|
}
|
|
|
|
if (ilits->chip->core_ver >= CORE_VER_1470) {
|
|
cmd = P5_X_GET_REPORT_FORMAT;
|
|
ret = ilits->wrapper(&cmd, sizeof(cmd), buf, 2, ON, OFF);
|
|
if (ret < 0)
|
|
ILI_ERR("Read report format info error\n");
|
|
|
|
if (buf[0] != cmd) {
|
|
ILI_INFO("Invalid report format info, use default report format resolution\n");
|
|
ilits->rib.nReportResolutionMode = POSITION_LOW_RESOLUTION;
|
|
ilits->rib.nCustomerType = POSITION_CUSTOMER_TYPE_OFF;
|
|
ilits->PenType = POSITION_PEN_TYPE_OFF;
|
|
if (ilits->chip->core_ver >= CORE_VER_1700) {
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF_3BITS;
|
|
} else {
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF;
|
|
}
|
|
} else {
|
|
ilits->rib.nReportResolutionMode = buf[1] & 0x07;
|
|
|
|
if (ilits->chip->core_ver >= CORE_VER_1700) {
|
|
ilits->rib.nCustomerType = (buf[1] >> 3) & 0x07;
|
|
ilits->PenType = buf[1] >> 6;
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF_3BITS;
|
|
|
|
if (ilits->PenType == POSITION_PEN_TYPE_ON) {
|
|
ilits->touch_num = MAX_TOUCH_NUM + MAX_PEN_NUM;
|
|
ili_set_tp_data_len(DATA_FORMAT_DEMO, false, &data_type);
|
|
ILI_INFO("Panel support Pen Mode, Packet Len = %d, Touch Number = %d\n", ilits->tp_data_len, ilits->touch_num);
|
|
}
|
|
} else {
|
|
ilits->PenType = POSITION_PEN_TYPE_OFF;
|
|
ilits->rib.nCustomerType = buf[1] >> 3;
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF;
|
|
}
|
|
}
|
|
} else {
|
|
ilits->PenType = POSITION_PEN_TYPE_OFF;
|
|
ilits->rib.nReportResolutionMode = POSITION_LOW_RESOLUTION;
|
|
ilits->rib.nCustomerType = POSITION_CUSTOMER_TYPE_OFF;
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF;
|
|
}
|
|
ILI_INFO("PenType = 0x%x, Customer Type OFF = 0x%x\n", ilits->PenType, ilits->customertype_off);
|
|
|
|
#if ENABLE_PEN_MODE
|
|
cmd = P5_X_GET_PEN_INFO;
|
|
ret = ilits->wrapper(&cmd, sizeof(cmd), buf, 9, ON, OFF);
|
|
ILI_INFO("cmd = 0x%X, buf[0] = 0x%X, buf[1] = 0x%X, buf[2] = 0x%X, buf[3] = 0x%X, buf[4] = 0x%X\n", cmd, buf[0], buf[1], buf[2], buf[3], buf[4]);
|
|
if (ret < 0)
|
|
ILI_ERR("Read report format info error\n");
|
|
|
|
if (buf[0] != cmd) {
|
|
ILI_INFO("Invalid Pen info, use default report format resolution\n");
|
|
ilits->pen_info_block.nPxRaw = P5_X_PEN_INFO_X_DATA_LEN;
|
|
ilits->pen_info_block.nPyRaw = P5_X_PEN_INFO_Y_DATA_LEN;
|
|
ilits->pen_info_block.nPxVa = 1;
|
|
ilits->pen_info_block.nPyVa = 1;
|
|
ilits->pen_info_block.nPenX_MP = 0;
|
|
} else {
|
|
ilits->pen_info_block.nPxRaw = buf[1];
|
|
ilits->pen_info_block.nPyRaw = buf[2];
|
|
ilits->pen_info_block.nPxVa = buf[3];
|
|
ilits->pen_info_block.nPyVa = buf[4];
|
|
ilits->pen_info_block.nPenX_MP = buf[5];
|
|
}
|
|
#endif
|
|
#if ENABLE_CASCADE
|
|
cmd = P5_X_GET_CASCADE_INFO;
|
|
ret = ilits->wrapper(&cmd, sizeof(cmd), buf, 5, ON, OFF);
|
|
ILI_INFO("cmd = 0x%X, buf[0] = 0x%X, buf[1] = 0x%X, buf[2] = 0x%X, buf[3] = 0x%X\n", cmd, buf[0], buf[1], buf[2], buf[3]);
|
|
if (ret < 0)
|
|
ILI_ERR("Read report format info error\n");
|
|
|
|
if (buf[0] != cmd) {
|
|
ilits->cascade_info_block.nDisable = ENABLE;
|
|
ilits->cascade_info_block.nNum = 2;
|
|
} else {
|
|
ilits->cascade_info_block.nDisable = buf[1] & BIT(0);
|
|
ilits->cascade_info_block.nNum = (buf[1] >> 1) & 0x07;
|
|
}
|
|
#else
|
|
ilits->cascade_info_block.nDisable = ENABLE;
|
|
ilits->cascade_info_block.nNum = 0;
|
|
#endif
|
|
out:
|
|
ILI_INFO("Panel info: width = %d, height = %d\n", ilits->panel_wid, ilits->panel_hei);
|
|
ILI_INFO("Transfer touch coordinate = %s\n", ilits->trans_xy ? "ON" : "OFF");
|
|
ILI_INFO("Customer Type = %X\n", ilits->rib.nCustomerType);
|
|
ILI_INFO("Report Resolution Format Mode = %X\n", ilits->rib.nReportResolutionMode);
|
|
|
|
if (ilits->chip->core_ver >= CORE_VER_1700) {
|
|
ILI_INFO("Pen Type = %X\n", ilits->PenType);
|
|
ILI_INFO("Pen Info Data, nPxRaw = %d, nPyRaw = %d, nPxVa = %d, nPyVa = %d, nPenX_MP = %d\n", ilits->pen_info_block.nPxRaw, ilits->pen_info_block.nPyRaw, ilits->pen_info_block.nPxVa, ilits->pen_info_block.nPyVa, ilits->pen_info_block.nPenX_MP);
|
|
ILI_INFO("Cascade Info Data, nDisable = %d, nNum = %d\n", ilits->cascade_info_block.nDisable, ilits->cascade_info_block.nNum);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ili_ic_get_tp_info(void)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd[2] = {0};
|
|
u8 buf[20] = {0};
|
|
|
|
if (ilits->info_from_hex && (ilits->chip->core_ver >= CORE_VER_1410)) {
|
|
buf[1] = ilits->fw_info[5];
|
|
buf[2] = ilits->fw_info[7];
|
|
buf[3] = ilits->fw_info[8];
|
|
buf[4] = ilits->fw_info[9];
|
|
buf[5] = ilits->fw_info[10];
|
|
buf[6] = ilits->fw_info[11];
|
|
buf[7] = ilits->fw_info[12];
|
|
buf[8] = ilits->fw_info[14];
|
|
if (ilits->chip->core_ver >= CORE_VER_1700) {
|
|
buf[11] = ilits->fw_info[13];
|
|
buf[12] = ilits->fw_info[15];
|
|
} else {
|
|
buf[11] = buf[7];
|
|
buf[12] = buf[8];
|
|
}
|
|
goto out;
|
|
}
|
|
|
|
cmd[0] = P5_X_READ_DATA_CTRL;
|
|
cmd[1] = P5_X_GET_TP_INFORMATION;
|
|
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0) {
|
|
ILI_ERR("Write tp info pre cmd failed\n");
|
|
ret = -EINVAL;
|
|
goto out;
|
|
|
|
}
|
|
|
|
ret = ilits->wrapper(&cmd[1], sizeof(u8), buf, ilits->protocol->tp_info_len, ON, OFF);
|
|
if (ret < 0) {
|
|
ILI_ERR("Read tp info error\n");
|
|
goto out;
|
|
}
|
|
|
|
if (buf[0] != P5_X_GET_TP_INFORMATION) {
|
|
ILI_ERR("Invalid tp info\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
ilits->min_x = buf[1];
|
|
ilits->min_y = buf[2];
|
|
ilits->max_x = buf[4] << 8 | buf[3];
|
|
ilits->max_y = buf[6] << 8 | buf[5];
|
|
ilits->xch_num = buf[7];
|
|
ilits->ych_num = buf[8];
|
|
ilits->stx = buf[11];
|
|
ilits->srx = buf[12];
|
|
|
|
ILI_INFO("TP Info: min_x = %d, min_y = %d, max_x = %d, max_y = %d\n", ilits->min_x, ilits->min_y, ilits->max_x, ilits->max_y);
|
|
ILI_INFO("TP Info: xch = %d, ych = %d, stx = %d, srx = %d\n", ilits->xch_num, ilits->ych_num, ilits->stx, ilits->srx);
|
|
return ret;
|
|
}
|
|
|
|
void ili_ic_get_compress_info(void)
|
|
{
|
|
#if ENABLE_COMPRESS_MODE
|
|
int ret = 0;
|
|
u8 cmd = P5_X_GET_COMPRESS_INFORMATION;
|
|
u8 buf[10] = {0};
|
|
|
|
if (ilits->info_from_hex && (ilits->chip->core_ver >= CORE_VER_1700)) {
|
|
buf[1] = ilits->fw_info[0];
|
|
goto out;
|
|
}
|
|
|
|
ret = ilits->wrapper(&cmd, sizeof(cmd), buf, 5, ON, OFF);
|
|
if (ret < 0)
|
|
ILI_ERR("Read compress info error\n");
|
|
|
|
if (buf[0] != cmd) {
|
|
ILI_INFO("Invalid compress info, use default value\n");
|
|
ilits->compress_disable = true;
|
|
ilits->compress_handonly_disable = true;
|
|
ilits->compress_penonly_disable = true;
|
|
} else {
|
|
ilits->compress_disable = (buf[1] & 0x20) >> 5;
|
|
ilits->compress_handonly_disable = (buf[1] & 0x40) >> 6;
|
|
ilits->compress_penonly_disable = (buf[1] & 0x80) >> 7;
|
|
}
|
|
|
|
out:
|
|
ilits->compress_disable = (buf[1] & 0x20) >> 5;
|
|
ilits->compress_handonly_disable = (buf[1] & 0x40) >> 6;
|
|
ilits->compress_penonly_disable = (buf[1] & 0x80) >> 7;
|
|
ILI_INFO("compress_disable = %d, compress_handonly_disable = %d, compress_penonly_disable = %d\n", ilits->compress_disable, ilits->compress_handonly_disable, ilits->compress_penonly_disable);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
int ili_ic_get_all_info(void)
|
|
{
|
|
int ret = 0;
|
|
#if (TDDI_INTERFACE == BUS_I2C && ENABLE_GET_ALL_INFO)
|
|
u8 cmd = P5_X_GET_ALL_INFORMATION;
|
|
u8 buf[100] = {0};
|
|
bool get_all_info;
|
|
|
|
if (ilits->wrapper(&cmd, sizeof(cmd), buf, 96, ON, OFF) < 0) {
|
|
ILI_ERR("Write ALL info cmd failed\n");
|
|
get_all_info = false;
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
if (buf[0] == P5_X_GET_ALL_INFORMATION) {
|
|
get_all_info = true;
|
|
|
|
/* CORE_VERSION */
|
|
ilits->chip->core_ver = buf[25] << 24 | buf[26] << 16 | buf[27] << 8 | buf[28];
|
|
|
|
/*GET_TP_INFORMATION*/
|
|
ilits->min_x = buf[2];
|
|
ilits->min_y = buf[3];
|
|
ilits->max_x = buf[5] << 8 | buf[4];
|
|
ilits->max_y = buf[7] << 8 | buf[6];
|
|
ilits->xch_num = buf[8];
|
|
ilits->ych_num = buf[9];
|
|
ilits->stx = buf[12];
|
|
ilits->srx = buf[13];
|
|
|
|
/* GET_FW_VERSION */
|
|
ilits->chip->fw_ver = buf[16] << 24 | buf[17] << 16 | buf[18] << 8 | buf[19];
|
|
ilits->chip->fw_mp_ver = buf[20] << 24 | buf[21] << 16 | buf[22] << 8 | buf[23];
|
|
|
|
/* GET_PANEL_INFORMATION */
|
|
cmd = P5_X_GET_PANEL_INFORMATION;
|
|
if (buf[46] != cmd) {
|
|
ILI_INFO("Invalid panel info, use default resolution\n");
|
|
ilits->panel_wid = TOUCH_SCREEN_X_MAX;
|
|
ilits->panel_hei = TOUCH_SCREEN_Y_MAX;
|
|
ilits->trans_xy = OFF;
|
|
} else {
|
|
ilits->panel_wid = buf[47] << 8 | buf[48];
|
|
ilits->panel_hei = buf[49] << 8 | buf[50];
|
|
ilits->trans_xy = (ilits->chip->core_ver >= CORE_VER_1430) ? buf[51] : OFF;
|
|
}
|
|
|
|
/* GET_COMPRESS_INFORMATION */
|
|
cmd = P5_X_GET_COMPRESS_INFORMATION;
|
|
if (buf[52] != cmd) {
|
|
ILI_INFO("Invalid compress & report format info, use default report format resolution\n");
|
|
ilits->compress_disable = true;
|
|
ilits->compress_handonly_disable = true;
|
|
ilits->compress_penonly_disable = true;
|
|
ilits->rib.nReportResolutionMode = POSITION_LOW_RESOLUTION;
|
|
ilits->rib.nCustomerType = POSITION_CUSTOMER_TYPE_OFF;
|
|
ilits->PenType = POSITION_PEN_TYPE_OFF;
|
|
if (ilits->chip->core_ver >= CORE_VER_1700) {
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF_3BITS;
|
|
} else {
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF;
|
|
}
|
|
} else {
|
|
/* GET_COMPRESS_INFORMATION(0x2B) */
|
|
ilits->compress_disable = (buf[53] & 0x20) >> 5;
|
|
ilits->compress_handonly_disable = (buf[53] & 0x40) >> 6;
|
|
ilits->compress_penonly_disable = (buf[53] & 0x80) >> 7;
|
|
/* GET_REPORT_FORMAT(0x37) */
|
|
ilits->rib.nReportResolutionMode = buf[54] & 0x07;
|
|
|
|
/* note : After core ver 1.7.0.0 support 0x2F cmd, so ignore before case */
|
|
ilits->rib.nCustomerType = (buf[54] >> 3) & 0x07;
|
|
ilits->PenType = buf[54] >> 6;
|
|
ilits->customertype_off = POSITION_CUSTOMER_TYPE_OFF_3BITS;
|
|
|
|
if (ilits->PenType == POSITION_PEN_TYPE_ON) {
|
|
ilits->touch_num = MAX_TOUCH_NUM + MAX_PEN_NUM;
|
|
ili_set_tp_data_len(DATA_FORMAT_DEMO, false, NULL);
|
|
ILI_INFO("Panel support Pen Mode, Packet Len = %d, Touch Number = %d\n", ilits->tp_data_len, ilits->touch_num);
|
|
}
|
|
|
|
/* reserved : buf[55] ~ buf[56] = 0xFF */
|
|
}
|
|
|
|
#if ENABLE_PEN_MODE
|
|
/* GET_PEN_INFO */
|
|
cmd = P5_X_GET_PEN_INFO;
|
|
if (buf[57] != cmd) {
|
|
ILI_INFO("Invalid Pen info, use default report format resolution\n");
|
|
ilits->pen_info_block.nPxRaw = P5_X_PEN_INFO_X_DATA_LEN;
|
|
ilits->pen_info_block.nPyRaw = P5_X_PEN_INFO_Y_DATA_LEN;
|
|
ilits->pen_info_block.nPxVa = 1;
|
|
ilits->pen_info_block.nPyVa = 1;
|
|
ilits->pen_info_block.nPenX_MP = 0;
|
|
} else {
|
|
ilits->pen_info_block.nPxRaw = buf[58];
|
|
ilits->pen_info_block.nPyRaw = buf[59];
|
|
ilits->pen_info_block.nPxVa = buf[60];
|
|
ilits->pen_info_block.nPyVa = buf[61];
|
|
ilits->pen_info_block.nPenX_MP = buf[62];
|
|
}
|
|
/* reserved : buf[62] ~ buf[65] = 0xFF */
|
|
#endif
|
|
|
|
#if ENABLE_CASCADE
|
|
/* GET_CASCADE_INFO */
|
|
cmd = P5_X_GET_CASCADE_INFO;
|
|
if (buf[66] != cmd) {
|
|
ilits->cascade_info_block.nDisable = ENABLE;
|
|
ilits->cascade_info_block.nNum = 2;
|
|
} else {
|
|
ilits->cascade_info_block.nDisable = buf[67] & BIT(0);
|
|
ilits->cascade_info_block.nNum = (buf[67] >> 1) & 0x07;
|
|
}
|
|
#else
|
|
ilits->cascade_info_block.nDisable = ENABLE;
|
|
ilits->cascade_info_block.nNum = 0;
|
|
#endif
|
|
} else {
|
|
ILI_ERR("Read 0x2F error, buf[0] = 0x%X\n", buf[0]);
|
|
get_all_info = false;
|
|
}
|
|
|
|
if (get_all_info == true) {
|
|
ILI_INFO("Firmware version(0x%8X) = %d.%d.%d.%d\n",ilits->chip->fw_ver , buf[16], buf[17], buf[18], buf[19]);
|
|
ILI_INFO("Firmware MP version(0x%8X) = %d.%d.%d.%d\n",ilits->chip->fw_mp_ver , buf[20], buf[21], buf[22], buf[23]);
|
|
ILI_INFO("Core version = %d.%d.%d.%d\n", buf[25], buf[26], buf[27], buf[28]);
|
|
ILI_INFO("TP Info: min_x = %d, min_y = %d, max_x = %d, max_y = %d\n", ilits->min_x, ilits->min_y, ilits->max_x, ilits->max_y);
|
|
ILI_INFO("TP Info: xch = %d, ych = %d, stx = %d, srx = %d\n", ilits->xch_num, ilits->ych_num, ilits->stx, ilits->srx);
|
|
ILI_INFO("Compress Info : compress_disable = %d, compress_handonly_disable = %d, compress_penonly_disable = %d\n",ilits->compress_disable, ilits->compress_handonly_disable, ilits->compress_penonly_disable);
|
|
ILI_INFO("Pen Len Info : PxRaw = %d, PyRaw = %d, PxVa = %d, PyVa = %d, nPenX_MP = %d\n", ilits->pen_info_block.nPxRaw, ilits->pen_info_block.nPyRaw, ilits->pen_info_block.nPxVa, ilits->pen_info_block.nPyVa, ilits->pen_info_block.nPenX_MP);
|
|
ILI_INFO("CASCADE Info : cascade_info_block.nDisable = %d, cascade_info_block.nNum = %d\n", ilits->cascade_info_block.nDisable, ilits->cascade_info_block.nNum);
|
|
ILI_INFO("Panel info: width = %d, height = %d\n", ilits->panel_wid, ilits->panel_hei);
|
|
ILI_INFO("Transfer touch coordinate = %s, Customer Type = %X, Report Resolution Format Mode = %X\n", ilits->trans_xy ? "ON" : "OFF", ilits->rib.nCustomerType, ilits->rib.nReportResolutionMode);
|
|
} else {
|
|
ili_ic_get_core_ver();
|
|
ili_ic_get_protocl_ver();
|
|
ili_ic_get_fw_ver();
|
|
ili_ic_get_tp_info();
|
|
ili_ic_get_panel_info();
|
|
ili_ic_get_compress_info();
|
|
}
|
|
#else
|
|
ili_ic_get_core_ver();
|
|
ili_ic_get_protocl_ver();
|
|
ili_ic_get_fw_ver();
|
|
ili_ic_get_tp_info();
|
|
ili_ic_get_panel_info();
|
|
ili_ic_get_compress_info();
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void ilitek_tddi_ic_check_protocol_ver(u32 pver)
|
|
{
|
|
int i = 0;
|
|
|
|
if (ilits->protocol->ver == pver) {
|
|
ILI_DBG("same procotol version, do nothing\n");
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < PROTOCL_VER_NUM - 1; i++) {
|
|
if (protocol_info[i].ver == pver) {
|
|
ilits->protocol = &protocol_info[i];
|
|
ILI_INFO("update protocol version = %x\n", ilits->protocol->ver);
|
|
return;
|
|
}
|
|
}
|
|
|
|
ILI_ERR("Not found a correct protocol version in list, use newest version\n");
|
|
ilits->protocol = &protocol_info[PROTOCL_VER_NUM - 1];
|
|
}
|
|
|
|
int ili_ic_get_protocl_ver(void)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd[2] = {0};
|
|
u8 buf[10] = {0};
|
|
u32 ver;
|
|
|
|
if (ilits->info_from_hex) {
|
|
buf[1] = ilits->fw_info[72];
|
|
buf[2] = ilits->fw_info[73];
|
|
buf[3] = ilits->fw_info[74];
|
|
goto out;
|
|
}
|
|
|
|
cmd[0] = P5_X_READ_DATA_CTRL;
|
|
cmd[1] = P5_X_GET_PROTOCOL_VERSION;
|
|
|
|
if (ilits->wrapper(cmd, sizeof(cmd), NULL, 0, OFF, OFF) < 0) {
|
|
ILI_ERR("Write protocol ver pre cmd failed\n");
|
|
ret = -EINVAL;
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (ilits->wrapper(&cmd[1], sizeof(u8), buf, ilits->protocol->pro_ver_len, ON, OFF) < 0) {
|
|
ILI_ERR("Read protocol version error\n");
|
|
ret = -EINVAL;
|
|
goto out;
|
|
}
|
|
|
|
if (buf[0] != P5_X_GET_PROTOCOL_VERSION) {
|
|
ILI_ERR("Invalid protocol ver\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
ver = buf[1] << 16 | buf[2] << 8 | buf[3];
|
|
|
|
ilitek_tddi_ic_check_protocol_ver(ver);
|
|
|
|
ILI_INFO("Protocol version = %d.%d.%d\n", ilits->protocol->ver >> 16,
|
|
(ilits->protocol->ver >> 8) & 0xFF, ilits->protocol->ver & 0xFF);
|
|
return ret;
|
|
}
|
|
|
|
u8 ili_chip_id_translate_to_ascii(u8 data)
|
|
{
|
|
u8 ret = 0;
|
|
if (data >= 0 && data <= 9) {
|
|
ret = data + 48;
|
|
} else if (data >= 0x0A && data <= 0x23) {
|
|
ret = data - 0x0A + 65;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ili_ic_get_info(void)
|
|
{
|
|
int ret = 0;
|
|
u8 ddi_data = 0;
|
|
u8 tmp1 = 0, tmp2 = 0;
|
|
|
|
if (!atomic_read(&ilits->ice_stat)) {
|
|
ILI_ERR("ice mode doesn't enable\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
if (ili_ice_mode_read(ilits->chip->pid_addr, &ilits->chip->pid, sizeof(u32)) < 0)
|
|
ILI_ERR("Read chip pid error\n");
|
|
|
|
if (((ilits->chip->pid >> 28) & 0xF) == 0xF) {
|
|
/* Need to Read Second Chip ID */
|
|
if (ili_ice_mode_read(ilits->chip->second_pid_addr, &ilits->chip->second_pid, sizeof(u32)) < 0)
|
|
ILI_ERR("Read second chip pid error\n");
|
|
ilits->chip->id = ((ilits->chip->second_pid & 0x0000FFFF) << 12) + ((ilits->chip->pid & 0x0FFF0000) >> 16);
|
|
|
|
tmp1 = (ilits->chip->second_pid & 0xFF00) >> 8;
|
|
tmp2 = (ilits->chip->pid & 0x00FF0000) >> 16;
|
|
tmp1 = ili_chip_id_translate_to_ascii(tmp1);
|
|
tmp2 = ili_chip_id_translate_to_ascii(tmp2);
|
|
if (tmp1 == 0 || tmp2 == 0) {
|
|
ILI_ERR("Chip id translate error\n");
|
|
}
|
|
snprintf(ilits->chip->product_id, sizeof(ilits->chip->product_id), "%c%02X%X%c",
|
|
tmp1, ilits->chip->second_pid & 0xFF, (ilits->chip->pid & 0x0F000000) >> 24, tmp2);
|
|
} else {
|
|
ilits->chip->id = ilits->chip->pid >> 16;
|
|
snprintf(ilits->chip->product_id, sizeof(ilits->chip->product_id), "%04X", ilits->chip->id);
|
|
if (ilits->chip->id == ILI9882_CHIP) {
|
|
ili_ic_get_ddi_reg_onepage(0x6, 0xF3, &ddi_data, OFF);
|
|
if (ddi_data == 0x30)
|
|
snprintf(ilits->chip->product_id, sizeof(ilits->chip->product_id), "%04X", ILI2882_CHIP);
|
|
}
|
|
}
|
|
|
|
if (ili_ice_mode_read(ilits->chip->otp_addr, &ilits->chip->otp_id, sizeof(u32)) < 0)
|
|
ILI_ERR("Read otp id error\n");
|
|
if (ili_ice_mode_read(ilits->chip->ana_addr, &ilits->chip->ana_id, sizeof(u32)) < 0)
|
|
ILI_ERR("Read ana id error\n");
|
|
|
|
ilits->chip->type = (ilits->chip->pid & 0x0000FF00) >> 8;
|
|
ilits->chip->ver = ilits->chip->pid & 0xFF;
|
|
ilits->chip->otp_id &= 0xFF;
|
|
ilits->chip->ana_id &= 0xFF;
|
|
|
|
ILI_INFO("CHIP ID = %s\n", ilits->chip->product_id);
|
|
|
|
ret = ilitek_tddi_ic_check_info(ilits->chip->pid, ilits->chip->id);
|
|
return ret;
|
|
}
|
|
|
|
int ili_cascade_ic_get_info(bool enter_ice, bool exit_ice)
|
|
{
|
|
int ret = 0;
|
|
bool needSecondSlaveChipID = false;
|
|
|
|
#if (TDDI_INTERFACE == BUS_I2C)
|
|
if (enter_ice) {
|
|
ili_ice_mode_ctrl_by_mode(ENABLE, OFF, BOTH);
|
|
}
|
|
|
|
if (ili_ice_mode_read_by_mode(ilits->chip->pid_addr, &ilits->chip->slave_pid, sizeof(u32), SLAVE) < 0)
|
|
ILI_ERR("Read Slave chip pid error\n");
|
|
|
|
if (((ilits->chip->slave_pid >> 28) & 0xF) == 0xF) {
|
|
needSecondSlaveChipID = true;
|
|
if (ili_ice_mode_read_by_mode(ilits->chip->second_pid_addr, &ilits->chip->slave_second_pid, sizeof(u32), SLAVE) < 0)
|
|
ILI_ERR("Read second slave chip pid error\n");
|
|
}
|
|
|
|
ili_ic_get_info();
|
|
|
|
#else
|
|
if (enter_ice) {
|
|
ilits->ice_mode_ctrl(ENABLE, OFF, BOTH);
|
|
}
|
|
|
|
ili_ic_get_info();
|
|
|
|
ili_spi_ice_mode_read(TDDI_PID_ADDR, &ilits->chip->slave_pid, sizeof(u32), SLAVE);
|
|
|
|
if (((ilits->chip->slave_pid >> 28) & 0xF) == 0xF) {
|
|
needSecondSlaveChipID = true;
|
|
ili_spi_ice_mode_read(TDDI_SECOND_PID_ADDR, &ilits->chip->slave_second_pid, sizeof(u32), SLAVE);
|
|
}
|
|
|
|
/* set mspi 0 */
|
|
if (ili_ice_mode_write_by_mode(MSPI_REG, 0x00, 1, MASTER) < 0) {
|
|
ILI_ERR("Failed to write MSPI_REG in ice mode\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
if (exit_ice) {
|
|
ilits->ice_mode_ctrl(DISABLE, OFF, BOTH);
|
|
}
|
|
|
|
ilits->chip->slave_id = ilits->chip->slave_pid >> 16;
|
|
|
|
/* Compare chip id and chip type.*/
|
|
if (((ilits->chip->pid & 0xFFFFFF00) != (ilits->chip->slave_pid & 0xFFFFFF00)) ||
|
|
(needSecondSlaveChipID && ((ilits->chip->second_pid & 0xFFFF) != (ilits->chip->slave_second_pid & 0xFFFF)))) {
|
|
ILI_ERR("Slave chip pid different from Master\n");
|
|
ret = -1;
|
|
}
|
|
|
|
ILI_INFO("Read Slave CHIP PID = 0x%X, CHIP ID = 0x%X\n", ilits->chip->slave_pid, ilits->chip->slave_id);
|
|
if (needSecondSlaveChipID) {
|
|
ILI_INFO("Read Slave Second CHIP PID = 0x%X\n", ilits->chip->second_pid);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ili_ic_dummy_check(void)
|
|
{
|
|
int ret = 0;
|
|
u32 wdata = 0xA55A5AA5;
|
|
u32 rdata = 0;
|
|
#if (ENGINEER_FLOW)
|
|
int i = 0;
|
|
if (!atomic_read(&ilits->ice_stat)) {
|
|
ILI_ERR("ice mode doesn't enable\n");
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
if (ili_ice_mode_write(WDT9_DUMMY2, wdata, sizeof(u32)) < 0)
|
|
ILI_ERR("Write dummy error\n");
|
|
|
|
if (ili_ice_mode_read(WDT9_DUMMY2, &rdata, sizeof(u32)) < 0)
|
|
ILI_ERR("Read dummy error\n");
|
|
|
|
if (rdata == wdata || rdata == (u32)-wdata) {
|
|
if (rdata == -wdata) {
|
|
ilits->eng_flow = true;
|
|
} else {
|
|
ilits->eng_flow = false;
|
|
}
|
|
break;
|
|
}
|
|
mdelay(30);
|
|
}
|
|
if (i >= 3) {
|
|
ILI_ERR("Dummy check incorrect, rdata = %x wdata = %x \n", rdata, wdata);
|
|
return -1;
|
|
}
|
|
ILI_INFO("Ilitek IC check successe ilits->eng_flow = %d\n", ilits->eng_flow);
|
|
#else
|
|
if (!atomic_read(&ilits->ice_stat)) {
|
|
ILI_ERR("ice mode doesn't enable\n");
|
|
return -1;
|
|
}
|
|
|
|
if (ili_ice_mode_write(WDT9_DUMMY2, wdata, sizeof(u32)) < 0)
|
|
ILI_ERR("Write dummy error\n");
|
|
|
|
|
|
if (ili_ice_mode_read(WDT9_DUMMY2, &rdata, sizeof(u32)) < 0)
|
|
ILI_ERR("Read dummy error\n");
|
|
|
|
if (rdata != wdata) {
|
|
ILI_ERR("Dummy check incorrect, rdata = %x wdata = %x \n", rdata, wdata);
|
|
return -1;
|
|
}
|
|
ILI_INFO("Ilitek IC check successe\n");
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int ili_ic_report_rate_set(u8 mode)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd[4] = {0};
|
|
ILI_INFO("current report rate mode = %x\n", ilits->current_report_rate_mode);
|
|
|
|
if (mode == ilits->current_report_rate_mode) {
|
|
ILI_INFO("set mode = %x, same as current mode = %x\n", mode, ilits->current_report_rate_mode);
|
|
return ret;
|
|
}
|
|
|
|
cmd[0] = 0x01;
|
|
cmd[1] = 0x1F;
|
|
cmd[2] = 0x00;
|
|
cmd[3] = mode;
|
|
|
|
ret = ilits->wrapper(cmd, 4, NULL, 0, OFF, OFF);
|
|
|
|
if (ret < 0)
|
|
ILI_ERR("Write TP function failed\n");
|
|
|
|
ilits->current_report_rate_mode = mode;
|
|
return ret;
|
|
}
|
|
|
|
int ili_ic_check_debug_lite_support(int format, bool send, u8 *data)
|
|
{
|
|
u8 cmd[12] = {0}, buf[4] = {0}, ctrl = 0, debug_ctrl = 0, data_type = 0;
|
|
int ret;
|
|
if (ilits->chip->core_ver < CORE_VER_1700) {
|
|
ILI_INFO("no support check debug lite\n");
|
|
return -1;
|
|
}
|
|
|
|
if (data == NULL) {
|
|
data_type = P5_X_FW_SIGNAL_DATA_MODE;
|
|
ILI_INFO("Data Type is Null, Set Single data type\n");
|
|
} else {
|
|
data_type = data[0];
|
|
ILI_INFO("Set data type = 0x%X \n", data[0]);
|
|
}
|
|
|
|
switch (format) {
|
|
case DATA_FORMAT_DEBUG_LITE_ROI:
|
|
debug_ctrl = DATA_FORMAT_DEBUG_LITE_ROI_CMD;
|
|
ctrl = DATA_FORMAT_DEBUG_LITE_CMD;
|
|
break;
|
|
case DATA_FORMAT_DEBUG_LITE_WINDOW:
|
|
debug_ctrl = DATA_FORMAT_DEBUG_LITE_WINDOW_CMD;
|
|
ctrl = DATA_FORMAT_DEBUG_LITE_CMD;
|
|
break;
|
|
case DATA_FORMAT_DEBUG_LITE_AREA:
|
|
if (data == NULL) {
|
|
ILI_ERR("DATA_FORMAT_DEBUG_LITE_AREA error cmd\n");
|
|
return -1;
|
|
}
|
|
debug_ctrl = DATA_FORMAT_DEBUG_LITE_AREA_CMD;
|
|
ctrl = DATA_FORMAT_DEBUG_LITE_CMD;
|
|
data_type = data[0];
|
|
cmd[4] = data[1];
|
|
cmd[5] = data[2];
|
|
cmd[6] = data[3];
|
|
cmd[7] = data[4];
|
|
break;
|
|
}
|
|
cmd[0] = P5_X_NEW_CONTROL_FORMAT;
|
|
cmd[1] = ctrl;
|
|
cmd[2] = data_type;
|
|
cmd[3] = debug_ctrl;
|
|
cmd[9] = 0x0A; /* pre command */
|
|
|
|
ret = ilits->wrapper(cmd, 10, buf, 2, ON, OFF);
|
|
if (ret < 0) {
|
|
ILI_ERR("check debug lite function failed\n");
|
|
return ret;
|
|
}
|
|
|
|
ILI_DBG("check ,0x%X\n", buf[0]);
|
|
return buf[0];
|
|
}
|
|
|
|
int ili_ic_report_rate_get(void)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd[3] = {0}, rxbuf[4] = {0};
|
|
|
|
cmd[0] = 0x01;
|
|
cmd[1] = 0x1F;
|
|
cmd[2] = 0x01;
|
|
|
|
ret = ilits->wrapper(cmd, 3, rxbuf, 4, OFF, OFF);
|
|
if (ret < 0) {
|
|
ILI_ERR("Write TP function failed\n");
|
|
return ret;
|
|
}
|
|
ILI_INFO("get report rate mode = %x, rxbuf = %x %x %x %x \n", rxbuf[3], rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3]);
|
|
ret = rxbuf[3];
|
|
return ret;
|
|
}
|
|
|
|
int ili_ic_report_rate_register_set(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (ili_ice_mode_ctrl(ENABLE, OFF) < 0)
|
|
ILI_ERR("Enable ice mode failed\n");
|
|
ILI_INFO("current_report_rate_mode: %X when reset\n", ilits->current_report_rate_mode);
|
|
ret = ili_ice_mode_write(0x4005E, (0x5A00 | (ilits->current_report_rate_mode & 0xFF)), 2);
|
|
if (ret < 0)
|
|
ILI_ERR("write report rate password failed\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static struct ilitek_ic_info chip;
|
|
|
|
void ili_ic_init(void)
|
|
{
|
|
chip.pid_addr = TDDI_PID_ADDR;
|
|
chip.second_pid_addr = TDDI_SECOND_PID_ADDR;
|
|
chip.pc_counter_addr = TDDI_PC_COUNTER_ADDR;
|
|
chip.pc_latch_addr = TDDI_PC_LATCH_ADDR;
|
|
chip.otp_addr = TDDI_OTP_ID_ADDR;
|
|
chip.ana_addr = TDDI_ANA_ID_ADDR;
|
|
chip.reset_addr = TDDI_CHIP_RESET_ADDR;
|
|
|
|
ilits->protocol = &protocol_info[PROTOCL_VER_NUM - 1];
|
|
ilits->chip = &chip;
|
|
}
|