/* RB API fuctions */
void usb_enable(bool on)
{
#ifdef HAVE_USBSTACK
    if (on){
        cpu_boost(1);
        usb_core_init();
    } else {
        usb_core_exit();
        cpu_boost(0);
    }
#else
    (void)on;
#endif
}
Example #2
0
static void button_boost(bool state)
{
    static bool boosted = false;
    
    if (state && !boosted)
    {
        cpu_boost(true);
        boosted = true;
    }
    else if (!state && boosted)
    {
        cpu_boost(false);
        boosted = false;
    }
}
/* Helper function which is called to boost / unboost CPU. This function
 * avoids to increase boost_count with each call of gui_boost(). */
static void gui_boost(bool want_to_boost)
{
    static bool boosted = false;
    
    if (want_to_boost && !boosted)
    {
        cpu_boost(true);
        boosted = true;
    }
    else if (!want_to_boost && boosted)
    {
        cpu_boost(false);
        boosted = false;
    }
}
Example #4
0
/* This function checks if parameters are appropriate for DMA,
   and if they are, it sets up for DMA.

   If return value is false, caller may use PIO for this transfer.

   If return value is true, caller must issue a DMA ATA command
   and then call ata_dma_finish().
 */
bool ata_dma_setup(void *addr, unsigned long bytes, bool write) {
    /* Require cacheline alignment for reads to prevent interference. */
    if (!write && ((unsigned long)addr & 15))
        return false;

    /* Writes only need to be word-aligned, but by default DMA
     * is not used for writing as it appears to be slower.
     */
#ifdef ATA_DMA_WRITES
    if (write && ((unsigned long)addr & 3))
        return false;
#else
    if (write)
        return false;
#endif

#if ATA_MAX_UDMA > 2
    if (dma_needs_boost && !dma_boosted) {
        cpu_boost(true);
        dma_boosted = true;
    }
#endif

    if (write) {
        /* If unflushed, old data may be written to disk */
        commit_dcache();
    }
    else {
        /* Invalidate cache because new data may be present in RAM */
        commit_discard_dcache();
    }

    /* Clear pending interrupts so ata_dma_finish() can wait for an
       interrupt from this transfer
     */
    IDE0_CFG |= IDE_CFG_INTRQ;

    IDE_DMA_CONTROL |= 2;
    IDE_DMA_LENGTH = bytes - 4;

#if !defined(BOOTLOADER) || defined (HAVE_BOOTLOADER_USB_MODE)
    if ((unsigned long)addr < DRAM_START)
        /* Rockbox remaps DRAM to start at 0 */
        IDE_DMA_ADDR = (unsigned long)addr + DRAM_START;
    else
#endif
        IDE_DMA_ADDR = (unsigned long)addr;

    if (write)
        IDE_DMA_CONTROL &= ~IDE_DMA_CONTROL_READ;
    else
        IDE_DMA_CONTROL |= IDE_DMA_CONTROL_READ;

    IDE0_CFG |= 0x8000;

    return true;
}
static void button_boost(bool state)
{
    if (state)
    {
        button_unboost_tick = current_tick + BUTTON_UNBOOST_TMO;

        if (!button_boosted)
        {
            button_boosted = true;
            cpu_boost(true);
        }
    }
    else if (!state && button_boosted)
    {
        button_boosted = false;
        cpu_boost(false);
    }
}
static void audio_cpu_boost(bool state)
{
    static bool cpu_boosted = false;

    if (state != cpu_boosted)
    {
        cpu_boost(state);
        cpu_boosted = state;
    }
} /* audio_cpu_boost */
Example #7
0
/* share code for file and directory deletion, saves space */
static bool delete_file_dir(void)
{
    char file_to_delete[MAX_PATH];
    strcpy(file_to_delete, selected_file);

    const char *lines[]={
        ID2P(LANG_REALLY_DELETE),
        file_to_delete
    };
    const char *yes_lines[]={
        ID2P(LANG_DELETING),
        file_to_delete
    };

    const struct text_message message={lines, 2};
    const struct text_message yes_message={yes_lines, 2};

    if(gui_syncyesno_run(&message, &yes_message, NULL)!=YESNO_YES)
        return false;

    splash(0, str(LANG_DELETING));

    int res;
    if (selected_file_attr & ATTR_DIRECTORY) /* true if directory */
    {
        char pathname[MAX_PATH]; /* space to go deep */
        cpu_boost(true);
        strlcpy(pathname, file_to_delete, sizeof(pathname));
        res = remove_dir(pathname, sizeof(pathname));
        cpu_boost(false);
    }
    else
        res = remove(file_to_delete);

    if (!res)
        onplay_result = ONPLAY_RELOAD_DIR;

    return (res == 0);
}
void usb_drv_exit(void)
{
    tick_remove_task(usb_tick);
    USB_DEV_CTRL |= (1<<10); /* soft disconnect */
    usb_phy_suspend();
    /*
     * mask all interrupts _before_ writing to VIC_INT_EN_CLEAR,
     * or else the core might latch the interrupt while
     * the write ot VIC_INT_EN_CLEAR is in the pipeline and
     * so cause a fake spurious interrupt.
     */
    USB_DEV_EP_INTR_MASK = 0xffffffff;
    USB_DEV_INTR_MASK    = 0xffffffff;
    VIC_INT_EN_CLEAR = INTERRUPT_USB;
    CGU_USB &= ~(1<<5);
    bitclr32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
    /* Disable UVDD generating LDO */
    ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) & ~(1<<4));
    usb_disable_pll();
    cpu_boost(0);
    initialized = false;
    logf("usb_drv_exit() !!!!\n");
}
Example #9
0
/* This function waits for a DMA transfer to end.
   It must be called to finish what ata_dma_setup started.

   Return value is true if DMA completed before the timeout, and false
   if a timeout happened.
 */
bool ata_dma_finish(void) {
    bool res;

    /* It may be okay to put this at the end of setup */
    IDE_DMA_CONTROL |= 1;

    /* Wait for end of transfer.
       Reading standard ATA status while DMA is in progress causes
       failures and hangs.  Because of that, another wait is used.
     */
    res = ata_wait_intrq();

    IDE0_CFG &= ~0x8000;
    IDE_DMA_CONTROL &= ~0x80000001;

#if ATA_MAX_UDMA > 2
    if (dma_boosted) {
        cpu_boost(false);
        dma_boosted = false;
    }
#endif

    return res;
}
Example #10
0
/* Paste the clipboard to the current directory */
static bool clipboard_paste(void)
{
    char target[MAX_PATH];
    char *cwd, *nameptr;
    bool success;

    static const char *lines[]={ID2P(LANG_REALLY_OVERWRITE)};
    static const struct text_message message={lines, 1};

    /* Get the name of the current directory */
    cwd = getcwd(NULL, 0);

    /* Figure out the name of the selection */
    nameptr = strrchr(clipboard_selection, '/');

    /* Final target is current directory plus name of selection  */
    snprintf(target, sizeof(target), "%s%s", cwd[1] ? cwd : "", nameptr);

    /* If the target existed but they choose not to overwite, exit */
    if (file_exists(target) &&
        (gui_syncyesno_run(&message, NULL, NULL) == YESNO_NO)) {
        return false;
    }

    if (clipboard_is_copy) {
        splash(0, ID2P(LANG_COPYING));
    }
    else
    {
        splash(0, ID2P(LANG_MOVING));
    }

    /* Now figure out what we're doing */
    cpu_boost(true);
    if (clipboard_selection_attr & ATTR_DIRECTORY) {
        /* Recursion. Set up external stack */
        char srcpath[MAX_PATH];
        char targetpath[MAX_PATH];
        if (!strncmp(clipboard_selection, target, strlen(clipboard_selection)))
        {
            /* Do not allow the user to paste a directory into a dir they are
               copying */
            success = 0;
        }
        else
        {
            strlcpy(srcpath, clipboard_selection, sizeof(srcpath));
            strlcpy(targetpath, target, sizeof(targetpath));

            success = clipboard_pastedirectory(srcpath, sizeof(srcpath),
                             target, sizeof(targetpath), clipboard_is_copy);

            if (success && !clipboard_is_copy)
            {
                strlcpy(srcpath, clipboard_selection, sizeof(srcpath));
                remove_dir(srcpath, sizeof(srcpath));
            }
        }
    } else {
        success = clipboard_pastefile(clipboard_selection, target,
            clipboard_is_copy);
    }
    cpu_boost(false);

    /* Did it work? */
    if (success) {
        /* Reset everything */
        clipboard_selection[0] = 0;
        clipboard_selection_attr = 0;
        clipboard_is_copy = false;

        /* Force reload of the current directory */
        onplay_result = ONPLAY_RELOAD_DIR;
    } else {
        cond_talk_ids_fq(LANG_PASTE, LANG_FAILED);
        splashf(HZ, (unsigned char *)"%s %s", str(LANG_PASTE),
                                              str(LANG_FAILED));
    }

    return true;
}
void usb_drv_init(void)
{
    logf("usb_drv_init() !!!!\n");

    if (!initialized)
    {
        int i;
        for (i = 0; i < USB_NUM_EPS; i++)
        {
            semaphore_init(&endpoints[i][0].complete, 1, 0);
            semaphore_init(&endpoints[i][1].complete, 1, 0);
        }

        initialized = true;
    }

    usb_enable_pll();

    /* we have external power, so boost cpu */
    cpu_boost(1);

    /* length regulator: normal operation */
    ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2);

    /* AHB part */
    bitset32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);

    /* reset AHB */
    CCU_SRC = CCU_SRC_USB_AHB_EN;
    CCU_SRL = CCU_SRL_MAGIC_NUMBER;
    mdelay(1);
    CCU_SRC = CCU_SRL = 0;

    USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
                 | USB_GPIO_TX_BIT_STUFF_EN
                 | USB_GPIO_XO_ON
                 | USB_GPIO_CLK_SEL10; /* 0x06180000; */

    /* bug workaround according to linux patch */
    USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */

    /* enable soft disconnect */
    USB_DEV_CTRL |= USB_DEV_CTRL_SOFT_DISCONN;

    usb_phy_on();
    usb_phy_suspend();
    USB_DEV_CTRL |= USB_DEV_CTRL_SOFT_DISCONN;

    /* We don't care about SVC or SOF events */
    /* Right now we don't handle suspend, so mask those too */
    USB_DEV_INTR_MASK = USB_DEV_INTR_SVC |
                        USB_DEV_INTR_SOF |
                        USB_DEV_INTR_USB_SUSPEND |
                        USB_DEV_INTR_EARLY_SUSPEND;

    USB_DEV_CFG = USB_DEV_CFG_STAT_ACK      |
                  USB_DEV_CFG_UNI_DIR       |
                  USB_DEV_CFG_PI_16BIT      |
                  USB_DEV_CFG_HS            |
                  USB_DEV_CFG_SELF_POWERED  |
                  USB_DEV_CFG_CSR_PRG       |
                  USB_DEV_CFG_PHY_ERR_DETECT;

    USB_DEV_CTRL = USB_DEV_CTRL_DESC_UPDATE  |
                   USB_DEV_CTRL_THRES_ENABLE |
                   USB_DEV_CTRL_BURST_ENABLE |
                   USB_DEV_CTRL_BLEN_8DWORDS |
                   USB_DEV_CTRL_TLEN_8THMAXSIZE;

    USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16));    /* ep 0 */

    reset_endpoints(1);

    /* clear pending interrupts */
    USB_DEV_EP_INTR = 0xffffffff;
    USB_DEV_INTR    = 0xffffffff;

    VIC_INT_ENABLE = INTERRUPT_USB;

    usb_phy_resume();
    USB_DEV_CTRL &= ~USB_DEV_CTRL_SOFT_DISCONN;

    USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
                 | USB_GPIO_TX_BIT_STUFF_EN
                 | USB_GPIO_XO_ON
                 | USB_GPIO_HS_INTR
                 | USB_GPIO_CLK_SEL10; /* 0x06180000; */

    tick_add_task(usb_tick);

    usb_enum_timeout = HZ; /* one second timeout for enumeration */
}
Example #12
0
static void init(void)
{
    int rc;
    bool mounted = false;
#if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
    /* if nobody initialized ATA before, I consider this a cold start */
    bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
#endif

    system_init();
    kernel_init();

#ifdef HAVE_ADJUSTABLE_CPU_FREQ
    set_cpu_frequency(CPUFREQ_NORMAL);
#ifdef CPU_COLDFIRE
    coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
#endif
    cpu_boost(true);
#endif
    
    buffer_init();

    settings_reset();

    i2c_init();
    
    power_init();

    enable_irq();
#ifdef CPU_ARM
    enable_fiq();
#endif
    /* current_tick should be ticking by now */
    CHART("ticking");

    lcd_init();
#ifdef HAVE_REMOTE_LCD
    lcd_remote_init();
#endif
    font_init();

    CHART(">show_logo");
    show_logo();
    CHART("<show_logo");
    lang_init(core_language_builtin, language_strings, 
              LANG_LAST_INDEX_IN_ARRAY);

#ifdef DEBUG
    debug_init();
#else
#ifdef HAVE_SERIAL
    serial_setup();
#endif
#endif

#if CONFIG_RTC
    rtc_init();
#endif
#ifdef HAVE_RTC_RAM
    CHART(">settings_load(RTC)");
    settings_load(SETTINGS_RTC); /* early load parts of global_settings */
    CHART("<settings_load(RTC)");
#endif

    adc_init();

    usb_init();
#if CONFIG_USBOTG == USBOTG_ISP1362
    isp1362_init();
#elif CONFIG_USBOTG == USBOTG_M5636
    m5636_init();
#endif

    backlight_init();

    button_init();

    powermgmt_init();

#if CONFIG_TUNER
    radio_init();
#endif

    /* Keep the order of this 3 (viewportmanager handles statusbars)
     * Must be done before any code uses the multi-screen API */
    CHART(">gui_syncstatusbar_init");
    gui_syncstatusbar_init(&statusbars);
    CHART("<gui_syncstatusbar_init");
    CHART(">sb_skin_init");
    sb_skin_init();
    CHART("<sb_skin_init");
    CHART(">gui_sync_wps_init");
    gui_sync_wps_init();
    CHART("<gui_sync_wps_init");
    CHART(">viewportmanager_init");
    viewportmanager_init();
    CHART("<viewportmanager_init");

#if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
    /* charger_inserted() can't be used here because power_thread()
       hasn't checked power_input_status() yet */
    if (coldstart && (power_input_status() & POWER_INPUT_MAIN_CHARGER)
        && !global_settings.car_adapter_mode
#ifdef ATA_POWER_PLAYERSTYLE
        && !ide_powered() /* relies on probing result from bootloader */
#endif
        )
    {
        rc = charging_screen(); /* display a "charging" screen */
        if (rc == 1)            /* charger removed */
            power_off();
        /* "On" pressed or USB connected: proceed */
        show_logo();  /* again, to provide better visual feedback */
    }
#endif

    CHART(">storage_init");
    rc = storage_init();
    CHART("<storage_init");
    if(rc)
    {
#ifdef HAVE_LCD_BITMAP
        lcd_clear_display();
        lcd_putsf(0, 1, "ATA error: %d", rc);
        lcd_puts(0, 3, "Press ON to debug");
        lcd_update();
        while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
        dbg_ports();
#endif
        panicf("ata: %d", rc);
    }

#ifdef HAVE_EEPROM_SETTINGS
    CHART(">eeprom_settings_init");
    eeprom_settings_init();
    CHART("<eeprom_settings_init");
#endif

#ifndef HAVE_USBSTACK
    usb_start_monitoring();
    while (usb_detect() == USB_INSERTED)
    {
#ifdef HAVE_EEPROM_SETTINGS
        firmware_settings.disk_clean = false;
#endif
        /* enter USB mode early, before trying to mount */
        if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
#if (CONFIG_STORAGE & STORAGE_MMC)
            if (!mmc_touched() ||
                (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
#endif
            {
                gui_usb_screen_run();
                mounted = true; /* mounting done @ end of USB mode */
            }
#ifdef HAVE_USB_POWER
        if (usb_powered())      /* avoid deadlock */
            break;
#endif
    }
#endif

    if (!mounted)
    {
        CHART(">disk_mount_all");
        rc = disk_mount_all();
        CHART("<disk_mount_all");
        if (rc<=0)
        {
            lcd_clear_display();
            lcd_puts(0, 0, "No partition");
            lcd_puts(0, 1, "found.");
#ifdef HAVE_LCD_BITMAP
            lcd_puts(0, 2, "Insert USB cable");
            lcd_puts(0, 3, "and fix it.");
#endif
            lcd_update();

            while(button_get(true) != SYS_USB_CONNECTED) {};
            gui_usb_screen_run();
            system_reboot();
        }
    }

#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
    (CONFIG_KEYPAD == IRIVER_H10_PAD)
#ifdef SETTINGS_RESET
    /* Reset settings if holding the reset button. (Rec on Archos,
       A on Gigabeat) */
    if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
#else
    /* Reset settings if the hold button is turned on */
    if (button_hold())
#endif
    {
        splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
        settings_reset();
    }
    else
#endif
    {
        CHART(">settings_load(ALL)");
        settings_load(SETTINGS_ALL);
        CHART("<settings_load(ALL)");
    }

    CHART(">init_dircache(true)");
    rc = init_dircache(true);
    CHART("<init_dircache(true)");
    if (rc < 0)
    {
#ifdef HAVE_TAGCACHE
        remove(TAGCACHE_STATEFILE);
#endif
    }

    CHART(">settings_apply(true)");
    settings_apply(true);        
    CHART("<settings_apply(true)");
    CHART(">init_dircache(false)");
    init_dircache(false);
    CHART("<init_dircache(false)");
#ifdef HAVE_TAGCACHE
    CHART(">init_tagcache");
    init_tagcache();
    CHART("<init_tagcache");
#endif

#ifdef HAVE_EEPROM_SETTINGS
    if (firmware_settings.initialized)
    {
        /* In case we crash. */
        firmware_settings.disk_clean = false;
        CHART(">eeprom_settings_store");
        eeprom_settings_store();
        CHART("<eeprom_settings_store");
    }
#endif
    playlist_init();
    tree_mem_init();
    filetype_init();
    scrobbler_init();
#if CONFIG_CODEC == SWCODEC
    tdspeed_init();
#endif /* CONFIG_CODEC == SWCODEC */

#if CONFIG_CODEC != SWCODEC
    /* No buffer allocation (see buffer.c) may take place after the call to
       audio_init() since the mpeg thread takes the rest of the buffer space */
    mp3_init( global_settings.volume,
              global_settings.bass,
              global_settings.treble,
              global_settings.balance,
              global_settings.loudness,
              global_settings.avc,
              global_settings.channel_config,
              global_settings.stereo_width,
              global_settings.mdb_strength,
              global_settings.mdb_harmonics,
              global_settings.mdb_center,
              global_settings.mdb_shape,
              global_settings.mdb_enable,
              global_settings.superbass);

     /* audio_init must to know the size of voice buffer so init voice first */
    talk_init();
#endif /* CONFIG_CODEC != SWCODEC */

    CHART(">audio_init");
    audio_init();
    CHART("<audio_init");

#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
    pcm_rec_init();
#endif

    /* runtime database has to be initialized after audio_init() */
    cpu_boost(false);

#if CONFIG_CHARGING
    car_adapter_mode_init();
#endif
#ifdef IPOD_ACCESSORY_PROTOCOL
    iap_setup(global_settings.serial_bitrate);
#endif
#ifdef HAVE_ACCESSORY_SUPPLY
    accessory_supply_set(global_settings.accessory_supply);
#endif
#ifdef HAVE_LINEOUT_POWEROFF
    lineout_set(global_settings.lineout_active);
#endif
#ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
    CHART("<check_bootfile(false)");
    check_bootfile(false); /* remember write time and filesize */
    CHART(">check_bootfile(false)");
#endif
    CHART("<settings_apply_skins");
    settings_apply_skins();
    CHART(">settings_apply_skins");
}
bool search_playlist(void)
{
    char search_str[32] = "";
    bool ret = false, exit = false;
    int i, playlist_count;
    int found_indicies[MAX_PLAYLIST_ENTRIES];
    int found_indicies_count = 0, last_found_count = -1;
    int button;
    struct gui_synclist playlist_lists;
    struct playlist_track_info track;

    if (!playlist_viewer_init(&viewer, 0, false))
        return ret;
    if (kbd_input(search_str, sizeof(search_str)) < 0)
        return ret;
    lcd_clear_display();
    playlist_count = playlist_amount_ex(viewer.playlist);

    cpu_boost(true);

    for (i = 0; i < playlist_count &&
        found_indicies_count < MAX_PLAYLIST_ENTRIES; i++)
    {
        if (found_indicies_count != last_found_count)
        {
            splashf(0, str(LANG_PLAYLIST_SEARCH_MSG), found_indicies_count,
                       str(LANG_OFF_ABORT));
            last_found_count = found_indicies_count;
        }

        if (action_userabort(TIMEOUT_NOBLOCK))
            break;

        playlist_get_track_info(viewer.playlist, i, &track);

        if (strcasestr(track.filename,search_str))
            found_indicies[found_indicies_count++] = track.index;

        yield();
    }

    cpu_boost(false);

    if (!found_indicies_count)
    {
        return ret;
    }
    backlight_on();

    gui_synclist_init(&playlist_lists, playlist_search_callback_name,
                      found_indicies, false, 1, NULL);
    gui_synclist_set_title(&playlist_lists, str(LANG_SEARCH_RESULTS), NOICON);
    gui_synclist_set_icon_callback(&playlist_lists, NULL);
    gui_synclist_set_nb_items(&playlist_lists, found_indicies_count);
    gui_synclist_select_item(&playlist_lists, 0);
    gui_synclist_draw(&playlist_lists);
    while (!exit)
    {
        if (list_do_action(CONTEXT_LIST, HZ/4,
                           &playlist_lists, &button, LIST_WRAP_UNLESS_HELD))
            continue;
        switch (button)
        {
            case ACTION_STD_CANCEL:
                exit = true;
                break;

            case ACTION_STD_OK:
            {
                int sel = gui_synclist_get_sel_pos(&playlist_lists);
                playlist_start(found_indicies[sel], 0);
                exit = 1;
            }
                break;

            default:
                if (default_event_handler(button) == SYS_USB_CONNECTED)
                {
                    ret = true;
                    exit = true;
                }
                break;
        }
    }
    return ret;
}