zapm.c revision 1.1 1 /* $NetBSD: zapm.c,v 1.1 2006/12/16 05:20:02 ober Exp $ */
2 /* $OpenBSD: zaurus_apm.c,v 1.12 2005/12/22 00:38:48 deraadt Exp $ */
3
4 /*
5 * Copyright (c) 2005 Uwe Stuehler <uwe (at) bsdx.de>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/kernel.h>
23 #include <sys/timeout.h>
24 #include <sys/conf.h>
25 #include <sys/sysctl.h>
26
27 #include <arm/xscale/pxa2x0reg.h>
28 #include <arm/xscale/pxa2x0var.h>
29 #include <arm/xscale/pxa2x0_apm.h>
30 #include <arm/xscale/pxa2x0_gpio.h>
31
32 #include <zaurus/dev/zaurus_scoopvar.h>
33 #include <zaurus/dev/zaurus_sspvar.h>
34 void zssp_init(void); /* XXX */
35
36 #include <zaurus/dev/zaurus_apm.h>
37
38 #if defined(APMDEBUG)
39 #define DPRINTF(x) printf x
40 #else
41 #define DPRINTF(x) /**/
42 #endif
43
44 struct zapm_softc {
45 struct pxa2x0_apm_softc sc;
46 struct timeout sc_poll;
47 struct timeval sc_lastbattchk;
48 int sc_suspended;
49 int sc_ac_on;
50 int sc_charging;
51 int sc_discharging;
52 int sc_batt_full;
53 int sc_batt_volt;
54 u_int sc_event;
55 };
56
57 int apm_match(struct device *, void *, void *);
58 void apm_attach(struct device *, struct device *, void *);
59
60 struct cfattach apm_pxaip_ca = {
61 sizeof (struct zapm_softc), apm_match, apm_attach
62 };
63 extern struct cfdriver apm_cd;
64
65 /* MAX1111 command word */
66 #define MAXCTRL_PD0 (1<<0)
67 #define MAXCTRL_PD1 (1<<1)
68 #define MAXCTRL_SGL (1<<2)
69 #define MAXCTRL_UNI (1<<3)
70 #define MAXCTRL_SEL_SHIFT 4
71 #define MAXCTRL_STR (1<<7)
72
73 /* MAX1111 ADC channels */
74 #define BATT_THM 2
75 #define BATT_AD 4
76 #define JK_VAD 6
77
78 /* battery-related GPIO pins */
79 #define GPIO_AC_IN_C3000 115 /* 0=AC connected */
80 #define GPIO_CHRG_CO_C3000 101 /* 1=battery full */
81 #define GPIO_BATT_COVER_C3000 90 /* 0=unlocked */
82
83 /*
84 * Battery-specific information
85 */
86
87 struct battery_threshold {
88 int bt_volt;
89 int bt_life;
90 int bt_state;
91 };
92
93 struct battery_info {
94 int bi_minutes; /* 100% life time */
95 const struct battery_threshold *bi_thres;
96 };
97
98 const struct battery_threshold zaurus_battery_life_c3000[] = {
99 #if 0
100 {224, 125, APM_BATT_HIGH}, /* XXX unverified */
101 #endif
102 {194, 100, APM_BATT_HIGH},
103 {188, 75, APM_BATT_HIGH},
104 {184, 50, APM_BATT_HIGH},
105 {180, 25, APM_BATT_LOW},
106 {178, 5, APM_BATT_LOW},
107 {0, 0, APM_BATT_CRITICAL},
108 };
109
110 const struct battery_info zaurus_battery_c3000 = {
111 180 /* minutes; pessimistic estimate */,
112 zaurus_battery_life_c3000
113 };
114
115 const struct battery_info *zaurus_main_battery = &zaurus_battery_c3000;
116
117 /* Restart charging this many times before accepting BATT_FULL. */
118 #define MIN_BATT_FULL 2
119
120 /* Discharge 100 ms before reading the voltage if AC is connected. */
121 #define DISCHARGE_TIMEOUT (hz / 10)
122
123 /* Check battery voltage and "kick charging" every minute. */
124 const struct timeval zapm_battchkrate = { 60, 0 };
125
126 /* Prototypes */
127
128 #if 0
129 void zapm_shutdown(void *);
130 #endif
131 int zapm_acintr(void *);
132 int zapm_bcintr(void *);
133 int zapm_ac_on(void);
134 int max1111_adc_value(int);
135 int max1111_adc_value_avg(int, int);
136 #if 0
137 int zapm_jkvad_voltage(void);
138 int zapm_batt_temp(void);
139 #endif
140 int zapm_batt_volt(void);
141 int zapm_batt_state(int);
142 int zapm_batt_life(int);
143 int zapm_batt_minutes(int);
144 void zapm_enable_charging(struct zapm_softc *, int);
145 int zapm_charge_complete(struct zapm_softc *);
146 void zapm_poll(void *);
147 int zapm_get_event(struct pxa2x0_apm_softc *, u_int *);
148 void zapm_power_info(struct pxa2x0_apm_softc *, struct apm_power_info *);
149 void zapm_suspend(struct pxa2x0_apm_softc *);
150 int zapm_resume(struct pxa2x0_apm_softc *);
151 int pxa2x0_setperf(int);
152 int pxa2x0_cpuspeed(int *);
153
154
155 int
156 apm_match(struct device *parent, void *match, void *aux)
157 {
158 return (1);
159 }
160
161 void
162 apm_attach(struct device *parent, struct device *self, void *aux)
163 {
164 struct zapm_softc *sc = (struct zapm_softc *)self;
165
166 pxa2x0_gpio_set_function(GPIO_AC_IN_C3000, GPIO_IN);
167 pxa2x0_gpio_set_function(GPIO_CHRG_CO_C3000, GPIO_IN);
168 pxa2x0_gpio_set_function(GPIO_BATT_COVER_C3000, GPIO_IN);
169
170 (void)pxa2x0_gpio_intr_establish(GPIO_AC_IN_C3000,
171 IST_EDGE_BOTH, IPL_BIO, zapm_acintr, sc, "apm_ac");
172 (void)pxa2x0_gpio_intr_establish(GPIO_BATT_COVER_C3000,
173 IST_EDGE_BOTH, IPL_BIO, zapm_bcintr, sc, "apm_bc");
174
175 sc->sc_event = APM_NOEVENT;
176 sc->sc.sc_get_event = zapm_get_event;
177 sc->sc.sc_power_info = zapm_power_info;
178 sc->sc.sc_suspend = zapm_suspend;
179 sc->sc.sc_resume = zapm_resume;
180
181 timeout_set(&sc->sc_poll, &zapm_poll, sc);
182
183 /* Get initial battery voltage. */
184 zapm_enable_charging(sc, 0);
185 if (zapm_ac_on()) {
186 /* C3000: discharge 100 ms when AC is on. */
187 scoop_discharge_battery(1);
188 delay(100000);
189 }
190 sc->sc_batt_volt = zapm_batt_volt();
191 scoop_discharge_battery(0);
192
193 pxa2x0_apm_attach_sub(&sc->sc);
194
195 #if 0
196 (void)shutdownhook_establish(zapm_shutdown, NULL);
197 #endif
198
199 cpu_setperf = pxa2x0_setperf;
200 cpu_cpuspeed = pxa2x0_cpuspeed;
201 }
202
203 #if 0
204 void
205 zapm_shutdown(void *v)
206 {
207 struct zapm_softc *sc = v;
208
209 zapm_enable_charging(sc, 0);
210 }
211 #endif
212
213 int
214 zapm_acintr(void *v)
215 {
216 zapm_poll(v);
217 return (1);
218 }
219
220 int
221 zapm_bcintr(void *v)
222 {
223 zapm_poll(v);
224 return (1);
225 }
226
227 int
228 zapm_ac_on(void)
229 {
230 return (!pxa2x0_gpio_get_bit(GPIO_AC_IN_C3000));
231 }
232
233 int
234 max1111_adc_value(int chan)
235 {
236
237 return ((int)zssp_ic_send(ZSSP_IC_MAX1111, MAXCTRL_PD0 |
238 MAXCTRL_PD1 | MAXCTRL_SGL | MAXCTRL_UNI |
239 (chan << MAXCTRL_SEL_SHIFT) | MAXCTRL_STR));
240 }
241
242 /* XXX simplify */
243 int
244 max1111_adc_value_avg(int chan, int pause)
245 {
246 int val[5];
247 int i, j, k, x;
248 int sum = 0;
249
250 for (i = 0; i < 5; i++) {
251 val[i] = max1111_adc_value(chan);
252 if (i != 4)
253 delay(pause * 1000);
254 }
255
256 x = val[0];
257 j = 0;
258 for (i = 1; i < 5; i++) {
259 if (x < val[i]) {
260 x = val[i];
261 j = i;
262 }
263 }
264
265 x = val[4];
266 k = 4;
267 for (i = 3; i >= 0; i--) {
268 if (x > val[i]) {
269 x = val[i];
270 k = i;
271 }
272 }
273
274 for (i = 0; i < 5; i++) {
275 if (i == j || i == k)
276 continue;
277 sum += val[i];
278 }
279
280 return (sum / 3);
281 }
282
283 #if 0
284 /*
285 * Return the voltage available for charging. This will be zero,
286 * unless A/C power is connected.
287 */
288 int
289 zapm_jkvad_voltage(void)
290 {
291
292 return (max1111_adc_value_avg(JK_VAD, 10));
293 }
294
295 int
296 zapm_batt_temp(void)
297 {
298 int temp;
299
300 scoop_battery_temp_adc(1);
301 delay(10000);
302 temp = max1111_adc_value_avg(BATT_THM, 1);
303 scoop_battery_temp_adc(0);
304
305 return (temp);
306 }
307 #endif
308
309 int
310 zapm_batt_volt(void)
311 {
312
313 return (max1111_adc_value_avg(BATT_AD, 10));
314 }
315
316 int
317 zapm_batt_state(int volt)
318 {
319 const struct battery_threshold *bthr;
320 int i;
321
322 bthr = zaurus_main_battery->bi_thres;
323
324 for (i = 0; bthr[i].bt_volt > 0; i++)
325 if (bthr[i].bt_volt <= volt)
326 break;
327
328 return (bthr[i].bt_state);
329 }
330
331 int
332 zapm_batt_life(int volt)
333 {
334 const struct battery_threshold *bthr;
335 int i;
336
337 bthr = zaurus_main_battery->bi_thres;
338
339 for (i = 0; bthr[i].bt_volt > 0; i++)
340 if (bthr[i].bt_volt <= volt)
341 break;
342
343 if (i == 0)
344 return (bthr[i].bt_life);
345
346 return (bthr[i].bt_life +
347 ((volt - bthr[i].bt_volt) * 100) /
348 (bthr[i-1].bt_volt - bthr[i].bt_volt) *
349 (bthr[i-1].bt_life - bthr[i].bt_life) / 100);
350 }
351
352 int
353 zapm_batt_minutes(int life)
354 {
355
356 return (zaurus_main_battery->bi_minutes * life / 100);
357 }
358
359 void
360 zapm_enable_charging(struct zapm_softc *sc, int enable)
361 {
362
363 scoop_discharge_battery(0);
364 scoop_charge_battery(enable, 0);
365 scoop_led_set(SCOOP_LED_ORANGE, enable);
366 }
367
368 /*
369 * Return non-zero if the charge complete signal indicates that the
370 * battery is fully charged. Restart charging to clear this signal.
371 */
372 int
373 zapm_charge_complete(struct zapm_softc *sc)
374 {
375
376 if (sc->sc_charging && sc->sc_batt_full < MIN_BATT_FULL) {
377 if (pxa2x0_gpio_get_bit(GPIO_CHRG_CO_C3000) != 0) {
378 if (++sc->sc_batt_full < MIN_BATT_FULL) {
379 DPRINTF(("battery almost full\n"));
380 zapm_enable_charging(sc, 0);
381 delay(15000);
382 zapm_enable_charging(sc, 1);
383 }
384 } else if (sc->sc_batt_full > 0) {
385 /* false alarm */
386 sc->sc_batt_full = 0;
387 zapm_enable_charging(sc, 0);
388 delay(15000);
389 zapm_enable_charging(sc, 1);
390 }
391 }
392
393 return (sc->sc_batt_full >= MIN_BATT_FULL);
394 }
395
396 /*
397 * Poll power-management related GPIO inputs, update battery life
398 * in softc, and/or control battery charging.
399 */
400 void
401 zapm_poll(void *v)
402 {
403 struct zapm_softc *sc = v;
404 int ac_on;
405 int bc_lock;
406 int charging;
407 int volt;
408 int s;
409
410 s = splhigh();
411
412 /* Check positition of battery compartment lock switch. */
413 bc_lock = pxa2x0_gpio_get_bit(GPIO_BATT_COVER_C3000) ? 1 : 0;
414
415 /* Stop discharging. */
416 if (sc->sc_discharging) {
417 sc->sc_discharging = 0;
418 volt = zapm_batt_volt();
419 ac_on = zapm_ac_on();
420 charging = 0;
421 DPRINTF(("zapm_poll: discharge off volt %d\n", volt));
422 } else {
423 ac_on = zapm_ac_on();
424 charging = sc->sc_charging;
425 volt = sc->sc_batt_volt;
426 }
427
428 /* Start or stop charging as necessary. */
429 if (ac_on && bc_lock) {
430 if (charging) {
431 if (zapm_charge_complete(sc)) {
432 DPRINTF(("zapm_poll: batt full\n"));
433 charging = 0;
434 zapm_enable_charging(sc, 0);
435 }
436 } else if (!zapm_charge_complete(sc)) {
437 charging = 1;
438 volt = zapm_batt_volt();
439 zapm_enable_charging(sc, 1);
440 DPRINTF(("zapm_poll: start charging volt %d\n", volt));
441 }
442 } else {
443 if (charging) {
444 charging = 0;
445 zapm_enable_charging(sc, 0);
446 timerclear(&sc->sc_lastbattchk);
447 DPRINTF(("zapm_poll: stop charging\n"));
448 }
449 sc->sc_batt_full = 0;
450 }
451
452 /*
453 * Restart charging once in a while. Discharge a few milliseconds
454 * before updating the voltage in our softc if A/C is connected.
455 */
456 if (bc_lock && ratecheck(&sc->sc_lastbattchk, &zapm_battchkrate)) {
457 if (sc->sc_suspended) {
458 DPRINTF(("zapm_poll: suspended %lu %lu\n",
459 sc->sc_lastbattchk.tv_sec,
460 pxa2x0_rtc_getsecs()));
461 if (charging) {
462 zapm_enable_charging(sc, 0);
463 delay(15000);
464 zapm_enable_charging(sc, 1);
465 pxa2x0_rtc_setalarm(pxa2x0_rtc_getsecs() +
466 zapm_battchkrate.tv_sec + 1);
467 }
468 } else if (ac_on && sc->sc_batt_full == 0) {
469 DPRINTF(("zapm_poll: discharge on\n"));
470 if (charging)
471 zapm_enable_charging(sc, 0);
472 sc->sc_discharging = 1;
473 scoop_discharge_battery(1);
474 timeout_add(&sc->sc_poll, DISCHARGE_TIMEOUT);
475 } else if (!ac_on) {
476 volt = zapm_batt_volt();
477 DPRINTF(("zapm_poll: volt %d\n", volt));
478 }
479 }
480
481 /* Update the cached power state in our softc. */
482 if (ac_on != sc->sc_ac_on || charging != sc->sc_charging ||
483 volt != sc->sc_batt_volt) {
484 sc->sc_ac_on = ac_on;
485 sc->sc_charging = charging;
486 sc->sc_batt_volt = volt;
487 if (sc->sc_event == APM_NOEVENT)
488 sc->sc_event = APM_POWER_CHANGE;
489 }
490
491 /* Detect battery low conditions. */
492 if (!ac_on) {
493 if (zapm_batt_life(volt) < 5)
494 sc->sc_event = APM_BATTERY_LOW;
495 if (zapm_batt_state(volt) == APM_BATT_CRITICAL)
496 sc->sc_event = APM_CRIT_SUSPEND_REQ;
497 }
498
499 #ifdef APMDEBUG
500 if (sc->sc_event != APM_NOEVENT)
501 DPRINTF(("zapm_poll: power event %d\n", sc->sc_event));
502 #endif
503 splx(s);
504 }
505
506 /*
507 * apm_thread() calls this routine approximately once per second.
508 */
509 int
510 zapm_get_event(struct pxa2x0_apm_softc *pxa_sc, u_int *typep)
511 {
512 struct zapm_softc *sc = (struct zapm_softc *)pxa_sc;
513 int s;
514
515 s = splsoftclock();
516
517 /* Don't interfere with discharging. */
518 if (sc->sc_discharging)
519 *typep = sc->sc_event;
520 else if (sc->sc_event == APM_NOEVENT) {
521 zapm_poll(sc);
522 *typep = sc->sc_event;
523 }
524 sc->sc_event = APM_NOEVENT;
525
526 splx(s);
527 return (*typep == APM_NOEVENT);
528 }
529
530 /*
531 * Return power status to the generic APM driver.
532 */
533 void
534 zapm_power_info(struct pxa2x0_apm_softc *pxa_sc, struct apm_power_info *power)
535 {
536 struct zapm_softc *sc = (struct zapm_softc *)pxa_sc;
537 int s;
538 int ac_on;
539 int volt;
540 int charging;
541
542 s = splsoftclock();
543 ac_on = sc->sc_ac_on;
544 volt = sc->sc_batt_volt;
545 charging = sc->sc_charging;
546 splx(s);
547
548 power->ac_state = ac_on ? APM_AC_ON : APM_AC_OFF;
549 if (charging)
550 power->battery_state = APM_BATT_CHARGING;
551 else
552 power->battery_state = zapm_batt_state(volt);
553
554 power->battery_life = zapm_batt_life(volt);
555 power->minutes_left = zapm_batt_minutes(power->battery_life);
556 }
557
558 /*
559 * Called before suspending when all powerhooks are done.
560 */
561 void
562 zapm_suspend(struct pxa2x0_apm_softc *pxa_sc)
563 {
564 struct zapm_softc *sc = (struct zapm_softc *)pxa_sc;
565
566 /* Poll in suspended mode and forget the discharge timeout. */
567 sc->sc_suspended = 1;
568 timeout_del(&sc->sc_poll);
569
570 /* Make sure charging is enabled and RTC alarm is set. */
571 timerclear(&sc->sc_lastbattchk);
572
573 zapm_poll(sc);
574
575 #if 0
576 pxa2x0_rtc_setalarm(pxa2x0_rtc_getsecs() + 5);
577 #endif
578 pxa2x0_wakeup_config(PXA2X0_WAKEUP_ALL, 1);
579 }
580
581 /*
582 * Called after wake-up from suspend with interrupts still disabled,
583 * before any powerhooks are done.
584 */
585 int
586 zapm_resume(struct pxa2x0_apm_softc *pxa_sc)
587 {
588 struct zapm_softc *sc = (struct zapm_softc *)pxa_sc;
589 int a, b;
590 u_int wsrc;
591 int wakeup = 0;
592
593 /* C3000 */
594 a = pxa2x0_gpio_get_bit(97) ? 1 : 0;
595 b = pxa2x0_gpio_get_bit(96) ? 2 : 0;
596
597 wsrc = pxa2x0_wakeup_status();
598
599 /* Resume only if the lid is not closed. */
600 if ((a | b) != 3 && (wsrc & PXA2X0_WAKEUP_POWERON) != 0) {
601 int timeout = 100; /* 10 ms */
602 /* C3000 */
603 while (timeout-- > 0 && pxa2x0_gpio_get_bit(95) != 0) {
604 if (timeout == 0) {
605 wakeup = 1;
606 break;
607 }
608 delay(100);
609 }
610 }
611
612 /* Initialize the SSP unit before using the MAX1111 again. */
613 zssp_init();
614
615 zapm_poll(sc);
616
617 if (wakeup) {
618 /* Resume normal polling. */
619 sc->sc_suspended = 0;
620
621 pxa2x0_rtc_setalarm(0);
622 } else {
623 #if 0
624 DPRINTF(("zapm_resume: suspended %lu %lu\n",
625 sc->sc_lastbattchk.tv_sec, pxa2x0_rtc_getsecs()));
626 pxa2x0_rtc_setalarm(pxa2x0_rtc_getsecs() + 5);
627 #endif
628 }
629
630 return (wakeup);
631 }
632
633 void
634 zapm_poweroff(void)
635 {
636 struct pxa2x0_apm_softc *sc;
637
638 KASSERT(apm_cd.cd_ndevs > 0 && apm_cd.cd_devs[0] != NULL);
639 sc = apm_cd.cd_devs[0];
640
641 dopowerhooks(PWR_SUSPEND);
642
643 /* XXX enable charging during suspend */
644
645 /* XXX keep power LED state during suspend */
646
647 /* XXX do the same thing for GPIO 43 (BTTXD) */
648
649 /* XXX scoop power down */
650
651 /* XXX set PGSRn and GPDRn */
652
653 pxa2x0_wakeup_config(PXA2X0_WAKEUP_ALL, 1);
654
655 do {
656 pxa2x0_apm_sleep(sc);
657 }
658 while (!zapm_resume(sc));
659
660 zapm_restart();
661
662 /* NOTREACHED */
663 dopowerhooks(PWR_RESUME);
664 }
665
666 /*
667 * Do a GPIO reset, immediately causing the processor to begin the normal
668 * boot sequence. See 2.7 Reset in the PXA27x Developer's Manual for the
669 * summary of effects of this kind of reset.
670 */
671 void
672 zapm_restart(void)
673 {
674 if (apm_cd.cd_ndevs > 0 && apm_cd.cd_devs[0] != NULL) {
675 struct pxa2x0_apm_softc *sc = apm_cd.cd_devs[0];
676 int rv;
677
678 /*
679 * Reduce the ROM Delay Next Access and ROM Delay First
680 * Access times for synchronous flash connected to nCS1.
681 */
682 rv = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh,
683 MEMCTL_MSC0);
684 if ((rv & 0xffff0000) == 0x7ff00000)
685 bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh,
686 MEMCTL_MSC0, (rv & 0xffff) | 0x7ee00000);
687 }
688
689 /* External reset circuit presumably asserts nRESET_GPIO. */
690 pxa2x0_gpio_set_function(89, GPIO_OUT | GPIO_SET);
691 delay(1000000);
692 }
693