summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/SOURCES2
-rw-r--r--apps/keymaps/keymap-cowond2.c177
-rw-r--r--apps/plugins/SOURCES2
-rw-r--r--apps/plugins/lib/pluginlib_actions.c22
-rw-r--r--apps/plugins/plugin.lds4
-rw-r--r--bootloader/SOURCES2
-rw-r--r--bootloader/telechips.c49
-rw-r--r--firmware/FILES2
-rw-r--r--firmware/SOURCES28
-rw-r--r--firmware/app.lds111
-rw-r--r--firmware/boot.lds12
-rw-r--r--firmware/drivers/audio/wm8985.c143
-rw-r--r--firmware/export/audiohw.h4
-rw-r--r--firmware/export/config-cowond2.h140
-rw-r--r--firmware/export/config.h17
-rw-r--r--firmware/export/cpu.h3
-rw-r--r--firmware/export/tcc780x.h156
-rw-r--r--firmware/export/timer.h2
-rw-r--r--firmware/export/wm8985.h43
-rw-r--r--firmware/target/arm/i2c-telechips.c187
-rw-r--r--firmware/target/arm/tcc780x/adc-tcc780x.c76
-rw-r--r--firmware/target/arm/tcc780x/ata-nand-tcc780x.c113
-rw-r--r--firmware/target/arm/tcc780x/ata-target.h22
-rw-r--r--firmware/target/arm/tcc780x/cowond2/adc-target.h26
-rw-r--r--firmware/target/arm/tcc780x/cowond2/backlight-target.h40
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-cowond2.c67
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-target.h52
-rw-r--r--firmware/target/arm/tcc780x/cowond2/i2c-target.h37
-rw-r--r--firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c346
-rw-r--r--firmware/target/arm/tcc780x/cowond2/pcm-cowond2.c86
-rw-r--r--firmware/target/arm/tcc780x/cowond2/power-cowond2.c71
-rw-r--r--firmware/target/arm/tcc780x/cowond2/powermgmt-cowond2.c59
-rw-r--r--firmware/target/arm/tcc780x/cowond2/usb-cowond2.c49
-rw-r--r--firmware/target/arm/tcc780x/crt0.S304
-rw-r--r--firmware/target/arm/tcc780x/debug-tcc780x.c88
-rw-r--r--firmware/target/arm/tcc780x/kernel-tcc780x.c43
-rw-r--r--firmware/target/arm/tcc780x/system-target.h35
-rw-r--r--firmware/target/arm/tcc780x/system-tcc780x.c275
-rw-r--r--firmware/target/arm/tcc780x/timer-target.h39
-rw-r--r--firmware/target/arm/tcc780x/timer-tcc780x.c82
-rw-r--r--firmware/target/arm/wmcodec-telechips.c51
-rwxr-xr-xtools/configure26
42 files changed, 3082 insertions, 11 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 38192316a6..c93c5bcc1f 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -164,4 +164,6 @@ keymaps/keymap-av300.c
keymaps/keymap-mr500.c
#elif CONFIG_KEYPAD == MROBE100_PAD
keymaps/keymap-mr100.c
+#elif CONFIG_KEYPAD == COWOND2_PAD
+keymaps/keymap-cowond2.c
#endif
diff --git a/apps/keymaps/keymap-cowond2.c b/apps/keymaps/keymap-cowond2.c
new file mode 100644
index 0000000000..ab4216e9cf
--- /dev/null
+++ b/apps/keymaps/keymap-cowond2.c
@@ -0,0 +1,177 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id
+ *
+ * Copyright (C) 2008 Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+/* Button Code Definitions for the Cowon D2 target */
+/* Some of these mappings are rather 'creative', given it only has 3 buttons! */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "action.h"
+#include "button.h"
+#include "settings.h"
+
+/*
+ * The format of the list is as follows
+ * { Action Code, Button code, Prereq button code }
+ * if there's no need to check the previous button's value, use BUTTON_NONE
+ * Insert LAST_ITEM_IN_LIST at the end of each mapping
+ */
+
+static const struct button_mapping button_context_standard[] = {
+ { ACTION_STD_PREV, BUTTON_MINUS, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_MINUS|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_PLUS, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_PLUS|BUTTON_REPEAT, BUTTON_NONE },
+
+ { ACTION_STD_OK, BUTTON_MENU|BUTTON_REL, BUTTON_NONE },
+ //{ ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE },
+ //{ ACTION_STD_OK, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_RIGHT },
+
+ { ACTION_STD_MENU, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE },
+ // { ACTION_STD_QUICKSCREEN, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_CONTEXT, BUTTON_MINUS|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
+// { ACTION_STD_CANCEL, BUTTON_LEFT, BUTTON_NONE },
+// { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
+ LAST_ITEM_IN_LIST
+}; /* button_context_standard */
+
+
+static const struct button_mapping button_context_wps[] = {
+ LAST_ITEM_IN_LIST
+}; /* button_context_wps */
+
+static const struct button_mapping button_context_list[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_list */
+
+static const struct button_mapping button_context_tree[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
+}; /* button_context_tree */
+
+static const struct button_mapping button_context_listtree_scroll_with_combo[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
+};
+
+static const struct button_mapping button_context_listtree_scroll_without_combo[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
+};
+
+static const struct button_mapping button_context_settings[] = {
+ { ACTION_SETTINGS_INC, BUTTON_PLUS, BUTTON_NONE },
+ { ACTION_SETTINGS_INCREPEAT, BUTTON_PLUS|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_SETTINGS_DEC, BUTTON_MINUS, BUTTON_NONE },
+ { ACTION_SETTINGS_DECREPEAT, BUTTON_MINUS|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_OK, BUTTON_MENU, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_settings */
+
+static const struct button_mapping button_context_settings_right_is_inc[] = {
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_settingsgraphical */
+
+static const struct button_mapping button_context_yesno[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_settings_yesno */
+
+static const struct button_mapping button_context_colorchooser[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS),
+}; /* button_context_colorchooser */
+
+static const struct button_mapping button_context_eq[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS),
+}; /* button_context_eq */
+
+/** Bookmark Screen **/
+static const struct button_mapping button_context_bmark[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
+}; /* button_context_bmark */
+
+static const struct button_mapping button_context_time[] = {
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
+}; /* button_context_time */
+
+static const struct button_mapping button_context_quickscreen[] = {
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_quickscreen */
+
+static const struct button_mapping button_context_pitchscreen[] = {
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_pitchcreen */
+
+static const struct button_mapping button_context_keyboard[] = {
+
+ LAST_ITEM_IN_LIST
+}; /* button_context_keyboard */
+
+extern int current_tick;
+const struct button_mapping* get_context_mapping(int context)
+{
+ switch (context&(~CONTEXT_REMOTE))
+ {
+ case CONTEXT_STD:
+ return button_context_standard;
+ case CONTEXT_WPS:
+ return button_context_wps;
+
+ case CONTEXT_LIST:
+ return button_context_list;
+ case CONTEXT_MAINMENU:
+ case CONTEXT_TREE:
+ if (global_settings.hold_lr_for_scroll_in_list)
+ return button_context_listtree_scroll_without_combo;
+ else
+ return button_context_listtree_scroll_with_combo;
+ case CONTEXT_CUSTOM|CONTEXT_TREE:
+ return button_context_tree;
+
+ case CONTEXT_SETTINGS:
+ return button_context_settings;
+ case CONTEXT_CUSTOM|CONTEXT_SETTINGS:
+ return button_context_settings_right_is_inc;
+
+ case CONTEXT_SETTINGS_COLOURCHOOSER:
+ return button_context_colorchooser;
+ case CONTEXT_SETTINGS_EQ:
+ return button_context_eq;
+
+ case CONTEXT_SETTINGS_TIME:
+ return button_context_time;
+
+ case CONTEXT_YESNOSCREEN:
+ return button_context_yesno;
+ case CONTEXT_BOOKMARKSCREEN:
+ return button_context_bmark;
+ case CONTEXT_QUICKSCREEN:
+ return button_context_quickscreen;
+ case CONTEXT_PITCHSCREEN:
+ return button_context_pitchscreen;
+ case CONTEXT_KEYBOARD:
+ return button_context_keyboard;
+ }
+ return button_context_standard;
+}
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 392544dbbf..4444934e36 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -1,4 +1,4 @@
-#ifndef OLYMPUS_MROBE_100
+#if !defined(OLYMPUS_MROBE_100)
/* plugins common to all models */
battery_bench.c
diff --git a/apps/plugins/lib/pluginlib_actions.c b/apps/plugins/lib/pluginlib_actions.c
index d277fe6d0d..e74ffc0315 100644
--- a/apps/plugins/lib/pluginlib_actions.c
+++ b/apps/plugins/lib/pluginlib_actions.c
@@ -130,6 +130,15 @@ const struct button_mapping generic_directions[] =
{ PLA_DOWN_REPEAT, BUTTON_RC_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 == COWOND2_PAD)
+ { PLA_UP, BUTTON_UP, BUTTON_NONE},
+ { PLA_DOWN, BUTTON_DOWN, BUTTON_NONE},
+ { PLA_LEFT, BUTTON_UP, BUTTON_MENU},
+ { PLA_RIGHT, BUTTON_DOWN, BUTTON_MENU},
+ { PLA_UP_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE},
+ { PLA_DOWN_REPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE},
+ { PLA_LEFT_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_MENU},
+ { PLA_RIGHT_REPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_MENU},
#else
#error pluginlib_actions: Unsupported keypad
#endif
@@ -209,6 +218,13 @@ const struct button_mapping generic_left_right_fire[] =
{ PLA_RIGHT_REPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE},
{ PLA_FIRE, BUTTON_RC_HEART, BUTTON_NONE},
{ PLA_FIRE_REPEAT, BUTTON_RC_HEART|BUTTON_REPEAT, BUTTON_NONE},
+#elif (CONFIG_KEYPAD == COWOND2_PAD)
+ { PLA_LEFT, BUTTON_UP, BUTTON_NONE},
+ { PLA_RIGHT, BUTTON_DOWN, BUTTON_NONE},
+ { PLA_LEFT_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE},
+ { PLA_RIGHT_REPEAT, BUTTON_DOWN|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
@@ -307,6 +323,12 @@ const struct button_mapping generic_actions[] =
{PLA_MENU, BUTTON_RC_MODE, BUTTON_NONE},
{PLA_FIRE, BUTTON_RC_HEART, BUTTON_NONE},
{PLA_FIRE_REPEAT, BUTTON_RC_HEART|BUTTON_REPEAT, BUTTON_NONE},
+#elif (CONFIG_KEYPAD == COWOND2_PAD)
+ {PLA_QUIT, BUTTON_POWER, BUTTON_NONE},
+ {PLA_START, BUTTON_UP, BUTTON_NONE},
+ {PLA_MENU, BUTTON_DOWN, BUTTON_NONE},
+ {PLA_FIRE, BUTTON_MENU, BUTTON_NONE},
+ {PLA_FIRE_REPEAT, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE},
#else
#error pluginlib_actions: Unsupported keypad
#endif
diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds
index e877811365..a08a4a8a54 100644
--- a/apps/plugins/plugin.lds
+++ b/apps/plugins/plugin.lds
@@ -60,6 +60,10 @@ OUTPUT_FORMAT(elf32-sh)
#define IRAMORIG DRAMORIG
#define IRAMSIZE 0x4000
#define IRAM DRAM
+#elif defined(CPU_TCC780X)
+#define DRAMORIG 0x20000000
+#define IRAMORIG 0x1000c000
+#define IRAMSIZE 0xc000
#else
#define DRAMORIG 0x09000000 + STUBOFFSET
#endif
diff --git a/bootloader/SOURCES b/bootloader/SOURCES
index b8d8d3ca6b..2753debe77 100644
--- a/bootloader/SOURCES
+++ b/bootloader/SOURCES
@@ -23,7 +23,7 @@ iaudio_x5.c
iriver_h300.c
#elif defined(MROBE_500)
mrobe500.c
-#elif defined(CPU_TCC77X)
+#elif defined(CPU_TCC77X) || defined(CPU_TCC780X)
telechips.c
#else
main.c
diff --git a/bootloader/telechips.c b/bootloader/telechips.c
index 6093701044..a51b6775a1 100644
--- a/bootloader/telechips.c
+++ b/bootloader/telechips.c
@@ -41,6 +41,10 @@
#include "file.h"
#include "common.h"
+#if defined(COWON_D2)
+#include "i2c.h"
+#endif
+
char version[] = APPSVERSION;
extern int line;
@@ -50,6 +54,7 @@ void* main(void)
int button;
int power_count = 0;
int count = 0;
+ int i;
bool do_power_off = false;
system_init();
@@ -57,6 +62,10 @@ void* main(void)
lcd_init();
font_init();
+#if defined(COWON_D2)
+ lcd_enable(true);
+#endif
+
_backlight_on();
while(!do_power_off) {
@@ -68,7 +77,7 @@ void* main(void)
/* Power-off if POWER button has been held for a long time
This loop is currently running at about 100 iterations/second
*/
- if (button & BUTTON_POWERPLAY) {
+ if (button & POWEROFF_BUTTON) {
power_count++;
if (power_count > 200)
do_power_off = true;
@@ -78,6 +87,40 @@ void* main(void)
printf("Btn: 0x%08x",button);
+#if defined(COWON_D2)
+ printf("GPIOA: 0x%08x",GPIOA);
+ printf("GPIOB: 0x%08x",GPIOB);
+ printf("GPIOC: 0x%08x",GPIOC);
+ printf("GPIOD: 0x%08x",GPIOD);
+ printf("GPIOE: 0x%08x",GPIOE);
+
+ for (i = 0; i<4; i++)
+ {
+ printf("ADC%d: 0x%04x",i,adc_read(i));
+ }
+
+ /* TODO: Establish how the touchscreen driver is going to work.
+ Since it needs I2C read/write, it can't easily go on a tick task */
+ {
+ unsigned char buf[] = { 0x2f, (0xE<<1) | 1, /* ADC start for X+Y */
+ 0, 0, 0 };
+ int x,y;
+ i2c_write(0x10, buf, 2);
+ i2c_readmem(0x10, 0x2e, buf, 5);
+ x = (buf[2] << 2) | (buf[3] & 3);
+ y = (buf[4] << 2) | ((buf[3] & 0xC) >> 2);
+ printf("X: 0x%03x Y: 0x%03x",x,y);
+
+ buf[0] = 0x2f;
+ buf[1] = (0xF<<1) | 1; /* ADC start for P1+P2 */
+ i2c_write(0x10, buf, 2);
+ i2c_readmem(0x10, 0x2e, buf, 5);
+ x = (buf[2] << 2) | (buf[3] & 3);
+ y = (buf[4] << 2) | ((buf[3] & 0xC) >> 2);
+ printf("P1: 0x%03x P2: 0x%03x",x,y);
+ }
+#endif
+
count++;
printf("Count: %d",count);
}
@@ -86,6 +129,10 @@ void* main(void)
line = 0;
printf("POWER-OFF");
+#if defined(COWON_D2)
+ lcd_enable(false);
+#endif
+
/* TODO: Power-off */
while(1);
diff --git a/firmware/FILES b/firmware/FILES
index d884e76d75..986d8beec6 100644
--- a/firmware/FILES
+++ b/firmware/FILES
@@ -39,6 +39,8 @@ target/arm/sandisk/sansa-e200/*.[chS]
target/arm/tatung/tpj1022/*.[chS]
target/arm/tcc77x/*.[chS]
target/arm/tcc77x/logikdax/*.[chS]
+target/arm/tcc780x/*.[chS]
+target/arm/tcc780x/cowond2/*.[chS]
target/arm/tms320dm320/*.[chS]
target/arm/tms320dm320/mrobe-500/*.[chS]
target/coldfire/*.[chS]
diff --git a/firmware/SOURCES b/firmware/SOURCES
index ac874a6cf9..bfc34e55c8 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -111,7 +111,7 @@ drivers/ata_mmc.c
#ifdef HAVE_FLASH_DISK
drivers/ata_flash.c
#else /* !HAVE_FLASH_DISK */
-#if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(LOGIK_DAX) && !defined(IAUDIO_7)
+#if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(LOGIK_DAX) && !defined(IAUDIO_7) && !defined(COWON_D2)
drivers/ata.c
#endif /* SANSA_E200 */
#endif /* HAVE_FLASH_DISK */
@@ -209,6 +209,8 @@ drivers/audio/uda1380.c
drivers/audio/wm8751.c
#elif defined(HAVE_WM8975) || defined(HAVE_WM8978)
drivers/audio/wm8975.c
+#elif defined(HAVE_WM8985)
+drivers/audio/wm8985.c
#elif defined(HAVE_WM8758)
drivers/audio/wm8758.c
#elif defined(HAVE_WM8721)
@@ -297,6 +299,8 @@ target/arm/memset16-arm.S
target/arm/i2c-pp.c
#elif CONFIG_I2C == I2C_PNX0101
target/arm/pnx0101/i2c-pnx0101.c
+#elif CONFIG_I2C == I2C_TCC780X
+target/arm/i2c-telechips.c
#elif CONFIG_I2C == I2C_S3C2440
/* no i2c driver yet */
#endif
@@ -326,6 +330,8 @@ target/arm/tms320dm320/crt0.S
target/arm/s3c2440/crt0.S
#elif defined(CPU_TCC77X)
target/arm/tcc77x/crt0.S
+#elif defined(CPU_TCC780X)
+target/arm/tcc780x/crt0.S
#elif CONFIG_CPU==IMX31L
target/arm/imx31/crt0.S
#elif defined(CPU_ARM)
@@ -858,3 +864,23 @@ target/arm/tcc77x/iaudio7/lcd-iaudio7.c
target/arm/tcc77x/iaudio7/power-iaudio7.c
#endif /* SIMULATOR */
#endif /* IAUDIO_7 */
+
+#ifdef COWON_D2
+#ifndef SIMULATOR
+target/arm/tcc780x/adc-tcc780x.c
+target/arm/tcc780x/ata-nand-tcc780x.c
+target/arm/tcc780x/kernel-tcc780x.c
+target/arm/tcc780x/timer-tcc780x.c
+target/arm/tcc780x/system-tcc780x.c
+target/arm/tcc780x/cowond2/button-cowond2.c
+target/arm/tcc780x/cowond2/lcd-cowond2.c
+target/arm/tcc780x/cowond2/power-cowond2.c
+target/arm/tcc780x/cowond2/powermgmt-cowond2.c
+target/arm/tcc780x/cowond2/usb-cowond2.c
+#ifndef BOOTLOADER
+target/arm/wmcodec-telechips.c
+target/arm/tcc780x/debug-tcc780x.c
+target/arm/tcc780x/cowond2/pcm-cowond2.c
+#endif /* BOOTLOADER */
+#endif /* SIMULATOR */
+#endif /* COWON_D2 */
diff --git a/firmware/app.lds b/firmware/app.lds
index 9b83537dfe..c5c4e6e30e 100644
--- a/firmware/app.lds
+++ b/firmware/app.lds
@@ -13,6 +13,8 @@ INPUT(target/arm/crt0-pp.o)
INPUT(target/arm/tms320dm320/crt0.o)
#elif CONFIG_CPU==S3C2440
INPUT(target/arm/s3c2440/crt0.o)
+#elif defined(CPU_TCC780X)
+INPUT(target/arm/tcc780x/crt0.o)
#elif CONFIG_CPU == PNX0101
INPUT(target/arm/pnx0101/crt0-pnx0101.o)
#elif CONFIG_CPU == IMX31L
@@ -75,6 +77,14 @@ INPUT(target/sh/crt0.o)
#define DRAMORIG (0x0 + STUBOFFSET)
#define IRAMORIG 0x1FFFC000
#define IRAMSIZE 0x4000
+#elif defined(CPU_TCC780X)
+#define DRAMORIG 0x20000000 + STUBOFFSET
+#define ITCMORIG 0x00000000
+#define ITCMSIZE 0x1000
+#define DTCMORIG 0xA0000000
+#define DTCMSIZE 0x2000
+#define SRAMORIG 0x10000000
+#define SRAMSIZE 0xc000
#else
#define DRAMORIG 0x09000000 + STUBOFFSET
#define IRAMORIG 0x0f000000
@@ -90,7 +100,12 @@ INPUT(target/sh/crt0.o)
MEMORY
{
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
-#if CONFIG_CPU != S3C2440
+#if defined(CPU_TCC780X)
+ /* Seperate data & instruction TCMs plus SRAM. */
+ ITCM : ORIGIN = ITCMORIG, LENGTH = ITCMSIZE
+ DTCM : ORIGIN = DTCMORIG, LENGTH = DTCMSIZE
+ SRAM : ORIGIN = SRAMORIG, LENGTH = SRAMSIZE
+#elif CONFIG_CPU != S3C2440
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
#endif
#if CONFIG_CPU==PNX0101
@@ -187,6 +202,100 @@ SECTIONS
_end = .;
} > DRAM
+#elif defined(CPU_TCC780X)
+ .text :
+ {
+ loadaddress = .;
+ _loadaddress = .;
+ . = ALIGN(0x200);
+ *(.init.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);
+
+ /* 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 ITCMORIG :
+ {
+ _vectorsstart = .;
+ *(.vectors);
+ _vectorsend = .;
+ } > ITCM AT> DRAM
+
+ _vectorscopy = LOADADDR(.vectors);
+
+ .itcm :
+ {
+ _itcmstart = .;
+ *(.icode)
+ _itcmend = .;
+ } > ITCM AT> DRAM
+
+ _itcmcopy = LOADADDR(.itcm);
+
+ .dtcm :
+ {
+ _dtcmstart = .;
+ *(.irodata)
+ *(.idata)
+ _dtcmend = .;
+ } > DTCM AT> DRAM
+
+ _dtcmcopy = LOADADDR(.dtcm);
+
+ .ibss (NOLOAD) :
+ {
+ _iedata = .;
+ *(.ibss)
+ . = ALIGN(0x4);
+ _iend = .;
+ } > SRAM
+
+ .stack :
+ {
+ *(.stack)
+ stackbegin = .;
+ . += 0x2000;
+ stackend = .;
+ } > SRAM
+
+ .bss :
+ {
+ _edata = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(0x4);
+ _end = .;
+ } > DRAM
+
#elif CONFIG_CPU==S3C2440
.text :
{
diff --git a/firmware/boot.lds b/firmware/boot.lds
index 1b13211608..8d7d55a607 100644
--- a/firmware/boot.lds
+++ b/firmware/boot.lds
@@ -15,6 +15,8 @@ INPUT(target/arm/tms320dm320/crt0.o)
INPUT(target/arm/s3c2440/crt0.o)
#elif defined(CPU_TCC77X)
INPUT(target/arm/tcc77x/crt0.o)
+#elif defined(CPU_TCC780X)
+INPUT(target/arm/tcc780x/crt0.o)
#elif CONFIG_CPU==IMX31L
INPUT(target/arm/imx31/crt0.o)
#else
@@ -89,6 +91,12 @@ INPUT(target/sh/crt0.o)
#define IRAMSIZE 64K
#define FLASHORIG 0x0000000
#define FLASHSIZE 1M
+#elif defined(CPU_TCC780X)
+#define DRAMORIG 0x20000000
+#define IRAMORIG 0x00000000
+#define IRAMSIZE 4K
+#define FLASHORIG 0x0000000
+#define FLASHSIZE 1M
#else
#define DRAMORIG 0x09000000
#define IRAMORIG 0x0f000000
@@ -97,7 +105,7 @@ INPUT(target/sh/crt0.o)
#define FLASHSIZE 256K - ROM_START
#endif
-#if defined(CPU_TCC77X)
+#if defined(CPU_TCC77X) || defined(CPU_TCC780X)
MEMORY
{
#ifdef TCCBOOT
@@ -190,7 +198,7 @@ SECTIONS
_end = .;
}
}
-#elif defined(CPU_TCC77X)
+#elif defined(CPU_TCC77X) || defined(CPU_TCC780X)
{
.text : {
*(.init.text)
diff --git a/firmware/drivers/audio/wm8985.c b/firmware/drivers/audio/wm8985.c
new file mode 100644
index 0000000000..3117b06f98
--- /dev/null
+++ b/firmware/drivers/audio/wm8985.c
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Stubs for WM8985 audio codec, (unwisely?) based on 8975 driver.
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "logf.h"
+#include "system.h"
+#include "string.h"
+#include "audio.h"
+
+#include "wmcodec.h"
+#include "audiohw.h"
+#include "i2s.h"
+
+/* TODO: fix these values, they're copied straight from WM8975 */
+const struct sound_settings_info audiohw_settings[] = {
+ [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
+ [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0},
+ [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0},
+ [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
+ [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
+ [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
+ [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
+ [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
+ [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
+};
+
+/* convert tenth of dB volume to master volume register value */
+int tenthdb2master(int db)
+{
+ #warning function not implemented
+
+ (void)db;
+ return 0;
+}
+
+/* Silently enable / disable audio output */
+void audiohw_enable_output(bool enable)
+{
+ #warning function not implemented
+
+ (void)enable;
+}
+
+int audiohw_set_master_vol(int vol_l, int vol_r)
+{
+ #warning function not implemented
+
+ (void)vol_l;
+ (void)vol_r;
+ return 0;
+}
+
+int audiohw_set_lineout_vol(int vol_l, int vol_r)
+{
+ #warning function not implemented
+
+ (void)vol_l;
+ (void)vol_r;
+ return 0;
+}
+
+void audiohw_set_bass(int value)
+{
+ #warning function not implemented
+
+ (void)value;
+}
+
+void audiohw_set_treble(int value)
+{
+ #warning function not implemented
+
+ (void)value;
+}
+
+void audiohw_mute(bool mute)
+{
+ #warning function not implemented
+
+ (void)mute;
+}
+
+void audiohw_close(void)
+{
+ #warning function not implemented
+}
+
+void audiohw_set_nsorder(int order)
+{
+ #warning function not implemented
+
+ (void)order;
+}
+
+/* Note: Disable output before calling this function */
+void audiohw_set_sample_rate(int sampling_control)
+{
+ #warning function not implemented
+
+ (void)sampling_control;
+}
+
+void audiohw_enable_recording(bool source_mic)
+{
+ #warning function not implemented
+
+ (void)source_mic;
+}
+
+void audiohw_disable_recording(void)
+{
+ #warning function not implemented
+}
+
+void audiohw_set_recvol(int left, int right, int type)
+{
+ #warning function not implemented
+
+ (void)left;
+ (void)right;
+ (void)type;
+}
+
+void audiohw_set_monitor(bool enable)
+{
+ #warning function not implemented
+
+ (void)enable;
+}
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h
index 5dc7550478..cdc92221d7 100644
--- a/firmware/export/audiohw.h
+++ b/firmware/export/audiohw.h
@@ -29,6 +29,8 @@
#include "wm8751.h"
#elif defined(HAVE_WM8975) || defined(HAVE_WM8978)
#include "wm8975.h"
+#elif defined(HAVE_WM8985)
+#include "wm8985.h"
#elif defined(HAVE_WM8758)
#include "wm8758.h"
#elif defined(HAVE_WM8721)
@@ -62,7 +64,7 @@ enum {
#endif
#if CONFIG_CODEC == MAS3587F || defined(HAVE_UDA1380) || defined(HAVE_TLV320)\
|| defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731) \
- || defined(HAVE_AS3514) || defined(HAVE_WM8978)
+ || defined(HAVE_AS3514) || defined(HAVE_WM8978) || defined(HAVE_WM8985)
SOUND_LEFT_GAIN,
SOUND_RIGHT_GAIN,
SOUND_MIC_GAIN,
diff --git a/firmware/export/config-cowond2.h b/firmware/export/config-cowond2.h
new file mode 100644
index 0000000000..4f2d11e424
--- /dev/null
+++ b/firmware/export/config-cowond2.h
@@ -0,0 +1,140 @@
+/*
+ * This config file is for the Cowon iAudio D2
+ */
+#define TARGET_TREE /* this target is using the target tree system */
+
+/* For Rolo and boot loader */
+#define MODEL_NUMBER 34
+
+/* 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_SPDIF)
+
+/* 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 want album art for this target */
+#define HAVE_ALBUMART
+
+/* 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 would like tagcache to build on this target */
+#define HAVE_TAGCACHE
+
+/* define this if you have a flash memory storage */
+#define HAVE_FLASH_STORAGE
+
+/* LCD dimensions */
+#define LCD_WIDTH 320
+#define LCD_HEIGHT 240
+#define LCD_DEPTH 16
+#define LCD_PIXELFORMAT 565
+
+/* define this if you have LCD enable function */
+#define HAVE_LCD_ENABLE
+
+/* define this to indicate your device's keypad */
+#define CONFIG_KEYPAD COWOND2_PAD
+
+/* define this if you have a real-time clock */
+//#define CONFIG_RTC RTC_TCC780X
+
+/* 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
+
+/* 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 D2 uses a WM8985 codec */
+#define HAVE_WM8985
+
+/* There is no hardware tone control */
+/* TODO: probably need to use this */
+//#define HAVE_SW_TONE_CONTROLS
+
+/* Define this for LCD backlight available */
+#define HAVE_BACKLIGHT
+
+/* TODO: Enable LCD brightness control */
+//#define HAVE_BACKLIGHT_BRIGHTNESS
+
+/* Main LCD backlight brightness range and defaults */
+//#define MIN_BRIGHTNESS_SETTING 1
+//#define MAX_BRIGHTNESS_SETTING 10
+//#define DEFAULT_BRIGHTNESS_SETTING 8
+
+#define CONFIG_I2C I2C_TCC780X
+
+#define BATTERY_CAPACITY_DEFAULT 1500 /* default battery capacity */
+#define BATTERY_CAPACITY_MIN 1500 /* min. capacity selectable */
+#define BATTERY_CAPACITY_MAX 3200 /* 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. */
+/* TODO: this is temporary until battery monitoring implemented */
+#define NO_LOW_BATTERY_SHUTDOWN
+
+#ifndef SIMULATOR
+
+/* Define this if you have a TCC7801 */
+#define CONFIG_CPU TCC7801
+
+/* Define this if you have ATA power-off control */
+#define HAVE_ATA_POWER_OFF
+
+/* Define this to the CPU frequency */
+#define CPU_FREQ 192000000
+
+/* Define this if you have adjustable CPU frequency */
+#define HAVE_ADJUSTABLE_CPU_FREQ
+
+/* 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 4
+
+/* Offset ( in the firmware file's header ) to the real data */
+#define FIRMWARE_OFFSET_FILE_DATA 6
+
+/* The start address index for ROM builds */
+/* #define ROM_START 0x11010 for behind original Archos */
+#define ROM_START 0x7010 /* for behind BootBox */
+
+/* Software controlled LED */
+#define CONFIG_LED LED_VIRTUAL
+
+#define CONFIG_LCD LCD_COWOND2
+
+#define BOOTFILE_EXT "iaudio"
+#define BOOTFILE "rockbox." BOOTFILE_EXT
+#define BOOTDIR "/"
+
+#endif /* SIMULATOR */
diff --git a/firmware/export/config.h b/firmware/export/config.h
index a3c2390f84..cf75d67aa5 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -53,6 +53,7 @@
#define IMX31L 31
#define TCC771L 771
#define TCC773L 773
+#define TCC7801 7801
/* CONFIG_KEYPAD */
#define PLAYER_PAD 1
@@ -75,7 +76,8 @@
#define MROBE500_PAD 18
#define GIGABEAT_S_PAD 19
#define LOGIK_DAX_PAD 20
-#define IAUDIO67_PAD 21
+#define IAUDIO67_PAD 21
+#define COWOND2_PAD 22
/* CONFIG_REMOTE_KEYPAD */
#define H100_REMOTE 1
@@ -111,6 +113,7 @@
#define LCD_MROBE100 19 /* as used by Olympus M:Robe 100 */
#define LCD_LOGIKDAX 20 /* as used by Logik DAX - SSD1815 */
#define LCD_IAUDIO67 21 /* as used by iAudio 6/7 - unknown */
+#define LCD_COWOND2 21 /* as used by Cowon D2 - LTV250QV, TCC7801 driver */
/* LCD_PIXELFORMAT */
#define HORIZONTAL_PACKING 1
@@ -136,6 +139,7 @@
#define I2C_PP5024 8 /* PP5024 style */
#define I2C_IMX31L 9
#define I2C_TCC77X 10
+#define I2C_TCC780X 11
/* CONFIG_LED */
#define LED_REAL 1 /* SW controlled LED (Archos recorders, player) */
@@ -156,6 +160,7 @@
#define RTC_IMX31L 8
#define RTC_RX5X348AB 9
#define RTC_TCC77X 10
+#define RTC_TCC780X 11
/* USB On-the-go */
#define USBOTG_ISP1362 1362 /* iriver H300 */
@@ -231,6 +236,8 @@
#include "config-logikdax.h"
#elif defined(IAUDIO_7)
#include "config-iaudio7.h"
+#elif defined(COWON_D2)
+#include "config-cowond2.h"
#else
/* no known platform */
#endif
@@ -345,6 +352,11 @@
#define CPU_TCC77X
#endif
+/* define for all cpus from TCC780 family */
+#if (CONFIG_CPU == TCC7801)
+#define CPU_TCC780X
+#endif
+
/* define for all cpus from ARM7TDMI family (for specific optimisations) */
#if defined(CPU_PP) || (CONFIG_CPU == PNX0101) || (CONFIG_CPU == DSC25)
#define CPU_ARM7TDMI
@@ -353,7 +365,7 @@
/* define for all cpus from ARM family */
#if defined(CPU_PP) || (CONFIG_CPU == PNX0101) || (CONFIG_CPU == S3C2440) \
|| (CONFIG_CPU == DSC25) || (CONFIG_CPU == IMX31L) || (CONFIG_CPU == DM320) \
- || defined(CPU_TCC77X)
+ || defined(CPU_TCC77X) || defined(CPU_TCC780X)
#define CPU_ARM
#endif
@@ -380,6 +392,7 @@
defined(CPU_COLDFIRE) || /* Coldfire: core, plugins, codecs */ \
defined(CPU_PP) || /* PortalPlayer: core, plugins, codecs */ \
defined(CPU_TCC77X) || /* Telechips: core, plugins, codecs */ \
+ defined(CPU_TCC780X) || /* Telechips: core, plugins, codecs */ \
(CONFIG_CPU == PNX0101))
#define ICODE_ATTR __attribute__ ((section(".icode")))
#define ICONST_ATTR __attribute__ ((section(".irodata")))
diff --git a/firmware/export/cpu.h b/firmware/export/cpu.h
index 84229378ec..08a91a6d10 100644
--- a/firmware/export/cpu.h
+++ b/firmware/export/cpu.h
@@ -51,3 +51,6 @@
#ifdef CPU_TCC77X
#include "tcc77x.h"
#endif
+#ifdef CPU_TCC780X
+#include "tcc780x.h"
+#endif
diff --git a/firmware/export/tcc780x.h b/firmware/export/tcc780x.h
new file mode 100644
index 0000000000..df55c6f03d
--- /dev/null
+++ b/firmware/export/tcc780x.h
@@ -0,0 +1,156 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __TCC780X_H__
+#define __TCC780X_H__
+
+/* General-purpose IO */
+
+#define PORTCFG0 (*(volatile unsigned long *)0xF005A000)
+#define PORTCFG1 (*(volatile unsigned long *)0xF005A004)
+#define PORTCFG2 (*(volatile unsigned long *)0xF005A008)
+#define PORTCFG3 (*(volatile unsigned long *)0xF005A00C)
+
+#define GPIOA (*(volatile unsigned long *)0xF005A020)
+#define GPIOB (*(volatile unsigned long *)0xF005A040)
+#define GPIOC (*(volatile unsigned long *)0xF005A060)
+#define GPIOD (*(volatile unsigned long *)0xF005A080)
+#define GPIOE (*(volatile unsigned long *)0xF005A0A0)
+
+#define GPIOA_DIR (*(volatile unsigned long *)0xF005A024)
+#define GPIOB_DIR (*(volatile unsigned long *)0xF005A044)
+#define GPIOC_DIR (*(volatile unsigned long *)0xF005A064)
+#define GPIOD_DIR (*(volatile unsigned long *)0xF005A084)
+#define GPIOE_DIR (*(volatile unsigned long *)0xF005A0A4)
+
+#define GPIOA_SET (*(volatile unsigned long *)0xF005A028)
+#define GPIOB_SET (*(volatile unsigned long *)0xF005A048)
+#define GPIOC_SET (*(volatile unsigned long *)0xF005A068)
+#define GPIOD_SET (*(volatile unsigned long *)0xF005A088)
+#define GPIOE_SET (*(volatile unsigned long *)0xF005A0A8)
+
+#define GPIOA_CLEAR (*(volatile unsigned long *)0xF005A02C)
+#define GPIOB_CLEAR (*(volatile unsigned long *)0xF005A04C)
+#define GPIOC_CLEAR (*(volatile unsigned long *)0xF005A06C)
+#define GPIOD_CLEAR (*(volatile unsigned long *)0xF005A08C)
+#define GPIOE_CLEAR (*(volatile unsigned long *)0xF005A0AC)
+
+/* Clock Generator */
+
+#define CLKCTRL (*(volatile unsigned long *)0xF3000000)
+#define PLL0CFG (*(volatile unsigned long *)0xF3000004)
+#define PLL1CFG (*(volatile unsigned long *)0xF3000008)
+#define CLKDIVC (*(volatile unsigned long *)0xF300000C)
+#define CLKDIVC1 (*(volatile unsigned long *)0xF3000010)
+#define MODECTR (*(volatile unsigned long *)0xF3000014)
+#define BCLKCTR (*(volatile unsigned long *)0xF3000018)
+#define SWRESET (*(volatile unsigned long *)0xF300001C)
+#define PCLKCFG0 (*(volatile unsigned long *)0xF3000020)
+#define PCLKCFG1 (*(volatile unsigned long *)0xF3000024)
+#define PCLKCFG2 (*(volatile unsigned long *)0xF3000028)
+#define PCLKCFG3 (*(volatile unsigned long *)0xF300002C)
+#define PCLK_LCD (*(volatile unsigned long *)0xF3000030)
+#define PCLKCFG5 (*(volatile unsigned long *)0xF3000034)
+#define PCLKCFG6 (*(volatile unsigned long *)0xF3000038)
+#define PCLKCFG7 (*(volatile unsigned long *)0xF300003C)
+#define PCLKCFG8 (*(volatile unsigned long *)0xF3000040)
+#define PCLK_TCT (*(volatile unsigned long *)0xF3000044)
+#define PCLKCFG10 (*(volatile unsigned long *)0xF3000048)
+#define PCLKCFG11 (*(volatile unsigned long *)0xF300004C)
+#define PCLK_ADC (*(volatile unsigned long *)0xF3000050)
+#define PCLKCFG13 (*(volatile unsigned long *)0xF3000054)
+#define PCLKCFG14 (*(volatile unsigned long *)0xF3000058)
+#define PCLK_RFREQ (*(volatile unsigned long *)0xF300005C)
+#define PCLKCFG16 (*(volatile unsigned long *)0xF3000060)
+#define PCLKCFG17 (*(volatile unsigned long *)0xF3000064)
+
+#define PCK_EN (1<<28)
+
+#define CKSEL_PLL0 0
+#define CKSEL_PLL1 1
+#define CKSEL_XIN 4
+
+/* IRQ Controller */
+
+#define IEN (*(volatile unsigned long *)0xF3001000)
+#define CREQ (*(volatile unsigned long *)0xF3001004)
+#define IRQSEL (*(volatile unsigned long *)0xF300100C)
+#define MREQ (*(volatile unsigned long *)0xF3001014)
+#define MIRQ (*(volatile unsigned long *)0xF3001028)
+#define MFIQ (*(volatile unsigned long *)0xF300102C)
+#define ALLMASK (*(volatile unsigned long *)0xF3001044)
+#define VAIRQ (*(volatile unsigned long *)0xF3001080)
+#define VAFIQ (*(volatile unsigned long *)0xF3001084)
+#define VNIRQ (*(volatile unsigned long *)0xF3001088)
+#define VNFIQ (*(volatile unsigned long *)0xF300108C)
+
+#define TIMER_IRQ_MASK (1<<6)
+
+/* Timer / Counters */
+
+#define TCFG0 (*(volatile unsigned long *)0xF3003000)
+#define TCNT0 (*(volatile unsigned long *)0xF3003004)
+#define TREF0 (*(volatile unsigned long *)0xF3003008)
+#define TCFG1 (*(volatile unsigned long *)0xF3003010)
+#define TCNT1 (*(volatile unsigned long *)0xF3003014)
+#define TREF1 (*(volatile unsigned long *)0xF3003018)
+
+#define TIREQ (*(volatile unsigned long *)0xF3003060)
+/* ref. value reached */
+#define TF0 (1<<8)
+#define TF1 (1<<9)
+/* irq. status */
+#define TI0 (1<<0)
+#define TI1 (1<<1)
+
+#define TC32EN (*(volatile unsigned long *)0xF3003080)
+#define TC32LDV (*(volatile unsigned long *)0xF3003084)
+#define TC32MCNT (*(volatile unsigned long *)0xF3003094)
+#define TC32IRQ (*(volatile unsigned long *)0xF3003098)
+
+/* ADC */
+
+#define ADCCON (*(volatile unsigned long *)0xF3004000)
+#define ADCDATA (*(volatile unsigned long *)0xF3004004)
+#define ADCCONA (*(volatile unsigned long *)0xF3004080)
+#define ADCSTATUS (*(volatile unsigned long *)0xF3004084)
+#define ADCCFG (*(volatile unsigned long *)0xF3004088)
+
+/* Memory Controller */
+
+#define SDCFG (*(volatile unsigned long *)0xF1000000)
+#define SDFSM (*(volatile unsigned long *)0xF1000004)
+#define MCFG (*(volatile unsigned long *)0xF1000008)
+#define CSCFG0 (*(volatile unsigned long *)0xF1000010)
+#define CSCFG1 (*(volatile unsigned long *)0xF1000014)
+#define CSCFG2 (*(volatile unsigned long *)0xF1000018)
+#define CSCFG3 (*(volatile unsigned long *)0xF100001C)
+#define CLKCFG (*(volatile unsigned long *)0xF1000020)
+#define SDCMD (*(volatile unsigned long *)0xF1000024)
+
+#define SDCFG1 (*(volatile unsigned long *)0xF1001000)
+#define MCFG1 (*(volatile unsigned long *)0xF1001008)
+
+/* Misc */
+
+#define ECFG0 (*(volatile unsigned long *)0xF300500C)
+#define MBCFG (*(volatile unsigned long *)0xF3005020)
+
+#define TCC780_VER (*(volatile unsigned long *)0xE0001FFC)
+
+#endif
diff --git a/firmware/export/timer.h b/firmware/export/timer.h
index f4df8d51d4..21995ef459 100644
--- a/firmware/export/timer.h
+++ b/firmware/export/timer.h
@@ -31,7 +31,7 @@
#define TIMER_FREQ (CPU_FREQ/2)
#elif CONFIG_CPU == PNX0101
#define TIMER_FREQ 3000000
-#elif CONFIG_CPU == S3C2440 || CONFIG_CPU == DM320
+#elif CONFIG_CPU == S3C2440 || CONFIG_CPU == DM320 || CONFIG_CPU == TCC7801
#include "timer-target.h"
#elif defined(SIMULATOR)
#define TIMER_FREQ 1000000
diff --git a/firmware/export/wm8985.h b/firmware/export/wm8985.h
new file mode 100644
index 0000000000..9ae5515fa7
--- /dev/null
+++ b/firmware/export/wm8985.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _WM8985_H
+#define _WM8985_H
+
+/* volume/balance/treble/bass interdependency */
+#define VOLUME_MIN -730
+#define VOLUME_MAX 60
+
+extern int tenthdb2master(int db);
+
+extern void audiohw_enable_output(bool enable);
+extern int audiohw_set_master_vol(int vol_l, int vol_r);
+extern int audiohw_set_lineout_vol(int vol_l, int vol_r);
+extern void audiohw_set_bass(int value);
+extern void audiohw_set_treble(int value);
+extern void audiohw_set_nsorder(int order);
+extern void audiohw_set_sample_rate(int sampling_control);
+
+/* Register addresses */
+// .. tbc
+
+/* Register settings for the supported samplerates: */
+// .. tbc
+
+#endif /* _WM8985_H */
diff --git a/firmware/target/arm/i2c-telechips.c b/firmware/target/arm/i2c-telechips.c
new file mode 100644
index 0000000000..e3e8fd3d33
--- /dev/null
+++ b/firmware/target/arm/i2c-telechips.c
@@ -0,0 +1,187 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+
+#include "system.h"
+#include "i2c.h"
+#include "i2c-target.h"
+
+/* arbitrary delay loop */
+#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0)
+
+static struct mutex i2c_mtx;
+
+void i2c_init(void)
+{
+ /* nothing to do */
+}
+
+void i2c_start(void)
+{
+ SDA_OUTPUT;
+
+ SCL_HI;
+ SDA_HI;
+ DELAY;
+
+ SDA_LO;
+ DELAY;
+ SCL_LO;
+ DELAY;
+}
+
+void i2c_stop(void)
+{
+ SDA_OUTPUT;
+
+ SDA_LO;
+ DELAY;
+
+ SCL_HI;
+ DELAY;
+ SDA_HI;
+ DELAY;
+}
+
+void i2c_outb(unsigned char byte)
+{
+ int bit;
+
+ SDA_OUTPUT;
+
+ for (bit = 0; bit < 8; bit++)
+ {
+ if ((byte<<bit) & 0x80)
+ SDA_HI;
+ else
+ SDA_LO;
+
+ DELAY;
+
+ SCL_HI;
+ DELAY;
+ SCL_LO;
+ DELAY;
+ }
+}
+
+unsigned char i2c_inb(int ack)
+{
+ int i;
+ unsigned char byte = 0;
+
+ SDA_INPUT;
+
+ /* clock in each bit, MSB first */
+ for ( i=0x80; i; i>>=1 )
+ {
+ SCL_HI;
+ DELAY;
+
+ if ( SDA ) byte |= i;
+
+ SCL_LO;
+ DELAY;
+ }
+
+ i2c_ack(ack);
+ return byte;
+}
+
+void i2c_ack(int bit)
+{
+ SDA_OUTPUT;
+
+ if (bit)
+ SDA_HI;
+ else
+ SDA_LO;
+
+ SCL_HI;
+ DELAY;
+ SCL_LO;
+ DELAY;
+}
+
+int i2c_getack(void)
+{
+ bool ack_bit;
+
+ SDA_INPUT;
+
+ SCL_HI;
+ DELAY;
+
+ ack_bit = SDA;
+ DELAY;
+
+ SCL_LO;
+ DELAY;
+
+ return ack_bit;
+}
+
+/* device = 8 bit slave address */
+int i2c_write(int device, unsigned char* buf, int count )
+{
+ int i = 0;
+ mutex_lock(&i2c_mtx);
+
+ i2c_start();
+ i2c_outb(device & 0xfe);
+
+ while (!i2c_getack() && i < count)
+ {
+ i2c_outb(buf[i++]);
+ }
+
+ i2c_stop();
+ mutex_unlock(&i2c_mtx);
+ return 0;
+}
+
+
+/* device = 8 bit slave address */
+int i2c_readmem(int device, int address, unsigned char* buf, int count )
+{
+ int i = 0;
+ mutex_lock(&i2c_mtx);
+
+ i2c_start();
+ i2c_outb(device & 0xfe);
+ if (i2c_getack()) goto exit;
+
+ i2c_outb(address);
+ if (i2c_getack()) goto exit;
+
+ i2c_start();
+ i2c_outb(device | 1);
+ if (i2c_getack()) goto exit;
+
+ while (i < count)
+ {
+ buf[i] = i2c_inb(i == (count-1));
+ i++;
+ }
+
+exit:
+ i2c_stop();
+ mutex_unlock(&i2c_mtx);
+ return 0;
+}
diff --git a/firmware/target/arm/tcc780x/adc-tcc780x.c b/firmware/target/arm/tcc780x/adc-tcc780x.c
new file mode 100644
index 0000000000..871db2b61d
--- /dev/null
+++ b/firmware/target/arm/tcc780x/adc-tcc780x.c
@@ -0,0 +1,76 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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 "system.h"
+#include "kernel.h"
+#include "thread.h"
+#include "string.h"
+#include "adc.h"
+
+/*
+ TODO: We probably want to do this on the timer interrupt once we get
+ interrupts going - see the sh-adc.c implementation for an example which
+ looks like it should work well with the TCC77x.
+
+ Also, this code is practically identical between 77x & 780x targets.
+ Should probably find a common location to avoid the duplication.
+*/
+
+static unsigned short adcdata[8];
+
+static void adc_do_read(void)
+{
+ int i;
+ uint32_t adc_status;
+
+ PCLK_ADC |= PCK_EN; /* Enable ADC clock */
+
+ /* Start converting the first 4 channels */
+ for (i = 0; i < 4; i++)
+ ADCCON = i;
+
+ /* Wait for data to become stable */
+ while ((ADCDATA & 0x1) == 0);
+
+ /* Now read the values back */
+ for (i=0;i < 4; i++) {
+ adc_status = ADCSTATUS;
+ adcdata[(adc_status >> 16) & 0x7] = adc_status & 0x3ff;
+ }
+
+ PCLK_ADC &= ~PCK_EN; /* Disable ADC clock */
+}
+
+unsigned short adc_read(int channel)
+{
+ /* Either move this to an interrupt routine, or only perform the read if
+ the last call was X length of time ago. */
+ adc_do_read();
+
+ return adcdata[channel];
+}
+
+void adc_init(void)
+{
+ /* consider configuring PCK_ADC source here */
+
+ ADCCON = (1<<4); /* Leave standby mode */
+ ADCCFG |= 0x00000003; /* Single-mode, auto power-down */
+}
diff --git a/firmware/target/arm/tcc780x/ata-nand-tcc780x.c b/firmware/target/arm/tcc780x/ata-nand-tcc780x.c
new file mode 100644
index 0000000000..5aed090d5c
--- /dev/null
+++ b/firmware/target/arm/tcc780x/ata-nand-tcc780x.c
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "ata.h"
+#include "ata-target.h"
+#include "ata_idle_notify.h"
+#include "system.h"
+#include <string.h>
+#include "thread.h"
+#include "led.h"
+#include "disk.h"
+#include "panic.h"
+#include "usb.h"
+
+/* for compatibility */
+int ata_spinup_time = 0;
+
+long last_disk_activity = -1;
+
+/** static, private data **/
+static bool initialized = false;
+
+static long next_yield = 0;
+#define MIN_YIELD_PERIOD 2000
+
+/* API Functions */
+
+void ata_led(bool onoff)
+{
+ led(onoff);
+}
+
+int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
+ void* inbuf)
+{
+ #warning function not implemented
+ (void)start;
+ (void)incount;
+ (void)inbuf;
+ return 0;
+}
+
+int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
+ const void* outbuf)
+{
+ #warning function not implemented
+ (void)start;
+ (void)count;
+ (void)outbuf;
+ return 0;
+}
+
+void ata_spindown(int seconds)
+{
+ #warning function not implemented
+ (void)seconds;
+}
+
+bool ata_disk_is_active(void)
+{
+ #warning function not implemented
+ return 0;
+}
+
+void ata_sleep(void)
+{
+ #warning function not implemented
+}
+
+void ata_spin(void)
+{
+ #warning function not implemented
+}
+
+/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
+int ata_hard_reset(void)
+{
+ #warning function not implemented
+ return 0;
+}
+
+int ata_soft_reset(void)
+{
+ #warning function not implemented
+ return 0;
+}
+
+void ata_enable(bool on)
+{
+ #warning function not implemented
+ (void)on;
+}
+
+int ata_init(void)
+{
+ #warning function not implemented
+ return 0;
+}
diff --git a/firmware/target/arm/tcc780x/ata-target.h b/firmware/target/arm/tcc780x/ata-target.h
new file mode 100644
index 0000000000..79ac638de1
--- /dev/null
+++ b/firmware/target/arm/tcc780x/ata-target.h
@@ -0,0 +1,22 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef ATA_TARGET_H
+#define ATA_TARGET_H
+
+#endif
diff --git a/firmware/target/arm/tcc780x/cowond2/adc-target.h b/firmware/target/arm/tcc780x/cowond2/adc-target.h
new file mode 100644
index 0000000000..873183d721
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/adc-target.h
@@ -0,0 +1,26 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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 4
+
+#define ADC_BUTTONS 0
+
+#endif /* _ADC_TARGET_H_ */
diff --git a/firmware/target/arm/tcc780x/cowond2/backlight-target.h b/firmware/target/arm/tcc780x/cowond2/backlight-target.h
new file mode 100644
index 0000000000..0563fc20f5
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/backlight-target.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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 "tcc780x.h"
+
+#define _backlight_init() true
+
+/* nb: we can set the backlight intensity using PCF50606 register 0x35 */
+
+static inline void _backlight_on(void)
+{
+ /* Enable backlight */
+ GPIOA_SET = (1<<6);
+}
+
+static inline void _backlight_off(void)
+{
+ /* Disable backlight */
+ GPIOA_CLEAR = (1<<6);
+}
+
+#endif
diff --git a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
new file mode 100644
index 0000000000..dccdf4e8e0
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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"
+
+void button_init_device(void)
+{
+ /* Nothing to do */
+}
+
+int button_read_device(void)
+{
+ int btn = BUTTON_NONE;
+ int adc;
+
+ if (GPIOB & 0x4)
+ {
+ adc = adc_read(ADC_BUTTONS);
+
+ /* The following contains some abitrary, but working, guesswork */
+ if (adc < 0x038) {
+ btn |= (BUTTON_MINUS | BUTTON_PLUS | BUTTON_MENU);
+ } else if (adc < 0x048) {
+ btn |= (BUTTON_MINUS | BUTTON_PLUS);
+ } else if (adc < 0x058) {
+ btn |= (BUTTON_PLUS | BUTTON_MENU);
+ } else if (adc < 0x070) {
+ btn |= BUTTON_PLUS;
+ } else if (adc < 0x090) {
+ btn |= (BUTTON_MINUS | BUTTON_MENU);
+ } else if (adc < 0x150) {
+ btn |= BUTTON_MINUS;
+ } else if (adc < 0x200) {
+ btn |= BUTTON_MENU;
+ }
+ }
+
+ /* TODO: Read 'fake' buttons based on touchscreen quadrants.
+ Question: How can I read from the PCF chip (I2C) in a tick task? */
+
+ if (!(GPIOA & 0x8))
+ btn |= BUTTON_HOLD;
+
+ if (!(GPIOA & 0x4))
+ btn |= BUTTON_POWER;
+
+ return btn;
+}
diff --git a/firmware/target/arm/tcc780x/cowond2/button-target.h b/firmware/target/arm/tcc780x/cowond2/button-target.h
new file mode 100644
index 0000000000..aa336f2f1f
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/button-target.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+#include <stdbool.h>
+#include "config.h"
+
+void button_init_device(void);
+int button_read_device(void);
+
+/* Main unit's buttons */
+#define BUTTON_POWER 0x00000001
+#define BUTTON_HOLD 0x00000002
+#define BUTTON_PLUS 0x00000004
+#define BUTTON_MINUS 0x00000008
+#define BUTTON_MENU 0x00000010
+
+/* Faked buttons based on touchscreen quadrants (not yet read) */
+#define BUTTON_UP 0x00000020
+#define BUTTON_DOWN 0x00000040
+#define BUTTON_LEFT 0x00000080
+#define BUTTON_RIGHT 0x00000100
+#define BUTTON_SELECT 0x00000200
+
+#define BUTTON_MAIN 0x3FF
+
+/* No remote */
+#define BUTTON_REMOTE 0
+
+/* Software power-off */
+#define POWEROFF_BUTTON BUTTON_POWER
+#define POWEROFF_COUNT 40
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/tcc780x/cowond2/i2c-target.h b/firmware/target/arm/tcc780x/cowond2/i2c-target.h
new file mode 100644
index 0000000000..8925a9bae3
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/i2c-target.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef I2C_TARGET_H
+#define I2C_TARGET_H
+
+/* Definitions for the D2 I2C bus */
+
+#define SCL_BIT (1<<0)
+#define SDA_BIT (1<<1)
+
+#define SCL (GPIOA & SCL_BIT)
+#define SCL_HI GPIOA_SET = SCL_BIT
+#define SCL_LO GPIOA_CLEAR = SCL_BIT
+
+#define SDA (GPIOA & SDA_BIT)
+#define SDA_HI GPIOA_SET = SDA_BIT
+#define SDA_LO GPIOA_CLEAR = SDA_BIT
+#define SDA_INPUT GPIOA_DIR &= ~SDA_BIT
+#define SDA_OUTPUT GPIOA_DIR |= SDA_BIT
+
+#endif /* I2C_TARGET_H */
diff --git a/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c
new file mode 100644
index 0000000000..181c58669e
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c
@@ -0,0 +1,346 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+
+#include "hwcompat.h"
+#include "kernel.h"
+#include "lcd.h"
+#include "system.h"
+#include "cpu.h"
+#include "i2c.h"
+
+/* GPIO A pins for LCD panel SDI interface */
+
+#define LTV250QV_CS (1<<24)
+#define LTV250QV_SCL (1<<25)
+#define LTV250QV_SDI (1<<26)
+
+/* LCD Controller registers */
+
+#define LCDC_CTRL (*(volatile unsigned long *)0xF0000000)
+#define LCDC_CLKDIV (*(volatile unsigned long *)0xF0000008)
+#define LCDC_HTIME1 (*(volatile unsigned long *)0xF000000C)
+#define LCDC_HTIME2 (*(volatile unsigned long *)0xF0000010)
+#define LCDC_VTIME1 (*(volatile unsigned long *)0xF0000014)
+#define LCDC_VTIME2 (*(volatile unsigned long *)0xF0000018)
+#define LCDC_VTIME3 (*(volatile unsigned long *)0xF000001C)
+#define LCDC_VTIME4 (*(volatile unsigned long *)0xF0000020)
+#define LCDC_DS (*(volatile unsigned long *)0xF000005C)
+#define LCDC_I1CTRL (*(volatile unsigned long *)0xF000008C)
+#define LCDC_I1POS (*(volatile unsigned long *)0xF0000090)
+#define LCDC_I1SIZE (*(volatile unsigned long *)0xF0000094)
+#define LCDC_I1BASE (*(volatile unsigned long *)0xF0000098)
+#define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8)
+#define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC)
+
+/* Power and display status */
+static bool display_on = false; /* Is the display turned on? */
+
+
+int lcd_default_contrast(void)
+{
+ return 0x1f;
+}
+
+void lcd_set_contrast(int val)
+{
+ /* iirc there is an ltv250qv command to do this */
+ #warning function not implemented
+ (void)val;
+}
+
+
+/* LTV250QV panel functions */
+
+static void ltv250qv_write(unsigned int command)
+{
+ int i;
+
+ GPIOA_CLEAR = LTV250QV_CS;
+
+ for (i = 23; i >= 0; i--)
+ {
+ GPIOA_CLEAR = LTV250QV_SCL;
+
+ if ((command>>i) & 1)
+ GPIOA_SET = LTV250QV_SDI;
+ else
+ GPIOA_CLEAR = LTV250QV_SDI;
+
+ GPIOA_SET = LTV250QV_SCL;
+ }
+
+ GPIOA_SET = LTV250QV_CS;
+}
+
+static void lcd_write_reg(unsigned char reg, unsigned short val)
+{
+ ltv250qv_write(0x740000 | reg);
+ ltv250qv_write(0x760000 | val);
+}
+
+
+/* TODO: The existing pcf50606 drivers are target-specific, so the following
+ lonely function exists until a D2 driver exists. */
+
+void pcf50606_write_reg(unsigned char reg, unsigned char val)
+{
+ unsigned char data[] = { reg, val };
+ i2c_write(0x10, data, 2);
+}
+
+
+/*
+ TEMP: Rough millisecond delay routine used by the LCD panel init sequence.
+ PCK_TCT must first have been initialised to 2Mhz by calling clock_init().
+*/
+static void sleep_ms(unsigned int ms)
+{
+ /* disable timer */
+ TCFG1 = 0;
+
+ /* set Timer1 reference value based on 125kHz tick */
+ TREF1 = ms * 125;
+
+ /* single count, zero the counter, divider = 16 [2^(3+1)], enable */
+ TCFG1 = (1<<9) | (1<<8) | (3<<4) | 1;
+
+ /* wait until Timer1 ref reached */
+ while (!(TIREQ & TF1)) {};
+}
+
+
+static void lcd_display_on(void)
+{
+ /* power on sequence as per the D2 firmware */
+ GPIOA_SET = (1<<16);
+
+ sleep_ms(10);
+
+ lcd_write_reg(1, 0x1D);
+ lcd_write_reg(2, 0x0);
+ lcd_write_reg(3, 0x0);
+ lcd_write_reg(4, 0x0);
+ lcd_write_reg(5, 0x40A3);
+ lcd_write_reg(6, 0x0);
+ lcd_write_reg(7, 0x0);
+ lcd_write_reg(8, 0x0);
+ lcd_write_reg(9, 0x0);
+ lcd_write_reg(10, 0x0);
+ lcd_write_reg(16, 0x0);
+ lcd_write_reg(17, 0x0);
+ lcd_write_reg(18, 0x0);
+ lcd_write_reg(19, 0x0);
+ lcd_write_reg(20, 0x0);
+ lcd_write_reg(21, 0x0);
+ lcd_write_reg(22, 0x0);
+ lcd_write_reg(23, 0x0);
+ lcd_write_reg(24, 0x0);
+ lcd_write_reg(25, 0x0);
+ sleep_ms(10);
+
+ lcd_write_reg(9, 0x4055);
+ lcd_write_reg(10, 0x0);
+ sleep_ms(40);
+
+ lcd_write_reg(10, 0x2000);
+ sleep_ms(40);
+
+ lcd_write_reg(1, 0xC01D);
+ lcd_write_reg(2, 0x204);
+ lcd_write_reg(3, 0xE100);
+ lcd_write_reg(4, 0x1000);
+ lcd_write_reg(5, 0x5033);
+ lcd_write_reg(6, 0x4);
+ lcd_write_reg(7, 0x30);
+ lcd_write_reg(8, 0x41C);
+ lcd_write_reg(16, 0x207);
+ lcd_write_reg(17, 0x702);
+ lcd_write_reg(18, 0xB05);
+ lcd_write_reg(19, 0xB05);
+ lcd_write_reg(20, 0x707);
+ lcd_write_reg(21, 0x507);
+ lcd_write_reg(22, 0x103);
+ lcd_write_reg(23, 0x406);
+ lcd_write_reg(24, 0x2);
+ lcd_write_reg(25, 0x0);
+ sleep_ms(60);
+
+ lcd_write_reg(9, 0xA55);
+ lcd_write_reg(10, 0x111F);
+ sleep_ms(10);
+
+ pcf50606_write_reg(0x35, 0xe9); /* PWMC1 - backlight power (intensity) */
+ pcf50606_write_reg(0x38, 0x3); /* GPOC1 - ? */
+
+ /* tell that we're on now */
+ display_on = true;
+}
+
+static void lcd_display_off(void)
+{
+ /* block drawing operations and changing of first */
+ display_on = false;
+
+ /* LQV shutdown sequence */
+ lcd_write_reg(9, 0x55);
+ lcd_write_reg(10, 0x1417);
+ lcd_write_reg(5, 0x4003);
+ sleep_ms(10);
+
+ lcd_write_reg(9, 0x0);
+ sleep_ms(10);
+
+ /* kill power to LCD panel (unconfirmed) */
+ GPIOA_CLEAR = (1<<16);
+
+ /* also kill the backlight, otherwise LCD fade is visible on screen */
+ GPIOA_CLEAR = (1<<6);
+}
+
+
+void lcd_enable(bool on)
+{
+ if (on == display_on)
+ return;
+
+ if (on)
+ {
+ lcd_display_on(); /* Turn on display */
+ lcd_update(); /* Resync display */
+ }
+ else
+ {
+ lcd_display_off(); /* Turn off display */
+ }
+}
+
+bool lcd_enabled(void)
+{
+ return display_on;
+}
+
+
+void lcd_init_device(void)
+{
+ BCLKCTR |= 4; /* enable LCD bus clock */
+
+ /* set PCK_LCD to 108Mhz */
+ PCLK_LCD &= ~PCK_EN;
+ PCLK_LCD = PCK_EN | (CKSEL_PLL1<<24) | 1; /* source = PLL1, divided by 2 */
+
+ /* reset the LCD controller */
+ SWRESET |= 4;
+ SWRESET &= ~4;
+
+ /* set port configuration */
+ PORTCFG1 &= ~0xC0000000;
+ PORTCFG1 &= ~0x3FC0;
+ PORTCFG2 &= ~0x100;
+
+ /* set physical display size */
+ LCDC_DS = (LCD_HEIGHT<<16) | LCD_WIDTH;
+
+ LCDC_HTIME1 = (0x2d<<16) | 0x3bf;
+ LCDC_HTIME2 = (1<<16) | 1;
+ LCDC_VTIME1 = LCDC_VTIME3 = (0<<16) | 239;
+ LCDC_VTIME2 = LCDC_VTIME4 = (1<<16) | 3;
+
+ LCDC_I1BASE = (unsigned int)lcd_framebuffer; /* dirty, dirty hack */
+ LCDC_I1SIZE = (LCD_HEIGHT<<16) | LCD_WIDTH; /* image 1 size */
+ //LCDC_I1POS = (0<<16) | 0; /* position */
+ //LCDC_I1OFF = 0; /* address offset */
+ //LCDC_I1SCALE = 0; /* scaling */
+ LCDC_I1CTRL = 5; /* 565bpp (7 = 888bpp) */
+ //LCDC_CTRL &= ~(1<<28);
+
+ LCDC_CLKDIV = (LCDC_CLKDIV &~ 0xFF00FF) | (1<<16) | 2; /* and this means? */
+
+ /* set and clear various flags - not investigated yet */
+ //LCDC_CTRL &~ 0x090006AA; /* clear bits 1,3,5,7,9,10,24,27 */
+ LCDC_CTRL |= 0x02800144; /* set bits 2,6,8,25,23 */
+ LCDC_CTRL = (LCDC_CTRL &~ 0xF0000) | 0x20000;
+ //LCDC_CTRL = (LCDC_CTRL &~ 0x700000) | 0x700000;
+
+ /* enable LCD controller */
+ LCDC_CTRL |= 1;
+}
+
+
+/*** Update functions ***/
+
+
+/* Update the display.
+ This must be called after all other LCD functions that change the display. */
+void lcd_update(void) ICODE_ATTR;
+void lcd_update(void)
+{
+ #warning function not implemented
+ /* currently lcd_framebuffer is accessed directly by the hardware */
+}
+
+/* Update a fraction of the display. */
+void lcd_update_rect(int, int, int, int) ICODE_ATTR;
+void lcd_update_rect(int x, int y, int width, int height)
+{
+ #warning function not implemented
+ (void)x;
+ (void)y;
+ (void)width;
+ (void)height;
+}
+
+void lcd_set_flip(bool yesno)
+{
+ #warning function not implemented
+ (void)yesno;
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+ #warning function not implemented
+ (void)yesno;
+}
+
+void lcd_blit(const fb_data* data, int bx, int y, int bwidth,
+ int height, int stride)
+{
+ #warning function not implemented
+ (void)data;
+ (void)bx;
+ (void)y;
+ (void)bwidth;
+ (void)height;
+ (void)stride;
+}
+
+void lcd_yuv_blit(unsigned char * const src[3],
+ int src_x, int src_y, int stride,
+ int x, int y, int width, int height)
+{
+ #warning function not implemented
+ (void)src;
+ (void)src_x;
+ (void)src_y;
+ (void)stride;
+ (void)x;
+ (void)y;
+ (void)width;
+ (void)height;
+}
diff --git a/firmware/target/arm/tcc780x/cowond2/pcm-cowond2.c b/firmware/target/arm/tcc780x/cowond2/pcm-cowond2.c
new file mode 100644
index 0000000000..2d50f042d9
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/pcm-cowond2.c
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Karl Kurbjun
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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)
+{
+ #warning function not implemented
+}
+
+const void * pcm_play_dma_get_peak_buffer(int *count)
+{
+ #warning function not implemented
+ (void) count;
+ return 0;
+}
+
+void pcm_play_dma_init(void)
+{
+ #warning function not implemented
+}
+
+void pcm_apply_settings(void)
+{
+ #warning function not implemented
+}
+
+void pcm_set_frequency(unsigned int frequency)
+{
+ #warning function not implemented
+ (void) frequency;
+}
+
+void pcm_play_dma_start(const void *addr, size_t size)
+{
+ #warning function not implemented
+ (void) addr;
+ (void) size;
+}
+
+void pcm_play_dma_stop(void)
+{
+ #warning function not implemented
+}
+
+void pcm_play_lock(void)
+{
+ #warning function not implemented
+}
+
+void pcm_play_unlock(void)
+{
+ #warning function not implemented
+}
+
+void pcm_play_dma_pause(bool pause)
+{
+ #warning function not implemented
+ (void) pause;
+}
+
+size_t pcm_get_bytes_waiting(void)
+{
+ #warning function not implemented
+ return 0;
+}
diff --git a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
new file mode 100644
index 0000000000..d8a58570e4
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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 <stdbool.h>
+#include "kernel.h"
+#include "system.h"
+#include "power.h"
+
+#ifndef SIMULATOR
+
+void power_init(void)
+{
+ #warning function not implemented
+}
+
+void ide_power_enable(bool on)
+{
+ #warning function not implemented
+ (void)on;
+}
+
+bool ide_powered(void)
+{
+ #warning function not implemented
+ return true;
+}
+
+void power_off(void)
+{
+ #warning function not implemented
+}
+
+#else /* SIMULATOR */
+
+bool charger_inserted(void)
+{
+ return false;
+}
+
+void charger_enable(bool on)
+{
+ (void)on;
+}
+
+void power_off(void)
+{
+}
+
+void ide_power_enable(bool on)
+{
+ (void)on;
+}
+
+#endif /* SIMULATOR */
diff --git a/firmware/target/arm/tcc780x/cowond2/powermgmt-cowond2.c b/firmware/target/arm/tcc780x/cowond2/powermgmt-cowond2.c
new file mode 100644
index 0000000000..b3572307e9
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/powermgmt-cowond2.c
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Karl Kurbjun
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "adc.h"
+#include "powermgmt.h"
+#include "kernel.h"
+
+unsigned short current_voltage = 3910;
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+ 0
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+ 0
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+ { 100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320 },
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+ 100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320,
+};
+
+void read_battery_inputs(void)
+{
+ #warning function not implemented
+}
+
+/* Returns battery voltage from ADC [millivolts] */
+unsigned int battery_adc_voltage(void)
+{
+ #warning function not implemented
+ return 0;
+}
+
diff --git a/firmware/target/arm/tcc780x/cowond2/usb-cowond2.c b/firmware/target/arm/tcc780x/cowond2/usb-cowond2.c
new file mode 100644
index 0000000000..6ec903b917
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/usb-cowond2.c
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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 "system.h"
+#include "kernel.h"
+#include "ata.h"
+
+/* USB detect is GPIOC 26 active low */
+inline bool usb_detect(void)
+{
+ return (GPIOC & 1<<26)?false:true;
+}
+
+void usb_init_device(void)
+{
+ #warning function not implemented
+}
+
+void usb_enable(bool on)
+{
+ #warning function not implemented
+
+ if (on)
+ {
+
+ }
+ else
+ {
+
+ }
+}
diff --git a/firmware/target/arm/tcc780x/crt0.S b/firmware/target/arm/tcc780x/crt0.S
new file mode 100644
index 0000000000..6e092bcd82
--- /dev/null
+++ b/firmware/target/arm/tcc780x/crt0.S
@@ -0,0 +1,304 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+/* Arm bootloader and startup code based on startup.s from the iPodLinux loader
+ *
+ * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
+ * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
+ *
+ */
+
+#include "config.h"
+#include "cpu.h"
+
+ .section .init.text,"ax",%progbits
+
+ .global start
+
+/* Telechips firmware files start with a 32-byte header, as part of the code. */
+
+start:
+#ifdef TCCBOOT
+ /* Add -DTCCBOOT to EXTRA_DEFINES in the bootloader Makefile to
+ enable building the bootloader to be appended to the end of the
+ original firmware, dual-booting based on a key-press.
+
+ NB: On the D2 TCCBOOT currently only works in USB boot mode (via tcctool)
+ When flashed to the device, the OF will boot as normal - but holding a
+ key to boot Rockbox results in a blank screen and crashed player.
+
+ The following two values are filled in by mktccboot.
+ */
+ .word 0 /* Saved entrypoint of original firmware*/
+ .word 0 /* Location in RAM of the start of our bootloader */
+#else
+ ldr pc, =start_loc /* jump to the main entry point */
+
+ .word 0xffff0601 /* Unknown magic */
+ .word 0x3a726556 /* "Ver:" */
+ .word 0x31373030 /* "0071" */
+ .word 0 /* First CRC32 */
+ .word 0 /* Unknown - always 0 */
+ .word 0 /* Second CRC32 */
+ .word 0 /* length of firmware file */
+
+#ifdef COWON_D2
+ /* Some original firmwares have 0x40 bytes of zeroes here - we
+ don't know why, but err on the side of caution and include it
+ here. */
+ .space 0x40
+#endif
+#endif
+
+start_loc:
+
+#ifdef BOOTLOADER
+#ifdef TCCBOOT
+#ifdef COWON_D2
+ ldr r0, =0xf005a000
+ ldr r0, [r0, #0x40] /* Read GPIO B */
+ tst r0, #0x4
+ ldreq pc, [pc, #-28] /* Jump to original firmware if keypad not pressed */
+#else
+ #error No bootup key detection implemented for this target
+#endif
+
+ /* Copy bootloader to safe area - 0x21000000 (DRAM) */
+ /* TODO: Adjust this for other targets - DRAM + DRAMSIZE - 0x100000 */
+ ldr r0, [pc, #-28]
+ mov r1, #0x22000000
+ sub r1, r1, #0x100000
+ ldr r2, =_dataend
+1:
+ cmp r2, r1
+ ldrhi r3, [r0], #4
+ strhi r3, [r1], #4
+ bhi 1b
+
+ ldr pc, =copied_start /* jump to the relocated start_loc: */
+
+copied_start:
+#endif
+#else
+ /* We don't use interrupts in the bootloader */
+
+ /* Set up stack for IRQ mode */
+ mov r0,#0xd2
+ msr cpsr, r0
+ ldr sp, =irq_stack
+ /* Set up stack for FIQ mode */
+ mov r0,#0xd1
+ msr cpsr, r0
+ ldr sp, =fiq_stack
+
+ /* Let abort and undefined modes use IRQ stack */
+ mov r0,#0xd7
+ msr cpsr, r0
+ ldr sp, =irq_stack
+ mov r0,#0xdb
+ msr cpsr, r0
+ ldr sp, =irq_stack
+#endif
+
+ /* Switch to supervisor mode */
+ mov r0,#0xd3
+ msr cpsr, r0
+ ldr sp, =stackend
+
+
+#if !defined(BOOTLOADER) && !defined(STUB)
+
+ /* Copy exception handler code to address 0 */
+ ldr r2, =_vectorsstart
+ ldr r3, =_vectorsend
+ ldr r4, =_vectorscopy
+1:
+ cmp r3, r2
+ ldrhi r5, [r4], #4
+ strhi r5, [r2], #4
+ bhi 1b
+
+ /* Zero out IBSS */
+ ldr r2, =_iedata
+ ldr r3, =_iend
+ mov r4, #0
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /* Copy the ITCM */
+ ldr r2, =_itcmcopy
+ ldr r3, =_itcmstart
+ ldr r4, =_itcmend
+1:
+ cmp r4, r3
+ ldrhi r5, [r2], #4
+ strhi r5, [r3], #4
+ bhi 1b
+
+ /* Copy the DTCM */
+ ldr r2, =_dtcmcopy
+ ldr r3, =_dtcmstart
+ ldr r4, =_dtcmend
+1:
+ cmp r4, r3
+ ldrhi r5, [r2], #4
+ strhi r5, [r3], #4
+ bhi 1b
+#endif /* !BOOTLOADER,!STUB */
+
+ /* Initialise bss section to zero */
+ ldr r2, =_edata
+ ldr r3, =_end
+ mov r4, #0
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /* Set up some stack and munge it with 0xdeadbeef */
+ ldr sp, =stackend
+ mov r3, sp
+ ldr r2, =stackbegin
+ ldr r4, =0xdeadbeef
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /*
+ Enable cache & TCM regions
+ TODO: This is just doing what the OF does at present. It needs to be
+ better understood and moved out to a separate MMU functions package.
+ */
+ ldr r1, =0x1fe0c
+ mov r0, #0xf7000000
+ str r1, [r0]
+ ldr r1, =0x2801ae24
+ str r1, [r0,#4]
+ ldr r1, =0x13e44
+ str r1, [r0,#8]
+ ldr r1, =0x4001ce60
+ str r1, [r0,#0xc]
+ ldr r1, =0x6001be80
+ str r1, [r0,#0x10]
+ ldr r1, =0x3801aea4
+ str r1, [r0,#0x14]
+ ldr r1, =0x8001eec0
+ str r1, [r0,#0x18]
+ ldr r1, =0x1001aee0
+ str r1, [r0,#0x1c]
+ add r1, r0, #0x8000 /* r1 now = 0xf7008000 */
+ ldr r0, =0xa0000011
+ ldr r2, =0x5507d
+ mcr p15, 0, r0,c9,c1 /* data tcm region (enabled; 8kb; 0xa0000000) */
+ mov r0, #0xd
+ mcr p15, 0, r0,c9,c1, 1 /* inst tcm region (enabled, 4kb, 0x00000000) */
+ ldr r0, =0x55555555
+ mcr p15, 0, r1,c2,c0 /* translation table base register = 0xf7008000 */
+ mcr p15, 0, r0,c3,c0 /* domain access d0-d15 = 'client' */
+ mov r0, #0
+ mcr p15, 0, r0,c7,c5 /* invalidate icache */
+ mcr p15, 0, r2,c1,c0 /* enable mmu, i & d caches */
+ mcr p15, 0, r0,c7,c6 /* invalidate dcache */
+ mcr p15, 0, r1,c8,c7 /* invalidate tlb */
+
+ bl main
+ /* main() should never return */
+
+#ifndef BOOTLOADER
+
+/* Exception handlers. Will be copied to address 0 after memory remapping */
+ .section .vectors,"aw"
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+
+ /* Exception vectors */
+ .global vectors
+vectors:
+ .word start
+ .word undef_instr_handler
+ .word software_int_handler
+ .word prefetch_abort_handler
+ .word data_abort_handler
+ .word reserved_handler
+ .word irq_handler
+ .word fiq_handler
+
+ .text
+
+#if !defined(STUB)
+ .global irq
+ .global fiq
+ .global UIE
+#endif
+
+/* All illegal exceptions call into UIE with exception address as first
+ parameter. This is calculated differently depending on which exception
+ we're in. Second parameter is exception number, used for a string lookup
+ in UIE.
+ */
+undef_instr_handler:
+ mov r0, lr
+ mov r1, #0
+ b UIE
+
+/* We run supervisor mode most of the time, and should never see a software
+ exception being thrown. Perhaps make it illegal and call UIE?
+ */
+software_int_handler:
+reserved_handler:
+ movs pc, lr
+
+prefetch_abort_handler:
+ sub r0, lr, #4
+ mov r1, #1
+ b UIE
+
+data_abort_handler:
+ sub r0, lr, #8
+ mov r1, #2
+ b UIE
+
+#if defined(STUB)
+UIE:
+ b UIE
+#endif
+
+ /* We don't use interrupts in the bootloader */
+
+/* Align stacks to cache line boundary */
+ .balign 16
+
+/* 256 words of IRQ stack */
+ .space 256*4
+irq_stack:
+
+/* 256 words of FIQ stack */
+ .space 256*4
+fiq_stack:
+
+#endif
diff --git a/firmware/target/arm/tcc780x/debug-tcc780x.c b/firmware/target/arm/tcc780x/debug-tcc780x.c
new file mode 100644
index 0000000000..cc5716fd88
--- /dev/null
+++ b/firmware/target/arm/tcc780x/debug-tcc780x.c
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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 "system.h"
+#include "string.h"
+#include <stdbool.h>
+#include "button.h"
+#include "lcd.h"
+#include "sprintf.h"
+#include "font.h"
+
+bool __dbg_ports(void);
+bool __dbg_ports(void)
+{
+ return false;
+}
+
+//extern char r_buffer[5];
+//extern int r_button;
+
+bool __dbg_hw_info(void);
+bool __dbg_hw_info(void)
+{
+ int line = 0, button, oldline;
+ int *address=0x0;
+ bool done=false;
+ char buf[100];
+
+ lcd_setmargins(0, 0);
+ lcd_setfont(FONT_SYSFIXED);
+ lcd_clear_display();
+
+ /* Put all the static text before the while loop */
+ lcd_puts(0, line++, "[Hardware info]");
+
+ /* TODO: ... */
+
+ line++;
+ oldline=line;
+ while(!done)
+ {
+ line = oldline;
+ button = button_get(false);
+
+ button &= ~BUTTON_REPEAT;
+
+ if (button == BUTTON_MENU)
+ done=true;
+ if(button==BUTTON_DOWN)
+ address+=0x01;
+ else if (button==BUTTON_UP)
+ address-=0x01;
+
+ /*snprintf(buf, sizeof(buf), "Buffer: 0x%02x%02x%02x%02x%02x",
+ r_buffer[0], r_buffer[1], r_buffer[2], r_buffer[3],r_buffer[4] ); lcd_puts(0, line++, buf);
+ snprintf(buf, sizeof(buf), "Button: 0x%08x, HWread: 0x%08x",
+ (unsigned int)button, r_button); lcd_puts(0, line++, buf);*/
+ snprintf(buf, sizeof(buf), "current tick: %08x Seconds running: %08d",
+ (unsigned int)current_tick, (unsigned int)current_tick/100); lcd_puts(0, line++, buf);
+ snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x",
+ (unsigned int)address, *address); lcd_puts(0, line++, buf);
+ snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x",
+ (unsigned int)(address+1), *(address+1)); lcd_puts(0, line++, buf);
+ snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x",
+ (unsigned int)(address+2), *(address+2)); lcd_puts(0, line++, buf);
+
+ lcd_update();
+ }
+ return false;
+}
diff --git a/firmware/target/arm/tcc780x/kernel-tcc780x.c b/firmware/target/arm/tcc780x/kernel-tcc780x.c
new file mode 100644
index 0000000000..e0d9c3342e
--- /dev/null
+++ b/firmware/target/arm/tcc780x/kernel-tcc780x.c
@@ -0,0 +1,43 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2008 by Rob Purchase
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "config.h"
+#include "system.h"
+#include "kernel.h"
+#include "timer.h"
+#include "thread.h"
+
+/* NB: PCK_TCT must previously have been set to 2Mhz by calling clock_init() */
+void tick_start(unsigned int interval_in_ms)
+{
+ /* disable Timer0 */
+ TCFG0 &= ~1;
+
+ /* set counter reference value based on 1Mhz tick */
+ TREF0 = interval_in_ms * 1000;
+
+ /* Timer0 = reset to 0, divide=2, IRQ enable, enable (continuous) */
+ TCFG0 = (1<<8) | (0<<4) | (1<<3) | 1;
+
+ /* Unmask timer IRQ */
+ MIRQ &= ~TIMER_IRQ_MASK;
+}
+
+/* NB: Since the 7801 has a single timer IRQ, the tick tasks are dispatched
+ as part of the central timer IRQ processing in timer-tcc780x.c */
diff --git a/firmware/target/arm/tcc780x/system-target.h b/firmware/target/arm/tcc780x/system-target.h
new file mode 100644
index 0000000000..15508bc8bf
--- /dev/null
+++ b/firmware/target/arm/tcc780x/system-target.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef SYSTEM_TARGET_H
+#define SYSTEM_TARGET_H
+
+#include "system-arm.h"
+
+#define CPUFREQ_DEFAULT 98784000
+#define CPUFREQ_NORMAL 98784000
+#define CPUFREQ_MAX 192000000
+
+#define inl(a) (*(volatile unsigned long *) (a))
+#define outl(a,b) (*(volatile unsigned long *) (b) = (a))
+#define inb(a) (*(volatile unsigned char *) (a))
+#define outb(a,b) (*(volatile unsigned char *) (b) = (a))
+#define inw(a) (*(volatile unsigned short *) (a))
+#define outw(a,b) (*(volatile unsigned short *) (b) = (a))
+
+#endif /* SYSTEM_TARGET_H */
diff --git a/firmware/target/arm/tcc780x/system-tcc780x.c b/firmware/target/arm/tcc780x/system-tcc780x.c
new file mode 100644
index 0000000000..30221d180e
--- /dev/null
+++ b/firmware/target/arm/tcc780x/system-tcc780x.c
@@ -0,0 +1,275 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Rob Purchase
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "kernel.h"
+#include "system.h"
+#include "panic.h"
+
+#if !defined(BOOTLOADER)
+
+#define default_interrupt(name) \
+ extern __attribute__((weak,alias("UIRQ"))) void name (void)
+
+void irq_handler(void) __attribute__((interrupt ("IRQ"), naked));
+void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked));
+
+default_interrupt(EXT0);
+default_interrupt(EXT1);
+default_interrupt(EXT2);
+default_interrupt(EXT3);
+default_interrupt(IRQ4);
+default_interrupt(IRQ5);
+default_interrupt(TIMER);
+default_interrupt(IRQ7);
+default_interrupt(IRQ8);
+default_interrupt(IRQ9);
+default_interrupt(IRQ10);
+default_interrupt(IRQ11);
+default_interrupt(IRQ12);
+default_interrupt(IRQ13);
+default_interrupt(DAI_RX);
+default_interrupt(DAI_TX);
+default_interrupt(IRQ16);
+default_interrupt(IRQ17);
+default_interrupt(IRQ18);
+default_interrupt(IRQ19);
+default_interrupt(IRQ20);
+default_interrupt(IRQ21);
+default_interrupt(IRQ22);
+default_interrupt(IRQ23);
+default_interrupt(IRQ24);
+default_interrupt(IRQ25);
+default_interrupt(IRQ26);
+default_interrupt(IRQ27);
+default_interrupt(IRQ28);
+default_interrupt(IRQ29);
+default_interrupt(IRQ30);
+default_interrupt(IRQ31);
+
+static void (* const irqvector[])(void) =
+{
+ EXT0,EXT1,EXT2,EXT3,IRQ4,IRQ5,TIMER,IRQ7,
+ IRQ8,IRQ9,IRQ10,IRQ11,IRQ12,IRQ13,DAI_RX,DAI_TX,
+ IRQ16,IRQ17,IRQ18,IRQ19,IRQ20,IRQ21,IRQ22,IRQ23,
+ IRQ24,IRQ25,IRQ26,IRQ27,IRQ28,IRQ29,IRQ30,IRQ31
+};
+
+static const char * const irqname[] =
+{
+ "EXT0","EXT1","EXT2","EXT3","IRQ4","IRQ5","TIMER","IRQ7",
+ "IRQ8","IRQ9","IRQ10","IRQ11","IRQ12","IRQ13","DAI_RX","DAI_TX",
+ "IRQ16","IRQ17","IRQ18","IRQ19","IRQ20","IRQ21","IRQ22","IRQ23",
+ "IRQ24","IRQ25","IRQ26","IRQ27","IRQ28","IRQ29","IRQ30","IRQ31"
+};
+
+static void UIRQ(void)
+{
+ unsigned int offset = VNIRQ;
+ panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]);
+}
+
+void irq_handler(void)
+{
+ /*
+ * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c
+ */
+
+ asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
+ "sub sp, sp, #8 \n"); /* Reserve stack */
+ irqvector[VNIRQ]();
+ 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 */
+}
+
+void fiq_handler(void)
+{
+ asm volatile (
+ "sub lr, lr, #4 \r\n"
+ "movs lr,pc \r\n"
+ );
+}
+#endif /* !defined(BOOTLOADER) */
+
+
+/* TODO:
+ a) this is not the place for this function
+ b) it currently ignores the supplied frequency and uses default values
+ c) if the PLL being set drives any PCKs, an appropriate new clock divider
+ will have to be re-calculated for those PCKs (the OF maintains a list of
+ PCK frequencies for this purpose).
+*/
+void set_pll_frequency(unsigned int pll_number, unsigned int frequency)
+{
+ int i = 0;
+
+ if (pll_number > 1) return;
+
+ /* The frequency parameter is currently ignored and temporary values are
+ used (PLL0=192Mhz, PLL1=216Mhz). The D2 firmware uses a lookup table
+ to derive the values of PLLxCFG from a the supplied frequency.
+ Presumably we will need to do something similar. */
+ if (pll_number == 0)
+ {
+ /* drive CPU off Xin while switching */
+ CLKCTRL = 0xB00FF014; /* Xin enable, Fsys driven by Xin, Fbus = Fsys,
+ MCPU=Fbus, SCPU=Fbus */
+
+ asm volatile (
+ "nop \n\t"
+ "nop \n\t"
+ );
+
+ PLL0CFG |= (1<<31); /* power down */
+ CLKDIVC = CLKDIVC &~ (0xff << 24); /* disable PLL0 divider */
+ PLL0CFG = 0x80019808; /* set for 192Mhz (with power down) */
+ PLL0CFG = PLL0CFG &~ (1<<31); /* power up */
+
+ CLKCTRL = (CLKCTRL & ~0x1f) | 0x800FF010;
+
+ asm volatile (
+ "nop \n\t"
+ "nop \n\t"
+ );
+ }
+ else if (pll_number == 1)
+ {
+ PLL1CFG |= (1<<31); /* power down */
+ CLKDIVC = CLKDIVC &~ (0xff << 16); /* disable PLL1 divider */
+ PLL1CFG = 0x80002503; /* set for 216Mhz (with power down)*/
+ PLL1CFG = PLL1CFG &~ (1<<31); /* power up */
+ }
+
+ i = 0x1000;
+ while (--i) {};
+}
+
+
+/* TODO - these should live in the target-specific directories and
+ once we understand what all the GPIO pins do, move the init to the
+ specific driver for that hardware. For now, we just perform the
+ same GPIO init as the original firmware - this makes it easier to
+ investigate what the GPIO pins do.
+*/
+
+#ifdef COWON_D2
+static void gpio_init(void)
+{
+ /* Do what the original firmware does */
+ GPIOA = 0x07000C83;
+ GPIOA_DIR = 0x0F010CE3;
+ GPIOB = 0;
+ GPIOB_DIR = 0x00080000;
+ GPIOC = 0x39000000;
+ GPIOC_DIR = 0xB9000000;
+ GPIOD = 0;
+ GPIOD_DIR = 0;
+ GPIOD = 0;
+ GPIOD_DIR = 0x00480000;
+
+ PORTCFG0 = 0x00034540;
+ PORTCFG1 = 0x0566A000;
+ PORTCFG2 = 0x000004C0;
+ PORTCFG3 = 0x0AA40455;
+}
+#endif
+
+
+/* Second function called in the original firmware's startup code - we just
+ set up the clocks in the same way as the original firmware for now. */
+#ifdef COWON_D2
+static void clock_init(void)
+{
+ int i;
+
+ CSCFG3 = (CSCFG3 &~ 0x3fff) | 0x841;
+ CLKCTRL = (CLKCTRL & ~0xff) | 0x14;
+
+ PCLK_RFREQ = 0x1401002d; /* RAM refresh source = Xin (4) / 0x2d = 266kHz */
+
+ MCFG |= 1;
+ SDCFG = (SDCFG &~ 0x7000) | 0x2000;
+
+ MCFG1 |= 1;
+ SDCFG1 = (SDCFG &~ 0x7000) | 0x2000;
+
+ PLL0CFG |= 0x80000000; /* power down */
+ PLL0CFG = 0x14010000; /* power up, source = Xin (4) undivided = 12Mhz */
+
+ i = 0x8000;
+ while (--i) {};
+
+ CLKCTRL = (CLKCTRL &~ 0x1f) | 0x800FF010; /* CPU and COP driven by PLL0 */
+
+ asm volatile (
+ "nop \n\t"
+ "nop \n\t"
+ );
+
+ /* configure PCK_TCT to 2Mhz (clock source 4 (Xin) divided by 6) */
+ PCLK_TCT = PCK_EN | (CKSEL_XIN<<24) | 5;
+}
+#endif
+
+
+#ifdef COWON_D2
+void system_init(void)
+{
+ MBCFG = 0x19;
+
+ if (TCC780_VER == 0)
+ ECFG0 = 0x309;
+ else
+ ECFG0 = 0x30d;
+
+ /* mask all interrupts */
+ MIRQ = -1;
+
+ gpio_init();
+ clock_init();
+
+ /* TODO: these almost certainly shouldn't be here */
+ set_pll_frequency(0, 192000000); /* drives CPU */
+ set_pll_frequency(1, 216000000); /* drives LCD PXCLK - divided by 2 */
+}
+#endif
+
+
+void system_reboot(void)
+{
+ #warning function not implemented
+}
+
+int system_memory_guard(int newmode)
+{
+ #warning function not implemented
+
+ (void)newmode;
+ return 0;
+}
+
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+
+void set_cpu_frequency(long frequency)
+{
+ #warning function not implemented
+ (void)frequency;
+}
+
+#endif
diff --git a/firmware/target/arm/tcc780x/timer-target.h b/firmware/target/arm/tcc780x/timer-target.h
new file mode 100644
index 0000000000..db25df7cd4
--- /dev/null
+++ b/firmware/target/arm/tcc780x/timer-target.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2007 by Karl Kurbjun
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+#ifndef TIMER_TARGET_H
+#define TIMER_TARGET_H
+
+/* timers are based on XIN (12Mhz) */
+#define TIMER_FREQ (12000000)
+
+bool __timer_set(long cycles, bool set);
+bool __timer_register(void);
+void __timer_unregister(void);
+
+#define __TIMER_SET(cycles, set) \
+ __timer_set(cycles, set)
+
+#define __TIMER_REGISTER(reg_prio, unregister_callback, cycles, \
+ int_prio, timer_callback) \
+ __timer_register()
+
+#define __TIMER_UNREGISTER(...) \
+ __timer_unregister()
+
+#endif /* TIMER_TARGET_H */
diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c
new file mode 100644
index 0000000000..c724c4b3a8
--- /dev/null
+++ b/firmware/target/arm/tcc780x/timer-tcc780x.c
@@ -0,0 +1,82 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2008 by Rob Purchase
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* 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 "system.h"
+#include "timer.h"
+#include "logf.h"
+
+/* Use the TC32 counter [sourced by Xin:12Mhz] for this timer, as it's the
+ only one that allows a 32-bit counter (Timer0-5 are 16/20 bit only). */
+
+bool __timer_set(long cycles, bool start)
+{
+ #warning function not implemented
+
+ (void)cycles;
+ (void)start;
+ return false;
+}
+
+bool __timer_register(void)
+{
+ #warning function not implemented
+
+ return false;
+}
+
+void __timer_unregister(void)
+{
+ #warning function not implemented
+}
+
+
+/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
+
+extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
+
+void TIMER(void)
+{
+ if (TIREQ & TF0) /* Timer0 reached ref value */
+ {
+ int i;
+
+ /* Run through the list of tick tasks */
+ for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
+ {
+ if(tick_funcs[i])
+ {
+ tick_funcs[i]();
+ }
+ }
+
+ current_tick++;
+
+ /* reset Timer 0 IRQ & ref flags */
+ TIREQ |= TI0 | TF0;
+ }
+
+ if (TC32IRQ & (1<<3)) /* end of TC32 prescale */
+ {
+ /* dispatch timer */
+ }
+
+ CREQ |= TIMER_IRQ_MASK; /* clear IRQ */
+}
diff --git a/firmware/target/arm/wmcodec-telechips.c b/firmware/target/arm/wmcodec-telechips.c
new file mode 100644
index 0000000000..851158ca8d
--- /dev/null
+++ b/firmware/target/arm/wmcodec-telechips.c
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * TCC specific code for Wolfson audio codecs
+ *
+ * Based on code from the ipodlinux project - http://ipodlinux.org/
+ * Adapted for Rockbox in December 2005
+ *
+ * Original file: linux/arch/armnommu/mach-ipod/audio.c
+ *
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "system.h"
+#include "audiohw.h"
+#include "i2c.h"
+
+#if defined(COWON_D2)
+/* The D2's audio codec uses an I2C address of 0x34 */
+#define I2C_AUDIO_ADDRESS 0x34
+#else
+#error wmcodec not implemented for this target!
+#endif
+
+
+void audiohw_init(void)
+{
+ #warning function not implemented
+}
+
+void wmcodec_write(int reg, int data)
+{
+ unsigned char d[2];
+ d[0] = (reg << 1) | ((data & 0x100) >> 8);
+ d[1] = data;
+
+ i2c_write(I2C_AUDIO_ADDRESS, d, 2);
+}
diff --git a/tools/configure b/tools/configure
index 4d654f35af..2ece6cd3ff 100755
--- a/tools/configure
+++ b/tools/configure
@@ -600,6 +600,7 @@ cat <<EOF
30) X5/X5V/X5L 40) Gigabeat F 50) Sansa e200
31) M5/M5L 41) Gigabeat S 51) Sansa e200R
32) 7 52) Sansa c200
+ 33) Cowon D2
==Tatung== ==Olympus== ==Logik==
60) Elio TPJ-1022 70) M:Robe 500 80) DAX 1GB MP3/DAB
@@ -1479,6 +1480,31 @@ EOF
t_manufacturer="tcc77x"
t_model="iaudio7"
;;
+
+ 33|cowond2)
+ target_id=34
+ archos="cowond2"
+ target="-DCOWON_D2"
+ memory=32
+ arm926ejscc
+ tool="cp "
+ boottool="$rootdir/tools/scramble -tcc=crc"
+ bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
+ bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
+ bmp2rb_remotemono="$rootdir/tools/bmp2rb -f 0"
+ bmp2rb_remotenative="$rootdir/tools/bmp2rb -f 0"
+ output="rockbox.iaudio"
+ appextra="recorder:gui"
+ archosrom=""
+ flash=""
+ plugins="no"
+ swcodec="yes"
+ toolset="$tccbitmaptools"
+ # architecture, manufacturer and model for the target-tree build
+ t_cpu="arm"
+ t_manufacturer="tcc780x"
+ t_model="cowond2"
+ ;;
*)
echo "Please select a supported target platform!"