aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/olpc_battery.c
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@queued.net>2008-05-02 16:41:59 -0400
committerAnton Vorontsov <cbouatmailru@gmail.com>2008-05-04 05:14:05 -0400
commitb2bd8a3bcdd18101eb5d85c267c1a1fb8ce9acc7 (patch)
tree327477daa7d5ff48e9572958f7ca16214400ebd0 /drivers/power/olpc_battery.c
parentd7eb9e36c42504e87c7d92dd5c05cb6f2cf74d28 (diff)
power_supply: cleanup of the OLPC battery driver
Move portions of the massive switch statement into functions. The layout of this thing has already caused one bug (a break in the wrong place), it needed to shrink. Signed-off-by: Andres Salomon <dilinger@debian.org> Cc: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
Diffstat (limited to 'drivers/power/olpc_battery.c')
-rw-r--r--drivers/power/olpc_battery.c191
1 files changed, 118 insertions, 73 deletions
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
index f8dc2b18bb49..d5fe6f0c9de0 100644
--- a/drivers/power/olpc_battery.c
+++ b/drivers/power/olpc_battery.c
@@ -86,6 +86,117 @@ static struct power_supply olpc_ac = {
86 86
87static char bat_serial[17]; /* Ick */ 87static char bat_serial[17]; /* Ick */
88 88
89static int olpc_bat_get_status(union power_supply_propval *val, uint8_t ec_byte)
90{
91 if (olpc_platform_info.ecver > 0x44) {
92 if (ec_byte & BAT_STAT_CHARGING)
93 val->intval = POWER_SUPPLY_STATUS_CHARGING;
94 else if (ec_byte & BAT_STAT_DISCHARGING)
95 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
96 else if (ec_byte & BAT_STAT_FULL)
97 val->intval = POWER_SUPPLY_STATUS_FULL;
98 else /* er,... */
99 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
100 } else {
101 /* Older EC didn't report charge/discharge bits */
102 if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
103 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
104 else if (ec_byte & BAT_STAT_FULL)
105 val->intval = POWER_SUPPLY_STATUS_FULL;
106 else /* Not _necessarily_ true but EC doesn't tell all yet */
107 val->intval = POWER_SUPPLY_STATUS_CHARGING;
108 }
109
110 return 0;
111}
112
113static int olpc_bat_get_health(union power_supply_propval *val)
114{
115 uint8_t ec_byte;
116 int ret;
117
118 ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
119 if (ret)
120 return ret;
121
122 switch (ec_byte) {
123 case 0:
124 val->intval = POWER_SUPPLY_HEALTH_GOOD;
125 break;
126
127 case BAT_ERR_OVERTEMP:
128 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
129 break;
130
131 case BAT_ERR_OVERVOLTAGE:
132 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
133 break;
134
135 case BAT_ERR_INFOFAIL:
136 case BAT_ERR_OUT_OF_CONTROL:
137 case BAT_ERR_ID_FAIL:
138 case BAT_ERR_ACR_FAIL:
139 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
140 break;
141
142 default:
143 /* Eep. We don't know this failure code */
144 ret = -EIO;
145 }
146
147 return ret;
148}
149
150static int olpc_bat_get_mfr(union power_supply_propval *val)
151{
152 uint8_t ec_byte;
153 int ret;
154
155 ec_byte = BAT_ADDR_MFR_TYPE;
156 ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
157 if (ret)
158 return ret;
159
160 switch (ec_byte >> 4) {
161 case 1:
162 val->strval = "Gold Peak";
163 break;
164 case 2:
165 val->strval = "BYD";
166 break;
167 default:
168 val->strval = "Unknown";
169 break;
170 }
171
172 return ret;
173}
174
175static int olpc_bat_get_tech(union power_supply_propval *val)
176{
177 uint8_t ec_byte;
178 int ret;
179
180 ec_byte = BAT_ADDR_MFR_TYPE;
181 ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
182 if (ret)
183 return ret;
184
185 switch (ec_byte & 0xf) {
186 case 1:
187 val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
188 break;
189 case 2:
190 val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
191 break;
192 default:
193 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
194 break;
195 }
196
197 return ret;
198}
199
89/********************************************************************* 200/*********************************************************************
90 * Battery properties 201 * Battery properties
91 *********************************************************************/ 202 *********************************************************************/
@@ -113,25 +224,10 @@ static int olpc_bat_get_property(struct power_supply *psy,
113 224
114 switch (psp) { 225 switch (psp) {
115 case POWER_SUPPLY_PROP_STATUS: 226 case POWER_SUPPLY_PROP_STATUS:
116 if (olpc_platform_info.ecver > 0x44) { 227 ret = olpc_bat_get_status(val, ec_byte);
117 if (ec_byte & BAT_STAT_CHARGING) 228 if (ret)
118 val->intval = POWER_SUPPLY_STATUS_CHARGING; 229 return ret;
119 else if (ec_byte & BAT_STAT_DISCHARGING) 230 break;
120 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
121 else if (ec_byte & BAT_STAT_FULL)
122 val->intval = POWER_SUPPLY_STATUS_FULL;
123 else /* er,... */
124 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
125 } else {
126 /* Older EC didn't report charge/discharge bits */
127 if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
128 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
129 else if (ec_byte & BAT_STAT_FULL)
130 val->intval = POWER_SUPPLY_STATUS_FULL;
131 else /* Not _necessarily_ true but EC doesn't tell all yet */
132 val->intval = POWER_SUPPLY_STATUS_CHARGING;
133 break;
134 }
135 case POWER_SUPPLY_PROP_PRESENT: 231 case POWER_SUPPLY_PROP_PRESENT:
136 val->intval = !!(ec_byte & BAT_STAT_PRESENT); 232 val->intval = !!(ec_byte & BAT_STAT_PRESENT);
137 break; 233 break;
@@ -140,72 +236,21 @@ static int olpc_bat_get_property(struct power_supply *psy,
140 if (ec_byte & BAT_STAT_DESTROY) 236 if (ec_byte & BAT_STAT_DESTROY)
141 val->intval = POWER_SUPPLY_HEALTH_DEAD; 237 val->intval = POWER_SUPPLY_HEALTH_DEAD;
142 else { 238 else {
143 ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1); 239 ret = olpc_bat_get_health(val);
144 if (ret) 240 if (ret)
145 return ret; 241 return ret;
146
147 switch (ec_byte) {
148 case 0:
149 val->intval = POWER_SUPPLY_HEALTH_GOOD;
150 break;
151
152 case BAT_ERR_OVERTEMP:
153 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
154 break;
155
156 case BAT_ERR_OVERVOLTAGE:
157 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
158 break;
159
160 case BAT_ERR_INFOFAIL:
161 case BAT_ERR_OUT_OF_CONTROL:
162 case BAT_ERR_ID_FAIL:
163 case BAT_ERR_ACR_FAIL:
164 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
165 break;
166
167 default:
168 /* Eep. We don't know this failure code */
169 return -EIO;
170 }
171 } 242 }
172 break; 243 break;
173 244
174 case POWER_SUPPLY_PROP_MANUFACTURER: 245 case POWER_SUPPLY_PROP_MANUFACTURER:
175 ec_byte = BAT_ADDR_MFR_TYPE; 246 ret = olpc_bat_get_mfr(val);
176 ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
177 if (ret) 247 if (ret)
178 return ret; 248 return ret;
179
180 switch (ec_byte >> 4) {
181 case 1:
182 val->strval = "Gold Peak";
183 break;
184 case 2:
185 val->strval = "BYD";
186 break;
187 default:
188 val->strval = "Unknown";
189 break;
190 }
191 break; 249 break;
192 case POWER_SUPPLY_PROP_TECHNOLOGY: 250 case POWER_SUPPLY_PROP_TECHNOLOGY:
193 ec_byte = BAT_ADDR_MFR_TYPE; 251 ret = olpc_bat_get_tech(val);
194 ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
195 if (ret) 252 if (ret)
196 return ret; 253 return ret;
197
198 switch (ec_byte & 0xf) {
199 case 1:
200 val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
201 break;
202 case 2:
203 val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
204 break;
205 default:
206 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
207 break;
208 }
209 break; 254 break;
210 case POWER_SUPPLY_PROP_VOLTAGE_AVG: 255 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
211 ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2); 256 ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2);