clk: rockchip: rk3366: modify the parent's name of usbphy480m
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / rk2818_lp8725.c
old mode 100644 (file)
new mode 100755 (executable)
index ba29580..3a99ff1
@@ -31,6 +31,16 @@ REVISION 0.01
 #include <linux/kernel.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/rk2818_lp8725.h>
+#include <mach/gpio.h>
+#include <linux/delay.h>
+#include <mach/iomux.h>
+
+//add by robert for reboot notifier
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+//end add
+
 
 
 #if 0
@@ -44,7 +54,7 @@ REVISION 0.01
 #define DBG_INFO(x...)
 #endif
 
-
+#define PM_CONTROL
 
 
 struct lp8725 {
@@ -210,7 +220,7 @@ static int lp8725_lilo_is_enabled(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
        int lilo = rdev_get_id(dev) - LP8725_LILO1;
-       u16 mask = 1 << (lilo+4);
+       u16 mask = 1 << (lilo+5);
        u16 val;
 
        val = lp8725_reg_read(lp8725, LP8725_LILO_ENABLE_REG);
@@ -221,7 +231,7 @@ static int lp8725_lilo_enable(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
        int lilo = rdev_get_id(dev) - LP8725_LILO1;
-       u16 mask = 1 << (lilo+4);
+       u16 mask = 1 << (lilo+5);
 
        return lp8725_set_bits(lp8725, LP8725_LILO_ENABLE_REG, mask, mask);
 }
@@ -230,7 +240,7 @@ static int lp8725_lilo_disable(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
        int lilo = rdev_get_id(dev) - LP8725_LILO1;
-       u16 mask = 1 << (lilo+4);
+       u16 mask = 1 << (lilo+5);
 
        return lp8725_set_bits(lp8725, LP8725_LILO_ENABLE_REG, mask, 0);
 }
@@ -447,7 +457,7 @@ static int lp8725_dcdc_set_voltage(struct regulator_dev *dev,
        return ret;
 }
 
-static int lp8725_dcdc_get_mode(struct regulator_dev *dev)
+static unsigned int lp8725_dcdc_get_mode(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
        u16 mask = 1 << 1;
@@ -670,12 +680,96 @@ static int lp8725_set_bits(struct lp8725 *lp8725, u8 reg, u16 mask, u16 val)
 }
 
 
+//add by robert for power on bp
+#define AP_TD_UNDEFINED_GBIN5 FPGA_PIO2_02
+#define AP_RESET_TD FPGA_PIO2_04
+#define AP_SHUTDOWN_TD_PMU FPGA_PIO2_05
+#define AP_PW_EN_TD FPGA_PIO2_03
+
+static int bp_power_on(void)
+{
+       int ret=0;
+       
+       ret = gpio_request(AP_TD_UNDEFINED_GBIN5, NULL);
+       if (ret) {
+               printk("%s:failed to request fpga s %d\n",__FUNCTION__,__LINE__);
+               goto err;
+       }
+       ret = gpio_request(AP_RESET_TD, NULL);
+       if (ret) {
+               printk("%s:failed to request fpga s %d\n",__FUNCTION__,__LINE__);
+               goto err0;
+       }
+       
+
+       ret = gpio_request(AP_SHUTDOWN_TD_PMU, NULL);
+       if (ret) {
+               printk("%s:failed to request fpga %d\n",__FUNCTION__,__LINE__);
+               goto err1;
+       }
+
+       ret = gpio_request(AP_PW_EN_TD, NULL);
+       if (ret) {
+               printk("%s:failed to request fpga  %d\n",__FUNCTION__,__LINE__);
+               goto err2;
+       }
+
+       gpio_set_value(AP_TD_UNDEFINED_GBIN5, 1);
+       gpio_direction_output(AP_TD_UNDEFINED_GBIN5, 1);   
+       gpio_direction_input(AP_RESET_TD);
+
+        gpio_set_value(AP_SHUTDOWN_TD_PMU, 0);
+        gpio_direction_output(AP_SHUTDOWN_TD_PMU, 0);  
+
+       gpio_set_value(AP_PW_EN_TD, 0);
+       gpio_direction_output(AP_PW_EN_TD, 0);  
+       mdelay(1);
+       gpio_set_value(AP_PW_EN_TD, 1);
+       mdelay(1200);
+       gpio_set_value(AP_PW_EN_TD, 0);
+
+       return true;
+err2:
+       gpio_free(AP_SHUTDOWN_TD_PMU);
+err1:
+       gpio_free(AP_RESET_TD);
+err0:
+       gpio_free(AP_TD_UNDEFINED_GBIN5);
+err:   
+       return false;
+}
+
+
+
+static int bp_power_off(struct notifier_block *this,
+                                       unsigned long code, void *unused)
+{
+       printk("+++--++++++%s_________%d \r\n",__FUNCTION__,code);
+
+        gpio_set_value(AP_TD_UNDEFINED_GBIN5, 0);
+       
+       gpio_set_value(AP_PW_EN_TD, 0);
+       //gpio_direction_output(AP_PW_EN_TD, 0);  
+       mdelay(1);
+       gpio_set_value(AP_PW_EN_TD, 1);
+       mdelay(1200);
+       gpio_set_value(AP_PW_EN_TD, 0);
+
+       mdelay(5000);
+        gpio_set_value(AP_SHUTDOWN_TD_PMU, 1);
+       mdelay(1200);
+       // gpio_free(AP_PW_EN_TD);
+printk("++++--+++++%s   ok_________\r\n",__FUNCTION__);
+        return NOTIFY_DONE;
+}
+//add end
+
 static int lp8725_set_init(void)
 {
        int tmp = 0;
        struct regulator *ldo1,*ldo2,*ldo3,*ldo4,*ldo5;
        struct regulator *lilo1,*lilo2;
-       struct regulator *buck1,*buck2;
+       struct regulator *buck1,*buck1_v2,*buck2;
 
        DBG_INFO("***run in %s %d ",__FUNCTION__,__LINE__);
 
@@ -742,6 +836,15 @@ static int lp8725_set_init(void)
        tmp = regulator_get_voltage(buck1);
        DBG_INFO("***regulator_set_init: buck1 vcc =%d\n",tmp);
 
+       #ifdef PM_CONTROL
+       DBG_INFO("***buck1 v2 init\n");
+       buck1_v2 = regulator_get(NULL, "vdd12_v2");// dvs 0
+       regulator_enable(buck1_v2);
+       regulator_set_voltage(buck1_v2,1000000,1000000);//1300000
+       tmp = regulator_get_voltage(buck1_v2);
+       DBG_INFO("***regulator_set_init: buck1 v2 =%d\n",tmp);
+       #endif
+
        /*init buck2*/
        DBG_INFO("***buck2 vcc init\n");
        buck2 = regulator_get(NULL, "vccdr");
@@ -749,26 +852,34 @@ static int lp8725_set_init(void)
        tmp = regulator_get_voltage(buck2);
        DBG_INFO("***regulator_set_init: buck2 vcc =%d\n",tmp);
 
+       
+//add by robert for power on bp
+       bp_power_on();
+//end add
+
        return(0);
 }
 
 
-static int setup_regulators(struct lp8725 *lp8725, struct lp8725_platform_data *pdata)
+static int __devinit setup_regulators(struct lp8725 *lp8725, struct lp8725_platform_data *pdata)
 {      
        int i, err;
-       int num_regulators = pdata->num_regulators;
-       lp8725->num_regulators = num_regulators;
-       lp8725->rdev = kzalloc(sizeof(struct regulator_dev *) * num_regulators,
-               GFP_KERNEL);
+
+       lp8725->num_regulators = pdata->num_regulators;
+       lp8725->rdev = kcalloc(pdata->num_regulators,
+                              sizeof(struct regulator_dev *), GFP_KERNEL);
+       if (!lp8725->rdev) {
+               return -ENOMEM;
+       }
 
        /* Instantiate the regulators */
-       for (i = 0; i < num_regulators; i++) {
+       for (i = 0; i < pdata->num_regulators; i++) {
                int id = pdata->regulators[i].id;
                lp8725->rdev[i] = regulator_register(&regulators[id],
                        lp8725->dev, pdata->regulators[i].initdata, lp8725);
 
-               err = IS_ERR(lp8725->rdev[i]);
-               if (err) {
+               if (IS_ERR(lp8725->rdev[i])) {
+                       err = PTR_ERR(lp8725->rdev[i]);
                        dev_err(lp8725->dev, "regulator init failed: %d\n",
                                err);
                        goto error;
@@ -777,9 +888,8 @@ static int setup_regulators(struct lp8725 *lp8725, struct lp8725_platform_data *
 
        return 0;
 error:
-       for (i = 0; i < num_regulators; i++)
-               if (lp8725->rdev[i])
-                       regulator_unregister(lp8725->rdev[i]);
+       while (--i >= 0)
+               regulator_unregister(lp8725->rdev[i]);
        kfree(lp8725->rdev);
        lp8725->rdev = NULL;
        return err;
@@ -810,6 +920,10 @@ static int __devinit lp8725_i2c_probe(struct i2c_client *i2c, const struct i2c_d
        } else
                dev_warn(lp8725->dev, "No platform init data supplied\n");
 
+       //DVS pin control, make sure it is high level at start.
+       #ifdef PM_CONTROL
+       rk2818_lp8725_pm_control();
+       #endif
        lp8725_set_init();
 
        return 0;
@@ -822,6 +936,7 @@ static int __devexit lp8725_i2c_remove(struct i2c_client *i2c)
 {
        struct lp8725 *lp8725 = i2c_get_clientdata(i2c);
        int i;
+
        for (i = 0; i < lp8725->num_regulators; i++)
                if (lp8725->rdev[i])
                        regulator_unregister(lp8725->rdev[i]);
@@ -849,6 +964,15 @@ static struct i2c_driver lp8725_i2c_driver = {
        .id_table = lp8725_i2c_id,
 };
 
+
+//add by robert for bp powerdown register
+static struct notifier_block BP_powerdown_notifier = {
+       .notifier_call =        bp_power_off,
+};
+//end add
+
+
+
 static int __init lp8725_module_init(void)
 {
        int ret;
@@ -857,12 +981,25 @@ static int __init lp8725_module_init(void)
        if (ret != 0)
                pr_err("Failed to register I2C driver: %d\n", ret);
 
+       //add by robert for bp powerdown register
+       ret = register_reboot_notifier(&BP_powerdown_notifier);
+       if (ret != 0) 
+               {
+               printk("cannot register reboot notifier (err=%d), %s\n", ret,__FUNCTION__);
+               }
+       //end add
+
+
        return ret;
 }
 module_init(lp8725_module_init);
 
 static void __exit lp8725_module_exit(void)
 {
+//add by robert for bp power down
+       unregister_reboot_notifier(&BP_powerdown_notifier);
+//end add
+
        i2c_del_driver(&lp8725_i2c_driver);
 }
 module_exit(lp8725_module_exit);