Merge "msm8960: Clean up board detect code."
diff --git a/dev/pmic/pm8921/include/dev/pm8921.h b/dev/pmic/pm8921/include/dev/pm8921.h
index 2a41690..0426d42 100644
--- a/dev/pmic/pm8921/include/dev/pm8921.h
+++ b/dev/pmic/pm8921/include/dev/pm8921.h
@@ -32,10 +32,43 @@
 #include <sys/types.h>
 #include <dev/pm8921_leds.h>
 
+enum {
+	lvs_start = 1,
+	lvs_1 = lvs_start,
+	lvs_2,
+	lvs_3,
+	lvs_4,
+	lvs_5,
+	lvs_6,
+	lvs_7,
+	lvs_end = lvs_7,
+};
+
+enum {
+	mpp_start = 1,
+	mpp_1 = mpp_start,
+	mpp_2,
+	mpp_3,
+	mpp_4,
+	mpp_5,
+	mpp_6,
+	mpp_7,
+	mpp_8,
+	mpp_9,
+	mpp_10,
+	mpp_11,
+	mpp_12,
+	mpp_end = mpp_12,
+};
+
 #define PM_GPIO_DIR_OUT         0x01
 #define PM_GPIO_DIR_IN          0x02
 #define PM_GPIO_DIR_BOTH        (PM_GPIO_DIR_OUT | PM_GPIO_DIR_IN)
 
+/* output_buffer */
+#define PM_GPIO_OUT_BUF_OPEN_DRAIN  1
+#define PM_GPIO_OUT_BUF_CMOS        0
+
 #define PM_GPIO_PULL_UP_30      0
 #define PM_GPIO_PULL_UP_1_5     1
 #define PM_GPIO_PULL_UP_31_5    2
@@ -59,6 +92,7 @@
 
 #define LDO_2      (2)
 #define LDO_8      (8  | LDO_P_MASK)
+#define LDO_11     (11 | LDO_P_MASK)
 #define LDO_23     (23 | LDO_P_MASK)
 
 enum
@@ -119,6 +153,6 @@
 int pm8921_config_drv_keypad(unsigned int drv_flash_sel,
 	unsigned int flash_logic,
 	unsigned int flash_ensel);
-
-
+int pm8921_low_voltage_switch_enable(uint8_t lvs_id);
+int pm8921_mpp_set_digital_output(uint8_t mpp_id);
 #endif
diff --git a/dev/pmic/pm8921/pm8921.c b/dev/pmic/pm8921/pm8921.c
index 3200c47..15f409b 100644
--- a/dev/pmic/pm8921/pm8921.c
+++ b/dev/pmic/pm8921/pm8921.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -28,6 +28,7 @@
  */
 #include <assert.h>
 #include <sys/types.h>
+#include <err.h>
 #include <dev/pm8921.h>
 #include "pm8921_hw.h"
 
@@ -454,3 +455,66 @@
 	return ret;
 
 }
+
+int pm8921_low_voltage_switch_enable(uint8_t lvs_id)
+{
+	int ret =  NO_ERROR;
+	uint8_t val;
+
+	if (lvs_id < lvs_start || lvs_id > lvs_end) {
+		printf(CRITICAL, "Requested unsupported LVS.\n");
+		return ERROR;
+	}
+
+	if (lvs_id == lvs_2) {
+		printf(CRITICAL, "No support for LVS2 yet!\n");
+		return ERROR;
+	}
+
+	/* Read LVS_TEST Reg first*/
+	ret = dev->read(&val, 1, PM8921_LVS_TEST_REG(lvs_id));
+	if (ret) {
+		printf(CRITICAL, "Failed to read LVS_TEST Reg ret=%d.\n", ret);
+		return ret;
+	}
+
+	/* Check if switch is already ON */
+	val = val & PM8921_LVS_100_TEST_VOUT_OK;
+	if (val)
+		return ret;
+
+	/* Turn on switch in normal mode */
+	val = 0;
+	val |= PM8921_LVS_100_CTRL_SW_EN; /* Enable Switch */
+	val |= PM8921_LVS_100_CTRL_SLEEP_B_IGNORE; /* Ignore sleep mode pin */
+	ret = dev->write(&val, 1, PM8921_LVS_CTRL_REG(lvs_id));
+	if (ret)
+		printf(CRITICAL, "Failed to write LVS_CTRL Reg ret=%d.\n", ret);
+
+	return ret;
+}
+
+int pm8921_mpp_set_digital_output(uint8_t mpp_id)
+{
+	int ret = NO_ERROR;
+	uint8_t val;
+
+	if (mpp_id < mpp_start || mpp_id > mpp_end) {
+		printf(CRITICAL, "Requested unsupported MPP.\n");
+		return ERROR;
+	}
+
+	val = 0;
+	/* Configure in digital output mode */
+	val |= PM8921_MPP_CTRL_DIGITAL_OUTPUT;
+	val |= PM8921_MPP_CTRL_VIO_1; /* Set input voltage to 1.8V */
+	val |= PM8921_MPP_CTRL_OUTPUT_HIGH; /* Set mpp to high */
+
+	ret = dev->write(&val, 1, PM8921_MPP_CTRL_REG(mpp_id));
+	if (ret) {
+		printf(CRITICAL, "Failed to write MPP_CTRL Reg ret=%d.\n",
+			   ret);
+	}
+
+	return ret;
+}
diff --git a/dev/pmic/pm8921/pm8921_hw.h b/dev/pmic/pm8921/pm8921_hw.h
index 41e2d9a..02b01c6 100644
--- a/dev/pmic/pm8921/pm8921_hw.h
+++ b/dev/pmic/pm8921/pm8921_hw.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -112,3 +112,17 @@
 #define IRQ_BLOCK_SEL_USR_ADDR           0x1C0
 #define IRQ_STATUS_RT_USR_ADDR           0x1C3
 
+#define PM8921_LVS_REG_BASE       0x060
+#define PM8921_LVS_CTRL_REG(id)   (PM8921_LVS_REG_BASE + (2 * (id-1)))
+#define PM8921_LVS_TEST_REG(id)   (PM8921_LVS_CTRL_REG(id) + 1)
+
+#define PM8921_LVS_100_CTRL_SW_EN             (1 << 7)
+#define PM8921_LVS_100_CTRL_SLEEP_B_IGNORE    (1 << 4)
+#define PM8921_LVS_100_TEST_VOUT_OK           (1 << 6)
+
+#define PM8921_MPP_REG_BASE                   0x050
+#define PM8921_MPP_CTRL_REG(id)               (PM8921_MPP_REG_BASE + (id-1))
+
+#define PM8921_MPP_CTRL_DIGITAL_OUTPUT        (1 << 5)
+#define PM8921_MPP_CTRL_VIO_1                 (1 << 2)
+#define PM8921_MPP_CTRL_OUTPUT_HIGH           (1 << 0)
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index 0b1bf46..9651e6f 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -199,6 +199,7 @@
 	unsigned int header_size;
 	unsigned long long first_usable_lba;
 	unsigned long long backup_header_lba;
+	unsigned long long card_size_sec;
 	unsigned int max_partition_count = 0;
 	unsigned int partition_entry_size;
 	unsigned char data[BLOCK_SIZE];
@@ -207,15 +208,16 @@
 	unsigned int n = 0;	/* Counter for UTF-16 -> 8 conversion */
 	unsigned char UTF16_name[MAX_GPT_NAME_SIZE];
 	/* LBA of first partition -- 1 Block after Protected MBR + 1 for PT */
-	unsigned long long partition_0 = 2;
+	unsigned long long partition_0;
 	partition_count = 0;
 
 	/* Print out the GPT first */
 	ret = mmc_boot_read_from_card(mmc_host, mmc_card,
 				      PROTECTIVE_MBR_SIZE,
 				      BLOCK_SIZE, (unsigned int *)data);
-	if (ret)
+	if (ret){
 		dprintf(CRITICAL, "GPT: Could not read primary gpt from mmc\n");
+	}
 
 	ret = partition_parse_gpt_header(data, &first_usable_lba,
 					 &partition_entry_size, &header_size,
@@ -224,8 +226,12 @@
 		dprintf(INFO, "GPT: (WARNING) Primary signature invalid\n");
 
 		/* Check the backup gpt */
-		backup_header_lba =
-		    GET_LLWORD_FROM_BYTE(&data[BACKUP_HEADER_OFFSET]);
+
+		/* Get size of MMC */
+		card_size_sec = (mmc_card->capacity) / BLOCK_SIZE;
+		ASSERT (card_size_sec > 0);
+
+		backup_header_lba = card_size_sec - 1;
 		ret =
 		    mmc_boot_read_from_card(mmc_host, mmc_card,
 					    (backup_header_lba * BLOCK_SIZE),
@@ -246,9 +252,8 @@
 				"GPT: Primary and backup signatures invalid\n");
 			return ret;
 		}
-		partition_0 = backup_header_lba - (max_partition_count / 4);
 	}
-
+	partition_0 = GET_LLWORD_FROM_BYTE(&data[PARTITION_ENTRIES_OFFSET]);
 	/* Read GPT Entries */
 	for (i = 0; i < (max_partition_count / 4); i++) {
 		ASSERT(partition_count < NUM_PARTITIONS);