From 7cb7dd1968028cb2583d4ae6f132a76c2bcbdd8e Mon Sep 17 00:00:00 2001 From: Shaochan Liu Date: Fri, 18 Jan 2019 19:35:36 +0800 Subject: [PATCH] lcd: add wait for gpio input value support in lcd power step [2/2] PD#SWPL-3938 Problem: add wait for gpio input value support in lcd power step Solution: add wait for gpio input value support in lcd power step Verify: verify by t962x-r311 Change-Id: Ie1c4ec6f9f5d91332b6b20e1d1bd2adde17e547b Signed-off-by: Shaochan Liu --- drivers/amlogic/media/vout/lcd/lcd_common.c | 9 ++++- drivers/amlogic/media/vout/lcd/lcd_debug.c | 41 ++++++++++++++++----- drivers/amlogic/media/vout/lcd/lcd_vout.c | 24 +++++++++--- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.c b/drivers/amlogic/media/vout/lcd/lcd_common.c index 33308db1c90a..ff11fa3c352c 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.c +++ b/drivers/amlogic/media/vout/lcd/lcd_common.c @@ -411,6 +411,9 @@ int lcd_power_load_from_dts(struct lcd_config_s *pconf, int i, j; unsigned int index; + if (lcd_debug_print_flag) + LCDPR("%s\n", __func__); + if (child == NULL) { LCDPR("error: failed to get %s\n", pconf->lcd_propname); return -1; @@ -447,6 +450,7 @@ int lcd_power_load_from_dts(struct lcd_config_s *pconf, index = lcd_power->power_on_step[i].index; switch (lcd_power->power_on_step[i].type) { case LCD_POWER_TYPE_CPU: + case LCD_POWER_TYPE_WAIT_GPIO: if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; @@ -501,6 +505,7 @@ int lcd_power_load_from_dts(struct lcd_config_s *pconf, index = lcd_power->power_off_step[i].index; switch (lcd_power->power_off_step[i].type) { case LCD_POWER_TYPE_CPU: + case LCD_POWER_TYPE_WAIT_GPIO: if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; @@ -546,8 +551,6 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf, /* power: (5byte * n) */ p = buf + len; - if (lcd_debug_print_flag) - LCDPR("power_on step:\n"); i = 0; while (i < LCD_PWR_STEP_MAX) { pconf->lcd_power->power_on_step_max = i; @@ -575,6 +578,7 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf, index = pconf->lcd_power->power_on_step[i].index; switch (pconf->lcd_power->power_on_step[i].type) { case LCD_POWER_TYPE_CPU: + case LCD_POWER_TYPE_WAIT_GPIO: if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; @@ -627,6 +631,7 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf, index = pconf->lcd_power->power_off_step[j].index; switch (pconf->lcd_power->power_off_step[j].type) { case LCD_POWER_TYPE_CPU: + case LCD_POWER_TYPE_WAIT_GPIO: if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; diff --git a/drivers/amlogic/media/vout/lcd/lcd_debug.c b/drivers/amlogic/media/vout/lcd/lcd_debug.c index 6733d9822217..dff52544f4ef 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_debug.c +++ b/drivers/amlogic/media/vout/lcd/lcd_debug.c @@ -231,6 +231,7 @@ static int lcd_power_step_print(struct lcd_config_s *pconf, int status, switch (power_step->type) { case LCD_POWER_TYPE_CPU: case LCD_POWER_TYPE_PMU: + case LCD_POWER_TYPE_WAIT_GPIO: n = lcd_debug_info_len(len + offset); len += snprintf((buf+len), n, "%d: type=%d, index=%d, value=%d, delay=%d\n", @@ -2223,37 +2224,59 @@ static ssize_t lcd_debug_power_step_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { int ret = 0; - unsigned int i, delay; + unsigned int i; + unsigned int tmp[2]; struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); struct lcd_power_ctrl_s *lcd_power_step; lcd_power_step = lcd_drv->lcd_config->lcd_power; switch (buf[1]) { case 'n': /* on */ - ret = sscanf(buf, "on %d %d", &i, &delay); - if (ret == 2) { + ret = sscanf(buf, "on %d %d %d", &i, &tmp[0], &tmp[1]); + if (ret == 3) { + if (i >= lcd_power_step->power_on_step_max) { + pr_info("invalid power_on step: %d, step_max: %d\n", + i, lcd_power_step->power_on_step_max); + return -EINVAL; + } + lcd_power_step->power_on_step[i].value = tmp[0]; + lcd_power_step->power_on_step[i].delay = tmp[1]; + pr_info( + "set power_on step %d value %d delay: %dms\n", + i, tmp[0], tmp[1]); + } else if (ret == 2) { if (i >= lcd_power_step->power_on_step_max) { pr_info("invalid power_on step: %d\n", i); return -EINVAL; } - lcd_power_step->power_on_step[i].delay = delay; + lcd_power_step->power_on_step[i].delay = tmp[0]; pr_info("set power_on step %d delay: %dms\n", - i, delay); + i, tmp[0]); } else { pr_info("invalid data\n"); return -EINVAL; } break; case 'f': /* off */ - ret = sscanf(buf, "off %d %d", &i, &delay); - if (ret == 1) { + ret = sscanf(buf, "off %d %d %d\n", &i, &tmp[0], &tmp[1]); + if (ret == 3) { if (i >= lcd_power_step->power_off_step_max) { pr_info("invalid power_off step: %d\n", i); return -EINVAL; } - lcd_power_step->power_off_step[i].delay = delay; + lcd_power_step->power_off_step[i].value = tmp[0]; + lcd_power_step->power_off_step[i].delay = tmp[1]; + pr_info( + "set power_off step %d value %d delay: %dms\n", + i, tmp[0], tmp[1]); + } else if (ret == 2) { + if (i >= lcd_power_step->power_off_step_max) { + pr_info("invalid power_off step: %d\n", i); + return -EINVAL; + } + lcd_power_step->power_off_step[i].delay = tmp[0]; pr_info("set power_off step %d delay: %dms\n", - i, delay); + i, tmp[0]); } else { pr_info("invalid data\n"); return -EINVAL; diff --git a/drivers/amlogic/media/vout/lcd/lcd_vout.c b/drivers/amlogic/media/vout/lcd/lcd_vout.c index 7521a49d4667..967d96ce7ccf 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_vout.c +++ b/drivers/amlogic/media/vout/lcd/lcd_vout.c @@ -259,7 +259,8 @@ static void lcd_power_ctrl(int status) #ifdef CONFIG_AMLOGIC_LCD_EXTERN struct aml_lcd_extern_driver_s *ext_drv; #endif - unsigned int i, index, value, temp; + unsigned int i, index, wait, temp; + int value = -1; int ret = 0; LCDPR("%s: %d\n", __func__, status); @@ -274,8 +275,8 @@ static void lcd_power_ctrl(int status) break; if (lcd_debug_print_flag) { LCDPR("power_ctrl: %d, step %d\n", status, i); - LCDPR("type=%d, index=%d, value=%d, delay=%d\n", - power_step->type, power_step->index, + LCDPR("%s: type=%d, index=%d, value=%d, delay=%d\n", + __func__, power_step->type, power_step->index, power_step->value, power_step->delay); } switch (power_step->type) { @@ -312,6 +313,19 @@ static void lcd_power_ctrl(int status) break; #endif case LCD_POWER_TYPE_WAIT_GPIO: + index = power_step->index; + lcd_cpu_gpio_set(index, LCD_GPIO_INPUT); + LCDPR("lcd_power_type_wait_gpio wait\n"); + for (wait = 0; wait < power_step->delay; wait++) { + value = lcd_cpu_gpio_get(index); + if (value == power_step->value) { + LCDPR("wait_gpio %d ok\n", value); + break; + } + mdelay(1); + } + if (wait == power_step->delay) + LCDERR("wait_gpio %d timeout!\n", value); break; case LCD_POWER_TYPE_CLK_SS: temp = lcd_driver->lcd_config->lcd_timing.ss_level; @@ -329,11 +343,11 @@ static void lcd_power_ctrl(int status) default: break; } - if (power_step->delay) + if ((power_step->type != LCD_POWER_TYPE_WAIT_GPIO) && + (power_step->delay > 0)) mdelay(power_step->delay); i++; } - if (lcd_debug_print_flag) LCDPR("%s: %d finished\n", __func__, status); }