From 5f1ad88c974789c0cbc9d641c035347056cf8420 Mon Sep 17 00:00:00 2001 From: shkwak Date: Fri, 10 Jan 2025 12:43:01 +0900 Subject: [PATCH 1/3] driver/input: Add ist415 semaphore and recording mode - Apply IC reset semaphore. - Apply recording mode. Signed-off-by: sanghoon --- os/drivers/input/ist415.c | 36 ++++++-- os/drivers/input/ist415.h | 4 +- os/drivers/input/ist415_misc.c | 141 +++++++++++++++++++++++++++++++ os/drivers/input/ist415_misc.h | 11 +++ os/drivers/input/ist415_update.c | 10 +++ 5 files changed, 195 insertions(+), 7 deletions(-) diff --git a/os/drivers/input/ist415.c b/os/drivers/input/ist415.c index 61ace2adef..61d57a598a 100644 --- a/os/drivers/input/ist415.c +++ b/os/drivers/input/ist415.c @@ -336,6 +336,10 @@ static int ist415_process_event(struct ist415_dev_s *dev) kmm_free(touch_event); + if (dev->rec_mode) { + ist415_recording(dev); + } + return OK; } @@ -406,6 +410,8 @@ static int ist415_cmd(struct touchscreen_s *upper, int argc, char **argv) ret = ist415_set_dbg(dev, argc, argv); } else if (strncmp(argv[1], "selftest", 9) == 0) { ist415_selftest(dev); + } else if (strncmp(argv[1], "rec", 4) == 0) { + ret = ist415_rec_mode(dev, argc, argv); } else { ret = -EINVAL; } @@ -490,6 +496,8 @@ static void ist415_stop_device(struct ist415_dev_s *dev) { ist415vdbg("%s\n", __func__); + sem_wait(&dev->sem); + dev->suspend = true; if (dev->knockknock) { @@ -503,6 +511,10 @@ static void ist415_stop_device(struct ist415_dev_s *dev) ist415_disable(dev); ist415_power_off(dev); } + + ist415_forced_release(dev); + + sem_post(&dev->sem); } /**************************************************************************** @@ -513,6 +525,8 @@ static void ist415_start_device(struct ist415_dev_s *dev) { ist415vdbg("%s\n", __func__); + sem_wait(&dev->sem); + dev->suspend = false; if (dev->knockknock) { @@ -525,6 +539,8 @@ static void ist415_start_device(struct ist415_dev_s *dev) ist415_enable(dev); ist415_start(dev); } + + sem_post(&dev->sem); } /**************************************************************************** @@ -553,10 +569,10 @@ static void ist415_enable_touch(struct touchscreen_s *upper) * Name: ist415_lockup_work ****************************************************************************/ -static void ist415_lookup_work(struct ist415_dev_s *dev) +static void ist415_lockup_work(struct ist415_dev_s *dev) { - u32 touch_status = 0; - u32 scan_count = 0; + uint32_t touch_status = 0; + uint32_t scan_count = 0; int ret = 0; if (dev->irq_working == false) { @@ -595,6 +611,8 @@ static void ist415_lookup_work(struct ist415_dev_s *dev) dev->alive_retry++; ist415dbg("Retry touch status(%d)\n", dev->alive_retry); if (dev->alive_retry == IST415_MAX_ALIVE_CNT) { + sem_wait(&dev->sem); + ist415_disable(dev); ist415_forced_release(dev); ist415_reset(dev, false); @@ -615,8 +633,11 @@ static void ist415_lookup_work(struct ist415_dev_s *dev) ist415_start(dev); ist415_enable(dev); } + dev->alive_retry = 0; dev->scan_count = 0; + + sem_post(&dev->sem); } else { (void)wd_start(dev->wdog, MSEC2TICK(IST415_LOOKUP_RETRY_MS), (wdentry_t)ist415_timer_handler, 1, (uint32_t)dev); } @@ -630,7 +651,7 @@ static void ist415_timer_handler(int argc, uint32_t arg1) { struct ist415_dev_s *dev = (struct ist415_dev_s *)arg1; - work_queue(HPWORK, &dev->work, (worker_t)ist415_lookup_work, dev, 0); + work_queue(HPWORK, &dev->work, (worker_t)ist415_lockup_work, dev, 0); } /**************************************************************************** @@ -672,7 +693,7 @@ static int ist415_event_thread(int argc, char **argv) if (ist415_process_event(dev) != OK) { ist415dbg("Fail to process event\n"); } - + dev->irq_working = false; dev->lower->ops->irq_enable(dev->lower); } @@ -1076,7 +1097,7 @@ int ist415_initialize(const char *path, struct i2c_dev_s *i2c, struct ist415_con dev->enable = false; dev->pre_enable = false; dev->suspend = false; - dev->log = IST415_LOG_LEVEL_ERRO; + dev->log = IST415_LOG_LEVEL_INFO; dev->sys_mode = SYS_MODE_TOUCH; dev->touch_type = (1 << TOUCH_TYPE_NORMAL) | (1 << TOUCH_TYPE_WET) | (1 << TOUCH_TYPE_PALMLARGE); @@ -1105,6 +1126,9 @@ int ist415_initialize(const char *path, struct i2c_dev_s *i2c, struct ist415_con ist415_disable(dev); + // Semaphore reset scenario + sem_init(&dev->sem, 0, 1); + dev->lower->handler = touch_interrupt; sem_init(&dev->wait_irq, 0, 0); itoa((int)dev, parm_buf, 16); diff --git a/os/drivers/input/ist415.h b/os/drivers/input/ist415.h index 452e4ea42d..272b0897f1 100644 --- a/os/drivers/input/ist415.h +++ b/os/drivers/input/ist415.h @@ -443,7 +443,7 @@ struct ist415_dev_s { bool rec_idle; int rec_type; int rec_delay; - uint32_t recording_scancnt; + uint32_t rec_scancnt; uint32_t rec_addr; uint32_t rec_size; @@ -460,6 +460,8 @@ struct ist415_dev_s { int pid; sem_t wait_irq; + sem_t sem; + WDOG_ID wdog; struct work_s work; }; diff --git a/os/drivers/input/ist415_misc.c b/os/drivers/input/ist415_misc.c index b94de532ad..2fa12adba7 100644 --- a/os/drivers/input/ist415_misc.c +++ b/os/drivers/input/ist415_misc.c @@ -340,9 +340,13 @@ int ist415_get_info(struct ist415_dev_s *dev) void ist415_autocalibration(struct ist415_dev_s *dev) { + sem_wait(&dev->sem); + ist415_calibrate(dev, 1); ist415_start(dev); ist415_enable(dev); + + sem_post(&dev->sem); } /**************************************************************************** @@ -787,3 +791,140 @@ int ist415_selftest(struct ist415_dev_s *dev) return ret; } + +/**************************************************************************** + * Name: ist415_rec_mode + * + * Description + * This function is called by Uart Command. + ****************************************************************************/ + +int ist415_rec_mode(struct ist415_dev_s *dev, int argc, char **argv) +{ + int mode; + uint8_t data; + char header[32]; + int ret = 0; + + if (argc < 4) { + return -EINVAL; + } + + mode = atoi(argv[2]); + ist415vdbg("rec mode : %s\n", mode ? "start" : "stop"); + + ret = ist415_i2c_write(dev, HCOM_SET_REC_MODE, (uint8_t *)&mode, 1); + if (ret) { + return -ENODEV; + } + + dev->rec_mode = mode; + if (dev->rec_mode) { + dev->rec_delay = atoi(argv[3]); + ist415vdbg("rec delay : %d\n", dev->rec_delay); + + snprintf(header, sizeof(header), "%s2 2 %d, %d, %d, %d\n", RECS_TAG, dev->slf_node_len, dev->tx_num, dev->rx_num, dev->rec_size); + ist415vdbg("%s", header); + + msleep(100); + + data = REC_START_SCAN; + ret = ist415_i2c_write(dev, HCOM_SET_REC_MODE, (uint8_t *)&data, 1); + if (ret) { + return -ENODEV; + } + } + + return OK; +} + +void ist415_recording(struct ist415_dev_s *dev) +{ + uint32_t *buf32 = NULL; + uint32_t fb = 0; + uint32_t scancnt = 0; + uint8_t data = 0; + int size = 0; + char logbuf[512] = { 0, }; + int offset = 0; + int i; + int ret = 0; + + if (dev->rec_idle && (dev->rec_mode > REC_ENABLE)) { + goto rec_end; + } + + msleep(dev->rec_delay); + + ret = ist415_i2c_read_da(dev, IST415_TOUCH_STATUS, (uint32_t *)&scancnt, 1); + if (ret) { + ist415dbg("Fail to read scan count\n"); + goto rec_end; + } + + if (dev->rec_scancnt == scancnt) { + ist415dbg("Same rec scan count\n"); + goto rec_end; + } + + dev->rec_scancnt = scancnt; + + buf32 = (uint32_t *)kmm_malloc(dev->rec_size + ((dev->slf_node_len + dev->mtl_node_len) * sizeof(uint32_t))); + if (!buf32) { + ist415dbg("Fail to allocate buf32\n"); + goto rec_end; + } + + if (dev->rec_size > 0) { + ret = ist415_i2c_read_da(dev, dev->rec_addr, (uint32_t *)buf32, dev->rec_size / sizeof(uint32_t)); + if (ret) { + ist415dbg("Fail to reaqd rec data\n"); + goto rec_end; + } + } + + ret = ist415_i2c_read_da(dev, IST415_FB_SEL, (uint32_t *)&fb, 1); + if (ret) { + ist415dbg("Fail to read fb\n"); + goto rec_end; + } + + size = dev->rec_size / sizeof(uint32_t); + ret = ist415_i2c_read_da(dev, IST415_FB_SLF_ADDR(fb), (uint32_t *)(buf32 + size), + dev->slf_node_len); + if (ret) { + ist415dbg("Fail to read self data\n"); + goto rec_end; + } + + size += dev->slf_node_len; + ret = ist415_i2c_read_da(dev, IST415_FB_MTL_ADDR(fb), (uint32_t *)(buf32 + size), dev->mtl_node_len); + if (ret) { + ist415dbg("Fail to read mutual data\n"); + goto rec_end; + } + + size += dev->mtl_node_len; + + offset = snprintf(logbuf, sizeof(logbuf), "%s", RECS_TAG); + for (i = 1; i <= size; i++) { + offset += snprintf(logbuf + offset, sizeof(logbuf) - offset, "%08X ", buf32[i]); + if ((i % REC_PRINT_SIZE) == 0) { + ist415vdbg("%s", logbuf); + offset = snprintf(logbuf, sizeof(logbuf), "%s", RECC_TAG); + } + } + snprintf(logbuf + offset, sizeof(logbuf) - offset, "\n"); + ist415vdbg("%s", logbuf); + +rec_end: + if (buf32) { + kmm_free(buf32); + } + + data = REC_START_SCAN; + ret = ist415_i2c_write(dev, HCOM_SET_REC_MODE, (uint8_t *)&data, 1); + if (ret) { + ist415dbg("Fail to write rec start scan\n"); + } +} \ No newline at end of file diff --git a/os/drivers/input/ist415_misc.h b/os/drivers/input/ist415_misc.h index 0d1b8cd206..4a6b844734 100644 --- a/os/drivers/input/ist415_misc.h +++ b/os/drivers/input/ist415_misc.h @@ -45,6 +45,15 @@ #define REC_ENABLE 1 #define REC_DISABLE 0 +#define REC_PRINT_SIZE 50 + +#define RECS_TAG "[RECS] " +#define RECC_TAG "[RECC] " + +#define IST415_FB_SEL 0x3002002C +#define IST415_FB_MTL_ADDR(n) (n ? 0x40010000 : 0x40000000) +#define IST415_FB_SLF_ADDR(n) (n ? 0x40011768 : 0x40001768) + // SelfTest //#define USE_SELFTEST_CS @@ -83,5 +92,7 @@ void ist415_run_intr_debug(struct ist415_dev_s *dev); void ist415_display_cpc(struct ist415_dev_s *dev); void ist415_display_rawdata(struct ist415_dev_s *dev); int ist415_selftest(struct ist415_dev_s *dev); +int ist415_rec_mode(struct ist415_dev_s *dev, int argc, char **argv); +void ist415_recording(struct ist415_dev_s *dev); #endif /* __DRIVERS_INPUT_IST415_MISC_H */ diff --git a/os/drivers/input/ist415_update.c b/os/drivers/input/ist415_update.c index e5e75b0630..e41c58b453 100644 --- a/os/drivers/input/ist415_update.c +++ b/os/drivers/input/ist415_update.c @@ -581,7 +581,9 @@ int ist415_check_fw(struct ist415_dev_s *dev) ist415vdbg("Main : %08X Core: %x, Config %x, Release: %x, Test: %x\n", fw->bin.main_ver, fw->bin.core_ver, fw->bin.config_ver, fw->bin.release_ver, fw->bin.test_ver); + sem_wait(&dev->sem); ret = ist415_check_auto_update(dev); + sem_post(&dev->sem); if (ret >= 0) { kmm_free(fw->buf); return OK; @@ -589,6 +591,8 @@ int ist415_check_fw(struct ist415_dev_s *dev) ist415vdbg("Update version. release(core, config, test): %x(%x, %x, %x) -> %x(%x, %x, %x)\n", fw->cur.release_ver, fw->cur.core_ver, fw->cur.config_ver, fw->cur.test_ver, fw->bin.release_ver, fw->bin.core_ver, fw->bin.config_ver, fw->bin.test_ver); + sem_wait(&dev->sem); + retry = IST415_RETRY_CNT; while (retry--) { ret = ist415_fw_update(dev, fw->buf, fw->buf_size); @@ -598,6 +602,8 @@ int ist415_check_fw(struct ist415_dev_s *dev) } } + sem_post(&dev->sem); + kmm_free(fw->buf); return ret; } @@ -659,6 +665,8 @@ int ist415_force_update(struct ist415_dev_s *dev, int argc, char **argv) ist415vdbg("Update version. release(core, config, test): %x(%x, %x, %x) -> %x(%x, %x, %x)\n", fw->cur.release_ver, fw->cur.core_ver, fw->cur.config_ver, fw->cur.test_ver, fw->bin.release_ver, fw->bin.core_ver, fw->bin.config_ver, fw->bin.test_ver); + sem_wait(&dev->sem); + ist415_disable(dev); ret = ist415_fw_update(dev, fw->buf, fw->buf_size); @@ -671,6 +679,8 @@ int ist415_force_update(struct ist415_dev_s *dev, int argc, char **argv) ist415_start(dev); ist415_enable(dev); + sem_post(&dev->sem); + kmm_free(fw->buf); return ret; From d8fcb2e5759b3ddbf2dbd645ffca753be9fd1c76 Mon Sep 17 00:00:00 2001 From: shkwak Date: Fri, 10 Jan 2025 13:58:42 +0900 Subject: [PATCH 2/3] drives/input: Change the called sem_wait() code. The sem_wait() code modified the called part. - sem_wait(&dev->sem) + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } Signed-off-by: sanghoon --- os/drivers/input/ist415.c | 12 +++++++++--- os/drivers/input/ist415_misc.c | 9 +++++++-- os/drivers/input/ist415_update.c | 12 +++++++++--- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/os/drivers/input/ist415.c b/os/drivers/input/ist415.c index 61d57a598a..dc00c05efa 100644 --- a/os/drivers/input/ist415.c +++ b/os/drivers/input/ist415.c @@ -496,7 +496,9 @@ static void ist415_stop_device(struct ist415_dev_s *dev) { ist415vdbg("%s\n", __func__); - sem_wait(&dev->sem); + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } dev->suspend = true; @@ -525,7 +527,9 @@ static void ist415_start_device(struct ist415_dev_s *dev) { ist415vdbg("%s\n", __func__); - sem_wait(&dev->sem); + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } dev->suspend = false; @@ -611,7 +615,9 @@ static void ist415_lockup_work(struct ist415_dev_s *dev) dev->alive_retry++; ist415dbg("Retry touch status(%d)\n", dev->alive_retry); if (dev->alive_retry == IST415_MAX_ALIVE_CNT) { - sem_wait(&dev->sem); + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } ist415_disable(dev); ist415_forced_release(dev); diff --git a/os/drivers/input/ist415_misc.c b/os/drivers/input/ist415_misc.c index 2fa12adba7..9537573863 100644 --- a/os/drivers/input/ist415_misc.c +++ b/os/drivers/input/ist415_misc.c @@ -340,7 +340,9 @@ int ist415_get_info(struct ist415_dev_s *dev) void ist415_autocalibration(struct ist415_dev_s *dev) { - sem_wait(&dev->sem); + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } ist415_calibrate(dev, 1); ist415_start(dev); @@ -838,6 +840,9 @@ int ist415_rec_mode(struct ist415_dev_s *dev, int argc, char **argv) return OK; } +/**************************************************************************** + * Name: ist415_recording + ****************************************************************************/ void ist415_recording(struct ist415_dev_s *dev) { uint32_t *buf32 = NULL; @@ -927,4 +932,4 @@ void ist415_recording(struct ist415_dev_s *dev) if (ret) { ist415dbg("Fail to write rec start scan\n"); } -} \ No newline at end of file +} diff --git a/os/drivers/input/ist415_update.c b/os/drivers/input/ist415_update.c index e41c58b453..4a1e7970e5 100644 --- a/os/drivers/input/ist415_update.c +++ b/os/drivers/input/ist415_update.c @@ -581,7 +581,9 @@ int ist415_check_fw(struct ist415_dev_s *dev) ist415vdbg("Main : %08X Core: %x, Config %x, Release: %x, Test: %x\n", fw->bin.main_ver, fw->bin.core_ver, fw->bin.config_ver, fw->bin.release_ver, fw->bin.test_ver); - sem_wait(&dev->sem); + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } ret = ist415_check_auto_update(dev); sem_post(&dev->sem); if (ret >= 0) { @@ -591,7 +593,9 @@ int ist415_check_fw(struct ist415_dev_s *dev) ist415vdbg("Update version. release(core, config, test): %x(%x, %x, %x) -> %x(%x, %x, %x)\n", fw->cur.release_ver, fw->cur.core_ver, fw->cur.config_ver, fw->cur.test_ver, fw->bin.release_ver, fw->bin.core_ver, fw->bin.config_ver, fw->bin.test_ver); - sem_wait(&dev->sem); + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } retry = IST415_RETRY_CNT; while (retry--) { @@ -665,7 +669,9 @@ int ist415_force_update(struct ist415_dev_s *dev, int argc, char **argv) ist415vdbg("Update version. release(core, config, test): %x(%x, %x, %x) -> %x(%x, %x, %x)\n", fw->cur.release_ver, fw->cur.core_ver, fw->cur.config_ver, fw->cur.test_ver, fw->bin.release_ver, fw->bin.core_ver, fw->bin.config_ver, fw->bin.test_ver); - sem_wait(&dev->sem); + while (sem_wait(&dev->sem) != OK) { + ASSERT(get_errno() == EINTR); + } ist415_disable(dev); From c13ab7e7a0615c8a189fec75191af162e250ca3d Mon Sep 17 00:00:00 2001 From: shkwak Date: Tue, 14 Jan 2025 17:28:24 +0900 Subject: [PATCH 3/3] * drives/input: Revert the log level. Log level : IST415_LOG_LEVEL_INFO -> IST415_LOG_LEVEL_ERRO --- os/drivers/input/ist415.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/drivers/input/ist415.c b/os/drivers/input/ist415.c index dc00c05efa..d9a0ec5729 100644 --- a/os/drivers/input/ist415.c +++ b/os/drivers/input/ist415.c @@ -699,7 +699,7 @@ static int ist415_event_thread(int argc, char **argv) if (ist415_process_event(dev) != OK) { ist415dbg("Fail to process event\n"); } - + dev->irq_working = false; dev->lower->ops->irq_enable(dev->lower); } @@ -1103,7 +1103,7 @@ int ist415_initialize(const char *path, struct i2c_dev_s *i2c, struct ist415_con dev->enable = false; dev->pre_enable = false; dev->suspend = false; - dev->log = IST415_LOG_LEVEL_INFO; + dev->log = IST415_LOG_LEVEL_ERRO; dev->sys_mode = SYS_MODE_TOUCH; dev->touch_type = (1 << TOUCH_TYPE_NORMAL) | (1 << TOUCH_TYPE_WET) | (1 << TOUCH_TYPE_PALMLARGE);