17 #include <linux/module.h>
18 #include <linux/kernel.h>
32 #include <mach/regs-rtc.h>
38 #define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000))
39 #define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000))
40 #define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000))
41 #define SHARPSL_BATCHK_TIME_SUSPEND (60*10)
43 #define SHARPSL_WAIT_CO_TIME 15
44 #define SHARPSL_WAIT_DISCHARGE_ON 100
45 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10
46 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10
47 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10
48 #define SHARPSL_CHARGE_WAIT_TIME 15
49 #define SHARPSL_CHARGE_CO_CHECK_TIME 5
50 #define SHARPSL_CHARGE_RETRY_CNT 1
56 static int sharpsl_off_charge_battery(
void);
57 static int sharpsl_check_battery_voltage(
void);
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_);
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)
178 if (machine_is_tosa())
187 static int get_percentage(
int voltage)
190 int bl_status =
sharpsl_pm.machinfo->backlight_get_status ?
sharpsl_pm.machinfo->backlight_get_status() : 0;
194 thresh = bl_status ?
sharpsl_pm.machinfo->bat_levels_acin_bl :
sharpsl_pm.machinfo->bat_levels_acin;
196 thresh = bl_status ?
sharpsl_pm.machinfo->bat_levels_noac_bl :
sharpsl_pm.machinfo->bat_levels_noac;
198 while (i > 0 && (voltage > thresh[i].voltage))
204 static int get_apm_status(
int voltage)
206 int low_thresh, high_thresh;
209 high_thresh =
sharpsl_pm.machinfo->status_high_acin;
210 low_thresh =
sharpsl_pm.machinfo->status_low_acin;
212 high_thresh =
sharpsl_pm.machinfo->status_high_noac;
213 low_thresh =
sharpsl_pm.machinfo->status_low_noac;
216 if (voltage >= high_thresh)
218 if (voltage >= low_thresh)
230 static void sharpsl_battery_thread(
struct work_struct *private_)
244 for (i = 0; i < 5; i++) {
250 voltage =
sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
254 voltage = sharpsl_average_value(voltage);
255 apm_status = get_apm_status(voltage);
256 percent = get_percentage(voltage);
262 || percent <=
sharpsl_pm.battstat.mainbat_percent) {
264 sharpsl_pm.battstat.mainbat_status = apm_status;
268 dev_dbg(
sharpsl_pm.dev,
"Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage,
296 static void sharpsl_charge_on(
void)
306 static void sharpsl_charge_off(
void)
317 static void sharpsl_charge_error(
void)
324 static void sharpsl_charge_toggle(
struct work_struct *private_)
329 sharpsl_charge_off();
331 }
else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
332 sharpsl_charge_error();
344 static void sharpsl_ac_timer(
unsigned long data)
350 sharpsl_average_clear();
354 sharpsl_charge_off();
369 static void sharpsl_chrg_full_timer(
unsigned long data)
378 sharpsl_charge_off();
383 dev_dbg(
sharpsl_pm.dev,
"Charge Full: Interrupt generated too slowly - retry.\n");
386 sharpsl_charge_off();
395 static irqreturn_t sharpsl_chrg_full_isr(
int irq,
void *dev_id)
406 static irqreturn_t sharpsl_fatal_isr(
int irq,
void *dev_id)
431 #define SHARPSL_CNV_VALUE_NUM 10
432 static int sharpsl_ad_index;
434 static void sharpsl_average_clear(
void)
436 sharpsl_ad_index = 0;
439 static int sharpsl_average_value(
int ad)
445 sharpsl_ad_index = 0;
449 sharpsl_ad[sharpsl_ad_index] = ad;
453 sharpsl_ad[i] = sharpsl_ad[i+1];
456 for (i = 0; i < sharpsl_ad_index; i++)
457 ad_val += sharpsl_ad[i];
459 return ad_val / sharpsl_ad_index;
466 static int get_select_val(
int *
val)
473 for (i = 1; i < 5; i++) {
483 for (i = 3; i >= 0; i--) {
490 for (i = 0; i < 5; i++)
491 if (i != j && i != k)
494 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]);
499 static int sharpsl_check_battery_temp(
void)
504 for (i = 0; i < 5; i++) {
512 val = get_select_val(buff);
515 if (val >
sharpsl_pm.machinfo->charge_on_temp) {
524 static int sharpsl_check_battery_voltage(
void)
537 for (i = 0; i < 5; i++) {
547 val = get_select_val(buff);
550 if (val < sharpsl_pm.machinfo->charge_on_volt)
557 static int sharpsl_ac_check(
void)
559 int temp,
i, buff[5];
561 for (i = 0; i < 5; i++) {
566 temp = get_select_val(buff);
569 if ((temp >
sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) {
596 sharpsl_average_clear();
603 static void corgi_goto_sleep(
unsigned long alarm_time,
unsigned int alarm_enable,
suspend_state_t state)
614 sharpsl_off_charge_battery();
627 }
else if (alarm_enable) {
642 static int corgi_enter_suspend(
unsigned long alarm_time,
unsigned int alarm_enable,
suspend_state_t state)
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);
650 if (sharpsl_off_charge_battery()) {
652 corgi_goto_sleep(alarm_time, alarm_enable, state);
661 corgi_goto_sleep(alarm_time, alarm_enable, state);
670 unsigned long alarm_time =
RTAR;
675 corgi_goto_sleep(alarm_time, alarm_status, state);
677 while (corgi_enter_suspend(alarm_time, alarm_status, state))
688 static int sharpsl_off_charge_error(
void)
702 static int sharpsl_off_charge_battery(
void)
712 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
713 return sharpsl_off_charge_error();
734 if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
735 return sharpsl_off_charge_error();
747 if (
sharpsl_pm.machinfo->charger_wakeup() != 0)
753 dev_dbg(
sharpsl_pm.dev,
"Offline Charger: Charge full occurred. Retrying to check\n");
775 dev_dbg(
sharpsl_pm.dev,
"Offline Charger: Not charged sufficiently. Retrying.\n");
791 #define sharpsl_pm_suspend NULL
792 #define sharpsl_pm_resume NULL
805 static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show,
NULL);
827 .enter = corgi_pxa_pm_enter,
836 if (!pdev->
dev.platform_data)
845 sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
848 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
890 dev_warn(&pdev->
dev,
"Failed to register attributes (%d)\n", ret);
935 .probe = sharpsl_pm_probe,
936 .remove = sharpsl_pm_remove,
940 .name =
"sharpsl-pm",
944 static int __devinit sharpsl_pm_init(
void)
949 static void sharpsl_pm_exit(
void)