blob: fd878ac5f6f34791cd02a72e7465a8e371494fca [file] [log] [blame]
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "config.h"
20
21#include <stdlib.h>
22#include <stdio.h>
Miika Pekkarinene1eb91b2006-08-09 12:04:13 +000023#include "inttypes.h"
24#include "string.h"
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +000025#include "cpu.h"
26#include "system.h"
27#include "lcd.h"
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +000028#include "lcd-remote.h"
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +000029#include "kernel.h"
30#include "thread.h"
31#include "ata.h"
Linus Nielsen Feltzing01917ec2005-12-06 12:12:29 +000032#include "usb.h"
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +000033#include "disk.h"
34#include "font.h"
35#include "adc.h"
36#include "backlight.h"
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +000037#include "backlight-target.h"
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +000038#include "button.h"
39#include "panic.h"
40#include "power.h"
41#include "file.h"
Linus Nielsen Feltzingd2ca7fc2005-07-12 05:25:42 +000042#include "uda1380.h"
Miika Pekkarinene1eb91b2006-08-09 12:04:13 +000043#include "eeprom_settings.h"
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +000044
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +000045#include "pcf50606.h"
46
47#include <stdarg.h>
48
Linus Nielsen Feltzing62c768c2005-07-09 07:46:42 +000049#define DRAM_START 0x31000000
50
Miika Pekkarinen886c3022007-01-13 08:16:02 +000051#ifdef HAVE_EEPROM_SETTINGS
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +000052static bool recovery_mode = false;
Miika Pekkarinen886c3022007-01-13 08:16:02 +000053#endif
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +000054
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +000055int line = 0;
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +000056#ifdef HAVE_REMOTE_LCD
57int remote_line = 0;
58#endif
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +000059
60int usb_screen(void)
61{
62 return 0;
63}
64
Linus Nielsen Feltzinga2e8cf72005-07-15 07:42:25 +000065char version[] = APPSVERSION;
66
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +000067char printfbuf[256];
68
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +000069void reset_screen(void)
70{
71 lcd_clear_display();
72 line = 0;
73#ifdef HAVE_REMOTE_LCD
74 lcd_remote_clear_display();
75 remote_line = 0;
76#endif
77}
78
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +000079void printf(const char *format, ...)
80{
81 int len;
82 unsigned char *ptr;
83 va_list ap;
84 va_start(ap, format);
85
86 ptr = printfbuf;
87 len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
88 va_end(ap);
89
90 lcd_puts(0, line++, ptr);
91 lcd_update();
92 if(line >= 16)
93 line = 0;
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +000094#ifdef HAVE_REMOTE_LCD
95 lcd_remote_puts(0, remote_line++, ptr);
96 lcd_remote_update();
97 if(remote_line >= 8)
98 remote_line = 0;
99#endif
100}
101
102/* Reset the cookie for the crt0 crash check */
103inline void __reset_cookie(void)
104{
105 asm(" move.l #0,%d0");
106 asm(" move.l %d0,0x10017ffc");
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000107}
108
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000109void start_iriver_fw(void)
110{
111 asm(" move.w #0x2700,%sr");
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000112 __reset_cookie();
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000113 asm(" movec.l %d0,%vbr");
114 asm(" move.l 0,%sp");
115 asm(" lea.l 8,%a0");
116 asm(" jmp (%a0)");
117}
118
119int load_firmware(void)
120{
121 int fd;
122 int rc;
123 int len;
124 unsigned long chksum;
Linus Nielsen Feltzinga75f0e52005-07-09 09:04:37 +0000125 char model[5];
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000126 unsigned long sum;
127 int i;
Linus Nielsen Feltzinge82df4e2005-07-08 15:09:44 +0000128 unsigned char *buf = (unsigned char *)DRAM_START;
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000129
Linus Nielsen Feltzingbbe919b2005-11-19 01:33:28 +0000130 fd = open("/.rockbox/" BOOTFILE, O_RDONLY);
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000131 if(fd < 0)
Linus Nielsen Feltzingbbe919b2005-11-19 01:33:28 +0000132 {
133 fd = open("/" BOOTFILE, O_RDONLY);
134 if(fd < 0)
135 return -1;
136 }
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000137
Linus Nielsen Feltzingb8a00d22005-02-10 21:55:48 +0000138 len = filesize(fd) - 8;
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000139
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000140 printf("Length: %x", len);
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000141
Linus Nielsen Feltzing2a77d3a2005-01-28 13:27:58 +0000142 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000143
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000144 rc = read(fd, &chksum, 4);
145 if(rc < 4)
146 return -2;
147
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000148 printf("Checksum: %x", chksum);
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000149
Linus Nielsen Feltzinga75f0e52005-07-09 09:04:37 +0000150 rc = read(fd, model, 4);
151 if(rc < 4)
152 return -3;
153
154 model[4] = 0;
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000155
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000156 printf("Model name: %s", model);
Linus Nielsen Feltzinga75f0e52005-07-09 09:04:37 +0000157 lcd_update();
158
Linus Nielsen Feltzing2a77d3a2005-01-28 13:27:58 +0000159 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000160
161 rc = read(fd, buf, len);
162 if(rc < len)
163 return -4;
164
165 close(fd);
166
Linus Nielsen Feltzinge82df4e2005-07-08 15:09:44 +0000167 sum = MODEL_NUMBER;
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000168
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000169 for(i = 0;i < len;i++) {
170 sum += buf[i];
171 }
172
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000173 printf("Sum: %x", sum);
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000174
175 if(sum != chksum)
176 return -5;
177
178 return 0;
179}
180
181void start_firmware(void)
182{
183 asm(" move.w #0x2700,%sr");
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000184 __reset_cookie();
Linus Nielsen Feltzinge82df4e2005-07-08 15:09:44 +0000185 asm(" move.l %0,%%d0" :: "i"(DRAM_START));
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000186 asm(" movec.l %d0,%vbr");
Linus Nielsen Feltzinge82df4e2005-07-08 15:09:44 +0000187 asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START));
188 asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4)));
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000189 asm(" jmp (%a0)");
190}
191
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000192#ifdef IRIVER_H100_SERIES
193void start_flashed_romimage(void)
194{
195 uint8_t *src = (uint8_t *)FLASH_ROMIMAGE_ENTRY;
196 int *reset_vector;
197
198 if (!detect_flashed_romimage())
199 return ;
200
201 reset_vector = (int *)(&src[sizeof(struct flash_header)+4]);
202
203 asm(" move.w #0x2700,%sr");
204 __reset_cookie();
205
206 asm(" move.l %0,%%d0" :: "i"(DRAM_START));
207 asm(" movec.l %d0,%vbr");
208 asm(" move.l %0,%%sp" :: "m"(reset_vector[0]));
209 asm(" move.l %0,%%a0" :: "m"(reset_vector[1]));
210 asm(" jmp (%a0)");
211
212 /* Failure */
213 power_off();
214}
215
216void start_flashed_ramimage(void)
217{
218 struct flash_header hdr;
219 unsigned char *buf = (unsigned char *)DRAM_START;
220 uint8_t *src = (uint8_t *)FLASH_RAMIMAGE_ENTRY;
221
222 if (!detect_flashed_ramimage())
223 return;
224
225 /* Load firmware from flash */
226 cpu_boost(true);
227 memcpy(&hdr, src, sizeof(struct flash_header));
228 src += sizeof(struct flash_header);
229 memcpy(buf, src, hdr.length);
230 cpu_boost(false);
231
232 start_firmware();
233
234 /* Failure */
235 power_off();
236}
237#endif /* IRIVER_H100_SERIES */
238
239void shutdown(void)
240{
241 printf("Shutting down...");
242#ifdef HAVE_EEPROM_SETTINGS
243 /* Reset the rockbox crash check. */
244 firmware_settings.bl_version = 0;
245 eeprom_settings_store();
246#endif
247
248 /* We need to gracefully spin down the disk to prevent clicks. */
249 if (ide_powered())
250 {
251 /* Make sure ATA has been initialized. */
252 ata_init();
253
254 /* And put the disk into sleep immediately. */
255 ata_sleepnow();
256 }
257
258 sleep(HZ*2);
259
260 /* Backlight OFF */
261 __backlight_off();
262#ifdef HAVE_REMOTE_LCD
263 __remote_backlight_off();
264#endif
265
266 __reset_cookie();
267 power_off();
268}
269
270/* Print the battery voltage (and a warning message). */
271void check_battery(void)
272{
273 int adc_battery, battery_voltage, batt_int, batt_frac;
274
275 adc_battery = adc_read(ADC_BATTERY);
276
277 battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000;
278 batt_int = battery_voltage / 100;
279 batt_frac = battery_voltage % 100;
280
281 printf("Batt: %d.%02dV", batt_int, batt_frac);
282
283 if (battery_voltage <= 310)
284 {
285 printf("WARNING! BATTERY LOW!!");
286 sleep(HZ*2);
287 }
288}
289
290#ifdef HAVE_EEPROM_SETTINGS
291void initialize_eeprom(void)
292{
293 if (detect_original_firmware())
294 return ;
295
296 if (!eeprom_settings_init())
297 {
298 recovery_mode = true;
299 return ;
300 }
301
302 /* If bootloader version has not been reset, disk might
303 * not be intact. */
304 if (firmware_settings.bl_version || !firmware_settings.disk_clean)
305 {
306 firmware_settings.disk_clean = false;
307 recovery_mode = true;
308 }
309
310 firmware_settings.bl_version = EEPROM_SETTINGS_BL_MINVER;
311 eeprom_settings_store();
312}
313
314void try_flashboot(void)
315{
316 if (!firmware_settings.initialized)
317 return ;
318
319 switch (firmware_settings.bootmethod)
320 {
321 case BOOT_DISK:
322 return;
323
324 case BOOT_ROM:
325 start_flashed_romimage();
326 recovery_mode = true;
327 break;
328
329 case BOOT_RAM:
330 start_flashed_ramimage();
331 recovery_mode = true;
332 break;
333
334 default:
335 recovery_mode = true;
336 return;
337 }
338}
339
340static const char *options[] = {
341 "Boot from disk",
342 "Boot RAM image",
343 "Boot ROM image",
344 "Shutdown"
345};
346
347#define FAILSAFE_OPTIONS 4
348void failsafe_menu(void)
349{
350 int timeout = 15;
351 int option = 3;
352 int button;
353 int defopt = -1;
354 char buf[32];
355 int i;
356
357 reset_screen();
358 printf("Bootloader %s", version);
359 check_battery();
360 printf("=========================");
361 line += FAILSAFE_OPTIONS;
362 printf("");
363 printf(" [NAVI] to confirm.");
364 printf(" [REC] to set as default.");
365 printf("");
366
367 if (firmware_settings.initialized)
368 {
369 defopt = firmware_settings.bootmethod;
370 if (defopt < 0 || defopt >= FAILSAFE_OPTIONS)
371 defopt = option;
372 }
373
374 while (timeout > 0)
375 {
376 /* Draw the menu. */
377 line = 3;
378 for (i = 0; i < FAILSAFE_OPTIONS; i++)
379 {
380 char *def = "[DEF]";
381 char *arrow = "->";
382
383 if (i != defopt)
384 def = "";
385 if (i != option)
386 arrow = " ";
387
388 printf("%s %s %s", arrow, options[i], def);
389 }
390
391 snprintf(buf, sizeof(buf), "Time left: %ds", timeout);
392 lcd_puts(0, 10, buf);
393 lcd_update();
394 button = button_get_w_tmo(HZ);
395
396 if (button == BUTTON_NONE)
397 {
398 timeout--;
399 continue ;
400 }
401
402 timeout = 15;
403 /* Ignore the ON/PLAY -button because it can cause trouble
404 with the RTC alarm mod. */
405 switch (button & ~(BUTTON_ON))
406 {
407 case BUTTON_UP:
408 case BUTTON_RC_REW:
409 if (option > 0)
410 option--;
411 break ;
412
413 case BUTTON_DOWN:
414 case BUTTON_RC_FF:
415 if (option < FAILSAFE_OPTIONS-1)
416 option++;
417 break ;
418
419 case BUTTON_SELECT:
420 case BUTTON_RC_ON:
421 timeout = 0;
422 break ;
423
424 case BUTTON_REC:
425 case BUTTON_RC_REC:
426 if (firmware_settings.initialized)
427 {
428 firmware_settings.bootmethod = option;
429 eeprom_settings_store();
430 defopt = option;
431 }
432 break ;
433 }
434 }
435
436 lcd_puts(0, 10, "Executing command...");
437 lcd_update();
438 sleep(HZ);
439 reset_screen();
440
441 switch (option)
442 {
443 case BOOT_DISK:
444 return ;
445
446 case BOOT_RAM:
447 start_flashed_ramimage();
448 printf("Image not found");
449 break;
450
451 case BOOT_ROM:
452 start_flashed_romimage();
453 printf("Image not found");
454 break;
455 }
456
457 shutdown();
458}
459#endif
460
Linus Nielsen Feltzingb8a00d22005-02-10 21:55:48 +0000461void main(void)
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000462{
463 int i;
464 int rc;
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000465 bool rc_on_button = false;
466 bool on_button = false;
Miika Pekkarinene1eb91b2006-08-09 12:04:13 +0000467 bool rec_button = false;
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000468 bool hold_status = false;
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000469 int data;
470
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000471#ifdef IAUDIO_X5
472 (void)rc_on_button;
473 (void)on_button;
Miika Pekkarinene1eb91b2006-08-09 12:04:13 +0000474 (void)rec_button;
Miika Pekkarinen886c3022007-01-13 08:16:02 +0000475 (void)hold_status;
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000476 (void)data;
477 power_init();
478
479 system_init();
480 kernel_init();
481
482 set_cpu_frequency(CPUFREQ_NORMAL);
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000483 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000484
485 set_irq_level(0);
486 lcd_init();
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000487#ifdef HAVE_REMOTE_LCD
488 lcd_remote_init();
489#endif
Michael Sevakis58825f62006-11-10 18:47:41 +0000490 backlight_init();
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000491 font_init();
492 adc_init();
493 button_init();
494
495 printf("Rockbox boot loader");
496 printf("Version %s", version);
Miika Pekkarinen886c3022007-01-13 08:16:02 +0000497
498 check_battery();
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000499
500 rc = ata_init();
501 if(rc)
502 {
503 printf("ATA error: %d", rc);
504 sleep(HZ*5);
505 power_off();
506 }
507
508 disk_init();
509
510 rc = disk_mount_all();
511 if (rc<=0)
512 {
513 printf("No partition found");
514 sleep(HZ*5);
515 power_off();
516 }
517
518 printf("Loading firmware");
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000519 i = load_firmware();
520 printf("Result: %d", i);
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000521
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000522 if(i == 0)
523 start_firmware();
524
525 power_off();
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000526
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000527#else
Linus Nielsen Feltzinge628b5c2005-07-19 08:08:33 +0000528 /* We want to read the buttons as early as possible, before the user
529 releases the ON button */
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000530
Linus Nielsen Feltzinge628b5c2005-07-19 08:08:33 +0000531 /* Set GPIO33, GPIO37, GPIO38 and GPIO52 as general purpose inputs
532 (The ON and Hold buttons on the main unit and the remote) */
Linus Nielsen Feltzingd2ca7fc2005-07-12 05:25:42 +0000533 or_l(0x00100062, &GPIO1_FUNCTION);
534 and_l(~0x00100062, &GPIO1_ENABLE);
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000535
536 data = GPIO1_READ;
537 if ((data & 0x20) == 0)
538 on_button = true;
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000539
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000540 if ((data & 0x40) == 0)
541 rc_on_button = true;
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000542
Linus Nielsen Feltzinge628b5c2005-07-19 08:08:33 +0000543 /* Set the default state of the hard drive power to OFF */
544 ide_power_enable(false);
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000545
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000546 power_init();
Linus Nielsen Feltzinge628b5c2005-07-19 08:08:33 +0000547
Linus Nielsen Feltzingbbe919b2005-11-19 01:33:28 +0000548 /* Turn off if neither ON button is pressed */
Linus Nielsen Feltzing54da9242006-01-10 23:11:57 +0000549 if(!(on_button || rc_on_button || usb_detect()))
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000550 {
551 __reset_cookie();
Linus Nielsen Feltzingbbe919b2005-11-19 01:33:28 +0000552 power_off();
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000553 }
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000554
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000555 /* Start with the main backlight OFF. */
556 __backlight_init();
557 __backlight_off();
558
Linus Nielsen Feltzingbbe919b2005-11-19 01:33:28 +0000559 /* Remote backlight ON */
560#ifdef HAVE_REMOTE_LCD
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000561 __remote_backlight_on();
Linus Nielsen Feltzingb68cb9b2005-12-03 00:54:59 +0000562#endif
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000563
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000564 system_init();
565 kernel_init();
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000566
567#ifdef HAVE_ADJUSTABLE_CPU_FREQ
568 /* Set up waitstates for the peripherals */
569 set_cpu_frequency(0); /* PLL off */
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000570#ifdef CPU_COLDFIRE
571 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
572#endif
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000573#endif
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000574 set_irq_level(0);
Linus Nielsen Feltzingd2ca7fc2005-07-12 05:25:42 +0000575
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000576#ifdef HAVE_EEPROM_SETTINGS
577 initialize_eeprom();
578#endif
579
580 adc_init();
581 button_init();
582
583 if ((on_button && button_hold()) ||
584 (rc_on_button && remote_button_hold()))
585 {
586 hold_status = true;
587 }
588
589 /* Power on the hard drive early, to speed up the loading.
590 Some H300 don't like this, so we only do it for the H100 */
591#ifndef IRIVER_H300_SERIES
Miika Pekkarinen20171c12007-01-13 09:08:18 +0000592 if (!hold_status
593# ifdef HAVE_EEPROM_SETTINGS
594 && !recovery_mode
595# endif
596 )
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000597 {
598 ide_power_enable(true);
599 }
600
Miika Pekkarinen20171c12007-01-13 09:08:18 +0000601# ifdef EEPROM_SETTINGS
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000602 if (!hold_status && !usb_detect() && !recovery_mode)
603 try_flashboot();
Miika Pekkarinen20171c12007-01-13 09:08:18 +0000604# endif
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000605#endif
606
607 backlight_init();
Linus Nielsen Feltzing2fcd1b02006-02-04 23:09:56 +0000608#ifdef HAVE_UDA1380
Marcoen Hirschberg6c2e1b82006-12-06 10:36:20 +0000609 audiohw_reset();
Linus Nielsen Feltzing2fcd1b02006-02-04 23:09:56 +0000610#endif
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000611
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000612 lcd_init();
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000613#ifdef HAVE_REMOTE_LCD
614 lcd_remote_init();
615#endif
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000616 font_init();
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000617
618 lcd_setfont(FONT_SYSFIXED);
619
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000620 printf("Rockbox boot loader");
621 printf("Version %s", version);
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000622
Linus Nielsen Feltzingb8a00d22005-02-10 21:55:48 +0000623 sleep(HZ/50); /* Allow the button driver to check the buttons */
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000624 rec_button = ((button_status() & BUTTON_REC) == BUTTON_REC)
Miika Pekkarinene1eb91b2006-08-09 12:04:13 +0000625 || ((button_status() & BUTTON_RC_REC) == BUTTON_RC_REC);
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000626
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000627 check_battery();
628
Miika Pekkarinen22860a92006-08-11 19:59:16 +0000629 /* Don't start if the Hold button is active on the device you
630 are starting with */
Miika Pekkarinen20171c12007-01-13 09:08:18 +0000631 if (!usb_detect() && (hold_status
632#ifdef HAVE_EEPROM_SETTINGS
633 || recovery_mode
634#endif
635 ))
Miika Pekkarinen22860a92006-08-11 19:59:16 +0000636 {
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000637 if (detect_original_firmware())
638 {
639 printf("Hold switch on");
640 shutdown();
641 }
642
Miika Pekkarinen20171c12007-01-13 09:08:18 +0000643#ifdef HAVE_EEPROM_SETTINGS
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000644 failsafe_menu();
Miika Pekkarinen22860a92006-08-11 19:59:16 +0000645#endif
Miika Pekkarinen22860a92006-08-11 19:59:16 +0000646 }
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000647
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000648 /* Holding REC while starting runs the original firmware */
649 if (detect_original_firmware() && rec_button)
Miika Pekkarinene1eb91b2006-08-09 12:04:13 +0000650 {
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000651 printf("Starting original firmware...");
652 start_iriver_fw();
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000653 }
654
Linus Nielsen Feltzing01917ec2005-12-06 12:12:29 +0000655 usb_init();
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000656
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000657 rc = ata_init();
658 if(rc)
659 {
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000660 reset_screen();
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000661 printf("ATA error: %d", rc);
662 printf("Insert USB cable and press");
663 printf("a button");
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000664 while(!(button_get(true) & BUTTON_REL));
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000665 }
666
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000667 /* A hack to enter USB mode without using the USB thread */
668 if(usb_detect())
669 {
Linus Nielsen Feltzing01917ec2005-12-06 12:12:29 +0000670 const char msg[] = "Bootloader USB mode";
671 int w, h;
672 font_getstringsize(msg, &w, &h, FONT_SYSFIXED);
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000673 reset_screen();
Linus Nielsen Feltzing01917ec2005-12-06 12:12:29 +0000674 lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, msg);
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000675 lcd_update();
676
Linus Nielsen Feltzing780cfff2006-01-11 15:37:08 +0000677#ifdef IRIVER_H300_SERIES
678 sleep(HZ);
679#endif
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000680
Peter D'Hoyec4a59a22006-08-15 22:54:06 +0000681#ifdef HAVE_EEPROM_SETTINGS
Miika Pekkarinene1eb91b2006-08-09 12:04:13 +0000682 if (firmware_settings.initialized)
683 {
684 firmware_settings.disk_clean = false;
685 eeprom_settings_store();
686 }
687#endif
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000688 ata_spin();
689 ata_enable(false);
690 usb_enable(true);
Linus Nielsen Feltzing01917ec2005-12-06 12:12:29 +0000691 cpu_idle_mode(true);
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000692 while (usb_detect())
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000693 {
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000694 /* Print the battery status. */
695 line = 0;
696 check_battery();
697
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000698 ata_spin(); /* Prevent the drive from spinning down */
699 sleep(HZ);
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000700
Linus Nielsen Feltzinge628b5c2005-07-19 08:08:33 +0000701 /* Backlight OFF */
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000702 __backlight_off();
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000703 }
704
Linus Nielsen Feltzing01917ec2005-12-06 12:12:29 +0000705 cpu_idle_mode(false);
Linus Nielsen Feltzing13103902005-07-19 11:03:00 +0000706 usb_enable(false);
707 ata_init(); /* Reinitialize ATA and continue booting */
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000708
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000709 reset_screen();
Linus Nielsen Feltzing13103902005-07-19 11:03:00 +0000710 lcd_update();
Linus Nielsen Feltzing8e958b52005-05-20 18:16:45 +0000711 }
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000712
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000713 disk_init();
714
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000715 rc = disk_mount_all();
716 if (rc<=0)
717 {
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000718 reset_screen();
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000719 printf("No partition found");
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000720 while(button_get(true) != SYS_USB_CONNECTED) {};
721 }
722
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000723 printf("Loading firmware");
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000724 i = load_firmware();
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000725 printf("Result: %d", i);
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000726
Miika Pekkarinen973ee5d2006-09-04 16:06:11 +0000727 if (i == 0)
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000728 start_firmware();
Michael Sevakis9e8fe0e2006-10-30 11:33:38 +0000729
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000730 if (!detect_original_firmware())
Miika Pekkarinen973ee5d2006-09-04 16:06:11 +0000731 {
732 printf("No firmware found on disk");
Miika Pekkarinen35b0c3f2007-01-12 20:45:37 +0000733 shutdown();
Miika Pekkarinen973ee5d2006-09-04 16:06:11 +0000734 }
735 else
736 start_iriver_fw();
Linus Nielsen Feltzingce6527b2006-03-22 11:45:33 +0000737#endif /* IAUDIO_X5 */
Linus Nielsen Feltzingd3971452005-01-28 12:51:10 +0000738}
739
740/* These functions are present in the firmware library, but we reimplement
741 them here because the originals do a lot more than we want */
742
743void reset_poweroff_timer(void)
744{
745}
746
747void screen_dump(void)
748{
749}
750
751int dbg_ports(void)
752{
753 return 0;
754}
755
756void mpeg_stop(void)
757{
758}
759
Linus Nielsen Feltzinge244f7f2005-09-14 09:44:45 +0000760void sys_poweroff(void)
761{
762}