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