4

I am currently working on porting Android 4.4 (Kitkat) on an embedded system (Freescale i.MX6 based). In order to start my development, I used a few development kits (Wandboard, Boundary Device's BD-SL).

While working on the power management of my custom board, I had no trouble to put the devkits in suspend. However, I couldn't find how to wake them from sleep (other than power cycling them). The expected way of waking the system would be by getting an interrupt on a GPIO (e.g. the on-off button on an Android based phone).

I wanted to know what was the usual way to wake up an android device from suspend with a GPIO's interrupt. Though the question may seem trivial, I had trouble gathering all the information I needed from various searches on Google and specialized forums. I found a lot of information but nothing that covered the whole subject. Probably because I was missing the required background, I had trouble putting everything together without a code example. I guessed I was not the only one in this situation, thus this post.

Here are some of the information I found:

gfrigon
  • 2,237
  • 2
  • 23
  • 32

1 Answers1

3

In the end, I was digging too deep. The code example was right under my nose. Everything I needed was in the BD-SL devkit's board specific code (can be found in the BD-SL source tree in mydroid/BD-SL-i.MX6/kernel_imx/arch/arm/mach-mx6/board-mx6_nitrogen6x.c)

This code is specific to the Freescale i.MX6 provided kernel but the different parts should easily be ported/Adapted to other Android Embedded Platforms.

GPIO define. I am skipping the GPIO pin mux for simplicity. The pin needs to be multiplexed to the GPIO functionality:

#define GP_ONOFF_KEY        IMX_GPIO_NR(2, 3)

Definition of the input key

#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake)    \
{                               \
    .gpio       = gpio_num,             \
    .type       = EV_KEY,               \
    .code       = ev_code,              \
    .active_low = act_low,              \
    .desc       = "btn " descr,             \
    .wakeup     = wake,                 \
}

static struct gpio_keys_button buttons[] = {
    GPIO_BUTTON(GP_ONOFF_KEY, KEY_POWER, 1, "key-power", 1),
};

Definition of the corresponding platform data and platform device:

static struct gpio_keys_platform_data button_data = {
    .buttons    = buttons,
    .nbuttons   = ARRAY_SIZE(buttons),
};

static struct platform_device button_device = {
    .name       = "gpio-keys",
    .id     = -1,
    .num_resources  = 0,
    .dev        = {
        .platform_data = &button_data,
    }
};

Registering of the platform device

static void __init add_device_buttons(void)
{
    platform_device_register(&button_device);
}

/*!
 * Board specific initialization.
 */
static void __init board_init(void)
{
    //...

    add_device_buttons();

    //...
}

And for completeness, the initialize data structure that points to the Board specific initialization

/*
 * initialize data structure.
 */
MACHINE_START(MX6_NITROGEN6X, "Boundary Devices Nitrogen6X/SABRE Lite Board")
    /* Maintainer: Boundary Devices */
    .boot_params = MX6_PHYS_OFFSET + 0x100,
    .fixup = fixup_mxc_board,
    .map_io = mx6_map_io,
    .init_irq = mx6_init_irq,
    .init_machine = board_init,
    .timer = &timer,
    .reserve = reserve,
MACHINE_END
gfrigon
  • 2,237
  • 2
  • 23
  • 32
  • Hi gfrigon. We are trying to wake up Android running on Q7A-551 with MX 6DualLite. When Android is in "suspended mode" usb keyboard can wakeup android with a single keystroke. But if Android goes in to deep sleep, "MEM mode" it does not react to keystrokes on the keyboard. Do you have any idea of what can be done to this? – MRodrigues Nov 26 '15 at 17:21
  • 1
    @MRodrigues I don't have any issues waking from MEM mode with a GPIO Key. Therefore, I don't have a clear answer for your question. However I will try to give a few hints. Is the USB bus powered when in MEM mode? If you have access to the keyboard driver code, you can add debug prints to see if the code is called at all when in MEM mode. You can also look at your Board Specific file / USB driver file to see what peripherals are shutdown while in suspend. – gfrigon Dec 02 '15 at 15:12
  • Curious our approach was sort of what you just said. I noticed it would stay on, but I had to enable wakeup on the correct device for the usb port, and also for the internal hub on the board and to fsl-ehci.1 . One detail I was missing was it also require to configure the correct usb port on fsl-ehci.1 to have it's power control to auto. After this it worked fine. – MRodrigues Dec 02 '15 at 15:39