rk30:sdk:support wm8326 early suspend and modify dcdc or ldo mode when in early suspend
author张晴 <zhangqing@rock-chips.com>
Fri, 17 Aug 2012 06:30:45 +0000 (14:30 +0800)
committer张晴 <zhangqing@rock-chips.com>
Fri, 17 Aug 2012 06:30:45 +0000 (14:30 +0800)
arch/arm/mach-rk30/board-rk30-sdk-wm8326.c
drivers/mfd/wm831x-core.c
drivers/regulator/wm831x-ldo.c

index fbba1ea0aeb37f4be4591752b5aa970d53c10787..ac710815443442f5ea7bbf21c306214e19c3937d 100755 (executable)
@@ -5,6 +5,7 @@
 #include <linux/mfd/wm831x/pmu.h>
 
 #include <mach/sram.h>
+#include <linux/earlysuspend.h>
 
 #define cru_readl(offset)      readl_relaxed(RK30_CRU_BASE + offset)
 #define cru_writel(v, offset)  do { writel_relaxed(v, RK30_CRU_BASE + offset); dsb(); } while (0)
@@ -498,7 +499,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
                        .min_uV = 600000,
                        .max_uV = 1800000,      //0.6-1.8V
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
                },
                .num_consumer_supplies = ARRAY_SIZE(dcdc1_consumers),
                .consumer_supplies = dcdc1_consumers,
@@ -509,7 +511,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
                        .min_uV = 600000,
                        .max_uV = 1800000,      //0.6-1.8V
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
                },
                .num_consumer_supplies = ARRAY_SIZE(dcdc2_consumers),
                .consumer_supplies = dcdc2_consumers,
@@ -520,7 +523,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
                        .min_uV = 850000,
                        .max_uV = 3400000,      //0.85-3.4V
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
                },
                .num_consumer_supplies = ARRAY_SIZE(dcdc3_consumers),
                .consumer_supplies = dcdc3_consumers,
@@ -531,7 +535,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
                        .min_uV = 850000,
                        .max_uV = 3400000,      //0.85-3.4V
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
                },
                .num_consumer_supplies = ARRAY_SIZE(dcdc4_consumers),
                .consumer_supplies = dcdc4_consumers,
@@ -572,7 +577,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 900000,
                        .max_uV = 3300000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo1_consumers),
                .consumer_supplies = ldo1_consumers,
@@ -583,7 +589,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 900000,
                        .max_uV = 3300000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
                .consumer_supplies = ldo2_consumers,
@@ -594,7 +601,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 900000,
                        .max_uV = 3300000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo3_consumers),
                .consumer_supplies = ldo3_consumers,
@@ -605,7 +613,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 900000,
                        .max_uV = 3300000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo4_consumers),
                .consumer_supplies = ldo4_consumers,
@@ -616,7 +625,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 900000,
                        .max_uV = 3300000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo5_consumers),
                .consumer_supplies = ldo5_consumers,
@@ -627,7 +637,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 900000,
                        .max_uV = 3300000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo6_consumers),
                .consumer_supplies = ldo6_consumers,
@@ -638,7 +649,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 1000000,
                        .max_uV = 3500000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo7_consumers),
                .consumer_supplies = ldo7_consumers,
@@ -649,7 +661,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 1000000,
                        .max_uV = 3500000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo8_consumers),
                .consumer_supplies = ldo8_consumers,
@@ -660,7 +673,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 1000000,
                        .max_uV = 3500000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo9_consumers),
                .consumer_supplies = ldo9_consumers,
@@ -671,7 +685,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 1000000,
                        .max_uV = 3500000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo10_consumers),
                .consumer_supplies = ldo10_consumers,
@@ -682,7 +697,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
                        .min_uV = 800000,
                        .max_uV = 1550000,
                        .apply_uV = true,
-                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+                       .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
                },
                .num_consumer_supplies = ARRAY_SIZE(ldo11_consumers),
                .consumer_supplies = ldo11_consumers,
@@ -777,6 +793,93 @@ out:
        return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
+void wm831x_pmu_early_suspend(struct regulator_dev *rdev)
+{
+       struct regulator *dcdc;
+       struct regulator *ldo;
+       printk("%s\n", __func__);
+       
+       dcdc = regulator_get(NULL, "dcdc4");    //vcc_io
+       regulator_set_voltage(dcdc, 2800000, 2800000);
+       regulator_set_mode(dcdc, REGULATOR_MODE_STANDBY);
+       regulator_enable(dcdc);
+       printk("%s set dcdc4 vcc_io=%dmV end\n", __func__, regulator_get_voltage(dcdc));
+       regulator_put(dcdc);
+       udelay(100);
+
+       ldo = regulator_get(NULL, "ldo1");      //
+       regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);
+       
+       ldo = regulator_get(NULL, "ldo4");
+       regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);
+       
+       ldo = regulator_get(NULL, "ldo6");
+       regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);
+
+       ldo = regulator_get(NULL, "ldo8");
+       regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);    
+               
+}
+void wm831x_pmu_early_resume(struct regulator_dev *rdev)
+{
+       struct regulator *dcdc;
+       struct regulator *ldo;
+       printk("%s\n", __func__);
+       
+       dcdc = regulator_get(NULL, "dcdc4");    //vcc_io
+       regulator_set_voltage(dcdc, 3000000, 3000000);
+       regulator_set_mode(dcdc, REGULATOR_MODE_FAST);
+       regulator_enable(dcdc);
+       printk("%s set dcdc4 vcc_io=%dmV end\n", __func__, regulator_get_voltage(dcdc));
+       regulator_put(dcdc);
+       udelay(100);
+
+       ldo = regulator_get(NULL, "ldo1");      //
+       regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);
+
+       ldo = regulator_get(NULL, "ldo4");
+       regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);
+
+       ldo = regulator_get(NULL, "ldo6");
+       regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);
+
+       ldo = regulator_get(NULL, "ldo8");
+       regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
+       regulator_enable(ldo);
+       regulator_put(ldo);
+       udelay(100);    
+}
+#else
+void wm831x_pmu_early_suspend(struct regulator_dev *rdev)
+{
+}
+void wm831x_pmu_early_resume(struct regulator_dev *rdev)
+{
+}
+#endif
+
 void __sramfunc board_pmu_wm8326_suspend(void)
 {      
        cru_writel(CRU_CLKGATE5_GRFCLK_ON,CRU_CLKGATE5_CON_ADDR); //open grf clk
index 504314e87de102618486939bd37222c6651554cf..6ff1849eba14b6d66c764222442f538dd7f4bc06 100755 (executable)
 #include <linux/mfd/wm831x/pmu.h>
 
 #include <mach/board.h>
+#include <linux/earlysuspend.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct early_suspend wm831x_early_suspend;
+#endif
 
 /* Current settings - values are 2*2^(reg_val/4) microamps.  These are
  * exported since they are used by multiple drivers.
@@ -1465,6 +1470,10 @@ static struct mfd_cell backlight_devs[] = {
 /*
  * Instantiate the generic non-control parts of the device.
  */
+
+__weak void  wm831x_pmu_early_suspend(struct regulator_dev *rdev) {}
+__weak void  wm831x_pmu_early_resume(struct regulator_dev *rdev) {}
+
 int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 {
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -1729,7 +1738,13 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
                        goto err_irq;
                }
        }
-       
+       #ifdef CONFIG_HAS_EARLYSUSPEND
+       wm831x_early_suspend.level = 0xffff;
+    wm831x_early_suspend.suspend = wm831x_pmu_early_suspend;
+    wm831x_early_suspend.resume = wm831x_pmu_early_resume;
+    register_early_suspend(&wm831x_early_suspend);
+       #endif
+
        return 0;
 
 err_irq:
index a5fc30d8b3cac0a81e29536fcdfdbc8df0f5c5e4..aff55c8e08b02e6937d2db1159af6fe64807de74 100755 (executable)
@@ -206,7 +206,7 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
        int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
        int ret;
 
-       printk("%s base=%x,mode=%x\n", __FUNCTION__,ldo->base,mode);
+//     printk("%s base=%x,mode=%x\n", __FUNCTION__,ldo->base,mode);
        switch (mode) {
        case REGULATOR_MODE_NORMAL:
                ret = wm831x_set_bits(wm831x, on_reg,