diff mbox

[U-Boot,v4,09/12] samsung: misc: Add LCD download menu.

Message ID 1389266596-14581-10-git-send-email-p.marczak@samsung.com
State Changes Requested
Delegated to: Minkyu Kang
Headers show

Commit Message

Przemyslaw Marczak Jan. 9, 2014, 11:23 a.m. UTC
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 <p.marczak@samsung.com>

---
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

Comments

Minkyu Kang Jan. 10, 2014, 1:37 a.m. UTC | #1
On 09/01/14 20:23, Przemyslaw Marczak wrote:
> 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 <p.marczak@samsung.com>
> 
> ---
> 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 <common.h>
>  #include <lcd.h>
>  #include <libtizen.h>
> +#include <errno.h>
> +#include <version.h>
> +#include <asm/sizes.h>
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/gpio.h>
> +#include <asm/gpio.h>
> +#include <linux/input.h>
> +#include <lcd.h>
> +#include <libtizen.h>

lcd.h, libtizen.h are duplicated.

> +#include <power/pmic.h>
> +#include <mmc.h>
> +#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)
> +{

#ifdef CONFIG_GENERIC_MMC
> +	struct mmc *mmc = find_mmc_device(0);
#endif

> +	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);
> +

#ifdef CONFIG_GENERIC_MMC
> +	if (mmc) {
> +		if (!mmc->capacity)
> +			mmc_init(mmc);
> +
> +		lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
> +	}
#endif

> +
> +	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 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);

mdelay(1000)?

> +
> +		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;
> +}
> +

Thanks,
Minkyu Kang.
Przemyslaw Marczak Jan. 10, 2014, 9:37 a.m. UTC | #2
Hello Minkyu,

On 01/10/2014 02:37 AM, Minkyu Kang wrote:
> On 09/01/14 20:23, Przemyslaw Marczak wrote:
>> 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 <p.marczak@samsung.com>
>>
>> ---
>> 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 <common.h>
>>   #include <lcd.h>
>>   #include <libtizen.h>
>> +#include <errno.h>
>> +#include <version.h>
>> +#include <asm/sizes.h>
>> +#include <asm/arch/cpu.h>
>> +#include <asm/arch/gpio.h>
>> +#include <asm/gpio.h>
>> +#include <linux/input.h>
>> +#include <lcd.h>
>> +#include <libtizen.h>
>
> lcd.h, libtizen.h are duplicated.
>

Thanks, will be removed.

>> +#include <power/pmic.h>
>> +#include <mmc.h>
>> +#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)
>> +{
>
> #ifdef CONFIG_GENERIC_MMC
>> +	struct mmc *mmc = find_mmc_device(0);
> #endif
>
>> +	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);
>> +
>
> #ifdef CONFIG_GENERIC_MMC
>> +	if (mmc) {
>> +		if (!mmc->capacity)
>> +			mmc_init(mmc);
>> +
>> +		lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
>> +	}
> #endif
>
>> +
>> +	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 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);
>
> mdelay(1000)?
>

OK.

>> +
>> +		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;
>> +}
>> +
>
> Thanks,
> Minkyu Kang.
>
>

Thank you for review.

Regards
Minkyu Kang Jan. 10, 2014, 9:43 a.m. UTC | #3
On 10/01/14 18:37, Przemyslaw Marczak wrote:
> Hello Minkyu,
> 
> On 01/10/2014 02:37 AM, Minkyu Kang wrote:
>> On 09/01/14 20:23, Przemyslaw Marczak wrote:
>>> 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 <p.marczak@samsung.com>
>>>
>>> ---
>>> 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 <common.h>
>>>   #include <lcd.h>
>>>   #include <libtizen.h>
>>> +#include <errno.h>
>>> +#include <version.h>
>>> +#include <asm/sizes.h>
>>> +#include <asm/arch/cpu.h>
>>> +#include <asm/arch/gpio.h>
>>> +#include <asm/gpio.h>
>>> +#include <linux/input.h>
>>> +#include <lcd.h>
>>> +#include <libtizen.h>
>>
>> lcd.h, libtizen.h are duplicated.
>>
> 
> Thanks, will be removed.
> 
>>> +#include <power/pmic.h>
>>> +#include <mmc.h>
>>> +#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)
>>> +{
>>
>> #ifdef CONFIG_GENERIC_MMC

Did you check this comment also?

>>> +    struct mmc *mmc = find_mmc_device(0);
>> #endif
>>
>>> +    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);
>>> +
>>
>> #ifdef CONFIG_GENERIC_MMC

ditto.

>>> +    if (mmc) {
>>> +        if (!mmc->capacity)
>>> +            mmc_init(mmc);
>>> +
>>> +        lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
>>> +    }
>> #endif
>>
>>> +
>>> +    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);
>>> +}
>>> +

Thanks,
Minkyu Kang.
Przemyslaw Marczak Jan. 10, 2014, 9:48 a.m. UTC | #4
On 01/10/2014 10:43 AM, Minkyu Kang wrote:
> On 10/01/14 18:37, Przemyslaw Marczak wrote:
>> Hello Minkyu,
>>
>> On 01/10/2014 02:37 AM, Minkyu Kang wrote:
>>> On 09/01/14 20:23, Przemyslaw Marczak wrote:
>>>> 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 <p.marczak@samsung.com>
>>>>
>>>> ---
>>>> 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 <common.h>
>>>>    #include <lcd.h>
>>>>    #include <libtizen.h>
>>>> +#include <errno.h>
>>>> +#include <version.h>
>>>> +#include <asm/sizes.h>
>>>> +#include <asm/arch/cpu.h>
>>>> +#include <asm/arch/gpio.h>
>>>> +#include <asm/gpio.h>
>>>> +#include <linux/input.h>
>>>> +#include <lcd.h>
>>>> +#include <libtizen.h>
>>>
>>> lcd.h, libtizen.h are duplicated.
>>>
>>
>> Thanks, will be removed.
>>
>>>> +#include <power/pmic.h>
>>>> +#include <mmc.h>
>>>> +#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)
>>>> +{
>>>
>>> #ifdef CONFIG_GENERIC_MMC
>
> Did you check this comment also?
>
>>>> +    struct mmc *mmc = find_mmc_device(0);
>>> #endif
>>>
>>>> +    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);
>>>> +
>>>
>>> #ifdef CONFIG_GENERIC_MMC
>
> ditto.
>

Yes, these will apply too.

>>>> +    if (mmc) {
>>>> +        if (!mmc->capacity)
>>>> +            mmc_init(mmc);
>>>> +
>>>> +        lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
>>>> +    }
>>> #endif
>>>
>>>> +
>>>> +    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);
>>>> +}
>>>> +
>
> Thanks,
> Minkyu Kang.
>

Thank you,
diff mbox

Patch

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 <common.h>
 #include <lcd.h>
 #include <libtizen.h>
+#include <errno.h>
+#include <version.h>
+#include <asm/sizes.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
+#include <linux/input.h>
+#include <lcd.h>
+#include <libtizen.h>
+#include <power/pmic.h>
+#include <mmc.h>
+#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__ */