summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/SOURCES2
-rw-r--r--apps/debug_menu.c15
-rwxr-xr-xapps/keymaps/keymap-sa9200.c315
-rw-r--r--apps/lang/english.lang29
-rw-r--r--apps/plugins/lib/pluginlib_actions.c15
-rw-r--r--bootloader/SOURCES2
-rw-r--r--bootloader/common.c3
-rw-r--r--bootloader/main-pp.c25
-rw-r--r--firmware/SOURCES16
-rw-r--r--firmware/drivers/audio/as3514.c6
-rw-r--r--firmware/export/as3514.h2
-rwxr-xr-xfirmware/export/config-sa9200.h167
-rw-r--r--firmware/export/config.h4
-rw-r--r--firmware/export/usb.h3
-rw-r--r--firmware/target/arm/ata-sd-pp.c2
-rw-r--r--firmware/target/arm/i2c-pp.c2
-rw-r--r--firmware/target/arm/philips/app.lds198
-rw-r--r--firmware/target/arm/philips/boot.lds65
-rw-r--r--firmware/target/arm/philips/sa9200/adc-target.h43
-rw-r--r--firmware/target/arm/philips/sa9200/backlight-sa9200.c75
-rw-r--r--firmware/target/arm/philips/sa9200/backlight-target.h30
-rwxr-xr-xfirmware/target/arm/philips/sa9200/button-sa9200.c72
-rwxr-xr-xfirmware/target/arm/philips/sa9200/button-target.h53
-rwxr-xr-xfirmware/target/arm/philips/sa9200/lcd-sa9200.c205
-rw-r--r--firmware/target/arm/philips/sa9200/power-sa9200.c136
-rw-r--r--firmware/target/arm/philips/sa9200/powermgmt-sa9200.c58
-rw-r--r--firmware/target/arm/system-pp502x.c6
-rw-r--r--firmware/target/arm/usb-fw-pp502x.c5
-rwxr-xr-xtools/configure29
-rw-r--r--tools/scramble.c5
30 files changed, 1543 insertions, 45 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index c8cd03a29d..8c7cc15ecb 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -189,4 +189,6 @@ keymaps/keymap-cowond2.c
keymaps/keymap-creativezvm.c
#elif CONFIG_KEYPAD == CREATIVEZV_PAD
keymaps/keymap-creativezv.c
+#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
+keymaps/keymap-sa9200.c
#endif
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index e198bfa18d..313a2aacac 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -99,7 +99,7 @@
#include "debug-target.h"
#endif
-#if defined(SANSA_E200)
+#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
#include "i2c-pp.h"
#include "as3514.h"
#endif
@@ -1017,6 +1017,11 @@ static bool dbg_spdif(void)
#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
(CONFIG_KEYPAD == SANSA_C200_PAD)
# define DEBUG_CANCEL BUTTON_LEFT
+
+/* This is temporary until the SA9200 touchpad works */
+#elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD)
+# define DEBUG_CANCEL BUTTON_POWER
+
#endif /* key definitions */
/* Test code!!! */
@@ -1197,7 +1202,7 @@ bool dbg_ports(void)
snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
lcd_puts(0, line++, buf);
-#elif defined(SANSA_E200)
+#elif defined(SANSA_E200) || defined(PHILIPS_SA9200)
snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
@@ -1220,6 +1225,7 @@ bool dbg_ports(void)
lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
lcd_puts(0, line++, buf);
+#if !defined(PHILIPS_SA9200)
snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
@@ -1227,6 +1233,7 @@ bool dbg_ports(void)
snprintf(buf, sizeof(buf), "CHARGER: %02X/%02X", i2c_readbyte(AS3514_I2C_ADDR, AS3514_CHARGER), i2c_readbyte(AS3514_I2C_ADDR, AS3514_IRQ_ENRD0));
lcd_puts(0, line++, buf);
#endif
+#endif
lcd_update();
if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
return false;
@@ -2136,7 +2143,7 @@ static bool dbg_save_roms(void)
return false;
}
-#elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
+#elif defined(CPU_PP) && !defined(HAVE_ATA_SD)
static bool dbg_save_roms(void)
{
int fd;
@@ -2459,7 +2466,7 @@ struct the_menu_item {
};
static const struct the_menu_item menuitems[] = {
#if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
- (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
+ (defined(CPU_PP) && !defined(HAVE_ATA_SD))
{ "Dump ROM contents", dbg_save_roms },
#endif
#if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
diff --git a/apps/keymaps/keymap-sa9200.c b/apps/keymaps/keymap-sa9200.c
new file mode 100755
index 0000000000..c2fa6e44e8
--- /dev/null
+++ b/apps/keymaps/keymap-sa9200.c
@@ -0,0 +1,315 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 Jonathan Gordon
+ *
+ * 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 Philips SA9200 target */
+#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
+ */
+
+/* CONTEXT_CUSTOM's used in this file...
+
+CONTEXT_CUSTOM|CONTEXT_TREE = the standard list/tree defines (without directions)
+CONTEXT_CUSTOM|CONTEXT_SETTINGS = the direction keys for the eq/col picker screens
+ i.e where up/down is inc/dec
+ CONTEXT_SETTINGS = up/down is prev/next, l/r is inc/dec
+
+*/
+
+
+static const struct button_mapping button_context_standard[] = {
+ { ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+
+ { ACTION_STD_CANCEL, BUTTON_REW, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
+
+ { ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
+
+ { ACTION_STD_QUICKSCREEN, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU },
+ { ACTION_STD_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
+
+ { ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
+ { ACTION_STD_OK, BUTTON_FFWD, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST
+}; /* button_context_standard */
+
+
+static const struct button_mapping button_context_wps[] = {
+ { ACTION_WPS_PLAY, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
+ { ACTION_WPS_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
+
+ { ACTION_WPS_SKIPNEXT, BUTTON_FFWD|BUTTON_REL, BUTTON_FFWD },
+ { ACTION_WPS_SKIPPREV, BUTTON_REW|BUTTON_REL, BUTTON_REW },
+
+ { ACTION_WPS_SEEKBACK, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_WPS_SEEKFWD, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_WPS_STOPSEEK, BUTTON_REW|BUTTON_REL, BUTTON_REW|BUTTON_REPEAT },
+ { ACTION_WPS_STOPSEEK, BUTTON_FFWD|BUTTON_REL, BUTTON_FFWD|BUTTON_REPEAT },
+
+ { ACTION_WPS_ABSETB_NEXTDIR, BUTTON_RIGHT|BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_WPS_ABSETA_PREVDIR, BUTTON_RIGHT|BUTTON_REW, BUTTON_NONE },
+ { ACTION_WPS_ABRESET, BUTTON_RIGHT|BUTTON_SELECT, BUTTON_NONE },
+
+ { ACTION_WPS_VOLDOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_WPS_VOLDOWN, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
+ { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_WPS_VOLUP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_WPS_VOLUP, BUTTON_UP, BUTTON_NONE },
+ { ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
+
+ { ACTION_WPS_PITCHSCREEN, BUTTON_RIGHT|BUTTON_UP, BUTTON_RIGHT },
+ { ACTION_WPS_PITCHSCREEN, BUTTON_RIGHT|BUTTON_DOWN, BUTTON_RIGHT },
+
+ { ACTION_WPS_QUICKSCREEN, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU },
+ { ACTION_WPS_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
+ { ACTION_WPS_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
+
+ { ACTION_WPS_ID3SCREEN, BUTTON_RIGHT|BUTTON_MENU, BUTTON_NONE },
+ { ACTION_WPS_BROWSE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
+
+ LAST_ITEM_IN_LIST
+}; /* button_context_wps */
+
+static const struct button_mapping button_context_list[] = {
+ { ACTION_LISTTREE_PGUP, BUTTON_RIGHT|BUTTON_UP, BUTTON_RIGHT },
+ { ACTION_LISTTREE_PGUP, BUTTON_UP|BUTTON_REL, BUTTON_RIGHT|BUTTON_UP },
+ { ACTION_LISTTREE_PGUP, BUTTON_RIGHT|BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_LISTTREE_PGDOWN, BUTTON_RIGHT|BUTTON_DOWN, BUTTON_RIGHT },
+ { ACTION_LISTTREE_PGDOWN, BUTTON_DOWN|BUTTON_REL, BUTTON_RIGHT|BUTTON_DOWN },
+ { ACTION_LISTTREE_PGDOWN, BUTTON_RIGHT|BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+#ifdef HAVE_VOLUME_IN_LIST
+ { ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_LIST_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
+ { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
+ { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+#endif
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_list */
+
+static const struct button_mapping button_context_tree[] = {
+ { ACTION_TREE_WPS, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
+ { ACTION_TREE_STOP, BUTTON_POWER, BUTTON_NONE },
+ { ACTION_TREE_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
+ { ACTION_TREE_STOP, BUTTON_POWER|BUTTON_REPEAT, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
+}; /* button_context_tree */
+
+static const struct button_mapping button_context_listtree_scroll_with_combo[] = {
+ { ACTION_NONE, BUTTON_RIGHT, BUTTON_NONE },
+ { ACTION_TREE_PGLEFT, BUTTON_RIGHT|BUTTON_REW, BUTTON_RIGHT },
+ { ACTION_TREE_PGLEFT, BUTTON_REW|BUTTON_REL, BUTTON_RIGHT|BUTTON_REW },
+ { ACTION_TREE_PGLEFT, BUTTON_RIGHT|BUTTON_REW, BUTTON_REW|BUTTON_REL },
+ { ACTION_TREE_ROOT_INIT, BUTTON_RIGHT|BUTTON_REW|BUTTON_REPEAT, BUTTON_RIGHT|BUTTON_REW },
+ { ACTION_TREE_PGLEFT, BUTTON_RIGHT|BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_FFWD, BUTTON_RIGHT },
+ { ACTION_TREE_PGRIGHT, BUTTON_FFWD|BUTTON_REL, BUTTON_RIGHT|BUTTON_FFWD },
+ { ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_FFWD, BUTTON_FFWD|BUTTON_REL },
+ { ACTION_TREE_PGRIGHT, BUTTON_RIGHT|BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
+};
+
+static const struct button_mapping button_context_listtree_scroll_without_combo[] = {
+ { ACTION_NONE, BUTTON_REW, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_REW|BUTTON_REL, BUTTON_REW },
+ { ACTION_TREE_ROOT_INIT, BUTTON_REW|BUTTON_REPEAT, BUTTON_REW },
+ { ACTION_TREE_PGLEFT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_TREE_PGLEFT, BUTTON_REW|BUTTON_REL, BUTTON_REW|BUTTON_REPEAT },
+ { ACTION_NONE, BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_STD_OK, BUTTON_FFWD|BUTTON_REL, BUTTON_FFWD },
+ { ACTION_TREE_PGRIGHT, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_TREE_PGRIGHT, BUTTON_FFWD|BUTTON_REL, BUTTON_FFWD|BUTTON_REPEAT },
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
+};
+
+static const struct button_mapping button_context_settings[] = {
+ { ACTION_SETTINGS_INC, BUTTON_UP, BUTTON_NONE },
+ { ACTION_SETTINGS_INCREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_PREV, BUTTON_REW, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_SETTINGS_RESET, BUTTON_RIGHT, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_settings */
+
+static const struct button_mapping button_context_settings_right_is_inc[] = {
+ { ACTION_SETTINGS_INC, BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_SETTINGS_INCREPEAT, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_SETTINGS_DEC, BUTTON_REW, BUTTON_NONE },
+ { ACTION_SETTINGS_DECREPEAT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_SETTINGS_RESET, BUTTON_RIGHT, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_settingsgraphical */
+
+static const struct button_mapping button_context_yesno[] = {
+ { ACTION_YESNO_ACCEPT, BUTTON_SELECT, BUTTON_NONE },
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_settings_yesno */
+
+static const struct button_mapping button_context_colorchooser[] = {
+ { ACTION_STD_OK, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS),
+}; /* button_context_colorchooser */
+
+static const struct button_mapping button_context_eq[] = {
+ { ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE },
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS),
+}; /* button_context_eq */
+
+/** Bookmark Screen **/
+static const struct button_mapping button_context_bmark[] = {
+ { ACTION_BMS_DELETE, BUTTON_RIGHT, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
+}; /* button_context_bmark */
+
+static const struct button_mapping button_context_time[] = {
+ { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
+ { ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE },
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
+}; /* button_context_time */
+
+static const struct button_mapping button_context_quickscreen[] = {
+ { ACTION_QS_DOWNINV, BUTTON_UP, BUTTON_NONE },
+ { ACTION_QS_DOWNINV, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_DOWN, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_LEFT, BUTTON_REW, BUTTON_NONE },
+ { ACTION_QS_LEFT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_RIGHT, BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_QS_RIGHT, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_MENU, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_quickscreen */
+
+static const struct button_mapping button_context_pitchscreen[] = {
+ { ACTION_PS_INC_SMALL, BUTTON_UP, BUTTON_NONE },
+ { ACTION_PS_INC_BIG, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_PS_DEC_SMALL, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_PS_DEC_BIG, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_PS_NUDGE_LEFT, BUTTON_REW, BUTTON_NONE },
+ { ACTION_PS_NUDGE_LEFTOFF, BUTTON_REW|BUTTON_REL, BUTTON_NONE },
+ { ACTION_PS_NUDGE_RIGHT, BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_FFWD|BUTTON_REL, BUTTON_NONE },
+ { ACTION_PS_TOGGLE_MODE, BUTTON_MENU, BUTTON_NONE },
+ { ACTION_PS_RESET, BUTTON_RIGHT, BUTTON_NONE },
+ { ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_pitchcreen */
+
+static const struct button_mapping button_context_keyboard[] = {
+ { ACTION_KBD_LEFT, BUTTON_REW, BUTTON_NONE },
+ { ACTION_KBD_LEFT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_RIGHT, BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_KBD_RIGHT, BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_CURSOR_LEFT, BUTTON_RIGHT|BUTTON_REW, BUTTON_NONE },
+ { ACTION_KBD_CURSOR_LEFT, BUTTON_RIGHT|BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_CURSOR_RIGHT, BUTTON_RIGHT|BUTTON_FFWD, BUTTON_NONE },
+ { ACTION_KBD_CURSOR_RIGHT, BUTTON_RIGHT|BUTTON_FFWD|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_SELECT, BUTTON_SELECT, BUTTON_NONE },
+ { ACTION_KBD_PAGE_FLIP, BUTTON_RIGHT|BUTTON_MENU, BUTTON_NONE },
+ { ACTION_KBD_DONE, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
+ { ACTION_KBD_ABORT, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
+ { ACTION_KBD_BACKSPACE, BUTTON_MENU, BUTTON_NONE },
+ { ACTION_KBD_BACKSPACE, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_UP, BUTTON_UP, BUTTON_NONE },
+ { ACTION_KBD_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_DOWN, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_KBD_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_MORSE_INPUT, BUTTON_RIGHT|BUTTON_POWER, BUTTON_NONE },
+ { ACTION_KBD_MORSE_SELECT, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST
+}; /* button_context_keyboard */
+
+const struct button_mapping* get_context_mapping(int context)
+{
+ switch (context)
+ {
+ case CONTEXT_STD:
+ return button_context_standard;
+ case CONTEXT_WPS:
+ return button_context_wps;
+
+ case CONTEXT_LIST:
+ return button_context_list;
+ case CONTEXT_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/lang/english.lang b/apps/lang/english.lang
index 2a087bb5cf..b0795d3e67 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -77,6 +77,9 @@
#
# Olympus
# m:robe 100 mrobe100
+#
+# Philips
+# GoGear SA9200 sa9200
<phrase>
id: LANG_SET_BOOL_YES
@@ -323,13 +326,13 @@
<source>
*: "PLAY = Yes"
h100,h120,h300: "NAVI = Yes"
- ipod*,x5,m5,gigabeat*,e200,c200,h10,h10_5gb,mrobe100: "SELECT = Yes"
+ ipod*,x5,m5,gigabeat*,e200,c200,h10,h10_5gb,mrobe100,sa9200: "SELECT = Yes"
player: "(PLAY/STOP)"
</source>
<dest>
*: "PLAY = Yes"
h100,h120,h300: "NAVI = Yes"
- ipod*,x5,m5,gigabeat*,e200,c200,h10,h10_5gb,mrobe100: "SELECT = Yes"
+ ipod*,x5,m5,gigabeat*,e200,c200,h10,h10_5gb,mrobe100,sa9200: "SELECT = Yes"
player: "(PLAY/STOP)"
</dest>
<voice>
@@ -2425,14 +2428,14 @@
h100,h120,h300: "Building database... %d found (STOP to return)"
ipod*: "Building database... %d found (PREV to return)"
x5,m5,gigabeat*,mrobe100: "Building database... %d found (LEFT to return)"
- h10,h10_5gb,e200,c200: "Building database... %d found (PREV to return)"
+ h10,h10_5gb,e200,c200,sa9200: "Building database... %d found (PREV to return)"
</source>
<dest>
*: "Building database... %d found (OFF to return)"
h100,h120,h300: "Building database... %d found (STOP to return)"
ipod*: "Building database... %d found (PREV to return)"
x5,m5,gigabeat*,mrobe100: "Building database... %d found (LEFT to return)"
- h10,h10_5gb,e200,c200: "Building database... %d found (PREV to return)"
+ h10,h10_5gb,e200,c200,sa9200: "Building database... %d found (PREV to return)"
</dest>
<voice>
*: "entries found for database"
@@ -3891,17 +3894,17 @@
<source>
*: none
e200: "Wheel Light Timeout"
- c200,gigabeatf,mrobe100: "Button Light Timeout"
+ c200,gigabeatf,mrobe100,sa9200: "Button Light Timeout"
</source>
<dest>
*: none
e200: "Wheel Light Timeout"
- c200,gigabeatf,mrobe100: "Button Light Timeout"
+ c200,gigabeatf,mrobe100,sa9200: "Button Light Timeout"
</dest>
<voice>
*: none
e200: "Wheel Light Timeout"
- c200,gigabeatf,mrobe100: "Button Light Timeout"
+ c200,gigabeatf,mrobe100,sa9200: "Button Light Timeout"
</voice>
</phrase>
<phrase>
@@ -4183,17 +4186,17 @@
*: none
rtc: "ON = Set"
h100,h120,h300: "NAVI = Set"
- ipod*,x5,m5,h10,h10_5gb,e200,c200,gigabeat*,mrobe100: "SELECT = Set"
+ ipod*,x5,m5,h10,h10_5gb,e200,c200,gigabeat*,mrobe100,sa9200: "SELECT = Set"
</source>
<dest>
*: none
rtc: "ON = Set"
h100,h120,h300: "NAVI = Set"
- ipod*,x5,m5,h10,h10_5gb,e200,c200,gigabeat*,mrobe100: "SELECT = Set"
+ ipod*,x5,m5,h10,h10_5gb,e200,c200,gigabeat*,mrobe100,sa9200: "SELECT = Set"
</dest>
<voice>
*: none
- rtc,h100,h120,h300,h10,h10_5gb,x5,m5,ipod*,e200,c200,gigabeat*,mrobe100: ""
+ rtc,h100,h120,h300,h10,h10_5gb,x5,m5,ipod*,e200,c200,gigabeat*,mrobe100,sa9200: ""
</voice>
</phrase>
<phrase>
@@ -4204,7 +4207,7 @@
*: none
rtc: "OFF = Revert"
h100,h120,h300: "STOP = Revert"
- ipod*,e200,c200: "MENU = Revert"
+ ipod*,e200,c200,sa9200: "MENU = Revert"
x5,m5: "RECORD = Revert"
h10,h10_5gb: "PREV = Revert"
gigabeatf: "A = Revert"
@@ -4215,7 +4218,7 @@
*: none
rtc: "OFF = Revert"
h100,h120,h300: "STOP = Revert"
- ipod*,e200,c200: "MENU = Revert"
+ ipod*,e200,c200,sa9200: "MENU = Revert"
x5,m5: "RECORD = Revert"
h10,h10_5gb: "PREV = Revert"
gigabeatf: "A = Revert"
@@ -4224,7 +4227,7 @@
</dest>
<voice>
*: none
- rtc,h100,h120,h300,ipod*,e200,c200,x5,m5,h10,h10_gb,gigabeat*,mrobe100: ""
+ rtc,h100,h120,h300,ipod*,e200,c200,x5,m5,h10,h10_gb,gigabeat*,mrobe100,sa9200: ""
</voice>
</phrase>
<phrase>
diff --git a/apps/plugins/lib/pluginlib_actions.c b/apps/plugins/lib/pluginlib_actions.c
index a63ffb352a..6a008303da 100644
--- a/apps/plugins/lib/pluginlib_actions.c
+++ b/apps/plugins/lib/pluginlib_actions.c
@@ -84,7 +84,8 @@ const struct button_mapping generic_directions[] =
|| (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) \
|| (CONFIG_KEYPAD == SANSA_C200_PAD) \
|| (CONFIG_KEYPAD == GIGABEAT_S_PAD) \
- || (CONFIG_KEYPAD == MROBE100_PAD)
+ || (CONFIG_KEYPAD == MROBE100_PAD) \
+ || (CONFIG_KEYPAD == PHILIPS_SA9200_PAD)
{ PLA_UP, BUTTON_UP, BUTTON_NONE},
{ PLA_DOWN, BUTTON_DOWN, BUTTON_NONE},
{ PLA_LEFT, BUTTON_LEFT, BUTTON_NONE},
@@ -173,7 +174,8 @@ const struct button_mapping generic_left_right_fire[] =
|| (CONFIG_KEYPAD == GIGABEAT_PAD) \
|| (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) \
|| (CONFIG_KEYPAD == GIGABEAT_S_PAD) \
- || (CONFIG_KEYPAD == MROBE100_PAD)
+ || (CONFIG_KEYPAD == MROBE100_PAD) \
+ || (CONFIG_KEYPAD == PHILIPS_SA9200_PAD)
{ PLA_LEFT, BUTTON_LEFT, BUTTON_NONE},
{ PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE},
{ PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE},
@@ -381,6 +383,12 @@ const struct button_mapping generic_actions[] =
{PLA_MENU, BUTTON_RC_MENU, BUTTON_NONE},
{PLA_FIRE, BUTTON_RC_MODE, BUTTON_NONE},
{PLA_FIRE_REPEAT, BUTTON_RC_MODE|BUTTON_REPEAT, BUTTON_NONE},
+#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
+ {PLA_QUIT, BUTTON_POWER, BUTTON_NONE},
+ {PLA_START, BUTTON_RIGHT, BUTTON_NONE},
+ {PLA_MENU, BUTTON_MENU, BUTTON_NONE},
+ {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE},
+ {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE},
#else
#error pluginlib_actions: Unsupported keypad
#endif
@@ -404,7 +412,8 @@ const struct button_mapping generic_increase_decrease[] =
|| (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) \
|| (CONFIG_KEYPAD == ONDIO_PAD) \
|| (CONFIG_KEYPAD == GIGABEAT_S_PAD) \
- || (CONFIG_KEYPAD == MROBE100_PAD)
+ || (CONFIG_KEYPAD == MROBE100_PAD) \
+ || (CONFIG_KEYPAD == PHILIPS_SA9200_PAD)
{PLA_INC, BUTTON_UP, BUTTON_NONE},
{PLA_DEC, BUTTON_DOWN, BUTTON_NONE},
{PLA_INC_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE},
diff --git a/bootloader/SOURCES b/bootloader/SOURCES
index 40b2f5dc2a..c38b8ade1f 100644
--- a/bootloader/SOURCES
+++ b/bootloader/SOURCES
@@ -9,7 +9,7 @@ gigabeat-s.c
../firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \
defined(SANSA_E200) || defined(SANSA_C200) || \
- defined(MROBE_100)
+ defined(MROBE_100) || defined(PHILIPS_SA9200)
#ifdef E200R_INSTALLER
main-e200r-installer.c
#else
diff --git a/bootloader/common.c b/bootloader/common.c
index e6b8f5a7d2..66a60c5f6c 100644
--- a/bootloader/common.c
+++ b/bootloader/common.c
@@ -31,7 +31,8 @@
/* TODO: Other bootloaders need to be adjusted to set this variable to true
on a button press - currently only the ipod, H10 and Sansa versions do. */
#if defined(IPOD_ARCH) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) \
- || defined(SANSA_E200) || defined(SANSA_C200) || defined(GIGABEAT_F)
+ || defined(SANSA_E200) || defined(SANSA_C200) || defined(GIGABEAT_F) \
+ || defined(PHILIPS_SA9200)
bool verbose = false;
#else
bool verbose = true;
diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c
index 07222139e7..dee728d8ed 100644
--- a/bootloader/main-pp.c
+++ b/bootloader/main-pp.c
@@ -34,11 +34,11 @@
#include "crc32-mi4.h"
#include <string.h>
#include "power.h"
-#if defined(SANSA_E200)
+#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
#include "i2c.h"
#include "backlight-target.h"
#endif
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
#include "usb.h"
#include "usb_drv.h"
#endif
@@ -59,6 +59,8 @@ extern int show_logo(void);
#elif CONFIG_KEYPAD == MROBE100_PAD
#define BOOTLOADER_BOOT_OF BUTTON_POWER
+#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
+#define BOOTLOADER_BOOT_OF BUTTON_VOL_UP
#endif
/* Maximum allowed firmware image size. 10MB is more than enough */
@@ -71,7 +73,7 @@ unsigned char *loadbuffer = (unsigned char *)DRAM_START;
char version[] = APPSVERSION;
/* Locations and sizes in hidden partition on Sansa */
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(HAVE_ATA_SD)
#define PPMI_SECTOR_OFFSET 1024
#define PPMI_SECTORS 1
#define MI4_HEADER_SECTORS 1
@@ -351,7 +353,7 @@ int load_mi4(unsigned char* buf, char* firmware, unsigned int buffer_size)
return EOK;
}
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(HAVE_ATA_SD)
/* Load mi4 firmware from a hidden disk partition */
int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
unsigned int buffer_size, bool disable_rebuild)
@@ -432,7 +434,7 @@ void* main(void)
int rc;
int num_partitions;
struct partinfo* pinfo;
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
int usb_retry = 0;
bool usb = false;
#else
@@ -451,12 +453,11 @@ void* main(void)
show_logo();
button_init();
-#if defined(SANSA_E200)
+#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
i2c_init();
_backlight_on();
#endif
-
if (button_hold())
{
verbose = true;
@@ -466,7 +467,7 @@ void* main(void)
sleep(HZ);
power_off();
}
-
+
btn = button_read_device();
/* Enable bootloader messages if any button is pressed */
@@ -475,7 +476,7 @@ void* main(void)
verbose = true;
}
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
#if !defined(USE_ROCKBOX_USB)
usb_init();
while (usb_drv_powered() && usb_retry < 5 && !usb)
@@ -496,7 +497,7 @@ void* main(void)
printf(MODEL_NAME);
i=ata_init();
-#if !defined(SANSA_E200) && !defined(SANSA_C200)
+#if !defined(HAVE_ATA_SD)
if (i==0) {
identify_info=ata_get_identify();
/* Show model */
@@ -540,7 +541,7 @@ void* main(void)
*/
printf("Loading original firmware...");
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(HAVE_ATA_SD)
/* First try a (hidden) firmware partition */
printf("Trying firmware partition");
pinfo = disk_partinfo(1);
@@ -617,7 +618,7 @@ void* main(void)
return (void*)loadbuffer;
}
-#if !defined(SANSA_E200) && !defined(SANSA_C200)
+#if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(PHILIPS_SA9200)
/* These functions are present in the firmware library, but we reimplement
them here because the originals do a lot more than we want */
void usb_acknowledge(void)
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 0d7261632d..bbdd0bc5a2 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -118,7 +118,7 @@ drivers/ata_flash.c
drivers/ata.c
#endif /* HAVE_MMC */
drivers/fat.c
-#ifdef HAVE_HOTSWAP
+#if defined(HAVE_HOTSWAP) || defined(HAVE_ATA_SD)
hotswap.c
#endif
#endif /* SIMULATOR */
@@ -467,6 +467,20 @@ target/arm/sandisk/audio-c200_e200.c
#endif /* SIMULATOR */
#endif /* SANSA_C200 */
+#ifdef PHILIPS_SA9200
+#ifndef SIMULATOR
+target/arm/ata-sd-pp.c
+target/arm/philips/sa9200/lcd-sa9200.c
+target/arm/adc-as3514.c
+target/arm/philips/sa9200/backlight-sa9200.c
+target/arm/usb-fw-pp502x.c
+target/arm/philips/sa9200/button-sa9200.c
+target/arm/philips/sa9200/power-sa9200.c
+target/arm/philips/sa9200/powermgmt-sa9200.c
+target/arm/i2s-pp.c
+#endif /* SIMULATOR */
+#endif /* PHILIPS_SA9200 */
+
#ifdef IAUDIO_X5
#ifndef SIMULATOR
target/coldfire/ata-as-coldfire.S
diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c
index e1f325c3fe..b801375846 100644
--- a/firmware/drivers/audio/as3514.c
+++ b/firmware/drivers/audio/as3514.c
@@ -37,9 +37,11 @@ const struct sound_settings_info audiohw_settings[] = {
[SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
[SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
[SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
+#if defined(HAVE_RECORDING)
[SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 39, 23},
[SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23},
[SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23},
+#endif
};
/* Shadow registers */
@@ -112,11 +114,13 @@ int sound_val2phys(int setting, int value)
switch(setting)
{
+#if defined(HAVE_RECORDING)
case SOUND_LEFT_GAIN:
case SOUND_RIGHT_GAIN:
case SOUND_MIC_GAIN:
result = (value - 23) * 15;
break;
+#endif
default:
result = value;
@@ -292,6 +296,7 @@ void audiohw_set_sample_rate(int sampling_control)
(void)sampling_control;
}
+#if defined(HAVE_RECORDING)
void audiohw_enable_recording(bool source_mic)
{
if (source_mic) {
@@ -417,3 +422,4 @@ void audiohw_set_monitor(bool enable)
/* Sync mixer volume */
audiohw_set_master_vol(as3514.vol_l, as3514.vol_r);
}
+#endif /* HAVE_RECORDING */
diff --git a/firmware/export/as3514.h b/firmware/export/as3514.h
index f6f759b75c..6edb5878f3 100644
--- a/firmware/export/as3514.h
+++ b/firmware/export/as3514.h
@@ -77,7 +77,7 @@ extern void audiohw_set_sample_rate(int sampling_control);
#define VOLUME_MIN -735
#define VOLUME_MAX 60
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
#define AS3514_I2C_ADDR 0x46
#endif
diff --git a/firmware/export/config-sa9200.h b/firmware/export/config-sa9200.h
new file mode 100755
index 0000000000..9cdfe6bba7
--- /dev/null
+++ b/firmware/export/config-sa9200.h
@@ -0,0 +1,167 @@
+/*
+ * This config file is for the Philips GoGear SA9200
+ */
+#define TARGET_TREE /* this target is using the target tree system */
+
+/* For Rolo and boot loader */
+#define MODEL_NUMBER 26
+#define MODEL_NAME "Philips GoGear SA200"
+
+#define HW_SAMPR_CAPS (SAMPR_CAP_44)
+
+/* 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 want album art for this target */
+#define HAVE_ALBUMART
+
+/* define this if you have a light associated with the buttons */
+#define HAVE_BUTTON_LIGHT
+
+/* 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
+
+/* LCD dimensions */
+#define LCD_WIDTH 128
+#define LCD_HEIGHT 160
+#define LCD_DEPTH 16 /* 65536 colours */
+#define LCD_PIXELFORMAT RGB565 /* rgb565 */
+
+/* define this if you have LCD enable function */
+/* #define HAVE_LCD_ENABLE */
+
+/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE
+ should be defined as well. */
+/* #define HAVE_LCD_SLEEP */
+
+/* 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 IRAM_LCDFRAMEBUFFER IDATA_ATTR *//* put the lcd frame buffer in IRAM */
+
+#define CONFIG_KEYPAD PHILIPS_SA9200_PAD
+
+/* Define this if you do software codec */
+#define CONFIG_CODEC SWCODEC
+
+/* There is no hardware tone control */
+#define HAVE_SW_TONE_CONTROLS
+
+/* The PP5024 has a built-in AustriaMicrosystems AS3514 */
+#define HAVE_AS3514
+
+/* define this if you have a real-time clock */
+#ifndef BOOTLOADER
+#define CONFIG_RTC RTC_AS3514
+#endif
+
+/* Define this if you have a software controlled poweroff */
+#define HAVE_SW_POWEROFF
+
+/* Some Sansa E200s seem to be FAT16 formatted */
+#define HAVE_FAT16SUPPORT
+
+/* 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 for LCD backlight available */
+#define HAVE_BACKLIGHT
+#define HAVE_BACKLIGHT_BRIGHTNESS
+
+/* Main LCD backlight brightness range and defaults */
+#define MIN_BRIGHTNESS_SETTING 1
+#define MAX_BRIGHTNESS_SETTING 12
+#define DEFAULT_BRIGHTNESS_SETTING 6
+
+/* define this if you have a flash memory storage */
+#define HAVE_FLASH_STORAGE
+
+/* define this if the flash memory uses the SecureDigital Memory Card protocol */
+#define HAVE_ATA_SD
+
+#define BATTERY_CAPACITY_DEFAULT 750 /* default battery capacity */
+#define BATTERY_CAPACITY_MIN 750 /* min. capacity selectable */
+#define BATTERY_CAPACITY_MAX 750 /* max. capacity selectable */
+#define BATTERY_CAPACITY_INC 0 /* capacity increment */
+#define BATTERY_TYPES_COUNT 1 /* only one type */
+
+/* Hardware controlled charging? FIXME */
+#define CONFIG_CHARGING CHARGING_SIMPLE
+
+/* define this if the unit can be powered or charged via USB */
+#define HAVE_USB_POWER
+
+/** Non-simulator section **/
+#ifndef SIMULATOR
+
+/* Define this if you have a PortalPlayer PP5024 */
+#define CONFIG_CPU PP5024
+
+/* Define this if you want to use the PP5024 i2c interface */
+#define CONFIG_I2C I2C_PP5024
+
+/* define this if the hardware can be powered off while charging */
+/* Sansa can't be powered off while charging */
+/* #define HAVE_POWEROFF_WHILE_CHARGING */
+
+/* The start address index for ROM builds */
+#define ROM_START 0x00000000
+
+/* Define this to the CPU frequency */
+#define CPU_FREQ 75000000
+
+/* Type of LCD TODO: hopefully the same as the x5 but check this*/
+#define CONFIG_LCD LCD_SA9200
+
+/* #define USB_IPODSTYLE */
+
+/* USB On-the-go */
+#define CONFIG_USBOTG USBOTG_ARC
+
+/* enable these for the experimental usb stack */
+#define HAVE_USBSTACK
+#define USB_VENDOR_ID 0x0471
+#define USB_PRODUCT_ID 0x014f
+
+/* WARNING! Enable Rockbox USB mass storage. */
+#ifndef BOOTLOADER
+#define USE_ROCKBOX_USB
+#endif
+
+/* Virtual LED (icon) */
+#define CONFIG_LED LED_VIRTUAL
+
+/* Define this if you have adjustable CPU frequency */
+#define HAVE_ADJUSTABLE_CPU_FREQ
+
+#define MI4_FORMAT
+#define BOOTFILE_EXT "mi4"
+#define BOOTFILE "rockbox." BOOTFILE_EXT
+#define BOOTDIR "/.rockbox"
+
+/* These values are unused, but need to be defined */
+#define FIRMWARE_OFFSET_FILE_CRC 0x0
+#define FIRMWARE_OFFSET_FILE_DATA 0x8
+
+#define ICODE_ATTR_TREMOR_NOT_MDCT
+
+#define INCLUDE_TIMEOUT_API
+
+#endif /* SIMULATOR */
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 51c79abccf..c200355872 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -82,6 +82,7 @@
#define CREATIVEZVM_PAD 24
#define SANSA_M200_PAD 25
#define CREATIVEZV_PAD 26
+#define PHILIPS_SA9200_PAD 27
/* CONFIG_REMOTE_KEYPAD */
#define H100_REMOTE 1
@@ -120,6 +121,7 @@
#define LCD_CREATIVEZVM 22 /* as used by Creative Zen Vision:M */
#define LCD_TL0350A 23 /* as used by the iAudio M3 remote, treated as main LCD */
#define LCD_COWOND2 24 /* as used by Cowon D2 - LTV250QV, TCC7801 driver */
+#define LCD_SA9200 25 /* as used by the Philips SA9200 */
/* LCD_PIXELFORMAT */
#define HORIZONTAL_PACKING 1
@@ -258,6 +260,8 @@
#include "config-creativezvm60gb.h"
#elif defined(CREATIVE_ZV)
#include "config-creativezv.h"
+#elif defined(PHILIPS_SA9200)
+#include "config-sa9200.h"
#else
/* no known platform */
#endif
diff --git a/firmware/export/usb.h b/firmware/export/usb.h
index ff1f55cd35..0590f702c5 100644
--- a/firmware/export/usb.h
+++ b/firmware/export/usb.h
@@ -60,7 +60,8 @@ enum {
#define USBPOWER_BUTTON BUTTON_RIGHT
#define USBPOWER_BTN_IGNORE BUTTON_POWER
#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
- (CONFIG_KEYPAD == SANSA_C200_PAD)
+ (CONFIG_KEYPAD == SANSA_C200_PAD) || \
+ (CONFIG_KEYPAD == PHILIPS_SA9200_PAD)
#define USBPOWER_BUTTON BUTTON_SELECT
#define USBPOWER_BTN_IGNORE BUTTON_POWER
#endif
diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c
index e4ab922f24..797a9f8e36 100644
--- a/firmware/target/arm/ata-sd-pp.c
+++ b/firmware/target/arm/ata-sd-pp.c
@@ -526,7 +526,7 @@ static int sd_select_bank(unsigned char bank)
static void sd_card_mux(int card_no)
{
/* Set the current card mux */
-#ifdef SANSA_E200
+#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
if (card_no == 0)
{
GPO32_VAL |= 0x4;
diff --git a/firmware/target/arm/i2c-pp.c b/firmware/target/arm/i2c-pp.c
index 5799d7c37f..7dbd223ddf 100644
--- a/firmware/target/arm/i2c-pp.c
+++ b/firmware/target/arm/i2c-pp.c
@@ -209,7 +209,7 @@ void i2c_init(void)
outl(0x0, 0x600060a4);
outl(0x80 | (0 << 8), 0x600060a4);
#elif CONFIG_I2C == I2C_PP5024
-#ifdef SANSA_E200
+#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
/* Sansa OF sets this to 0x20 first, communicates with the AS3514
then sets it to 0x23 - this still works fine though */
outl(0x0, 0x600060a4);
diff --git a/firmware/target/arm/philips/app.lds b/firmware/target/arm/philips/app.lds
new file mode 100644
index 0000000000..d7159e8e1e
--- /dev/null
+++ b/firmware/target/arm/philips/app.lds
@@ -0,0 +1,198 @@
+#include "config.h"
+
+ENTRY(start)
+
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(target/arm/crt0-pp.o)
+
+#define PLUGINSIZE PLUGIN_BUFFER_SIZE
+#define CODECSIZE CODEC_SIZE
+
+#ifdef DEBUG
+#define STUBOFFSET 0x10000
+#else
+#define STUBOFFSET 0
+#endif
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - STUBOFFSET - CODECSIZE
+
+#define DRAMORIG 0x00000000 + STUBOFFSET
+#define IRAMORIG 0x40000000
+#define IRAMSIZE 0xc000
+
+#ifdef CPU_PP502x
+#define NOCACHE_BASE 0x10000000
+#else
+#define NOCACHE_BASE 0x28000000
+#endif
+
+#define CACHEALIGN_SIZE 16
+
+/* End of the audio buffer, where the codec buffer starts */
+#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
+
+/* Where the codec buffer ends, and the plugin buffer starts */
+#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
+
+MEMORY
+{
+ DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+}
+
+SECTIONS
+{
+ .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
+
+#if NOCACHE_BASE != 0
+ /* .ncdata section is placed at uncached physical alias address and is
+ * loaded at the proper cached virtual address - no copying is
+ * performed in the init code */
+ .ncdata . + NOCACHE_BASE :
+ {
+ . = ALIGN(CACHEALIGN_SIZE);
+ *(.ncdata*)
+ . = ALIGN(CACHEALIGN_SIZE);
+ } AT> DRAM
+#endif
+
+ /DISCARD/ :
+ {
+ *(.eh_frame)
+ }
+
+ .vectors 0x0 :
+ {
+ _vectorsstart = .;
+ *(.vectors);
+ _vectorsend = .;
+ } AT> DRAM
+
+ _vectorscopy = LOADADDR(.vectors);
+
+ .ibss IRAMORIG (NOLOAD) :
+ {
+ _iedata = .;
+ *(.qharray)
+ *(.ibss)
+ . = ALIGN(0x4);
+ _iend = .;
+ } > IRAM
+
+ .iram _iend :
+ {
+ _iramstart = .;
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ . = ALIGN(0x4);
+ _iramend = .;
+ } > IRAM AT> DRAM
+
+ _iramcopy = LOADADDR(.iram);
+
+ .idle_stacks (NOLOAD) :
+ {
+ *(.idle_stacks)
+#if NUM_CORES > 1
+ cpu_idlestackbegin = .;
+ . += IDLE_STACK_SIZE;
+ cpu_idlestackend = .;
+#endif
+ cop_idlestackbegin = .;
+ . += IDLE_STACK_SIZE;
+ cop_idlestackend = .;
+ } > IRAM
+
+ .stack (NOLOAD) :
+ {
+ *(.stack)
+ stackbegin = .;
+ . += 0x2000;
+ stackend = .;
+ } > IRAM
+
+ /* .bss and .ncbss are treated as a single section to use one init loop to
+ * zero it - note "_edata" and "_end" */
+ .bss ADDR(.data) + SIZEOF(.data) + SIZEOF(.ncdata) +\
+ SIZEOF(.iram) + SIZEOF(.vectors) (NOLOAD) :
+ {
+ _edata = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(0x4);
+ } > DRAM
+
+#if NOCACHE_BASE != 0
+ .ncbss . + NOCACHE_BASE (NOLOAD):
+ {
+ . = ALIGN(CACHEALIGN_SIZE);
+ *(.ncbss*)
+ . = ALIGN(CACHEALIGN_SIZE);
+ } AT> DRAM
+#endif
+
+ /* This will be aligned by preceding alignments */
+ .endaddr . - NOCACHE_BASE (NOLOAD) :
+ {
+ _end = .;
+ } > DRAM
+
+ .audiobuf (NOLOAD) :
+ {
+ _audiobuffer = .;
+ audiobuffer = .;
+ } > DRAM
+
+ .audiobufend ENDAUDIOADDR (NOLOAD) :
+ {
+ audiobufend = .;
+ _audiobufend = .;
+ } > DRAM
+
+ .codec ENDAUDIOADDR (NOLOAD) :
+ {
+ codecbuf = .;
+ _codecbuf = .;
+ }
+
+ .plugin ENDADDR (NOLOAD) :
+ {
+ _pluginbuf = .;
+ pluginbuf = .;
+ }
+}
diff --git a/firmware/target/arm/philips/boot.lds b/firmware/target/arm/philips/boot.lds
new file mode 100644
index 0000000000..d115aa5949
--- /dev/null
+++ b/firmware/target/arm/philips/boot.lds
@@ -0,0 +1,65 @@
+#include "config.h"
+
+ENTRY(start)
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(target/arm/crt0-pp-bl.o)
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000)
+
+#define DRAMORIG 0x10000000
+#ifndef IRAMORIG
+#define IRAMORIG 0x40000000
+#endif
+#define IRAMSIZE 0x20000
+#define FLASHORIG 0x001f0000
+#define FLASHSIZE 2M
+
+MEMORY
+{
+ DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+}
+
+SECTIONS
+{
+ . = IRAMORIG;
+
+ .text : {
+ *(.init.text)
+ *(.text*)
+ *(.glue_7)
+ *(.glue_7t)
+ } > IRAM
+
+ .data : {
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ *(.data*)
+ *(.ncdata*)
+ *(.rodata*)
+ _dataend = . ;
+ } > IRAM
+
+ .stack : {
+ *(.stack)
+ _stackbegin = .;
+ stackbegin = .;
+ . += 0x2000;
+ _stackend = .;
+ stackend = .;
+ } > IRAM
+
+ /* The bss section is too large for IRAM - we just move it 16MB into the
+ DRAM */
+
+ . = DRAMORIG;
+ .bss . + (16*1024*1024) : {
+ _edata = .;
+ *(.bss*);
+ *(.ibss);
+ *(.ncbss*);
+ _end = .;
+ } > DRAM
+}
diff --git a/firmware/target/arm/philips/sa9200/adc-target.h b/firmware/target/arm/philips/sa9200/adc-target.h
new file mode 100644
index 0000000000..56efdf7574
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/adc-target.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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_
+
+/* ADC channels */
+#define NUM_ADC_CHANNELS 13
+
+#define ADC_BVDD 0 /* Battery voltage of 4V LiIo accumulator */
+#define ADC_RTCSUP 1 /* RTC backup battery voltage */
+#define ADC_UVDD 2 /* USB host voltage */
+#define ADC_CHG_IN 3 /* Charger input voltage */
+#define ADC_CVDD 4 /* Charger pump output voltage */
+#define ADC_BATTEMP 5 /* Battery charging temperature */
+#define ADC_MICSUP1 6 /* Voltage on MicSup1 for remote control
+ or external voltage measurement */
+#define ADC_MICSUP2 7 /* Voltage on MicSup1 for remote control
+ or external voltage measurement */
+#define ADC_VBE1 8 /* Measuring junction temperature @ 2uA */
+#define ADC_VBE2 9 /* Measuring junction temperature @ 1uA */
+#define ADC_I_MICSUP1 10 /* Current of MicSup1 for remote control detection */
+#define ADC_I_MICSUP2 11 /* Current of MicSup2 for remote control detection */
+#define ADC_VBAT 12 /* Single cell battery voltage */
+
+#define ADC_UNREG_POWER ADC_BVDD /* For compatibility */
+
+#endif
diff --git a/firmware/target/arm/philips/sa9200/backlight-sa9200.c b/firmware/target/arm/philips/sa9200/backlight-sa9200.c
new file mode 100644
index 0000000000..aaec8cf007
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/backlight-sa9200.c
@@ -0,0 +1,75 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 "backlight-target.h"
+#include "system.h"
+#include "lcd.h"
+#include "backlight.h"
+#include "i2c-pp.h"
+#include "as3514.h"
+
+static unsigned short backlight_brightness = DEFAULT_BRIGHTNESS_SETTING;
+
+void _backlight_set_brightness(int brightness)
+{
+ backlight_brightness = brightness;
+
+ if (brightness > 0)
+ _backlight_on();
+ else
+ _backlight_off();
+}
+
+void _backlight_on(void)
+{
+#ifdef HAVE_LCD_SLEEP
+ backlight_lcd_sleep_countdown(false); /* stop counter */
+#endif
+#ifdef HAVE_LCD_ENABLE
+ lcd_enable(true); /* power on lcd + visible display */
+#endif
+ pp_i2c_send(AS3514_I2C_ADDR, AS3514_DCDC15, backlight_brightness);
+}
+
+void _backlight_off(void)
+{
+ pp_i2c_send(AS3514_I2C_ADDR, AS3514_DCDC15, 0x0);
+#ifdef HAVE_LCD_ENABLE
+ lcd_enable(false); /* power off visible display */
+#endif
+#ifdef HAVE_LCD_SLEEP
+ backlight_lcd_sleep_countdown(true); /* start countdown */
+#endif
+}
+
+void _buttonlight_on(void)
+{
+ GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, 0x80);
+#ifdef SANSA_C200
+ GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x10); /* The "menu" backlight */
+#endif
+}
+
+void _buttonlight_off(void)
+{
+ GPIO_CLEAR_BITWISE(GPIOG_OUTPUT_VAL, 0x80);
+#ifdef SANSA_C200
+ GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x10); /* The "menu" backlight */
+#endif
+}
diff --git a/firmware/target/arm/philips/sa9200/backlight-target.h b/firmware/target/arm/philips/sa9200/backlight-target.h
new file mode 100644
index 0000000000..01573b8403
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/backlight-target.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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
+
+#define _backlight_init() true
+void _backlight_on(void);
+void _backlight_off(void);
+void _backlight_set_brightness(int brightness);
+int __backlight_is_on(void);
+
+void _buttonlight_on(void);
+void _buttonlight_off(void);
+#endif
diff --git a/firmware/target/arm/philips/sa9200/button-sa9200.c b/firmware/target/arm/philips/sa9200/button-sa9200.c
new file mode 100755
index 0000000000..dc9f3466c2
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/button-sa9200.c
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Mark Arigo
+ *
+ * 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 "button.h"
+#include "backlight.h"
+
+void button_init_device(void)
+{
+ /* TODO...for now, hardware initialisation is done by the c200 bootloader */
+}
+
+bool button_hold(void)
+{
+ return !(GPIOL_INPUT_VAL & 0x40);
+}
+
+/*
+ * Get button pressed from hardware
+ */
+int button_read_device(void)
+{
+ int btn = BUTTON_NONE;
+ static bool hold_button = false;
+ bool hold_button_old;
+
+ /* Hold */
+ hold_button_old = hold_button;
+ hold_button = button_hold();
+
+#ifndef BOOTLOADER
+ if (hold_button != hold_button_old)
+ backlight_hold_changed(hold_button);
+#endif
+
+ /* device buttons */
+ if (!hold_button)
+ {
+#if 0
+ if (!(GPIOB_INPUT_VAL & 0x20)) btn |= BUTTON_POWER;
+ if (!(GPIOF_INPUT_VAL & 0x10)) btn |= BUTTON_VOL_UP;
+ if (!(GPIOF_INPUT_VAL & 0x04)) btn |= BUTTON_VOL_DOWN;
+#endif
+ /* A hack until the touchpad works */
+ if (!(GPIOB_INPUT_VAL & 0x20)) btn |= BUTTON_SELECT;
+ if (!(GPIOF_INPUT_VAL & 0x10)) btn |= BUTTON_UP;
+ if (!(GPIOF_INPUT_VAL & 0x04)) btn |= BUTTON_DOWN;
+ }
+
+ return btn;
+}
+
+bool headphones_inserted(void)
+{
+ return (GPIOB_INPUT_VAL & 0x10) ? false : true;
+}
diff --git a/firmware/target/arm/philips/sa9200/button-target.h b/firmware/target/arm/philips/sa9200/button-target.h
new file mode 100755
index 0000000000..1cd6e52097
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/button-target.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2007 by Mark Arigo
+ *
+ * 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"
+
+#define HAS_BUTTON_HOLD
+
+bool button_hold(void);
+void button_init_device(void);
+int button_read_device(void);
+
+/* Main unit's buttons */
+#define BUTTON_POWER 0x00000001
+#define BUTTON_SELECT 0x00000002
+#define BUTTON_MENU 0x00000004
+#define BUTTON_LEFT 0x00000008
+#define BUTTON_RIGHT 0x00000010
+#define BUTTON_REW 0x00000020
+#define BUTTON_FFWD 0x00000040
+#define BUTTON_UP 0x00000080
+#define BUTTON_DOWN 0x00000100
+#define BUTTON_VOL_UP 0x00000200
+#define BUTTON_VOL_DOWN 0x00000400
+
+#define BUTTON_MAIN 0x00000fff
+
+/* No Remote control */
+#define BUTTON_REMOTE 0
+
+#define POWEROFF_BUTTON BUTTON_POWER
+#define POWEROFF_COUNT 10
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/philips/sa9200/lcd-sa9200.c b/firmware/target/arm/philips/sa9200/lcd-sa9200.c
new file mode 100755
index 0000000000..b06dcd952b
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/lcd-sa9200.c
@@ -0,0 +1,205 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Mark Arigo
+ *
+ * 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 "lcd.h"
+#include "kernel.h"
+#include "system.h"
+
+/* Display status */
+static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
+
+/* wait for LCD */
+static inline void lcd_wait_write(void)
+{
+ while (LCD1_CONTROL & LCD1_BUSY_MASK);
+}
+
+/* send LCD data */
+static void lcd_send_data(unsigned data)
+{
+ lcd_wait_write();
+ LCD1_DATA = data >> 8;
+ lcd_wait_write();
+ LCD1_DATA = data & 0xff;
+}
+
+/* send LCD command */
+static void lcd_send_command(unsigned cmd)
+{
+ lcd_wait_write();
+ LCD1_CMD = cmd >> 8;
+ lcd_wait_write();
+ LCD1_CMD = cmd & 0xff;
+}
+
+static void lcd_write_reg(unsigned reg, unsigned data)
+{
+ lcd_send_command(reg);
+ lcd_send_data(data);
+}
+
+void lcd_init_device(void)
+{
+#if 0
+ /* This is the init done by the OF bootloader.
+ Re-initializing the lcd causes it to flash
+ a white screen, so for now disable this. */
+ DEV_INIT1 &= ~0x3000;
+ DEV_INIT1 = DEV_INIT1;
+ DEV_INIT2 &= ~0x400;
+
+ LCD1_CONTROL = 0x4680;
+ udelay(1500);
+ LCD1_CONTROL = 0x4684;
+
+ outl(1, 0x70003018);
+
+ LCD1_CONTROL &= ~0x200;
+ LCD1_CONTROL &= ~0x800;
+ LCD1_CONTROL &= ~0x400;
+ udelay(30000);
+
+ LCD1_CONTROL |= 0x1;
+
+ lcd_write_reg(0x0000, 0x0001);
+ udelay(50000);
+
+ lcd_write_reg(0x0011, 0x171f);
+ lcd_write_reg(0x0012, 0x0001);
+ lcd_write_reg(0x0013, 0x08cd);
+ lcd_write_reg(0x0014, 0x0416);
+ lcd_write_reg(0x0010, 0x1208);
+ udelay(50000);
+
+ lcd_write_reg(0x0013, 0x081C);
+ udelay(200000);
+
+ lcd_write_reg(0x0001, 0x0a0c);
+ lcd_write_reg(0x0002, 0x0200);
+ lcd_write_reg(0x0003, 0x1030);
+ lcd_write_reg(0x0007, 0x0005);
+ lcd_write_reg(0x0008, 0x030a);
+ lcd_write_reg(0x000b, 0x0000);
+ lcd_write_reg(0x000c, 0x0000);
+ lcd_write_reg(0x0030, 0x0000);
+ lcd_write_reg(0x0031, 0x0204);
+ lcd_write_reg(0x0032, 0x0001);
+ lcd_write_reg(0x0033, 0x0600);
+ lcd_write_reg(0x0034, 0x0607);
+ lcd_write_reg(0x0035, 0x0305);
+ lcd_write_reg(0x0036, 0x0707);
+ lcd_write_reg(0x0037, 0x0006);
+ lcd_write_reg(0x0038, 0x0400);
+ lcd_write_reg(0x0040, 0x0000);
+ lcd_write_reg(0x0042, 0x9f00);
+ lcd_write_reg(0x0043, 0x0000);
+ lcd_write_reg(0x0044, 0x7f00);
+ lcd_write_reg(0x0045, 0x9f00);
+ lcd_write_reg(0x00a8, 0x0125);
+ lcd_write_reg(0x00a9, 0x0014);
+ lcd_write_reg(0x00a7, 0x0022);
+
+ lcd_write_reg(0x0007, 0x0021);
+ udelay(40000);
+ lcd_write_reg(0x0007, 0x0023);
+ udelay(40000);
+ lcd_write_reg(0x0007, 0x1037);
+
+ lcd_write_reg(0x0021, 0x0000);
+#endif
+}
+
+/*** hardware configuration ***/
+#if 0
+int lcd_default_contrast(void)
+{
+ return DEFAULT_CONTRAST_SETTING;
+}
+#endif
+
+void lcd_set_contrast(int val)
+{
+ (void)val;
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+ (void)yesno;
+}
+
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+ (void)yesno;
+}
+
+void lcd_yuv_set_options(unsigned options)
+{
+ lcd_yuv_options = options;
+}
+
+/* Performance function to blit a YUV bitmap directly to the LCD */
+void lcd_blit_yuv(unsigned char * const src[3],
+ int src_x, int src_y, int stride,
+ int x, int y, int width, int height)
+{
+ (void)src;
+ (void)src_x;
+ (void)src_y;
+ (void)stride;
+ (void)x;
+ (void)y;
+ (void)width;
+ (void)height;
+}
+
+/* Update the display.
+ This must be called after all other LCD functions that change the display. */
+void lcd_update(void)
+{
+ lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+}
+
+/* Update a fraction of the display. */
+void lcd_update_rect(int x, int y, int width, int height)
+{
+ const fb_data *addr;
+
+ if (x + width >= LCD_WIDTH)
+ width = LCD_WIDTH - x;
+ if (y + height >= LCD_HEIGHT)
+ height = LCD_HEIGHT - y;
+
+ if ((width <= 0) || (height <= 0))
+ return; /* Nothing left to do. */
+
+ addr = &lcd_framebuffer[y][x];
+
+ do {
+ lcd_write_reg(0x0021, ((y++ & 0xff) << 8) | (x & 0xff));
+ lcd_send_command(0x0022);
+
+ int w = width;
+ do {
+ lcd_send_data(*addr++);
+ } while (--w > 0);
+ addr += LCD_WIDTH - width;
+ } while (--height > 0);
+}
diff --git a/firmware/target/arm/philips/sa9200/power-sa9200.c b/firmware/target/arm/philips/sa9200/power-sa9200.c
new file mode 100644
index 0000000000..8c8214a7ce
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/power-sa9200.c
@@ -0,0 +1,136 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Daniel Ankers
+ *
+ * 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 <stdbool.h>
+#include "system.h"
+#include "cpu.h"
+#include "i2c-pp.h"
+#include "tuner.h"
+#include "as3514.h"
+#include "power.h"
+
+void power_init(void)
+{
+}
+
+void power_off(void)
+{
+ char byte;
+
+ /* Send shutdown command to PMU */
+ byte = i2c_readbyte(AS3514_I2C_ADDR, AS3514_SYSTEM);
+ byte &= ~0x1;
+ pp_i2c_send(AS3514_I2C_ADDR, AS3514_SYSTEM, byte);
+
+ /* Stop interrupts on both cores */
+ disable_interrupt(IRQ_FIQ_STATUS);
+ COP_INT_CLR = -1;
+ CPU_INT_CLR = -1;
+
+ /* Halt everything and wait for device to power off */
+ while (1)
+ {
+ COP_CTL = 0x40000000;
+ CPU_CTL = 0x40000000;
+ }
+}
+
+bool charger_inserted(void)
+{
+#ifdef SANSA_E200
+ if(GPIOB_INPUT_VAL & 0x10)
+#else /* SANSA_C200 */
+ if(GPIOH_INPUT_VAL & 0x2)
+#endif
+ return true;
+ return false;
+}
+
+void ide_power_enable(bool on)
+{
+ (void)on;
+}
+
+#if CONFIG_TUNER
+
+/** Tuner **/
+static bool powered = false;
+
+bool tuner_power(bool status)
+{
+ bool old_status;
+ lv24020lp_lock();
+
+ old_status = powered;
+
+ if (status != old_status)
+ {
+ if (status)
+ {
+ /* init mystery amplification device */
+#if defined(SANSA_E200)
+ GPO32_ENABLE |= 0x1;
+#else /* SANSA_C200 */
+ DEV_INIT2 &= ~0x800;
+#endif
+ udelay(5);
+
+ /* When power up, host should initialize the 3-wire bus
+ in host read mode: */
+
+ /* 1. Set direction of the DATA-line to input-mode. */
+ GPIOH_OUTPUT_EN &= ~(1 << 5);
+ GPIOH_ENABLE |= (1 << 5);
+
+ /* 2. Drive NR_W low */
+ GPIOH_OUTPUT_VAL &= ~(1 << 3);
+ GPIOH_OUTPUT_EN |= (1 << 3);
+ GPIOH_ENABLE |= (1 << 3);
+
+ /* 3. Drive CLOCK high */
+ GPIOH_OUTPUT_VAL |= (1 << 4);
+ GPIOH_OUTPUT_EN |= (1 << 4);
+ GPIOH_ENABLE |= (1 << 4);
+
+ lv24020lp_power(true);
+ }
+ else
+ {
+ lv24020lp_power(false);
+
+ /* set all as inputs */
+ GPIOH_OUTPUT_EN &= ~((1 << 5) | (1 << 3) | (1 << 4));
+ GPIOH_ENABLE &= ~((1 << 3) | (1 << 4));
+
+ /* turn off mystery amplification device */
+#if defined (SANSA_E200)
+ GPO32_ENABLE &= ~0x1;
+#else
+ DEV_INIT2 |= 0x800;
+#endif
+ }
+
+ powered = status;
+ }
+
+ lv24020lp_unlock();
+ return old_status;
+}
+
+#endif /* CONFIG_TUNER */
diff --git a/firmware/target/arm/philips/sa9200/powermgmt-sa9200.c b/firmware/target/arm/philips/sa9200/powermgmt-sa9200.c
new file mode 100644
index 0000000000..9bb70263be
--- /dev/null
+++ b/firmware/target/arm/philips/sa9200/powermgmt-sa9200.c
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
+ * Revisions copyright (C) 2005 by Gerald Van Baren
+ *
+ * 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"
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+ 3400
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+ 3300
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+ /* Sansa Li Ion 750mAH, took from battery benchs */
+ { 3300, 3680, 3740, 3760, 3780, 3810, 3870, 3930, 3970, 4070, 4160 },
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+ /* Sansa Li Ion 750mAH FIXME */
+ 3300, 3680, 3740, 3760, 3780, 3810, 3870, 3930, 3970, 4070, 4160
+};
+
+/* ADC should read 0x3ff=5.12V */
+#define BATTERY_SCALE_FACTOR 5125
+/* full-scale ADC readout (2^10) in millivolt */
+
+/* Returns battery voltage from ADC [millivolts] */
+unsigned int battery_adc_voltage(void)
+{
+ return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
+}
+
diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c
index 4e3f2c0cf0..f74b0484ab 100644
--- a/firmware/target/arm/system-pp502x.c
+++ b/firmware/target/arm/system-pp502x.c
@@ -374,7 +374,7 @@ void system_init(void)
/* to be done */
#endif
-#if !defined(SANSA_E200) && !defined(SANSA_C200)
+#if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(PHILIPS_SA9200)
/* Remap the flash ROM on CPU, keep hidden from COP:
* 0x00000000-0x3fffffff = 0x20000000-0x23ffffff */
MMAP1_LOGICAL = 0x20003c00;
@@ -405,7 +405,7 @@ void system_init(void)
GPIOK_INT_EN = 0;
GPIOL_INT_EN = 0;
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
/* outl(0x00000000, 0x6000b000); */
outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */
#endif
@@ -433,7 +433,7 @@ void system_init(void)
void system_reboot(void)
{
/* Reboot */
-#if defined(SANSA_E200) || defined(SANSA_C200)
+#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
CACHE_CTL &= ~CACHE_CTL_VECT_REMAP;
/* Magic used by the c200 OF: 0x23066000
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c
index 18ef3d234e..eae78886f4 100644
--- a/firmware/target/arm/usb-fw-pp502x.c
+++ b/firmware/target/arm/usb-fw-pp502x.c
@@ -121,6 +121,11 @@ static bool usb_pin_detect(void)
/* GPIO L bit 2 is usb detect */
if (GPIOL_INPUT_VAL & 0x4)
retval = true;
+
+#elif defined(PHILIPS_SA9200)
+ /* GPIO F bit 7 is usb detect */
+ if (!(GPIOF_INPUT_VAL & 0x80))
+ retval = true;
#endif
return retval;
diff --git a/tools/configure b/tools/configure
index 7fffcfdb6a..324e7a3cc2 100755
--- a/tools/configure
+++ b/tools/configure
@@ -676,8 +676,9 @@ cat <<EOF
==Tatung== ==Olympus== ==Logik==
60) Elio TPJ-1022 70) M:Robe 500 80) DAX 1GB MP3/DAB
71) M:Robe 100
- ==Creative==
- 90) Zen Vision:M 30GB
+
+ ==Creative== ==Philips==
+ 90) Zen Vision:M 30GB 100) GoGear SA9200
91) Zen Vision:M 60GB
92) Zen Vision
@@ -1651,6 +1652,30 @@ fi
t_model="tpj1022"
;;
+ 100|sa9200)
+ target_id=41
+ modelname="sa9200"
+ target="-DPHILIPS_SA9200"
+ memory=32 # supposedly
+ arm7tdmicc
+ tool="$rootdir/tools/scramble -mi4v3 -model=9200 -type=RBOS"
+ bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
+ bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
+ output="rockbox.mi4"
+ appextra="recorder:gui"
+ plugins=""
+ swcodec="yes"
+ boottool="$rootdir/tools/scramble -mi4v3 -model=9200 -type=RBBL"
+ bootoutput="FWImage.ebn"
+ # toolset is the tools within the tools directory that we build for
+ # this particular target.
+ toolset="$genericbitmaptools scramble"
+ # architecture, manufacturer and model for the target-tree build
+ t_cpu="arm"
+ t_manufacturer="philips"
+ t_model="sa9200"
+ ;;
+
*)
echo "Please select a supported target platform!"
exit
diff --git a/tools/scramble.c b/tools/scramble.c
index 3730f1b62a..c02c78916b 100644
--- a/tools/scramble.c
+++ b/tools/scramble.c
@@ -119,7 +119,8 @@ void usage(void)
"\t-add=X Rockbox generic \"add-up\" checksum format\n"
"\t (X values: h100, h120, h140, h300, ipco, nano, ipvd, mn2g\n"
"\t ip3g, ip4g, mini, iax5, iam5, iam3, h10, h10_5gb,\n"
- "\t tpj2, c200, e200, giga, gigs, m100, m500, d2)\n");
+ "\t tpj2, c200, e200, giga, gigs, m100, m500, d2,\n");
+ printf("\t 9200)\n");
printf("\nNo option results in Archos standard player/recorder format.\n");
exit(1);
@@ -271,6 +272,8 @@ int main (int argc, char** argv)
modelnum = 24;
else if(!strcmp(&argv[1][5], "iam3"))
modelnum = 25;
+ else if(!strcmp(&argv[1][5], "9200")) /* Philips SA9200 */
+ modelnum = 26;
else {
fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
return 2;