1 /* 2 * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00 3 * series of PDAs 4 * 5 * Copyright (c) 2004-2005 Richard Purdie 6 * 7 * Based on code written by Sharp for 2.4 kernels 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14 15 #undef DEBUG 16 17 #include <linux/module.h> 18 #include <linux/kernel.h> 19 #include <linux/interrupt.h> 20 #include <linux/platform_device.h> 21 #include <linux/apm-emulation.h> 22 #include <linux/timer.h> 23 #include <linux/delay.h> 24 #include <linux/leds.h> 25 #include <linux/suspend.h> 26 #include <linux/gpio.h> 27 28 #include <asm/mach-types.h> 29 #include <mach/pm.h> 30 #include <mach/pxa2xx-regs.h> 31 #include <mach/regs-rtc.h> 32 #include <mach/sharpsl_pm.h> 33 34 /* 35 * Constants 36 */ 37 #define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */ 38 #define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ 39 #define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ 40 #define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ 41 42 #define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ 43 #define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ 44 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ 45 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */ 46 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */ 47 #define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */ 48 #define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */ 49 #define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */ 50 51 /* 52 * Prototypes 53 */ 54 #ifdef CONFIG_PM 55 static int sharpsl_off_charge_battery(void); 56 static int sharpsl_check_battery_voltage(void); 57 static int sharpsl_fatal_check(void); 58 #endif 59 static int sharpsl_check_battery_temp(void); 60 static int sharpsl_ac_check(void); 61 static int sharpsl_average_value(int ad); 62 static void sharpsl_average_clear(void); 63 static void sharpsl_charge_toggle(struct work_struct *private_); 64 static void sharpsl_battery_thread(struct work_struct *private_); 65 66 67 /* 68 * Variables 69 */ 70 struct sharpsl_pm_status sharpsl_pm; 71 static DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle); 72 static DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread); 73 DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); 74 75 76 77 struct battery_thresh sharpsl_battery_levels_acin[] = { 78 { 213, 100}, 79 { 212, 98}, 80 { 211, 95}, 81 { 210, 93}, 82 { 209, 90}, 83 { 208, 88}, 84 { 207, 85}, 85 { 206, 83}, 86 { 205, 80}, 87 { 204, 78}, 88 { 203, 75}, 89 { 202, 73}, 90 { 201, 70}, 91 { 200, 68}, 92 { 199, 65}, 93 { 198, 63}, 94 { 197, 60}, 95 { 196, 58}, 96 { 195, 55}, 97 { 194, 53}, 98 { 193, 50}, 99 { 192, 48}, 100 { 192, 45}, 101 { 191, 43}, 102 { 191, 40}, 103 { 190, 38}, 104 { 190, 35}, 105 { 189, 33}, 106 { 188, 30}, 107 { 187, 28}, 108 { 186, 25}, 109 { 185, 23}, 110 { 184, 20}, 111 { 183, 18}, 112 { 182, 15}, 113 { 181, 13}, 114 { 180, 10}, 115 { 179, 8}, 116 { 178, 5}, 117 { 0, 0}, 118 }; 119 120 struct battery_thresh sharpsl_battery_levels_noac[] = { 121 { 213, 100}, 122 { 212, 98}, 123 { 211, 95}, 124 { 210, 93}, 125 { 209, 90}, 126 { 208, 88}, 127 { 207, 85}, 128 { 206, 83}, 129 { 205, 80}, 130 { 204, 78}, 131 { 203, 75}, 132 { 202, 73}, 133 { 201, 70}, 134 { 200, 68}, 135 { 199, 65}, 136 { 198, 63}, 137 { 197, 60}, 138 { 196, 58}, 139 { 195, 55}, 140 { 194, 53}, 141 { 193, 50}, 142 { 192, 48}, 143 { 191, 45}, 144 { 190, 43}, 145 { 189, 40}, 146 { 188, 38}, 147 { 187, 35}, 148 { 186, 33}, 149 { 185, 30}, 150 { 184, 28}, 151 { 183, 25}, 152 { 182, 23}, 153 { 181, 20}, 154 { 180, 18}, 155 { 179, 15}, 156 { 178, 13}, 157 { 177, 10}, 158 { 176, 8}, 159 { 175, 5}, 160 { 0, 0}, 161 }; 162 163 /* MAX1111 Commands */ 164 #define MAXCTRL_PD0 (1u << 0) 165 #define MAXCTRL_PD1 (1u << 1) 166 #define MAXCTRL_SGL (1u << 2) 167 #define MAXCTRL_UNI (1u << 3) 168 #define MAXCTRL_SEL_SH 4 169 #define MAXCTRL_STR (1u << 7) 170 171 /* 172 * Read MAX1111 ADC 173 */ 174 int sharpsl_pm_pxa_read_max1111(int channel) 175 { 176 /* Ugly, better move this function into another module */ 177 if (machine_is_tosa()) 178 return 0; 179 180 extern int max1111_read_channel(int); 181 182 /* max1111 accepts channels from 0-3, however, 183 * it is encoded from 0-7 here in the code. 184 */ 185 return max1111_read_channel(channel >> 1); 186 } 187 188 static int get_percentage(int voltage) 189 { 190 int i = sharpsl_pm.machinfo->bat_levels - 1; 191 int bl_status = sharpsl_pm.machinfo->backlight_get_status ? sharpsl_pm.machinfo->backlight_get_status() : 0; 192 struct battery_thresh *thresh; 193 194 if (sharpsl_pm.charge_mode == CHRG_ON) 195 thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_acin_bl : sharpsl_pm.machinfo->bat_levels_acin; 196 else 197 thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_noac_bl : sharpsl_pm.machinfo->bat_levels_noac; 198 199 while (i > 0 && (voltage > thresh[i].voltage)) 200 i--; 201 202 return thresh[i].percentage; 203 } 204 205 static int get_apm_status(int voltage) 206 { 207 int low_thresh, high_thresh; 208 209 if (sharpsl_pm.charge_mode == CHRG_ON) { 210 high_thresh = sharpsl_pm.machinfo->status_high_acin; 211 low_thresh = sharpsl_pm.machinfo->status_low_acin; 212 } else { 213 high_thresh = sharpsl_pm.machinfo->status_high_noac; 214 low_thresh = sharpsl_pm.machinfo->status_low_noac; 215 } 216 217 if (voltage >= high_thresh) 218 return APM_BATTERY_STATUS_HIGH; 219 if (voltage >= low_thresh) 220 return APM_BATTERY_STATUS_LOW; 221 return APM_BATTERY_STATUS_CRITICAL; 222 } 223 224 void sharpsl_battery_kick(void) 225 { 226 schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); 227 } 228 EXPORT_SYMBOL(sharpsl_battery_kick); 229 230 231 static void sharpsl_battery_thread(struct work_struct *private_) 232 { 233 int voltage, percent, apm_status, i; 234 235 if (!sharpsl_pm.machinfo) 236 return; 237 238 sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE); 239 240 /* Corgi cannot confirm when battery fully charged so periodically kick! */ 241 if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON) 242 && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) 243 schedule_delayed_work(&toggle_charger, 0); 244 245 for (i = 0; i < 5; i++) { 246 voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); 247 if (voltage > 0) 248 break; 249 } 250 if (voltage <= 0) { 251 voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; 252 dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n"); 253 } 254 255 voltage = sharpsl_average_value(voltage); 256 apm_status = get_apm_status(voltage); 257 percent = get_percentage(voltage); 258 259 /* At low battery voltages, the voltage has a tendency to start 260 creeping back up so we try to avoid this here */ 261 if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) 262 || (apm_status == APM_BATTERY_STATUS_HIGH) 263 || percent <= sharpsl_pm.battstat.mainbat_percent) { 264 sharpsl_pm.battstat.mainbat_voltage = voltage; 265 sharpsl_pm.battstat.mainbat_status = apm_status; 266 sharpsl_pm.battstat.mainbat_percent = percent; 267 } 268 269 dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage, 270 sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); 271 272 /* Suspend if critical battery level */ 273 if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) 274 && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL) 275 && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) { 276 sharpsl_pm.flags |= SHARPSL_APM_QUEUED; 277 dev_err(sharpsl_pm.dev, "Fatal Off\n"); 278 apm_queue_event(APM_CRITICAL_SUSPEND); 279 } 280 281 schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME); 282 } 283 284 void sharpsl_pm_led(int val) 285 { 286 if (val == SHARPSL_LED_ERROR) { 287 dev_err(sharpsl_pm.dev, "Charging Error!\n"); 288 } else if (val == SHARPSL_LED_ON) { 289 dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); 290 led_trigger_event(sharpsl_charge_led_trigger, LED_FULL); 291 } else { 292 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); 293 led_trigger_event(sharpsl_charge_led_trigger, LED_OFF); 294 } 295 } 296 297 static void sharpsl_charge_on(void) 298 { 299 dev_dbg(sharpsl_pm.dev, "Turning Charger On\n"); 300 301 sharpsl_pm.full_count = 0; 302 sharpsl_pm.charge_mode = CHRG_ON; 303 schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250)); 304 schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500)); 305 } 306 307 static void sharpsl_charge_off(void) 308 { 309 dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n"); 310 311 sharpsl_pm.machinfo->charge(0); 312 sharpsl_pm_led(SHARPSL_LED_OFF); 313 sharpsl_pm.charge_mode = CHRG_OFF; 314 315 schedule_delayed_work(&sharpsl_bat, 0); 316 } 317 318 static void sharpsl_charge_error(void) 319 { 320 sharpsl_pm_led(SHARPSL_LED_ERROR); 321 sharpsl_pm.machinfo->charge(0); 322 sharpsl_pm.charge_mode = CHRG_ERROR; 323 } 324 325 static void sharpsl_charge_toggle(struct work_struct *private_) 326 { 327 dev_dbg(sharpsl_pm.dev, "Toggling Charger at time: %lx\n", jiffies); 328 329 if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { 330 sharpsl_charge_off(); 331 return; 332 } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) { 333 sharpsl_charge_error(); 334 return; 335 } 336 337 sharpsl_pm_led(SHARPSL_LED_ON); 338 sharpsl_pm.machinfo->charge(0); 339 mdelay(SHARPSL_CHARGE_WAIT_TIME); 340 sharpsl_pm.machinfo->charge(1); 341 342 sharpsl_pm.charge_start_time = jiffies; 343 } 344 345 static void sharpsl_ac_timer(unsigned long data) 346 { 347 int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); 348 349 dev_dbg(sharpsl_pm.dev, "AC Status: %d\n", acin); 350 351 sharpsl_average_clear(); 352 if (acin && (sharpsl_pm.charge_mode != CHRG_ON)) 353 sharpsl_charge_on(); 354 else if (sharpsl_pm.charge_mode == CHRG_ON) 355 sharpsl_charge_off(); 356 357 schedule_delayed_work(&sharpsl_bat, 0); 358 } 359 360 361 static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id) 362 { 363 /* Delay the event slightly to debounce */ 364 /* Must be a smaller delay than the chrg_full_isr below */ 365 mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); 366 367 return IRQ_HANDLED; 368 } 369 370 static void sharpsl_chrg_full_timer(unsigned long data) 371 { 372 dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies); 373 374 sharpsl_pm.full_count++; 375 376 if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { 377 dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n"); 378 if (sharpsl_pm.charge_mode == CHRG_ON) 379 sharpsl_charge_off(); 380 } else if (sharpsl_pm.full_count < 2) { 381 dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); 382 schedule_delayed_work(&toggle_charger, 0); 383 } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { 384 dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); 385 schedule_delayed_work(&toggle_charger, 0); 386 } else { 387 sharpsl_charge_off(); 388 sharpsl_pm.charge_mode = CHRG_DONE; 389 dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n"); 390 } 391 } 392 393 /* Charging Finished Interrupt (Not present on Corgi) */ 394 /* Can trigger at the same time as an AC status change so 395 delay until after that has been processed */ 396 static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id) 397 { 398 if (sharpsl_pm.flags & SHARPSL_SUSPENDED) 399 return IRQ_HANDLED; 400 401 /* delay until after any ac interrupt */ 402 mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500)); 403 404 return IRQ_HANDLED; 405 } 406 407 static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id) 408 { 409 int is_fatal = 0; 410 411 if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) { 412 dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n"); 413 is_fatal = 1; 414 } 415 416 if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) { 417 dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n"); 418 is_fatal = 1; 419 } 420 421 if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) { 422 sharpsl_pm.flags |= SHARPSL_APM_QUEUED; 423 apm_queue_event(APM_CRITICAL_SUSPEND); 424 } 425 426 return IRQ_HANDLED; 427 } 428 429 /* 430 * Maintain an average of the last 10 readings 431 */ 432 #define SHARPSL_CNV_VALUE_NUM 10 433 static int sharpsl_ad_index; 434 435 static void sharpsl_average_clear(void) 436 { 437 sharpsl_ad_index = 0; 438 } 439 440 static int sharpsl_average_value(int ad) 441 { 442 int i, ad_val = 0; 443 static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1]; 444 445 if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) { 446 sharpsl_ad_index = 0; 447 return ad; 448 } 449 450 sharpsl_ad[sharpsl_ad_index] = ad; 451 sharpsl_ad_index++; 452 if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) { 453 for (i = 0; i < (SHARPSL_CNV_VALUE_NUM-1); i++) 454 sharpsl_ad[i] = sharpsl_ad[i+1]; 455 sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1; 456 } 457 for (i = 0; i < sharpsl_ad_index; i++) 458 ad_val += sharpsl_ad[i]; 459 460 return ad_val / sharpsl_ad_index; 461 } 462 463 /* 464 * Take an array of 5 integers, remove the maximum and minimum values 465 * and return the average. 466 */ 467 static int get_select_val(int *val) 468 { 469 int i, j, k, temp, sum = 0; 470 471 /* Find MAX val */ 472 temp = val[0]; 473 j = 0; 474 for (i = 1; i < 5; i++) { 475 if (temp < val[i]) { 476 temp = val[i]; 477 j = i; 478 } 479 } 480 481 /* Find MIN val */ 482 temp = val[4]; 483 k = 4; 484 for (i = 3; i >= 0; i--) { 485 if (temp > val[i]) { 486 temp = val[i]; 487 k = i; 488 } 489 } 490 491 for (i = 0; i < 5; i++) 492 if (i != j && i != k) 493 sum += val[i]; 494 495 dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]); 496 497 return sum/3; 498 } 499 500 static int sharpsl_check_battery_temp(void) 501 { 502 int val, i, buff[5]; 503 504 /* Check battery temperature */ 505 for (i = 0; i < 5; i++) { 506 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); 507 sharpsl_pm.machinfo->measure_temp(1); 508 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); 509 buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP); 510 sharpsl_pm.machinfo->measure_temp(0); 511 } 512 513 val = get_select_val(buff); 514 515 dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val); 516 if (val > sharpsl_pm.machinfo->charge_on_temp) { 517 printk(KERN_WARNING "Not charging: temperature out of limits.\n"); 518 return -1; 519 } 520 521 return 0; 522 } 523 524 #ifdef CONFIG_PM 525 static int sharpsl_check_battery_voltage(void) 526 { 527 int val, i, buff[5]; 528 529 /* disable charge, enable discharge */ 530 sharpsl_pm.machinfo->charge(0); 531 sharpsl_pm.machinfo->discharge(1); 532 mdelay(SHARPSL_WAIT_DISCHARGE_ON); 533 534 if (sharpsl_pm.machinfo->discharge1) 535 sharpsl_pm.machinfo->discharge1(1); 536 537 /* Check battery voltage */ 538 for (i = 0; i < 5; i++) { 539 buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); 540 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); 541 } 542 543 if (sharpsl_pm.machinfo->discharge1) 544 sharpsl_pm.machinfo->discharge1(0); 545 546 sharpsl_pm.machinfo->discharge(0); 547 548 val = get_select_val(buff); 549 dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val); 550 551 if (val < sharpsl_pm.machinfo->charge_on_volt) 552 return -1; 553 554 return 0; 555 } 556 #endif 557 558 static int sharpsl_ac_check(void) 559 { 560 int temp, i, buff[5]; 561 562 for (i = 0; i < 5; i++) { 563 buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT); 564 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN); 565 } 566 567 temp = get_select_val(buff); 568 dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n", temp); 569 570 if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) { 571 dev_err(sharpsl_pm.dev, "Error: AC check failed: voltage %d.\n", temp); 572 return -1; 573 } 574 575 return 0; 576 } 577 578 #ifdef CONFIG_PM 579 static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state) 580 { 581 sharpsl_pm.flags |= SHARPSL_SUSPENDED; 582 flush_scheduled_work(); 583 584 if (sharpsl_pm.charge_mode == CHRG_ON) 585 sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; 586 else 587 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; 588 589 return 0; 590 } 591 592 static int sharpsl_pm_resume(struct platform_device *pdev) 593 { 594 /* Clear the reset source indicators as they break the bootloader upon reboot */ 595 RCSR = 0x0f; 596 sharpsl_average_clear(); 597 sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED; 598 sharpsl_pm.flags &= ~SHARPSL_SUSPENDED; 599 600 return 0; 601 } 602 603 static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) 604 { 605 dev_dbg(sharpsl_pm.dev, "Time is: %08x\n", RCNR); 606 607 dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n", sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); 608 /* not charging and AC-IN! */ 609 610 if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) { 611 dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); 612 sharpsl_pm.charge_mode = CHRG_OFF; 613 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; 614 sharpsl_off_charge_battery(); 615 } 616 617 sharpsl_pm.machinfo->presuspend(); 618 619 PEDR = 0xffffffff; /* clear it */ 620 621 sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE; 622 if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) { 623 RTSR &= RTSR_ALE; 624 RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND; 625 dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n", RTAR); 626 sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE; 627 } else if (alarm_enable) { 628 RTSR &= RTSR_ALE; 629 RTAR = alarm_time; 630 dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n", RTAR); 631 } else { 632 dev_dbg(sharpsl_pm.dev, "No alarms set.\n"); 633 } 634 635 pxa_pm_enter(state); 636 637 sharpsl_pm.machinfo->postsuspend(); 638 639 dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n", PEDR); 640 } 641 642 static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) 643 { 644 if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable)) { 645 if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) { 646 dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n"); 647 corgi_goto_sleep(alarm_time, alarm_enable, state); 648 return 1; 649 } 650 if (sharpsl_off_charge_battery()) { 651 dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n"); 652 corgi_goto_sleep(alarm_time, alarm_enable, state); 653 return 1; 654 } 655 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); 656 } 657 658 if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || 659 (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) { 660 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); 661 corgi_goto_sleep(alarm_time, alarm_enable, state); 662 return 1; 663 } 664 665 return 0; 666 } 667 668 static int corgi_pxa_pm_enter(suspend_state_t state) 669 { 670 unsigned long alarm_time = RTAR; 671 unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0); 672 673 dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n"); 674 675 corgi_goto_sleep(alarm_time, alarm_status, state); 676 677 while (corgi_enter_suspend(alarm_time, alarm_status, state)) 678 {} 679 680 if (sharpsl_pm.machinfo->earlyresume) 681 sharpsl_pm.machinfo->earlyresume(); 682 683 dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); 684 685 return 0; 686 } 687 688 /* 689 * Check for fatal battery errors 690 * Fatal returns -1 691 */ 692 static int sharpsl_fatal_check(void) 693 { 694 int buff[5], temp, i, acin; 695 696 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n"); 697 698 /* Check AC-Adapter */ 699 acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); 700 701 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { 702 sharpsl_pm.machinfo->charge(0); 703 udelay(100); 704 sharpsl_pm.machinfo->discharge(1); /* enable discharge */ 705 mdelay(SHARPSL_WAIT_DISCHARGE_ON); 706 } 707 708 if (sharpsl_pm.machinfo->discharge1) 709 sharpsl_pm.machinfo->discharge1(1); 710 711 /* Check battery : check inserting battery ? */ 712 for (i = 0; i < 5; i++) { 713 buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); 714 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); 715 } 716 717 if (sharpsl_pm.machinfo->discharge1) 718 sharpsl_pm.machinfo->discharge1(0); 719 720 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { 721 udelay(100); 722 sharpsl_pm.machinfo->charge(1); 723 sharpsl_pm.machinfo->discharge(0); 724 } 725 726 temp = get_select_val(buff); 727 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %ld\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT)); 728 729 if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) || 730 (!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt))) 731 return -1; 732 return 0; 733 } 734 735 static int sharpsl_off_charge_error(void) 736 { 737 dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n"); 738 sharpsl_pm.machinfo->charge(0); 739 sharpsl_pm_led(SHARPSL_LED_ERROR); 740 sharpsl_pm.charge_mode = CHRG_ERROR; 741 return 1; 742 } 743 744 /* 745 * Charging Control while suspended 746 * Return 1 - go straight to sleep 747 * Return 0 - sleep or wakeup depending on other factors 748 */ 749 static int sharpsl_off_charge_battery(void) 750 { 751 int time; 752 753 dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode); 754 755 if (sharpsl_pm.charge_mode == CHRG_OFF) { 756 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); 757 758 /* AC Check */ 759 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0)) 760 return sharpsl_off_charge_error(); 761 762 /* Start Charging */ 763 sharpsl_pm_led(SHARPSL_LED_ON); 764 sharpsl_pm.machinfo->charge(0); 765 mdelay(SHARPSL_CHARGE_WAIT_TIME); 766 sharpsl_pm.machinfo->charge(1); 767 768 sharpsl_pm.charge_mode = CHRG_ON; 769 sharpsl_pm.full_count = 0; 770 771 return 1; 772 } else if (sharpsl_pm.charge_mode != CHRG_ON) { 773 return 1; 774 } 775 776 if (sharpsl_pm.full_count == 0) { 777 int time; 778 779 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); 780 781 if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0)) 782 return sharpsl_off_charge_error(); 783 784 sharpsl_pm.machinfo->charge(0); 785 mdelay(SHARPSL_CHARGE_WAIT_TIME); 786 sharpsl_pm.machinfo->charge(1); 787 sharpsl_pm.charge_mode = CHRG_ON; 788 789 mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); 790 791 time = RCNR; 792 while (1) { 793 /* Check if any wakeup event had occurred */ 794 if (sharpsl_pm.machinfo->charger_wakeup() != 0) 795 return 0; 796 /* Check for timeout */ 797 if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) 798 return 1; 799 if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { 800 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n"); 801 sharpsl_pm.full_count++; 802 sharpsl_pm.machinfo->charge(0); 803 mdelay(SHARPSL_CHARGE_WAIT_TIME); 804 sharpsl_pm.machinfo->charge(1); 805 return 1; 806 } 807 } 808 } 809 810 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n"); 811 812 mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); 813 814 time = RCNR; 815 while (1) { 816 /* Check if any wakeup event had occurred */ 817 if (sharpsl_pm.machinfo->charger_wakeup()) 818 return 0; 819 /* Check for timeout */ 820 if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) { 821 if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) { 822 dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n"); 823 sharpsl_pm.full_count = 0; 824 } 825 sharpsl_pm.full_count++; 826 return 1; 827 } 828 if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { 829 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); 830 sharpsl_pm_led(SHARPSL_LED_OFF); 831 sharpsl_pm.machinfo->charge(0); 832 sharpsl_pm.charge_mode = CHRG_DONE; 833 return 1; 834 } 835 } 836 } 837 #else 838 #define sharpsl_pm_suspend NULL 839 #define sharpsl_pm_resume NULL 840 #endif 841 842 static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf) 843 { 844 return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_percent); 845 } 846 847 static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) 848 { 849 return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_voltage); 850 } 851 852 static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL); 853 static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL); 854 855 extern void (*apm_get_power_status)(struct apm_power_info *); 856 857 static void sharpsl_apm_get_power_status(struct apm_power_info *info) 858 { 859 info->ac_line_status = sharpsl_pm.battstat.ac_status; 860 861 if (sharpsl_pm.charge_mode == CHRG_ON) 862 info->battery_status = APM_BATTERY_STATUS_CHARGING; 863 else 864 info->battery_status = sharpsl_pm.battstat.mainbat_status; 865 866 info->battery_flag = (1 << info->battery_status); 867 info->battery_life = sharpsl_pm.battstat.mainbat_percent; 868 } 869 870 #ifdef CONFIG_PM 871 static struct platform_suspend_ops sharpsl_pm_ops = { 872 .prepare = pxa_pm_prepare, 873 .finish = pxa_pm_finish, 874 .enter = corgi_pxa_pm_enter, 875 .valid = suspend_valid_only_mem, 876 }; 877 #endif 878 879 static int __devinit sharpsl_pm_probe(struct platform_device *pdev) 880 { 881 int ret; 882 883 if (!pdev->dev.platform_data) 884 return -EINVAL; 885 886 sharpsl_pm.dev = &pdev->dev; 887 sharpsl_pm.machinfo = pdev->dev.platform_data; 888 sharpsl_pm.charge_mode = CHRG_OFF; 889 sharpsl_pm.flags = 0; 890 891 init_timer(&sharpsl_pm.ac_timer); 892 sharpsl_pm.ac_timer.function = sharpsl_ac_timer; 893 894 init_timer(&sharpsl_pm.chrg_full_timer); 895 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; 896 897 led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger); 898 899 sharpsl_pm.machinfo->init(); 900 901 gpio_request(sharpsl_pm.machinfo->gpio_acin, "AC IN"); 902 gpio_direction_input(sharpsl_pm.machinfo->gpio_acin); 903 gpio_request(sharpsl_pm.machinfo->gpio_batfull, "Battery Full"); 904 gpio_direction_input(sharpsl_pm.machinfo->gpio_batfull); 905 gpio_request(sharpsl_pm.machinfo->gpio_batlock, "Battery Lock"); 906 gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock); 907 908 /* Register interrupt handlers */ 909 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) { 910 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); 911 } 912 913 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) { 914 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); 915 } 916 917 if (sharpsl_pm.machinfo->gpio_fatal) { 918 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) { 919 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); 920 } 921 } 922 923 if (sharpsl_pm.machinfo->batfull_irq) { 924 /* Register interrupt handler. */ 925 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) { 926 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); 927 } 928 } 929 930 ret = device_create_file(&pdev->dev, &dev_attr_battery_percentage); 931 ret |= device_create_file(&pdev->dev, &dev_attr_battery_voltage); 932 if (ret != 0) 933 dev_warn(&pdev->dev, "Failed to register attributes (%d)\n", ret); 934 935 apm_get_power_status = sharpsl_apm_get_power_status; 936 937 #ifdef CONFIG_PM 938 suspend_set_ops(&sharpsl_pm_ops); 939 #endif 940 941 mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); 942 943 return 0; 944 } 945 946 static int sharpsl_pm_remove(struct platform_device *pdev) 947 { 948 suspend_set_ops(NULL); 949 950 device_remove_file(&pdev->dev, &dev_attr_battery_percentage); 951 device_remove_file(&pdev->dev, &dev_attr_battery_voltage); 952 953 led_trigger_unregister_simple(sharpsl_charge_led_trigger); 954 955 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); 956 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); 957 958 if (sharpsl_pm.machinfo->gpio_fatal) 959 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); 960 961 if (sharpsl_pm.machinfo->batfull_irq) 962 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); 963 964 gpio_free(sharpsl_pm.machinfo->gpio_batlock); 965 gpio_free(sharpsl_pm.machinfo->gpio_batfull); 966 gpio_free(sharpsl_pm.machinfo->gpio_acin); 967 968 if (sharpsl_pm.machinfo->exit) 969 sharpsl_pm.machinfo->exit(); 970 971 del_timer_sync(&sharpsl_pm.chrg_full_timer); 972 del_timer_sync(&sharpsl_pm.ac_timer); 973 974 return 0; 975 } 976 977 static struct platform_driver sharpsl_pm_driver = { 978 .probe = sharpsl_pm_probe, 979 .remove = sharpsl_pm_remove, 980 .suspend = sharpsl_pm_suspend, 981 .resume = sharpsl_pm_resume, 982 .driver = { 983 .name = "sharpsl-pm", 984 }, 985 }; 986 987 static int __devinit sharpsl_pm_init(void) 988 { 989 return platform_driver_register(&sharpsl_pm_driver); 990 } 991 992 static void sharpsl_pm_exit(void) 993 { 994 platform_driver_unregister(&sharpsl_pm_driver); 995 } 996 997 late_initcall(sharpsl_pm_init); 998 module_exit(sharpsl_pm_exit); 999