Files

408 lines
11 KiB
C

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <common.h>
#include <malloc.h>
#include <command.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <partition_table.h>
#include <amlogic/aml_model.h>
#include "model_log.h"
#include "model_size.h"
#include "model.h"
#define LOG_TAG "model"
#define LOG_NDEBUG 0
#ifndef CONFIG_YOCTO
#define DEFAULT_MODEL_SUM_PATH1 "/odm/etc/tvconfig/model/model_sum.ini"
#define DEFAULT_MODEL1_SUM_PATH1 "/odm/etc/tvconfig/model/model1_sum.ini"
#define DEFAULT_MODEL2_SUM_PATH1 "/odm/etc/tvconfig/model/model2_sum.ini"
#else
#define DEFAULT_MODEL_SUM_PATH1 "/vendor/etc/tvconfig/model/model_sum.ini"
#define DEFAULT_MODEL1_SUM_PATH1 "/vendor/etc/tvconfig/model/model1_sum.ini"
#define DEFAULT_MODEL2_SUM_PATH1 "/vendor/etc/tvconfig/model/model2_sum.ini"
#endif
#define DEFAULT_MODEL_SUM_PATH2 "/odm_ext/etc/tvconfig/model/model_sum.ini"
#define DEFAULT_MODEL1_SUM_PATH2 "/odm_ext/etc/tvconfig/model/model1_sum.ini"
#define DEFAULT_MODEL2_SUM_PATH2 "/odm_ext/etc/tvconfig/model/model2_sum.ini"
/********************************* common api *************************************/
int model_set_panel_misc(struct panel_misc_s *misc_attr)
{
int tmp_val = 0;
char *rev_ctrl = NULL;
char *ret = NULL;
char param[32], buf[64] = {0};
unsigned int panel_reverse = 0, display_layer = 0, n;
if (!misc_attr)
return -1;
if (misc_attr->disp_idx == 0xff)
return -1;
tmp_val = env_get_ulong("model_outputmode_bypass", 10, 0);
if (tmp_val) {
ALOGI("model_outputmode_bypass\n");
goto model_set_panel_misc_next;
}
if (misc_attr->disp_idx == 0)
sprintf(param, "outputmode");
else
sprintf(param, "outputmode%d", misc_attr->disp_idx + 1);
ALOGD("%s: %s is (%s)\n", __func__, param, misc_attr->outputmode);
snprintf(buf, 63, "setenv %s %s", param, misc_attr->outputmode);
run_command(buf, 0);
model_set_panel_misc_next:
tmp_val = env_get_ulong("model_connector_bypass", 10, 0);
if (tmp_val) {
ALOGI("model_connector_bypass\n");
goto model_set_panel_misc_next2;
}
sprintf(param, "connector%d_type", misc_attr->disp_idx);
misc_attr->connector_type[sizeof(misc_attr->connector_type) - 1] = '\0';
ret = strstr(misc_attr->connector_type, "_");
if (ret)
misc_attr->connector_type[ret - misc_attr->connector_type] = '-';
ALOGD("%s: %s is (%s)\n", __func__, param, misc_attr->connector_type);
snprintf(buf, 63, "setenv %s %s", param, misc_attr->connector_type);
run_command(buf, 0);
model_set_panel_misc_next2:
if (misc_attr->version >= 2)
goto model_set_panel_misc_next3;
rev_ctrl = env_get("reverse_ctrl");
if (!rev_ctrl || strcmp(rev_ctrl, "0") == 0) {
ALOGD("%s: panel_reverse is (%s)\n", __func__, misc_attr->panel_reverse);
if (strcmp(misc_attr->panel_reverse, "null") == 0 ||
strcmp(misc_attr->panel_reverse, "0") == 0 ||
strcmp(misc_attr->panel_reverse, "false") == 0 ||
strcmp(misc_attr->panel_reverse, "no_rev") == 0) {
panel_reverse = 0;
} else if (strcmp(misc_attr->panel_reverse, "true") == 0 ||
strcmp(misc_attr->panel_reverse, "1") == 0 ||
strcmp(misc_attr->panel_reverse, "have_rev") == 0) {
panel_reverse = 1;
} else if (strcmp(misc_attr->panel_reverse, "x_rev") == 0 ||
strcmp(misc_attr->panel_reverse, "2") == 0) {
panel_reverse = 2;
} else if (strcmp(misc_attr->panel_reverse, "y_rev") == 0 ||
strcmp(misc_attr->panel_reverse, "3") == 0) {
panel_reverse = 3;
} else {
panel_reverse = 0;
}
if (panel_reverse) {
if (strcmp(misc_attr->display_layer, "osd0") == 0 ||
strcmp(misc_attr->display_layer, "0") == 0)
display_layer = 0;
else if (strcmp(misc_attr->display_layer, "osd1") == 0 ||
strcmp(misc_attr->display_layer, "1") == 0)
display_layer = 1;
else
display_layer = 4;
}
switch (panel_reverse) {
case 1:
run_command("setenv panel_reverse 1", 0);
switch (display_layer) {
case 0:
run_command("setenv osd_reverse osd0,true", 0);
break;
case 1:
run_command("setenv osd_reverse osd1,true", 0);
break;
default:
run_command("setenv osd_reverse all,true", 0);
break;
}
run_command("setenv video_reverse 1", 0);
break;
case 2:
run_command("setenv panel_reverse 2", 0);
switch (display_layer) {
case 0:
run_command("setenv osd_reverse osd0,x_rev", 0);
break;
case 1:
run_command("setenv osd_reverse osd1,x_rev", 0);
break;
default:
run_command("setenv osd_reverse all,x_rev", 0);
break;
}
run_command("setenv video_reverse 2", 0);
break;
case 3:
run_command("setenv panel_reverse 3", 0);
switch (display_layer) {
case 0:
run_command("setenv osd_reverse osd0,y_rev", 0);
break;
case 1:
run_command("setenv osd_reverse osd1,y_rev", 0);
break;
default:
run_command("setenv osd_reverse all,y_rev", 0);
break;
}
run_command("setenv video_reverse 3", 0);
break;
default:
run_command("setenv panel_reverse 0", 0);
run_command("setenv osd_reverse n", 0);
run_command("setenv video_reverse 0", 0);
break;
}
}
return 0;
model_set_panel_misc_next3:
n = misc_attr->hmirror_val << 1 | misc_attr->vmirror_val;
snprintf(buf, 64, "setenv osd_reverse %s%s",
misc_attr->disp_layer_val == 0 ?
"osd0," : misc_attr->disp_layer_val == 1 ? "osd1," : "all,",
n == 0 ? "n" : n == 1 ? "y_rev" : n == 2 ? "x_rev" : "true");
ALOGD("%s: %s\n", __func__, buf);
run_command(buf, 0);
snprintf(buf, 64, "setenv video_reverse %c",
n == 0 ? '0' : n == 1 ? '3' : n == 2 ? '2' : '1');
ALOGD("%s: %s\n", __func__, buf);
run_command(buf, 0);
snprintf(buf, 64, "setenv panel_reverse %c",
n == 0 ? '0' : n == 1 ? '3' : n == 2 ? '2' : '1');
ALOGD("%s: %s\n", __func__, buf);
run_command(buf, 0);
return 0;
}
/********************************* cmd api *************************************/
static int parse_model_sum(int index, const char *file_name, char *model_name)
{
void *local_ini_mem, *psec;
const char *str = NULL;
#ifdef CONFIG_AML_LCD
char model_panel[16], *p;
#endif
local_ini_mem = handle_ini_file_parse(file_name, 0);
if (!local_ini_mem) {
ALOGE("%s: error: %s\n", __func__, file_name);
return -1;
}
psec = handle_ini_get_section(local_ini_mem, model_name);
if (!psec) {
ALOGE("%s: section %s: error: %s\n", __func__, model_name, file_name);
return -1;
}
#ifdef CONFIG_AML_LCD
str = handle_ini_get_str(local_ini_mem, psec, "PANELINI_PATH", "null");
if (strcmp(str, "null") == 0)
ALOGE("%s: %s: invalid PANELINI_PATH!\n", __func__, model_name);
if (index == 0)
sprintf(model_panel, "model_panel");
else
sprintf(model_panel, "model%d_panel", index);
env_set(model_panel, str);
set_panel_file_path(index, str);
p = strrchr(str, '.');
if (p && (!strncmp(p + 1, "ini", 3) || !strncmp(p + 1, "INI", 3)))
set_lcd_panel_file_type(index, PANEL_FILE_INI);
else //regard as json file, will be parse later
set_lcd_panel_file_type(index, PANEL_FILE_JSON);
#endif
str = handle_ini_get_str(local_ini_mem, psec, "EDID_14_FILE_PATH", "null");
if (strcmp(str, "null") == 0)
ALOGD("%s: %s: invalid EDID_14_FILE_PATH!\n", __func__, model_name);
env_set("model_edid", str);
/*
*str = handle_ini_get_str(local_ini_mem, psec, "PQINI_PATH", "null");
*env_set("model_pq", str);
*
*str = handle_ini_get_str(local_ini_mem, psec, "AMLOGIC_AUDIO_EFFECT_INI_PATH", "null");
*env_set("model_audio", str);
*/
handle_ini_parser_uninit(local_ini_mem);
return 0;
}
static const char *get_model_sum_path(int index)
{
char *model_path, str[15];
if (index == 0)
sprintf(str, "model_path");
else
sprintf(str, "model%d_path", index);
model_path = env_get(str);
if (!model_path) {
if (dynamic_partition) {
if (index == 2)
return DEFAULT_MODEL2_SUM_PATH2;
else if (index == 1)
return DEFAULT_MODEL1_SUM_PATH2;
else
return DEFAULT_MODEL_SUM_PATH2;
} else {
if (index == 2)
return DEFAULT_MODEL2_SUM_PATH1;
else if (index == 1)
return DEFAULT_MODEL1_SUM_PATH1;
else
return DEFAULT_MODEL_SUM_PATH1;
}
}
printf("%s: %s\n", __func__, model_path);
return model_path;
}
#ifdef CONFIG_AML_LCD
static char *model_list_panel_path(int index)
{
char *path_str, str[15];
if (index == 0)
sprintf(str, "model_panel");
else
sprintf(str, "model%d_panel", index);
path_str = env_get(str);
if (path_str)
printf("current %s: %s\n", str, path_str);
return path_str;
}
#endif
static int handle_model_list(void)
{
void *local_ini_mem;
const char *model, *model_path;
char str[15];
int i;
for (i = 0; i < 3; i++) {
if (i == 0)
sprintf(str, "model_name");
else
sprintf(str, "model%d_name", i);
model = env_get(str);
if (!model) {
ALOGD("%s: no %s\n", __func__, str);
continue;
}
printf("current %s: %s\n", str, model);
#ifdef CONFIG_AML_LCD
model_list_panel_path(i);
#endif
model_path = get_model_sum_path(i);
local_ini_mem = handle_ini_file_parse(model_path, 0);
if (!local_ini_mem) {
ALOGE("%s: error: %s\n", __func__, model_path);
return -1;
}
printf("%s list:\n", str);
handle_ini_list_section(local_ini_mem);
printf("\n");
handle_ini_parser_uninit(local_ini_mem);
}
return 0;
}
int handle_model_sum(void)
{
char *model, str[15];
unsigned int print_flag;
int i;
print_flag = env_get_ulong("model_debug_print", 10, 0xffff);
if (print_flag != 0xffff) {
model_set_log_level(print_flag);
printf("model_debug_flag: %d\n", print_flag);
}
for (i = 0; i < 3; i++) {
if (i == 0)
sprintf(str, "model_name");
else
sprintf(str, "model%d_name", i);
model = env_get(str);
if (!model) {
ALOGD("%s: no %s\n", __func__, str);
continue;
}
ALOGI("%s: %s: %s\n", __func__, str, model);
parse_model_sum(i, get_model_sum_path(i), model);
}
return 0;
}
/********************************* cmd *************************************/
static int do_ini_model_list(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int ret;
if (argc == 1) {
ret = handle_model_list();
return ret;
}
if (strcmp(argv[1], "lcd") == 0 || strcmp(argv[1], "panel") == 0) {
aml_lcd_panel_dump(0, NULL);
return 0;
} else if (strcmp(argv[1], "lcd1") == 0 || strcmp(argv[1], "panel1") == 0) {
aml_lcd_panel_dump(1, NULL);
return 0;
} else if (strcmp(argv[1], "lcd2") == 0 || strcmp(argv[1], "panel2") == 0) {
aml_lcd_panel_dump(2, NULL);
return 0;
}
return CMD_RET_USAGE;
}
U_BOOT_CMD(model_list, 4, 0, do_ini_model_list,
"list ini model name",
" "
);
static int do_ini_model(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int ret;
if (argc > 1)
return CMD_RET_USAGE;
ret = handle_model_sum();
return ret;
}
U_BOOT_CMD(ini_model, 4, 0, do_ini_model,
"parse ini file by env model_name",
" "
);