X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fpower%2Frk30_factory_adc_battery.c;h=69790668f05e7bdaab2704e4522badf5bc0780d2;hb=c71a0bf1fdd48a97be1524f2d450575a590c07db;hp=6276cf154746804f5eaf3cabc8fb9b7ad4227446;hpb=b637a56758510d716d71d2b59a9addc1193f0d31;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/power/rk30_factory_adc_battery.c b/drivers/power/rk30_factory_adc_battery.c old mode 100644 new mode 100755 index 6276cf154746..69790668f05e --- a/drivers/power/rk30_factory_adc_battery.c +++ b/drivers/power/rk30_factory_adc_battery.c @@ -22,13 +22,7 @@ #include #include #include -#include -#include -#include -#include #include -#include -#include #include #include #include @@ -38,25 +32,33 @@ #include #include #include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include + #ifdef CONFIG_EARLYSUSPEND /* kernel/power/earlysuspend.c */ extern suspend_state_t get_suspend_state(void); #endif -static int rk30_battery_dbg_level = 0; +static int rk30_battery_dbg_level; module_param_named(dbg_level, rk30_battery_dbg_level, int, 0644); #define DBG( args...) \ - do { \ - if (rk30_battery_dbg_level) { \ - pr_info(args); \ - } \ - } while (0) +do {\ + if (rk30_battery_dbg_level) {\ + pr_info(args);\ + } \ +} while (0) #define TIMER_MS_COUNTS 1000 #define SLOPE_SECOND_COUNTS 15 -#define DISCHARGE_MIN_SECOND 60 +#define DISCHARGE_MIN_SECOND 30 #define CHARGE_MIN_SECOND 45 #define CHARGE_MID_SECOND 90 #define CHARGE_MAX_SECOND 250 @@ -79,11 +81,15 @@ module_param_named(dbg_level, rk30_battery_dbg_level, int, 0644); #elif defined(CONFIG_ARCH_RK2928) #define BAT_DEFINE_VALUE 3300 #else -#define BAT_DEFINE_VALUE 2500 +#define BAT_DEFINE_VALUE 3300 /*2500*/ #endif +#define RK30_GPIO_LOW 0 +#define RK30_GPIO_HIGH 1 + + -#define BATT_FILENAME "/data/bat_last_capacity.dat" +//#define BATT_FILENAME "/data/bat_last_capacity.dat" #define BATTERY_APK @@ -95,11 +101,12 @@ 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; - -#ifdef CONFIG_BATTERY_RK30_VOL3V8 -#define BATT_MAX_VOL_VALUE 4120 //Full charge volate -#define BATT_ZERO_VOL_VALUE 3600//3500 //power down voltage +#if 1 +#define BATT_MAX_VOL_VALUE 4250/*Full charge volatge*/ +#define BATT_ZERO_VOL_VALUE 3500/*power down voltage*/ #define BATT_NOMAL_VOL_VALUE 3800 static int batt_table[2*BATT_NUM+6] = @@ -157,7 +164,7 @@ struct rk30_adc_battery_data { //struct timer_list timer; struct workqueue_struct *wq; struct delayed_work delay_work; - struct delayed_work check_work; + struct delayed_work check_work; struct work_struct dcwakeup_work; struct work_struct lowerpower_work; bool resume; @@ -231,8 +238,10 @@ 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); - - +static bool batt_gpio_is_valid(int number) +{ + return number > 0 && number < 256; +} #ifdef BATTERY_APK //#define BAT_ADC_TABLE_LEN 11 static ssize_t bat_param_read(struct device *dev,struct device_attribute *attr, char *buf) @@ -245,7 +254,7 @@ static ssize_t bat_param_read(struct device *dev,struct device_attribute *attr, printk("i=%d batt_table=%d\n",i+17,batt_table[i+17]); return 0; } -DEVICE_ATTR(batparam, 0664, bat_param_read,NULL); +DEVICE_ATTR(batparam, 0444, bat_param_read, NULL); static ssize_t rkbatt_show_debug_attrs(struct device *dev, @@ -331,13 +340,63 @@ 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) +{ + struct iio_channel *channel = data->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 create_sysfs_interfaces(struct device *dev) { int liTmep; @@ -361,7 +420,7 @@ error: #endif - +#if 0 static int rk30_adc_battery_load_capacity(void) { char value[4]; @@ -394,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) @@ -418,26 +478,24 @@ EXPORT_SYMBOL_GPL(adc_battery_notifier_call_chain); static void rk_start_charge(struct rk30_adc_battery_data *bat) { struct rk30_adc_battery_platform_data *pdata = bat->pdata; - - if (pdata->charge_set_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(pdata->charge_set_pin)) gpio_direction_output(pdata->charge_set_pin, pdata->charge_set_level); - } } static void rk_stop_charge(struct rk30_adc_battery_data *bat) { struct rk30_adc_battery_platform_data *pdata = bat->pdata; - if (pdata->charge_set_pin != INVALID_GPIO){ + + if (batt_gpio_is_valid(pdata->charge_set_pin)) gpio_direction_output(pdata->charge_set_pin, 1 - pdata->charge_set_level); - } } static int get_ac_status(struct rk30_adc_battery_data *bat){ struct rk30_adc_battery_platform_data *pdata = bat->pdata; int status = 0; - if (pdata->dc_det_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(pdata->dc_det_pin)) { if (gpio_get_value (pdata->dc_det_pin) == pdata->dc_det_level){ status = 1; }else{ @@ -451,18 +509,8 @@ static int get_ac_status(struct rk30_adc_battery_data *bat){ return status; } -// state of charge --- charge-display -static int get_usb_status1(struct rk30_adc_battery_data *bat){ - struct rk30_adc_battery_platform_data *pdata = bat->pdata; - int status = 0; - if(pdata->is_usb_charging){ - status = pdata->is_usb_charging(); - } - return status; - - +#if defined CONFIG_BATTERY_RK30_USB_CHARGE -} //state of charge ----running static int get_usb_status2(struct rk30_adc_battery_data *bat){ @@ -506,24 +554,22 @@ static int get_usb_status2(struct rk30_adc_battery_data *bat){ return usb_status; } - +#endif static int rk_battery_get_status(struct rk30_adc_battery_data *bat) { int charge_on = 0; - struct rk30_adc_battery_platform_data *pdata = bat->pdata; +/* struct rk30_adc_battery_platform_data *pdata = bat->pdata;*/ int ac_ac_charging = 0, usb_ac_charging = 0; int i=0; -#if defined (CONFIG_BATTERY_RK30_AC_CHARGE) ac_ac_charging = get_ac_status(bat); if(1 == ac_ac_charging) charge_on = 1; -#endif #if defined (CONFIG_BATTERY_RK30_USB_CHARGE) if (strstr(saved_command_line,"charger")){ wake_lock(&charge_display_lock); //lock - if( bat->pdata->usb_det_pin != INVALID_GPIO ){ + if (batt_gpio_is_valid(bat->pdata->usb_det_pin)) { if( gpio_get_value(bat->pdata->usb_det_pin)== bat->pdata->usb_det_level){ if(( 1 == usb_ac_charging )||( 1 == ac_ac_charging )) bat -> ac_charging = 1; @@ -620,10 +666,11 @@ static int is_charge_ok(struct rk30_adc_battery_data *bat) if( 1 != bat->charge_level) return -1; - if((pdata->charge_ok_pin == INVALID_GPIO)&& ( pdata->charging_ok == NULL)) + if ((!(batt_gpio_is_valid(pdata->charge_ok_pin))) && ( + pdata->charging_ok == NULL)) return -1; - if (pdata->charge_ok_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(pdata->charge_ok_pin)) { if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level){ charge_is_ok =1; } @@ -634,7 +681,6 @@ static int is_charge_ok(struct rk30_adc_battery_data *bat) return charge_is_ok; - } @@ -695,9 +741,10 @@ static int rk30_adc_battery_status_samples(struct rk30_adc_battery_data *bat) bat->time_to_full = get_seconds(); }else if(bat->bat_capacity == 99) { - if(get_seconds() - bat->time_to_full > 1800) + if(get_seconds() - bat->time_to_full > 1800){ bat->bat_capacity = 100; bat->time_to_full = 0; + } } @@ -709,6 +756,19 @@ static int rk30_adc_battery_status_samples(struct rk30_adc_battery_data *bat) bat->full_times = 0; bat->bat_status = POWER_SUPPLY_STATUS_CHARGING; + + if((bat->bat_capacity == 99)&&(bat->time_to_full == 0)){ + bat->time_to_full = get_seconds(); + }else if(bat->bat_capacity == 99) + { + if(get_seconds() - bat->time_to_full > 1800){ + bat->bat_capacity = 100; + bat->time_to_full = 0; + } + + } + + }else{ bat->full_times++; @@ -733,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 =voltage = adc_to_voltage(value); -#endif + voltage = adc_to_voltage(value); } - - DBG("ref_voltage =%d, voltage=%d \n", ref_voltage,voltage); + DBG("ref_voltage =%d, voltage=%d\n", ref_voltage, voltage); return voltage; } @@ -804,7 +873,7 @@ static void rk30_adc_battery_voltage_samples(struct rk30_adc_battery_data *bat) value = bat->adc_val; - adc_async_read(bat->client); + bat->adc_val = rk_adc_battery_iio_read(bat->pdata); *(bat->pSamples++) = rk_adc_voltage(bat,value); @@ -886,11 +955,15 @@ static int rk30_adc_battery_voltage_to_capacity(struct rk30_adc_battery_data *ba int capacity = 0; int *p; + if (bat->pdata->use_board_table) - p = bat->pdata->board_batt_table; + p = bat->pdata->board_batt_table; + else if (bat->pdata->dts_batt_table) + p = bat->pdata->dts_batt_table; else p = batt_table; + if (1 == bat->charge_level){ //charge if(0 == bat->start_voltage_status ){ if(BatVoltage >= (p[2*BATT_NUM +5])){ @@ -997,12 +1070,11 @@ static int rk30_adc_battery_voltage_to_capacity(struct rk30_adc_battery_data *ba return capacity; } +#if defined CONFIG_BATTERY_RK30_USB_CHARGE static void rk_usb_charger(struct rk30_adc_battery_data *bat) { - int capacity = 0; -// struct rk30_adc_battery_platform_data *pdata = bat->pdata; int timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE; int timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE; @@ -1131,6 +1203,7 @@ static void rk_usb_charger(struct rk30_adc_battery_data *bat) bat->capacitytmp = capacity; } +#endif static void rk_ac_charger(struct rk30_adc_battery_data *bat) { int capacity = 0; @@ -1313,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; @@ -1331,25 +1408,20 @@ 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) bat->bat_capacity =1; } - printk("old_capacity = %d , new_capacity =%d, capacity = %d\n ",old_capacity,new_capacity ,bat ->bat_capacity); + DBG("oldcapacity %d,newcapacity %d,capacity %d\n", old_capacity + , new_capacity, bat->bat_capacity); bat ->bat_change = 1; } +#if defined CONFIG_BATTERY_RK30_USB_CHARGE #define to_battery_usb_device_info(x) container_of((x), \ struct rk30_adc_battery_data, usb); @@ -1393,7 +1465,7 @@ static struct power_supply rk30_usb_supply = .properties = rk30_adc_battery_usb_props, .num_properties = ARRAY_SIZE(rk30_adc_battery_usb_props), }; - +#endif static irqreturn_t rk30_adc_battery_dc_wakeup(int irq, void *dev_id) { disable_irq_nosync(irq); @@ -1456,9 +1528,6 @@ static void rk30_adc_battery_dcdet_delaywork(struct work_struct *work) struct rk30_adc_battery_data *bat = container_of((work), \ struct rk30_adc_battery_data, dcwakeup_work); - rk28_send_wakeup_key(); // wake up the system - - pdata = bat->pdata; irq = gpio_to_irq(pdata->dc_det_pin); free_irq(irq, NULL); @@ -1470,6 +1539,7 @@ static void rk30_adc_battery_dcdet_delaywork(struct work_struct *work) } power_supply_changed(&bat ->ac); + rk_send_wakeup_key(); bat ->bat_status_cnt = 0; //the state of battery is change @@ -1586,7 +1656,8 @@ static void rk30_adc_battery_resume_check(struct rk30_adc_battery_data *bat) bat ->old_charge_level = -1; bat ->pSamples = bat->adc_samples; - adc_sync_read(bat->client); //start adc sample + bat->adc_val = rk_adc_battery_iio_read(bat->pdata); + level = oldlevel = rk_battery_get_status(bat);//rk30_adc_battery_status_samples(bat);//init charge status for (i = 0; i < NUM_VOLTAGE_SAMPLE; i++) { //0.3 s @@ -1611,7 +1682,7 @@ static void rk30_adc_battery_resume_check(struct rk30_adc_battery_data *bat) bat->bat_capacity = (new_capacity < old_capacity) ? new_capacity : old_capacity; // aviod the value of capacity increase dicharge } - if( bat ->pdata->batt_low_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(bat->pdata->batt_low_pin)) { if (gpio_get_value(bat ->pdata->batt_low_pin) == bat ->pdata->batt_low_level) bat->bat_capacity = 0; @@ -1628,7 +1699,7 @@ static int rk30_adc_battery_suspend(struct platform_device *dev, pm_message_t st data ->suspend_time = get_seconds(); cancel_delayed_work(&data ->delay_work); - if( data ->pdata->batt_low_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(data->pdata->batt_low_pin)) { irq = gpio_to_irq(data ->pdata->batt_low_pin); enable_irq(irq); @@ -1649,7 +1720,7 @@ static int rk30_adc_battery_resume(struct platform_device *dev) data ->resume_time = get_seconds(); data ->resume = true; queue_delayed_work(data->wq, &data ->delay_work, msecs_to_jiffies(100)); - if( data ->pdata->batt_low_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(data->pdata->batt_low_pin)) { irq = gpio_to_irq(data ->pdata ->batt_low_pin); disable_irq_wake(irq); @@ -1666,8 +1737,8 @@ static int rk30_adc_battery_resume(struct platform_device *dev) unsigned long AdcTestCnt = 0; static void rk30_adc_battery_timer_work(struct work_struct *work) { -struct rk30_adc_battery_data *bat = container_of((work), \ - struct rk30_adc_battery_data, delay_work); + struct rk30_adc_battery_data *bat = container_of((work), struct + rk30_adc_battery_data, delay_work.work); #ifdef CONFIG_PM if (bat ->resume) { @@ -1721,7 +1792,7 @@ struct rk30_adc_battery_data *bat = container_of((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) @@ -1750,65 +1821,46 @@ struct rk30_adc_battery_data *bat = container_of((work), \ static int rk30_adc_battery_io_init(struct rk30_adc_battery_platform_data *pdata) { int ret = 0; - - if (pdata->io_init) { - pdata->io_init(); - return 0; - } - - //charge control pin - if (pdata->charge_set_pin != INVALID_GPIO){ - ret = gpio_request(pdata->charge_set_pin, NULL); - if (ret) { - printk("failed to request dc_det gpio\n"); - goto error; - } - gpio_direction_output(pdata->charge_set_pin, 1 - pdata->charge_set_level); - } - - //dc charge detect pin - if (pdata->dc_det_pin != INVALID_GPIO){ + + if (batt_gpio_is_valid(pdata->dc_det_pin)) { ret = gpio_request(pdata->dc_det_pin, NULL); if (ret) { - printk("failed to request dc_det gpio\n"); + pr_info("failed to request dc_det gpio\n"); goto error; } - gpio_pull_updown(pdata->dc_det_pin, GPIOPullUp);//important ret = gpio_direction_input(pdata->dc_det_pin); if (ret) { - printk("failed to set gpio dc_det input\n"); + pr_info("failed to set gpio dc_det input\n"); goto error; } } //charge ok detect - if (pdata->charge_ok_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(pdata->charge_ok_pin)) { ret = gpio_request(pdata->charge_ok_pin, NULL); if (ret) { - printk("failed to request charge_ok gpio\n"); + pr_err("failed to request charge_ok gpio\n"); goto error; } - gpio_pull_updown(pdata->charge_ok_pin, GPIOPullUp);//important ret = gpio_direction_input(pdata->charge_ok_pin); if (ret) { - printk("failed to set gpio charge_ok input\n"); + pr_err("failed to set gpio charge_ok input\n"); goto error; } } //batt low pin - if( pdata->batt_low_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(pdata->batt_low_pin)) { ret = gpio_request(pdata->batt_low_pin, NULL); if (ret) { - printk("failed to request batt_low_pin gpio\n"); + pr_err("failed to request batt_low_pin gpio\n"); goto error; } - gpio_pull_updown(pdata->batt_low_pin, GPIOPullUp); ret = gpio_direction_input(pdata->batt_low_pin); if (ret) { - printk("failed to set gpio batt_low_pin input\n"); + pr_err("failed to set gpio batt_low_pin input\n"); goto error; } } @@ -1826,7 +1878,10 @@ int get_battery_status(void) static int rk_adc_battery_poweron_status(struct rk30_adc_battery_data *bat) { int status; +#if defined CONFIG_BATTERY_RK30_USB_CHARGE int otg_status = 0; +#endif + // struct rk30_adc_battery_platform_data *pdata = bat->pdata; if (get_ac_status(bat) ){ @@ -1889,9 +1944,10 @@ static void rk30_adc_battery_check(struct rk30_adc_battery_data *bat) //bat ->old_charge_level // pSamples = bat->adc_samples; - adc_sync_read(bat->client); //start adc sample - DBG("first_adc_value is %d \n",bat->adc_val ); + bat->adc_val = rk_adc_battery_iio_read(bat->pdata); + + DBG("first_adc_value is %d\n", bat->adc_val); level = oldlevel = rk_adc_battery_poweron_status(bat);// rk30_adc_battery_status_samples(bat);//init charge status for (i = 0; i < NUM_VOLTAGE_SAMPLE; i++){ //0.3 s @@ -1911,7 +1967,7 @@ static void rk30_adc_battery_check(struct rk30_adc_battery_data *bat) mdelay(10); check_data[i] = bat->adc_val; - adc_async_read(bat->client); + bat->adc_val = rk_adc_battery_iio_read(bat->pdata); bat->adc_value += check_data[i]; } bat->adc_value /= NUM_VOLTAGE_SAMPLE; @@ -1975,13 +2031,16 @@ static void rk30_adc_battery_check(struct rk30_adc_battery_data *bat) #endif if(0 !=bat ->pdata->low_voltage_protection ){ - if((bat->bat_voltage <= bat ->pdata->low_voltage_protection)) + if (bat->bat_voltage <= bat->pdata->low_voltage_protection) { system_lowerpower = 1; printk("protection lower power .....\n"); + } }else{ - if((bat->bat_voltage <= BATT_ZERO_VOL_VALUE)) + if (bat->bat_voltage <= BATT_ZERO_VOL_VALUE) { system_lowerpower = 1; - printk("lower power .....\n"); + pr_info("lower power bat->bat_voltage = %d\n" + , bat->bat_voltage); + } } #if 0 @@ -1992,21 +2051,6 @@ static void rk30_adc_battery_check(struct rk30_adc_battery_data *bat) } -static void rk30_adc_battery_callback(struct adc_client *client, void *param, int result) -{ - struct rk30_adc_battery_data *bat = container_of((client), \ - struct rk30_adc_battery_data, client); - - if (result < 0){ - DBG("adc_battery_callback resule < 0 , the value "); - return; - }else{ - gBatteryData->adc_val = result; - DBG("result = %d, gBatteryData->adc_val = %d\n", result, gBatteryData->adc_val ); - } - return; -} - static void rk30_adc_battery_lowerpower_delaywork(struct work_struct *work) { int irq; @@ -2014,13 +2058,12 @@ static void rk30_adc_battery_lowerpower_delaywork(struct work_struct *work) struct rk30_adc_battery_data *bat = container_of((work), \ struct rk30_adc_battery_data, lowerpower_work); - if( bat->pdata->batt_low_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(bat->pdata->batt_low_pin)) { irq = gpio_to_irq(bat ->pdata ->batt_low_pin); disable_irq(irq); } printk("lowerpower\n"); - rk28_send_wakeup_key(); // wake up the system return; } @@ -2038,7 +2081,7 @@ static void rk_lowerpower_check(struct rk30_adc_battery_data *bat) for(i=0; i< NUM_VOLTAGE_SAMPLE; i++){ mdelay(10); - adc_async_read(bat->client); + bat->adc_val = rk_adc_battery_iio_read(bat->pdata); check_data[i] = bat->adc_val; adc_val += check_data[i]; @@ -2058,8 +2101,9 @@ static void rk_lowerpower_check(struct rk30_adc_battery_data *bat) } static void rk_adc_battery_check_work(struct work_struct *work) { - struct rk30_adc_battery_data *bat = container_of((work), \ - struct rk30_adc_battery_data, check_work); + struct rk30_adc_battery_data *bat = + container_of((work), struct + rk30_adc_battery_data, check_work.work); if(1 == get_ac_status(bat)){ bat->bat_status = POWER_SUPPLY_STATUS_CHARGING; @@ -2088,29 +2132,148 @@ static int battery_notifier_call(struct notifier_block *nb, container_of(nb, struct rk30_adc_battery_data, battery_nb); switch (event) { - case LCDC_ON: - DBG("LCDC on \n"); - rk_lowerpower_check(bat);//for lower power protect - break; + case 1: + rk_lowerpower_check(bat); + break; - case BACKLIGHT_ON: - DBG("display \n"); - poweron_lowerpoer_handle(bat); - break; - default: - return NOTIFY_OK; - } + case 2: + poweron_lowerpoer_handle(bat); + break; + default: + return NOTIFY_OK; + } return NOTIFY_OK; } + +#ifdef CONFIG_OF +static int rk31_adcbat_parse_dt(struct platform_device *pdev, struct +rk30_adc_battery_platform_data *data) +{ + struct device_node *node = pdev->dev.of_node; + enum of_gpio_flags flags; + struct property *prop; + int length; + u32 value; + int ret; + int i; + size_t size; + + 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; + + 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); + if (!prop) + return -EINVAL; + + length /= sizeof(u32); + + if (length > 0) { + size = (sizeof(*data->dts_batt_table)) * length; + data->dts_batt_table = + devm_kzalloc(&(pdev->dev), size, GFP_KERNEL); + if (!data->dts_batt_table) + return -ENOMEM; + + ret = of_property_read_u32_array(node + , "bat_table", data->dts_batt_table, length); + if (ret < 0) + return ret; + } + + for (i = 4; i < length; i++) { + batt_table[i] = data->dts_batt_table[i]; + + pr_info("data->dts_batt_table[ %d ] %d %d\n", i + , data->dts_batt_table[i], batt_table[i]); + } + data->dc_det_pin = of_get_named_gpio_flags(node + , "dc_det_gpio", 0, &flags); + if (data->dc_det_pin == -EPROBE_DEFER) + pr_info("%s dc_det_gpio error\n", __func__); + + if (batt_gpio_is_valid(data->dc_det_pin)) + data->dc_det_level = (flags & OF_GPIO_ACTIVE_LOW) + ? RK30_GPIO_LOW : RK30_GPIO_HIGH; + + data->batt_low_pin = of_get_named_gpio_flags(node + , "bat_low_gpio", 0, &flags); + if (data->batt_low_pin == -EPROBE_DEFER) + pr_info("%s bat_low_gpio error\n", __func__); + + if (batt_gpio_is_valid(data->batt_low_pin)) + data->batt_low_level = (flags & OF_GPIO_ACTIVE_LOW) + ? RK30_GPIO_LOW : RK30_GPIO_HIGH; + + data->charge_ok_pin = of_get_named_gpio_flags(node + , "chg_ok_gpio", 0, &flags); + if (data->charge_ok_pin == -EPROBE_DEFER) + pr_info("%s chg_ok_gpio error\n", __func__); + + if (batt_gpio_is_valid(data->charge_ok_pin)) + data->charge_ok_level = (flags & OF_GPIO_ACTIVE_LOW) + ? RK30_GPIO_LOW : RK30_GPIO_HIGH; + + ret = of_property_read_u32(node, "is_dc_charge", &value); + if (ret < 0) { + pr_info("%s:hardware unsupport dc charge\n", __func__); + value = 0; + } + data->is_dc_charge = value; + + ret = of_property_read_u32(node, "is_usb_charge" + , &value); + if (ret < 0) { + pr_err("%s:hardware unsupport usb charge\n", __func__); + value = 0; + } + data->is_usb_charge = value; + + pr_info("rk30 battery:support %s %s charger\n", + data->is_dc_charge ? "DC" : "" + , data->is_usb_charge ? "USB" : ""); + + return 0; +} +#else +static int rk31_adcbat_parse_dt(struct platform_device +*dev, struct rk30_adc_battery_platform_data *data) +{ + return -ENODEV; +} +#endif + + static int rk30_adc_battery_probe(struct platform_device *pdev) { int ret; int irq; int irq_flag; - struct adc_client *client; struct rk30_adc_battery_data *data; - struct rk30_adc_battery_platform_data *pdata = pdev->dev.platform_data; + struct rk30_adc_battery_platform_data *pdata; #ifdef CONFIG_MACH_RK_FAC int i; for(i=0;idev, sizeof(*data), GFP_KERNEL); + 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) + ret = -ENOMEM; + memset(data, 0, sizeof(struct rk30_adc_battery_data)); gBatteryData = data; - platform_set_drvdata(pdev, data); data->pdata = pdata; @@ -2157,9 +2324,17 @@ static int rk30_adc_battery_probe(struct platform_device *pdev) data->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING; wake_lock_init(&batt_wake_lock, WAKE_LOCK_SUSPEND, "batt_lock"); wake_lock_init(&charge_display_lock, WAKE_LOCK_SUSPEND, "charge_display_lock"); //charge_display_lock - wake_lock_init(&batt_wake_lock_detect_lowpower, WAKE_LOCK_SUSPEND, "lowpower_lock"); - - ret = rk30_adc_battery_io_init(pdata); + wake_lock_init(&batt_wake_lock_detect_lowpower + , WAKE_LOCK_SUSPEND, "lowpower_lock"); + + ret = rk31_adcbat_parse_dt(pdev, data->pdata); + /*ret = rk31_adcbat_parse_dt(pdev, pdata);*/ + if (ret < 0) { + pr_err("failed to find rk30 adc battery platform data\n"); + goto err_io_init; + } + + ret = rk30_adc_battery_io_init(data->pdata); if (ret) { ret = -EINVAL; goto err_io_init; @@ -2168,19 +2343,10 @@ static int rk30_adc_battery_probe(struct platform_device *pdev) memset(data->adc_samples, 0, sizeof(int)*(NUM_VOLTAGE_SAMPLE + 2)); //register adc for battery sample - if(0 == pdata->adc_channel) - client = adc_register(0, rk30_adc_battery_callback, NULL); //pdata->adc_channel = ani0 - else - client = adc_register(pdata->adc_channel, rk30_adc_battery_callback, NULL); - if(!client){ - ret = -EINVAL; - goto err_adc_register_failed; - } data->wq = create_singlethread_workqueue("adc_battd"); - //variable init - data->client = client; - data->adc_val = adc_sync_read(client); + /*data->client = client;*/ + data->adc_val = rk_adc_battery_iio_read(data->pdata); data ->bat = rk30_battery_supply; ret = power_supply_register(&pdev->dev,&data ->bat); @@ -2206,13 +2372,13 @@ static int rk30_adc_battery_probe(struct platform_device *pdev) goto err_ac_failed; } -#if defined (CONFIG_BATTERY_RK30_AC_CHARGE) //init dc dectet irq & delay work - if (pdata->dc_det_pin != INVALID_GPIO){ + if (batt_gpio_is_valid(data->pdata->dc_det_pin)) { INIT_WORK(&data->dcwakeup_work, rk30_adc_battery_dcdet_delaywork); - irq = gpio_to_irq(pdata->dc_det_pin); - irq_flag = gpio_get_value (pdata->dc_det_pin) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; + irq = gpio_to_irq(data->pdata->dc_det_pin); + irq_flag = gpio_get_value(data->pdata->dc_det_pin) + ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; ret = request_irq(irq, rk30_adc_battery_dc_wakeup, irq_flag, "ac_charge_irq", NULL); if (ret) { ret = -EINVAL; @@ -2222,7 +2388,6 @@ static int rk30_adc_battery_probe(struct platform_device *pdev) enable_irq_wake(irq); } -#endif #ifdef BATTERY_APK ret = device_create_file(&pdev->dev,&dev_attr_batparam); @@ -2247,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 == 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{ @@ -2256,18 +2422,17 @@ static int rk30_adc_battery_probe(struct platform_device *pdev) } INIT_DELAYED_WORK(&data->check_work, rk_adc_battery_check_work); queue_delayed_work(data ->wq, &data ->check_work, msecs_to_jiffies(TIMER_MS_COUNTS)); - if( pdata->batt_low_pin != INVALID_GPIO){ - - if (gpio_get_value(pdata->batt_low_pin) ==0){ - mdelay(20); - if (gpio_get_value(pdata->batt_low_pin) ==0){ + if (batt_gpio_is_valid(data->pdata->batt_low_pin)) { + if (0 == gpio_get_value(data->pdata->batt_low_pin)) { + mdelay(20); + if (gpio_get_value(data->pdata->batt_low_pin) == 0) { printk("lower power\n"); kernel_power_off(); } } INIT_WORK(&data->lowerpower_work, rk30_adc_battery_lowerpower_delaywork); - irq = gpio_to_irq(pdata->batt_low_pin); + irq = gpio_to_irq(data->pdata->batt_low_pin); ret = request_irq(irq, rk30_adc_battery_low_wakeup, IRQF_TRIGGER_LOW, "batt_low_irq", NULL); if (ret) { ret = -EINVAL; @@ -2284,29 +2449,24 @@ static int rk30_adc_battery_probe(struct platform_device *pdev) return 0; err_sysfs: -err_usb_failed: power_supply_unregister(&data ->usb); err_ac_failed: power_supply_unregister(&data ->ac); +err_usb_failed: err_battery_failed: power_supply_unregister(&data ->bat); err_dcirq_failed: - if (pdata->dc_det_pin != INVALID_GPIO){ - free_irq(gpio_to_irq(pdata->dc_det_pin), data); - } + if (batt_gpio_is_valid(data->pdata->dc_det_pin)) + free_irq(gpio_to_irq(data->pdata->dc_det_pin), data); #if 1 err_lowpowerirq_failed: - if( pdata->batt_low_pin != INVALID_GPIO){ - free_irq(gpio_to_irq(pdata->batt_low_pin), data); - } -#endif -err_adc_register_failed: -err_io_init: -err_data_alloc_failed: - kfree(data); + if (batt_gpio_is_valid(data->pdata->batt_low_pin)) + free_irq(gpio_to_irq(data->pdata->batt_low_pin), data); +#endif +err_io_init: printk("rk30_adc_battery: error!\n"); return ret; @@ -2315,38 +2475,44 @@ err_data_alloc_failed: static int rk30_adc_battery_remove(struct platform_device *pdev) { struct rk30_adc_battery_data *data = platform_get_drvdata(pdev); - struct rk30_adc_battery_platform_data *pdata = pdev->dev.platform_data; + struct rk30_adc_battery_platform_data *pdata = data->pdata; cancel_delayed_work_sync(&data->delay_work); -#if defined (CONFIG_BATTERY_RK30_AC_CHARGE) - if (pdata->dc_det_pin != INVALID_GPIO) - cancel_delayed_work_sync(&data->dcwakeup_work); -#endif + if (batt_gpio_is_valid(pdata->dc_det_pin)) + cancel_work_sync(&data->dcwakeup_work); cancel_delayed_work_sync(&data->check_work); - if( pdata->batt_low_pin != INVALID_GPIO) - cancel_delayed_work_sync(&data->lowerpower_work); + if (batt_gpio_is_valid(pdata->batt_low_pin)) + cancel_work_sync(&data->lowerpower_work); #if defined (CONFIG_BATTERY_RK30_USB_CHARGE) power_supply_unregister(&data ->usb); #endif power_supply_unregister(&data ->ac); power_supply_unregister(&data ->bat); - if (pdata->dc_det_pin != INVALID_GPIO) + if (batt_gpio_is_valid(pdata->dc_det_pin)) free_irq(gpio_to_irq(pdata->dc_det_pin), data); - - kfree(data); return 0; } +#ifdef CONFIG_OF +static const struct of_device_id rk30_adc_battery_dt_match[] = { + { .compatible = "rk30-adc-battery",}, + {}, +}; +MODULE_DEVICE_TABLE(of, rk30_adc_battery_dt_match); +#endif + + static struct platform_driver rk30_adc_battery_driver = { .probe = rk30_adc_battery_probe, .remove = rk30_adc_battery_remove, .suspend = rk30_adc_battery_suspend, .resume = rk30_adc_battery_resume, .driver = { - .name = "rk30-battery", + .name = "rk30-adc-battery", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rk30_adc_battery_dt_match), } }; @@ -2364,6 +2530,8 @@ subsys_initcall(rk30_adc_battery_init); //fs_initcall(rk30_adc_battery_init); module_exit(rk30_adc_battery_exit); + + MODULE_DESCRIPTION("Battery detect driver for the rk30"); MODULE_AUTHOR("luowei lw@rock-chips.com"); MODULE_LICENSE("GPL");