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");
 }