[U-Boot] [PATCH] i.MX6: mx6qsabrelite: Add keypress support

Eric Nelson
2012-03-03T15:30:20Z

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