blob: 6538c06a31ccda375269677b3e9ef0634d9df241 [file] [log] [blame]
Marcin Bukat28d54c62010-04-26 21:40:16 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Marcin Bukat082c7d32010-10-22 12:28:43 +00008 * $Id$
Marcin Bukat28d54c62010-04-26 21:40:16 +00009 *
10 * Copyright (C) 2010 Marcin Bukat
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22
23#include <stdlib.h>
24#include <stdio.h>
25#include "inttypes.h"
26#include "string.h"
27#include "cpu.h"
28#include "system.h"
29#include "lcd.h"
Michael Sevakis4ea4cdf2014-08-08 02:28:11 -040030#include "../kernel-internal.h"
Marcin Bukat28d54c62010-04-26 21:40:16 +000031#include "storage.h"
Michael Sevakis7d1a47c2013-08-05 22:02:45 -040032#include "file_internal.h"
Marcin Bukat28d54c62010-04-26 21:40:16 +000033#include "usb.h"
34#include "disk.h"
35#include "font.h"
36#include "adc.h"
37#include "backlight.h"
38#include "backlight-target.h"
39#include "button.h"
40#include "panic.h"
41#include "power.h"
42#include "powermgmt.h"
43#include "file.h"
44
45#include "common.h"
Marcin Bukat0b296912012-03-04 15:34:29 +010046#include "rb-loader.h"
47#include "loader_strerror.h"
Rafaël Carré5d236b22010-05-27 09:41:46 +000048#include "version.h"
Marcin Bukat28d54c62010-04-26 21:40:16 +000049
50#include <stdarg.h>
51
52/* Maximum allowed firmware image size. 10MB is more than enough */
53#define MAX_LOADSIZE (10*1024*1024)
54
55#define DRAM_START 0x31000000
56
57#define BOOTMENU_TIMEOUT (10*HZ)
58#define BOOTMENU_OPTIONS 3
59
Marcin Bukat69fa42d2010-05-04 11:16:17 +000060#define EVENT_NONE 0x00
61#define EVENT_ON 0x01
62#define EVENT_AC 0x02
63#define EVENT_USB 0x04
Marcin Bukata73102f2010-12-06 10:24:29 +000064#define EVENT_RTC 0x08
Marcin Bukat69fa42d2010-05-04 11:16:17 +000065
Marcin Bukat28d54c62010-04-26 21:40:16 +000066/* From common.c */
67extern int line;
68static const char *bootmenu_options[] = {
69 "Boot rockbox",
70 "Boot MPIO firmware",
71 "Shutdown"
72};
73
74enum option_t {
75 rockbox,
76 mpio_firmware,
77 shutdown
78};
79
80int usb_screen(void)
81{
82 return 0;
83}
84
Marcin Bukata73102f2010-12-06 10:24:29 +000085/* return true if charger is present */
Marcin Bukat69fa42d2010-05-04 11:16:17 +000086static inline bool _charger_inserted(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +000087{
88 return (GPIO1_READ & (1<<14)) ? false : true;
89}
90
Marcin Bukata73102f2010-12-06 10:24:29 +000091/* returns true if end of charge condition is reached */
Marcin Bukat69fa42d2010-05-04 11:16:17 +000092static inline bool _battery_full(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +000093{
94 return (GPIO_READ & (1<<30)) ? true : false;
95}
96
Marcin Bukata73102f2010-12-06 10:24:29 +000097#ifdef MPIO_HD300
98/* returns true if startup is due to RTC alarm */
99static inline bool _rtc_alarm(void)
100{
101 if ( (GPIO1_READ & (1<<4)) && (GPIO1_READ & (1<<5)) )
102 return false;
103
104 return true;
105}
106#endif
107
Marcin Bukat28d54c62010-04-26 21:40:16 +0000108/* Reset the cookie for the crt0 crash check */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000109static inline void __reset_cookie(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000110{
111 asm(" move.l #0,%d0");
112 asm(" move.l %d0,0x10017ffc");
113}
114
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000115static void start_rockbox(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000116{
117 adc_close();
118 asm(" move.w #0x2700,%sr");
119 __reset_cookie();
120 asm(" move.l %0,%%d0" :: "i"(DRAM_START));
121 asm(" movec.l %d0,%vbr");
122 asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START));
123 asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4)));
124 asm(" jmp (%a0)");
125}
126
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000127static void start_mpio_firmware(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000128{
129 asm(" move.w #0x2700,%sr");
130 __reset_cookie();
131 asm(" movec.l %d0,%vbr");
132 asm(" move.l 0,%sp");
133 asm(" jmp 8");
134}
135
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000136static void __shutdown(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000137{
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000138 if (_charger_inserted())
139 /* if AC power do nothing */
140 return;
141
Marcin Bukat28d54c62010-04-26 21:40:16 +0000142 /* We need to gracefully spin down the disk to prevent clicks. */
143 if (ide_powered())
144 {
145 /* Make sure ATA has been initialized. */
146 storage_init();
147
148 /* And put the disk into sleep immediately. */
149 storage_sleepnow();
150 }
151
152 /* Backlight OFF */
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100153 backlight_hw_off();
Marcin Bukat28d54c62010-04-26 21:40:16 +0000154 __reset_cookie();
155
Marcin Bukat28d54c62010-04-26 21:40:16 +0000156 power_off();
Marcin Bukat28d54c62010-04-26 21:40:16 +0000157}
158
159/* Print the battery voltage (and a warning message). */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000160static void check_battery(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000161{
162
163 int battery_voltage, batt_int, batt_frac;
164
Thomas Martitzc1bd9b02012-01-03 23:44:38 +0000165 battery_voltage = _battery_voltage();
Marcin Bukat28d54c62010-04-26 21:40:16 +0000166 batt_int = battery_voltage / 1000;
167 batt_frac = (battery_voltage % 1000) / 10;
168
169 printf("Battery: %d.%02dV", batt_int, batt_frac);
170
171 if (battery_voltage <= 3500)
172 {
173 printf("WARNING! BATTERY LOW!!");
174 sleep(HZ*2);
175 }
176
177}
178
179
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000180static void lcd_putstring_centered(const char *string)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000181{
182 int w,h;
183 font_getstringsize(string, &w, &h, FONT_SYSFIXED);
184 lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, string);
185}
186
Marcin Bukata73102f2010-12-06 10:24:29 +0000187/* This function initializes ATA driver, mounts partitions,
188 * loads rockbox image from disk to ram and finally
189 * jumps to entry point in ram
190 */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000191static void rb_boot(void)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000192{
193 int rc;
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000194
Marcin Bukat57484bd2010-07-06 17:30:10 +0000195 /* boost to speedup rb image loading */
196 cpu_boost(true);
197
Marcin Bukata73102f2010-12-06 10:24:29 +0000198 reset_screen();
Marcin Bukat15a0a3c2010-11-28 23:10:09 +0000199 printf("Rockbox boot loader");
Michael Sevakis95a4c3a2014-08-28 10:26:45 -0400200 printf("Version %s", rbversion);
Marcin Bukat15a0a3c2010-11-28 23:10:09 +0000201
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000202 rc = storage_init();
203 if(rc)
Marcin Bukat0b296912012-03-04 15:34:29 +0100204 error(EATA, rc, true);
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000205
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400206 filesystem_init();
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000207
208 rc = disk_mount_all();
Marcin Bukat0b296912012-03-04 15:34:29 +0100209 if (rc <= 0)
210 error(EDISK, rc, true);
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000211
212 printf("Loading firmware");
213
214 rc = load_firmware((unsigned char *)DRAM_START,
215 BOOTFILE, MAX_LOADSIZE);
216
Marcin Bukat0b296912012-03-04 15:34:29 +0100217 if (rc <= EFILE_EMPTY)
218 error(EBOOTFILE, rc, true);
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000219
Marcin Bukat57484bd2010-07-06 17:30:10 +0000220 cpu_boost(false);
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000221 start_rockbox();
222}
223
Marcin Bukata73102f2010-12-06 10:24:29 +0000224/* This function prints small bootmenu where
225 * you can choose to boot OF, rockbox or just shutdown
226 */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000227static void bootmenu(void)
228{
Marcin Bukat28d54c62010-04-26 21:40:16 +0000229 enum option_t i;
230 enum option_t option = rockbox;
231 int button;
232 const char select[] = "->";
233 long start_tick = current_tick;
234
235 /* backbone of menu */
236 /* run the loader */
237 printf("Rockbox boot loader");
Michael Sevakis95a4c3a2014-08-28 10:26:45 -0400238 printf("Ver: %s", rbversion);
Marcin Bukat28d54c62010-04-26 21:40:16 +0000239
240 check_battery();
241
242 printf("");
243 printf("=========================");
244
245 line += BOOTMENU_OPTIONS+2; /* skip lines */
246
247 printf("=========================");
248 printf("");
Marcin Bukat650a2942010-11-02 10:51:04 +0000249 printf(" [FF] [REW] to move ");
Marcin Bukat28d54c62010-04-26 21:40:16 +0000250 printf(" [PLAY] to confirm ");
251
252 /* content of menu and keys handling */
253 while (TIME_BEFORE(current_tick,start_tick + BOOTMENU_TIMEOUT))
254 {
255 /* Draw the menu. */
256 line = 6; /* move below header */
257
258 for (i=0;i<BOOTMENU_OPTIONS;i++)
259 {
260 if (i != option)
261 printf(" %s",bootmenu_options[i]);
262 else
263 printf("%s %s",select,bootmenu_options[i]);
264 }
265
266 line = 15;
267
268 printf("Time left: %ds",(BOOTMENU_TIMEOUT -
269 (current_tick - start_tick))/HZ);
270
271 lcd_update();
272
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000273 button = BUTTON_NONE;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000274 button = button_get_w_tmo(HZ);
275
276 switch (button)
277 {
Marcin Bukat650a2942010-11-02 10:51:04 +0000278 case BUTTON_REW:
Marcin Bukat9a248922010-11-26 23:28:08 +0000279#ifdef MPIO_HD200
Marcin Bukat650a2942010-11-02 10:51:04 +0000280 case BUTTON_RC_REW:
Marcin Bukat9a248922010-11-26 23:28:08 +0000281#endif
Marcin Bukat28d54c62010-04-26 21:40:16 +0000282 if (option > rockbox)
283 option--;
284 else
285 option = shutdown;
286 break;
287
Marcin Bukat650a2942010-11-02 10:51:04 +0000288 case BUTTON_FF:
Marcin Bukat9a248922010-11-26 23:28:08 +0000289#ifdef MPIO_HD200
Marcin Bukat650a2942010-11-02 10:51:04 +0000290 case BUTTON_RC_FF:
Marcin Bukat9a248922010-11-26 23:28:08 +0000291#endif
Marcin Bukat28d54c62010-04-26 21:40:16 +0000292 if (option < shutdown)
293 option++;
294 else
295 option = rockbox;
296 break;
297
298 case BUTTON_PLAY:
Marcin Bukat9a248922010-11-26 23:28:08 +0000299#ifdef MPIO_HD200
Marcin Bukat57484bd2010-07-06 17:30:10 +0000300 case BUTTON_RC_PLAY:
Marcin Bukat28d54c62010-04-26 21:40:16 +0000301 case (BUTTON_PLAY|BUTTON_REC):
Marcin Bukat9a248922010-11-26 23:28:08 +0000302#endif
Marcin Bukat28d54c62010-04-26 21:40:16 +0000303 reset_screen();
304
305 switch (option)
306 {
307 case rockbox:
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000308 rb_boot();
Marcin Bukat28d54c62010-04-26 21:40:16 +0000309 break;
310
311 case mpio_firmware:
312 start_mpio_firmware();
313 break;
314
315 default:
Marcin Bukata73102f2010-12-06 10:24:29 +0000316 __shutdown();
Marcin Bukat28d54c62010-04-26 21:40:16 +0000317 break;
318 }
319 }
320}
321/* timeout */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000322}
323
324void main(void)
325{
326 /* messages */
327 const char usb_connect_msg[] = "Bootloader USB mode";
328 const char charging_msg[] = "Charging...";
329 const char complete_msg[] = "Charging complete";
Marcin Bukat28d54c62010-04-26 21:40:16 +0000330
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000331 /* helper variable for messages */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000332 bool blink_toggle = false;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000333
Marcin Bukat28d54c62010-04-26 21:40:16 +0000334 int button;
Marcin Bukat67feb812011-01-03 13:11:48 +0000335
336 /* hold status variables
337 * this two must have different
338 * values in the begining
339 */
340 bool hold = false;
341 bool last_hold = true;
342
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000343 unsigned int event = EVENT_NONE;
344 unsigned int last_event = EVENT_NONE;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000345
Marcin Bukat57484bd2010-07-06 17:30:10 +0000346 /* this is default mode after power_init() */
347 bool high_current_charging = true;
348
Marcin Bukat38edf672010-10-22 12:11:58 +0000349 /* setup GPIOs related to power functions */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000350 power_init();
351
352 system_init();
353 kernel_init();
354
Marcin Bukat38edf672010-10-22 12:11:58 +0000355 /* run at 45MHz */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000356 set_cpu_frequency(CPUFREQ_NORMAL);
Marcin Bukat28d54c62010-04-26 21:40:16 +0000357
Marcin Bukat38edf672010-10-22 12:11:58 +0000358 /* IRQs are needed by button driver */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000359 enable_irq();
Marcin Bukat38edf672010-10-22 12:11:58 +0000360
Marcin Bukat28d54c62010-04-26 21:40:16 +0000361 lcd_init();
362
Marcin Bukat67feb812011-01-03 13:11:48 +0000363 /* setup font system */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000364 font_init();
365 lcd_setfont(FONT_SYSFIXED);
Marcin Bukat38edf672010-10-22 12:11:58 +0000366
Marcin Bukat67feb812011-01-03 13:11:48 +0000367 /* buttons reading init */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000368 adc_init();
369 button_init();
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000370
Marcin Bukat28d54c62010-04-26 21:40:16 +0000371 usb_init();
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000372 cpu_idle_mode(true);
Marcin Bukat28d54c62010-04-26 21:40:16 +0000373
Marcin Bukat67feb812011-01-03 13:11:48 +0000374 /* lowlevel init only */
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100375 backlight_hw_init();
Marcin Bukat67feb812011-01-03 13:11:48 +0000376
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000377 /* Handle wakeup event. Possibilities are:
Marcin Bukata73102f2010-12-06 10:24:29 +0000378 * RTC alarm (HD300)
379 * ON button (PLAY or RC_PLAY on HD200)
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000380 * USB insert
381 * AC charger plug
382 */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000383 while(1)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000384 {
Marcin Bukat67feb812011-01-03 13:11:48 +0000385 /* check hold status */
386 hold = button_hold();
387
388 /* backlight handling
389 * change only on hold toggle */
390 if ( hold != last_hold )
391 {
392 if ( hold )
Marcin Bukat200ca662015-01-12 13:25:14 +0100393 backlight_hw_off();
Marcin Bukat67feb812011-01-03 13:11:48 +0000394 else
Marcin Bukat200ca662015-01-12 13:25:14 +0100395 backlight_hw_on();
Marcin Bukat67feb812011-01-03 13:11:48 +0000396
397 last_hold = hold;
398 }
399
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000400 /* read buttons */
401 event = EVENT_NONE;
402 button = button_get_w_tmo(HZ);
Marcin Bukat28d54c62010-04-26 21:40:16 +0000403
Marcin Bukat9a248922010-11-26 23:28:08 +0000404 if ( (button & BUTTON_PLAY)
405#ifdef MPIO_HD200
406 || (button & BUTTON_RC_PLAY)
407#endif
408 )
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000409 event |= EVENT_ON;
410
411 if ( usb_detect() == USB_INSERTED )
412 event |= EVENT_USB;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000413
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000414 if ( _charger_inserted() )
415 event |= EVENT_AC;
Marcin Bukata73102f2010-12-06 10:24:29 +0000416#ifdef MPIO_HD300
417 if ( _rtc_alarm() )
418 event |= EVENT_RTC;
419#endif
Marcin Bukat67feb812011-01-03 13:11:48 +0000420
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000421 reset_screen();
422 switch (event)
Marcin Bukat28d54c62010-04-26 21:40:16 +0000423 {
Marcin Bukata73102f2010-12-06 10:24:29 +0000424#ifdef MPIO_HD300
425 case EVENT_RTC:
426 case (EVENT_RTC | EVENT_ON):
427 /* start regardles of buttons state */
428 rb_boot();
429 break;
430#endif
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000431 case EVENT_ON:
432 case (EVENT_ON | EVENT_AC):
433 /* hold is handled in button driver */
Marcin Bukata73102f2010-12-06 10:24:29 +0000434 cpu_idle_mode(false);
435 ide_power_enable(true);
Marcin Bukat28d54c62010-04-26 21:40:16 +0000436
Marcin Bukata73102f2010-12-06 10:24:29 +0000437 if (button & BUTTON_REC)
438 bootmenu();
439 else
440 rb_boot();
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000441
Marcin Bukat28d54c62010-04-26 21:40:16 +0000442 break;
443
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000444 case EVENT_AC:
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000445 /* AC plug in */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000446 if (!(last_event & EVENT_AC))
Marcin Bukatcd879712010-06-14 10:42:45 +0000447 {
Marcin Bukat57484bd2010-07-06 17:30:10 +0000448 /* reset charging circuit */
Marcin Bukatcd879712010-06-14 10:42:45 +0000449 and_l(~(1<<23), &GPIO_ENABLE);
450 }
Marcin Bukat28d54c62010-04-26 21:40:16 +0000451
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000452 /* USB unplug */
453 if (last_event & EVENT_USB)
Marcin Bukatcd879712010-06-14 10:42:45 +0000454 {
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000455 usb_enable(false);
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000456 sleep(HZ);
Marcin Bukatcd879712010-06-14 10:42:45 +0000457 ide_power_enable(false);
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000458 sleep(HZ);
Marcin Bukatcd879712010-06-14 10:42:45 +0000459 }
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000460
Marcin Bukat28d54c62010-04-26 21:40:16 +0000461 if(!_battery_full())
462 {
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000463 if (blink_toggle)
464 lcd_putstring_centered(charging_msg);
465
Marcin Bukat28d54c62010-04-26 21:40:16 +0000466 blink_toggle = !blink_toggle;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000467 }
Marcin Bukat57484bd2010-07-06 17:30:10 +0000468 else /* end of charge condition */
Marcin Bukat28d54c62010-04-26 21:40:16 +0000469 {
Marcin Bukat57484bd2010-07-06 17:30:10 +0000470 /* put LTC1733 into shutdown mode */
471 or_l((1<<23), &GPIO_ENABLE);
472
473 if (high_current_charging)
474 {
475 /* switch to low current mode */
476 and_l(~(1<<15), &GPIO_OUT);
477
478 /* reset charging circuit */
479 and_l(~(1<<23), &GPIO_ENABLE);
480
481 high_current_charging = false;
482 }
483 else
484 {
485 lcd_putstring_centered(complete_msg);
486 }
Marcin Bukat28d54c62010-04-26 21:40:16 +0000487 }
Marcin Bukat28d54c62010-04-26 21:40:16 +0000488 check_battery();
489 break;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000490
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000491 case EVENT_USB:
492 case (EVENT_USB | EVENT_AC):
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000493 /* AC plug in while in USB mode */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000494 if (!(last_event & EVENT_AC))
Marcin Bukatcd879712010-06-14 10:42:45 +0000495 {
Marcin Bukat57484bd2010-07-06 17:30:10 +0000496 /* reset charger circuit */
Marcin Bukatcd879712010-06-14 10:42:45 +0000497 and_l(~(1<<23), &GPIO_ENABLE);
498 }
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000499
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000500 /* USB plug in */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000501 if (!(last_event & EVENT_USB))
502 {
503 /* init USB */
504 ide_power_enable(true);
505 sleep(HZ/20);
Marcin Bukat0358e7b2010-12-09 11:31:08 +0000506 ata_enable(false);
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000507 usb_enable(true);
508 }
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000509
510 /* display blinking USB indicator */
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000511 line = 0;
512
513 if (blink_toggle)
514 lcd_putstring_centered(usb_connect_msg);
515
516 check_battery();
517 blink_toggle = !blink_toggle;
518 storage_spin();
519 break;
520
521 default:
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000522 /* USB unplug */
Marcin Bukat57484bd2010-07-06 17:30:10 +0000523 if (last_event & EVENT_USB)
524 {
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000525 /* disable USB */
Marcin Bukat57484bd2010-07-06 17:30:10 +0000526 usb_enable(false);
Marcin Bukat0358e7b2010-12-09 11:31:08 +0000527 ata_enable(true);
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000528 sleep(HZ);
Marcin Bukat57484bd2010-07-06 17:30:10 +0000529 ide_power_enable(false);
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000530 sleep(HZ);
Marcin Bukat57484bd2010-07-06 17:30:10 +0000531 }
532
Marcin Bukat78d54fa2010-07-09 09:12:51 +0000533 /* spurious wakeup ?*/
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000534 __shutdown();
535 break;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000536 }
Marcin Bukat28d54c62010-04-26 21:40:16 +0000537 lcd_update();
Marcin Bukat69fa42d2010-05-04 11:16:17 +0000538 last_event = event;
Marcin Bukat28d54c62010-04-26 21:40:16 +0000539 }
540
Marcin Bukat28d54c62010-04-26 21:40:16 +0000541}
542
543/* These functions are present in the firmware library, but we reimplement
544 them here because the originals do a lot more than we want */
545void screen_dump(void)
546{
547}