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_delayed_work_sync(&toggle_charger); 583 flush_delayed_work_sync(&sharpsl_bat); 584 585 if (sharpsl_pm.charge_mode == CHRG_ON) 586 sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; 587 else 588 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; 589 590 return 0; 591 } 592 593 static int sharpsl_pm_resume(struct platform_device *pdev) 594 { 595 /* Clear the reset source indicators as they break the bootloader upon reboot */ 596 RCSR = 0x0f; 597 sharpsl_average_clear(); 598 sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED; 599 sharpsl_pm.flags &= ~SHARPSL_SUSPENDED; 600 601 return 0; 602 } 603 604 static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) 605 { 606 dev_dbg(sharpsl_pm.dev, "Time is: %08x\n", RCNR); 607 608 dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n", sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); 609 /* not charging and AC-IN! */ 610 611 if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) { 612 dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); 613 sharpsl_pm.charge_mode = CHRG_OFF; 614 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; 615 sharpsl_off_charge_battery(); 616 } 617 618 sharpsl_pm.machinfo->presuspend(); 619 620 PEDR = 0xffffffff; /* clear it */ 621 622 sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE; 623 if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) { 624 RTSR &= RTSR_ALE; 625 RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND; 626 dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n", RTAR); 627 sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE; 628 } else if (alarm_enable) { 629 RTSR &= RTSR_ALE; 630 RTAR = alarm_time; 631 dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n", RTAR); 632 } else { 633 dev_dbg(sharpsl_pm.dev, "No alarms set.\n"); 634 } 635 636 pxa_pm_enter(state); 637 638 sharpsl_pm.machinfo->postsuspend(); 639 640 dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n", PEDR); 641 } 642 643 static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) 644 { 645 if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable)) { 646 if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) { 647 dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n"); 648 corgi_goto_sleep(alarm_time, alarm_enable, state); 649 return 1; 650 } 651 if (sharpsl_off_charge_battery()) { 652 dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n"); 653 corgi_goto_sleep(alarm_time, alarm_enable, state); 654 return 1; 655 } 656 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); 657 } 658 659 if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || 660 (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) { 661 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); 662 corgi_goto_sleep(alarm_time, alarm_enable, state); 663 return 1; 664 } 665 666 return 0; 667 } 668 669 static int corgi_pxa_pm_enter(suspend_state_t state) 670 { 671 unsigned long alarm_time = RTAR; 672 unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0); 673 674 dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n"); 675 676 corgi_goto_sleep(alarm_time, alarm_status, state); 677 678 while (corgi_enter_suspend(alarm_time, alarm_status, state)) 679 {} 680 681 if (sharpsl_pm.machinfo->earlyresume) 682 sharpsl_pm.machinfo->earlyresume(); 683 684 dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); 685 686 return 0; 687 } 688 689 /* 690 * Check for fatal battery errors 691 * Fatal returns -1 692 */ 693 static int sharpsl_fatal_check(void) 694 { 695 int buff[5], temp, i, acin; 696 697 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n"); 698 699 /* Check AC-Adapter */ 700 acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); 701 702 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { 703 sharpsl_pm.machinfo->charge(0); 704 udelay(100); 705 sharpsl_pm.machinfo->discharge(1); /* enable discharge */ 706 mdelay(SHARPSL_WAIT_DISCHARGE_ON); 707 } 708 709 if (sharpsl_pm.machinfo->discharge1) 710 sharpsl_pm.machinfo->discharge1(1); 711 712 /* Check battery : check inserting battery ? */ 713 for (i = 0; i < 5; i++) { 714 buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); 715 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); 716 } 717 718 if (sharpsl_pm.machinfo->discharge1) 719 sharpsl_pm.machinfo->discharge1(0); 720 721 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { 722 udelay(100); 723 sharpsl_pm.machinfo->charge(1); 724 sharpsl_pm.machinfo->discharge(0); 725 } 726 727 temp = get_select_val(buff); 728 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)); 729 730 if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) || 731 (!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt))) 732 return -1; 733 return 0; 734 } 735 736 static int sharpsl_off_charge_error(void) 737 { 738 dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n"); 739 sharpsl_pm.machinfo->charge(0); 740 sharpsl_pm_led(SHARPSL_LED_ERROR); 741 sharpsl_pm.charge_mode = CHRG_ERROR; 742 return 1; 743 } 744 745 /* 746 * Charging Control while suspended 747 * Return 1 - go straight to sleep 748 * Return 0 - sleep or wakeup depending on other factors 749 */ 750 static int sharpsl_off_charge_battery(void) 751 { 752 int time; 753 754 dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode); 755 756 if (sharpsl_pm.charge_mode == CHRG_OFF) { 757 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); 758 759 /* AC Check */ 760 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0)) 761 return sharpsl_off_charge_error(); 762 763 /* Start Charging */ 764 sharpsl_pm_led(SHARPSL_LED_ON); 765 sharpsl_pm.machinfo->charge(0); 766 mdelay(SHARPSL_CHARGE_WAIT_TIME); 767 sharpsl_pm.machinfo->charge(1); 768 769 sharpsl_pm.charge_mode = CHRG_ON; 770 sharpsl_pm.full_count = 0; 771 772 return 1; 773 } else if (sharpsl_pm.charge_mode != CHRG_ON) { 774 return 1; 775 } 776 777 if (sharpsl_pm.full_count == 0) { 778 int time; 779 780 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); 781 782 if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0)) 783 return sharpsl_off_charge_error(); 784 785 sharpsl_pm.machinfo->charge(0); 786 mdelay(SHARPSL_CHARGE_WAIT_TIME); 787 sharpsl_pm.machinfo->charge(1); 788 sharpsl_pm.charge_mode = CHRG_ON; 789 790 mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); 791 792 time = RCNR; 793 while (1) { 794 /* Check if any wakeup event had occurred */ 795 if (sharpsl_pm.machinfo->charger_wakeup() != 0) 796 return 0; 797 /* Check for timeout */ 798 if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) 799 return 1; 800 if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { 801 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n"); 802 sharpsl_pm.full_count++; 803 sharpsl_pm.machinfo->charge(0); 804 mdelay(SHARPSL_CHARGE_WAIT_TIME); 805 sharpsl_pm.machinfo->charge(1); 806 return 1; 807 } 808 } 809 } 810 811 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n"); 812 813 mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); 814 815 time = RCNR; 816 while (1) { 817 /* Check if any wakeup event had occurred */ 818 if (sharpsl_pm.machinfo->charger_wakeup()) 819 return 0; 820 /* Check for timeout */ 821 if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) { 822 if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) { 823 dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n"); 824 sharpsl_pm.full_count = 0; 825 } 826 sharpsl_pm.full_count++; 827 return 1; 828 } 829 if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { 830 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); 831 sharpsl_pm_led(SHARPSL_LED_OFF); 832 sharpsl_pm.machinfo->charge(0); 833 sharpsl_pm.charge_mode = CHRG_DONE; 834 return 1; 835 } 836 } 837 } 838 #else 839 #define sharpsl_pm_suspend NULL 840 #define sharpsl_pm_resume NULL 841 #endif 842 843 static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf) 844 { 845 return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_percent); 846 } 847 848 static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) 849 { 850 return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_voltage); 851 } 852 853 static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL); 854 static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL); 855 856 extern void (*apm_get_power_status)(struct apm_power_info *); 857 858 static void sharpsl_apm_get_power_status(struct apm_power_info *info) 859 { 860 info->ac_line_status = sharpsl_pm.battstat.ac_status; 861 862 if (sharpsl_pm.charge_mode == CHRG_ON) 863 info->battery_status = APM_BATTERY_STATUS_CHARGING; 864 else 865 info->battery_status = sharpsl_pm.battstat.mainbat_status; 866 867 info->battery_flag = (1 << info->battery_status); 868 info->battery_life = sharpsl_pm.battstat.mainbat_percent; 869 } 870 871 #ifdef CONFIG_PM 872 static const struct platform_suspend_ops sharpsl_pm_ops = { 873 .prepare = pxa_pm_prepare, 874 .finish = pxa_pm_finish, 875 .enter = corgi_pxa_pm_enter, 876 .valid = suspend_valid_only_mem, 877 }; 878 #endif 879 880 static int __devinit sharpsl_pm_probe(struct platform_device *pdev) 881 { 882 int ret; 883 884 if (!pdev->dev.platform_data) 885 return -EINVAL; 886 887 sharpsl_pm.dev = &pdev->dev; 888 sharpsl_pm.machinfo = pdev->dev.platform_data; 889 sharpsl_pm.charge_mode = CHRG_OFF; 890 sharpsl_pm.flags = 0; 891 892 init_timer(&sharpsl_pm.ac_timer); 893 sharpsl_pm.ac_timer.function = sharpsl_ac_timer; 894 895 init_timer(&sharpsl_pm.chrg_full_timer); 896 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; 897 898 led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger); 899 900 sharpsl_pm.machinfo->init(); 901 902 gpio_request(sharpsl_pm.machinfo->gpio_acin, "AC IN"); 903 gpio_direction_input(sharpsl_pm.machinfo->gpio_acin); 904 gpio_request(sharpsl_pm.machinfo->gpio_batfull, "Battery Full"); 905 gpio_direction_input(sharpsl_pm.machinfo->gpio_batfull); 906 gpio_request(sharpsl_pm.machinfo->gpio_batlock, "Battery Lock"); 907 gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock); 908 909 /* Register interrupt handlers */ 910 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)) { 911 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); 912 } 913 914 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) { 915 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); 916 } 917 918 if (sharpsl_pm.machinfo->gpio_fatal) { 919 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) { 920 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); 921 } 922 } 923 924 if (sharpsl_pm.machinfo->batfull_irq) { 925 /* Register interrupt handler. */ 926 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) { 927 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); 928 } 929 } 930 931 ret = device_create_file(&pdev->dev, &dev_attr_battery_percentage); 932 ret |= device_create_file(&pdev->dev, &dev_attr_battery_voltage); 933 if (ret != 0) 934 dev_warn(&pdev->dev, "Failed to register attributes (%d)\n", ret); 935 936 apm_get_power_status = sharpsl_apm_get_power_status; 937 938 #ifdef CONFIG_PM 939 suspend_set_ops(&sharpsl_pm_ops); 940 #endif 941 942 mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); 943 944 return 0; 945 } 946 947 static int sharpsl_pm_remove(struct platform_device *pdev) 948 { 949 suspend_set_ops(NULL); 950 951 device_remove_file(&pdev->dev, &dev_attr_battery_percentage); 952 device_remove_file(&pdev->dev, &dev_attr_battery_voltage); 953 954 led_trigger_unregister_simple(sharpsl_charge_led_trigger); 955 956 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); 957 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); 958 959 if (sharpsl_pm.machinfo->gpio_fatal) 960 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); 961 962 if (sharpsl_pm.machinfo->batfull_irq) 963 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); 964 965 gpio_free(sharpsl_pm.machinfo->gpio_batlock); 966 gpio_free(sharpsl_pm.machinfo->gpio_batfull); 967 gpio_free(sharpsl_pm.machinfo->gpio_acin); 968 969 if (sharpsl_pm.machinfo->exit) 970 sharpsl_pm.machinfo->exit(); 971 972 del_timer_sync(&sharpsl_pm.chrg_full_timer); 973 del_timer_sync(&sharpsl_pm.ac_timer); 974 975 return 0; 976 } 977 978 static struct platform_driver sharpsl_pm_driver = { 979 .probe = sharpsl_pm_probe, 980 .remove = sharpsl_pm_remove, 981 .suspend = sharpsl_pm_suspend, 982 .resume = sharpsl_pm_resume, 983 .driver = { 984 .name = "sharpsl-pm", 985 }, 986 }; 987 988 static int __devinit sharpsl_pm_init(void) 989 { 990 return platform_driver_register(&sharpsl_pm_driver); 991 } 992 993 static void sharpsl_pm_exit(void) 994 { 995 platform_driver_unregister(&sharpsl_pm_driver); 996 } 997 998 late_initcall(sharpsl_pm_init); 999 module_exit(sharpsl_pm_exit); 1000