Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 107224
b: refs/heads/master
c: b2bd8a3
h: refs/heads/master
v: v3
  • Loading branch information
Andres Salomon authored and Anton Vorontsov committed May 4, 2008
1 parent 74fbeec commit 55d101f
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 74 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d7eb9e36c42504e87c7d92dd5c05cb6f2cf74d28
refs/heads/master: b2bd8a3bcdd18101eb5d85c267c1a1fb8ce9acc7
191 changes: 118 additions & 73 deletions trunk/drivers/power/olpc_battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,117 @@ static struct power_supply olpc_ac = {

static char bat_serial[17]; /* Ick */

static int olpc_bat_get_status(union power_supply_propval *val, uint8_t ec_byte)
{
if (olpc_platform_info.ecver > 0x44) {
if (ec_byte & BAT_STAT_CHARGING)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else if (ec_byte & BAT_STAT_DISCHARGING)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (ec_byte & BAT_STAT_FULL)
val->intval = POWER_SUPPLY_STATUS_FULL;
else /* er,... */
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
} else {
/* Older EC didn't report charge/discharge bits */
if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (ec_byte & BAT_STAT_FULL)
val->intval = POWER_SUPPLY_STATUS_FULL;
else /* Not _necessarily_ true but EC doesn't tell all yet */
val->intval = POWER_SUPPLY_STATUS_CHARGING;
}

return 0;
}

static int olpc_bat_get_health(union power_supply_propval *val)
{
uint8_t ec_byte;
int ret;

ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
if (ret)
return ret;

switch (ec_byte) {
case 0:
val->intval = POWER_SUPPLY_HEALTH_GOOD;
break;

case BAT_ERR_OVERTEMP:
val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
break;

case BAT_ERR_OVERVOLTAGE:
val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
break;

case BAT_ERR_INFOFAIL:
case BAT_ERR_OUT_OF_CONTROL:
case BAT_ERR_ID_FAIL:
case BAT_ERR_ACR_FAIL:
val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
break;

default:
/* Eep. We don't know this failure code */
ret = -EIO;
}

return ret;
}

static int olpc_bat_get_mfr(union power_supply_propval *val)
{
uint8_t ec_byte;
int ret;

ec_byte = BAT_ADDR_MFR_TYPE;
ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
if (ret)
return ret;

switch (ec_byte >> 4) {
case 1:
val->strval = "Gold Peak";
break;
case 2:
val->strval = "BYD";
break;
default:
val->strval = "Unknown";
break;
}

return ret;
}

static int olpc_bat_get_tech(union power_supply_propval *val)
{
uint8_t ec_byte;
int ret;

ec_byte = BAT_ADDR_MFR_TYPE;
ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
if (ret)
return ret;

switch (ec_byte & 0xf) {
case 1:
val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
break;
case 2:
val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
break;
default:
val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
break;
}

return ret;
}

/*********************************************************************
* Battery properties
*********************************************************************/
Expand Down Expand Up @@ -113,25 +224,10 @@ static int olpc_bat_get_property(struct power_supply *psy,

switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
if (olpc_platform_info.ecver > 0x44) {
if (ec_byte & BAT_STAT_CHARGING)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else if (ec_byte & BAT_STAT_DISCHARGING)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (ec_byte & BAT_STAT_FULL)
val->intval = POWER_SUPPLY_STATUS_FULL;
else /* er,... */
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
} else {
/* Older EC didn't report charge/discharge bits */
if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (ec_byte & BAT_STAT_FULL)
val->intval = POWER_SUPPLY_STATUS_FULL;
else /* Not _necessarily_ true but EC doesn't tell all yet */
val->intval = POWER_SUPPLY_STATUS_CHARGING;
break;
}
ret = olpc_bat_get_status(val, ec_byte);
if (ret)
return ret;
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = !!(ec_byte & BAT_STAT_PRESENT);
break;
Expand All @@ -140,72 +236,21 @@ static int olpc_bat_get_property(struct power_supply *psy,
if (ec_byte & BAT_STAT_DESTROY)
val->intval = POWER_SUPPLY_HEALTH_DEAD;
else {
ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
ret = olpc_bat_get_health(val);
if (ret)
return ret;

switch (ec_byte) {
case 0:
val->intval = POWER_SUPPLY_HEALTH_GOOD;
break;

case BAT_ERR_OVERTEMP:
val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
break;

case BAT_ERR_OVERVOLTAGE:
val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
break;

case BAT_ERR_INFOFAIL:
case BAT_ERR_OUT_OF_CONTROL:
case BAT_ERR_ID_FAIL:
case BAT_ERR_ACR_FAIL:
val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
break;

default:
/* Eep. We don't know this failure code */
return -EIO;
}
}
break;

case POWER_SUPPLY_PROP_MANUFACTURER:
ec_byte = BAT_ADDR_MFR_TYPE;
ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
ret = olpc_bat_get_mfr(val);
if (ret)
return ret;

switch (ec_byte >> 4) {
case 1:
val->strval = "Gold Peak";
break;
case 2:
val->strval = "BYD";
break;
default:
val->strval = "Unknown";
break;
}
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
ec_byte = BAT_ADDR_MFR_TYPE;
ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
ret = olpc_bat_get_tech(val);
if (ret)
return ret;

switch (ec_byte & 0xf) {
case 1:
val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
break;
case 2:
val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
break;
default:
val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
break;
}
break;
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2);
Expand Down

0 comments on commit 55d101f

Please sign in to comment.