static int wm831x_bat_get_prop(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent); struct wm831x *wm831x = wm831x_power->wm831x; int ret = 0; switch (psp) { case POWER_SUPPLY_PROP_STATUS: ret = wm831x_bat_check_status(wm831x, &val->intval); break; case POWER_SUPPLY_PROP_ONLINE: ret = wm831x_power_check_online(wm831x, WM831X_PWR_SRC_BATT, val); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val); break; case POWER_SUPPLY_PROP_HEALTH: ret = wm831x_bat_check_health(wm831x, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_TYPE: ret = wm831x_bat_check_type(wm831x, &val->intval); break; default: ret = -EINVAL; break; } return ret; }
static int wm831x_bat_get_prop(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent); struct wm831x *wm831x = wm831x_power->wm831x; int ret = 0; switch (psp) { case POWER_SUPPLY_PROP_STATUS: ret = wm831x_bat_check_status(wm831x, &val->intval); //val->intval = wm831x_power->batt_info.status; break; case POWER_SUPPLY_PROP_PRESENT: //case POWER_SUPPLY_PROP_ONLINE: //ret = wm831x_power_check_online(wm831x, WM831X_PWR_SRC_BATT, val); val->intval = wm831x_power->batt_info.online; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: //ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val); val->intval = wm831x_power->batt_info.voltage;//uV break; case POWER_SUPPLY_PROP_HEALTH: //ret = wm831x_bat_check_health(wm831x, &val->intval); val->intval = wm831x_power->batt_info.health; break; case POWER_SUPPLY_PROP_CHARGE_TYPE: ret = wm831x_bat_check_type(wm831x, &val->intval); break; case POWER_SUPPLY_PROP_CAPACITY: //ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val); //wm831x_batt_vol_level(wm831x_power, val->intval, &level); //val->intval = level; val->intval = wm831x_power->batt_info.level; break; case POWER_SUPPLY_PROP_TEMP: val->intval = 0; break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = POWER_SUPPLY_TECHNOLOGY_LION; break; default: ret = -EINVAL; break; } return ret; }
static void wm831x_batt_work(struct work_struct *work) { int online, status,health,level, ret; union power_supply_propval val; struct wm831x_power *power = container_of(work, struct wm831x_power, batt_work); ret = wm831x_power_check_online(power->wm831x, WM831X_PWR_SRC_BATT, &val); if (ret < 0) { printk("%s: check bat online failer... err = %d\n", __FUNCTION__, ret); return; } online = val.intval; ret = wm831x_bat_check_status(power->wm831x, &status); if (ret < 0) { printk("%s: check bat status failer... err = %d\n", __FUNCTION__, ret); return; } ret = wm831x_bat_check_health(power->wm831x, &health); if (ret < 0) { printk("%s: check bat health failer... err = %d\n", __FUNCTION__, ret); return; } ret = wm831x_power_read_voltage(power->wm831x, WM831X_AUX_BATT, &val); if (ret < 0) { printk("%s: read bat voltage failer...err = %d\n", __FUNCTION__, ret); return; } power->batt_info.voltage = val.intval; wm831x_batt_vol_level(power, val.intval / 1000, &level); //mod_timer(&power->timer, jiffies + msecs_to_jiffies(power->interval)); if (online != power->batt_info.online || status != power->batt_info.status || health != power->batt_info.health || level != power->batt_info.level) { power->batt_info.online = online; power->batt_info.status = status; power->batt_info.health = health; power->batt_info.level = level; power_supply_changed(&power->battery); } }
int wm831x_read_bat_charging_status(void) { int ret, status; if(!g_wm831x_power) { printk("err:%s:g_wm831x_power address is 0\n",__FUNCTION__); return -1; } ret = wm831x_bat_check_status(g_wm831x_power->wm831x, &status); if (ret < 0) return ret; if (status == POWER_SUPPLY_STATUS_CHARGING) return 1; return 0; }
void wm831x_batt_vol_level(struct wm831x_power *wm831x_power, int batt_vol, int *level) { int i, ret, status; static int chg_plus = 1000; static int chg_minus = 1000; static int chg_curr = 0; static int chg_num = 60; static int disp_plus = 1000; static int disp_minus = 1000; static int disp_minus2 = 1000; static int disp_curr = 0; static int disp_num = 50; static int batt_level_all = 0; static int batt_level[20]; static int avr_num = 0; static int avr_int = 0; *level = wm831x_power->batt_info.level; ret = wm831x_bat_check_status(wm831x_power->wm831x, &status); if (ret < 0) { printk("%s: check bat status failer...err = %d\n", __FUNCTION__, ret); return; } if (status == POWER_SUPPLY_STATUS_NOT_CHARGING && batt_vol >= batt_step_table[batt_num-1]) { *level = 100; return; } if (status == POWER_SUPPLY_STATUS_CHARGING) { disp_plus = 0; disp_minus = 0; disp_minus2 = 0; disp_curr = 0; for(i = 0; i < batt_num; i++){ if(batt_vol >= batt_chg_step_table[i] && batt_vol < batt_chg_step_table[i+1]) break; } if(batt_vol <= batt_chg_step_table[0]) i = 0; if(batt_vol >= batt_chg_step_table[batt_num-1]) i = batt_num-1; if(avr_int==0){ batt_level[avr_num] = batt_disp_table[i]; batt_level_all += batt_level[avr_num]; avr_num++; if(avr_num >= 20) { avr_num = 0; avr_int = 1; } else { *level = batt_disp_table[i]; return 0; } } else { batt_level_all -= batt_level[avr_num]; batt_level[avr_num]=batt_disp_table[i]; batt_level_all += batt_level[avr_num]; avr_num++; } if(avr_num >= 20) avr_num = 0; *level = batt_level_all/20; if ((chg_plus == 1000) && (chg_minus == 1000)) { *level = *level; chg_plus = 0; chg_minus = 0; chg_curr = 0; } else { if (*level >= (wm831x_power->batt_info.level+1)) { chg_minus = 0; chg_curr = 0; if(*level < 85) chg_num =10; else chg_num = 5; if (++chg_plus > chg_num) { *level = wm831x_power->batt_info.level + 1; chg_plus = 0; } else { *level = wm831x_power->batt_info.level; } } else { chg_plus = 0; chg_minus = 0; chg_curr = 0; *level = wm831x_power->batt_info.level; } } if (*level >= 100) *level = 100; if (*level < 0) *level = 0; } else { chg_plus = 0; chg_minus = 0; chg_curr = 0; for(i = 0; i < batt_num; i++){ if(batt_vol >= batt_step_table[i] && batt_vol < batt_step_table[i+1]) break; } if(batt_vol <= batt_step_table[0]) i = 0; if(batt_vol >= batt_step_table[batt_num-1]) i = batt_num-1; if(avr_int==0){ batt_level[avr_num] = batt_disp_table[i]; batt_level_all += batt_level[avr_num]; avr_num++; if(avr_num >= 20) { avr_num = 0; avr_int = 1; } else { *level = batt_disp_table[i]; return 0; } } else { batt_level_all -= batt_level[avr_num]; batt_level[avr_num]=batt_disp_table[i]; batt_level_all += batt_level[avr_num]; avr_num++; } if(avr_num >= 20) avr_num = 0; *level = batt_level_all/20; if ((disp_plus == 1000) && (disp_minus == 1000)) { *level = *level; disp_plus = 0; disp_minus = 0; disp_minus2 =0; disp_curr = 0; } else { if(*level <= (wm831x_power ->batt_info.level -20)) { disp_plus = 0; disp_curr = 0; disp_minus2 = 0; disp_num = 1; if (++disp_minus > disp_num) { *level = wm831x_power->batt_info.level - 20; disp_minus = 0; } else { *level = wm831x_power->batt_info.level; } } else if (*level <= (wm831x_power->batt_info.level-1)) { disp_plus = 0; disp_curr = 0; disp_minus = 0; if((*level < 17) || (*level > 85)) disp_num = 30; else disp_num = 80; if (++disp_minus2 > disp_num) { *level = wm831x_power->batt_info.level - 1; disp_minus2 = 0; } else { *level = wm831x_power->batt_info.level; } } else { disp_plus = 0; disp_minus = 0; disp_minus2 = 0; disp_curr = 0; *level = wm831x_power->batt_info.level; } } if (*level >= 100) *level = 100; if (*level < 0) *level = 0; } }