From patchwork Thu Jan 9 11:23:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Przemyslaw Marczak X-Patchwork-Id: 308596 X-Patchwork-Delegate: promsoft@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 8DB2A2C00B8 for ; Thu, 9 Jan 2014 22:26:00 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1B50E4B14A; Thu, 9 Jan 2014 12:25:57 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Nducetno8ew8; Thu, 9 Jan 2014 12:25:56 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 382B24B0CE; Thu, 9 Jan 2014 12:25:00 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 82EF84B0AF for ; Thu, 9 Jan 2014 12:24:55 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id q8MyThuP64E5 for ; Thu, 9 Jan 2014 12:24:54 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com [210.118.77.12]) by theia.denx.de (Postfix) with ESMTPS id 52CCA4B0B6 for ; Thu, 9 Jan 2014 12:24:23 +0100 (CET) Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MZ4006T8T07CP60@mailout2.w1.samsung.com> for u-boot@lists.denx.de; Thu, 09 Jan 2014 11:24:07 +0000 (GMT) X-AuditID: cbfec7f4-b7f796d000005a13-c4-52ce86d8656c Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id B1.A2.23059.8D68EC25; Thu, 09 Jan 2014 11:24:08 +0000 (GMT) Received: from AMDC1186.digital.local ([106.116.147.185]) by eusync4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MZ400EAVSZM4Z90@eusync4.samsung.com>; Thu, 09 Jan 2014 11:24:08 +0000 (GMT) From: Przemyslaw Marczak To: u-boot@lists.denx.de Date: Thu, 09 Jan 2014 12:23:13 +0100 Message-id: <1389266596-14581-10-git-send-email-p.marczak@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1389266596-14581-1-git-send-email-p.marczak@samsung.com> References: <1389266596-14581-1-git-send-email-p.marczak@samsung.com> In-reply-to: <1386093806-2948-1-git-send-email-p.marczak@samsung.com> References: <1386093806-2948-1-git-send-email-p.marczak@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpiluLIzCtJLcpLzFFi42I5/e/4Nd0bbeeCDCbflbe4ft7OYumMPlaL XX/vM1q8ebiZ0aLjSAujxY7LN1gs1j1Zy2rxdm8nuwOHx9k7Oxg9+rasYgxgiuKySUnNySxL LdK3S+DKmPF2KWtBu09Fz+UpLA2Mu2y6GDk5JARMJK6+mMEOYYtJXLi3nq2LkYtDSGApo8T+ r1uZIJw+JomNn1axgFSxCRhI7Ll0hhnEFhGQkPjVf5URxGYW2McocWapKYgtLGAv8arxF9BU Dg4WAVWJG5c8QcK8Am4SKy98YgIJSwgoSMyZBHYDJ1C44/cMsClCAq4S7+6tZYeIu0pcPr6P HSLuIrHh1QqmCYz8CxgZVjGKppYmFxQnpeca6hUn5haX5qXrJefnbmKEhNuXHYyLj1kdYhTg YFTi4eWoPRskxJpYVlyZe4hRgoNZSYR3auO5ICHelMTKqtSi/Pii0pzU4kOMTBycUg2M3vdD FobEL31b0Ju5f+H96yFSa4+UGPa9DZ5856kMY8auV+YzSyw1AnhfhAq92HVhgX5mhk8o2zGZ L3d4Kp3yMzhvCWZJ885REZ/mIb+P+VSLs9DibqtvsUe0I2pl9h5+UBAfve7Q86ScmVoFks4b QpdJMkU5TXOPc+G9m6AQVaFX41a5aLkSS3FGoqEWc1FxIgD0YlD6FQIAAA== Cc: p.wilczek@samsung.com, dh09.lee@samsung.com, Przemyslaw Marczak Subject: [U-Boot] [PATCH v4 09/12] samsung: misc: Add LCD download menu. X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This simple LCD menu allows run one of download mode on device without writing on console or for fast and easy upgrade. This feature check user keys combination at boot: - power key + volume up - download menu - power key + volume down - thor mode (without menu) New configs: - CONFIG_LCD_MENU - CONFIG_LCD_MENU_BOARD which depends on: CONFIG_MISC_INIT_R For proper effect this feature needs following definitions: Power key: - KEY_PWR_PMIC_NAME - (string) pmic which supports power key check Register address: - KEY_PWR_STATUS_REG - KEY_PWR_INTERRUPT_REG Register power key mask: - KEY_PWR_STATUS_MASK - KEY_PWR_INTERRUPT_MASK Gpio numbers: - KEY_PWR_INTERRUPT_MASK - KEY_VOL_DOWN_GPIO Signed-off-by: Przemyslaw Marczak --- Changes v2: - remove keys.h - definitions should be in boards headers - add misc.h - code cleanup - extend commit msg by more informations Changes v3: - none Changes v4: - code cleanup in board/samsung/common/misc.c - add command result check - clear PWR button interrupt flag after command finish to prevent immediately mode exit in mode_leave_menu() function. - introduce MODE_CMD_ARGC - max number of command arguments - split array mode_cmd[] to mode_cmd[][] with separated arguments - command support checking is now achieved without preprocessor ifdefs board/samsung/common/misc.c | 349 +++++++++++++++++++++++++++++++++++++++++++ board/samsung/common/misc.h | 18 +++ 2 files changed, 367 insertions(+) create mode 100644 board/samsung/common/misc.h diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 3a91d62..f29fca4 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -8,6 +8,350 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "misc.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_LCD_MENU +static int power_key_pressed(u32 reg) +{ + struct pmic *pmic; + u32 status; + u32 mask; + + pmic = pmic_get(KEY_PWR_PMIC_NAME); + if (!pmic) { + printf("%s: Not found\n", KEY_PWR_PMIC_NAME); + return 0; + } + + if (pmic_probe(pmic)) + return 0; + + 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 0; + + return !!(status & mask); +} + +static int key_pressed(int key) +{ + int value; + + 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: + value = 0; + 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; +} + +/* + * 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" +}; + +#define MODE_CMD_ARGC 4 + +static char * +mode_cmd[BOOT_MODE_EXIT + 1][MODE_CMD_ARGC] = { + {"", "", "", ""}, + {"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_SYS_BOARD + lcd_printf("\tBoard name: %s\n", CONFIG_SYS_BOARD); +#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) { + if (!mmc->capacity) + mmc_init(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) +{ + char *exit_option; + char *exit_boot = "boot"; + char *exit_back = "back"; + cmd_tbl_t *cmd; + int cmd_result; + int cmd_repeatable; + int leave; + + lcd_clear(); + + switch (mode) { + case BOOT_MODE_EXIT: + return 1; + case BOOT_MODE_INFO: + display_board_info(); + exit_option = exit_back; + leave = 0; + break; + default: + cmd = find_cmd(mode_cmd[mode][0]); + if (cmd) { + printf("Enter: %s %s\n", mode_name[mode], + mode_info[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"); + + cmd_result = cmd_process(0, MODE_CMD_ARGC, + *(mode_cmd + mode), + &cmd_repeatable, NULL); + + if (cmd_result == CMD_RET_SUCCESS) { + printf("Command finished\n"); + lcd_clear(); + lcd_printf("\n\n\t%s finished\n", + mode_name[mode]); + + exit_option = exit_boot; + leave = 1; + } else { + printf("Command error\n"); + lcd_clear(); + lcd_printf("\n\n\t%s command error\n", + mode_name[mode]); + + 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); + + /* Clear PWR button Rising edge interrupt status flag */ + power_key_pressed(KEY_PWR_INTERRUPT_REG); + + /* Wait for PWR key */ + while (!key_pressed(KEY_POWER)) + udelay(1000); + + lcd_clear(); + return leave; +} + +static void display_download_menu(int mode) +{ + char *selection[BOOT_MODE_EXIT + 1]; + int i; + + for (i = 0; i <= BOOT_MODE_EXIT; i++) + selection[i] = "[ ]"; + + selection[mode] = "[=>]"; + + lcd_clear(); + lcd_printf("\n\t\tDownload Mode Menu\n"); + + for (i = 0; i <= BOOT_MODE_EXIT; i++) + lcd_printf("\t%s %s - %s\n\n", selection[i], + mode_name[i], + mode_info[i]); +} + +static void download_menu(void) +{ + int mode = 0; + int last_mode = 0; + int run; + int key; + + display_download_menu(mode); + + while (1) { + run = 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_SYS_BOARD + lcd_printf("Board name: %s\n", CONFIG_SYS_BOARD); +#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"); + 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) + return; + + /* 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) @@ -50,9 +394,14 @@ 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; } diff --git a/board/samsung/common/misc.h b/board/samsung/common/misc.h new file mode 100644 index 0000000..f583552 --- /dev/null +++ b/board/samsung/common/misc.h @@ -0,0 +1,18 @@ +#ifndef __SAMSUNG_COMMON_MISC_H__ +#define __SAMSUNG_COMMON_MISC_H__ + +#ifdef CONFIG_LCD_MENU +enum { + BOOT_MODE_INFO, + BOOT_MODE_THOR, + BOOT_MODE_UMS, + BOOT_MODE_DFU, + BOOT_MODE_EXIT, +}; + +#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void); +#endif +#endif /* CONFIG_LCD_MENU */ + +#endif /* __SAMSUNG_COMMON_MISC_H__ */