From mboxrd@z Thu Jan 1 00:00:00 1970 From: Przemyslaw Marczak Date: Tue, 03 Dec 2013 19:03:23 +0100 Subject: [U-Boot] [PATCH 07/10] samsung: misc: Add LCD download menu. In-Reply-To: <1386093806-2948-1-git-send-email-p.marczak@samsung.com> References: <1386093806-2948-1-git-send-email-p.marczak@samsung.com> Message-ID: <1386093806-2948-8-git-send-email-p.marczak@samsung.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de New configs: - CONFIG_LCD_MENU - CONFIG_LCD_MENU_BOARD which depends on: CONFIG_MISC_INIT_R Signed-off-by: Przemyslaw Marczak --- board/samsung/common/keys.h | 78 ++++++++++ board/samsung/common/misc.c | 354 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 432 insertions(+) create mode 100644 board/samsung/common/keys.h diff --git a/board/samsung/common/keys.h b/board/samsung/common/keys.h new file mode 100644 index 0000000..48822d1 --- /dev/null +++ b/board/samsung/common/keys.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __SAMSUNG_KEYS__ +#define __SAMSUNG_KEYS__ + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include + +/* PMIC PWR ON key */ +#if defined(CONFIG_MACH_GONI) || defined(CONFIG_UNIVERSAL) + +#include + +#define KEY_PWR_PMIC_NAME "MAX8998_PMIC" + +#define KEY_PWR_STATUS_REG MAX8998_REG_STATUS1 +#define KEY_PWR_STATUS_MASK (1 << 7) + +#define KEY_PWR_INTERRUPT_REG MAX8998_REG_IRQ1 +#define KEY_PWR_INTERRUPT_MASK (1 << 7) + +#elif defined(CONFIG_TRATS) + +#include + +#define KEY_PWR_PMIC_NAME "MAX8997_PMIC" + +#define KEY_PWR_STATUS_REG MAX8997_REG_STATUS1 +#define KEY_PWR_STATUS_MASK (1 << 0) + +#define KEY_PWR_INTERRUPT_REG MAX8997_REG_INT1 +#define KEY_PWR_INTERRUPT_MASK (1 << 0) + +#elif defined(CONFIG_TRATS2) + +#include + +#define KEY_PWR_PMIC_NAME "MAX77686_PMIC" + +#define KEY_PWR_STATUS_REG MAX77686_REG_PMIC_STATUS1 +#define KEY_PWR_STATUS_MASK (1 << 0) + +#define KEY_PWR_INTERRUPT_REG MAX77686_REG_PMIC_INT1 +#define KEY_PWR_INTERRUPT_MASK (1 << 1) + +#endif /* PMIC PWR ON key */ + +/* GPIO for Vol Up and Vol Down */ +#if defined(CONFIG_MACH_GONI) + +#define KEY_VOL_UP_GPIO s5pc110_gpio_get(h3, 1) +#define KEY_VOL_DOWN_GPIO s5pc110_gpio_get(h3, 2) + +#elif defined(CONFIG_UNIVERSAL) || defined(CONFIG_TRATS) + +#define KEY_VOL_UP_GPIO exynos4_gpio_get(2, x2, 0) +#define KEY_VOL_DOWN_GPIO exynos4_gpio_get(2, x2, 1) + +#elif defined(CONFIG_TRATS2) + +#define KEY_VOL_UP_GPIO exynos4x12_gpio_get(2, x2, 2) +#define KEY_VOL_DOWN_GPIO exynos4x12_gpio_get(2, x3, 3) + +#else +#ifdef CONFIG_MISC_INIT_R +#warning Vol UP and Vol DOWN GPIO are undefined! +#endif +#endif /* GPIO for Vol Up and Vol Down */ + +#endif /* __ASSEMBLY__ */ +#endif /* __SAMSUNG_KEYS__ */ diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index fa97644..c792b87 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -8,8 +8,357 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "keys.h" #ifdef CONFIG_MISC_INIT_R +struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned); +int s5p_gpio_get_pin(unsigned); +#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void); +#endif + +#ifdef CONFIG_LCD_MENU +enum { + BOOT_MODE_INFO, + BOOT_MODE_THOR, + BOOT_MODE_UMS, + BOOT_MODE_DFU, + BOOT_MODE_EXIT, +}; + +static int power_key_pressed(int reg) +{ + struct pmic *pmic = pmic_get(KEY_PWR_PMIC_NAME); + u32 status = 0; + u32 mask; + + if (pmic_probe(pmic)) + return 0; + + if (!pmic) { + printf("%s: Not found\n", KEY_PWR_PMIC_NAME); + return -ENODEV; + } + + if (reg == KEY_PWR_STATUS_REG) + mask = KEY_PWR_STATUS_MASK; + else + mask = KEY_PWR_INTERRUPT_MASK; + + if (pmic_reg_read(pmic, reg, &status)) + return -EIO; + + return !!(status & mask); +} + +static int key_pressed(int key) +{ + int value = 0; + + switch (key) { + case KEY_POWER: + value = power_key_pressed(KEY_PWR_INTERRUPT_REG); + break; + case KEY_VOLUMEUP: + value = !gpio_get_value(KEY_VOL_UP_GPIO); + break; + case KEY_VOLUMEDOWN: + value = !gpio_get_value(KEY_VOL_DOWN_GPIO); + break; + default: + break; + } + + return value; +} + +static int check_keys(void) +{ + int keys = 0; + + if (key_pressed(KEY_POWER)) + keys += KEY_POWER; + if (key_pressed(KEY_VOLUMEUP)) + keys += KEY_VOLUMEUP; + if (key_pressed(KEY_VOLUMEDOWN)) + keys += KEY_VOLUMEDOWN; + + return keys; +} + +DECLARE_GLOBAL_DATA_PTR; + +/* + * 0 BOOT_MODE_INFO + * 1 BOOT_MODE_THOR + * 2 BOOT_MODE_UMS + * 3 BOOT_MODE_DFU + * 4 BOOT_MODE_EXIT +*/ +static char * +mode_name[BOOT_MODE_EXIT + 1] = {"DEVICE", + "THOR", + "UMS", + "DFU", + "EXIT"}; + +static char * +mode_info[BOOT_MODE_EXIT + 1] = {"info", + "downloader", + "mass storage", + "firmware update", + "and run normal boot"}; + +static char * +mode_cmd[BOOT_MODE_EXIT + 1] = {"", + "thor 0 mmc 0", + "ums 0 mmc 0", + "dfu 0 mmc 0", + ""}; + +static void display_board_info(void) +{ + struct mmc *mmc = find_mmc_device(0); + vidinfo_t *vid = &panel_info; + + lcd_position_cursor(4, 4); + + lcd_printf("%s\n\t", U_BOOT_VERSION); + lcd_puts("\n\t\tBoard Info:\n"); +#ifdef CONFIG_BOARD_NAME + lcd_printf("\tBoard name: %s\n", CONFIG_BOARD_NAME); +#endif +#ifdef CONFIG_REVISION_TAG + lcd_printf("\tBoard rev: %u\n", get_board_rev()); +#endif + lcd_printf("\tDRAM banks: %u\n", CONFIG_NR_DRAM_BANKS); + lcd_printf("\tDRAM size: %u MB\n", gd->ram_size / SZ_1M); + + if (mmc) + lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M); + + if (vid) + lcd_printf("\tDisplay resolution: %u x % u\n", + vid->vl_col, vid->vl_row); + + lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix); +} + +static int mode_leave_menu(int mode) +{ + int mode_supported = 1; + int leave = 0; + char *exit_option; + char *exit_boot = "boot"; + char *exit_back = "back"; + + switch (mode) { + case BOOT_MODE_INFO: +#if !defined(CONFIG_LCD_MENU_BOARD) + mode_supported = 0; +#endif + break; + case BOOT_MODE_THOR: +#if !defined(CONFIG_CMD_THOR_DOWNLOAD) + mode_supported = 0; +#endif + break; + case BOOT_MODE_UMS: +#if !defined(CONFIG_CMD_USB_MASS_STORAGE) + mode_supported = 0; +#endif + break; + case BOOT_MODE_DFU: +#if !defined(CONFIG_CMD_DFU) + mode_supported = 0; +#endif + break; + case BOOT_MODE_EXIT: + leave = 1; + goto exit; + default: + break; + } + + lcd_clear(); + + if (mode_supported) { + if (mode) { + lcd_printf("\n\n\t%s %s\n", mode_name[mode], + mode_info[mode]); + lcd_puts("\n\tDo not turn off device before finish!\n"); + + run_command(mode_cmd[mode], 0); + printf("Command finished\n"); + lcd_clear(); + lcd_printf("\n\n\t%s finished\n", mode_name[mode]); + exit_option = exit_boot; + leave = 1; + } else { + display_board_info(); + exit_option = exit_back; + leave = 0; + } + } else { + lcd_puts("\n\n\tThis mode is not supported.\n"); + exit_option = exit_back; + leave = 0; + } + + lcd_printf("\n\n\tPress POWER KEY to %s\n", exit_option); + + /* Wait for PWR key */ + while (!key_pressed(KEY_POWER)) + udelay(1000); +exit: + lcd_clear(); + return leave; +} + +static void display_download_menu(int mode) +{ + char *menu_name = "Download Mode Menu"; + char *indicator = "[=>]"; + char *blank = "[ ]"; + char *selection[BOOT_MODE_EXIT + 1]; + int i; + + for (i = 0; i <= BOOT_MODE_EXIT; i++) + selection[i] = blank; + + selection[mode] = indicator; + + lcd_clear(); + lcd_printf("\n\t\t%s\n", menu_name); + + for (i = 0; i <= BOOT_MODE_EXIT; i++) + lcd_printf("\t%s %s - %s\n\n", selection[i], + mode_name[i], + mode_info[i]); +} + +void download_menu(void) +{ + int mode = 0; + int last_mode = 0; + int run; + int key; + int menu_exit = 0; + + display_download_menu(mode); + + while (1) { + run = 0; + menu_exit = 0; + + if (mode != last_mode) + display_download_menu(mode); + + last_mode = mode; + udelay(100000); + + key = check_keys(); + switch (key) { + case KEY_POWER: + run = 1; + break; + case KEY_VOLUMEUP: + if (mode > 0) + mode--; + break; + case KEY_VOLUMEDOWN: + if (mode < BOOT_MODE_EXIT) + mode++; + break; + default: + break; + } + + if (run) { + if (mode_leave_menu(mode)) + break; + + display_download_menu(mode); + } + } + + lcd_clear(); +} + +static void display_mode_info(void) +{ + lcd_position_cursor(4, 4); + lcd_printf("%s\n", U_BOOT_VERSION); + lcd_puts("\nDownload Mode Menu\n"); +#ifdef CONFIG_BOARD_NAME + lcd_printf("Board name: %s\n", CONFIG_BOARD_NAME); +#endif + lcd_printf("Press POWER KEY to display MENU options."); +} + +static int boot_menu(void) +{ + int key = 0; + int timeout = 10; + + display_mode_info(); + + while (timeout--) { + lcd_printf("\rNormal boot will start in: %d seconds.", timeout); + udelay(1000000); + + key = key_pressed(KEY_POWER); + if (key) + break; + } + + lcd_clear(); + + /* If PWR pressed - show download menu */ + if (key) { + printf("Power pressed - go to download menu\n"); + udelay(1000000); + download_menu(); + printf("Download mode exit.\n"); + } + + return 0; +} + +static void check_boot_mode(void) +{ + int pwr_key; + + pwr_key = power_key_pressed(KEY_PWR_STATUS_REG); + if (pwr_key) { + /* Clear PWR button Rising edge interrupt status flag */ + power_key_pressed(KEY_PWR_INTERRUPT_REG); + + if (key_pressed(KEY_VOLUMEUP)) + boot_menu(); + else if (key_pressed(KEY_VOLUMEDOWN)) + mode_leave_menu(BOOT_MODE_THOR); + } +} + +static void keys_init(void) +{ + /* Set direction to input */ + gpio_direction_input(KEY_VOL_UP_GPIO); + gpio_direction_input(KEY_VOL_DOWN_GPIO); +} +#endif /* CONFIG_LCD_MENU */ + #ifdef CONFIG_CMD_BMP static void draw_logo(void) { @@ -46,10 +395,15 @@ static void draw_logo(void) /* Common for Samsung boards */ int misc_init_r(void) { +#ifdef CONFIG_LCD_MENU + keys_init(); + check_boot_mode(); +#endif #ifdef CONFIG_CMD_BMP if (panel_info.logo_on) draw_logo(); #endif + return 0; } #endif /* CONFIG_MISC_INIT_R */ -- 1.7.9.5