#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>
#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>
#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
-#define BATT_FILENAME "/data/bat_last_capacity.dat"
+//#define BATT_FILENAME "/data/bat_last_capacity.dat"
#define BATTERY_APK
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*/
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;
}
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)
#endif
+#if 0
static int rk30_adc_battery_load_capacity(void)
{
char value[4];
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)
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;
}
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;
}
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)
}
}
- 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)
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);
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);
// 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{
err_ac_failed:
power_supply_unregister(&data ->ac);
+err_usb_failed:
err_battery_failed:
power_supply_unregister(&data ->bat);
#endif
err_io_init:
-
-err_pdata_alloc_failed:
- kfree(pdata);
-err_data_alloc_failed:
- kfree(data);
-
printk("rk30_adc_battery: error!\n");
return ret;
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;
}