msm: board-8930: Add support for PMIC PM8917

Add support for boards consisting of MSM8930 + PM8917.
Conditionally Remove configuration for peripherals not present in
PM8917.  Also remap GPIOs and MPPs as follows:

GPIOs:
PM8038  PM8917
1       24
2       25
3       27
4       19
5       25
6       23
7       38
8       28
9       20
10      36
11      37
12      21

MPPs:
PM8038  PM8917
1       5
2       6
3       10
4       8
5       7
6       9

Change-Id: I38166aaa85271b9d7f857f27b070fc36a0d0a803
Signed-off-by: David Collins <collinsd@codeaurora.org>
(cherry picked from commit fd344aa2e4fc70cb33b0a0623577662288a7674e)
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index a3e1b27..82ab492 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -18,6 +18,7 @@
 #include <asm/mach-types.h>
 #include <mach/msm_bus_board.h>
 #include <mach/restart.h>
+#include <mach/socinfo.h>
 #include "devices.h"
 #include "board-8930.h"
 
@@ -31,7 +32,7 @@
 	struct pm8xxx_mpp_config_data	config;
 };
 
-#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+#define PM8038_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
 			_func, _inv, _disable) \
 { \
 	.gpio	= PM8038_GPIO_PM_TO_SYS(_gpio), \
@@ -48,7 +49,7 @@
 	} \
 }
 
-#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+#define PM8038_MPP_INIT(_mpp, _type, _level, _control) \
 { \
 	.mpp	= PM8038_MPP_PM_TO_SYS(_mpp), \
 	.config	= { \
@@ -58,49 +59,126 @@
 	} \
 }
 
-#define PM8XXX_GPIO_DISABLE(_gpio) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM8038_GPIO_VIN_L11, \
+#define PM8038_GPIO_DISABLE(_gpio) \
+	PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM8038_GPIO_VIN_L11, \
 			 0, 0, 0, 1)
 
-#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+#define PM8038_GPIO_OUTPUT(_gpio, _val) \
+	PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
 			PM_GPIO_PULL_NO, PM8038_GPIO_VIN_L11, \
 			PM_GPIO_STRENGTH_HIGH, \
 			PM_GPIO_FUNC_NORMAL, 0, 0)
 
-#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+#define PM8038_GPIO_INPUT(_gpio, _pull) \
+	PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
 			_pull, PM8038_GPIO_VIN_L11, \
 			PM_GPIO_STRENGTH_NO, \
 			PM_GPIO_FUNC_NORMAL, 0, 0)
 
-#define PM8XXX_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+#define PM8038_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+	PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
 			PM_GPIO_PULL_NO, PM8038_GPIO_VIN_L11, \
 			PM_GPIO_STRENGTH_HIGH, \
 			_func, 0, 0)
 
-#define PM8XXX_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+#define PM8038_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+	PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
 			PM_GPIO_PULL_NO, _vin, \
 			PM_GPIO_STRENGTH_HIGH, \
 			PM_GPIO_FUNC_NORMAL, 0, 0)
 
-/* Initial pm8038 GPIO configurations */
+#define PM8917_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+			_func, _inv, _disable) \
+{ \
+	.gpio	= PM8917_GPIO_PM_TO_SYS(_gpio), \
+	.config	= { \
+		.direction	= _dir, \
+		.output_buffer	= _buf, \
+		.output_value	= _val, \
+		.pull		= _pull, \
+		.vin_sel	= _vin, \
+		.out_strength	= _out_strength, \
+		.function	= _func, \
+		.inv_int_pol	= _inv, \
+		.disable_pin	= _disable, \
+	} \
+}
+
+#define PM8917_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8917_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
+
+#define PM8917_GPIO_DISABLE(_gpio) \
+	PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+			 0, 0, 0, 1)
+
+#define PM8917_GPIO_OUTPUT(_gpio, _val) \
+	PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8917_GPIO_INPUT(_gpio, _pull) \
+	PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+			_pull, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_NO, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8917_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+	PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_HIGH, \
+			_func, 0, 0)
+
+#define PM8917_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+	PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, _vin, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+/* GPIO and MPP configurations for MSM8930 + PM8038 targets */
+
+/* Initial PM8038 GPIO configurations */
 static struct pm8xxx_gpio_init pm8038_gpios[] __initdata = {
 	/* keys GPIOs */
-	PM8XXX_GPIO_INPUT(3, PM_GPIO_PULL_UP_30),
-	PM8XXX_GPIO_INPUT(8, PM_GPIO_PULL_UP_30),
-	PM8XXX_GPIO_INPUT(10, PM_GPIO_PULL_UP_30),
-	PM8XXX_GPIO_INPUT(11, PM_GPIO_PULL_UP_30),
+	PM8038_GPIO_INPUT(3, PM_GPIO_PULL_UP_30),
+	PM8038_GPIO_INPUT(8, PM_GPIO_PULL_UP_30),
+	PM8038_GPIO_INPUT(10, PM_GPIO_PULL_UP_30),
+	PM8038_GPIO_INPUT(11, PM_GPIO_PULL_UP_30),
 	/* haptics gpio */
-	PM8XXX_GPIO_OUTPUT_FUNC(7, 0, PM_GPIO_FUNC_1),
+	PM8038_GPIO_OUTPUT_FUNC(7, 0, PM_GPIO_FUNC_1),
 	/* MHL PWR EN */
-	PM8XXX_GPIO_OUTPUT_VIN(5, 1, PM_GPIO_VIN_VPH),
+	PM8038_GPIO_OUTPUT_VIN(5, 1, PM8038_GPIO_VIN_VPH),
 };
 
-/* Initial pm8038 MPP configurations */
-static struct pm8xxx_mpp_init pm8038_mpps[] __initdata = {};
+/* Initial PM8038 MPP configurations */
+static struct pm8xxx_mpp_init pm8038_mpps[] __initdata = {
+};
+
+/* GPIO and MPP configurations for MSM8930 + PM8917 targets */
+
+/* Initial PM8917 GPIO configurations */
+static struct pm8xxx_gpio_init pm8917_gpios[] __initdata = {
+	/* keys GPIOs */
+	PM8917_GPIO_INPUT(27, PM_GPIO_PULL_UP_30),
+	PM8917_GPIO_INPUT(28, PM_GPIO_PULL_UP_30),
+	PM8917_GPIO_INPUT(36, PM_GPIO_PULL_UP_30),
+	PM8917_GPIO_INPUT(37, PM_GPIO_PULL_UP_30),
+	/* haptics gpio */
+	PM8917_GPIO_OUTPUT_FUNC(38, 0, PM_GPIO_FUNC_2),
+	/* MHL PWR EN */
+	PM8917_GPIO_OUTPUT_VIN(25, 1, PM_GPIO_VIN_VPH),
+};
+
+/* Initial PM8917 MPP configurations */
+static struct pm8xxx_mpp_init pm8917_mpps[] __initdata = {
+};
 
 void __init msm8930_pm8038_gpio_mpp_init(void)
 {
@@ -126,7 +204,31 @@
 	}
 }
 
-static struct pm8xxx_adc_amux pm8xxx_adc_channels_data[] = {
+void __init msm8930_pm8917_gpio_mpp_init(void)
+{
+	int i, rc;
+
+	for (i = 0; i < ARRAY_SIZE(pm8917_gpios); i++) {
+		rc = pm8xxx_gpio_config(pm8917_gpios[i].gpio,
+					&pm8917_gpios[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+
+	/* Initial MPP configuration. */
+	for (i = 0; i < ARRAY_SIZE(pm8917_mpps); i++) {
+		rc = pm8xxx_mpp_config(pm8917_mpps[i].mpp,
+					&pm8917_mpps[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+}
+
+static struct pm8xxx_adc_amux pm8038_adc_channels_data[] = {
 	{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
 		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
 	{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
@@ -161,16 +263,16 @@
 		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
 };
 
-static struct pm8xxx_adc_properties pm8xxx_adc_data = {
+static struct pm8xxx_adc_properties pm8038_adc_data = {
 	.adc_vdd_reference	= 1800, /* milli-voltage for this adc */
 	.bitresolution		= 15,
 	.bipolar                = 0,
 };
 
-static struct pm8xxx_adc_platform_data pm8xxx_adc_pdata = {
-	.adc_channel            = pm8xxx_adc_channels_data,
-	.adc_num_board_channel  = ARRAY_SIZE(pm8xxx_adc_channels_data),
-	.adc_prop               = &pm8xxx_adc_data,
+static struct pm8xxx_adc_platform_data pm8038_adc_pdata = {
+	.adc_channel            = pm8038_adc_channels_data,
+	.adc_num_board_channel  = ARRAY_SIZE(pm8038_adc_channels_data),
+	.adc_prop               = &pm8038_adc_data,
 	.adc_mpp_base		= PM8038_MPP_PM_TO_SYS(1),
 };
 
@@ -228,6 +330,7 @@
 	.thermal_mitigation	= pm8921_therm_mitigation,
 	.thermal_levels		= ARRAY_SIZE(pm8921_therm_mitigation),
 	.led_src_config		= LED_SRC_VPH_PWR,
+	.rconn_mohm		= 18,
 };
 
 #define PM8038_WLED_MAX_CURRENT		25
@@ -363,6 +466,7 @@
 	.shutdown_soc_valid_limit	= 20,
 	.adjust_soc_low_threshold	= 25,
 	.chg_term_ua			= CHG_TERM_MA * 1000,
+	.rconn_mohm			= 18,
 };
 
 static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
@@ -375,7 +479,7 @@
 	.regulator_pdatas	= msm8930_pm8038_regulator_pdata,
 	.charger_pdata		= &pm8921_chg_pdata,
 	.bms_pdata		= &pm8921_bms_pdata,
-	.adc_pdata		= &pm8xxx_adc_pdata,
+	.adc_pdata		= &pm8038_adc_pdata,
 	.leds_pdata		= &pm8xxx_leds_pdata,
 	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
 	.spk_pdata		= &pm8xxx_spk_pdata,
@@ -389,15 +493,99 @@
 	},
 };
 
+/* PM8917 platform data */
+
+static struct pm8xxx_adc_amux pm8917_adc_channels_data[] = {
+	{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
+	{"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV2,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
+	{"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
+	{"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+};
+
+static struct pm8xxx_adc_properties pm8917_adc_data = {
+	.adc_vdd_reference	= 1800, /* milli-voltage for this adc */
+	.bitresolution		= 15,
+	.bipolar                = 0,
+};
+
+static struct pm8xxx_adc_platform_data pm8917_adc_pdata = {
+	.adc_channel            = pm8917_adc_channels_data,
+	.adc_num_board_channel  = ARRAY_SIZE(pm8917_adc_channels_data),
+	.adc_prop               = &pm8917_adc_data,
+	.adc_mpp_base		= PM8917_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8921_platform_data pm8917_platform_data __devinitdata = {
+	.irq_pdata		= &pm8xxx_irq_pdata,
+	.gpio_pdata		= &pm8xxx_gpio_pdata,
+	.mpp_pdata		= &pm8xxx_mpp_pdata,
+	.rtc_pdata              = &pm8xxx_rtc_pdata,
+	.pwrkey_pdata		= &pm8xxx_pwrkey_pdata,
+	.misc_pdata		= &pm8xxx_misc_pdata,
+	.regulator_pdatas	= msm8930_pm8038_regulator_pdata,
+	.charger_pdata		= &pm8921_chg_pdata,
+	.bms_pdata		= &pm8921_bms_pdata,
+	.adc_pdata		= &pm8917_adc_pdata,
+	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
+};
+
+static struct msm_ssbi_platform_data msm8930_ssbi_pm8917_pdata __devinitdata = {
+	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+	.slave	= {
+		.name			= "pm8921-core",
+		.platform_data		= &pm8917_platform_data,
+	},
+};
+
 void __init msm8930_init_pmic(void)
 {
-	pmic_reset_irq = PM8038_IRQ_BASE + PM8038_RESOUT_IRQ;
-	msm8960_device_ssbi_pmic.dev.platform_data =
-				&msm8930_ssbi_pm8038_pdata;
-	pm8038_platform_data.num_regulators
-		= msm8930_pm8038_regulator_pdata_len;
-	if (machine_is_apq8064_mtp())
-		pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
-	else if (machine_is_apq8064_liquid())
-		pm8921_bms_pdata.battery_type = BATT_DESAY;
+	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
+		/* PM8038 configuration */
+		pmic_reset_irq = PM8038_IRQ_BASE + PM8038_RESOUT_IRQ;
+		msm8960_device_ssbi_pmic.dev.platform_data =
+					&msm8930_ssbi_pm8038_pdata;
+		pm8038_platform_data.num_regulators
+			= msm8930_pm8038_regulator_pdata_len;
+		if (machine_is_apq8064_mtp())
+			pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
+		else if (machine_is_apq8064_liquid())
+			pm8921_bms_pdata.battery_type = BATT_DESAY;
+	} else {
+		/* PM8917 configuration */
+		pmic_reset_irq = PM8917_IRQ_BASE + PM8921_RESOUT_IRQ;
+		msm8960_device_ssbi_pmic.dev.platform_data =
+					&msm8930_ssbi_pm8917_pdata;
+		pm8038_platform_data.num_regulators
+			= msm8930_pm8038_regulator_pdata_len;
+		if (machine_is_apq8064_mtp())
+			pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
+		else if (machine_is_apq8064_liquid())
+			pm8921_bms_pdata.battery_type = BATT_DESAY;
+	}
 }
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index d065d90..889f6f1 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1674,18 +1674,26 @@
 
 #define ISA1200_HAP_EN_GPIO	77
 #define ISA1200_HAP_LEN_GPIO	78
-#define ISA1200_HAP_CLK		PM8038_GPIO_PM_TO_SYS(7)
+#define ISA1200_HAP_CLK_PM8038	PM8038_GPIO_PM_TO_SYS(7)
+#define ISA1200_HAP_CLK_PM8917	PM8917_GPIO_PM_TO_SYS(38)
 
 static int isa1200_power(int on)
 {
+	unsigned int gpio = ISA1200_HAP_CLK_PM8038;
+	enum pm8xxx_aux_clk_id clk_id = CLK_MP3_1;
 	int rc = 0;
 
-	gpio_set_value_cansleep(ISA1200_HAP_CLK, !!on);
+	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
+		gpio = ISA1200_HAP_CLK_PM8917;
+		clk_id = CLK_MP3_2;
+	}
+
+	gpio_set_value_cansleep(gpio, !!on);
 
 	if (on)
-		rc = pm8xxx_aux_clk_control(CLK_MP3_1, XO_DIV_1, true);
+		rc = pm8xxx_aux_clk_control(clk_id, XO_DIV_1, true);
 	else
-		rc = pm8xxx_aux_clk_control(CLK_MP3_1, XO_DIV_NONE, true);
+		rc = pm8xxx_aux_clk_control(clk_id, XO_DIV_NONE, true);
 
 	if (rc) {
 		pr_err("%s: unable to write aux clock register(%d)\n",
@@ -1697,29 +1705,33 @@
 
 static int isa1200_dev_setup(bool enable)
 {
+	unsigned int gpio = ISA1200_HAP_CLK_PM8038;
 	int rc = 0;
 
+	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+		gpio = ISA1200_HAP_CLK_PM8917;
+
 	if (!enable)
 		goto fail_gpio_dir;
 
-	rc = gpio_request(ISA1200_HAP_CLK, "haptics_clk");
+	rc = gpio_request(gpio, "haptics_clk");
 	if (rc) {
 		pr_err("%s: gpio_request for %d gpio failed rc(%d)\n",
-					__func__, ISA1200_HAP_CLK, rc);
+					__func__, gpio, rc);
 		goto fail_gpio_req;
 	}
 
-	rc = gpio_direction_output(ISA1200_HAP_CLK, 0);
+	rc = gpio_direction_output(gpio, 0);
 	if (rc) {
 		pr_err("%s: gpio_direction_output failed for %d gpio rc(%d)\n",
-						__func__, ISA1200_HAP_CLK, rc);
+						__func__, gpio, rc);
 		goto fail_gpio_dir;
 	}
 
 	return 0;
 
 fail_gpio_dir:
-	gpio_free(ISA1200_HAP_CLK);
+	gpio_free(gpio);
 fail_gpio_req:
 	return rc;
 
@@ -1956,12 +1968,13 @@
 	},
 };
 
-#define MHL_POWER_GPIO       PM8038_GPIO_PM_TO_SYS(MHL_GPIO_PWR_EN)
+#define MHL_POWER_GPIO_PM8038	PM8038_GPIO_PM_TO_SYS(MHL_GPIO_PWR_EN)
+#define MHL_POWER_GPIO_PM8917	PM8917_GPIO_PM_TO_SYS(25)
 static struct msm_mhl_platform_data mhl_platform_data = {
 	.irq = MSM_GPIO_TO_INT(MHL_GPIO_INT),
 	.gpio_mhl_int = MHL_GPIO_INT,
 	.gpio_mhl_reset = MHL_GPIO_RESET,
-	.gpio_mhl_power = MHL_POWER_GPIO,
+	.gpio_mhl_power = MHL_POWER_GPIO_PM8038,
 	.gpio_hdmi_mhl_mux = HDMI_MHL_MUX_GPIO,
 };
 
@@ -1980,17 +1993,22 @@
 
 #ifdef MSM8930_PHASE_2
 
-#define GPIO_VOLUME_UP		PM8038_GPIO_PM_TO_SYS(3)
-#define GPIO_VOLUME_DOWN	PM8038_GPIO_PM_TO_SYS(8)
-#define GPIO_CAMERA_SNAPSHOT	PM8038_GPIO_PM_TO_SYS(10)
-#define GPIO_CAMERA_FOCUS	PM8038_GPIO_PM_TO_SYS(11)
+#define GPIO_VOLUME_UP_PM8038		PM8038_GPIO_PM_TO_SYS(3)
+#define GPIO_VOLUME_DOWN_PM8038		PM8038_GPIO_PM_TO_SYS(8)
+#define GPIO_CAMERA_SNAPSHOT_PM8038	PM8038_GPIO_PM_TO_SYS(10)
+#define GPIO_CAMERA_FOCUS_PM8038	PM8038_GPIO_PM_TO_SYS(11)
 
-static struct gpio_keys_button keys_8930[] = {
+#define GPIO_VOLUME_UP_PM8917		PM8917_GPIO_PM_TO_SYS(27)
+#define GPIO_VOLUME_DOWN_PM8917		PM8917_GPIO_PM_TO_SYS(28)
+#define GPIO_CAMERA_SNAPSHOT_PM8917	PM8917_GPIO_PM_TO_SYS(36)
+#define GPIO_CAMERA_FOCUS_PM8917	PM8917_GPIO_PM_TO_SYS(37)
+
+static struct gpio_keys_button keys_8930_pm8038[] = {
 	{
 		.code = KEY_VOLUMEUP,
 		.type = EV_KEY,
 		.desc = "volume_up",
-		.gpio = GPIO_VOLUME_UP,
+		.gpio = GPIO_VOLUME_UP_PM8038,
 		.wakeup = 1,
 		.active_low = 1,
 		.debounce_interval = 15,
@@ -1999,7 +2017,7 @@
 		.code = KEY_VOLUMEDOWN,
 		.type = EV_KEY,
 		.desc = "volume_down",
-		.gpio = GPIO_VOLUME_DOWN,
+		.gpio = GPIO_VOLUME_DOWN_PM8038,
 		.wakeup = 1,
 		.active_low = 1,
 		.debounce_interval = 15,
@@ -2008,7 +2026,7 @@
 		.code = KEY_CAMERA_FOCUS,
 		.type = EV_KEY,
 		.desc = "camera_focus",
-		.gpio = GPIO_CAMERA_FOCUS,
+		.gpio = GPIO_CAMERA_FOCUS_PM8038,
 		.wakeup = 1,
 		.active_low = 1,
 		.debounce_interval = 15,
@@ -2017,7 +2035,46 @@
 		.code = KEY_CAMERA_SNAPSHOT,
 		.type = EV_KEY,
 		.desc = "camera_snapshot",
-		.gpio = GPIO_CAMERA_SNAPSHOT,
+		.gpio = GPIO_CAMERA_SNAPSHOT_PM8038,
+		.wakeup = 1,
+		.active_low = 1,
+		.debounce_interval = 15,
+	},
+};
+
+static struct gpio_keys_button keys_8930_pm8917[] = {
+	{
+		.code = KEY_VOLUMEUP,
+		.type = EV_KEY,
+		.desc = "volume_up",
+		.gpio = GPIO_VOLUME_UP_PM8917,
+		.wakeup = 1,
+		.active_low = 1,
+		.debounce_interval = 15,
+	},
+	{
+		.code = KEY_VOLUMEDOWN,
+		.type = EV_KEY,
+		.desc = "volume_down",
+		.gpio = GPIO_VOLUME_DOWN_PM8917,
+		.wakeup = 1,
+		.active_low = 1,
+		.debounce_interval = 15,
+	},
+	{
+		.code = KEY_CAMERA_FOCUS,
+		.type = EV_KEY,
+		.desc = "camera_focus",
+		.gpio = GPIO_CAMERA_FOCUS_PM8917,
+		.wakeup = 1,
+		.active_low = 1,
+		.debounce_interval = 15,
+	},
+	{
+		.code = KEY_CAMERA_SNAPSHOT,
+		.type = EV_KEY,
+		.desc = "camera_snapshot",
+		.gpio = GPIO_CAMERA_SNAPSHOT_PM8917,
 		.wakeup = 1,
 		.active_low = 1,
 		.debounce_interval = 15,
@@ -2026,8 +2083,8 @@
 
 /* Add GPIO keys for 8930 */
 static struct gpio_keys_platform_data gpio_keys_8930_pdata = {
-	.buttons = keys_8930,
-	.nbuttons = 4,
+	.buttons = keys_8930_pm8038,
+	.nbuttons = ARRAY_SIZE(keys_8930_pm8038),
 };
 
 static struct platform_device gpio_keys_8930 = {
@@ -2586,8 +2643,19 @@
 #endif
 }
 
+/* Modify platform data values to match requirements for PM8917. */
+static void __init msm8930_pm8917_pdata_fixup(void)
+{
+	mhl_platform_data.gpio_mhl_power = MHL_POWER_GPIO_PM8917;
+
+	gpio_keys_8930_pdata.buttons = keys_8930_pm8917;
+	gpio_keys_8930_pdata.nbuttons = ARRAY_SIZE(keys_8930_pm8917);
+}
+
 static void __init msm8930_cdp_init(void)
 {
+	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+		msm8930_pm8917_pdata_fixup();
 	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
 		pr_err("meminfo_init() failed!\n");
 
@@ -2648,7 +2716,10 @@
 #ifndef MSM8930_PHASE_2
 	msm8960_pm8921_gpio_mpp_init();
 #else
-	msm8930_pm8038_gpio_mpp_init();
+	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
+		msm8930_pm8038_gpio_mpp_init();
+	else
+		msm8930_pm8917_gpio_mpp_init();
 #endif
 	platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
 #ifdef CONFIG_MSM_CAMERA
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index daded29..20937e3 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -138,6 +138,7 @@
 int msm8930_init_gpiomux(void);
 void msm8930_allocate_fb_region(void);
 void msm8930_pm8038_gpio_mpp_init(void);
+void msm8930_pm8917_gpio_mpp_init(void);
 void msm8930_mdp_writeback(struct memtype_reserve *reserve_table);
 void __init msm8930_init_gpu(void);