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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
	}

}
Esempio n. 4
0
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;
}
Esempio n. 5
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;
	}
}