input: touchscreen: add touch screen of gslx680 for rk3399-firefly-edp
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rk818.c
index 4b73da29ff96391f4588eadfa894f8bdc69cc625..0da49fbfa3c3bf2e68358f6a332ce00642f536af 100755 (executable)
@@ -29,6 +29,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regmap.h>
+#include <linux/syscore_ops.h>
 
 
 #if 0
@@ -49,11 +50,11 @@ static struct mfd_cell rk818s[] = {
        {
                .name = "rk818-rtc",
        },
-       /*
+
        {
                .name = "rk818-battery",
        },
-       {
+       /*      {
                .name = "rk818-power",
        },      
        */
@@ -118,7 +119,7 @@ const static int ldo_set_slp_vol_base_addr[] = {
 #define rk818_LDO_SET_SLP_VOL_REG(x) (ldo_set_slp_vol_base_addr[x])
 
 const static int buck_voltage_map[] = {
-         700,  712,  725,  737,  750, 762,  775,  787,  800, 
+         712,  725,  737,  750, 762,  775,  787,  800,
          812,  825,  837,  850,862,  875,  887,  900,  912,
          925,  937,  950, 962,  975,  987, 1000, 1012, 1025, 
          1037, 1050,1062, 1075, 1087, 1100, 1112, 1125, 1137, 
@@ -277,6 +278,37 @@ static int rk818_ldo_suspend_disable(struct regulator_dev *dev)
                return rk818_set_bits(rk818, RK818_SLEEP_SET_OFF_REG2, 1 << ldo, 1 << ldo);
 
 }
+
+int rk818_ldo_slp_enable(int ldo_id)
+{
+       int ldo = ldo_id - 1;
+
+       if (ldo == 8)
+               return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+                                     1 << 5, 0); /*ldo9*/
+       else if (ldo == 9)
+               return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+                                     1 << 6, 0); /*ldo10 switch*/
+       else
+               return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG2,
+                                     1 << ldo, 0);
+}
+
+int rk818_ldo_slp_disable(int ldo_id)
+{
+       int ldo = ldo_id - 1;
+
+       if (ldo == 8)
+               return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+                                     1 << 5, 1 << 5); /*ldo9*/
+       else if (ldo == 9)
+               return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+                                     1 << 6, 1 << 6); /*ldo10 switch*/
+       else
+               return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG2,
+                                     1 << ldo, 1 << ldo);
+}
+
 static int rk818_ldo_set_sleep_voltage(struct regulator_dev *dev,
                                            int uV)
 {
@@ -382,7 +414,7 @@ static int rk818_dcdc_list_voltage(struct regulator_dev *dev, unsigned selector)
        switch (buck) {
        case 0:
        case 1:
-               volt = 700000 + selector * 12500;
+               volt = 712500 + selector * 12500;
                break;
        case 3:
                volt = 1800000 + selector * 100000;
@@ -445,10 +477,10 @@ static int rk818_dcdc_select_min_voltage(struct regulator_dev *dev,
        u16 vsel =0;
        
        if (buck == 0 || buck ==  1){
-               if (min_uV < 700000)
+               if (min_uV < 712500)
                vsel = 0;
                else if (min_uV <= 1500000)
-               vsel = ((min_uV - 700000) / 12500) ;
+               vsel = ((min_uV - 712500) / 12500) ;
                else
                return -EINVAL;
        }
@@ -471,7 +503,7 @@ static int rk818_dcdc_set_voltage(struct regulator_dev *dev,
        struct rk818 *rk818 = rdev_get_drvdata(dev);
        int buck = rdev_get_id(dev) - RK818_DCDC1;
        u16 val;
-       int ret = 0,old_voltage =0,vol_temp =0;
+       int ret = 0;
 
        if (buck ==2){
                return 0;
@@ -861,7 +893,7 @@ static ssize_t rk818_test_store(struct kobject *kobj, struct kobj_attribute *att
                                 const char *buf, size_t n)
 {
     u32 getdata[8];
-    u16 regAddr;
+    u8 regAddr;
     u8 data;
     char cmd;
     const char *buftmp = buf;
@@ -872,45 +904,32 @@ static ssize_t rk818_test_store(struct kobject *kobj, struct kobj_attribute *att
      * R regAddr(8Bit)
      * C gpio_name(poweron/powerhold/sleep/boot0/boot1) value(H/L)
      */
-        regAddr = (u16)(getdata[0] & 0xff);
-        if (strncmp(buf, "start", 5) == 0) {
-        
-
-    } else if (strncmp(buf, "stop", 4== 0) ){
-    
-    } else{
-        sscanf(buftmp, "%c ", &cmd);
-        printk("------zhangqing: get cmd = %c\n", cmd);
-        switch(cmd) {
-
-        case 'w':
-               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0],&getdata[1]);
-                regAddr = (u16)(getdata[0] & 0xff);
-                data = (u8)(getdata[1] & 0xff);
-                printk("get value = %x\n", data);
-
-             rk818_i2c_write(rk818, regAddr, 1, data);
-            rk818_i2c_read(rk818, regAddr, 1, &data);
-            printk("%x   %x\n", getdata[1],data);
-
-            break;
-
-        case 'r':
-            sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
-            printk("CMD : %c %x\n", cmd, getdata[0]);
-
-            regAddr = (u16)(getdata[0] & 0xff);
-            rk818_i2c_read(rk818, regAddr, 1, &data);
-               printk("%x %x\n", getdata[0],data);
-
-            break;
+       sscanf(buftmp, "%c ", &cmd);
+       printk("------zhangqing: get cmd = %c\n", cmd);
+       switch (cmd) {
+       case 'w':
+               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0], &getdata[1]);
+               regAddr = (u8)(getdata[0] & 0xff);
+               data = (u8)(getdata[1] & 0xff);
+               printk("get value = %x\n", data);
+
+               rk818_i2c_write(rk818, regAddr, 1, data);
+               rk818_i2c_read(rk818, regAddr, 1, &data);
+               printk("%x   %x\n", getdata[1], data);
+               break;
+       case 'r':
+               sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
+               printk("CMD : %c %x\n", cmd, getdata[0]);
 
-        default:
-            printk("Unknown command\n");
-            break;
-        }
-}
-    return n;
+               regAddr = (u8)(getdata[0] & 0xff);
+               rk818_i2c_read(rk818, regAddr, 1, &data);
+               printk("%x %x\n", getdata[0], data);
+               break;
+       default:
+               printk("Unknown command\n");
+               break;
+       }
+       return n;
 
 }
 static ssize_t rk818_test_show(struct kobject *kobj, struct kobj_attribute *attr,
@@ -937,7 +956,7 @@ static struct rk818_attribute rk818_attrs[] = {
 };
 #endif
 
-extern void rk_send_wakeup_key(void);
+#if 0
 static irqreturn_t rk818_vbat_lo_irq(int irq, void *data)
 {
         printk("rk818 vbat low %s:irq=%d\n",__func__,irq);
@@ -945,6 +964,7 @@ static irqreturn_t rk818_vbat_lo_irq(int irq, void *data)
        rk_send_wakeup_key();
         return IRQ_HANDLED;
 }
+#endif
 
 #ifdef CONFIG_OF
 static struct of_device_id rk818_of_match[] = {
@@ -1031,23 +1051,44 @@ static struct rk818_board *rk818_parse_dt(struct i2c_client *i2c)
 }
 #endif
 
-int rk818_device_shutdown(void)
+static void rk818_shutdown(void)
 {
        int ret;
-       int err = -1;
        struct rk818 *rk818 = g_rk818;
-       
-       printk("%s\n",__func__);
+
+       pr_info("%s\n", __func__);
        ret = rk818_set_bits(rk818, RK818_INT_STS_MSK_REG1,(0x3<<5),(0x3<<5)); //close rtc int when power off
        ret = rk818_clear_bits(rk818, RK818_RTC_INT_REG,(0x3<<2)); //close rtc int when power off
-       ret = rk818_reg_read(rk818,RK818_DEVCTRL_REG);
-       ret = rk818_set_bits(rk818, RK818_DEVCTRL_REG,(0x1<<0),(0x1<<0));
-//     ret = rk818_set_bits(rk818, RK818_DEVCTRL_REG,(0x1<<4),(0x1<<4));
-       if (ret < 0) {
-               printk("rk818 power off error!\n");
-               return err;
+       /*disable otg_en*/
+       ret = rk818_clear_bits(rk818, RK818_DCDC_EN_REG, (0x1<<7));
+
+       mutex_lock(&rk818->io_lock);
+       mdelay(100);
+}
+
+static struct syscore_ops rk818_syscore_ops = {
+       .shutdown = rk818_shutdown,
+};
+
+void rk818_device_shutdown(void)
+{
+       int ret, i;
+       u8 reg = 0;
+       struct rk818 *rk818 = g_rk818;
+
+       for (i = 0; i < 10; i++) {
+               pr_info("%s\n", __func__);
+               ret = rk818_i2c_read(rk818, RK818_DEVCTRL_REG, 1, &reg);
+               if (ret < 0)
+                       continue;
+               ret = rk818_i2c_write(rk818, RK818_DEVCTRL_REG, 1,
+                                    (reg | (0x1 << 0)));
+               if (ret < 0) {
+                       pr_err("rk818 power off error!\n");
+                       continue;
+               }
        }
-       return 0;       
+       while(1) wfi();
 }
 EXPORT_SYMBOL_GPL(rk818_device_shutdown);
 
@@ -1055,14 +1096,43 @@ __weak void  rk818_device_suspend(void) {}
 __weak void  rk818_device_resume(void) {}
 #ifdef CONFIG_PM
 static int rk818_suspend(struct i2c_client *i2c, pm_message_t mesg)
-{              
+{
+       int ret, val;
+       struct rk818 *rk818 = g_rk818;
+
        rk818_device_suspend();
+       /************set vbat low 3v4 to irq**********/
+       val = rk818_reg_read(rk818, RK818_VB_MON_REG);
+       val &= (~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
+       val |= (RK818_VBAT_LOW_3V4 | EN_VBAT_LOW_IRQ);
+       ret = rk818_reg_write(rk818, RK818_VB_MON_REG, val);
+       if (ret < 0) {
+               pr_err("Unable to write RK818_VB_MON_REG reg\n");
+               return ret;
+       }
+       /*enable low irq*/
+       rk818_set_bits(rk818, 0x4d, (0x1 << 1), (0x0 << 1));
        return 0;
 }
 
 static int rk818_resume(struct i2c_client *i2c)
 {
+       int ret, val;
+       struct rk818 *rk818 = g_rk818;
+
        rk818_device_resume();
+       /********set vbat low 3v0 to shutdown**********/
+       val = rk818_reg_read(rk818, RK818_VB_MON_REG);
+       val &= (~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
+       val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
+       ret = rk818_reg_write(rk818, RK818_VB_MON_REG, val);
+       if (ret < 0) {
+               pr_err("Unable to write RK818_VB_MON_REG reg\n");
+               return ret;
+       }
+       /*disable low irq*/
+       rk818_set_bits(rk818, 0x4d, (0x1 << 1), (0x1 << 1));
+
        return 0;
 }
 #else
@@ -1080,51 +1150,77 @@ static int rk818_resume(struct i2c_client *i2c)
 static int rk818_pre_init(struct rk818 *rk818)
 {
        int ret,val;
-        printk("%s,line=%d\n", __func__,__LINE__);
+       printk("%s,line=%d\n", __func__,__LINE__);
 
+       ret = rk818_set_bits(rk818, 0xa1, (0xF<<0),(0x7));
        ret = rk818_set_bits(rk818, 0xa1,(0x7<<4),(0x7<<4)); //close charger when usb low then 3.4V
-       ret = rk818_set_bits(rk818, 0x52,(0x1<<1),(0x1<<1)); //no action when vref
-       
+       ret = rk818_set_bits(rk818, 0x52,(0x1<<1),(0x1<<1)); //no action when vref
+       ret = rk818_set_bits(rk818, 0x52,(0x1<<0),(0x1<<0)); //enable HDMI 5V
+
        /*******enable switch and boost***********/
        val = rk818_reg_read(rk818,RK818_DCDC_EN_REG);
-        val |= (0x3 << 5);    //enable switch1/2
+       val |= (0x3 << 5);    //enable switch1/2
        val |= (0x1 << 4);    //enable boost
-        ret = rk818_reg_write(rk818,RK818_DCDC_EN_REG,val);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK818_DCDC_EN_REG reg\n");
-                return ret;
+       ret = rk818_reg_write(rk818,RK818_DCDC_EN_REG,val);
+       if (ret <0) {
+               printk(KERN_ERR "Unable to write RK818_DCDC_EN_REG reg\n");
+               return ret;
        }
        /****************************************/
-       
        /****************set vbat low **********/
        val = rk818_reg_read(rk818,RK818_VB_MON_REG);
-       val &=(~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
-       val |= (RK818_VBAT_LOW_3V5 | EN_VBAT_LOW_IRQ);
-       ret = rk818_reg_write(rk818,RK818_VB_MON_REG,val);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK818_VB_MON_REG reg\n");
-                return ret;
-        }
+       val &=(~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
+       val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
+       ret = rk818_reg_write(rk818,RK818_VB_MON_REG,val);
+       if (ret <0) {
+               printk(KERN_ERR "Unable to write RK818_VB_MON_REG reg\n");
+               return ret;
+       }
        /**************************************/
-       
+
        /**********mask int****************/
-        val = rk818_reg_read(rk818,RK818_INT_STS_MSK_REG1);
-         val |= (0x1<<0); //mask vout_lo_int    
-        ret = rk818_reg_write(rk818,RK818_INT_STS_MSK_REG1,val);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK818_INT_STS_MSK_REG1 reg\n");
-                return ret;
-        }
+
+       val = rk818_reg_read(rk818,RK818_INT_STS_MSK_REG1);
+       val |= (0x1<<0); //mask vout_lo_int
+       ret = rk818_reg_write(rk818,RK818_INT_STS_MSK_REG1,val);
+       if (ret <0) {
+               printk(KERN_ERR "Unable to write RK818_INT_STS_MSK_REG1 reg\n");
+               return ret;
+       }
+
        /**********************************/
        /**********enable clkout2****************/
-        ret = rk818_reg_write(rk818,RK818_CLK32OUT_REG,0x01);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK818_CLK32OUT_REG reg\n");
-                return ret;
-        }
+       ret = rk818_reg_write(rk818,RK818_CLK32OUT_REG,0x01);
+       if (ret <0) {
+               printk(KERN_ERR "Unable to write RK818_CLK32OUT_REG reg\n");
+               return ret;
+       }
        /**********************************/
        ret = rk818_clear_bits(rk818, RK818_INT_STS_MSK_REG1,(0x3<<5)); //open rtc int when power on
-       ret = rk818_set_bits(rk818, RK818_RTC_INT_REG,(0x1<<3),(0x1<<3)); //open rtc int when power on
+       ret = rk818_set_bits(rk818, RK818_RTC_INT_REG,(0x1<<3),(0x1<<3)); //open rtc int when power on
+
+       /*****disable otg when in sleep mode****/
+       val = rk818_reg_read(rk818, RK818_SLEEP_SET_OFF_REG1);
+       val |= (0x1 << 7);
+       ret =  rk818_reg_write(rk818, RK818_SLEEP_SET_OFF_REG1, val);
+       if (ret < 0) {
+               pr_err("Unable to write RK818_SLEEP_SET_OFF_REG1 reg\n");
+               return ret;
+       }
+
+       /*************** improve efficiency **********************/
+       ret =  rk818_reg_write(rk818, RK818_BUCK2_CONFIG_REG, 0x1c);
+       if (ret < 0) {
+               pr_err("Unable to write RK818_BUCK2_CONFIG_REG reg\n");
+               return ret;
+       }
+
+       ret =  rk818_reg_write(rk818, RK818_BUCK4_CONFIG_REG, 0x04);
+       if (ret < 0) {
+               pr_err("Unable to write RK818_BUCK4_CONFIG_REG reg\n");
+               return ret;
+       }
+
        return 0;
 }
  
@@ -1137,7 +1233,7 @@ static int  rk818_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *
        struct regulator_dev *rk818_rdev;
        struct regulator_init_data *reg_data;
        const char *rail_name = NULL;
-       int ret,vlow_irq,i=0;
+       int ret, i = 0;
        
        printk("%s,line=%d\n", __func__,__LINE__);
 
@@ -1264,6 +1360,8 @@ static int  rk818_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *
        }
        #endif
        
+       register_syscore_ops(&rk818_syscore_ops);
+
        return 0;
 
 err:
@@ -1277,11 +1375,11 @@ static int  rk818_i2c_remove(struct i2c_client *i2c)
        struct rk818 *rk818 = i2c_get_clientdata(i2c);
        int i;
 
+       unregister_syscore_ops(&rk818_syscore_ops);
        for (i = 0; i < rk818->num_regulators; i++)
                if (rk818->rdev[i])
                        regulator_unregister(rk818->rdev[i]);
        i2c_set_clientdata(i2c, NULL);
-       kfree(rk818);
 
        return 0;
 }