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