Message ID | 1330732824-15345-1-git-send-email-eric.nelson@boundarydevices.com |
---|---|
State | Rejected |
Headers | show |
On 03/02/2012 05:00 PM, Eric Nelson wrote: > This patch adds support for the GPIO keyboard used on MX6Q SabreLite. > > This is generally used for invoking Android "recovery mode" in > response to a long press of volume key down during boot. > > This can be tested by a boot script like so: > if keypress voldown&& sleep 1&& keypress voldown ; then > echo "do recovery thing" ; > fi > > Key values can be seen by issuing keypress with no arguments: > > MX6QSABRELITE U-Boot> keypress > keys: !menu !back !search !home !volup !voldown > --- > board/freescale/mx6qsabrelite/mx6qsabrelite.c | 76 +++++++++++++++++++++++++ > 1 files changed, 76 insertions(+), 0 deletions(-) > > <snip> I didn't want to litter the commit message with a lot of extraneous discussion, but it appears that Android recovery mode can be invoked either by Android itself or by a user pressing keys. When Android wants to invoke recovery mode, it creates a special "recovery" file and then re-boots. The Freescale U-Boot release accomplishes this by having special code to detect the keypress or the presence of the magic file. http://opensource.freescale.com/git?p=imx/uboot-imx.git;a=blob;f=board/freescale/common/recovery.c;h=16e0be479ba543a8ceb865c3c2eee55379186bda;hb=imx_v2009.08_11.11.01 http://opensource.freescale.com/git?p=imx/uboot-imx.git;a=blob;f=board/freescale/mx53_loco/mx53_loco.c;h=fda52dc4abff6482d6cb102002529a3f2edd3bbb;hb=imx_v2009.08_11.11.01#l733 Since U-Boot can test files using the hush parser, it seems cleaner to just enable keyboard detection and allow express the boot flow in boot commands. I looked for, but didn't find precedent for testing keys. Please advise if there's a more standard way to accomplish keypress detection. Regards, Eric
> This patch adds support for the GPIO keyboard used on MX6Q SabreLite. > > This is generally used for invoking Android "recovery mode" in > response to a long press of volume key down during boot. > > This can be tested by a boot script like so: > if keypress voldown && sleep 1 && keypress voldown ; then > echo "do recovery thing" ; > fi > > Key values can be seen by issuing keypress with no arguments: > > MX6QSABRELITE U-Boot > keypress > keys: !menu !back !search !home !volup !voldown > --- > board/freescale/mx6qsabrelite/mx6qsabrelite.c | 76 > +++++++++++++++++++++++++ 1 files changed, 76 insertions(+), 0 > deletions(-) > > diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c > b/board/freescale/mx6qsabrelite/mx6qsabrelite.c index e0ba6a4..0d45615 > 100644 > --- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c > +++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c > @@ -50,6 +50,10 @@ DECLARE_GLOBAL_DATA_PTR; > PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ > PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) > > +#define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ > + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ > + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) > + > int dram_init(void) > { > gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); > @@ -122,6 +126,15 @@ iomux_v3_cfg_t enet_pads2[] = { > MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), > }; > > +static iomux_v3_cfg_t const button_pads[] = { > + MX6Q_PAD_NANDF_D1__GPIO_2_1 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - > Menu Button */ + MX6Q_PAD_NANDF_D2__GPIO_2_2 | > MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Back Button */ > + MX6Q_PAD_NANDF_D3__GPIO_2_3 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - > Search Button */ + MX6Q_PAD_NANDF_D4__GPIO_2_4 | > MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Home Button */ > + MX6Q_PAD_GPIO_19__GPIO_4_5 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - > Volume Down */ + MX6Q_PAD_GPIO_18__GPIO_7_13 | > MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Volume Up */ +}; > + > static void setup_iomux_enet(void) > { > gpio_direction_output(87, 0); /* GPIO 3-23 */ > @@ -323,10 +336,18 @@ int setup_sata(void) > } > #endif > > +static void setup_buttons(void) > +{ > + imx_iomux_v3_setup_multiple_pads(button_pads, > + ARRAY_SIZE(button_pads)); > +} > + > int board_early_init_f(void) > { > setup_iomux_uart(); > > + setup_buttons(); > + > #ifdef CONFIG_CMD_SATA > setup_sata(); > #endif > @@ -350,3 +371,58 @@ int checkboard(void) > > return 0; > } > + > +struct button_key { > + char const *name; > + unsigned gpnum; > +}; > + > +static struct button_key const buttons[] = { > + {"menu", GPIO_NUMBER(2, 1)}, > + {"back", GPIO_NUMBER(2, 2)}, > + {"search", GPIO_NUMBER(2, 3)}, > + {"home", GPIO_NUMBER(2, 4)}, > + {"voldown", GPIO_NUMBER(4, 5)}, > + {"volup", GPIO_NUMBER(7, 13)}, > +}; > + > +static int keypress(cmd_tbl_t *cmdtp, int flag, int argc, char * const > argv[]) +{ > + if (1 < argc) { > + int arg; > + int pressed = 1 ; > + for (arg=1; arg<argc; arg++) { > + char const *keyname=argv[arg]; > + int i; > + for (i=0; pressed && (i < ARRAY_SIZE(buttons)); i++) { > + if (0 == strcmp(buttons[i].name,keyname)) { > + pressed = pressed && (0 == gpio_get_value(buttons[i].gpnum)); > + break; > + } > + } > + if (ARRAY_SIZE(buttons) == i) { > + printf ("unrecognized key %s\n", keyname); > + pressed = 0; > + break; > + } > + } > + return (0 == pressed); > + } else { > + int i; > + printf ("keys: "); > + for (i=0; i<ARRAY_SIZE(buttons); i++) { > + if (0 != gpio_get_value(buttons[i].gpnum)) > + printf("!"); > + printf("%s\t",buttons[i].name); > + } > + printf("\n"); > + return 0 ; > + } > +} > + > +U_BOOT_CMD( > + keypress, CONFIG_SYS_MAXARGS, 1, keypress, > + "Display or test keypresses", > + " keypress - show key(s) pressed\n" > + " keypress name - test key name (return 0 if pressed)\n" > +); Why not make it an STDIN device as any other keyboard? M
Dear Eric Nelson, In message <1330732824-15345-1-git-send-email-eric.nelson@boundarydevices.com> you wrote: > This patch adds support for the GPIO keyboard used on MX6Q SabreLite. > > This is generally used for invoking Android "recovery mode" in > response to a long press of volume key down during boot. > > This can be tested by a boot script like so: > if keypress voldown && sleep 1 && keypress voldown ; then > echo "do recovery thing" ; > fi > > Key values can be seen by issuing keypress with no arguments: I don't like introducing yet another way to handle key presses and create menu like interfaces from this. We already have two of these: - We have the powerful and flexible method to map key preesses to envrionment variables which can in turn hold commands (variables "magic_keys" and "key_magic*") as used for example on the enbw_cmc, lwmon5, hmi1001, mucmc52, pcs440ep, r360mpi and mucmc52 boards. - We have the menu system as implemented by common/menu.c etc. Please use either of these, but don't invent a new one. Thanks. Best regards, Wolfgang Denk
On 03/02/2012 07:18 PM, Marek Vasut wrote: >> This patch adds support for the GPIO keyboard used on MX6Q SabreLite. >> >> This is generally used for invoking Android "recovery mode" in >> response to a long press of volume key down during boot. >> >> This can be tested by a boot script like so: >> if keypress voldown&& sleep 1&& keypress voldown ; then >> echo "do recovery thing" ; >> fi >> >> Key values can be seen by issuing keypress with no arguments: >> >> MX6QSABRELITE U-Boot> keypress >> keys: !menu !back !search !home !volup !voldown >> --- >> board/freescale/mx6qsabrelite/mx6qsabrelite.c | 76 >> +++++++++++++++++++++++++ 1 files changed, 76 insertions(+), 0 >> deletions(-) >> >> diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c >> b/board/freescale/mx6qsabrelite/mx6qsabrelite.c index e0ba6a4..0d45615 >> 100644 >> --- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c >> +++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c >> @@ -50,6 +50,10 @@ DECLARE_GLOBAL_DATA_PTR; >> PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ >> PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) >> >> +#define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ >> + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ >> + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) >> + >> int dram_init(void) >> { >> gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); >> @@ -122,6 +126,15 @@ iomux_v3_cfg_t enet_pads2[] = { >> MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), >> }; >> >> +static iomux_v3_cfg_t const button_pads[] = { >> + MX6Q_PAD_NANDF_D1__GPIO_2_1 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 > - >> Menu Button */ + MX6Q_PAD_NANDF_D2__GPIO_2_2 | >> MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Back Button */ >> + MX6Q_PAD_NANDF_D3__GPIO_2_3 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 > - >> Search Button */ + MX6Q_PAD_NANDF_D4__GPIO_2_4 | >> MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Home Button */ >> + MX6Q_PAD_GPIO_19__GPIO_4_5 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 > - >> Volume Down */ + MX6Q_PAD_GPIO_18__GPIO_7_13 | >> MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Volume Up */ +}; >> + >> static void setup_iomux_enet(void) >> { >> gpio_direction_output(87, 0); /* GPIO 3-23 */ >> @@ -323,10 +336,18 @@ int setup_sata(void) >> } >> #endif >> >> +static void setup_buttons(void) >> +{ >> + imx_iomux_v3_setup_multiple_pads(button_pads, >> + ARRAY_SIZE(button_pads)); >> +} >> + >> int board_early_init_f(void) >> { >> setup_iomux_uart(); >> >> + setup_buttons(); >> + >> #ifdef CONFIG_CMD_SATA >> setup_sata(); >> #endif >> @@ -350,3 +371,58 @@ int checkboard(void) >> >> return 0; >> } >> + >> +struct button_key { >> + char const *name; >> + unsigned gpnum; >> +}; >> + >> +static struct button_key const buttons[] = { >> + {"menu", GPIO_NUMBER(2, 1)}, >> + {"back", GPIO_NUMBER(2, 2)}, >> + {"search", GPIO_NUMBER(2, 3)}, >> + {"home", GPIO_NUMBER(2, 4)}, >> + {"voldown", GPIO_NUMBER(4, 5)}, >> + {"volup", GPIO_NUMBER(7, 13)}, >> +}; >> + >> +static int keypress(cmd_tbl_t *cmdtp, int flag, int argc, char * const >> argv[]) +{ >> + if (1< argc) { >> + int arg; >> + int pressed = 1 ; >> + for (arg=1; arg<argc; arg++) { >> + char const *keyname=argv[arg]; >> + int i; >> + for (i=0; pressed&& (i< ARRAY_SIZE(buttons)); i++) { >> + if (0 == strcmp(buttons[i].name,keyname)) { >> + pressed = pressed&& (0 == > gpio_get_value(buttons[i].gpnum)); >> + break; >> + } >> + } >> + if (ARRAY_SIZE(buttons) == i) { >> + printf ("unrecognized key %s\n", keyname); >> + pressed = 0; >> + break; >> + } >> + } >> + return (0 == pressed); >> + } else { >> + int i; >> + printf ("keys: "); >> + for (i=0; i<ARRAY_SIZE(buttons); i++) { >> + if (0 != gpio_get_value(buttons[i].gpnum)) >> + printf("!"); >> + printf("%s\t",buttons[i].name); >> + } >> + printf("\n"); >> + return 0 ; >> + } >> +} >> + >> +U_BOOT_CMD( >> + keypress, CONFIG_SYS_MAXARGS, 1, keypress, >> + "Display or test keypresses", >> + " keypress - show key(s) pressed\n" >> + " keypress name - test key name (return 0 if pressed)\n" >> +); > > Why not make it an STDIN device as any other keyboard? > Is there a non-blocking read from stdin available to boot script? How would we represent keys like "Menu", "Home", "Volume up" and "Volume down"? Through ANSI escape sequences? Please advise, Eric
On 03/03/2012 02:15 AM, Wolfgang Denk wrote: > Dear Eric Nelson, > > In message<1330732824-15345-1-git-send-email-eric.nelson@boundarydevices.com> you wrote: >> This patch adds support for the GPIO keyboard used on MX6Q SabreLite. >> >> This is generally used for invoking Android "recovery mode" in >> response to a long press of volume key down during boot. >> >> This can be tested by a boot script like so: >> if keypress voldown&& sleep 1&& keypress voldown ; then >> echo "do recovery thing" ; >> fi >> >> Key values can be seen by issuing keypress with no arguments: > > I don't like introducing yet another way to handle key presses and > create menu like interfaces from this. > > We already have two of these: > > - We have the powerful and flexible method to map key preesses to > envrionment variables which can in turn hold commands (variables > "magic_keys" and "key_magic*") as used for example on the enbw_cmc, > lwmon5, hmi1001, mucmc52, pcs440ep, r360mpi and mucmc52 boards. > > - We have the menu system as implemented by common/menu.c etc. > > Please use either of these, but don't invent a new one. Thanks. > Thanks for the pointers. I'll rework accordingly. Grepping the sources rarely results in this kind of insight. Regards, Eric
Dear Eric Nelson, In message <4F52390C.4080108@boundarydevices.com> you wrote: > > > Why not make it an STDIN device as any other keyboard? > > > Is there a non-blocking read from stdin available to boot script? > > How would we represent keys like "Menu", "Home", "Volume up" and "Volume down"? > > Through ANSI escape sequences? No. You don't have to. Mapping key presses to functions (bind them to commands) is a different thing. Keys could be "1", "2", "3" and "4", and could be mapped to "run cmd_1", ... "run cmd_4" respectively. Then the user can define what "cmd_1" etc. does. Best regards, Wolfgang Denk
Dear Eric Nelson, In message <4F523A24.8020406@boundarydevices.com> you wrote: > > Thanks for the pointers. I'll rework accordingly. Thanks. > Grepping the sources rarely results in this kind of insight. I know. I can find the stuff myself only because I have an idea what to search for... Best regards, Wolfgang Denk
On 03/03/2012 08:48 AM, Wolfgang Denk wrote: > Dear Eric Nelson, > > In message<4F52390C.4080108@boundarydevices.com> you wrote: >> >>> Why not make it an STDIN device as any other keyboard? >>> >> Is there a non-blocking read from stdin available to boot script? >> >> How would we represent keys like "Menu", "Home", "Volume up" and "Volume down"? >> >> Through ANSI escape sequences? > > No. You don't have to. Mapping key presses to functions (bind them to > commands) is a different thing. Keys could be "1", "2", "3" and "4", > and could be mapped to "run cmd_1", ... "run cmd_4" respectively. > Then the user can define what "cmd_1" etc. does. > That's perfect. All that's left is the details... Thanks for your help.
Hi Eric, On 03.03.2012 16:51, Eric Nelson wrote: > On 03/03/2012 08:48 AM, Wolfgang Denk wrote: >> Dear Eric Nelson, >> >> In message<4F52390C.4080108@boundarydevices.com> you wrote: >>> >>>> Why not make it an STDIN device as any other keyboard? >>>> >>> Is there a non-blocking read from stdin available to boot script? >>> >>> How would we represent keys like "Menu", "Home", "Volume up" and >>> "Volume down"? >>> >>> Through ANSI escape sequences? >> >> No. You don't have to. Mapping key presses to functions (bind them to >> commands) is a different thing. Keys could be "1", "2", "3" and "4", >> and could be mapped to "run cmd_1", ... "run cmd_4" respectively. >> Then the user can define what "cmd_1" etc. does. >> > > That's perfect. All that's left is the details... Do you plan an update of this patch? Many thanks, Dirk
On 03/24/2012 12:13 AM, Dirk Behme wrote: > Hi Eric, > > On 03.03.2012 16:51, Eric Nelson wrote: >> On 03/03/2012 08:48 AM, Wolfgang Denk wrote: >>> Dear Eric Nelson, >>> >>> In message<4F52390C.4080108@boundarydevices.com> you wrote: >>>> >>>>> Why not make it an STDIN device as any other keyboard? >>>>> >>>> Is there a non-blocking read from stdin available to boot script? >>>> >>>> How would we represent keys like "Menu", "Home", "Volume up" and >>>> "Volume down"? >>>> >>>> Through ANSI escape sequences? >>> >>> No. You don't have to. Mapping key presses to functions (bind them to >>> commands) is a different thing. Keys could be "1", "2", "3" and "4", >>> and could be mapped to "run cmd_1", ... "run cmd_4" respectively. >>> Then the user can define what "cmd_1" etc. does. >>> >> That's perfect. All that's left is the details... > > Do you plan an update of this patch? > Yes I do. I'm just having trouble finding time these days. And I seem to be buttonless (without a button board) at the moment. I even have a fledgling README for keyboard support so the next person can find out what to do with grep! Regards, Eric
diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c b/board/freescale/mx6qsabrelite/mx6qsabrelite.c index e0ba6a4..0d45615 100644 --- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c +++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c @@ -50,6 +50,10 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) +#define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + int dram_init(void) { gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); @@ -122,6 +126,15 @@ iomux_v3_cfg_t enet_pads2[] = { MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), }; +static iomux_v3_cfg_t const button_pads[] = { + MX6Q_PAD_NANDF_D1__GPIO_2_1 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Menu Button */ + MX6Q_PAD_NANDF_D2__GPIO_2_2 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Back Button */ + MX6Q_PAD_NANDF_D3__GPIO_2_3 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Search Button */ + MX6Q_PAD_NANDF_D4__GPIO_2_4 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Home Button */ + MX6Q_PAD_GPIO_19__GPIO_4_5 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Volume Down */ + MX6Q_PAD_GPIO_18__GPIO_7_13 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), /* J14 - Volume Up */ +}; + static void setup_iomux_enet(void) { gpio_direction_output(87, 0); /* GPIO 3-23 */ @@ -323,10 +336,18 @@ int setup_sata(void) } #endif +static void setup_buttons(void) +{ + imx_iomux_v3_setup_multiple_pads(button_pads, + ARRAY_SIZE(button_pads)); +} + int board_early_init_f(void) { setup_iomux_uart(); + setup_buttons(); + #ifdef CONFIG_CMD_SATA setup_sata(); #endif @@ -350,3 +371,58 @@ int checkboard(void) return 0; } + +struct button_key { + char const *name; + unsigned gpnum; +}; + +static struct button_key const buttons[] = { + {"menu", GPIO_NUMBER(2, 1)}, + {"back", GPIO_NUMBER(2, 2)}, + {"search", GPIO_NUMBER(2, 3)}, + {"home", GPIO_NUMBER(2, 4)}, + {"voldown", GPIO_NUMBER(4, 5)}, + {"volup", GPIO_NUMBER(7, 13)}, +}; + +static int keypress(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (1 < argc) { + int arg; + int pressed = 1 ; + for (arg=1; arg<argc; arg++) { + char const *keyname=argv[arg]; + int i; + for (i=0; pressed && (i < ARRAY_SIZE(buttons)); i++) { + if (0 == strcmp(buttons[i].name,keyname)) { + pressed = pressed && (0 == gpio_get_value(buttons[i].gpnum)); + break; + } + } + if (ARRAY_SIZE(buttons) == i) { + printf ("unrecognized key %s\n", keyname); + pressed = 0; + break; + } + } + return (0 == pressed); + } else { + int i; + printf ("keys: "); + for (i=0; i<ARRAY_SIZE(buttons); i++) { + if (0 != gpio_get_value(buttons[i].gpnum)) + printf("!"); + printf("%s\t",buttons[i].name); + } + printf("\n"); + return 0 ; + } +} + +U_BOOT_CMD( + keypress, CONFIG_SYS_MAXARGS, 1, keypress, + "Display or test keypresses", + " keypress - show key(s) pressed\n" + " keypress name - test key name (return 0 if pressed)\n" +);