From 90b576f55ea6854a70c8ed77095b42e57b744723 Mon Sep 17 00:00:00 2001 From: Dominik Wenger Date: Mon, 26 Oct 2009 18:16:58 +0000 Subject: Many more drivers for mini2440. Now the main binary compiles and runs. Flyspray: FS#10725 Author: Bob Cousins git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23362 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 2 + apps/keymaps/keymap-mini2440.c | 389 +++++++++++++++++++++ bootloader/mini2440.c | 10 +- firmware/SOURCES | 16 +- firmware/drivers/audio/uda1341.c | 184 ++++++++++ firmware/export/audiohw.h | 2 + firmware/export/config-mini2440.h | 17 +- firmware/export/s3c2440.h | 33 ++ firmware/export/uda1341.h | 102 ++++++ firmware/target/arm/s3c2440/adc-s3c2440.c | 140 ++++++++ .../target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c | 140 -------- .../target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c | 144 -------- .../target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h | 46 --- .../arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c | 2 +- firmware/target/arm/s3c2440/i2c-s3c2440.c | 144 ++++++++ firmware/target/arm/s3c2440/i2c-s3c2440.h | 46 +++ .../target/arm/s3c2440/mini2440/pcm-mini2440.c | 292 ++++++++++++++++ .../arm/s3c2440/mini2440/powermgmt-mini2440.c | 69 ++++ firmware/target/arm/s3c2440/sd-s3c2440.c | 13 +- firmware/target/arm/s3c2440/system-target.h | 40 ++- firmware/target/arm/s3c2440/uart-s3c2440.c | 108 ++++-- firmware/target/arm/s3c2440/uart-s3c2440.h | 24 +- 22 files changed, 1543 insertions(+), 420 deletions(-) create mode 100644 apps/keymaps/keymap-mini2440.c create mode 100644 firmware/drivers/audio/uda1341.c create mode 100644 firmware/export/uda1341.h create mode 100644 firmware/target/arm/s3c2440/adc-s3c2440.c delete mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c delete mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c delete mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h create mode 100644 firmware/target/arm/s3c2440/i2c-s3c2440.c create mode 100644 firmware/target/arm/s3c2440/i2c-s3c2440.h create mode 100644 firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c create mode 100644 firmware/target/arm/s3c2440/mini2440/powermgmt-mini2440.c diff --git a/apps/SOURCES b/apps/SOURCES index 6ec1732881..6c0b12c88f 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -254,4 +254,6 @@ keymaps/keymap-ondavx777.c keymaps/keymap-ondavx767.c #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD keymaps/keymap-yh8xx_yh9xx.c +#elif CONFIG_KEYPAD == MINI2440_PAD +keymaps/keymap-mini2440.c #endif diff --git a/apps/keymaps/keymap-mini2440.c b/apps/keymaps/keymap-mini2440.c new file mode 100644 index 0000000000..4291bdfb68 --- /dev/null +++ b/apps/keymaps/keymap-mini2440.c @@ -0,0 +1,389 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Bob Cousins + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* Button Code Definitions for the Mini2440 target + * based on Toshiba Gigabeat F keymap + */ +#include +#include +#include + +#include "config.h" +#include "action.h" +#include "button.h" +#include "settings.h" + +/* + * The format of the list is as follows + * { Action Code, Button code, Prereq button code } + * if there's no need to check the previous button's value, use BUTTON_NONE + * Insert LAST_ITEM_IN_LIST at the end of each mapping + */ + +/* CONTEXT_CUSTOM's used in this file... + +CONTEXT_CUSTOM|CONTEXT_TREE = the standard list/tree defines (without directions) +CONTEXT_CUSTOM|CONTEXT_SETTINGS = the direction keys for the eq/col picker screens + i.e where up/down is inc/dec + CONTEXT_SETTINGS = up/down is prev/next, l/r is inc/dec + +*/ + + +static const struct button_mapping button_context_standard[] = { + { ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_STD_CANCEL, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, + + { ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT,BUTTON_SELECT }, + + { ACTION_STD_QUICKSCREEN, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU }, + { ACTION_STD_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, + + { ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT }, + { ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST +}; /* button_context_standard */ + + +static const struct button_mapping button_context_wps[] = { + { ACTION_WPS_PLAY, BUTTON_A|BUTTON_REL, BUTTON_A }, + { ACTION_WPS_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, + + { ACTION_WPS_SKIPNEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT }, + { ACTION_WPS_SKIPPREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, + + { ACTION_WPS_SEEKBACK, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_SEEKFWD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_STOPSEEK, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT }, + { ACTION_WPS_STOPSEEK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT }, + + { ACTION_WPS_ABSETB_NEXTDIR,BUTTON_A|BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_WPS_ABSETA_PREVDIR,BUTTON_A|BUTTON_LEFT, BUTTON_NONE }, + { ACTION_WPS_ABRESET, BUTTON_A|BUTTON_SELECT, BUTTON_NONE }, + + { ACTION_WPS_VOLDOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_UP, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE }, + + { ACTION_WPS_PITCHSCREEN, BUTTON_A|BUTTON_UP, BUTTON_A }, + { ACTION_WPS_VIEW_PLAYLIST, BUTTON_A|BUTTON_DOWN, BUTTON_NONE }, + + { ACTION_WPS_QUICKSCREEN, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU }, + { ACTION_WPS_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, + { ACTION_WPS_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT }, + + { ACTION_WPS_ID3SCREEN, BUTTON_A|BUTTON_MENU, BUTTON_NONE }, + { ACTION_WPS_BROWSE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT }, + + LAST_ITEM_IN_LIST +}; /* button_context_wps */ + +static const struct button_mapping button_context_list[] = { + { ACTION_LISTTREE_PGUP, BUTTON_A|BUTTON_UP, BUTTON_A }, + { ACTION_LISTTREE_PGUP, BUTTON_UP|BUTTON_REL, BUTTON_A|BUTTON_UP }, + { ACTION_LISTTREE_PGUP, BUTTON_A|BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_LISTTREE_PGDOWN, BUTTON_A|BUTTON_DOWN, BUTTON_A }, + { ACTION_LISTTREE_PGDOWN, BUTTON_DOWN|BUTTON_REL, BUTTON_A|BUTTON_DOWN }, + { ACTION_LISTTREE_PGDOWN, BUTTON_A|BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, +#ifdef HAVE_VOLUME_IN_LIST + { ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_LIST_VOLUP, BUTTON_VOL_UP, BUTTON_NONE }, + { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE }, + { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, +#endif + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_list */ + +static const struct button_mapping button_context_tree[] = { + { ACTION_TREE_WPS, BUTTON_A|BUTTON_REL, BUTTON_A }, + { ACTION_TREE_STOP, BUTTON_POWER, BUTTON_NONE }, + { ACTION_TREE_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, + { ACTION_TREE_STOP, BUTTON_POWER|BUTTON_REPEAT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST) +}; /* button_context_tree */ + +static const struct button_mapping button_context_listtree_scroll_with_combo[] = { + { ACTION_NONE, BUTTON_A, BUTTON_NONE }, + { ACTION_TREE_PGLEFT, BUTTON_A|BUTTON_LEFT, BUTTON_A }, + { ACTION_TREE_PGLEFT, BUTTON_LEFT|BUTTON_REL, BUTTON_A|BUTTON_LEFT }, + { ACTION_TREE_PGLEFT, BUTTON_A|BUTTON_LEFT, BUTTON_LEFT|BUTTON_REL }, + { ACTION_TREE_ROOT_INIT, BUTTON_A|BUTTON_LEFT|BUTTON_REPEAT, BUTTON_A|BUTTON_LEFT }, + { ACTION_TREE_PGLEFT, BUTTON_A|BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_TREE_PGRIGHT, BUTTON_A|BUTTON_RIGHT, BUTTON_A }, + { ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_REL, BUTTON_A|BUTTON_RIGHT }, + { ACTION_TREE_PGRIGHT, BUTTON_A|BUTTON_RIGHT, BUTTON_RIGHT|BUTTON_REL }, + { ACTION_TREE_PGRIGHT, BUTTON_A|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE), +}; + +static const struct button_mapping button_context_listtree_scroll_without_combo[] = { + { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, + { ACTION_TREE_ROOT_INIT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_LEFT }, + { ACTION_TREE_PGLEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_TREE_PGLEFT, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT }, + { ACTION_NONE, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_STD_OK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT }, + { ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT }, + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE), +}; + +static const struct button_mapping button_context_settings[] = { + { ACTION_SETTINGS_INC, BUTTON_UP, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_RESET, BUTTON_A, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_settings */ + +static const struct button_mapping button_context_settings_right_is_inc[] = { + { ACTION_SETTINGS_INC, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_DEC, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_RESET, BUTTON_A, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_settingsgraphical */ + +static const struct button_mapping button_context_yesno[] = { + { ACTION_YESNO_ACCEPT, BUTTON_SELECT, BUTTON_NONE }, + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_settings_yesno */ + +static const struct button_mapping button_context_colorchooser[] = { + { ACTION_STD_OK, BUTTON_A|BUTTON_REL, BUTTON_NONE }, + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS), +}; /* button_context_colorchooser */ + +static const struct button_mapping button_context_eq[] = { + { ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE }, + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS), +}; /* button_context_eq */ + +/** Bookmark Screen **/ +static const struct button_mapping button_context_bmark[] = { + { ACTION_BMS_DELETE, BUTTON_A, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), +}; /* button_context_bmark */ + +static const struct button_mapping button_context_time[] = { + { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, + { ACTION_STD_OK, BUTTON_A, BUTTON_NONE }, + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS), +}; /* button_context_time */ + +static const struct button_mapping button_context_quickscreen[] = { + { ACTION_QS_TOP, BUTTON_UP, BUTTON_NONE }, + { ACTION_QS_TOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_QS_DOWN, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_QS_LEFT, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_QS_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_MENU, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_quickscreen */ + +static const struct button_mapping button_context_pitchscreen[] = { + { ACTION_PS_INC_SMALL, BUTTON_UP, BUTTON_NONE }, + { ACTION_PS_INC_BIG, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_PS_DEC_SMALL, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_PS_DEC_BIG, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_PS_NUDGE_LEFT, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_MENU, BUTTON_NONE }, + { ACTION_PS_RESET, BUTTON_A, BUTTON_NONE }, + { ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE }, + { ACTION_PS_SLOWER, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_PS_FASTER, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_pitchcreen */ + +static const struct button_mapping button_context_keyboard[] = { + { ACTION_KBD_LEFT, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_KBD_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_KBD_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_CURSOR_LEFT, BUTTON_A|BUTTON_LEFT, BUTTON_NONE }, + { ACTION_KBD_CURSOR_LEFT, BUTTON_A|BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_CURSOR_RIGHT, BUTTON_A|BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_KBD_CURSOR_RIGHT, BUTTON_A|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_SELECT, BUTTON_SELECT, BUTTON_NONE }, + { ACTION_KBD_PAGE_FLIP, BUTTON_A|BUTTON_MENU, BUTTON_NONE }, + { ACTION_KBD_DONE, BUTTON_A|BUTTON_REL, BUTTON_A }, + { ACTION_KBD_ABORT, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, + { ACTION_KBD_BACKSPACE, BUTTON_MENU, BUTTON_NONE }, + { ACTION_KBD_BACKSPACE, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_UP, BUTTON_UP, BUTTON_NONE }, + { ACTION_KBD_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_DOWN, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_KBD_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_MORSE_INPUT, BUTTON_A|BUTTON_POWER, BUTTON_NONE }, + { ACTION_KBD_MORSE_SELECT, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE }, + + LAST_ITEM_IN_LIST +}; /* button_context_keyboard */ + +#ifdef HAVE_MINI2440_REMOTE +/***************************************************************************** + * Remote control mappings + *****************************************************************************/ + +static const struct button_mapping remote_button_context_standard[] = { + { ACTION_STD_PREV, BUTTON_RC_VOL_UP, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_RC_VOL_DOWN, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_RC_REW, BUTTON_NONE }, + { ACTION_STD_OK, BUTTON_RC_FF|BUTTON_REL, BUTTON_RC_FF }, + { ACTION_STD_CONTEXT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_RC_FF }, + { ACTION_STD_MENU, BUTTON_RC_DSP, BUTTON_NONE }, + + LAST_ITEM_IN_LIST +}; + +static const struct button_mapping remote_button_context_wps[] = { + { ACTION_WPS_PLAY, BUTTON_RC_PLAY, BUTTON_NONE }, + + { ACTION_WPS_SKIPNEXT, BUTTON_RC_FF|BUTTON_REL, BUTTON_RC_FF }, + { ACTION_WPS_SKIPPREV, BUTTON_RC_REW|BUTTON_REL, BUTTON_RC_REW }, + + { ACTION_WPS_SEEKBACK, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_SEEKFWD, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_STOPSEEK, BUTTON_RC_REW|BUTTON_REL, BUTTON_RC_REW|BUTTON_REPEAT }, + { ACTION_WPS_STOPSEEK, BUTTON_RC_FF|BUTTON_REL, BUTTON_RC_FF|BUTTON_REPEAT }, + + { ACTION_WPS_STOP, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_RC_PLAY }, + { ACTION_WPS_MENU, BUTTON_RC_DSP, BUTTON_NONE }, + + { ACTION_WPS_VOLDOWN, BUTTON_RC_VOL_DOWN, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_RC_VOL_UP, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; + +static const struct button_mapping remote_button_context_tree[] = { + { ACTION_TREE_WPS, BUTTON_RC_PLAY|BUTTON_REL, BUTTON_RC_PLAY }, + { ACTION_TREE_STOP, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_RC_PLAY }, + { ACTION_STD_CANCEL, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; + +static const struct button_mapping* get_context_mapping_remote( int context ) +{ + context ^= CONTEXT_REMOTE; + + switch (context) + { + case CONTEXT_WPS: + return remote_button_context_wps; + case CONTEXT_MAINMENU: + case CONTEXT_TREE: + return remote_button_context_tree; + } + return remote_button_context_standard; +} +#endif + +const struct button_mapping* get_context_mapping(int context) +{ +#ifdef HAVE_MINI2440_REMOTE + if (context&CONTEXT_REMOTE) + return get_context_mapping_remote(context); +#endif + switch (context) + { + case CONTEXT_STD: + return button_context_standard; + case CONTEXT_WPS: + return button_context_wps; + + case CONTEXT_LIST: + return button_context_list; + case CONTEXT_MAINMENU: + case CONTEXT_TREE: + if (global_settings.hold_lr_for_scroll_in_list) + return button_context_listtree_scroll_without_combo; + else + return button_context_listtree_scroll_with_combo; + case CONTEXT_CUSTOM|CONTEXT_TREE: + return button_context_tree; + + case CONTEXT_SETTINGS: + return button_context_settings; + case CONTEXT_CUSTOM|CONTEXT_SETTINGS: + return button_context_settings_right_is_inc; + + case CONTEXT_SETTINGS_COLOURCHOOSER: + return button_context_colorchooser; + case CONTEXT_SETTINGS_EQ: + return button_context_eq; + + case CONTEXT_SETTINGS_TIME: + return button_context_time; + + case CONTEXT_YESNOSCREEN: + return button_context_yesno; + case CONTEXT_BOOKMARKSCREEN: + return button_context_bmark; + case CONTEXT_QUICKSCREEN: + return button_context_quickscreen; + case CONTEXT_PITCHSCREEN: + return button_context_pitchscreen; + case CONTEXT_KEYBOARD: + return button_context_keyboard; + } + return button_context_standard; +} diff --git a/bootloader/mini2440.c b/bootloader/mini2440.c index dd811600f3..09698ed833 100644 --- a/bootloader/mini2440.c +++ b/bootloader/mini2440.c @@ -47,13 +47,9 @@ #include "uart-s3c2440.h" #include "led-mini2440.h" -/* Show the Rockbox logo - in show_logo.c */ -extern int show_logo(void); - int main(void) { - /* required later */ unsigned char* loadbuffer; int buffer_size; int rc; @@ -70,12 +66,12 @@ int main(void) lcd_setfont(FONT_SYSFIXED); button_init(); dma_init(); - uart_init_device(UART_DEBUG); + + uart_init(); + uart_init_device(DEBUG_UART_PORT); /* mini2440_test(); */ - /* TODO */ - /* Show debug messages if button is pressed */ if(button_read_device() & BUTTON_MENU) verbose = true; diff --git a/firmware/SOURCES b/firmware/SOURCES index 5406b161ad..2c666cb27c 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -809,11 +809,11 @@ target/arm/usb-fw-pp502x.c #ifndef SIMULATOR target/arm/lcd-as-memframe.S target/arm/mmu-arm.S +target/arm/s3c2440/adc-s3c2440.c target/arm/s3c2440/debug-s3c2440.c target/arm/s3c2440/kernel-s3c2440.c target/arm/s3c2440/lcd-s3c2440.c target/arm/s3c2440/system-s3c2440.c -target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c target/arm/s3c2440/gigabeat-fx/button-meg-fx.c @@ -821,7 +821,7 @@ target/arm/s3c2440/gigabeat-fx/power-meg-fx.c target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c #ifndef BOOTLOADER -target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c +target/arm/s3c2440/i2c-s3c2440.c target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c target/arm/s3c2440/gigabeat-fx/powermgmt-meg-fx.c target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c @@ -1405,20 +1405,16 @@ target/arm/s3c2440/lcd-s3c2440.c target/arm/s3c2440/sd-s3c2440.c target/arm/s3c2440/system-s3c2440.c target/arm/s3c2440/uart-s3c2440.c +target/arm/s3c2440/adc-s3c2440.c +target/arm/s3c2440/i2c-s3c2440.c target/arm/s3c2440/mini2440/backlight-mini2440.c target/arm/s3c2440/mini2440/button-mini2440.c target/arm/s3c2440/mini2440/led-mini2440.c target/arm/s3c2440/mini2440/power-mini2440.c -#ifdef BOOTLOADER -#endif #ifndef BOOTLOADER -target/arm/s3c2440/mini2440/adc-mini2440.c -//target/arm/s3c2440/mini2440/i2c-mini2440.c -target/arm/s3c2440/mini2440/pcm-mini2440.c target/arm/s3c2440/mini2440/powermgmt-mini2440.c -target/arm/s3c2440/mini2440/power-mini2440.c -target/arm/s3c2440/mini2440/timer-mini2440.c -//target/arm/s3c2440/mini2440/usb-mini2440.c +target/arm/s3c2440/mini2440/pcm-mini2440.c +target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c #endif #endif /* SIMULATOR */ #endif /* MINI2440 */ diff --git a/firmware/drivers/audio/uda1341.c b/firmware/drivers/audio/uda1341.c new file mode 100644 index 0000000000..f9d95eff02 --- /dev/null +++ b/firmware/drivers/audio/uda1341.c @@ -0,0 +1,184 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: uda1380.c 21975 2009-07-19 22:45:32Z bertrik $ + * + * Copyright (C) 2009 by Bob Cousins + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include + +#include "config.h" +#include "logf.h" +#include "system.h" +#include "audio.h" +#include "debug.h" + +#include "audiohw.h" + + +const struct sound_settings_info audiohw_settings[] = { + [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25}, + [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0}, + [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0}, + [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, + [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, + [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, +#ifdef HAVE_RECORDING + [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, + [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, + [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, +#endif +}; + +/****************************************************************************/ + +/* ------------------------------------------------- */ +/* Local functions and variables */ +/* ------------------------------------------------- */ + +/* Generic L3 functions */ + +#define L3PORT GPBDAT +#define L3MODE (1 << 2) +#define L3DATA (1 << 3) +#define L3CLOCK (1 << 4) + +static void l3_init (void) +{ + L3PORT |= L3MODE | L3CLOCK; + L3PORT &= L3DATA; + + S3C2440_GPIO_CONFIG (GPBCON, 2, GPIO_OUTPUT); /* L3 MODE */ + S3C2440_GPIO_CONFIG (GPBCON, 3, GPIO_OUTPUT); /* L3 DATA */ + S3C2440_GPIO_CONFIG (GPBCON, 4, GPIO_OUTPUT); /* L3 CLOCK */ + + S3C2440_GPIO_PULLUP (GPBUP, 2, GPIO_PULLUP_DISABLE); + S3C2440_GPIO_PULLUP (GPBUP, 3, GPIO_PULLUP_DISABLE); + S3C2440_GPIO_PULLUP (GPBUP, 4, GPIO_PULLUP_DISABLE); +} + +static void bit_delay (void) +{ + int j; + for (j=0; j<4; j++) + ; +} + +static void l3_write_byte (unsigned char data, bool address_mode) +{ + int bit; + + L3PORT |= L3CLOCK; + if (address_mode) + L3PORT &= ~L3MODE; + else + L3PORT |= L3MODE; + + for (bit=0; bit < 8; bit++) + { + if (data & 1) + { + L3PORT |= L3DATA; + } + else + { + L3PORT &= ~L3DATA; + } + L3PORT &= ~L3CLOCK; + bit_delay(); + L3PORT |= L3CLOCK; + bit_delay(); + + data >>= 1; + } + + if (address_mode) + L3PORT |= L3MODE; + else + L3PORT &= ~L3MODE; + bit_delay(); +} + +static void l3_write_addr (unsigned char addr) +{ + /* write address byte */ + l3_write_byte (addr, true); +} + +static void l3_write_data (unsigned char data) +{ + /* write data byte */ + l3_write_byte (data, false); +} + +/****************************************************************************/ + +/* UDA1341 access functions */ + +static int udacodec_write(unsigned char reg, unsigned short value) +{ + l3_write_addr (UDA1341_ADDR | reg); + l3_write_data (value & 0xff); + return 0; +} + +static void udacodec_reset(void) +{ + /* uda reset */ + l3_init(); + + udacodec_write (UDA_REG_STATUS, UDA_STATUS_0 | UDA_RESET | UDA_SYSCLK_256FS | + I2S_IFMT_IIS); + udacodec_write (UDA_REG_STATUS, UDA_STATUS_0 | UDA_SYSCLK_256FS | I2S_IFMT_IIS); + udacodec_write (UDA_REG_STATUS, UDA_STATUS_1 | UDA_POWER_DAC_ON); +} + +/****************************************************************************/ + +/* Audio API functions */ + +void audiohw_init(void) +{ + udacodec_reset(); +} + +void audiohw_close(void) +{ +} + +void audiohw_set_bass(int value) +{ +} + +void audiohw_set_treble(int value) +{ +} + +void audiohw_mute(bool mute) +{ +} + +void audiohw_set_prescaler(int val) +{ +} + +void audiohw_postinit(void) +{ +} + +void audiohw_set_frequency(int fsel) +{ +} diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 66fc19f923..91df2dd8b9 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -36,6 +36,8 @@ #ifdef HAVE_UDA1380 #include "uda1380.h" +#elif defined(HAVE_UDA1341) +#include "uda1341.h" #elif defined(HAVE_WM8751) #include "wm8751.h" #elif defined(HAVE_WM8978) diff --git a/firmware/export/config-mini2440.h b/firmware/export/config-mini2440.h index 0db027c7a0..b9d5dadf9c 100644 --- a/firmware/export/config-mini2440.h +++ b/firmware/export/config-mini2440.h @@ -39,9 +39,11 @@ /* define the storage type */ #define CONFIG_STORAGE STORAGE_SD +/* #define HAVE_MULTIDRIVE #define NUM_DRIVES 2 #define HAVE_HOTSWAP +*/ /* Disk storage */ /* define this if you have a disk storage, i.e. something @@ -62,7 +64,7 @@ #define LCD_DEPTH 16 /* 65536 colours */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ /* Define this for LCD backlight available */ -/* The Mini2440 supports backight brightness depending on LCD type */ +/* The Mini2440 supports backlight brightness depending on LCD type */ /* But the 3.5" LCD touch screen does not support brightness*/ #define HAVE_BACKLIGHT #define HAVE_BACKLIGHT_BRIGHTNESS @@ -71,15 +73,17 @@ #define CONFIG_KEYPAD MINI2440_PAD /* I2C */ -/* Do not use I2C */ -#define CONFIG_I2C I2C_NONE +/* We do not use currently use hardware I2C, but does not build without */ +#define CONFIG_I2C I2C_S3C2440 /* Define DAC/Codec */ -/*#define HAVE_UDA1341*/ -#define HAVE_TLV320 +#define HAVE_UDA1341 /* ... tone controls, use the software ones */ #define HAVE_SW_TONE_CONTROLS +#define HW_SAMPR_CAPS (SAMPR_CAP_64 | SAMPR_CAP_44 | SAMPR_CAP_22 | \ + SAMPR_CAP_11) + /* Battery */ #define BATTERY_CAPACITY_DEFAULT 1100 /* default battery capacity */ #define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */ @@ -89,6 +93,9 @@ /* USB */ /* TODO:#define HAVE_USBSTACK */ +#define USB_NONE + +#define HAVE_SERIAL /***************************************************************************/ /* Application Config */ diff --git a/firmware/export/s3c2440.h b/firmware/export/s3c2440.h index c783b37f29..b6ba79a34e 100644 --- a/firmware/export/s3c2440.h +++ b/firmware/export/s3c2440.h @@ -462,6 +462,39 @@ #define IISFCON (*(volatile unsigned long *)0x5500000C) /* IIS FIFO control */ #define IISFIFO (*(volatile unsigned short *)0x55000010) /* IIS FIFO entry */ +#define IISCON_RIGHT_CHANNEL (1 << 8) +#define IISCON_TX_FIFO_NOT_EMPTY (1 << 7) +#define IISCON_RX_FIFO_NOT_FULL (1 << 6) +#define IISCON_TX_DMA_REQUEST (1 << 5) +#define IISCON_RX_DMA_REQUEST (1 << 4) +#define IISCON_TX_IDLE (1 << 3) +#define IISCON_RX_IDLE (1 << 2) +#define IISCON_IIS_PRESCALER_ENABLE (1 << 1) +#define IISCON_IIS_INTERFACE_ENABLE (1 << 0) + +#define IISMOD_MASTER_CLOCK_PCLK (0 << 9) +#define IISMOD_MASTER_CLOCK_MPLLIN (1 << 9) +#define IISMOD_MASTER_MODE (0 << 8) +#define IISMOD_SLAVE_MODE (1 << 8) +#define IISMOD_NO_TRANSFER (0 << 6) +#define IISMOD_RECEIVE_MODE (1 << 6) +#define IISMOD_TRANSMIT_MODE (2 << 6) +#define IISMOD_TRANSMIT_RECEIVE_MODE (3 << 6) +#define IISMOD_LOW_LEFT (0 << 5) +#define IISMOD_HIGH_LEFT (1 << 5) +#define IISMOD_IIS (0 << 4) +#define IISMOD_MSB (1 << 4) +#define IISMOD_8_BIT (0 << 3) +#define IISMOD_16_BIT (1 << 3) +#define IISMOD_MASTER_CLOCK_256FS (0 << 2) +#define IISMOD_MASTER_CLOCK_384FS (1 << 2) +#define IISMOD_BIT_CLOCK_16FS (0 << 0) +#define IISMOD_BIT_CLOCK_32FS (1 << 0) +#define IISMOD_BIT_CLOCK_48FS (2 << 0) + +#define IISPSR_PRESCALER_A (1 << 5) +#define IISPSR_PRESCALER_B (1 << 0) + /* I/O port */ #define GPACON (*(volatile unsigned long *)0x56000000) /* Port A control */ diff --git a/firmware/export/uda1341.h b/firmware/export/uda1341.h new file mode 100644 index 0000000000..dcbbeef8e5 --- /dev/null +++ b/firmware/export/uda1341.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _UDA1341_H +#define _UDA1341_H + +/* volume/balance/treble/bass interdependency */ +#define VOLUME_MIN -840 +#define VOLUME_MAX 0 + +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP) + +extern int tenthdb2master(int db); +extern int tenthdb2mixer(int db); + +extern void audiohw_set_master_vol(int vol_l, int vol_r); +extern void audiohw_set_mixer_vol(int channel1, int channel2); + +/* Address byte */ +#define UDA1341_ADDR 0x14 +#define UDA_REG_DATA0 0x00 +#define UDA_REG_DATA1 0x01 +#define UDA_REG_STATUS 0x02 + +/* STATUS */ +#define UDA_STATUS_0 (0 << 7) +#define UDA_STATUS_1 (1 << 7) + +#define UDA_RESET (1 << 6) +#define UDA_SYSCLK_512FS (0 << 4) +#define UDA_SYSCLK_384FS (1 << 4) +#define UDA_SYSCLK_256FS (2 << 4) +#define I2S_IFMT_IIS (0 << 1) +#define I2S_IFMT_LSB16 (1 << 1) +#define I2S_IFMT_LSB18 (2 << 1) +#define I2S_IFMT_LSB20 (3 << 1) +#define I2S_IFMT_MSB (4 << 1) +#define I2S_IFMT_LSB16_OFMT_MSB (5 << 1) +#define I2S_IFMT_LSB18_OFMT_MSB (6 << 1) +#define I2S_IFMT_LSB20_OFMT_MSB (7 << 1) +#define UDA_DC_FILTER (1 << 0) + +#define UDA_OUTPUT_GAIN (1 << 6) +#define UDA_INPUT_GAIN (1 << 5) +#define UDA_ADC_INVERT (1 << 4) +#define UDA_DAC_INVERT (1 << 3) +#define UDA_DOUBLE_SPEED (1 << 2) +#define UDA_POWER_ADC_ON (1 << 1) +#define UDA_POWER_DAC_ON (1 << 0) + +/* DATA0 */ +#define UDA_DATA_CTRL0 (0 << 6) +#define UDA_DATA_CTRL1 (1 << 6) +#define UDA_DATA_CTRL2 (2 << 6) +#define UDA_DATA_EXT_ADDR (6 << 5) +#define UDA_DATA_EXT_DATA (7 << 5) + +#define UDA_VOLUME(x) ((x) << 8) /* 1=0dB, 61=-60dB */ + +#define UDA_BASS_BOOST(x) ((x) << 2) /* see datasheet */ +#define UDA_TREBLE(x) ((x) << 0) /* see datasheet */ + +#define UDA_PEAK_DETECT_POS (1 << 5) +#define UDA_DE_EMPHASIS_NONE (0 << 3) +#define UDA_DE_EMPHASIS_32 (1 << 3) +#define UDA_DE_EMPHASIS_44_1 (2 << 3) +#define UDA_DE_EMPHASIS_48 (3 << 3) +#define UDA_MUTE (1 << 2) +#define UDA_MODE_SWITCH_FLAT (0 << 0) +#define UDA_MODE_SWITCH_MIN (1 << 0) +#define UDA_MODE_SWITCH_MAX (3 << 0) + +#define UDA_EXT_0 (0 << 5) /* Mixer Gain Chan 1 */ +#define UDA_EXT_1 (1 << 5) /* Mixer Gain Chan 2 */ +#define UDA_EXT_2 (2 << 5) /* Mic sens and mixer mode */ +#define UDA_EXT_4 (4 << 5) /* AGC, Input amp gain */ +#define UDA_EXT_5 (5 << 5) /* Input amp gain */ +#define UDA_EXT_6 (6 << 5) /* AGC settings */ + +/* TODO: DATA0 extended registers */ + +/* DATA1: see datasheet */ + +#endif /* _UDA_1341_H */ diff --git a/firmware/target/arm/s3c2440/adc-s3c2440.c b/firmware/target/arm/s3c2440/adc-s3c2440.c new file mode 100644 index 0000000000..fd5151a3bf --- /dev/null +++ b/firmware/target/arm/s3c2440/adc-s3c2440.c @@ -0,0 +1,140 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Wade Brown + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "cpu.h" +#include "system.h" +#include "adc.h" +#include "adc-target.h" +#include "kernel.h" + +static unsigned short adc_readings[NUM_ADC_CHANNELS]; + +/* prototypes */ +static unsigned short __adc_read(int channel); +static void adc_tick(void); + +void adc_init(void) +{ + int i; + + /* Turn on the ADC PCLK */ + s3c_regset32(&CLKCON, 1<<15); + + /* Set channel 0, normal mode, disable "start by read" */ + ADCCON &= ~(0x3F); + + /* No start delay. Use normal conversion mode. */ + ADCDLY = 0x1; + + /* Set and enable the prescaler */ + ADCCON = (ADCCON & ~(0xff<<6)) | (0x19<<6); + ADCCON |= (1<<14); + + /* prefill the adc channels */ + for (i = 0; i < NUM_ADC_CHANNELS; i++) + { + adc_readings[i] = __adc_read(i); + } + + /* start at zero so when the tick starts it is at zero */ + adc_readings[0] = __adc_read(0); + + /* attach the adc reading to the tick */ + tick_add_task(adc_tick); +} + +/* Called to get the recent ADC reading */ +inline unsigned short adc_read(int channel) +{ + return adc_readings[channel]; +} + +/** + * Read the ADC by polling + * @param channel The ADC channel to read + * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout + */ +static unsigned short __adc_read(int channel) +{ + int i; + + /* Set the channel */ + ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3); + + /* Start the conversion process */ + ADCCON |= 0x1; + + /* Wait for a low Enable_start */ + for (i = 20000;;) + { + if(0 == (ADCCON & 0x1)) + { + break; + } + else + { + i--; + if (0 == i) + { + /* Ran out of time */ + return ADC_READ_ERROR; + } + } + } + + /* Wait for high End_of_Conversion */ + for(i = 20000;;) + { + if(ADCCON & (1<<15)) + { + break; + } + else + { + i--; + if(0 == i) + { + /* Ran out of time */ + return ADC_READ_ERROR; + } + } + } + return (ADCDAT0 & 0x3ff); +} + +/* add this to the tick so that the ADC converts are done in the background */ +static void adc_tick(void) +{ + static unsigned channel; + + /* Check if the End Of Conversion is set */ + if (ADCCON & (1<<15)) + { + adc_readings[channel] = (ADCDAT0 & 0x3FF); + if (++channel >= NUM_ADC_CHANNELS) + { + channel = 0; + } + + /* setup the next conversion and start it*/ + ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3) | 0x01; + } +} + diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c deleted file mode 100644 index fd5151a3bf..0000000000 --- a/firmware/target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Wade Brown - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "cpu.h" -#include "system.h" -#include "adc.h" -#include "adc-target.h" -#include "kernel.h" - -static unsigned short adc_readings[NUM_ADC_CHANNELS]; - -/* prototypes */ -static unsigned short __adc_read(int channel); -static void adc_tick(void); - -void adc_init(void) -{ - int i; - - /* Turn on the ADC PCLK */ - s3c_regset32(&CLKCON, 1<<15); - - /* Set channel 0, normal mode, disable "start by read" */ - ADCCON &= ~(0x3F); - - /* No start delay. Use normal conversion mode. */ - ADCDLY = 0x1; - - /* Set and enable the prescaler */ - ADCCON = (ADCCON & ~(0xff<<6)) | (0x19<<6); - ADCCON |= (1<<14); - - /* prefill the adc channels */ - for (i = 0; i < NUM_ADC_CHANNELS; i++) - { - adc_readings[i] = __adc_read(i); - } - - /* start at zero so when the tick starts it is at zero */ - adc_readings[0] = __adc_read(0); - - /* attach the adc reading to the tick */ - tick_add_task(adc_tick); -} - -/* Called to get the recent ADC reading */ -inline unsigned short adc_read(int channel) -{ - return adc_readings[channel]; -} - -/** - * Read the ADC by polling - * @param channel The ADC channel to read - * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout - */ -static unsigned short __adc_read(int channel) -{ - int i; - - /* Set the channel */ - ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3); - - /* Start the conversion process */ - ADCCON |= 0x1; - - /* Wait for a low Enable_start */ - for (i = 20000;;) - { - if(0 == (ADCCON & 0x1)) - { - break; - } - else - { - i--; - if (0 == i) - { - /* Ran out of time */ - return ADC_READ_ERROR; - } - } - } - - /* Wait for high End_of_Conversion */ - for(i = 20000;;) - { - if(ADCCON & (1<<15)) - { - break; - } - else - { - i--; - if(0 == i) - { - /* Ran out of time */ - return ADC_READ_ERROR; - } - } - } - return (ADCDAT0 & 0x3ff); -} - -/* add this to the tick so that the ADC converts are done in the background */ -static void adc_tick(void) -{ - static unsigned channel; - - /* Check if the End Of Conversion is set */ - if (ADCCON & (1<<15)) - { - adc_readings[channel] = (ADCDAT0 & 0x3FF); - if (++channel >= NUM_ADC_CHANNELS) - { - channel = 0; - } - - /* setup the next conversion and start it*/ - ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3) | 0x01; - } -} - diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c deleted file mode 100644 index 836dedd462..0000000000 --- a/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Michael Sevakis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "system.h" -#include "i2c-meg-fx.h" - -static struct wakeup i2c_wake; /* Transfer completion signal */ -static struct mutex i2c_mtx; /* Mutual exclusion */ -static unsigned char *buf_ptr; /* Next byte to transfer */ -static int buf_count; /* Number of bytes remaining to transfer */ - -static void i2c_stop(void) -{ - /* Generate STOP */ - IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_RXTX_ENB; - - /* No more interrupts, clear pending interrupt to continue */ - IICCON &= ~(I2C_TXRX_INTPND | I2C_TXRX_INTENB); -} - -void i2c_write(int addr, const unsigned char *buf, int count) -{ - if (count <= 0) - return; - - mutex_lock(&i2c_mtx); - - /* Turn on I2C clock */ - s3c_regset32(&CLKCON, 1 << 16); - - /* Set mode to master transmitter and enable lines */ - IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_RXTX_ENB; - - /* Set buffer start and count */ - buf_ptr = (unsigned char *)buf; - buf_count = count; - - /* Send slave address and then data */ - SRCPND = IIC_MASK; - INTPND = IIC_MASK; - - IICCON |= I2C_TXRX_INTENB; - - /* Load slave address into shift register */ - IICDS = addr & 0xfe; - - /* Generate START */ - IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_START | I2C_RXTX_ENB; - - if (wakeup_wait(&i2c_wake, HZ) != OBJ_WAIT_SUCCEEDED) - { - /* Something went wrong - stop transmission */ - int oldlevel = disable_irq_save(); - i2c_stop(); - restore_irq(oldlevel); - } - - /* Go back to slave receive mode and disable lines */ - IICSTAT = 0; - - /* Turn off I2C clock */ - s3c_regclr32(&CLKCON, 1 << 16); - - mutex_unlock(&i2c_mtx); -} - -void i2c_init(void) -{ - /* Init kernel objects */ - wakeup_init(&i2c_wake); - mutex_init(&i2c_mtx); - - /* Clear pending source */ - SRCPND = IIC_MASK; - INTPND = IIC_MASK; - - /* Enable i2c interrupt in controller */ - s3c_regclr32(&INTMOD, IIC_MASK); - s3c_regclr32(&INTMSK, IIC_MASK); - - /* Turn on I2C clock */ - s3c_regset32(&CLKCON, 1 << 16); - - /* Set GPE15 (IICSDA) and GPE14 (IICSCL) to IIC */ - GPECON = (GPECON & ~((3 << 30) | (3 << 28))) | - ((2 << 30) | (2 << 28)); - - /* Bus ACK, IICCLK: fPCLK / 16, Rx/Tx Int: Disable, Tx clock: IICCLK/8 */ - /* OF PCLK: 49.1568MHz / 16 / 8 = 384.0375 kHz */ - IICCON = (7 << 0); - - /* SDA line delayed 0 PCLKs */ - IICLC = (0 << 0); - - /* Turn off I2C clock */ - s3c_regclr32(&CLKCON, 1 << 16); -} - -void IIC(void) -{ - for (;;) - { - /* If ack was received from last byte and bytes are remaining */ - if (--buf_count >= 0 && (IICSTAT & I2C_ACK_L) == 0) - { - /* Write next byte to shift register */ - IICDS = *buf_ptr++; - - /* Clear pending interrupt to continue */ - IICCON &= ~I2C_TXRX_INTPND; - break; - } - - /* Finished */ - - /* Generate STOP */ - i2c_stop(); - - /* Signal thread */ - wakeup_signal(&i2c_wake); - break; - } - - /* Ack */ - SRCPND = IIC_MASK; - INTPND = IIC_MASK; -} diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h deleted file mode 100644 index 793ee213fd..0000000000 --- a/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Michael Sevakis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -/* chip-specific i2c functions */ - -/* IICCON */ -#define I2C_ACKGEN (1 << 7) -#define I2C_TXCLK_512 (1 << 6) -#define I2C_TXRX_INTENB (1 << 5) -#define I2C_TXRX_INTPND (1 << 4) - -/* IICSTAT */ -#define I2C_MODE_MASTER (2 << 6) -#define I2C_MODE_TX (1 << 6) -#define I2C_BUSY (1 << 5) -#define I2C_START (1 << 5) -#define I2C_RXTX_ENB (1 << 4) -#define I2C_BUS_ARB_FAILED (1 << 3) -#define I2C_S_ADDR_STAT (1 << 2) -#define I2C_S_ADDR_MATCH (1 << 1) -#define I2C_ACK_L (1 << 0) - -/* IICLC */ -#define I2C_FLT_ENB (1 << 2) - -void i2c_init(void); -void i2c_write(int addr, const unsigned char *data, int count); - diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c index 52c26b898d..01b177da6c 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c @@ -28,7 +28,7 @@ #include "cpu.h" #include "kernel.h" #include "sound.h" -#include "i2c-meg-fx.h" +#include "i2c-s3c2440.h" #include "system-target.h" #include "timer.h" #include "wmcodec.h" diff --git a/firmware/target/arm/s3c2440/i2c-s3c2440.c b/firmware/target/arm/s3c2440/i2c-s3c2440.c new file mode 100644 index 0000000000..4669186a4c --- /dev/null +++ b/firmware/target/arm/s3c2440/i2c-s3c2440.c @@ -0,0 +1,144 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "system.h" +#include "i2c-s3c2440.h" + +static struct wakeup i2c_wake; /* Transfer completion signal */ +static struct mutex i2c_mtx; /* Mutual exclusion */ +static unsigned char *buf_ptr; /* Next byte to transfer */ +static int buf_count; /* Number of bytes remaining to transfer */ + +static void i2c_stop(void) +{ + /* Generate STOP */ + IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_RXTX_ENB; + + /* No more interrupts, clear pending interrupt to continue */ + IICCON &= ~(I2C_TXRX_INTPND | I2C_TXRX_INTENB); +} + +void i2c_write(int addr, const unsigned char *buf, int count) +{ + if (count <= 0) + return; + + mutex_lock(&i2c_mtx); + + /* Turn on I2C clock */ + s3c_regset32(&CLKCON, 1 << 16); + + /* Set mode to master transmitter and enable lines */ + IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_RXTX_ENB; + + /* Set buffer start and count */ + buf_ptr = (unsigned char *)buf; + buf_count = count; + + /* Send slave address and then data */ + SRCPND = IIC_MASK; + INTPND = IIC_MASK; + + IICCON |= I2C_TXRX_INTENB; + + /* Load slave address into shift register */ + IICDS = addr & 0xfe; + + /* Generate START */ + IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_START | I2C_RXTX_ENB; + + if (wakeup_wait(&i2c_wake, HZ) != OBJ_WAIT_SUCCEEDED) + { + /* Something went wrong - stop transmission */ + int oldlevel = disable_irq_save(); + i2c_stop(); + restore_irq(oldlevel); + } + + /* Go back to slave receive mode and disable lines */ + IICSTAT = 0; + + /* Turn off I2C clock */ + s3c_regclr32(&CLKCON, 1 << 16); + + mutex_unlock(&i2c_mtx); +} + +void i2c_init(void) +{ + /* Init kernel objects */ + wakeup_init(&i2c_wake); + mutex_init(&i2c_mtx); + + /* Clear pending source */ + SRCPND = IIC_MASK; + INTPND = IIC_MASK; + + /* Enable i2c interrupt in controller */ + s3c_regclr32(&INTMOD, IIC_MASK); + s3c_regclr32(&INTMSK, IIC_MASK); + + /* Turn on I2C clock */ + s3c_regset32(&CLKCON, 1 << 16); + + /* Set GPE15 (IICSDA) and GPE14 (IICSCL) to IIC */ + GPECON = (GPECON & ~((3 << 30) | (3 << 28))) | + ((2 << 30) | (2 << 28)); + + /* Bus ACK, IICCLK: fPCLK / 16, Rx/Tx Int: Disable, Tx clock: IICCLK/8 */ + /* OF PCLK: 49.1568MHz / 16 / 8 = 384.0375 kHz */ + IICCON = (7 << 0); + + /* SDA line delayed 0 PCLKs */ + IICLC = (0 << 0); + + /* Turn off I2C clock */ + s3c_regclr32(&CLKCON, 1 << 16); +} + +void IIC(void) +{ + for (;;) + { + /* If ack was received from last byte and bytes are remaining */ + if (--buf_count >= 0 && (IICSTAT & I2C_ACK_L) == 0) + { + /* Write next byte to shift register */ + IICDS = *buf_ptr++; + + /* Clear pending interrupt to continue */ + IICCON &= ~I2C_TXRX_INTPND; + break; + } + + /* Finished */ + + /* Generate STOP */ + i2c_stop(); + + /* Signal thread */ + wakeup_signal(&i2c_wake); + break; + } + + /* Ack */ + SRCPND = IIC_MASK; + INTPND = IIC_MASK; +} diff --git a/firmware/target/arm/s3c2440/i2c-s3c2440.h b/firmware/target/arm/s3c2440/i2c-s3c2440.h new file mode 100644 index 0000000000..793ee213fd --- /dev/null +++ b/firmware/target/arm/s3c2440/i2c-s3c2440.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* chip-specific i2c functions */ + +/* IICCON */ +#define I2C_ACKGEN (1 << 7) +#define I2C_TXCLK_512 (1 << 6) +#define I2C_TXRX_INTENB (1 << 5) +#define I2C_TXRX_INTPND (1 << 4) + +/* IICSTAT */ +#define I2C_MODE_MASTER (2 << 6) +#define I2C_MODE_TX (1 << 6) +#define I2C_BUSY (1 << 5) +#define I2C_START (1 << 5) +#define I2C_RXTX_ENB (1 << 4) +#define I2C_BUS_ARB_FAILED (1 << 3) +#define I2C_S_ADDR_STAT (1 << 2) +#define I2C_S_ADDR_MATCH (1 << 1) +#define I2C_ACK_L (1 << 0) + +/* IICLC */ +#define I2C_FLT_ENB (1 << 2) + +void i2c_init(void); +void i2c_write(int addr, const unsigned char *data, int count); + diff --git a/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c new file mode 100644 index 0000000000..237bf264f5 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c @@ -0,0 +1,292 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "system.h" +#include "kernel.h" +#include "logf.h" +#include "audio.h" +#include "sound.h" +#include "file.h" + +/* PCM interrupt routine lockout */ +static struct +{ + int locked; + unsigned long state; +} dma_play_lock = +{ + .locked = 0, + .state = 0, +}; + +#define FIFO_COUNT ((IISFCON >> 6) & 0x3F) + +/* Setup for the DMA controller */ +#define DMA_CONTROL_SETUP ((1<<31) | (1<<29) | (1<<23) | (1<<22) | (1<<20)) + +#ifdef HAVE_UDA1341 +/* for PCLK = 50 MHz, frame size = 32 */ +/* [prescaler, master clock rate] */ +static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] = +{ + [HW_FREQ_64] = { 2, IISMOD_MASTER_CLOCK_256FS }, + [HW_FREQ_44] = { 3, IISMOD_MASTER_CLOCK_384FS }, + [HW_FREQ_22] = { 8, IISMOD_MASTER_CLOCK_256FS }, + [HW_FREQ_11] = { 17, IISMOD_MASTER_CLOCK_256FS }, +}; +#endif + +/* DMA count has hit zero - no more data */ +/* Get more data from the callback and top off the FIFO */ +void fiq_handler(void) __attribute__((interrupt ("FIQ"))); + +/* Mask the DMA interrupt */ +void pcm_play_lock(void) +{ + if (++dma_play_lock.locked == 1) + s3c_regset32(&INTMSK, DMA2_MASK); +} + +/* Unmask the DMA interrupt if enabled */ +void pcm_play_unlock(void) +{ + if (--dma_play_lock.locked == 0) + s3c_regclr32(&INTMSK, dma_play_lock.state); +} + +void pcm_play_dma_init(void) +{ + /* There seem to be problems when changing the IIS interface configuration + * when a clock is not present. + */ + s3c_regset32(&CLKCON, 1<<17); + +#ifdef HAVE_UDA1341 + /* master, transmit mode, 16 bit samples, BCLK 32fs, PCLK */ + IISMOD = IISMOD_MASTER_CLOCK_PCLK | IISMOD_MASTER_MODE | IISMOD_TRANSMIT_MODE + | IISMOD_16_BIT | IISMOD_MASTER_CLOCK_256FS | IISMOD_BIT_CLOCK_32FS; + + /* TX idle, enable prescaler */ + IISCON |= IISCON_TX_IDLE | IISCON_IIS_PRESCALER_ENABLE; +#else + /* slave, transmit mode, 16 bit samples - MCLK 384fs - use 16.9344Mhz - + BCLK 32fs */ + IISMOD = (1<<9) | (1<<8) | (2<<6) | (1<<3) | (1<<2) | (1<<0); + + /* RX,TX off,on */ + IISCON |= (1<<3) | (1<<2); +#endif + + s3c_regclr32(&CLKCON, 1<<17); + + audiohw_init(); + + /* init GPIO */ +#ifdef GIGABEAT_F +/* GPCCON = (GPCCON & ~(3<<14)) | (1<<14); */ + S3C244_GPIO_CONFIG (GPCCON, 7, GPIO_OUTPUT); + GPCDAT |= (1<<7); +#endif + + /* GPE4=I2SDO, GPE3=I2SDI, GPE2=CDCLK, GPE1=I2SSCLK, GPE0=I2SLRCK */ + GPECON = (GPECON & ~0x3ff) | 0x2aa; + + /* Do not service DMA requests, yet */ + + /* clear any pending int and mask it */ + s3c_regset32(&INTMSK, DMA2_MASK); + SRCPND = DMA2_MASK; + + /* connect to FIQ */ + s3c_regset32(&INTMOD, DMA2_MASK); +} + +void pcm_postinit(void) +{ + audiohw_postinit(); +} + +void pcm_dma_apply_settings(void) +{ +#ifdef HAVE_UDA1341 + /* set prescaler and master clock rate according to freq */ + IISPSR = (pcm_freq_parms [pcm_fsel][0] * IISPSR_PRESCALER_A) | pcm_freq_parms [pcm_fsel][0]; + IISMOD |= ~IISMOD_MASTER_CLOCK_384FS | pcm_freq_parms [pcm_fsel][1] ; +#endif + + audiohw_set_frequency(pcm_fsel); +} + +/* Connect the DMA and start filling the FIFO */ +static void play_start_pcm(void) +{ + /* clear pending DMA interrupt */ + SRCPND = DMA2_MASK; + + /* Flush any pending writes */ + clean_dcache_range((char*)DISRC2-0x30000000, (DCON2 & 0xFFFFF) * 2); + + /* unmask DMA interrupt when unlocking */ + dma_play_lock.state = DMA2_MASK; + + /* turn on the request */ + IISCON |= (1<<5); + + /* Activate the channel */ + DMASKTRIG2 = 0x2; + + /* turn off the idle */ + IISCON &= ~(1<<3); + + /* start the IIS */ + IISCON |= (1<<0); +} + +/* Disconnect the DMA and wait for the FIFO to clear */ +static void play_stop_pcm(void) +{ + /* Mask DMA interrupt */ + s3c_regset32(&INTMSK, DMA2_MASK); + + /* De-Activate the DMA channel */ + DMASKTRIG2 = 0x4; + + /* are we playing? wait for the chunk to finish */ + if (dma_play_lock.state != 0) + { + /* wait for the FIFO to empty and DMA to stop */ + while ((IISCON & (1<<7)) || (DMASKTRIG2 & 0x2)); + } + + /* Keep interrupt masked when unlocking */ + dma_play_lock.state = 0; + + /* turn off the request */ + IISCON &= ~(1<<5); + + /* turn on the idle */ + IISCON |= (1<<3); + + /* stop the IIS */ + IISCON &= ~(1<<0); +} + +void pcm_play_dma_start(const void *addr, size_t size) +{ + /* Enable the IIS clock */ + s3c_regset32(&CLKCON, 1<<17); + + /* stop any DMA in progress - idle IIS */ + play_stop_pcm(); + + /* connect DMA to the FIFO and enable the FIFO */ + IISFCON = (1<<15) | (1<<13); + + /* set DMA dest */ + DIDST2 = (unsigned int)&IISFIFO; + + /* IIS is on the APB bus, INT when TC reaches 0, fixed dest addr */ + DIDSTC2 = 0x03; + + /* set DMA source and options */ + DISRC2 = (unsigned int)addr + 0x30000000; + /* How many transfers to make - we transfer half-word at a time = 2 bytes */ + /* DMA control: CURR_TC int, single service mode, I2SSDO int, HW trig */ + /* no auto-reload, half-word (16bit) */ + DCON2 = DMA_CONTROL_SETUP | (size / 2); + DISRCC2 = 0x00; /* memory is on AHB bus, increment addresses */ + + play_start_pcm(); +} + +/* Promptly stop DMA transfers and stop IIS */ +void pcm_play_dma_stop(void) +{ + play_stop_pcm(); + + /* Disconnect the IIS clock */ + s3c_regclr32(&CLKCON, 1<<17); +} + +void pcm_play_dma_pause(bool pause) +{ + if (pause) + { + /* pause playback on current buffer */ + play_stop_pcm(); + } + else + { + /* restart playback on current buffer */ + /* make sure we're aligned on left channel - skip any right + channel sample left waiting */ + DISRC2 = (DCSRC2 + 2) & ~0x3; + DCON2 = DMA_CONTROL_SETUP | (DSTAT2 & 0xFFFFE); + play_start_pcm(); + } +} + +void fiq_handler(void) +{ + static unsigned char *start; + static size_t size; + register pcm_more_callback_type get_more; /* No stack for this */ + + /* clear any pending interrupt */ + SRCPND = DMA2_MASK; + + /* Buffer empty. Try to get more. */ + get_more = pcm_callback_for_more; + size = 0; + + if (get_more == NULL || (get_more(&start, &size), size == 0)) + { + /* Callback missing or no more DMA to do */ + pcm_play_dma_stop(); + pcm_play_dma_stopped_callback(); + } + else + { + /* Flush any pending cache writes */ + clean_dcache_range(start, size); + + /* set the new DMA values */ + DCON2 = DMA_CONTROL_SETUP | (size >> 1); + DISRC2 = (unsigned int)start + 0x30000000; + + /* Re-Activate the channel */ + DMASKTRIG2 = 0x2; + } +} + +size_t pcm_get_bytes_waiting(void) +{ + /* lie a little and only return full pairs */ + return (DSTAT2 & 0xFFFFE) * 2; +} + +const void * pcm_play_dma_get_peak_buffer(int *count) +{ + unsigned long addr = DCSRC2; + int cnt = DSTAT2; + *count = (cnt & 0xFFFFF) >> 1; + return (void *)((addr + 2) & ~3); +} diff --git a/firmware/target/arm/s3c2440/mini2440/powermgmt-mini2440.c b/firmware/target/arm/s3c2440/mini2440/powermgmt-mini2440.c new file mode 100644 index 0000000000..5584993040 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/powermgmt-mini2440.c @@ -0,0 +1,69 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "system.h" +#include "adc.h" +#include "power.h" +#include "powermgmt.h" + +/* The following constants are dummy values since there is no battery */ +const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = +{ + 3450 +}; + +const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = +{ + 3400 +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ +const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = +{ + /* Typical Li Ion 830mAH */ + { 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 }, +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ +const unsigned short percent_to_volt_charge[11] = +{ + /* Typical Li Ion 830mAH */ + 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 +}; + + +/* Returns battery voltage from ADC [millivolts] */ +/* full-scale (2^10) in millivolt */ +unsigned int battery_adc_voltage(void) +{ + /* Since we have no battery, return a fully charged value */ + return 4000 * 1024 / 1000; +} + +unsigned int input_millivolts(void) +{ + unsigned int batt_millivolts = battery_voltage(); + + /* No battery, return nominal value */ + return batt_millivolts; +} + + diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c index 78c9e9bf23..9cb9bdfc58 100644 --- a/firmware/target/arm/s3c2440/sd-s3c2440.c +++ b/firmware/target/arm/s3c2440/sd-s3c2440.c @@ -126,9 +126,6 @@ static unsigned char * uncached_buffer; /***************************************************************************** Definitions specific to Mini2440 *****************************************************************************/ -#define FCLK 405000000 -#define HCLK (FCLK/4) /* = 101,250,000 */ -#define PCLK (HCLK/2) /* = 50,625,000 */ #define SD_CD (1<<8) /* Port G */ #define SD_WP (1<<8) /* Port H */ @@ -206,8 +203,11 @@ static void debug_r1(int cmd) void SDI (void) { int status = SDIDSTA; +#ifndef HAVE_MULTIDRIVE + const int curr_card = 0; +#endif - transfer_error[curr_card] = status + transfer_error[curr_card] = status #if 0 & ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL | S3C2410_SDIDSTA_DATATIMEOUT ) @@ -619,7 +619,9 @@ static int sd_transfer_sectors(IF_MD2(int card_no,) unsigned long start, sd_enable(true); set_leds(SD_ACTIVE_LED); +#ifdef HAVE_MULTIDRIVE curr_card = card_no; +#endif if (card_info[card_no].initialized <= 0) { ret = sd_init_card(card_no); @@ -814,6 +816,9 @@ int sd_read_sectors(IF_MD2(int card_no,) unsigned long start, int incount, int sd_write_sectors(IF_MD2(int card_no,) unsigned long start, int count, const void* outbuf) { +#ifndef HAVE_MULTIDRIVE + const int card_no = 0; +#endif dbgprintf ("sd_write %d %x %d\n", card_no, start, count); return sd_transfer_sectors(IF_MD2(card_no,) start, count, outbuf, true); diff --git a/firmware/target/arm/s3c2440/system-target.h b/firmware/target/arm/s3c2440/system-target.h index 9808d31255..cf3db301eb 100644 --- a/firmware/target/arm/s3c2440/system-target.h +++ b/firmware/target/arm/s3c2440/system-target.h @@ -27,30 +27,34 @@ /* TODO: Needs checking/porting */ #ifdef GIGABEAT_F -#define CPUFREQ_DEFAULT 98784000 -#define CPUFREQ_NORMAL 98784000 -#define CPUFREQ_MAX 296352000 + #define CPUFREQ_DEFAULT 98784000 + #define CPUFREQ_NORMAL 98784000 + #define CPUFREQ_MAX 296352000 -#ifdef BOOTLOADER -/* All addresses within rockbox are in IRAM in the bootloader so - are therefore uncached */ -#define UNCACHED_ADDR(a) (a) -#else /* !BOOTLOADER */ -#define UNCACHED_BASE_ADDR 0x30000000 -#define UNCACHED_ADDR(a) ((typeof(a))((unsigned int)(a) | UNCACHED_BASE_ADDR )) -#endif /* BOOTLOADER */ + #ifdef BOOTLOADER + /* All addresses within rockbox are in IRAM in the bootloader so + are therefore uncached */ + #define UNCACHED_ADDR(a) (a) + #else /* !BOOTLOADER */ + #define UNCACHED_BASE_ADDR 0x30000000 + #define UNCACHED_ADDR(a) ((typeof(a))((unsigned int)(a) | UNCACHED_BASE_ADDR )) + #endif /* BOOTLOADER */ #elif defined(MINI2440) -#define CPUFREQ_DEFAULT 101250000 -#define CPUFREQ_NORMAL 101250000 -#define CPUFREQ_MAX 405000000 - -#define UNCACHED_BASE_ADDR 0x30000000 -#define UNCACHED_ADDR(a) ((typeof(a))((unsigned int)(a) | UNCACHED_BASE_ADDR )) + #define CPUFREQ_DEFAULT 101250000 + #define CPUFREQ_NORMAL 101250000 + #define CPUFREQ_MAX 405000000 + + #define UNCACHED_BASE_ADDR 0x30000000 + #define UNCACHED_ADDR(a) ((typeof(a))((unsigned int)(a) | UNCACHED_BASE_ADDR )) + #define FCLK 405000000 + #define HCLK (FCLK/4) /* = 101,250,000 */ + #define PCLK (HCLK/2) /* = 50,625,000 */ + #else -#error Unknown target + #error Unknown target #endif diff --git a/firmware/target/arm/s3c2440/uart-s3c2440.c b/firmware/target/arm/s3c2440/uart-s3c2440.c index 2a61b61a39..84282f731a 100644 --- a/firmware/target/arm/s3c2440/uart-s3c2440.c +++ b/firmware/target/arm/s3c2440/uart-s3c2440.c @@ -30,13 +30,32 @@ #include "kernel.h" #include "thread.h" +#include "system-target.h" #include "uart-s3c2440.h" -#define FCLK 405000000 -#define HCLK (FCLK/4) /* = 101,250,000 */ -#define PCLK (HCLK/2) /* = 50,625,000 */ +#define MAX_PRINTF_BUF 1024 -#define MAX_TX_BUF 1024 +/**************************************************************************** + * serial driver API + ****************************************************************************/ +void serial_setup (void) +{ + uart_init(); + uart_init_device(DEBUG_UART_PORT); +} + +int tx_rdy(void) +{ + if (uart_tx_ready (DEBUG_UART_PORT)) + return 1; + else + return 0; +} + +void tx_writec(unsigned char c) +{ + uart_send_byte (DEBUG_UART_PORT, c); +} /**************************************************************************** @@ -46,10 +65,12 @@ void uart_printf (const char *format, ...) { static bool debug_uart_init = false; - static char tx_buf [MAX_TX_BUF]; + static char tx_buf [MAX_PRINTF_BUF]; int len; unsigned char *ptr; + int j; + va_list ap; va_start(ap, format); @@ -59,11 +80,16 @@ void uart_printf (const char *format, ...) if (!debug_uart_init) { - uart_init_device(UART_DEBUG); + uart_init_device(DEBUG_UART_PORT); debug_uart_init = true; } - uart_send (UART_DEBUG, tx_buf, len); + for (j=0; j