apq8084: Add support for volume up/down keys, reboot and usb
Change-Id: I761eb82a05deaca228366edd243479d4ea9f36c9
diff --git a/platform/apq8084/include/platform/iomap.h b/platform/apq8084/include/platform/iomap.h
index 27812cc..9d6f15b 100644
--- a/platform/apq8084/include/platform/iomap.h
+++ b/platform/apq8084/include/platform/iomap.h
@@ -31,6 +31,10 @@
#define MSM_SHARED_BASE 0x0FA00000
+#define MSM_SHARED_IMEM_BASE 0xFE805000
+
+#define RESTART_REASON_ADDR (MSM_SHARED_IMEM_BASE + 0x65C)
+
#define KPSS_BASE 0xF9000000
#define MSM_GIC_DIST_BASE KPSS_BASE
diff --git a/target/apq8084/init.c b/target/apq8084/init.c
index 0de99e1..034c3e0 100644
--- a/target/apq8084/init.c
+++ b/target/apq8084/init.c
@@ -50,9 +50,16 @@
#include <platform/gpio.h>
#include <stdlib.h>
+#define PMIC_ARB_CHANNEL_NUM 0
+#define PMIC_ARB_OWNER_ID 0
+
+#define FASTBOOT_MODE 0x77665500
+
static uint32_t mmc_sdc_base[] =
{ MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_BASE };
+extern void ulpi_write(unsigned val, unsigned reg);
+
void target_early_init(void)
{
#if WITH_DEBUG_UART
@@ -63,13 +70,27 @@
/* Return 1 if vol_up pressed */
static int target_volume_up()
{
- return 0;
+ uint8_t status = 0;
+ struct pm8x41_gpio gpio;
+
+ /* Configure the GPIO */
+ gpio.direction = PM_GPIO_DIR_IN;
+ gpio.function = 0;
+ gpio.pull = PM_GPIO_PULL_UP_30;
+ gpio.vin_sel = 2;
+
+ pm8x41_gpio_config(2, &gpio);
+
+ /* Get status of P_GPIO_2 */
+ pm8x41_gpio_get(2, &status);
+
+ return !status; /* active low */
}
/* Return 1 if vol_down pressed */
uint32_t target_volume_down()
{
- return 0;
+ return pm8x41_resin_status();
}
static void target_keystatus()
@@ -83,6 +104,30 @@
keys_post_event(KEY_VOLUMEUP, 1);
}
+/* Do target specific usb initialization */
+void target_usb_init(void)
+{
+ uint32_t val;
+
+ /* Select and enable external configuration with USB PHY */
+ ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_SET);
+
+ /* Enable sess_vld */
+ val = readl(USB_GENCONFIG_2) | GEN2_SESS_VLD_CTRL_EN;
+ writel(val, USB_GENCONFIG_2);
+
+ /* Enable external vbus configuration in the LINK */
+ val = readl(USB_USBCMD);
+ val |= SESS_VLD_CTRL;
+ writel(val, USB_USBCMD);
+}
+
+void target_usb_stop(void)
+{
+ /* Disable VBUS mimicing in the controller. */
+ ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_CLEAR);
+}
+
static void target_mmc_mci_init()
{
uint32_t base_addr;
@@ -136,6 +181,8 @@
{
dprintf(INFO, "target_init()\n");
+ spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
+
target_keystatus();
/*
@@ -222,8 +269,36 @@
unsigned check_reboot_mode(void)
{
+ uint32_t restart_reason = 0;
+ uint32_t restart_reason_addr;
+
+ restart_reason_addr = RESTART_REASON_ADDR;
+
+ /* Read reboot reason and scrub it */
+ restart_reason = readl(restart_reason_addr);
+ writel(0x00, restart_reason_addr);
+
+ return restart_reason;
}
void reboot_device(unsigned reboot_reason)
{
+ uint8_t reset_type = 0;
+
+ /* Write the reboot reason */
+ writel(reboot_reason, RESTART_REASON_ADDR);
+
+ if(reboot_reason == FASTBOOT_MODE)
+ reset_type = PON_PSHOLD_WARM_RESET;
+ else
+ reset_type = PON_PSHOLD_HARD_RESET;
+
+ pm8x41_reset_configure(reset_type);
+
+ /* Drop PS_HOLD for MSM */
+ writel(0x00, MPM2_MPM_PS_HOLD);
+
+ mdelay(5000);
+
+ dprintf(CRITICAL, "Rebooting failed\n");
}