power: rk818-charger: set sleep otg 5v by otg_in status and dts
authorJianhong Chen <chenjh@rock-chips.com>
Mon, 19 Dec 2016 06:37:53 +0000 (14:37 +0800)
committerJianhong Chen <chenjh@rock-chips.com>
Mon, 13 Feb 2017 08:21:17 +0000 (16:21 +0800)
Change-Id: I1b2c14dfa64fe382e05717c5e9bb6a5617badba0
Signed-off-by: Jianhong Chen <chenjh@rock-chips.com>
drivers/power/rk818_charger.c
include/linux/mfd/rk808.h

index 425edd27c8428dbb5ed2b337ae6249f926a0724c..538952e61d54ee4d61a3f00957b6a020af1ab64b 100644 (file)
@@ -113,6 +113,7 @@ struct charger_platform_data {
        bool support_dc_det;
        int virtual_power;
        int sample_res;
+       int otg5v_suspend_enable;
        bool extcon;
 };
 
@@ -150,6 +151,7 @@ struct rk818_charger {
        u8 chrg_input;
        u8 chrg_current;
        u8 res_div;
+       u8 sleep_set_off_reg1;
        u8 plugin_trigger;
        u8 plugout_trigger;
        int plugin_irq;
@@ -1174,6 +1176,13 @@ static int rk818_cg_parse_dt(struct rk818_charger *cg)
                dev_err(dev, "sample_res missing!\n");
        }
 
+       ret = of_property_read_u32(np, "otg5v_suspend_enable",
+                                  &pdata->otg5v_suspend_enable);
+       if (ret < 0) {
+               pdata->otg5v_suspend_enable = 1;
+               dev_err(dev, "otg5v_suspend_enable missing!\n");
+       }
+
        if (!is_battery_exist(cg))
                pdata->virtual_power = 1;
 
@@ -1306,8 +1315,47 @@ static void rk818_charger_shutdown(struct platform_device *pdev)
                cg->ac_in, cg->usb_in, cg->dc_in, cg->otg_in);
 }
 
+static int rk818_charger_suspend(struct platform_device *pdev,
+                                pm_message_t state)
+{
+       struct rk818_charger *cg = platform_get_drvdata(pdev);
+
+       cg->sleep_set_off_reg1 = rk818_reg_read(cg, RK818_SLEEP_SET_OFF_REG1);
+
+       /* enable sleep boost5v and otg5v */
+       if (cg->pdata->otg5v_suspend_enable) {
+               if ((cg->otg_in && !cg->dc_in) ||
+                   (cg->otg_in && cg->dc_in && !cg->pdata->power_dc2otg)) {
+                       rk818_reg_clear_bits(cg, RK818_SLEEP_SET_OFF_REG1,
+                                            OTG_BOOST_SLP_OFF);
+                       CG_INFO("suspend: otg 5v on\n");
+                       return 0;
+               }
+       }
+
+       /* disable sleep otg5v */
+       rk818_reg_set_bits(cg, RK818_SLEEP_SET_OFF_REG1,
+                          OTG_SLP_SET_OFF, OTG_SLP_SET_OFF);
+       CG_INFO("suspend: otg 5v off\n");
+
+       return 0;
+}
+
+static int rk818_charger_resume(struct platform_device *pdev)
+{
+       struct rk818_charger *cg = platform_get_drvdata(pdev);
+
+       /* resume sleep boost5v and otg5v */
+       rk818_reg_set_bits(cg, RK818_SLEEP_SET_OFF_REG1,
+                          OTG_BOOST_SLP_OFF, cg->sleep_set_off_reg1);
+
+       return 0;
+}
+
 static struct platform_driver rk818_charger_driver = {
        .probe = rk818_charger_probe,
+       .suspend = rk818_charger_suspend,
+       .resume = rk818_charger_resume,
        .shutdown = rk818_charger_shutdown,
        .driver = {
                .name   = "rk818-charger",
index 59aa1eeb2845d17379a85f3b22b662a3015fde2f..e1bbc26dce843664753aa9e612a3fc75bdefd4fe 100644 (file)
@@ -389,6 +389,7 @@ enum rk805_reg {
 #define LDO9_SLP_SET_OFF       BIT(5)
 #define SWITCH_SLP_SET_OFF     BIT(6)
 #define OTG_SLP_SET_OFF                BIT(7)
+#define OTG_BOOST_SLP_OFF      (BOOST_SLP_SET_OFF | OTG_SLP_SET_OFF)
 
 #define BUCK1_SLP_SET_ON       BIT(0)
 #define BUCK2_SLP_SET_ON       BIT(1)