From d462a64a918117991e11dade2d7fa3a28196e07a Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Sat, 6 Sep 2008 17:50:59 +0000 Subject: Initial commit of iaudio 7 port by Vitja Makarov (FS#9245). Port is at quite an advanced stage, but is troubled by the lack of a reliable NAND driver (similar to the Cowon D2 port) and is not yet suitable for non-developers. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18435 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 2 + apps/keymaps/keymap-iaudio67.c | 325 +++++++++++++++ apps/plugins/battery_bench.c | 6 + apps/plugins/lib/pluginlib_actions.c | 27 ++ apps/plugins/plugin.lds | 2 +- bootloader/telechips.c | 24 +- docs/CREDITS | 1 + firmware/SOURCES | 23 +- firmware/drivers/audio/wm8731.c | 4 + firmware/drivers/tuner/lv24020lp.c | 15 + firmware/export/config-iaudio7.h | 163 ++++++++ firmware/export/config.h | 1 - firmware/export/hd66789r.h | 68 ++++ firmware/export/tcc77x.h | 102 ++++- firmware/export/usb-tcc7xx.h | 104 +++++ firmware/target/arm/ata-nand-telechips.c | 2 +- firmware/target/arm/pcm-telechips.c | 434 +++++++++++++++++++++ firmware/target/arm/tcc77x/adc-tcc77x.c | 3 + firmware/target/arm/tcc77x/app.lds | 123 ++---- firmware/target/arm/tcc77x/boot.lds | 5 + firmware/target/arm/tcc77x/crt0.S | 5 +- firmware/target/arm/tcc77x/debug-tcc77x.c | 5 +- firmware/target/arm/tcc77x/iaudio7/adc-target.h | 28 ++ firmware/target/arm/tcc77x/iaudio7/ata2501.c | 124 ++++++ firmware/target/arm/tcc77x/iaudio7/ata2501.h | 27 ++ firmware/target/arm/tcc77x/iaudio7/audio-iaudio7.c | 99 +++++ .../target/arm/tcc77x/iaudio7/backlight-target.h | 46 +++ .../target/arm/tcc77x/iaudio7/button-iaudio7.c | 81 ++++ firmware/target/arm/tcc77x/iaudio7/button-target.h | 57 +++ firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c | 252 ++++++++++++ firmware/target/arm/tcc77x/iaudio7/power-iaudio7.c | 146 +++++++ firmware/target/arm/tcc77x/pcm-tcc77x.c | 77 ---- firmware/target/arm/tcc77x/system-tcc77x.c | 11 +- firmware/target/arm/tcc77x/usb-tcc77x.c | 8 +- firmware/target/arm/tcc780x/pcm-tcc780x.c | 314 --------------- firmware/target/arm/wmcodec-telechips.c | 5 + tools/configure | 2 +- tools/scramble.c | 2 + 38 files changed, 2227 insertions(+), 496 deletions(-) create mode 100644 apps/keymaps/keymap-iaudio67.c create mode 100644 firmware/export/config-iaudio7.h create mode 100644 firmware/export/hd66789r.h create mode 100644 firmware/export/usb-tcc7xx.h create mode 100644 firmware/target/arm/pcm-telechips.c create mode 100644 firmware/target/arm/tcc77x/iaudio7/adc-target.h create mode 100644 firmware/target/arm/tcc77x/iaudio7/ata2501.c create mode 100644 firmware/target/arm/tcc77x/iaudio7/ata2501.h create mode 100644 firmware/target/arm/tcc77x/iaudio7/audio-iaudio7.c create mode 100644 firmware/target/arm/tcc77x/iaudio7/backlight-target.h create mode 100644 firmware/target/arm/tcc77x/iaudio7/button-iaudio7.c create mode 100644 firmware/target/arm/tcc77x/iaudio7/button-target.h create mode 100644 firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c create mode 100644 firmware/target/arm/tcc77x/iaudio7/power-iaudio7.c delete mode 100644 firmware/target/arm/tcc77x/pcm-tcc77x.c delete mode 100644 firmware/target/arm/tcc780x/pcm-tcc780x.c diff --git a/apps/SOURCES b/apps/SOURCES index c8371a71aa..419d24d7a8 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -198,4 +198,6 @@ keymaps/keymap-creativezv.c keymaps/keymap-sa9200.c #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD keymaps/keymap-hdd1630.c +#elif CONFIG_KEYPAD == IAUDIO67_PAD +keymaps/keymap-iaudio67.c #endif diff --git a/apps/keymaps/keymap-iaudio67.c b/apps/keymaps/keymap-iaudio67.c new file mode 100644 index 0000000000..b97a5602c9 --- /dev/null +++ b/apps/keymaps/keymap-iaudio67.c @@ -0,0 +1,325 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Mark Arigo + * + * 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 Iaudio[67] target */ + +#include "config.h" +#include "action.h" +#include "button.h" +#include "settings.h" + +/* {Action Code, Button code, Prereq button code } */ + +/* + * 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 + */ +static const struct button_mapping button_context_standard[] = { + { ACTION_STD_PREV, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_STD_NEXT, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY }, + { ACTION_STD_OK, BUTTON_PLAY, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_STOP, BUTTON_NONE }, + + { ACTION_STD_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, + { ACTION_STD_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY }, +// { ACTION_STD_QUICKSCREEN, BUTTON_REC|BUTTON_PLAY, BUTTON_NONE }, + + LAST_ITEM_IN_LIST +}; /* button_context_standard */ + + +static const struct button_mapping button_context_wps[] = { + + { ACTION_WPS_VOLDOWN, BUTTON_VOLDOWN, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_VOLDOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_VOLUP, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, + { ACTION_WPS_CONTEXT, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU }, + + { ACTION_WPS_SKIPPREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, + { ACTION_WPS_SEEKBACK, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_STOPSEEK, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT }, + + { ACTION_WPS_SKIPNEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT }, + { ACTION_WPS_SEEKFWD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_STOPSEEK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT }, + + { ACTION_WPS_STOP, BUTTON_STOP, BUTTON_NONE }, + + LAST_ITEM_IN_LIST +}; /* button_context_wps */ + +static const struct button_mapping button_context_settings[] = { + { ACTION_STD_CANCEL, BUTTON_MENU, BUTTON_NONE }, +// { ACTION_SETTINGS_RESET, BUTTON_PLAY, BUTTON_NONE }, + + { ACTION_SETTINGS_INC, BUTTON_VOLUP, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT,BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_SETTINGS_DEC, BUTTON_VOLDOWN, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT,BUTTON_VOLDOWN|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_STD_PREV, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_STD_NEXT, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), +}; /* button_context_settings */ + +static const struct button_mapping button_context_list[] = { +#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_REC|BUTTON_VOLUP, BUTTON_REC }, + // { ACTION_TREE_STOP, BUTTON_REC|BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_REC|BUTTON_VOLUP }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), +}; /* button_context_tree */ + +static const struct button_mapping button_context_listtree_scroll_without_combo[] = { +#if 0 + { 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 }, +#endif + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE), +}; /* button_context_listtree_scroll_without_combo */ + +static const struct button_mapping button_context_listtree_scroll_with_combo[] = { +// { ACTION_TREE_ROOT_INIT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + +// { ACTION_TREE_PGLEFT, BUTTON_REC|BUTTON_LEFT, BUTTON_REC }, +// { ACTION_TREE_PGLEFT, BUTTON_REC|BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + +// { ACTION_TREE_PGRIGHT, BUTTON_REC|BUTTON_RIGHT, BUTTON_REC }, +// { ACTION_TREE_PGRIGHT, BUTTON_REC|BUTTON_RIGHT|BUTTON_REPEAT,BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE), +}; /* button_context_listtree_scroll_with_combo */ + +static const struct button_mapping button_context_yesno[] = { +// { ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), +}; /* button_context_settings_yesno */ + +static const struct button_mapping button_context_quickscreen[] = { +#if 0 + { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_MENU|BUTTON_REL, BUTTON_NONE }, + + { ACTION_QS_DOWNINV, BUTTON_VOLUP|BUTTON_REL, BUTTON_NONE }, + { ACTION_QS_DOWNINV, BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_QS_DOWN, BUTTON_VOLDOWN|BUTTON_REL, BUTTON_NONE }, + { ACTION_QS_DOWN, BUTTON_VOLDOWN|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, + { ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, + { ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, +#endif + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), +}; /* button_context_quickscreen */ + +static const struct button_mapping button_context_settings_right_is_inc[] = { +#if 0 + { 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_CANCEL, BUTTON_MENU, BUTTON_NONE }, +#endif + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), +}; /* button_context_settings_right_is_inc */ + +static const struct button_mapping button_context_pitchscreen[] = { +#if 0 + { ACTION_PS_INC_SMALL, BUTTON_VOLUP, BUTTON_NONE }, + { ACTION_PS_INC_BIG, BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_PS_DEC_SMALL, BUTTON_VOLDOWN, BUTTON_NONE }, + { ACTION_PS_DEC_BIG, BUTTON_VOLDOWN|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_RESET, BUTTON_PLAY, BUTTON_NONE }, + { ACTION_PS_EXIT, BUTTON_MENU, BUTTON_NONE }, +#endif + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), +}; /* button_context_pitchscreen */ + +/** Recording Screen **/ +#ifdef HAVE_RECORDING +static const struct button_mapping button_context_recscreen[] = { + { ACTION_STD_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, + { ACTION_REC_PAUSE, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY }, + { ACTION_STD_CANCEL, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE }, +// { ACTION_REC_NEWFILE, BUTTON_REC|BUTTON_REL, BUTTON_REC }, + + { 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 }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_recscreen */ +#endif + +/** FM Radio Screen **/ +#if CONFIG_TUNER +static const struct button_mapping button_context_radio[] = { + { ACTION_NONE, BUTTON_VOLUP, BUTTON_NONE }, + { ACTION_FM_MENU, BUTTON_VOLDOWN, BUTTON_NONE }, + { ACTION_FM_PRESET, BUTTON_PLAY, BUTTON_NONE }, + { ACTION_FM_STOP, BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_VOLUP }, +// { ACTION_FM_MODE, BUTTON_REC, BUTTON_NONE }, + { ACTION_FM_EXIT, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, + { ACTION_FM_PLAY, BUTTON_VOLUP|BUTTON_REL, BUTTON_VOLUP }, + { ACTION_SETTINGS_INC, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT,BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_DEC, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT,BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) +}; /* button_context_radio */ +#endif + +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_REC|BUTTON_LEFT, BUTTON_NONE }, +// { ACTION_KBD_CURSOR_LEFT, BUTTON_REC|BUTTON_LEFT|BUTTON_REPEAT,BUTTON_NONE }, +// { ACTION_KBD_CURSOR_RIGHT, BUTTON_REC|BUTTON_RIGHT, BUTTON_NONE }, +// { ACTION_KBD_CURSOR_RIGHT, BUTTON_REC|BUTTON_RIGHT|BUTTON_REPEAT,BUTTON_NONE }, + + { ACTION_KBD_UP, BUTTON_VOLUP, BUTTON_NONE }, + { ACTION_KBD_UP, BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_DOWN, BUTTON_VOLDOWN, BUTTON_NONE }, + { ACTION_KBD_DOWN, BUTTON_VOLDOWN|BUTTON_REPEAT, BUTTON_NONE }, + +// { ACTION_KBD_BACKSPACE, BUTTON_REC|BUTTON_VOLDOWN, BUTTON_NONE }, +// { ACTION_KBD_BACKSPACE, BUTTON_REC|BUTTON_VOLDOWN|BUTTON_REPEAT,BUTTON_NONE }, + +// { ACTION_KBD_PAGE_FLIP, BUTTON_REC|BUTTON_PLAY, BUTTON_REC }, + + { ACTION_KBD_SELECT, BUTTON_PLAY, BUTTON_NONE }, + { ACTION_KBD_DONE, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY }, + { ACTION_KBD_ABORT, BUTTON_MENU, BUTTON_NONE }, + + LAST_ITEM_IN_LIST +}; /* button_context_keyboard */ + +static const struct button_mapping button_context_bmark[] = { +// { ACTION_BMS_DELETE, BUTTON_REC, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), +}; /* button_context_bmark */ + +/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */ +const struct button_mapping* get_context_mapping(int context) +{ + 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_TREE: + case CONTEXT_MAINMENU: + 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: + case CONTEXT_SETTINGS_TIME: + return button_context_settings; + case CONTEXT_CUSTOM|CONTEXT_SETTINGS: + case CONTEXT_SETTINGS_COLOURCHOOSER: + case CONTEXT_SETTINGS_EQ: + return button_context_settings_right_is_inc; + + case CONTEXT_YESNOSCREEN: + return button_context_yesno; +#if CONFIG_TUNER + case CONTEXT_FM: + return button_context_radio; +#endif + case CONTEXT_BOOKMARKSCREEN: + return button_context_bmark; + case CONTEXT_QUICKSCREEN: + return button_context_quickscreen; + case CONTEXT_PITCHSCREEN: + return button_context_pitchscreen; +#ifdef HAVE_RECORDING + case CONTEXT_RECSCREEN: + return button_context_recscreen; +#endif + case CONTEXT_KEYBOARD: + return button_context_keyboard; + + default: + return button_context_standard; + } + return button_context_standard; +} diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c index 4361bbc491..44e7ad7bec 100644 --- a/apps/plugins/battery_bench.c +++ b/apps/plugins/battery_bench.c @@ -150,6 +150,12 @@ PLUGIN_HEADER #define BATTERY_OFF BUTTON_POWER #define BATTERY_OFF_TXT "POWER - quit" +#elif CONFIG_KEYPAD == IAUDIO67_PAD + +#define BATTERY_OFF BUTTON_POWER +#define BATTERY_OFF_TXT "POWER - quit" +#define BATTERY_ON BUTTON_PLAY +#define BATTERY_ON_TXT "PLAY - start" #else #error No keymap defined! #endif diff --git a/apps/plugins/lib/pluginlib_actions.c b/apps/plugins/lib/pluginlib_actions.c index a6bf28302f..26ef590522 100644 --- a/apps/plugins/lib/pluginlib_actions.c +++ b/apps/plugins/lib/pluginlib_actions.c @@ -154,6 +154,15 @@ const struct button_mapping generic_directions[] = { PLA_DOWN_REPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE}, +#elif (CONFIG_KEYPAD == IAUDIO67_PAD) + { PLA_UP, BUTTON_STOP, BUTTON_NONE}, + { PLA_DOWN, BUTTON_PLAY, BUTTON_NONE}, + { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, + { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, + { PLA_UP_REPEAT, BUTTON_STOP|BUTTON_REPEAT, BUTTON_NONE}, + { PLA_DOWN_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, + { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, + { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported keypad #endif @@ -257,6 +266,13 @@ const struct button_mapping generic_left_right_fire[] = { PLA_RIGHT_REPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_RC_MODE, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_RC_MODE|BUTTON_REPEAT, BUTTON_NONE}, +#elif (CONFIG_KEYPAD == IAUDIO67_PAD) + { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, + { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, + { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, + { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, + { PLA_FIRE, BUTTON_MENU, BUTTON_NONE}, + { PLA_FIRE_REPEAT, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported keypad #endif @@ -391,6 +407,12 @@ const struct button_mapping generic_actions[] = {PLA_MENU, BUTTON_MENU, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, +#elif (CONFIG_KEYPAD == IAUDIO67_PAD) + {PLA_QUIT, BUTTON_POWER, BUTTON_NONE}, + {PLA_START, BUTTON_PLAY, BUTTON_NONE}, + {PLA_MENU, BUTTON_MENU, BUTTON_NONE}, + {PLA_FIRE, BUTTON_VOLUP, BUTTON_NONE}, + {PLA_FIRE_REPEAT, BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported keypad #endif @@ -456,6 +478,11 @@ const struct button_mapping generic_increase_decrease[] = {PLA_DEC, BUTTON_MINUS, BUTTON_NONE}, {PLA_INC_REPEAT, BUTTON_PLUS|BUTTON_REPEAT, BUTTON_NONE}, {PLA_DEC_REPEAT, BUTTON_MINUS|BUTTON_REPEAT, BUTTON_NONE}, +#elif CONFIG_KEYPAD == IAUDIO67_PAD + {PLA_INC, BUTTON_VOLUP, BUTTON_NONE}, + {PLA_DEC, BUTTON_VOLDOWN, BUTTON_NONE}, + {PLA_INC_REPEAT, BUTTON_VOLUP|BUTTON_REPEAT, BUTTON_NONE}, + {PLA_DEC_REPEAT, BUTTON_VOLDOWN|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported keypad #endif diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds index 418e29fc99..b26d03b48a 100644 --- a/apps/plugins/plugin.lds +++ b/apps/plugins/plugin.lds @@ -80,7 +80,7 @@ OUTPUT_FORMAT(elf32-sh) #define IRAMORIG DRAMORIG #define IRAMSIZE 0x4000 #define IRAM DRAM -#elif defined(CPU_TCC780X) +#elif defined(CPU_TCC780X) || defined(CPU_TCC77X) #define DRAMORIG 0x20000000 /*#define IRAMORIG 0x1000c000 #define IRAMSIZE 0xc000*/ diff --git a/bootloader/telechips.c b/bootloader/telechips.c index 47e508b8b3..7f9a3556c0 100644 --- a/bootloader/telechips.c +++ b/bootloader/telechips.c @@ -44,9 +44,15 @@ #include "file.h" #include "common.h" -#if defined(COWON_D2) -#include "pcf50606.h" -#define LOAD_ADDRESS 0x20000000 /* DRAM_START */ +#if defined(COWON_D2) || defined(IAUDIO_7) && defined(TCCBOOT) +# define REAL_BOOT +#endif + +#ifdef REAL_BOOT +# if defined(COWON_D2) || defined(IAUDIO_7) +# include "pcf50606.h" +# endif +# define LOAD_ADDRESS 0x20000000 /* DRAM_START */ #endif char version[] = APPSVERSION; @@ -80,14 +86,14 @@ void show_debug_screen(void) } else { power_count = 0; } - +#ifdef BUTTON_SELECT if (button & BUTTON_SELECT){ - _backlight_off(); + _backlight_off(); } else{ _backlight_on(); } - +#endif /*printf("Btn: 0x%08x",button); printf("Tick: %d",current_tick); printf("GPIOA: 0x%08x",GPIOA); @@ -172,13 +178,13 @@ void show_debug_screen(void) void* main(void) { -#if defined(COWON_D2) && defined(TCCBOOT) +#ifdef REAL_BOOT int rc; unsigned char* loadbuffer = (unsigned char*)LOAD_ADDRESS; #endif - power_init(); system_init(); + power_init(); #ifndef COWON_D2 /* The D2 doesn't enable threading or interrupts */ kernel_init(); @@ -197,7 +203,7 @@ void* main(void) /* Only load the firmware if TCCBOOT is defined - this ensures SDRAM_START is available for loading the firmware. Otherwise display the debug screen. */ -#if defined(COWON_D2) && defined(TCCBOOT) +#ifdef REAL_BOOT printf("Rockbox boot loader"); printf("Version %s", version); diff --git a/docs/CREDITS b/docs/CREDITS index 391edecd26..8141b8332a 100644 --- a/docs/CREDITS +++ b/docs/CREDITS @@ -416,6 +416,7 @@ Tadeusz Pyś Rostislav Chekan Florin Popescu Volker Mische +Vitja Makarov The libmad team The wavpack team diff --git a/firmware/SOURCES b/firmware/SOURCES index 2075f80891..4be623fada 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -988,7 +988,7 @@ target/arm/tcc77x/logikdax/button-logikdax.c target/arm/tcc77x/logikdax/power-logikdax.c #ifndef BOOTLOADER target/arm/tcc77x/debug-tcc77x.c -target/arm/tcc77x/pcm-tcc77x.c +target/arm/pcm-telechips.c #endif /* BOOTLOADER */ #endif /* SIMULATOR */ #endif /* LOGIK_DAX */ @@ -1008,7 +1008,7 @@ target/arm/tcc77x/m200/button-m200.c target/arm/tcc77x/m200/power-m200.c #ifndef BOOTLOADER target/arm/tcc77x/debug-tcc77x.c -target/arm/tcc77x/pcm-tcc77x.c +target/arm/pcm-telechips.c #endif /* BOOTLOADER */ #endif /* SIMULATOR */ #endif /* SANSA_M200 */ @@ -1028,7 +1028,7 @@ target/arm/tcc77x/c100/button-c100.c target/arm/tcc77x/c100/power-c100.c #ifndef BOOTLOADER target/arm/tcc77x/debug-tcc77x.c -target/arm/tcc77x/pcm-tcc77x.c +target/arm/pcm-telechips.c #endif /* BOOTLOADER */ #endif /* SIMULATOR */ #endif /* SANSA_C100 */ @@ -1036,11 +1036,24 @@ target/arm/tcc77x/pcm-tcc77x.c #ifdef IAUDIO_7 #ifndef SIMULATOR drivers/nand_id.c +drivers/pcf50606.c target/arm/ata-nand-telechips.c -target/arm/tcc77x/adc-tcc77x.c target/arm/tcc77x/system-tcc77x.c +target/arm/tcc77x/kernel-tcc77x.c +target/arm/tcc77x/timer-tcc77x.c +target/arm/tcc77x/adc-tcc77x.c +target/arm/tcc77x/powermgmt-tcc77x.c +target/arm/tcc77x/usb-tcc77x.c target/arm/tcc77x/iaudio7/lcd-iaudio7.c target/arm/tcc77x/iaudio7/power-iaudio7.c +target/arm/tcc77x/iaudio7/button-iaudio7.c +target/arm/tcc77x/iaudio7/ata2501.c +#ifndef BOOTLOADER +target/arm/wmcodec-telechips.c +target/arm/pcm-telechips.c +target/arm/tcc77x/debug-tcc77x.c +target/arm/tcc77x/iaudio7/audio-iaudio7.c +#endif /* BOOTLOADER */ #endif /* SIMULATOR */ #endif /* IAUDIO_7 */ @@ -1063,7 +1076,7 @@ target/arm/tcc780x/kernel-tcc780x.c target/arm/tcc780x/timer-tcc780x.c target/arm/wmcodec-telechips.c target/arm/tcc780x/debug-tcc780x.c -target/arm/tcc780x/pcm-tcc780x.c +target/arm/pcm-telechips.c target/arm/tcc780x/cowond2/audio-cowond2.c #endif /* BOOTLOADER */ #endif /* SIMULATOR */ diff --git a/firmware/drivers/audio/wm8731.c b/firmware/drivers/audio/wm8731.c index 3d378d0072..59fa4cffcf 100644 --- a/firmware/drivers/audio/wm8731.c +++ b/firmware/drivers/audio/wm8731.c @@ -167,7 +167,11 @@ void audiohw_preinit(void) /* 3) Set required values in all other registers except 12h (Active). */ wmcodec_write(AINTFCE, AINTFCE_FORMAT_I2S | AINTFCE_IWL_16BIT | +#ifdef CODEC_SLAVE + 0); +#else AINTFCE_MS); +#endif wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]); wm8731_write(DAPCTRL, wm8731_regs[DAPCTRL]); wmcodec_write(SAMPCTRL, WM8731_USB24_44100HZ); diff --git a/firmware/drivers/tuner/lv24020lp.c b/firmware/drivers/tuner/lv24020lp.c index 0f61e5d72b..0f05d90ea2 100644 --- a/firmware/drivers/tuner/lv24020lp.c +++ b/firmware/drivers/tuner/lv24020lp.c @@ -67,6 +67,21 @@ static int fd_log = -1; #define FM_NRW_PIN 3 #define FM_CLOCK_PIN 4 #define FM_DATA_PIN 5 +#elif defined(IAUDIO_7) +#define GPIO_OUTPUT_EN GPIOA_DIR +#define GPIO_OUTPUT_VAL GPIOA +#define GPIO_INPUT_VAL GPIOA +#define FM_CLOCK_PIN 5 +#define FM_DATA_PIN 6 +#define FM_NRW_PIN 7 +//#define udelay(x) /* Remove hack when D2 has udelay */ + +static void udelay(int usecs) +{ + while (usecs--) + asm("nop;nop;"); +} + #elif defined(COWON_D2) #define GPIO_OUTPUT_EN GPIOC_DIR #define GPIO_OUTPUT_VAL GPIOC diff --git a/firmware/export/config-iaudio7.h b/firmware/export/config-iaudio7.h new file mode 100644 index 0000000000..8bc73fa41c --- /dev/null +++ b/firmware/export/config-iaudio7.h @@ -0,0 +1,163 @@ +/* + * This config file is for the Iaudio7 series + */ +#define TARGET_TREE /* this target is using the target tree system */ + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 32 + +/* define this if you have recording possibility */ +#define HAVE_RECORDING + +/* Define bitmask of input sources - recordable bitmask can be defined + explicitly if different */ +#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO) + +/* define hardware samples rate caps mask */ +#define HW_SAMPR_CAPS (/*SAMPR_CAP_88 | */SAMPR_CAP_44/* | SAMPR_CAP_22 | SAMPR_CAP_11*/) + +/* define the bitmask of recording sample rates */ +#define REC_SAMPR_CAPS (SAMPR_CAP_44/* | SAMPR_CAP_22 | SAMPR_CAP_11*/) + +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP + +/* define this if you have a colour LCD */ +#define HAVE_LCD_COLOR + +/* define this if you can flip your LCD */ +//#define HAVE_LCD_FLIP + +/* define this if you can invert the colours on your LCD */ +//#define HAVE_LCD_INVERT + +/* define this if you have access to the quickscreen */ +#define HAVE_QUICKSCREEN + +/* define this if you have access to the pitchscreen */ +#define HAVE_PITCHSCREEN + +/* define this if you have LCD enable function */ +#define HAVE_LCD_ENABLE + +/* define this if you would like tagcache to build on this target */ +#define HAVE_TAGCACHE + +#define HAVE_FAT16SUPPORT + +#if 0 /* Enable for USB driver test */ +#define HAVE_USBSTACK +#define USE_HIGH_SPEED +#define USB_VENDOR_ID 0x0e21 +#define USB_PRODUCT_ID 0x0750 + +#define USB_STORAGE +#define USB_SERIAL +#endif + +/* define this if you have a flash memory storage */ +#define HAVE_FLASH_STORAGE + +/* LCD dimensions */ +#define LCD_WIDTH 160 +#define LCD_HEIGHT 128 +/* 16bits for now... */ +#define LCD_DEPTH 16 /* 262144 colours */ +#define LCD_PIXELFORMAT RGB565 /*rgb565*/ + +/*#define LCD_PIXELFORMAT VERTICAL_PACKING*/ + +/* define this to indicate your device's keypad */ +#define CONFIG_KEYPAD IAUDIO67_PAD + +/* #define HAVE_BUTTON_DATA */ + +/* define this if you have a real-time clock */ +#define CONFIG_RTC RTC_PCF50606 + +/* define this if you have RTC RAM available for settings */ +//#define HAVE_RTC_RAM + +/* Define this if you have a software controlled poweroff */ +#define HAVE_SW_POWEROFF + +/* Reduce Tremor's ICODE usage */ +#define ICODE_ATTR_TREMOR_NOT_MDCT + +/* The number of bytes reserved for loadable codecs */ +#define CODEC_SIZE 0x80000 + +/* The number of bytes reserved for loadable plugins */ +#define PLUGIN_BUFFER_SIZE 0x80000 + +#define AB_REPEAT_ENABLE 1 + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC + +/* The iaudio7 uses built-in WM8731 codec */ +#define HAVE_WM8731 +/* Codec is slave on serial bus */ +#define CODEC_SLAVE + +/* Define this if you have the TLV320 audio codec */ +//#define HAVE_TLV320 + +/* TLV320 has no tone controls, so we use the software ones */ +//#define HAVE_SW_TONE_CONTROLS + +/* Define this for LCD backlight available */ +#define HAVE_BACKLIGHT + +#define CONFIG_I2C I2C_TCC77X + +#define BATTERY_CAPACITY_DEFAULT 540 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 540 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 540 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 50 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ + +/* define this if the unit should not shut down on low battery. */ +#define NO_LOW_BATTERY_SHUTDOWN +#define CONFIG_CHARGING CHARGING_SIMPLE + +#ifndef SIMULATOR + +/* Define this if you have a TCC770 */ +#define CONFIG_CPU TCC770 + +/* Define this if you have ATA power-off control */ +#define HAVE_ATA_POWER_OFF + +/* Define this to the CPU frequency */ +#define CPU_FREQ 120000000 + +/* Offset ( in the firmware file's header ) to the file length */ +//#define FIRMWARE_OFFSET_FILE_LENGTH 0 + +/* Offset ( in the firmware file's header ) to the file CRC */ +#define FIRMWARE_OFFSET_FILE_CRC 0 + +/* Offset ( in the firmware file's header ) to the real data */ +#define FIRMWARE_OFFSET_FILE_DATA 8 + +/* Software controlled LED */ +#define CONFIG_LED LED_VIRTUAL + +#define CONFIG_LCD LCD_IAUDIO67 + +/* FM Tuner */ +#define CONFIG_TUNER LV24020LP +#define HAVE_TUNER_PWR_CTRL + +/* Define this for FM radio input available */ +#define HAVE_FMRADIO_IN + +#define BOOTFILE_EXT "iaudio" +#define BOOTFILE "rockbox." BOOTFILE_EXT +#define BOOTDIR "/" + +#ifdef BOOTLOADER +#define TCCBOOT +#endif +#endif /* SIMULATOR */ diff --git a/firmware/export/config.h b/firmware/export/config.h index bdf8743942..fe2cff0ea6 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -481,7 +481,6 @@ (((CONFIG_CPU == SH7034) && !defined(PLUGIN)) || /* SH1 archos: core only */ \ defined(CPU_COLDFIRE) || /* Coldfire: core, plugins, codecs */ \ defined(CPU_PP) || /* PortalPlayer: core, plugins, codecs */ \ - defined(CPU_TCC77X) || /* Telechips: core, plugins, codecs */ \ (CONFIG_CPU == PNX0101) || \ (CONFIG_CPU == S5L8700)) /* Samsung S5L8700: core, plugins, codecs */ #define ICODE_ATTR __attribute__ ((section(".icode"))) diff --git a/firmware/export/hd66789r.h b/firmware/export/hd66789r.h new file mode 100644 index 0000000000..464ddbab4f --- /dev/null +++ b/firmware/export/hd66789r.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 _HD66789R_H_ +#define _HD66789R_H_ + +/* HD66789R registers */ +#define R_START_OSC 0x00 +#define R_DRV_OUTPUT_CONTROL 0x01 +#define R_DRV_WAVEFORM_CONTROL 0x02 +#define R_ENTRY_MODE 0x03 +#define R_COMPARE_REG1 0x04 +#define R_COMPARE_REG2 0x05 + +#define R_DISP_CONTROL1 0x07 +#define R_DISP_CONTROL2 0x08 +#define R_DISP_CONTROL3 0x09 + +#define R_FRAME_CYCLE_CONTROL 0x0b +#define R_EXT_DISP_IF_CONTROL 0x0c + +#define R_POWER_CONTROL1 0x10 +#define R_POWER_CONTROL2 0x11 +#define R_POWER_CONTROL3 0x12 +#define R_POWER_CONTROL4 0x13 + +#define R_RAM_ADDR_SET 0x21 +#define R_WRITE_DATA_2_GRAM 0x22 + +#define R_GAMMA_FINE_ADJ_POS1 0x30 +#define R_GAMMA_FINE_ADJ_POS2 0x31 +#define R_GAMMA_FINE_ADJ_POS3 0x32 +#define R_GAMMA_GRAD_ADJ_POS 0x33 + +#define R_GAMMA_FINE_ADJ_NEG1 0x34 +#define R_GAMMA_FINE_ADJ_NEG2 0x35 +#define R_GAMMA_FINE_ADJ_NEG3 0x36 +#define R_GAMMA_GRAD_ADJ_NEG 0x37 + +#define R_GAMMA_AMP_ADJ_RES_POS 0x38 +#define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 + +#define R_GATE_SCAN_POS 0x40 +#define R_VERT_SCROLL_CONTROL 0x41 +#define R_1ST_SCR_DRV_POS 0x42 +#define R_2ND_SCR_DRV_POS 0x43 +#define R_HORIZ_RAM_ADDR_POS 0x44 +#define R_VERT_RAM_ADDR_POS 0x45 + +#endif /* _HD66789R_H_ */ diff --git a/firmware/export/tcc77x.h b/firmware/export/tcc77x.h index b17865e257..9ff8adea3e 100644 --- a/firmware/export/tcc77x.h +++ b/firmware/export/tcc77x.h @@ -59,8 +59,13 @@ #define PCLKCFG5 (*(volatile unsigned long *)0x80000430) #define PCLKCFG6 (*(volatile unsigned long *)0x80000434) +#define PCLK_DAI PCLKCFG6 + /* Device bits for SWRESET & BCLKCTR */ +#define DEV_DAI (1<<0) +#define DEV_USBD (1<<4) +#define DEV_ECC (1<<9) #define DEV_NAND (1<<16) /* ADC */ @@ -86,9 +91,23 @@ /* IRQ Controller */ +#define EXT0_IRQ_MASK (1<<0) +#define EXT1_IRQ_MASK (1<<1) +#define EXT2_IRQ_MASK (1<<2) +#define EXT3_IRQ_MASK (1<<3) +#define I2SR_IRQ_MASK (1<<4) +#define I2ST_IRQ_MASK (1<<5) +#define TIMER0_IRQ_MASK (1<<6) +#define USBD_IRQ_MASK (1<<8) /* USB 2.0 device */ +#define USBH_IRQ_MASK (1<<10) /* USB 1.1 host */ +#define ADC_IRQ_MASK (1<<16) +#define USB_DMA_IRQ_MASK (1<<26) /* USB DMA */ +#define ECC_IRQ_MASK (1<<27) + +#define DAI_RX_IRQ_MASK I2SR_IRQ_MASK +#define DAI_TX_IRQ_MASK I2ST_IRQ_MASK -#define TIMER0_IRQ_MASK (1<<6) -#define ADC_IRQ_MASK (1<<16) +#define USB_DMA_IRQ_MASK (1<<26) /* USB DMA */ #define IEN (*(volatile unsigned long *)0x80000100) #define CREQ (*(volatile unsigned long *)0x80000104) @@ -160,4 +179,83 @@ #define NFC_IREQ (*(volatile unsigned long *)0x90000060) #define NFC_RST (*(volatile unsigned long *)0x90000064) + +/* ECC controller */ + +#define ECC_CTRL (*(volatile unsigned long *)0x80000900) + #define ECC_DMA_REQ (1<<28) + #define ECC_ENC (1<<27) /* MLC ECC3/4 */ + #define ECC_FLG (1<<26) + #define ECC_IEN (1<<25) + #define ECC_MANUAL (1<<22) + #define ECC_WCNT (1<<12) /* [21:12] */ + #define ECC_HOLD (1<<7) + #define ECC_M4EN (1<<6) + #define ECC_ZERO (1<<5) + #define ECC_M3EN (1<<4) + #define ECC_CNT_MASK (7<<1) + #define ECC_CNT (1<<1) + #define ECC_SLC (1<<0) + +#define ECC_BASE (*(volatile unsigned long *)0x80000904) +#define ECC_MASK (*(volatile unsigned long *)0x80000908) +#define ECC_CLR (*(volatile unsigned long *)0x8000090c) +#define SLC_ECC0 (*(volatile unsigned long *)0x80000910) +#define SLC_ECC1 (*(volatile unsigned long *)0x80000914) +#define SLC_ECC2 (*(volatile unsigned long *)0x80000918) +#define SLC_ECC3 (*(volatile unsigned long *)0x8000091c) +#define SLC_ECC4 (*(volatile unsigned long *)0x80000920) +#define SLC_ECC5 (*(volatile unsigned long *)0x80000924) +#define SLC_ECC6 (*(volatile unsigned long *)0x80000928) +#define SLC_ECC7 (*(volatile unsigned long *)0x8000092c) +#define MLC_ECC0W (*(volatile unsigned long *)0x80000930) +#define MLC_ECC1W (*(volatile unsigned long *)0x80000934) +#define MLC_ECC2W (*(volatile unsigned long *)0x80000938) +#define MLC_ECC0R (*(volatile unsigned long *)0x80000940) +#define MLC_ECC1R (*(volatile unsigned long *)0x80000944) +#define MLC_ECC2R (*(volatile unsigned long *)0x80000948) +#define ECC_CORR_START (*(volatile unsigned long *)0x8000094c) +#define ECC_ERRADDR1 (*(volatile unsigned long *)0x80000950) +#define ECC_ERRADDR2 (*(volatile unsigned long *)0x80000954) +#define ECC_ERRADDR3 (*(volatile unsigned long *)0x80000958) +#define ECC_ERRADDR4 (*(volatile unsigned long *)0x8000095c) +#define ECC_ERRDATA1 (*(volatile unsigned long *)0x80000960) +#define ECC_ERRDATA2 (*(volatile unsigned long *)0x80000964) +#define ECC_ERRDATA3 (*(volatile unsigned long *)0x80000968) +#define ECC_ERRDATA4 (*(volatile unsigned long *)0x8000096c) +#define ECC_ERR_NUM (*(volatile unsigned long *)0x80000970) + +#define ECC_ERRDATA(x) (*(volatile unsigned long *)(0x80000960 + (x) * 4)) +#define ECC_ERRADDR(x) (*(volatile unsigned long *)(0x80000950 + (x) * 4)) + +/* Digital Audio Interface */ +#define DADI_L0 (*(volatile unsigned long *)0x80000000) +#define DADI_R0 (*(volatile unsigned long *)0x80000004) +#define DADI_L1 (*(volatile unsigned long *)0x80000008) +#define DADI_R1 (*(volatile unsigned long *)0x8000000C) +#define DADI_L2 (*(volatile unsigned long *)0x80000010) +#define DADI_R2 (*(volatile unsigned long *)0x80000014) +#define DADI_L3 (*(volatile unsigned long *)0x80000018) +#define DADI_R3 (*(volatile unsigned long *)0x8000001c) + +#define DADO_L0 (*(volatile unsigned long *)0x80000020) +#define DADO_R0 (*(volatile unsigned long *)0x80000024) +#define DADO_L1 (*(volatile unsigned long *)0x80000028) +#define DADO_R1 (*(volatile unsigned long *)0x8000002C) +#define DADO_L2 (*(volatile unsigned long *)0x80000030) +#define DADO_R2 (*(volatile unsigned long *)0x80000034) +#define DADO_L3 (*(volatile unsigned long *)0x80000038) +#define DADO_R3 (*(volatile unsigned long *)0x8000003c) + +#define DAMR (*(volatile unsigned long *)0x80000040) +#define DAVC (*(volatile unsigned long *)0x80000044) + +#define DADI_L(x) (*(volatile unsigned long *)(0x80000000 + (x) * 8)) +#define DADI_R(x) (*(volatile unsigned long *)(0x80000004 + (x) * 8)) +#define DADO_L(x) (*(volatile unsigned long *)(0x80000020 + (x) * 8)) +#define DADO_R(x) (*(volatile unsigned long *)(0x80000024 + (x) * 8)) + +/* USB 2.0 device system MMR base address */ +#define USB_BASE 0x90000b00 + #endif diff --git a/firmware/export/usb-tcc7xx.h b/firmware/export/usb-tcc7xx.h new file mode 100644 index 0000000000..dc091ad671 --- /dev/null +++ b/firmware/export/usb-tcc7xx.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 USB_TCC7XX_H +#define USB_TCC7XX_H + +#define MMR_REG16(base, x) (*(volatile unsigned short *) ((base) + (x))) + +/* USB PHY registers */ +#define TCC7xx_USB_PHY_CFG MMR_REG16(USB_BASE, 0xc4) + #define TCC7xx_USB_PHY_CFG_XSEL (1<<13) /* FS/HS Transceiver enable */ + #define TCC7xx_USB_PHY_CFG_DWS (1<<6) /* Host mode */ + #define TCC7xx_USB_PHY_XO (1<<5) /* Enable XO_OUT */ + #define TCC7xx_USB_PHY_CKSEL_12 0 + #define TCC7xx_USB_PHY_CKSEL_24 1 + #define TCC7xx_USB_PHY_CKSEL_48 2 + +/* USB 2.0 device registers */ +#define TCC7xx_USB_INDEX MMR_REG16(USB_BASE, 0x00) /* Endpoint Index register */ +#define TCC7xx_USB_EPIF MMR_REG16(USB_BASE, 0x04) /* Endpoint interrupt flag register */ +#define TCC7xx_USB_EPIE MMR_REG16(USB_BASE, 0x08) /* Endpoint interrupt enable register */ +#define TCC7xx_USB_FUNC MMR_REG16(USB_BASE, 0x0c) /* Function address register */ +#define TCC7xx_USB_EP_DIR MMR_REG16(USB_BASE, 0x14) /* Endpoint direction register */ +#define TCC7xx_USB_TST MMR_REG16(USB_BASE, 0x14) /* Test registerregister */ +#define TCC7xx_USB_SYS_STAT MMR_REG16(USB_BASE, 0x1c) /* System status register */ + #define TCC7xx_USB_SYS_STAT_RESET (1<<0) /* Host forced reced */ + #define TCC7xx_USB_SYS_STAT_SUSPEND (1<<1) /* Host forced suspend */ + #define TCC7xx_USB_SYS_STAT_RESUME (1<<2) /* Host forced resume */ + #define TCC7xx_USB_SYS_STAT_HIGH (1<<4) /* High speed */ + #define TCC7xx_USB_SYS_STAT_VBON (1<<8) + #define TCC7xx_USB_SYS_STAT_VBOF (1<<9) + #define TCC7xx_USB_SYS_STAT_EOERR (1<<10) /* overrun error */ + #define TCC7xx_USB_SYS_STAT_DCERR (1<<11) /* Data CRC error */ + #define TCC7xx_USB_SYS_STAT_TCERR (1<<12) /* Token CRC error */ + #define TCC7xx_USB_SYS_STAT_BSERR (1<<13) /* Bit-stuff error */ + #define TCC7xx_USB_SYS_STAT_TMERR (1<<14) /* Timeout error */ + #define TCC7xx_USB_SYS_STAT_BAERR (1<<15) /* Byte align error */ + +#define TCC7xx_USB_SYS_STAT_ERRORS (TCC7xx_USB_SYS_STAT_EOERR | \ + TCC7xx_USB_SYS_STAT_DCERR | \ + TCC7xx_USB_SYS_STAT_TCERR | \ + TCC7xx_USB_SYS_STAT_BSERR | \ + TCC7xx_USB_SYS_STAT_TMERR | \ + TCC7xx_USB_SYS_STAT_BAERR) + +#define TCC7xx_USB_SYS_CTRL MMR_REG16(USB_BASE, 0x20) /* System control register */ + #define TCC7xx_USB_SYS_CTRL_RESET (1<<0) /* Reset enable */ + #define TCC7xx_USB_SYS_CTRL_SUSPEND (1<<1) /* Suspend enable */ + #define TCC7xx_USB_SYS_CTRL_RESUME (1<<2) /* Resume enable */ + #define TCC7xx_USB_SYS_CTRL_IPS (1<<4) /* Interrupt polarity */ + #define TCC7xx_USB_SYS_CTRL_RFRE (1<<5) /* Reverse read data enable */ + #define TCC7xx_USB_SYS_CTRL_SPDEN (1<<6) /* Speed detection interrupt enable */ + #define TCC7xx_USB_SYS_CTRL_BUS16 (1<<7) /* Select bus width 8/16 */ + #define TCC7xx_USB_SYS_CTRL_EIEN (1<<8) /* Error interrupt enable */ + #define TCC7xx_USB_SYS_CTRL_RWDE (1<<9) /* Reverse write data enable */ + #define TCC7xx_USB_SYS_CTRL_VBONE (1<<10) /* VBus On enable */ + #define TCC7xx_USB_SYS_CTRL_VBOFE (1<<11) /* VBus Off enable */ + #define TCC7xx_USB_SYS_CTRL_DUAL (1<<12) /* Dual interrupt enable*/ + #define TCC7xx_USB_SYS_CTRL_DMAZ (1<<14) /* DMA total count zero int */ + +#define TCC7xx_USB_EP0_STAT MMR_REG16(USB_BASE, 0x24) /* EP0 status register */ +#define TCC7xx_USB_EP0_CTRL MMR_REG16(USB_BASE, 0x28) /* EP0 control register */ + +#define TCC7xx_USB_EP0_BUF MMR_REG16(USB_BASE, 0x60) /* EP0 buffer register */ +#define TCC7xx_USB_EP1_BUF MMR_REG16(USB_BASE, 0x64) /* EP1 buffer register */ +#define TCC7xx_USB_EP2_BUF MMR_REG16(USB_BASE, 0x68) /* EP2 buffer register */ +#define TCC7xx_USB_EP3_BUF MMR_REG16(USB_BASE, 0x6c) /* EP3 buffer register */ + +/* Indexed registers, write endpoint number to TCC7xx_USB_INDEX */ +#define TCC7xx_USB_EP_STAT MMR_REG16(USB_BASE, 0x2c) /* EP status register */ +#define TCC7xx_USB_EP_CTRL MMR_REG16(USB_BASE, 0x30) /* EP control register */ + #define TCC7xx_USB_EP_CTRL_CDP (1 << 2) /* Clear Data PID */ + #define TCC7xx_USB_EP_CTRL_FLUSH (1 << 6) /* Flush FIFO */ +#define TCC7xx_USB_EP_BRCR MMR_REG16(USB_BASE, 0x34) /* EP byte read count register */ +#define TCC7xx_USB_EP_BWCR MMR_REG16(USB_BASE, 0x38) /* EP byte write count register */ +#define TCC7xx_USB_EP_MAXP MMR_REG16(USB_BASE, 0x3c) /* EP max packet register */ + +#define TCC7xx_USB_EP_DMA_CTRL MMR_REG16(USB_BASE, 0x40) /* EP DMA control register */ +#define TCC7xx_USB_EP_DMA_TCNTR MMR_REG16(USB_BASE, 0x44) /* EP DMA transfer counter register */ +#define TCC7xx_USB_EP_DMA_FCNTR MMR_REG16(USB_BASE, 0x48) /* EP DMA fifo counter register */ +#define TCC7xx_USB_EP_DMA_TTCNTR1 MMR_REG16(USB_BASE, 0x4c) /* EP DMA total trasfer counter1 register */ +#define TCC7xx_USB_EP_DMA_TTCNTR2 MMR_REG16(USB_BASE, 0x50) /* EP DMA total trasfer counter2 register */ +#define TCC7xx_USB_EP_DMA_ADDR1 MMR_REG16(USB_BASE, 0xa0) /* EP DMA MCU addr1 register */ +#define TCC7xx_USB_EP_DMA_ADDR2 MMR_REG16(USB_BASE, 0xa4) /* EP DMA MCU addr2 register */ +#define TCC7xx_USB_EP_DMA_STAT MMR_REG16(USB_BASE, 0xc0) /* EP DMA Transfer Status register */ +#define TCC7xx_USB_DELAY_CTRL MMR_REG16(USB_BASE, 0x80) /* Delay control register */ +#endif /* USB_TCC7XX_H */ diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c index de688b4ff7..668c8a9d69 100644 --- a/firmware/target/arm/ata-nand-telechips.c +++ b/firmware/target/arm/ata-nand-telechips.c @@ -48,7 +48,7 @@ static struct mutex ata_mtx SHAREDBSS_ATTR; #define SECTOR_SIZE 512 -#ifdef COWON_D2 +#if defined(COWON_D2) || defined(IAUDIO_7) #define SEGMENT_ID_BIGENDIAN #define BLOCKS_PER_SEGMENT 4 #else diff --git a/firmware/target/arm/pcm-telechips.c b/firmware/target/arm/pcm-telechips.c new file mode 100644 index 0000000000..a0ad00eb22 --- /dev/null +++ b/firmware/target/arm/pcm-telechips.c @@ -0,0 +1,434 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Michael Sevakis + * Copyright (C) 2008 by Rob Purchase + * + * 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 "pcm.h" + +/* Just for tests enable it to play simple tone */ +//#define PCM_TELECHIPS_TEST + +struct dma_data +{ +/* NOTE: The order of size and p is important if you use assembler + optimised fiq handler, so don't change it. */ + uint16_t *p; + size_t size; +#if NUM_CORES > 1 + unsigned core; +#endif + int locked; + int state; +}; + +/**************************************************************************** + ** Playback DMA transfer + **/ +struct dma_data dma_play_data SHAREDBSS_ATTR = +{ + /* Initialize to a locked, stopped state */ + .p = NULL, + .size = 0, +#if NUM_CORES > 1 + .core = 0x00, +#endif + .locked = 0, + .state = 0 +}; + +static unsigned long pcm_freq SHAREDDATA_ATTR = HW_SAMPR_DEFAULT; /* 44.1 is default */ + +void pcm_postinit(void) +{ +#if defined(IAUDIO_7) + audiohw_postinit(); /* implemented not for all codecs */ +#endif + pcm_apply_settings(); +} + +const void * pcm_play_dma_get_peak_buffer(int *count) +{ + unsigned long addr = (unsigned long)dma_play_data.p; + size_t cnt = dma_play_data.size; + *count = cnt >> 2; + return (void *)((addr + 2) & ~3); +} + +void pcm_play_dma_init(void) +{ + DAVC = 0x0; /* Digital Volume = max */ +#ifdef COWON_D2 + /* Set DAI clock divided from PLL0 (192MHz). + The best approximation of 256*44.1kHz is 11.291MHz. */ + BCLKCTR &= ~DEV_DAI; + PCLK_DAI = (1<<28) | 61682; /* DCO mode */ + BCLKCTR |= DEV_DAI; + + /* Enable DAI block in Master mode, 256fs->32fs, 16bit LSB */ + DAMR = 0x3c8e80; +#elif defined(IAUDIO_7) + BCLKCTR &= ~DEV_DAI; + PCLK_DAI = (0x800b << 16) | (PCLK_DAI & 0xffff); + BCLKCTR |= DEV_DAI; + /* Master mode, 256->64fs, 16bit LSB*/ + DAMR = 0x3cce20; +#else +#error "Target isn't supported" +#endif + /* Set DAI interrupts as FIQs */ + IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK); + + pcm_set_frequency(SAMPR_44); + + /* Initialize default register values. */ + audiohw_init(); + + /* Power on */ + audiohw_enable_output(true); + + /* Unmute the master channel (DAC should be at zero point now). */ + audiohw_mute(false); + + dma_play_data.size = 0; +#if NUM_CORES > 1 + dma_play_data.core = 0; /* no core in control */ +#endif +} + +void pcm_apply_settings(void) +{ + pcm_curr_sampr = pcm_freq; +} + +void pcm_set_frequency(unsigned int frequency) +{ + (void) frequency; + pcm_freq = HW_SAMPR_DEFAULT; +} + +static void play_start_pcm(void) +{ + pcm_apply_settings(); + + DAMR &= ~(1<<14); /* disable tx */ + dma_play_data.state = 1; + + if (dma_play_data.size >= 16) + { + DADO_L(0) = *dma_play_data.p++; + DADO_R(0) = *dma_play_data.p++; + DADO_L(1) = *dma_play_data.p++; + DADO_R(1) = *dma_play_data.p++; + DADO_L(2) = *dma_play_data.p++; + DADO_R(2) = *dma_play_data.p++; + DADO_L(3) = *dma_play_data.p++; + DADO_R(3) = *dma_play_data.p++; + dma_play_data.size -= 16; + } + + DAMR |= (1<<14); /* enable tx */ +} + +static void play_stop_pcm(void) +{ + DAMR &= ~(1<<14); /* disable tx */ + dma_play_data.state = 0; +} + +void pcm_play_dma_start(const void *addr, size_t size) +{ + dma_play_data.p = (void *)(((uintptr_t)addr + 2) & ~3); + dma_play_data.size = (size & ~3); + +#if NUM_CORES > 1 + /* This will become more important later - and different ! */ + dma_play_data.core = processor_id(); /* save initiating core */ +#endif + + IEN |= DAI_TX_IRQ_MASK; + + play_start_pcm(); +} + +void pcm_play_dma_stop(void) +{ + play_stop_pcm(); + dma_play_data.size = 0; +#if NUM_CORES > 1 + dma_play_data.core = 0; /* no core in control */ +#endif +} + +void pcm_play_lock(void) +{ + int status = disable_fiq_save(); + + if (++dma_play_data.locked == 1) + { + IEN &= ~DAI_TX_IRQ_MASK; + } + + restore_fiq(status); +} + +void pcm_play_unlock(void) +{ + int status = disable_fiq_save(); + + if (--dma_play_data.locked == 0 && dma_play_data.state != 0) + { + IEN |= DAI_TX_IRQ_MASK; + } + + restore_fiq(status); +} + +void pcm_play_dma_pause(bool pause) +{ + (void) pause; +} + +size_t pcm_get_bytes_waiting(void) +{ + return dma_play_data.size & ~3; +} + +#ifdef HAVE_RECORDING +/* TODO: implement */ +void pcm_rec_dma_init(void) +{ +} + +void pcm_rec_dma_close(void) +{ +} + +void pcm_rec_dma_start(void *addr, size_t size) +{ + (void) addr; + (void) size; +} + +void pcm_rec_dma_stop(void) +{ +} + +void pcm_rec_lock(void) +{ +} + +void pcm_rec_unlock(void) +{ +} + +const void * pcm_rec_dma_get_peak_buffer(int *count) +{ + *count = 0; + return NULL; +} + +void pcm_record_more(void *start, size_t size) +{ +} +#endif + +#if defined(COWON_D2) +/* TODO: hardcoded hex values differs for tcc7xx and tcc8xx */ +void fiq_handler(void) ICODE_ATTR __attribute__((naked)); +void fiq_handler(void) +{ + /* r10 contains DADO_L0 base address (set in crt0.S to minimise code in the + * FIQ handler. r11 contains address of p (also set in crt0.S). Most other + * addresses we need are generated by using offsets with these two. + * r8 and r9 contains local copies of p and size respectively. + * r0-r3 and r12 is a working register. + */ + asm volatile ( + "mov r8, #0xc000 \n" /* DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK */ + "ldr r9, =0xf3001004 \n" /* CREQ */ + "str r8, [r9] \n" /* clear DAI IRQs */ + + "ldmia r11, { r8-r9 } \n" /* r8 = p, r9 = size */ + "cmp r9, #0x10 \n" /* is size <16? */ + "blt .more_data \n" /* if so, ask pcmbuf for more data */ + + ".fill_fifo: \n" + "ldr r12, [r8], #4 \n" /* load two samples */ + "str r12, [r10, #0x0] \n" /* write top sample to DADO_L0 */ + "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ + "str r12, [r10, #0x4] \n" /* write low sample to DADO_R0*/ + "ldr r12, [r8], #4 \n" /* load two samples */ + "str r12, [r10, #0x8] \n" /* write top sample to DADO_L1 */ + "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ + "str r12, [r10, #0xc] \n" /* write low sample to DADO_R1*/ + "ldr r12, [r8], #4 \n" /* load two samples */ + "str r12, [r10, #0x10] \n" /* write top sample to DADO_L2 */ + "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ + "str r12, [r10, #0x14] \n" /* write low sample to DADO_R2*/ + "ldr r12, [r8], #4 \n" /* load two samples */ + "str r12, [r10, #0x18] \n" /* write top sample to DADO_L3 */ + "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ + "str r12, [r10, #0x1c] \n" /* write low sample to DADO_R3*/ + "sub r9, r9, #0x10 \n" /* 4 words written */ + "stmia r11, { r8-r9 } \n" /* save p and size */ + + ".exit: \n" + "subs pc, lr, #4 \n" /* FIQ specific return sequence */ + + ".more_data: \n" + "stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */ + "ldr r2, =pcm_callback_for_more \n" + "ldr r2, [r2] \n" /* get callback address */ + "cmp r2, #0 \n" /* check for null pointer */ + "movne r0, r11 \n" /* r0 = &p */ + "addne r1, r11, #4 \n" /* r1 = &size */ + "blxne r2 \n" /* call pcm_callback_for_more */ + "ldmia r11, { r8-r9 } \n" /* reload p and size */ + "cmp r9, #0x10 \n" /* did we actually get more data? */ + "ldmgefd sp!, { r0-r3, lr } \n" + "bge .fill_fifo \n" /* yes: fill the fifo */ + "ldr r12, =pcm_play_dma_stop \n" + "blx r12 \n" /* no: stop playback */ + "ldr r12, =pcm_play_dma_stopped_callback \n" + "blx r12 \n" + "ldmfd sp!, { r0-r3, lr } \n" + "b .exit \n" + ".ltorg \n" + ); +} +#else /* C version for reference */ +void fiq_handler(void) ICODE_ATTR __attribute__((naked)); +void fiq_handler(void) +{ + asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ + "sub sp, sp, #8 \n"); /* Reserve stack */ + + register pcm_more_callback_type get_more; + + if (dma_play_data.size < 16) + { + /* p is empty, get some more data */ + get_more = pcm_callback_for_more; + if (get_more) + { + get_more((unsigned char**)&dma_play_data.p, + &dma_play_data.size); + } + } + + if (dma_play_data.size >= 16) + { + DADO_L(0) = *dma_play_data.p++; + DADO_R(0) = *dma_play_data.p++; + DADO_L(1) = *dma_play_data.p++; + DADO_R(1) = *dma_play_data.p++; + DADO_L(2) = *dma_play_data.p++; + DADO_R(2) = *dma_play_data.p++; + DADO_L(3) = *dma_play_data.p++; + DADO_R(3) = *dma_play_data.p++; + + dma_play_data.size -= 16; + } + else + { + /* No more data, so disable the FIFO/interrupt */ + pcm_play_dma_stop(); + pcm_play_dma_stopped_callback(); + } + + /* Clear FIQ status */ + CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; + + asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ + "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ + "subs pc, lr, #4 \n"); /* Return from FIQ */ +} +#endif + +/* TODO: required by wm8531 codec, why not to implement */ +void i2s_reset(void) +{ +/* DAMR = 0; */ +} + +#ifdef PCM_TELECHIPS_TEST +#include "lcd.h" +#include "sprintf.h" +#include "backlight-target.h" + +static int frame = 0; +static void test_callback_for_more(unsigned char **start, size_t *size) +{ + static unsigned short data[8]; + static int cntr = 0; + int i; + + for (i = 0; i < 8; i ++) { + unsigned short val; + + if (0x100 == (cntr & 0x100)) + val = 0x0fff; + else + val = 0x0000; + data[i] = val; + cntr++; + } + + *start = data; + *size = sizeof(data); + + frame++; +} + +void pcm_telechips_test(void) +{ + static char buf[100]; + unsigned char *data; + size_t size; + + _backlight_on(); + + audiohw_preinit(); + pcm_play_dma_init(); + pcm_postinit(); + + audiohw_mute(false); + audiohw_set_master_vol(0x7f, 0x7f); + + pcm_callback_for_more = test_callback_for_more; + test_callback_for_more(&data, &size); + pcm_play_dma_start(data, size); + + while (1) { + int line = 0; + lcd_clear_display(); + lcd_puts(0, line++, __func__); + snprintf(buf, sizeof(buf), "frame: %d", frame); + lcd_puts(0, line++, buf); + lcd_update(); + sleep(1); + } +} +#endif diff --git a/firmware/target/arm/tcc77x/adc-tcc77x.c b/firmware/target/arm/tcc77x/adc-tcc77x.c index 37bd15398b..f48528639e 100644 --- a/firmware/target/arm/tcc77x/adc-tcc77x.c +++ b/firmware/target/arm/tcc77x/adc-tcc77x.c @@ -104,6 +104,9 @@ unsigned short adc_read(int channel) void adc_init(void) { + /* Initialize ADC clocks */ + PCLKCFG6 = (PCLKCFG6 & 0xffff0000) | 4004; + ADCCON = (1<<4); /* Leave standby mode */ /* IRQ enable, auto power-down, single-mode */ diff --git a/firmware/target/arm/tcc77x/app.lds b/firmware/target/arm/tcc77x/app.lds index 03a427f76b..c50367cb08 100644 --- a/firmware/target/arm/tcc77x/app.lds +++ b/firmware/target/arm/tcc77x/app.lds @@ -1,21 +1,25 @@ #include "config.h" ENTRY(start) - OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) STARTUP(target/arm/tcc77x/crt0.o) #define PLUGINSIZE PLUGIN_BUFFER_SIZE #define CODECSIZE CODEC_SIZE + +#ifdef DEBUG +#define STUBOFFSET 0x10000 +#else +#define STUBOFFSET 0 +#endif -#include "imx31l.h" - -#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE +#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - STUBOFFSET - CODECSIZE #define DRAMORIG 0x20000000 #define IRAMORIG 0x00000000 -#define IRAMSIZE IRAM_SIZE +#define IRAMSIZE 64K + /* End of the audio buffer, where the codec buffer starts */ #define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) @@ -23,100 +27,58 @@ STARTUP(target/arm/tcc77x/crt0.o) /* Where the codec buffer ends, and the plugin buffer starts */ #define ENDADDR (ENDAUDIOADDR + CODECSIZE) + MEMORY { - DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE - IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE +#ifdef TCCBOOT + DRAM : ORIGIN = DRAMORIG + DRAMSIZE - 0x100000, LENGTH = 0x100000 +#else + DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE +#endif + IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE } SECTIONS { - .text : - { - loadaddress = .; - _loadaddress = .; - . = ALIGN(0x200); + .text : { + loadaddress = .; + _loadaddress = .; + . = ALIGN(0x200); *(.init.text) + *(.text) *(.text*) *(.glue_7) *(.glue_7t) - . = ALIGN(0x4); - } > DRAM - - .rodata : - { - *(.rodata) /* problems without this, dunno why */ - *(.rodata*) - *(.rodata.str1.1) - *(.rodata.str1.4) - . = ALIGN(0x4); + } > DRAM - /* Pseudo-allocate the copies of the data sections */ - _datacopy = .; - } > DRAM - - /* TRICK ALERT! For RAM execution, we put the .data section at the - same load address as the copy. Thus, we don't waste extra RAM - when we don't actually need the copy. */ - .data : AT ( _datacopy ) - { - _datastart = .; - *(.data*) - . = ALIGN(0x4); - _dataend = .; - } > DRAM - - /DISCARD/ : - { - *(.eh_frame) - } - - .vectors 0x0 : - { - _vectorsstart = .; - *(.vectors); - _vectorsend = .; - } AT> DRAM - - _vectorscopy = LOADADDR(.vectors); - - .iram : - { - _iramstart = .; + .data : { *(.icode) *(.irodata) *(.idata) + *(.data*) + *(.rodata.*) + *(.rodata) . = ALIGN(0x4); - _iramend = .; - } > DRAM - - _iramcopy = LOADADDR(.iram); - - .ibss (NOLOAD) : - { - _iedata = .; - *(.ibss) - . = ALIGN(0x4); - _iend = .; + _dataend = . ; } > DRAM .stack : { - *(.stack) - stackbegin = .; - . += 0x2000; - stackend = .; - } > DRAM - - .bss : - { - _edata = .; - *(.bss*) - *(COMMON) - . = ALIGN(0x4); - _end = .; + *(.stack) + _stackbegin = .; + stackbegin = .; + . += 0x2000; + _stackend = .; + stackend = .; } > DRAM + .bss : { + _edata = .; + *(.bss*); + *(.ibss); + *(COMMON) + _end = .; + } > DRAM .audiobuf ALIGN(4) : { _audiobuffer = .; @@ -128,7 +90,7 @@ SECTIONS audiobufend = .; _audiobufend = .; } > DRAM - + .codec ENDAUDIOADDR: { codecbuf = .; @@ -139,6 +101,5 @@ SECTIONS { _pluginbuf = .; pluginbuf = .; - } + } } - diff --git a/firmware/target/arm/tcc77x/boot.lds b/firmware/target/arm/tcc77x/boot.lds index 890c4ec785..2fd6964d57 100644 --- a/firmware/target/arm/tcc77x/boot.lds +++ b/firmware/target/arm/tcc77x/boot.lds @@ -14,7 +14,11 @@ STARTUP(target/arm/tcc77x/crt0.o) MEMORY { +#ifdef TCCBOOT DRAM : ORIGIN = DRAMORIG + DRAMSIZE - 0x100000, LENGTH = 0x100000 +#else + DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE +#endif IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE } @@ -34,6 +38,7 @@ SECTIONS *(.idata) *(.data*) *(.rodata.*) + *(.rodata) . = ALIGN(0x4); _dataend = . ; } > DRAM diff --git a/firmware/target/arm/tcc77x/crt0.S b/firmware/target/arm/tcc77x/crt0.S index e144c16fae..569930352a 100644 --- a/firmware/target/arm/tcc77x/crt0.S +++ b/firmware/target/arm/tcc77x/crt0.S @@ -82,12 +82,15 @@ start_loc: #ifdef TCCBOOT mov r0, #0x80000000 -#ifdef LOGIK_DAX +#if defined(LOGIK_DAX) ldr r0, [r0, #0x300] /* Hold button is GPIO A, pin 0x2 */ tst r0, #0x2 #elif defined(SANSA_M200) ldr r0, [r0, #0x310] /* Hold button is GPIO B, pin 0x200 */ tst r0, #0x200 +#elif defined(IAUDIO_7) + ldr r0, [r0, #0x300] /* Hold button is !GPIO A, pin 0x2 */ + tst r0, #0x2 #else #error No bootup key detection implemented for this target #endif diff --git a/firmware/target/arm/tcc77x/debug-tcc77x.c b/firmware/target/arm/tcc77x/debug-tcc77x.c index 4566c7ea73..203a6010ce 100644 --- a/firmware/target/arm/tcc77x/debug-tcc77x.c +++ b/firmware/target/arm/tcc77x/debug-tcc77x.c @@ -56,8 +56,11 @@ bool __dbg_hw_info(void) button = button_get(false); button &= ~BUTTON_REPEAT; - +#ifdef BUTTON_SELECT if (button == BUTTON_SELECT) +#else + if (button == BUTTON_STOP) +#endif done=true; snprintf(buf, sizeof(buf), "current tick: %08x Seconds running: %08d", diff --git a/firmware/target/arm/tcc77x/iaudio7/adc-target.h b/firmware/target/arm/tcc77x/iaudio7/adc-target.h new file mode 100644 index 0000000000..1916d93598 --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/adc-target.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Dave Chapman + * + * 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 _ADC_TARGET_H_ +#define _ADC_TARGET_H_ + +#define NUM_ADC_CHANNELS 8 + +#define ADC_BUTTONS 0 + +#endif /* _ADC_TARGET_H_ */ diff --git a/firmware/target/arm/tcc77x/iaudio7/ata2501.c b/firmware/target/arm/tcc77x/iaudio7/ata2501.c new file mode 100644 index 0000000000..fa165d9d0d --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/ata2501.c @@ -0,0 +1,124 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 "cpu.h" +#include "button.h" + +#include "ata2501.h" + +#define STB (1<<5) +#define SDATA (1<<4) +#define RESET (1<<6) +#define SIFMD (1<<7) +#define STB_DELAY 200 + +#define udelay _udelay + +/* do we really need it? */ +static void _udelay(int cycles) +{ + cycles /= 8; + while (cycles--) { + asm("nop;nop;"); + } +} + +/* + TODO: sensitivity using GPIOS +*/ +void ata2501_init(void) +{ + GPIOD_DIR |= (RESET | STB | SIFMD | (1 << 8) | (1 << 9)); + GPIOD_DIR &= ~(SDATA); + + GPIOD &= ~RESET; + udelay(1000); + + GPIOD |= RESET; + + GPIOD &= ~STB; + +#if 1 + GPIOD &= ~((1 << 9) | (1 << 8)); + GPIOD |= ((1 << 8) | SIFMD) | (1 << 9); +#else + GPIOD |= ((1 << 9) | (1 << 8)); + GPIOD &= ~(SIFMD); +#endif +} + +unsigned short ata2501_read(void) +{ + unsigned short ret = 0; + int i; + + for (i = 0; i < 12; i++) { + GPIOD |= STB; + udelay(50); + + ret <<= 1; + if (GPIOD & SDATA) + ret |= 1; + udelay(50); + GPIOD &= ~STB; + udelay(100); + } + + return ret; +} + +#define ATA2501_TEST +#ifdef ATA2501_TEST +#include "lcd.h" +#include "sprintf.h" + +static +void bits(char *str, unsigned short val) +{ + int i; + + for (i = 0; i < 12; i++) + str[i] = (val & (1 << i)) ? '1' : '0'; + str[i] = 0; +} + +void ata2501_test(void) +{ + char buf[100]; + ata2501_init(); + + while (1) { + unsigned short data; + int i, line = 0; + + data = ata2501_read(); + lcd_clear_display(); + lcd_puts(0, line++, "ATA2501 test"); + + bits(buf, data); + lcd_puts(0, line++, buf); + + lcd_update(); + udelay(2000); + } +} +#endif diff --git a/firmware/target/arm/tcc77x/iaudio7/ata2501.h b/firmware/target/arm/tcc77x/iaudio7/ata2501.h new file mode 100644 index 0000000000..465d0b199c --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/ata2501.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 _ATA2501_H_ +#define _ATA2501_H_ + +void ata2501_init(void); +unsigned short ata2501_read(void); + +#endif /* _ATA2501_H_ */ diff --git a/firmware/target/arm/tcc77x/iaudio7/audio-iaudio7.c b/firmware/target/arm/tcc77x/iaudio7/audio-iaudio7.c new file mode 100644 index 0000000000..4e7f58df47 --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/audio-iaudio7.c @@ -0,0 +1,99 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "cpu.h" +#include "audio.h" +#include "sound.h" + +int audio_channels = 2; +int audio_output_source = AUDIO_SRC_PLAYBACK; + +void audiohw_enable_output(bool on) +{ + (void) on; +} + +void audio_set_output_source(int source) +{ + int oldmode = set_fiq_status(FIQ_DISABLED); + + if ((unsigned)source >= AUDIO_NUM_SOURCES) + source = AUDIO_SRC_PLAYBACK; + + audio_output_source = source; + set_fiq_status(oldmode); +} + +void audio_input_mux(int source, unsigned flags) +{ + static int last_source = AUDIO_SRC_PLAYBACK; + static bool last_recording = false; + bool recording = flags & SRCF_RECORDING; + + switch (source) + { + default: /* playback - no recording */ + source = AUDIO_SRC_PLAYBACK; + case AUDIO_SRC_PLAYBACK: + audio_channels = 2; + if (source != last_source) + { + audiohw_set_monitor(false); + /* audiohw_disable_recording();*/ + } + break; + + case AUDIO_SRC_MIC: /* recording only */ + GPIOD |= 0x1; + + audio_channels = 1; + if (source != last_source) + { + /*audiohw_set_monitor(false); + audiohw_enable_recording(true); /. source mic */ + } + break; + + case AUDIO_SRC_FMRADIO: /* recording and playback */ + GPIOD &= ~0x1; + + audio_channels = 2; + + if (source == last_source && recording == last_recording) + break; + + last_recording = recording; + + if (recording) + { + /*audiohw_set_monitor(false); + audiohw_enable_recording(false);*/ + } + else + { + /*audiohw_disable_recording(); */ + audiohw_set_monitor(true); /* line 1 analog audio path */ + } + break; + } /* end switch */ + + last_source = source; +} /* audio_input_mux */ diff --git a/firmware/target/arm/tcc77x/iaudio7/backlight-target.h b/firmware/target/arm/tcc77x/iaudio7/backlight-target.h new file mode 100644 index 0000000000..597583b16f --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/backlight-target.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H + +#include +#include "tcc77x.h" + +void power_touch_panel(bool on); + +static inline bool _backlight_init(void) +{ + GPIOD_DIR |= 0x2; + return true; +} + +static inline void _backlight_on(void) +{ + GPIOD |= 0x2; + power_touch_panel(true); +} + +static inline void _backlight_off(void) +{ + GPIOD &= ~0x2; + power_touch_panel(false); +} +#endif /* BACKLIGHT_TARGET_H */ diff --git a/firmware/target/arm/tcc77x/iaudio7/button-iaudio7.c b/firmware/target/arm/tcc77x/iaudio7/button-iaudio7.c new file mode 100644 index 0000000000..3aad4f75a4 --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/button-iaudio7.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 "cpu.h" +#include "button.h" +#include "adc.h" + +#include "button-target.h" +#include "ata2501.h" + +void button_init_device(void) +{ + ata2501_init(); +} + +/* + touchpad: + 0: stop + 1-8: between next & prev + 9: play + 10: next + 11: prev +*/ + +int button_read_device(void) +{ + int btn = BUTTON_NONE; + int adc; + int sensor; + + if (button_hold()) + return BUTTON_NONE; + + adc = adc_read(0); + sensor = ata2501_read(); + + if (0 == (GPIOA & 4)) + btn |= BUTTON_POWER; + + /* seems they can't be hold together */ + if (adc < 0x120) + btn |= BUTTON_VOLUP; + else if (adc < 0x270) + btn |= BUTTON_VOLDOWN; + else if (adc < 0x300) + btn |= BUTTON_MENU; + + if (sensor & (1 << 0)) + btn |= BUTTON_STOP; + if (sensor & (1 << 9)) + btn |= BUTTON_PLAY; + if (sensor & ((1 << 10) | 0x1c0)) + btn |= BUTTON_RIGHT; + if (sensor & ((1 << 11) | 0xe)) + btn |= BUTTON_LEFT; + + return btn; +} + +bool button_hold(void) +{ + return !(GPIOA & 0x2); +} diff --git a/firmware/target/arm/tcc77x/iaudio7/button-target.h b/firmware/target/arm/tcc77x/iaudio7/button-target.h new file mode 100644 index 0000000000..fafaf4a303 --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/button-target.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 _IAUDIO7_BUTTON_TARGET_H_ +#define _IAUDIO7_BUTTON_TARGET_H_ + +#include +#include "config.h" + +#define HAS_BUTTON_HOLD + +bool button_hold(void); +void button_init_device(void); +int button_read_device(void); + +/* Main unit's buttons */ +#define BUTTON_POWER 0x00000001 +#define BUTTON_VOLUP 0x00000002 +#define BUTTON_VOLDOWN 0x00000004 +#define BUTTON_MENU 0x00000008 + +#define BUTTON_LEFT 0x00000010 +#define BUTTON_RIGHT 0x00000020 +#define BUTTON_PLAY 0x00000040 +#define BUTTON_STOP 0x00000080 + +#define BUTTON_ON BUTTON_POWER + +#define BUTTON_MAIN (BUTTON_POWER|BUTTON_VOLUP|BUTTON_VOLDOWN| \ + BUTTON_MENU|BUTTON_LEFT|BUTTON_RIGHT| \ + BUTTON_PLAY|BUTTON_STOP) + +/* No remote */ +#define BUTTON_REMOTE 0 + +/* Software power-off */ +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 10 + +#endif /* _IAUDIO7_BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c b/firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c new file mode 100644 index 0000000000..bbc20b6860 --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c @@ -0,0 +1,252 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2004 by Linus Nielsen Feltzing + * + * 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. + * + ****************************************************************************/ + +/* + Thanks Hein-Pieter van Braam for initial work. + + Mostly based on lcd-h300.c, adapted for the iaudio 7 by Vitja Makarov + */ + +#include + +#include +#include +#include +#include + +#include "hd66789r.h" + +static bool display_on = false; /* is the display turned on? */ + +static inline void lcd_write_reg(int reg, int data) +{ + GPIOA &= ~0x400; + outw(0, 0x50010000); + outw(reg << 1, 0x50010000); + GPIOA |= 0x400; + + outw((data & 0xff00) >> 7, 0x50010008); + outw((data << 24) >> 23, 0x50010008); +} + +static void lcd_write_cmd(int reg) +{ + GPIOA &= ~0x400; + outw(0, 0x50010000); + outw(reg << 1, 0x50010000); + GPIOA |= 0x400; +} + +/* Do what OF do */ +static void lcd_delay(int x) +{ + int i; + + x *= 0xc35; + for (i = 0; i < x * 8; i++) { + } +} + + +static void _display_on(void) +{ + GPIOA_DIR |= 0x8000 | 0x400; + GPIOA |= 0x8000; + + /* power setup */ + lcd_write_reg(R_START_OSC, 0x0001); + lcd_delay(0xf); + lcd_write_reg(R_DISP_CONTROL1, 0x000); + lcd_delay(0xa); + lcd_write_reg(R_POWER_CONTROL2, 0x0002); + lcd_write_reg(R_POWER_CONTROL3, 0x000a); + lcd_write_reg(R_POWER_CONTROL4, 0xc5a); + lcd_write_reg(R_POWER_CONTROL1, 0x0004); + lcd_write_reg(R_POWER_CONTROL1, 0x0134); + lcd_write_reg(R_POWER_CONTROL2, 0x0111); + lcd_write_reg(R_POWER_CONTROL3, 0x001c); + lcd_delay(0x28); + lcd_write_reg(R_POWER_CONTROL4, 0x2c40); + lcd_write_reg(R_POWER_CONTROL1, 0x0510); + lcd_delay(0x3c); + + /* lcd init 2 */ + lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x0113); + lcd_write_reg(R_DRV_WAVEFORM_CONTROL, 0x0700); + lcd_write_reg(R_ENTRY_MODE, 0x1038); + lcd_write_reg(R_DISP_CONTROL2, 0x0508); // 0x3c8, TMM + lcd_write_reg(R_DISP_CONTROL3, 0x0000); + lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0003); + lcd_write_reg(R_RAM_ADDR_SET, 0x0000); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0406); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0303); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0000); + lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0305); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0404); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0000); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0000); + lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0503); + lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0x1d05); + lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0x1d05); + lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000); + lcd_write_reg(R_1ST_SCR_DRV_POS, 0x9f00); + lcd_write_reg(R_2ND_SCR_DRV_POS, 0x9f00); + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00); + lcd_write_reg(R_VERT_RAM_ADDR_POS, 0x9f00); + + /* lcd init 3 */ + lcd_write_reg(R_POWER_CONTROL1, 0x4510); + lcd_write_reg(R_DISP_CONTROL1, 0x0005); + lcd_delay(0x28); + lcd_write_reg(R_DISP_CONTROL1, 0x0025); + lcd_write_reg(R_DISP_CONTROL1, 0x0027); + lcd_delay(0x28); + lcd_write_reg(R_DISP_CONTROL1, 0x0037); + + display_on = true; +} + +void lcd_init_device(void) +{ + /* Configure external memory banks */ + CSCFG1 = 0x3d500023; + + /* may be reset */ + GPIOA |= 0x8000; + + _display_on(); +} + +void lcd_enable(bool on) +{ + if (display_on == on) + return; + + if (on) { + _display_on(); +// lcd_call_enable_hook(); + } else { + /** Off sequence according to datasheet, p. 130 **/ + lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0002); /* EQ=0, 18 clks/line */ + lcd_write_reg(R_DISP_CONTROL1, 0x0036); /* GON=1, DTE=1, REV=1, D1-0=10 */ + sleep(2); + + lcd_write_reg(R_DISP_CONTROL1, 0x0026); /* GON=1, DTE=0, REV=1, D1-0=10 */ + sleep(2); + + lcd_write_reg(R_DISP_CONTROL1, 0x0000); /* GON=0, DTE=0, D1-0=00 */ + + lcd_write_reg(R_POWER_CONTROL1, 0x0000); /* SAP2-0=000, AP2-0=000 */ + lcd_write_reg(R_POWER_CONTROL3, 0x0000); /* PON=0 */ + lcd_write_reg(R_POWER_CONTROL4, 0x0000); /* VCOMG=0 */ + + /* datasheet p. 131 */ + lcd_write_reg(R_POWER_CONTROL1, 0x0001); /* STB=1: standby mode */ + + display_on = false; + } +} + +bool lcd_enabled(void) +{ + return display_on; +} + + +#define RGB(r,g,b) ((((r)&0x3f) << 12)|(((g)&0x3f) << 6)|(((b)&0x3f))) + + +void lcd_update(void) +{ + lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); +} + +/* todo: need tests */ +void lcd_update_rect(int sx, int sy, int width, int height) +{ + int x, y; + + if (!display_on) + return; + + if (width <= 0 || height <= 0) /* nothing to do */ + return; + + width += sx; + height += sy; + + if (width > LCD_WIDTH) + width = LCD_WIDTH; + if (height > LCD_HEIGHT) + height = LCD_HEIGHT; + + lcd_write_reg(R_ENTRY_MODE, 0x1028); + /* set update window */ + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_HEIGHT - 1) << 8); + lcd_write_reg(R_VERT_RAM_ADDR_POS, ((width - 1) << 8) | sx); + lcd_write_reg(R_RAM_ADDR_SET, (sx << 8) | (LCD_HEIGHT - sy - 1)); + lcd_write_cmd(R_WRITE_DATA_2_GRAM); + + for (y = sy; y < height; y++) { + for (x = sx; x < width; x++) { + fb_data c; + unsigned long color; + + c = lcd_framebuffer[y][x]; + color = + ((c & 0x1f) << 1) | ((c & 0x7e0) << 1) | ((c & 0xf800) << + 2); + + /* TODO: our color is 18-bit */ + outw((color >> 9) & 0x1ff, 0x50010008); + outw((color) & 0x1ff, 0x50010008); + } + } +} + +void lcd_set_contrast(int val) +{ + (void) val; +} + +void lcd_set_invert_display(bool yesno) +{ + (void) yesno; +} + +void lcd_set_flip(bool yesno) +{ + (void) yesno; +} + +/* TODO: implement me */ +void lcd_blit_yuv(unsigned char *const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + if (!display_on) + return; + + width &= ~1; /* stay on the safe side */ + height &= ~1; + + panicf("%s", __func__); +} diff --git a/firmware/target/arm/tcc77x/iaudio7/power-iaudio7.c b/firmware/target/arm/tcc77x/iaudio7/power-iaudio7.c new file mode 100644 index 0000000000..ef012cbbdf --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/power-iaudio7.c @@ -0,0 +1,146 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Vitja Makarov + * + * 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 "cpu.h" +#include "kernel.h" +#include "system.h" +#include "power.h" + +#include "pcf50606.h" + +void power_init(void) +{ + pcf50606_write(PCF5060X_DCDC1, 0x90); + pcf50606_write(PCF5060X_DCDC2, 0x48); + pcf50606_write(PCF5060X_DCDC3, 0xfc); + pcf50606_write(PCF5060X_DCDC4, 0xb1); + + pcf50606_write(PCF5060X_IOREGC, 0xe9); + /* 3.3V, touch-panel */ + pcf50606_write(PCF5060X_D1REGC1, 0xf8); + pcf50606_write(PCF5060X_D2REGC1, 0xf2); + pcf50606_write(PCF5060X_D3REGC1, 0xf5); + + pcf50606_write(PCF5060X_LPREGC1, 0x00); + pcf50606_write(PCF5060X_LPREGC2, 0x02); + + pcf50606_write(PCF5060X_DCUDC1, 0xe6); + pcf50606_write(PCF5060X_DCUDC2, 0x30); + + pcf50606_write(PCF5060X_DCDEC1, 0xe7); + pcf50606_write(PCF5060X_DCDEC2, 0x02); + + pcf50606_write(PCF5060X_INT1M, 0x5b); + pcf50606_write(PCF5060X_INT1M, 0xaf); + pcf50606_write(PCF5060X_INT1M, 0x8f); + + pcf50606_write(PCF5060X_OOCC1, 0x40); + pcf50606_write(PCF5060X_OOCC2, 0x05); + + pcf50606_write(PCF5060X_MBCC3, 0x3a); + pcf50606_write(PCF5060X_GPOC1, 0x00); + pcf50606_write(PCF5060X_BBCC, 0xf8); +} + +/* Control leds on ata2501 board */ +void power_touch_panel(bool on) +{ + if (on) + pcf50606_write(PCF5060X_D1REGC1, 0xf8); + else + pcf50606_write(PCF5060X_D1REGC1, 0x00); +} + +void ide_power_enable(bool on) +{ +} + +bool ide_powered(void) +{ + return true; +} + +void power_off(void) +{ + /* Forcibly cut power to SoC & peripherals by putting the PCF to sleep */ + pcf50606_write(PCF5060X_OOCC1, GOSTDBY | CHGWAK | EXTONWAK); +} + +#if CONFIG_TUNER +#include "tuner.h" + +/** Tuner **/ +static bool powered = false; + +#define TUNNER_CLK (1 << 5) +#define TUNNER_DATA (1 << 6) +#define TUNNER_NR_W (1 << 7) + +bool tuner_power(bool status) +{ + bool old_status; + lv24020lp_lock(); + + old_status = powered; + + if (status != old_status) + { + if (status) + { + /* When power up, host should initialize the 3-wire bus + in host read mode: */ + + /* 1. Set direction of the DATA-line to input-mode. */ + GPIOA_DIR &= ~TUNNER_DATA; + + /* 2. Drive NR_W low */ + GPIOA &= ~TUNNER_NR_W; + GPIOA_DIR |= TUNNER_NR_W; + + /* 3. Drive CLOCK high */ + GPIOA |= TUNNER_CLK; + GPIOA_DIR |= TUNNER_CLK; + + lv24020lp_power(true); + } + else + { + lv24020lp_power(false); + + /* set all as inputs */ + GPIOC_DIR &= ~(TUNNER_CLK | TUNNER_DATA | TUNNER_NR_W); + } + + powered = status; + } + + lv24020lp_unlock(); + return old_status; +} + +#endif /* CONFIG_TUNER */ + +bool charger_inserted(void) +{ + return (GPIOA & 0x1) ? true : false; +} diff --git a/firmware/target/arm/tcc77x/pcm-tcc77x.c b/firmware/target/arm/tcc77x/pcm-tcc77x.c deleted file mode 100644 index 184a264858..0000000000 --- a/firmware/target/arm/tcc77x/pcm-tcc77x.c +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2008 by [whoever fills in these functions] - * - * 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 "kernel.h" -#include "logf.h" -#include "audio.h" -#include "sound.h" -#include "file.h" - -void pcm_postinit(void) -{ -} - -const void * pcm_play_dma_get_peak_buffer(int *count) -{ - (void)count; - return 0; -} - -void pcm_play_dma_init(void) -{ -} - -void pcm_apply_settings(void) -{ -} - -void pcm_set_frequency(unsigned int frequency) -{ - (void)frequency; -} - -void pcm_play_dma_start(const void *addr, size_t size) -{ - (void)addr; - (void)size; -} - -void pcm_play_dma_stop(void) -{ -} - -void pcm_play_lock(void) -{ -} - -void pcm_play_unlock(void) -{ -} - -void pcm_play_dma_pause(bool pause) -{ - (void)pause; -} - -size_t pcm_get_bytes_waiting(void) -{ - return 0; -} diff --git a/firmware/target/arm/tcc77x/system-tcc77x.c b/firmware/target/arm/tcc77x/system-tcc77x.c index c50a8a6651..2c8959fded 100644 --- a/firmware/target/arm/tcc77x/system-tcc77x.c +++ b/firmware/target/arm/tcc77x/system-tcc77x.c @@ -26,6 +26,7 @@ /* Externally defined interrupt handlers */ extern void TIMER(void); extern void ADC(void); +extern void USBD_IRQ(void); void irq(void) { @@ -36,14 +37,22 @@ void irq(void) TIMER(); else if (irq & ADC_IRQ_MASK) ADC(); +#ifdef HAVE_USBSTACK + else if (irq & USBD_IRQ_MASK) + USBD_IRQ(); +#endif else panicf("Unhandled IRQ 0x%08X", irq); } +void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked)); + +#ifdef BOOTLOADER void fiq_handler(void) { /* TODO */ } +#endif void system_reboot(void) { @@ -94,7 +103,7 @@ static void gpio_init(void) GPIOC = 0; GPIOD = 0x180; GPIOE = 0; - GPIOA_DIR = 0x84b0 + GPIOA_DIR = 0x84b0; GPIOB_DIR = 0x80800; GPIOC_DIR = 0x2000000; GPIOD_DIR = 0x3e3; diff --git a/firmware/target/arm/tcc77x/usb-tcc77x.c b/firmware/target/arm/tcc77x/usb-tcc77x.c index 85c8bed3ef..9cfcb503e0 100644 --- a/firmware/target/arm/tcc77x/usb-tcc77x.c +++ b/firmware/target/arm/tcc77x/usb-tcc77x.c @@ -7,7 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * - * Copyright (C) 2008 by [whoever fills in these functions] + * Copyright (C) 2008 by Vitja Makarov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,9 +21,15 @@ #include "config.h" #include "usb.h" +#include "system.h" +#include "usb-tcc7xx.h" void usb_init_device(void) { + /* simply switch USB off for now */ + BCLKCTR |= DEV_USBD; + TCC7xx_USB_PHY_CFG = 0x3e4c; + BCLKCTR &= ~DEV_USBD; } void usb_enable(bool on) diff --git a/firmware/target/arm/tcc780x/pcm-tcc780x.c b/firmware/target/arm/tcc780x/pcm-tcc780x.c deleted file mode 100644 index 375274438a..0000000000 --- a/firmware/target/arm/tcc780x/pcm-tcc780x.c +++ /dev/null @@ -1,314 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006 by Michael Sevakis - * Copyright (C) 2008 by Rob Purchase - * - * 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 "pcm.h" - -struct dma_data -{ -/* NOTE: The order of size and p is important if you use assembler - optimised fiq handler, so don't change it. */ - uint16_t *p; - size_t size; -#if NUM_CORES > 1 - unsigned core; -#endif - int locked; - int state; -}; - -/**************************************************************************** - ** Playback DMA transfer - **/ -struct dma_data dma_play_data SHAREDBSS_ATTR = -{ - /* Initialize to a locked, stopped state */ - .p = NULL, - .size = 0, -#if NUM_CORES > 1 - .core = 0x00, -#endif - .locked = 0, - .state = 0 -}; - -static unsigned long pcm_freq SHAREDDATA_ATTR = HW_SAMPR_DEFAULT; /* 44.1 is default */ - -void pcm_postinit(void) -{ - /*audiohw_postinit();*/ - pcm_apply_settings(); -} - -const void * pcm_play_dma_get_peak_buffer(int *count) -{ - unsigned long addr = (unsigned long)dma_play_data.p; - size_t cnt = dma_play_data.size; - *count = cnt >> 2; - return (void *)((addr + 2) & ~3); -} - -void pcm_play_dma_init(void) -{ - /* Set DAI clock divided from PLL0 (192MHz). - The best approximation of 256*44.1kHz is 11.291MHz. */ - BCLKCTR &= ~DEV_DAI; - PCLK_DAI = (1<<28) | 61682; /* DCO mode */ - BCLKCTR |= DEV_DAI; - - /* Enable DAI block in Master mode, 256fs->32fs, 16bit LSB */ - DAMR = 0x3c8e80; - DAVC = 0x0; /* Digital Volume = max */ - - /* Set DAI interrupts as FIQs */ - IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK); - - pcm_set_frequency(SAMPR_44); - - /* Initialize default register values. */ - audiohw_init(); - - /* Power on */ - audiohw_enable_output(true); - - /* Unmute the master channel (DAC should be at zero point now). */ - audiohw_mute(false); - - dma_play_data.size = 0; -#if NUM_CORES > 1 - dma_play_data.core = 0; /* no core in control */ -#endif -} - -void pcm_apply_settings(void) -{ - pcm_curr_sampr = pcm_freq; -} - -void pcm_set_frequency(unsigned int frequency) -{ - (void) frequency; - pcm_freq = HW_SAMPR_DEFAULT; -} - -static void play_start_pcm(void) -{ - pcm_apply_settings(); - - DAMR &= ~(1<<14); /* disable tx */ - dma_play_data.state = 1; - - if (dma_play_data.size >= 16) - { - DADO_L(0) = *dma_play_data.p++; - DADO_R(0) = *dma_play_data.p++; - DADO_L(1) = *dma_play_data.p++; - DADO_R(1) = *dma_play_data.p++; - DADO_L(2) = *dma_play_data.p++; - DADO_R(2) = *dma_play_data.p++; - DADO_L(3) = *dma_play_data.p++; - DADO_R(3) = *dma_play_data.p++; - dma_play_data.size -= 16; - } - - DAMR |= (1<<14); /* enable tx */ -} - -static void play_stop_pcm(void) -{ - DAMR &= ~(1<<14); /* disable tx */ - dma_play_data.state = 0; -} - -void pcm_play_dma_start(const void *addr, size_t size) -{ - dma_play_data.p = (void *)(((uintptr_t)addr + 2) & ~3); - dma_play_data.size = (size & ~3); - -#if NUM_CORES > 1 - /* This will become more important later - and different ! */ - dma_play_data.core = processor_id(); /* save initiating core */ -#endif - - IEN |= DAI_TX_IRQ_MASK; - - play_start_pcm(); -} - -void pcm_play_dma_stop(void) -{ - play_stop_pcm(); - dma_play_data.size = 0; -#if NUM_CORES > 1 - dma_play_data.core = 0; /* no core in control */ -#endif -} - -void pcm_play_lock(void) -{ - int status = disable_fiq_save(); - - if (++dma_play_data.locked == 1) - { - IEN &= ~DAI_TX_IRQ_MASK; - } - - restore_fiq(status); -} - -void pcm_play_unlock(void) -{ - int status = disable_fiq_save(); - - if (--dma_play_data.locked == 0 && dma_play_data.state != 0) - { - IEN |= DAI_TX_IRQ_MASK; - } - - restore_fiq(status); -} - -void pcm_play_dma_pause(bool pause) -{ - (void) pause; -} - -size_t pcm_get_bytes_waiting(void) -{ - return dma_play_data.size & ~3; -} - -#if 1 -void fiq_handler(void) ICODE_ATTR __attribute__((naked)); -void fiq_handler(void) -{ - /* r10 contains DADO_L0 base address (set in crt0.S to minimise code in the - * FIQ handler. r11 contains address of p (also set in crt0.S). Most other - * addresses we need are generated by using offsets with these two. - * r8 and r9 contains local copies of p and size respectively. - * r0-r3 and r12 is a working register. - */ - asm volatile ( - "mov r8, #0xc000 \n" /* DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK */ - "ldr r9, =0xf3001004 \n" /* CREQ */ - "str r8, [r9] \n" /* clear DAI IRQs */ - - "ldmia r11, { r8-r9 } \n" /* r8 = p, r9 = size */ - "cmp r9, #0x10 \n" /* is size <16? */ - "blt .more_data \n" /* if so, ask pcmbuf for more data */ - - ".fill_fifo: \n" - "ldr r12, [r8], #4 \n" /* load two samples */ - "str r12, [r10, #0x0] \n" /* write top sample to DADO_L0 */ - "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ - "str r12, [r10, #0x4] \n" /* write low sample to DADO_R0*/ - "ldr r12, [r8], #4 \n" /* load two samples */ - "str r12, [r10, #0x8] \n" /* write top sample to DADO_L1 */ - "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ - "str r12, [r10, #0xc] \n" /* write low sample to DADO_R1*/ - "ldr r12, [r8], #4 \n" /* load two samples */ - "str r12, [r10, #0x10] \n" /* write top sample to DADO_L2 */ - "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ - "str r12, [r10, #0x14] \n" /* write low sample to DADO_R2*/ - "ldr r12, [r8], #4 \n" /* load two samples */ - "str r12, [r10, #0x18] \n" /* write top sample to DADO_L3 */ - "mov r12, r12, lsr #16 \n" /* put right sample at the bottom */ - "str r12, [r10, #0x1c] \n" /* write low sample to DADO_R3*/ - "sub r9, r9, #0x10 \n" /* 4 words written */ - "stmia r11, { r8-r9 } \n" /* save p and size */ - - ".exit: \n" - "subs pc, lr, #4 \n" /* FIQ specific return sequence */ - - ".more_data: \n" - "stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */ - "ldr r2, =pcm_callback_for_more \n" - "ldr r2, [r2] \n" /* get callback address */ - "cmp r2, #0 \n" /* check for null pointer */ - "movne r0, r11 \n" /* r0 = &p */ - "addne r1, r11, #4 \n" /* r1 = &size */ - "blxne r2 \n" /* call pcm_callback_for_more */ - "ldmia r11, { r8-r9 } \n" /* reload p and size */ - "cmp r9, #0x10 \n" /* did we actually get more data? */ - "ldmgefd sp!, { r0-r3, lr } \n" - "bge .fill_fifo \n" /* yes: fill the fifo */ - "ldr r12, =pcm_play_dma_stop \n" - "blx r12 \n" /* no: stop playback */ - "ldr r12, =pcm_play_dma_stopped_callback \n" - "blx r12 \n" - "ldmfd sp!, { r0-r3, lr } \n" - "b .exit \n" - ".ltorg \n" - ); -} -#else /* C version for reference */ -void fiq_handler(void) ICODE_ATTR __attribute__((naked)); -void fiq_handler(void) -{ - asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ - "sub sp, sp, #8 \n"); /* Reserve stack */ - - register pcm_more_callback_type get_more; - - if (dma_play_data.size < 16) - { - /* p is empty, get some more data */ - get_more = pcm_callback_for_more; - if (get_more) - { - get_more((unsigned char**)&dma_play_data.p, - &dma_play_data.size); - } - } - - if (dma_play_data.size >= 16) - { - DADO_L(0) = *dma_play_data.p++; - DADO_R(0) = *dma_play_data.p++; - DADO_L(1) = *dma_play_data.p++; - DADO_R(1) = *dma_play_data.p++; - DADO_L(2) = *dma_play_data.p++; - DADO_R(2) = *dma_play_data.p++; - DADO_L(3) = *dma_play_data.p++; - DADO_R(3) = *dma_play_data.p++; - - dma_play_data.size -= 16; - } - else - { - /* No more data, so disable the FIFO/interrupt */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); - } - - /* Clear FIQ status */ - CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; - - asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ - "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ - "subs pc, lr, #4 \n"); /* Return from FIQ */ -} -#endif diff --git a/firmware/target/arm/wmcodec-telechips.c b/firmware/target/arm/wmcodec-telechips.c index 985a72dccc..5fcc46154b 100644 --- a/firmware/target/arm/wmcodec-telechips.c +++ b/firmware/target/arm/wmcodec-telechips.c @@ -34,6 +34,8 @@ #if defined(COWON_D2) /* The D2's audio codec uses an I2C address of 0x34 */ #define I2C_AUDIO_ADDRESS 0x34 +#elif defined (IAUDIO_7) +#define I2C_AUDIO_ADDRESS 0x34 #else #error wmcodec not implemented for this target! #endif @@ -41,6 +43,9 @@ void audiohw_init(void) { +#if defined(HAVE_WM8731) || defined(HAVE_WM8751) + audiohw_preinit(); +#endif } void wmcodec_write(int reg, int data) diff --git a/tools/configure b/tools/configure index 2349b9efbf..fd46f03519 100755 --- a/tools/configure +++ b/tools/configure @@ -1291,7 +1291,7 @@ fi target="-DIAUDIO_7" memory=16 # always arm946cc - tool="$rootdir/tools/scramble -add i7" + tool="$rootdir/tools/scramble -add=i7" boottool="$rootdir/tools/scramble -tcc=crc" bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 5" diff --git a/tools/scramble.c b/tools/scramble.c index 5dff4f4086..ffcde9328b 100644 --- a/tools/scramble.c +++ b/tools/scramble.c @@ -279,6 +279,8 @@ int main (int argc, char** argv) modelnum = 26; else if(!strcmp(&argv[1][5], "1630")) /* Philips HDD1630 */ modelnum = 31; + else if (!strcmp(&argv[1][5], "i7")) + modelnum = 32; else { fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); return 2; -- cgit