arm64: dts: rockchip: enable mbox related for rk3368-tb
[firefly-linux-kernel-4.4.55.git] / drivers / power / rk30_factory_adc_battery.c
index 5b4d36cdb984f29bf4a3b6d2b5299267877a4859..69790668f05e7bdaab2704e4522badf5bc0780d2 100755 (executable)
@@ -22,9 +22,6 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <asm/io.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
 #include <linux/adc.h>
 #include <linux/delay.h>
 #include <linux/ktime.h>
@@ -39,6 +36,7 @@
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/power/rockchip-adc-battery.h>
+#include <linux/rk_keys.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/machine.h>
 #include <linux/iio/driver.h>
@@ -61,7 +59,7 @@ do {\
 #define        TIMER_MS_COUNTS          1000   
 #define        SLOPE_SECOND_COUNTS                    15       
 #define        DISCHARGE_MIN_SECOND                   30
-#define        CHARGE_MIN_SECOND                      30       
+#define        CHARGE_MIN_SECOND                      45       
 #define        CHARGE_MID_SECOND                      90       
 #define        CHARGE_MAX_SECOND                      250
 #define   CHARGE_FULL_DELAY_TIMES          10     
@@ -91,7 +89,7 @@ do {\
 
 
 
-#define BATT_FILENAME "/data/bat_last_capacity.dat"
+//#define BATT_FILENAME "/data/bat_last_capacity.dat"
 
 
 #define BATTERY_APK 
@@ -103,6 +101,8 @@ int    gVoltageCnt = 3400;
 int    gDoubleVoltageCnt = 6800;
 unsigned long gSecondsCnt = 0;
 char gDischargeFlag[4] = {"on "};
+static int    g_old_cap = -1;
+static int g_uboot_incre = 0;
 
 #if 1
 #define BATT_MAX_VOL_VALUE     4250/*Full  charge volatge*/
@@ -238,7 +238,6 @@ extern int get_gadget_connect_flag(void);
 extern int dwc_otg_check_dpdm(void);
 static int  is_charge_ok(struct rk30_adc_battery_data *bat);
 static void rk30_adc_battery_voltage_samples(struct rk30_adc_battery_data *bat);
-extern void rk_send_wakeup_key(void);
 static  bool batt_gpio_is_valid(int number)
 {
        return number > 0 && number < 256;
@@ -341,11 +340,47 @@ static ssize_t rkbatt_restore_flag_attrs(struct device *dev,
        }
        return size;
 }
+
+static int __init adc_bootloader_setup(char *str)
+{
+
+       if(str) {
+               printk("adc.incre is %s\n", str);
+               sscanf(str, "%d", &g_uboot_incre);
+       }
+       return 0;
+}
+early_param("adc.incre", adc_bootloader_setup);
+
+static ssize_t rkbatt_show_oldcap_attrs(struct device *dev, struct device_attribute *attr, char *buf) 
+{                               
+       return sprintf(buf, "%d\n", g_old_cap);
+}
+
+static ssize_t rkbatt_restore_oldcap_attrs(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
+{
+       int old_cap;
+       
+       sscanf(buf, "%d", &old_cap);
+       
+       if(old_cap >= 0 && old_cap <= 100)
+       {
+               g_old_cap = old_cap;
+       }
+       else
+       {
+               dev_err(dev, "rk29adc_restore_oldcap_attrs err\n");
+       }
+       return size;
+}
+
+
 static struct device_attribute rkbatt_attrs[] = {
        __ATTR(state, 0664, rkbatt_show_state_attrs, rkbatt_restore_state_attrs),
        __ATTR(debug, 0664, rkbatt_show_debug_attrs, rkbatt_restore_debug_attrs),
        __ATTR(value, 0555, rkbatt_show_value_attrs, rkbatt_restore_value_attrs),
        __ATTR(flag,  0555, rkbatt_show_flag_attrs,  rkbatt_restore_flag_attrs),
+       __ATTR(oldcap, 0664, rkbatt_show_oldcap_attrs, rkbatt_restore_oldcap_attrs),
 };
 
 static int rk_adc_battery_iio_read(struct rk30_adc_battery_platform_data *data)
@@ -385,6 +420,7 @@ error:
 
 #endif
 
+#if 0
 static int rk30_adc_battery_load_capacity(void)
 {
        char value[4];
@@ -417,6 +453,7 @@ static void rk30_adc_battery_put_capacity(int loadcapacity)
        sys_write(fd, (const char __user *)value, 4);
        sys_close(fd);
 }
+#endif
 static BLOCKING_NOTIFIER_HEAD(adc_battery_chain_head);
 
 int register_adc_battery_notifier(struct notifier_block *nb)
@@ -756,41 +793,50 @@ static int rk30_adc_battery_status_samples(struct rk30_adc_battery_data *bat)
 
        return charge_level;
 }
+
+static int rk_adc_battery_iio_read_refvol(struct rk30_adc_battery_platform_data *data)
+{
+       struct iio_channel *channel = data->ref_voltage_chan;
+       int val, ret;
+
+       ret = iio_read_channel_raw(channel, &val);
+       if (ret < 0) {
+               pr_err("read channel() error: %d\n", ret);
+               return ret;
+       }
+       return val;
+}
+
+static int get_ref_voltage(struct rk30_adc_battery_data *bat)
+{
+       int data_value;
+       struct regulator *logic;
+       int voltage, ref_voltage;
+
+       logic = regulator_get(NULL, "vdd_arm");
+       voltage = regulator_get_voltage(logic);
+       data_value = rk_adc_battery_iio_read_refvol(bat->pdata);
+       ref_voltage = voltage*1024/data_value/1000;
+
+       return ref_voltage;
+}
 static int rk_adc_voltage(struct rk30_adc_battery_data *bat, int value)
 {
        int voltage;
-
-       int ref_voltage; //reference_voltage
-       int pullup_res;
-       int pulldown_res;
+       int ref_voltage;
 
        ref_voltage = bat ->pdata->reference_voltage;
-       pullup_res = bat ->pdata->pull_up_res;
-       pulldown_res = bat ->pdata->pull_down_res;
-
-       if(ref_voltage && pullup_res && pulldown_res){
-#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026)
-               ref_voltage = adc_get_curr_ref_volt();
-#endif 
-               voltage =  ((value * ref_voltage * (pullup_res + pulldown_res)) / (1024 * pulldown_res));
-               DBG("ref_voltage =%d, voltage=%d \n", ref_voltage,voltage);
+
+       if (ref_voltage) {
+               if (bat->pdata->auto_calibration == 1)
+                       ref_voltage = get_ref_voltage(bat);
+               voltage = (value * ref_voltage * (batt_table[4] + batt_table[5])) / (1024 * batt_table[5]);
+               DBG("ref_voltage =%d, voltage=%d\n", ref_voltage, voltage);
                
        }else{
-#if 0
-               if(bat ->capacitytmp < 5)
-                       ref_voltage = adc_get_curr_ref_volt();
-               else
-                       ref_voltage = adc_get_def_ref_volt();
-#endif
-#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026)
-               ref_voltage = adc_get_curr_ref_volt();
-               voltage = (value * ref_voltage * (batt_table[4] +batt_table[5])) / (1024 *batt_table[5]); 
-#else
                voltage = adc_to_voltage(value);
-#endif
        }
-       
-       DBG("ref_voltage =%d, voltage=%d \n", ref_voltage,voltage);
+       DBG("ref_voltage =%d, voltage=%d\n", ref_voltage, voltage);
        return voltage;
 
 }
@@ -1340,12 +1386,16 @@ static void rk30_adc_battery_poweron_capacity_check(struct rk30_adc_battery_data
        new_capacity = bat ->bat_capacity;
                
        while( cnt -- ){
-           old_capacity = rk30_adc_battery_load_capacity();
-           if( old_capacity >= 0 ){
+               g_old_cap = g_old_cap + g_uboot_incre;
+               if(g_old_cap > 100)
+                       g_old_cap = 100;
+           old_capacity = g_old_cap;   // rk30_adc_battery_load_capacity();
+           if( old_capacity != -1 ){
                break ;
            }
            msleep(100);
        }
+        printk("func:%s; line:%d; old_capacity = %d; new_capacity = %d; g_uboot_incre = %d\n", __func__, __LINE__, old_capacity, new_capacity,g_uboot_incre);
 
        if ((old_capacity < 0) || (old_capacity > 100)){
                old_capacity = new_capacity;
@@ -1358,16 +1408,9 @@ static void rk30_adc_battery_poweron_capacity_check(struct rk30_adc_battery_data
        }
        else if (bat ->bat_status != POWER_SUPPLY_STATUS_NOT_CHARGING){
        //chargeing state
-
-               if( bat  ->pdata->is_reboot_charging == 1)
-                       bat ->bat_capacity = (old_capacity < 10) ?(old_capacity+2):old_capacity;
-               else
-                       bat ->bat_capacity = (new_capacity > old_capacity) ? new_capacity : old_capacity;
+               bat->bat_capacity = (old_capacity < 10) ? (old_capacity + 2) : old_capacity;
        }else{
-               if(new_capacity > old_capacity + 50 )
-                       bat ->bat_capacity = old_capacity + 5;
-               else
-                       bat ->bat_capacity = (new_capacity < old_capacity) ? new_capacity : old_capacity;  //avoid the value of capacity increase 
+                       bat ->bat_capacity = old_capacity;
                if(bat->bat_capacity == 100)
                        bat->bat_capacity = 99;
                if(bat->bat_capacity == 0)
@@ -1749,7 +1792,7 @@ static void rk30_adc_battery_timer_work(struct work_struct *work)
 
                        }
                }
-               rk30_adc_battery_put_capacity(bat ->bat_capacity);
+               // rk30_adc_battery_put_capacity(bat ->bat_capacity);
                power_supply_changed(&bat ->bat);
                power_supply_changed(&bat ->ac);
 #if  defined (CONFIG_BATTERY_RK30_USB_CHARGE)
@@ -2114,15 +2157,31 @@ rk30_adc_battery_platform_data *data)
        int ret;
        int i;
        size_t size;
-        struct iio_channel *chan;
 
-       if (!node)
-               return -ENODEV;
+       struct iio_channel *channels;
+       int num = 0;
+
+       channels = iio_channel_get_all(&pdev->dev);
+       if (IS_ERR(channels))
+               pr_err("get adc channels fails\n");
+       while (channels[num].indio_dev)
+               num++;
+       data->chan = &channels[0];
+       if (num > 1)
+               data->ref_voltage_chan = &channels[1];
+       ret = of_property_read_u32(node, "auto_calibration", &value);
+       if (ret < 0) {
+               pr_info("%s:unsupport auto_calibration\n", __func__);
+               value = 0;
+       }
+       data->auto_calibration = value;
 
-       chan = iio_channel_get(&pdev->dev, NULL);
-       if (IS_ERR(chan))
-               pr_err("iio_channel_get fail\n");
-       data->chan = chan;
+       ret = of_property_read_u32(node, "ref_voltage", &value);
+       if (ret < 0) {
+               pr_info("%s:unsupport ref_voltage\n", __func__);
+               value = 0;
+       }
+       data->reference_voltage = value;
 
        /* determine the number of config info */
        prop = of_find_property(node, "bat_table", &length);
@@ -2226,17 +2285,14 @@ static int rk30_adc_battery_probe(struct platform_device *pdev)
        gSecondsCnt = get_seconds();
        /*data = kzalloc(sizeof(*data), GFP_KERNEL);*/
        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-       if (data == NULL) {
+       if (data == NULL)
                ret = -ENOMEM;
-               goto err_data_alloc_failed;
-       }
 
        /*pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);*/
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-       if (pdata == NULL) {
+       if (pdata == NULL)
                ret = -ENOMEM;
-               goto err_pdata_alloc_failed;
-       }
+
        memset(data, 0, sizeof(struct rk30_adc_battery_data));
        gBatteryData = data;
        platform_set_drvdata(pdev, data);
@@ -2356,7 +2412,8 @@ static int rk30_adc_battery_probe(struct platform_device *pdev)
 //     data->wq = create_singlethread_workqueue("adc_battd");
        INIT_DELAYED_WORK(&data->delay_work, rk30_adc_battery_timer_work);
 
-       if (1 == data->pdata->save_capacity) {
+       //if (1 == data->pdata->save_capacity) {
+       if (1) {
                queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS*10));
                data ->poweron_check = 1;
        }else{
@@ -2396,6 +2453,7 @@ err_sysfs:
 err_ac_failed:
        power_supply_unregister(&data ->ac);
 
+err_usb_failed:
 err_battery_failed:
        power_supply_unregister(&data ->bat);
     
@@ -2409,12 +2467,6 @@ err_dcirq_failed:
 
 #endif
 err_io_init:
-
-err_pdata_alloc_failed:
-       kfree(pdata);
-err_data_alloc_failed:
-       kfree(data);
-
        printk("rk30_adc_battery: error!\n");
     
        return ret;
@@ -2439,8 +2491,6 @@ static int rk30_adc_battery_remove(struct platform_device *pdev)
        power_supply_unregister(&data ->bat);
        if (batt_gpio_is_valid(pdata->dc_det_pin))
                free_irq(gpio_to_irq(pdata->dc_det_pin), data);
-
-       kfree(data);
        
        return 0;
 }