target: add api to get battery info

Add api to get battery's voltage and add safeguards such as
refusing to flash if minimum battery levels are not present or
be bypass if the device doesn't have a battery

Change-Id: Ie9fc45cd2d3a5f588acedef4fd9b0ffdcb2eae24
diff --git a/include/target.h b/include/target.h
index f2e2acd..6f83b6f 100644
--- a/include/target.h
+++ b/include/target.h
@@ -92,4 +92,8 @@
 uint32_t get_vibration_type();
 #endif
 
+uint32_t target_get_battery_voltage();
+bool target_battery_soc_ok();
+bool target_battery_is_present();
+uint32_t target_get_pmic();
 #endif
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 44eb81d..ede3841 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -136,6 +136,12 @@
 	PMIC_IS_PM8019    = 3,
 	PMIC_IS_PM8026    = 4,
 	PMIC_IS_PM8110    = 5,
+	PMIC_IS_PM8916    = 11,
+	PMIC_IS_PM8909    = 13,
+	PMIC_IS_PMI8950   = 17,
+	PMIC_IS_PMI8994   = 10,
+	PMIC_IS_PMI8996   = 19,
+
 } pm_model_type_bfly;
 
 struct smem_board_info_v3 {
diff --git a/target/init.c b/target/init.c
index c3893d3..8a34b62 100644
--- a/target/init.c
+++ b/target/init.c
@@ -29,13 +29,25 @@
 #include <dload_util.h>
 #include <sdhci_msm.h>
 #if PON_VIB_SUPPORT
-#include <smem.h>
 #include <vibrator.h>
 #include <board.h>
 #endif
 
+#include <smem.h>
+#include <pm8x41_adc.h>
+#include <pm8x41_hw.h>
+
+#if CHECK_BAT_VOLTAGE
+#include <pm_fg_adc_usr.h>
+#endif
+
 #define EXPAND(NAME) #NAME
 #define TARGET(NAME) EXPAND(NAME)
+
+#define BATTERY_MIN_VOLTAGE		3600000  //uv
+#define PMIC_SLAVE_ID                   0x20000
+#define BAT_IF_BAT_PRES_STATUS		0x1208
+
 /*
  * default implementations of these routines, if the target code
  * chooses not to implement.
@@ -260,3 +272,91 @@
 	return false;
 #endif
 }
+
+__WEAK uint32_t target_get_pmic()
+{
+	return PMIC_IS_UNKNOWN;
+}
+
+/* Check battery if it's exist */
+bool target_battery_is_present()
+{
+	bool batt_is_exist;
+	uint8_t value = 0;
+	uint32_t pmic;
+
+	pmic = target_get_pmic();
+
+	switch(pmic)
+	{
+		case PMIC_IS_PM8909:
+		case PMIC_IS_PM8916:
+		case PMIC_IS_PM8941:
+			value = REG_READ(BAT_IF_BAT_PRES_STATUS);
+			break;
+		case PMIC_IS_PMI8950:
+		case PMIC_IS_PMI8994:
+		case PMIC_IS_PMI8996:
+			value = REG_READ(PMIC_SLAVE_ID|
+			BAT_IF_BAT_PRES_STATUS);
+			break;
+		default:
+			dprintf(CRITICAL, "ERROR: Couldn't get the pmic type\n");
+			break;
+	}
+
+	batt_is_exist = value >> 7;
+
+	return batt_is_exist;
+
+}
+
+#if CHECK_BAT_VOLTAGE
+/* Return battery voltage */
+uint32_t target_get_battery_voltage()
+{
+	uint32_t pmic;
+	uint32_t vbat = 0;
+
+	pmic = target_get_pmic();
+
+	switch(pmic)
+	{
+		case PMIC_IS_PM8909:
+		case PMIC_IS_PM8916:
+		case PMIC_IS_PM8941:
+			vbat = pm8x41_get_batt_voltage(); //uv
+			break;
+		case PMIC_IS_PMI8950:
+		case PMIC_IS_PMI8994:
+		case PMIC_IS_PMI8996:
+			if (!pm_fg_usr_get_vbat(1, &vbat)) {
+				vbat = vbat*1000; //uv
+			} else {
+				dprintf(CRITICAL, "ERROR: Get battery voltage failed!!!\n");
+			}
+			break;
+		default:
+			dprintf(CRITICAL, "ERROR: Couldn't get the pmic type\n");
+			break;
+	}
+
+	return vbat;
+}
+
+/* Add safeguards such as refusing to flash if minimum battery levels
+ * are not present or be bypass if the device doesn't have a battery
+ */
+bool target_battery_soc_ok()
+{
+	if (!target_battery_is_present()) {
+		dprintf(INFO, "battery is not present\n");
+		return true;
+	}
+
+	if (target_get_battery_voltage() >= BATTERY_MIN_VOLTAGE)
+		return true;
+
+	return false;
+}
+#endif
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index 3cc3923..78cb704 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -49,6 +49,7 @@
 #include <gpio.h>
 #include <rpm-smd.h>
 #include <qpic_nand.h>
+#include <smem.h>
 
 #if LONG_PRESS_POWER_ON
 #include <shutdown_detect.h>
@@ -698,3 +699,8 @@
 {
 	pm8x41_reset_configure(reset_type);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PM8909;
+}
diff --git a/target/msm8909/rules.mk b/target/msm8909/rules.mk
index b3e2059..508609f 100644
--- a/target/msm8909/rules.mk
+++ b/target/msm8909/rules.mk
@@ -22,6 +22,7 @@
 	lib/ptable \
 	dev/gcdb/display \
 	dev/pmic/pm8x41 \
+	dev/pmic/pmi8994 \
 	lib/libfdt
 
 DEFINES += \
diff --git a/target/msm8916/init.c b/target/msm8916/init.c
index 7502bc5..693db04 100644
--- a/target/msm8916/init.c
+++ b/target/msm8916/init.c
@@ -48,6 +48,7 @@
 #include <crypto5_wrapper.h>
 #include <partition_parser.h>
 #include <stdlib.h>
+#include <smem.h>
 
 #if LONG_PRESS_POWER_ON
 #include <shutdown_detect.h>
@@ -503,3 +504,8 @@
 {
 	pm8x41_reset_configure(reset_type);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PM8916;
+}
diff --git a/target/msm8916/rules.mk b/target/msm8916/rules.mk
index 6acddef..1533102 100644
--- a/target/msm8916/rules.mk
+++ b/target/msm8916/rules.mk
@@ -21,6 +21,7 @@
 	lib/ptable \
 	dev/pmic/pm8x41 \
 	lib/libfdt \
+	dev/pmic/pmi8994 \
 	dev/gcdb/display
 
 DEFINES += \
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index 0c711de..ebf0349 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -57,6 +57,7 @@
 #include <boot_device.h>
 #include <secapp_loader.h>
 #include <rpmb.h>
+#include <smem.h>
 
 #include "target/display.h"
 
@@ -669,3 +670,8 @@
 
 	crypto_init_params(&ce_params);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PMI8950;
+}
diff --git a/target/msm8952/rules.mk b/target/msm8952/rules.mk
index fd3a56e..1c404d7 100644
--- a/target/msm8952/rules.mk
+++ b/target/msm8952/rules.mk
@@ -28,6 +28,7 @@
 	dev/vib \
 	lib/libfdt \
 	dev/qpnp_wled \
+	dev/pmic/pmi8994 \
 	dev/gcdb/display
 
 DEFINES += \
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index 35b17bd..266e091 100644
--- a/target/msm8974/init.c
+++ b/target/msm8974/init.c
@@ -826,3 +826,8 @@
 		tcsr_hs_phy_mux_configure();
 	}
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PM8941;
+}
\ No newline at end of file
diff --git a/target/msm8974/rules.mk b/target/msm8974/rules.mk
index b5b1218..f95a816 100644
--- a/target/msm8974/rules.mk
+++ b/target/msm8974/rules.mk
@@ -23,6 +23,7 @@
 	dev/keys \
 	dev/pmic/pm8x41 \
 	dev/gcdb/display \
+	dev/pmic/pmi8994 \
     lib/ptable \
     lib/libfdt
 
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index e3b513f..066b50f 100644
--- a/target/msm8994/init.c
+++ b/target/msm8994/init.c
@@ -647,3 +647,8 @@
 
 	return 0;
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PMI8994;
+}
diff --git a/target/msm8994/rules.mk b/target/msm8994/rules.mk
index 677ce8d..e7ed5ff 100644
--- a/target/msm8994/rules.mk
+++ b/target/msm8994/rules.mk
@@ -27,6 +27,7 @@
 	dev/qpnp_led \
     lib/ptable \
 	dev/gcdb/display \
+	dev/pmic/pmi8994 \
     lib/libfdt
 
 DEFINES += \
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index a80ad30..f55b71c 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -522,3 +522,8 @@
 {
 	pm8994_reset_configure(reset_type);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PMI8996;
+}