[RAMEN9610-12679][Common] driver: fuelgauge: Force power off 3.25V.
authorKeunho Hwang <keunho.hwang@samsung.com>
Thu, 21 Feb 2019 10:17:24 +0000 (19:17 +0900)
committerhskang <hs1218.kang@samsung.com>
Thu, 28 Feb 2019 16:41:21 +0000 (01:41 +0900)
Change-Id: I9cf62abdc8bfaceb279c32dac8c229672db14f6b
Signed-off-by: Keunho Hwang <keunho.hwang@samsung.com>
drivers/power/supply/s2mu106_fuelgauge.c

index c088bff4d4bfd06d3f6a4cc7810a2adc06fe98e3..2aa19c16ac75c717e95555871144af5b502013d6 100644 (file)
 #include <linux/power/s2mu106_fuelgauge.h>
 #include <linux/of_gpio.h>
 #include <linux/platform_data/ntc_thermistor.h>
+#include <soc/samsung/exynos-pmu.h>
 
 static enum power_supply_property s2mu106_fuelgauge_props[] = {
 };
 
+#define PS_HOLD_CONTROL                        (0x330C)
+
+static void low_vbat_power_off(void);
 static int s2mu106_get_vbat(struct s2mu106_fuelgauge_data *fuelgauge);
 static int s2mu106_get_ocv(struct s2mu106_fuelgauge_data *fuelgauge);
 static int s2mu106_get_current(struct s2mu106_fuelgauge_data *fuelgauge);
@@ -927,6 +931,12 @@ static int s2mu106_get_rawsoc(struct s2mu106_fuelgauge_data *fuelgauge)
                fuelgauge->ui_soc, fuelgauge->is_charging, avg_vbat,
                float_voltage, avg_current, fg_mode_reg);
 
+       if (fuelgauge->ui_soc == 0 && avg_vbat <= 3250 && avg_current <= 5) {
+               pr_info("%s, UI SOC 0%! VBAT 3250!\n", __func__);
+
+               low_vbat_power_off();
+       }
+
        if ((fuelgauge->is_charging == true) &&
                ((fuelgauge->ui_soc >= 98) || ((avg_vbat > float_voltage) && (avg_current < 500)))) {
                if (fuelgauge->mode == CURRENT_MODE) { /* switch to VOLTAGE_MODE */
@@ -1403,6 +1413,18 @@ static int s2mu106_fg_set_property(struct power_supply *psy,
        return 0;
 }
 
+static void low_vbat_power_off(void)
+{
+       u32 ps_hold_data;
+
+       pr_info("%s, Set PS_HOLD Low\n", __func__);
+
+       mdelay(3000);
+
+       exynos_pmu_read(PS_HOLD_CONTROL, &ps_hold_data);
+       exynos_pmu_write(PS_HOLD_CONTROL, ps_hold_data & 0xFFFFFEFF);
+}
+
 static void s2mu106_fg_isr_work(struct work_struct *work)
 {
        struct s2mu106_fuelgauge_data *fuelgauge =