Message ID | 1389266596-14581-10-git-send-email-p.marczak@samsung.com |
---|---|
State | Changes Requested |
Delegated to: | Minkyu Kang |
Headers | show |
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.
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
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.
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 --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__ */
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