clk: rockchip: support setting ddr clock via SCPI APIs
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / act8846.c
index badf442e32c2ed46a3038a5ea55793a9b6b7ed68..3042b0000678d118ec41b1ed8c85a80b38d512b6 100755 (executable)
@@ -34,6 +34,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regmap.h>
+#include <asm/system_misc.h>
 
 #if 0
 #define DBG(x...)      printk(KERN_INFO x)
@@ -53,7 +54,9 @@ struct act8846 {
        struct i2c_client *i2c;
        int num_regulators;
        struct regulator_dev **rdev;
-//     struct early_suspend act8846_suspend;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       struct early_suspend act8846_suspend;
+#endif
        int irq_base;
        int chip_irq;
        int pmic_sleep_gpio; /* */
@@ -458,8 +461,7 @@ static int act8846_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
 static int act8846_dcdc_set_voltage_time_sel(struct regulator_dev *dev,   unsigned int old_selector,
                                     unsigned int new_selector)
 {
-       struct act8846 *act8846 = rdev_get_drvdata(dev);
-       int ret =0,old_volt, new_volt;
+       int old_volt, new_volt;
        
        old_volt = act8846_dcdc_list_voltage(dev, old_selector);
        if (old_volt < 0)
@@ -779,6 +781,7 @@ static struct act8846_board *act8846_parse_dt(struct act8846 *act8846)
                if (!gpio_is_valid(gpio)) 
                        printk("invalid gpio: %d\n",gpio);
        pdata->pmic_hold_gpio = gpio;   
+       pdata->pm_off = of_property_read_bool(act8846_pmic_np,"act8846,system-power-controller");
 
        return pdata;
 }
@@ -791,14 +794,19 @@ static struct act8846_board *act8846_parse_dt(struct i2c_client *i2c)
 #endif
 
 
-int act8846_device_shutdown(void)
+void act8846_device_shutdown(void)
 {
-       int ret;
-       int err = -1;
        struct act8846 *act8846 = g_act8846;
        
        printk("%s\n",__func__);
-
+#if 1
+       if (act8846->pmic_hold_gpio) {
+                       gpio_direction_output(act8846->pmic_hold_gpio,0);
+                       mdelay(100);
+                       arm_pm_restart('h', "charge");
+       }
+       
+#else
        ret = act8846_reg_read(act8846,0xc3);
        ret = act8846_set_bits(act8846, 0xc3,(0x1<<3),(0x1<<3));
        ret = act8846_set_bits(act8846, 0xc3,(0x1<<4),(0x1<<4));
@@ -806,31 +814,31 @@ int act8846_device_shutdown(void)
                printk("act8846 set 0xc3 error!\n");
                return err;
        }
-       return 0;       
+#endif
 }
 EXPORT_SYMBOL_GPL(act8846_device_shutdown);
 
 __weak void  act8846_device_suspend(void) {}
 __weak void  act8846_device_resume(void) {}
 #ifdef CONFIG_PM
-static int act8846_suspend(struct i2c_client *i2c, pm_message_t mesg)
-{              
+static int act8846_suspend(struct device *dev)
+{      
        act8846_device_suspend();
        return 0;
 }
 
-static int act8846_resume(struct i2c_client *i2c)
+static int act8846_resume(struct device *dev)
 {
        act8846_device_resume();
        return 0;
 }
 #else
-static int act8846_suspend(struct i2c_client *i2c, pm_message_t mesg)
+static int act8846_suspend(struct device *dev)
 {              
        return 0;
 }
 
-static int act8846_resume(struct i2c_client *i2c)
+static int act8846_resume(struct device *dev)
 {
        return 0;
 }
@@ -923,7 +931,7 @@ static int act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id
                        }
                        gpio_direction_output(act8846->pmic_hold_gpio,1);
                        ret = gpio_get_value(act8846->pmic_hold_gpio);
-                       gpio_free(act8846->pmic_hold_gpio);
+       //              gpio_free(act8846->pmic_hold_gpio);
                        printk("%s: act8846_pmic_hold=%x\n", __func__, ret);
        }
        #endif
@@ -937,7 +945,7 @@ static int act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id
                                dev_err(act8846->dev,"Failed to request gpio %d with ret:""%d\n",       act8846->pmic_sleep_gpio, ret);
                                return IRQ_NONE;
                        }
-                       gpio_direction_output(act8846->pmic_sleep_gpio,0);
+                       gpio_direction_output(act8846->pmic_sleep_gpio,1);
                        ret = gpio_get_value(act8846->pmic_sleep_gpio);
                        gpio_free(act8846->pmic_sleep_gpio);
                        printk("%s: act8846_pmic_sleep=%x\n", __func__, ret);
@@ -946,7 +954,10 @@ static int act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id
        
        if (pdev) {
                act8846->num_regulators = act8846_NUM_REGULATORS;
-               act8846->rdev = kcalloc(act8846_NUM_REGULATORS,sizeof(struct regulator_dev *), GFP_KERNEL);
+               act8846->rdev = devm_kcalloc(act8846->dev,
+                                            act8846_NUM_REGULATORS,
+                                            sizeof(struct regulator_dev *),
+                                            GFP_KERNEL);
                if (!act8846->rdev) {
                        return -ENOMEM;
                }
@@ -977,6 +988,10 @@ static int act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id
                act8846->rdev[i] = act_rdev;
                }
        }
+
+       if (pdev->pm_off && !pm_power_off) {
+               pm_power_off = act8846_device_shutdown;
+       }
        
        #ifdef CONFIG_HAS_EARLYSUSPEND
        act8846->act8846_suspend.suspend = act8846_early_suspend,
@@ -1000,13 +1015,16 @@ static int  act8846_i2c_remove(struct i2c_client *i2c)
        for (i = 0; i < act8846->num_regulators; i++)
                if (act8846->rdev[i])
                        regulator_unregister(act8846->rdev[i]);
-       kfree(act8846->rdev);
        i2c_set_clientdata(i2c, NULL);
-       kfree(act8846);
 
        return 0;
 }
 
+static const struct dev_pm_ops act8846_pm_ops = {
+       .suspend = act8846_suspend,
+       .resume =  act8846_resume,
+};
+
 static const struct i2c_device_id act8846_i2c_id[] = {
        { "act8846", 0 },
        { }
@@ -1018,15 +1036,14 @@ static struct i2c_driver act8846_i2c_driver = {
        .driver = {
                .name = "act8846",
                .owner = THIS_MODULE,
+               #ifdef CONFIG_PM
+               .pm = &act8846_pm_ops,
+               #endif
                .of_match_table =of_match_ptr(act8846_of_match),
        },
        .probe    = act8846_i2c_probe,
        .remove   = act8846_i2c_remove,
        .id_table = act8846_i2c_id,
-       #ifdef CONFIG_PM
-       .suspend        = act8846_suspend,
-       .resume         = act8846_resume,
-       #endif
 };
 
 static int __init act8846_module_init(void)