A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Björn Stenberg
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#include "system.h"
23
24#include "version.h"
25#include "gcc_extensions.h"
26#include "storage.h"
27#include "disk.h"
28#include "file_internal.h"
29#include "lcd.h"
30#include "rtc.h"
31#include "debug.h"
32#include "led.h"
33#include "../kernel-internal.h"
34#include "button.h"
35#include "core_keymap.h"
36#include "tree.h"
37#include "filetypes.h"
38#include "panic.h"
39#include "menu.h"
40#include "usb.h"
41#include "wifi.h"
42#include "powermgmt.h"
43#include "adc.h"
44#include "i2c.h"
45#ifndef DEBUG
46#include "serial.h"
47#endif
48#include "audio.h"
49#include "settings.h"
50#include "backlight.h"
51#include "status.h"
52#include "debug_menu.h"
53#include "font.h"
54#include "language.h"
55#include "wps.h"
56#include "playlist.h"
57#include "core_alloc.h"
58#include "rolo.h"
59#include "screens.h"
60#include "usb_screen.h"
61#include "power.h"
62#include "talk.h"
63#include "plugin.h"
64#include "misc.h"
65#include "dircache.h"
66#ifdef HAVE_TAGCACHE
67#include "tagcache.h"
68#include "tagtree.h"
69#endif
70#include "lang.h"
71#include "string.h"
72#include "splash.h"
73#include "eeprom_settings.h"
74#include "icon.h"
75#include "viewport.h"
76#include "skin_engine/skin_engine.h"
77#include "statusbar-skinned.h"
78#include "bootchart.h"
79#include "logdiskf.h"
80#include "bootdata.h"
81#if defined(HAVE_DEVICEDATA)
82#include "devicedata.h"
83#endif
84
85#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
86#include "notification.h"
87#endif
88#include "shortcuts.h"
89
90#ifdef IPOD_ACCESSORY_PROTOCOL
91#include "iap.h"
92#endif
93
94#include "audio_thread.h"
95#include "playback.h"
96#include "tdspeed.h"
97#include "server_thread.h"
98#include "broker_thread.h"
99#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
100#include "pcm_record.h"
101#endif
102
103#ifdef BUTTON_REC
104 #define SETTINGS_RESET BUTTON_REC
105#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
106 #define SETTINGS_RESET BUTTON_A
107#endif
108
109#if CONFIG_TUNER
110#include "radio.h"
111#endif
112#if (CONFIG_STORAGE & STORAGE_MMC)
113#include "ata_mmc.h"
114#endif
115
116#ifdef HAVE_REMOTE_LCD
117#include "lcd-remote.h"
118#endif
119
120#if CONFIG_USBOTG == USBOTG_ISP1362
121#include "isp1362.h"
122#endif
123
124#if CONFIG_USBOTG == USBOTG_M5636
125#include "m5636.h"
126#endif
127
128#ifdef HAVE_HARDWARE_CLICK
129#include "piezo.h"
130#endif
131
132#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
133#define MAIN_NORETURN_ATTR NORETURN_ATTR
134#else
135/* gcc adds an implicit 'return 0;' at the end of main(), causing a warning
136 * with noreturn attribute */
137#define MAIN_NORETURN_ATTR
138#endif
139
140#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
141#ifdef HAVE_MULTIVOLUME
142#include "pathfuncs.h" /* for init_volume_names */
143#endif
144#endif
145
146#if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
147#ifdef SIMULATOR
148#include "sim_tasks.h"
149#endif
150#include "system-sdl.h"
151#define HAVE_ARGV_MAIN
152/* Don't use SDL_main on windows -> no more stdio redirection */
153#if defined(WIN32)
154#undef main
155#endif
156#endif /* SDL|MAEMO|PAMDORA */
157
158/*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
159
160static void init(void);
161/* main(), and various functions called by main() and init() may be
162 * be INIT_ATTR. These functions must not be called after the final call
163 * to root_menu() at the end of main()
164 * see definition of INIT_ATTR in config.h */
165#if defined(HAVE_ARGV_MAIN) && !defined(ZIG_APP)
166int main(int argc, char *argv[]) INIT_ATTR MAIN_NORETURN_ATTR ;
167int main(int argc, char *argv[])
168{
169 sys_handle_argv(argc, argv);
170#elif defined(ZIG_APP)
171int main_c(void) INIT_ATTR MAIN_NORETURN_ATTR;
172int main_c(void)
173{
174#else
175int main(void) INIT_ATTR MAIN_NORETURN_ATTR;
176int main(void)
177{
178#endif
179 CHART(">init");
180 init();
181 CHART("<init");
182 FOR_NB_SCREENS(i)
183 {
184 screens[i].clear_display();
185 screens[i].update();
186 }
187 list_init();
188 tree_init();
189#if defined(HAVE_DEVICEDATA) && !defined(BOOTLOADER) /* SIMULATOR */
190 verify_device_data();
191#endif
192 /* Keep the order of this 3
193 * Must be done before any code uses the multi-screen API */
194#ifdef HAVE_USBSTACK
195 /* All threads should be created and public queues registered by now */
196 usb_start_monitoring();
197#endif
198
199#if !defined(DISABLE_ACTION_REMAP) && defined(CORE_KEYREMAP_FILE)
200 if (file_exists(CORE_KEYREMAP_FILE))
201 {
202 int mapct = core_load_key_remap(CORE_KEYREMAP_FILE);
203 if (mapct <= 0)
204 splashf(HZ, "key remap failed: %d, %s", mapct, CORE_KEYREMAP_FILE);
205 }
206#endif
207
208#if !defined(BOOTLOADER)
209 allocate_playback_log();
210 if (!file_exists(ROCKBOX_DIR"/playername.txt"))
211 {
212 int fd = open(ROCKBOX_DIR"/playername.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666);
213 if(fd >= 0)
214 {
215 fdprintf(fd, "%s", MODEL_NAME);
216 close(fd);
217 }
218 }
219#endif
220
221#ifdef AUTOROCK
222 {
223 char filename[MAX_PATH];
224 const char *file =
225#ifdef APPLICATION
226 ROCKBOX_DIR
227#else
228 PLUGIN_APPS_DIR
229#endif
230 "/autostart.rock";
231 if(file_exists(file)) /* no complaint if it doesn't exist */
232 {
233 plugin_load(file, NULL); /* start if it does */
234 }
235 }
236#endif /* #ifdef AUTOROCK */
237
238 global_status.last_volume_change = 0;
239 /* no calls INIT_ATTR functions after this point anymore!
240 * see definition of INIT_ATTR in config.h */
241 CHART(">root_menu");
242 root_menu();
243}
244
245/* The disk isn't ready at boot, rblogo is stored in bin and erased after boot */
246int show_logo_boot( void ) INIT_ATTR;
247int show_logo_boot( void )
248{
249 unsigned char version[32];
250 int font_h, ver_w;
251 snprintf(version, sizeof(version), "Ver. %s", rbversion);
252 ver_w = font_getstringsize(version, NULL, &font_h, FONT_SYSFIXED);
253 lcd_clear_display();
254 lcd_setfont(FONT_SYSFIXED);
255#if defined(SANSA_CLIP) || defined(SANSA_CLIPV2) || defined(SANSA_CLIPPLUS)
256 /* display the logo in the blue area of the screen (bottom 48 pixels) */
257 if (ver_w > LCD_WIDTH)
258 lcd_putsxy(0, 0, rbversion);
259 else
260 lcd_putsxy((LCD_WIDTH/2) - (ver_w/2), 0, version);
261 lcd_bmp(&bm_rockboxlogo, (LCD_WIDTH - BMPWIDTH_rockboxlogo) / 2, 16);
262#else
263 lcd_bmp(&bm_rockboxlogo, (LCD_WIDTH - BMPWIDTH_rockboxlogo) / 2, 10);
264 if (ver_w > LCD_WIDTH)
265 lcd_putsxy(0, LCD_HEIGHT-font_h, rbversion);
266 else
267 lcd_putsxy((LCD_WIDTH/2) - (ver_w/2), LCD_HEIGHT-font_h, version);
268#endif
269 lcd_setfont(FONT_UI);
270 lcd_update();
271#ifdef HAVE_REMOTE_LCD
272 lcd_remote_clear_display();
273 lcd_remote_bmp(&bm_remote_rockboxlogo, 0, 10);
274 lcd_remote_setfont(FONT_SYSFIXED);
275 if (ver_w > LCD_REMOTE_WIDTH)
276 lcd_remote_putsxy(0, LCD_REMOTE_HEIGHT-font_h, rbversion);
277 else
278 lcd_remote_putsxy((LCD_REMOTE_WIDTH/2) - (ver_w/2),
279 LCD_REMOTE_HEIGHT-font_h, version);
280 lcd_remote_setfont(FONT_UI);
281 lcd_remote_update();
282#endif
283#ifdef SIMULATOR
284 sleep(HZ); /* sim is too fast to see logo */
285#endif
286 return 0;
287}
288
289#ifdef HAVE_DIRCACHE
290static int INIT_ATTR init_dircache(bool preinit)
291{
292 if (preinit)
293 dircache_init(MAX(global_status.dircache_size, 0));
294
295 if (!global_settings.dircache)
296 return -1;
297
298 int result = -1;
299
300#ifdef HAVE_EEPROM_SETTINGS
301 if (firmware_settings.initialized &&
302 firmware_settings.disk_clean &&
303 preinit)
304 {
305 result = dircache_load();
306 if (result < 0)
307 firmware_settings.disk_clean = false;
308 }
309 else
310#endif /* HAVE_EEPROM_SETTINGS */
311 if (!preinit)
312 {
313 result = dircache_enable();
314 if (result != 0)
315 {
316 if (result > 0)
317 {
318 /* Print "Scanning disk..." to the display. */
319 splash(0, str(LANG_SCANNING_DISK));
320 dircache_wait();
321 backlight_on();
322 show_logo_boot();
323 }
324
325 struct dircache_info info;
326 dircache_get_info(&info);
327 global_status.dircache_size = info.size;
328 status_save(true);
329 }
330 /* else don't wait or already enabled by load */
331 }
332
333 return result;
334}
335#endif /* HAVE_DIRCACHE */
336
337#ifdef HAVE_TAGCACHE
338static void init_tagcache(void) INIT_ATTR;
339static void init_tagcache(void)
340{
341 bool clear = false;
342#if 0
343 long talked_tick = 0;
344#endif
345 tagcache_init();
346
347 while (!tagcache_is_initialized())
348 {
349 int ret = tagcache_get_commit_step();
350
351 if (ret > 0)
352 {
353#if 0 /* FIXME: Audio isn't even initialized yet! */
354 /* hwcodec can't use voice here, as the database commit
355 * uses the audio buffer. */
356 if(global_settings.talk_menu
357 && (talked_tick == 0
358 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
359 {
360 talked_tick = current_tick;
361 talk_id(LANG_TAGCACHE_INIT, false);
362 talk_number(ret, true);
363 talk_id(VOICE_OF, true);
364 talk_number(tagcache_get_max_commit_step(), true);
365 }
366#endif
367 if (lang_is_rtl())
368 {
369 splash_progress(ret, tagcache_get_max_commit_step(),
370 "[%d/%d] %s", ret, tagcache_get_max_commit_step(),
371 str(LANG_TAGCACHE_INIT));
372 }
373 else
374 {
375 splash_progress(ret, tagcache_get_max_commit_step(),
376 "%s [%d/%d]", str(LANG_TAGCACHE_INIT), ret,
377 tagcache_get_max_commit_step());
378 }
379 clear = true;
380 }
381 sleep(HZ/4);
382 }
383 tagtree_init();
384
385 if (clear)
386 {
387 backlight_on();
388 show_logo_boot();
389 }
390}
391#endif /* HAVE_TAGCACHE */
392
393#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
394
395static void init(void)
396{
397 system_init();
398 core_allocator_init();
399 kernel_init();
400#ifdef APPLICATION
401 paths_init();
402#endif
403 enable_irq();
404 lcd_init();
405#ifdef HAVE_REMOTE_LCD
406 lcd_remote_init();
407#endif
408 FOR_NB_SCREENS(i)
409 global_status.font_id[i] = FONT_SYSFIXED;
410 font_init();
411 show_logo_boot();
412 button_init();
413 powermgmt_init();
414 backlight_init();
415 unicode_init();
416#ifdef HAVE_MULTIVOLUME
417 init_volume_names();
418#endif
419#ifdef SIMULATOR
420 sim_tasks_init();
421#endif
422#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
423 notification_init();
424#endif
425 lang_init(core_language_builtin, language_strings,
426 LANG_LAST_INDEX_IN_ARRAY);
427#ifdef DEBUG
428 debug_init();
429#endif
430#if CONFIG_TUNER
431 radio_init();
432#endif
433 /* Keep the order of this 3 (viewportmanager handles statusbars)
434 * Must be done before any code uses the multi-screen API */
435 gui_syncstatusbar_init(&statusbars);
436 gui_sync_skin_init();
437 sb_skin_init();
438 viewportmanager_init();
439
440 storage_init();
441 pcm_init();
442 dsp_init();
443 settings_reset();
444 settings_load();
445 settings_apply(true);
446 init_battery_tables();
447#ifdef HAVE_DIRCACHE
448 init_dircache(true);
449 init_dircache(false);
450#endif
451#ifdef HAVE_TAGCACHE
452 init_tagcache();
453#endif
454 tree_mem_init();
455 filetype_init();
456 playlist_init();
457 shortcuts_init();
458
459 audio_init();
460 talk_announce_voice_invalid(); /* notify user w/ voice prompt if voice file invalid */
461 settings_apply_skins();
462
463/* do USB last so prompt (if enabled) can work correctly if USB was inserted with device off,
464 * also doesn't hurt that it will display the nice pretty backdrop this way too. */
465#ifndef USB_NONE
466 usb_init();
467 usb_start_monitoring();
468#endif
469
470#ifdef ROCKBOX_SERVER
471 server_init();
472 broker_init();
473#endif
474}
475
476#else /* ! (CONFIG_PLATFORM & PLATFORM_HOSTED) */
477
478#include "errno.h"
479
480static void init(void) INIT_ATTR;
481static void init(void)
482{
483 int rc;
484 bool mounted = false;
485
486 system_init();
487 core_allocator_init();
488 kernel_init();
489
490#if defined(HAVE_BOOTDATA) && !defined(BOOTLOADER)
491 verify_boot_data();
492#endif
493
494#if defined(HAVE_DEVICEDATA) && !defined(BOOTLOADER)
495 verify_device_data();
496#endif
497
498 /* early early early! */
499 filesystem_init();
500
501#ifdef HAVE_ADJUSTABLE_CPU_FREQ
502 set_cpu_frequency(CPUFREQ_NORMAL);
503#ifdef CPU_COLDFIRE
504 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
505#endif
506 cpu_boost(true);
507#endif
508
509 i2c_init();
510
511 power_init();
512
513 enable_irq();
514#if defined(CPU_ARM_CLASSIC)
515 enable_fiq();
516#endif
517 /* current_tick should be ticking by now */
518 CHART("ticking");
519
520 unicode_init();
521 lcd_init();
522#ifdef HAVE_REMOTE_LCD
523 lcd_remote_init();
524#endif
525 FOR_NB_SCREENS(i)
526 global_status.font_id[i] = FONT_SYSFIXED;
527 font_init();
528
529 settings_reset();
530
531 CHART(">show_logo");
532 show_logo_boot();
533 CHART("<show_logo");
534 lang_init(core_language_builtin, language_strings,
535 LANG_LAST_INDEX_IN_ARRAY);
536
537#ifdef DEBUG
538 debug_init();
539#else
540#ifdef HAVE_SERIAL
541 serial_setup();
542#endif
543#endif
544
545#if CONFIG_RTC
546 rtc_init();
547#endif
548
549 adc_init();
550
551 usb_init();
552#if CONFIG_USBOTG == USBOTG_ISP1362
553 isp1362_init();
554#elif CONFIG_USBOTG == USBOTG_M5636
555 m5636_init();
556#endif
557
558 backlight_init();
559
560 button_init();
561
562 /* Don't initialize power management here if it could incorrectly
563 * measure battery voltage, and it's not needed for charging. */
564#if !defined(NEED_ATA_POWER_BATT_MEASURE) || \
565 (CONFIG_CHARGING > CHARGING_MONITOR)
566 powermgmt_init();
567#endif
568
569#if CONFIG_TUNER
570 radio_init();
571#endif
572
573#ifdef HAVE_HARDWARE_CLICK
574 piezo_init();
575#endif
576
577 /* Keep the order of this 3 (viewportmanager handles statusbars)
578 * Must be done before any code uses the multi-screen API */
579 CHART(">gui_syncstatusbar_init");
580 gui_syncstatusbar_init(&statusbars);
581 CHART("<gui_syncstatusbar_init");
582 CHART(">sb_skin_init");
583 sb_skin_init();
584 CHART("<sb_skin_init");
585 CHART(">gui_sync_wps_init");
586 gui_sync_skin_init();
587 CHART("<gui_sync_wps_init");
588 CHART(">viewportmanager_init");
589 viewportmanager_init();
590 CHART("<viewportmanager_init");
591
592 CHART(">storage_init");
593 rc = storage_init();
594 CHART("<storage_init");
595 if(rc)
596 {
597 lcd_clear_display();
598 lcd_putsf(0, 1, "ATA error: %d", rc);
599 lcd_puts(0, 3, "Press button to debug");
600 lcd_update();
601 while(!(button_get(true) & BUTTON_REL)); /* DO NOT CHANGE TO ACTION SYSTEM */
602 dbg_ports();
603 panicf("ata: %d", rc);
604 }
605
606#if defined(NEED_ATA_POWER_BATT_MEASURE) && \
607 (CONFIG_CHARGING <= CHARGING_MONITOR)
608 /* After storage_init(), ATA power must be on, so battery voltage
609 * can be measured. Initialize power management if it was delayed. */
610 powermgmt_init();
611#endif
612#ifdef HAVE_EEPROM_SETTINGS
613 CHART(">eeprom_settings_init");
614 eeprom_settings_init();
615 CHART("<eeprom_settings_init");
616#endif
617
618#ifndef HAVE_USBSTACK
619 usb_start_monitoring();
620 while (usb_detect() == USB_INSERTED)
621 {
622#ifdef HAVE_EEPROM_SETTINGS
623 firmware_settings.disk_clean = false;
624#endif
625 /* enter USB mode early, before trying to mount */
626 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
627#if (CONFIG_STORAGE & STORAGE_MMC)
628 if (!mmc_touched() ||
629 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
630#endif
631 {
632 gui_usb_screen_run(true);
633 mounted = true; /* mounting done @ end of USB mode */
634 }
635#ifdef HAVE_USB_POWER
636 /* if there is no host or user requested no USB, skip this */
637 if (usb_powered_only())
638 break;
639#endif
640 }
641#endif
642
643 if (!mounted)
644 {
645 CHART(">disk_mount_all");
646 rc = disk_mount_all();
647 CHART("<disk_mount_all");
648 if (rc<=0)
649 {
650 int line=0;
651 lcd_clear_display();
652 lcd_putsf(0, line++, "No partition found (%d).", rc);
653#ifndef USB_NONE
654 lcd_puts(0, line++, "Insert USB cable");
655 lcd_puts(0, line++, "and fix it.");
656#elif !defined(DEBUG) && !(CONFIG_STORAGE & STORAGE_RAMDISK)
657 lcd_puts(0, line++, "Rebooting in 5s");
658#endif
659 lcd_puts(0, line++, rbversion);
660
661#ifdef STORAGE_GET_INFO
662 struct storage_info sinfo;
663 storage_get_info(0, &sinfo);
664#ifdef MAX_PHYS_SECTOR_SIZE
665 lcd_putsf(0, line++, "id: '%s' s:%u*%u", sinfo.product, sinfo.sector_size, sinfo.phys_sector_mult);
666#else
667 lcd_putsf(0, line++, "id: '%s' s:%u", sinfo.product, sinfo.sector_size);
668#endif
669#endif
670 struct partinfo pinfo;
671 for (int i = 0 ; i < NUM_VOLUMES ; i++) {
672 disk_partinfo(i, &pinfo);
673 if (pinfo.type)
674 lcd_putsf(0, line++, "P%d T%02x S%llx",
675 i, pinfo.type, (unsigned long long)pinfo.size);
676 }
677 lcd_update();
678
679#if defined(MAX_VIRT_SECTOR_SIZE) && defined(DEFAULT_VIRT_SECTOR_SIZE)
680#ifdef HAVE_MULTIDRIVE
681 for (int i = 0 ; i < NUM_DRIVES ; i++)
682#endif
683 disk_set_sector_multiplier(IF_MD(i,) DEFAULT_VIRT_SECTOR_SIZE/SECTOR_SIZE);
684#endif
685
686#ifndef USB_NONE
687 usb_start_monitoring();
688 while(button_get(true) != SYS_USB_CONNECTED) {};
689 gui_usb_screen_run(true);
690#elif !defined(DEBUG) && !(CONFIG_STORAGE & STORAGE_RAMDISK)
691 sleep(HZ*5);
692#endif
693
694#if !defined(DEBUG) && !(CONFIG_STORAGE & STORAGE_RAMDISK)
695 system_reboot();
696#else
697 rc = disk_mount_all();
698 if (rc <= 0) {
699 lcd_putsf(0, 4, "Error mounting: %08x", rc);
700 lcd_update();
701 sleep(HZ*5);
702 system_reboot();
703 }
704#endif
705 }
706 }
707
708 pcm_init();
709 dsp_init();
710
711 CHART(">settings_load");
712 settings_load();
713 CHART("<settings_load");
714
715#if defined(BUTTON_REC) || \
716 (CONFIG_KEYPAD == GIGABEAT_PAD) || \
717 (CONFIG_KEYPAD == IPOD_4G_PAD) || \
718 (CONFIG_KEYPAD == IRIVER_H10_PAD)
719 if (global_settings.clear_settings_on_hold &&
720#ifdef SETTINGS_RESET
721 /* Reset settings if holding the reset button. (Rec on Archos,
722 A on Gigabeat) */
723 ((button_status() & SETTINGS_RESET) == SETTINGS_RESET))
724#else
725 /* Reset settings if the hold button is turned on */
726 (button_hold()))
727#endif
728 {
729 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
730 settings_reset();
731 }
732#endif
733 CHART(">init_battery_tables");
734 init_battery_tables();
735 CHART("<init_battery_tables");
736#ifdef HAVE_DIRCACHE
737 CHART(">init_dircache(true)");
738 rc = init_dircache(true);
739 CHART("<init_dircache(true)");
740#ifdef HAVE_TAGCACHE
741 if (rc < 0)
742 tagcache_remove_statefile();
743#endif /* HAVE_TAGCACHE */
744#endif /* HAVE_DIRCACHE */
745
746 CHART(">settings_apply(true)");
747 settings_apply(true);
748 CHART("<settings_apply(true)");
749#ifdef HAVE_DIRCACHE
750 CHART(">init_dircache(false)");
751 init_dircache(false);
752 CHART("<init_dircache(false)");
753#endif
754#ifdef HAVE_TAGCACHE
755 CHART(">init_tagcache");
756 init_tagcache();
757 CHART("<init_tagcache");
758#endif
759
760#ifdef HAVE_EEPROM_SETTINGS
761 if (firmware_settings.initialized)
762 {
763 /* In case we crash. */
764 firmware_settings.disk_clean = false;
765 CHART(">eeprom_settings_store");
766 eeprom_settings_store();
767 CHART("<eeprom_settings_store");
768 }
769#endif
770 playlist_init();
771 tree_mem_init();
772 filetype_init();
773
774 shortcuts_init();
775
776 CHART(">audio_init");
777 audio_init();
778 CHART("<audio_init");
779 talk_announce_voice_invalid(); /* notify user w/ voice prompt if voice file invalid */
780
781#ifdef HAVE_WIFI
782 wifi_init();
783#endif
784
785 /* runtime database has to be initialized after audio_init() */
786 cpu_boost(false);
787
788#if CONFIG_CHARGING
789 car_adapter_mode_init();
790#endif
791#ifdef IPOD_ACCESSORY_PROTOCOL
792 iap_setup(global_settings.serial_bitrate);
793#endif
794#ifdef HAVE_ACCESSORY_SUPPLY
795 accessory_supply_set(global_settings.accessory_supply);
796#endif
797#ifdef HAVE_LINEOUT_POWEROFF
798 lineout_set(global_settings.lineout_active);
799#endif
800#ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
801 CHART("<check_bootfile(false)");
802 check_bootfile(false); /* remember write time and filesize */
803 CHART(">check_bootfile(false)");
804#endif
805 CHART("<settings_apply_skins");
806 settings_apply_skins();
807 CHART(">settings_apply_skins");
808}
809
810#ifdef CPU_PP
811void cop_main(void) MAIN_NORETURN_ATTR;
812void cop_main(void)
813{
814/* This is the entry point for the coprocessor
815 Anyone not running an upgraded bootloader will never reach this point,
816 so it should not be assumed that the coprocessor be usable even on
817 platforms which support it.
818
819 A kernel thread is initially setup on the coprocessor and immediately
820 destroyed for purposes of continuity. The cop sits idle until at least
821 one thread exists on it. */
822
823#if NUM_CORES > 1
824 system_init();
825 kernel_init();
826 /* This should never be reached */
827#endif
828 while(1) {
829 sleep_core(COP);
830 }
831}
832#endif /* CPU_PP */
833
834#endif /* CONFIG_PLATFORM & PLATFORM_HOSTED */