Added HiFiMAN HM-801 target. FS#12355. This also renames tda1543.{ch} used by HM-60x to dummy_codec.{ch} as it works for PCM1704 used by HM-801.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30891 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/SOURCES b/apps/SOURCES
index 78a1bfe..0734d34 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -327,5 +327,7 @@
 keymaps/keymap-rk27xx-generic.c
 #elif CONFIG_KEYPAD == HM60X_PAD
 keymaps/keymap-hm60x.c
+#elif CONFIG_KEYPAD == HM801_PAD
+keymaps/keymap-hm801.c
 #endif
 
diff --git a/apps/keymaps/keymap-hm801.c b/apps/keymaps/keymap-hm801.c
new file mode 100644
index 0000000..78221e5
--- /dev/null
+++ b/apps/keymaps/keymap-hm801.c
@@ -0,0 +1,108 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2011 Andrew Ryabinin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+/* Button Code Definitions for HiFiMAN HM-801 reference design target */
+
+#include "config.h"
+#include "action.h"
+#include "button.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_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_CONTEXT,    BUTTON_PLAY|BUTTON_REPEAT,    BUTTON_PLAY },
+    { ACTION_STD_CONTEXT,    BUTTON_SELECT|BUTTON_REPEAT,  BUTTON_SELECT },
+    { ACTION_STD_CANCEL,     BUTTON_LEFT,                  BUTTON_NONE },
+    { ACTION_STD_OK,         BUTTON_PLAY|BUTTON_REL,       BUTTON_PLAY },
+    { ACTION_STD_OK,         BUTTON_SELECT|BUTTON_REL,     BUTTON_SELECT },
+    { ACTION_STD_MENU,       BUTTON_RIGHT,                 BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST
+}; /* button_context_standard */
+
+static const struct button_mapping button_context_wps[]  = {
+    { ACTION_WPS_PLAY,      BUTTON_SELECT|BUTTON_REL,       BUTTON_SELECT},
+    { ACTION_WPS_STOP,      BUTTON_SELECT|BUTTON_REPEAT,    BUTTON_SELECT},
+    { ACTION_WPS_SKIPPREV,  BUTTON_LEFT|BUTTON_REL,         BUTTON_LEFT },
+    { ACTION_WPS_SEEKBACK,  BUTTON_LEFT|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,  BUTTON_LEFT|BUTTON_REL,         BUTTON_LEFT|BUTTON_REPEAT },
+    { ACTION_WPS_SKIPNEXT,  BUTTON_RIGHT|BUTTON_REL,        BUTTON_RIGHT},
+    { ACTION_WPS_SEEKFWD,   BUTTON_RIGHT|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,  BUTTON_RIGHT|BUTTON_REL,        BUTTON_RIGHT|BUTTON_REPEAT },
+
+    { ACTION_WPS_PLAY,      BUTTON_PLAY|BUTTON_REL,         BUTTON_PLAY },
+    { ACTION_WPS_STOP,      BUTTON_PLAY|BUTTON_REPEAT,      BUTTON_PLAY },
+    { ACTION_WPS_SKIPPREV,  BUTTON_PREV|BUTTON_REL,         BUTTON_PREV },
+    { ACTION_WPS_SEEKBACK,  BUTTON_PREV|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,  BUTTON_PREV|BUTTON_REL,         BUTTON_PREV|BUTTON_REPEAT },
+    { ACTION_WPS_SKIPNEXT,  BUTTON_NEXT|BUTTON_REL,         BUTTON_NEXT },
+    { ACTION_WPS_SEEKFWD,   BUTTON_NEXT|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,  BUTTON_NEXT|BUTTON_REL,         BUTTON_NEXT|BUTTON_REPEAT },
+
+    { ACTION_WPS_BROWSE,        BUTTON_UP|BUTTON_REL,       BUTTON_UP   },
+    { ACTION_WPS_CONTEXT,       BUTTON_UP|BUTTON_REPEAT,    BUTTON_UP   },
+    { ACTION_WPS_MENU,          BUTTON_DOWN|BUTTON_REL,     BUTTON_DOWN },
+    { ACTION_WPS_QUICKSCREEN,   BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_DOWN },
+
+    LAST_ITEM_IN_LIST
+}; /* button_context_wps */
+
+static const struct button_mapping button_context_yesnoscreen[]  = {
+    { ACTION_YESNO_ACCEPT,          BUTTON_SELECT,              BUTTON_NONE },
+    { ACTION_YESNO_ACCEPT,          BUTTON_PLAY,                BUTTON_NONE },
+    LAST_ITEM_IN_LIST
+}; /* button_context_settings_yesnoscreen */
+
+
+
+
+/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
+const struct button_mapping* get_context_mapping(int context)
+{
+    switch (context)
+    {
+        case CONTEXT_STD:
+            return button_context_standard;
+        case CONTEXT_WPS:
+            return button_context_wps;
+        case CONTEXT_YESNOSCREEN:
+            return button_context_yesnoscreen;
+            
+        case CONTEXT_TREE:
+        case CONTEXT_LIST:
+        case CONTEXT_MAINMENU:
+            
+        case CONTEXT_SETTINGS:
+        case CONTEXT_SETTINGS|CONTEXT_REMOTE:
+        default:
+            return button_context_standard;
+    } 
+    return button_context_standard;
+}
diff --git a/bootloader/SOURCES b/bootloader/SOURCES
index d1d6598..1725939 100644
--- a/bootloader/SOURCES
+++ b/bootloader/SOURCES
@@ -67,7 +67,7 @@
 show_logo.c
 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
 mpio_hd200_hd300.c
-#elif defined(RK27_GENERIC) || defined(HM60X)
+#elif defined(RK27_GENERIC) || defined(HM60X) || defined(HM801)
 rk27xx.c
 show_logo.c
 #endif
diff --git a/firmware/SOURCES b/firmware/SOURCES
index b729a9b..e7d8820 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -355,8 +355,8 @@
 drivers/audio/cs42l55.c
 #elif defined (HAVE_RK27XX_CODEC)
 drivers/audio/rk27xx_codec.c
-#elif defined (HAVE_TDA1543)
-drivers/audio/tda1543.c
+#elif defined (HAVE_DUMMY_CODEC)
+drivers/audio/dummy_codec.c
 #endif /* defined(HAVE_*) */
 #elif defined(HAVE_SDL_AUDIO)
 drivers/audio/sdl.c
@@ -1925,6 +1925,15 @@
 target/arm/rk27xx/hm60x/button-hm60x.c
 target/arm/rk27xx/hm60x/powermgmt-hm60x.c
 target/arm/rk27xx/hm60x/power-hm60x.c
-target/arm/rk27xx/hm60x/lcd-hm60x.c
+target/arm/rk27xx/lcd-hifiman.c
+#endif
+#endif
+
+#ifndef SIMULATOR
+#if defined(HM801)
+target/arm/rk27xx/hm801/button-hm801.c
+target/arm/rk27xx/hm801/powermgmt-hm801.c
+target/arm/rk27xx/hm801/power-hm801.c
+target/arm/rk27xx/lcd-hifiman.c
 #endif
 #endif
diff --git a/firmware/drivers/audio/tda1543.c b/firmware/drivers/audio/dummy_codec.c
similarity index 100%
rename from firmware/drivers/audio/tda1543.c
rename to firmware/drivers/audio/dummy_codec.c
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h
index e40ee6e..6bf4d71 100644
--- a/firmware/export/audiohw.h
+++ b/firmware/export/audiohw.h
@@ -74,8 +74,8 @@
 #include "cs42l55.h"
 #elif defined(HAVE_IMX233_CODEC)
 #include "imx233-codec.h"
-#elif defined(HAVE_TDA1543)
-#include "tda1543.h"
+#elif defined(HAVE_DUMMY_CODEC)
+#include "dummy_codec.h"
 #endif
 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
 /* #include <SDL_audio.h> gives errors in other code areas,
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 0d0617b..65c27ce 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -141,6 +141,7 @@
 #define SANSA_FUZEPLUS_PAD 48
 #define RK27XX_GENERIC_PAD 49
 #define HM60X_PAD          50
+#define HM801_PAD          51
 
 /* CONFIG_REMOTE_KEYPAD */
 #define H100_REMOTE   1
@@ -463,6 +464,8 @@
 #include "config/rk27generic.h"
 #elif defined(HM60X)
 #include "config/hifimanhm60x.h"
+#elif defined(HM801)
+#include "config/hifimanhm801.h"
 #elif defined(SDLAPP)
 #include "config/sdlapp.h"
 #elif defined(ANDROID)
diff --git a/firmware/export/config/hifimanhm60x.h b/firmware/export/config/hifimanhm60x.h
index 88af364..6ac4380 100644
--- a/firmware/export/config/hifimanhm60x.h
+++ b/firmware/export/config/hifimanhm60x.h
@@ -17,7 +17,7 @@
                          SAMPR_CAP_32 | SAMPR_CAP_24 | SAMPR_CAP_22 | \
                          SAMPR_CAP_16 | SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8)
 
-#define HAVE_TDA1543
+#define HAVE_DUMMY_CODEC
 #define CODEC_SLAVE
 /* define this if you have a bitmap LCD display */
 #define HAVE_LCD_BITMAP
diff --git a/firmware/export/config/hifimanhm801.h b/firmware/export/config/hifimanhm801.h
new file mode 100644
index 0000000..d0e805d
--- /dev/null
+++ b/firmware/export/config/hifimanhm801.h
@@ -0,0 +1,171 @@
+/*
+ * This config file is for HiFiMAN HM-60x reference design
+ */
+#define TARGET_TREE /* this target is using the target tree system */
+
+/* For Rolo and boot loader */
+#define MODEL_NUMBER 80
+
+#define MODEL_NAME   "HiFiMAN HM-801"
+
+
+/* define the bitmask of hardware sample rates */
+#define HW_SAMPR_CAPS   (SAMPR_CAP_96 | SAMPR_CAP_48 | SAMPR_CAP_44 | \
+                         SAMPR_CAP_32 | SAMPR_CAP_24 | SAMPR_CAP_22 | \
+                         SAMPR_CAP_16 | SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8)
+
+#define HAVE_DUMMY_CODEC
+#define CODEC_SLAVE
+/* define this if you have a bitmap LCD display */
+#define HAVE_LCD_BITMAP
+
+/* define this if you can flip your LCD */
+/* #define HAVE_LCD_FLIP */
+
+/* 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 to enable bitmap scaling */
+#define HAVE_BMP_SCALING
+
+/* define this to enable JPEG decoding */
+#define HAVE_JPEG
+
+/* define this if you can invert the colours on your LCD */
+/* #define HAVE_LCD_INVERT */
+
+/* define this if you have access to the quickscreen */
+#define HAVE_QUICKSCREEN
+
+/* define this if you have access to the pitchscreen */
+#define HAVE_PITCHSCREEN
+
+/* define this if you would like tagcache to build on this target */
+#define HAVE_TAGCACHE
+
+/* define this if you have a flash memory storage */
+#define HAVE_FLASH_STORAGE
+
+#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
+
+#define CONFIG_NAND NAND_RK27XX
+#define HAVE_SW_TONE_CONTROLS
+
+/* commented for now */
+/* #define HAVE_HOTSWAP */
+
+#define NUM_DRIVES 2
+#define SECTOR_SIZE 512
+
+/* for small(ish) SD cards */
+#define HAVE_FAT16SUPPORT
+
+/* LCD dimensions */
+#define LCD_WIDTH  220
+#define LCD_HEIGHT 176
+#define LCD_DEPTH  16   /* pseudo 262.144 colors */
+#define LCD_PIXELFORMAT RGB565 /* rgb565 */
+
+/* Define this if the LCD can shut down */
+/* #define HAVE_LCD_SHUTDOWN */
+
+/* Define this if your LCD can be enabled/disabled */
+/* #define HAVE_LCD_ENABLE */
+
+/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE
+   should be defined as well. */
+#ifndef BOOTLOADER
+/* TODO: #define HAVE_LCD_SLEEP */
+/* TODO: #define HAVE_LCD_SLEEP_SETTING */
+#endif
+
+#define CONFIG_KEYPAD HM801_PAD
+
+/* Define this to enable morse code input */
+#define HAVE_MORSE_INPUT
+
+/* Define this if you do software codec */
+#define CONFIG_CODEC SWCODEC
+
+#define CONFIG_LCD LCD_HX8340B
+
+/* #define HAVE_PCM_DMA_ADDRESS */
+
+/* Define this for LCD backlight available */
+#define HAVE_BACKLIGHT
+#define HAVE_BACKLIGHT_BRIGHTNESS
+#define MIN_BRIGHTNESS_SETTING      0
+#define MAX_BRIGHTNESS_SETTING      31
+#define DEFAULT_BRIGHTNESS_SETTING   20
+#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_HW_REG
+
+/* Define this if you have a software controlled poweroff */
+#define HAVE_SW_POWEROFF
+
+/* The number of bytes reserved for loadable codecs */
+#define CODEC_SIZE 0x100000
+
+/* The number of bytes reserved for loadable plugins */
+#define PLUGIN_BUFFER_SIZE 0x80000
+
+/* TODO: Figure out real values */
+#define BATTERY_CAPACITY_DEFAULT 4000 /* default battery capacity */
+#define BATTERY_CAPACITY_MIN     3000 /* min. capacity selectable */
+#define BATTERY_CAPACITY_MAX     4100 /* max. capacity selectable */
+#define BATTERY_CAPACITY_INC      50 /* capacity increment */
+#define BATTERY_TYPES_COUNT        1 /* only one type */
+
+/* Hardware controlled charging with monitoring */
+#define CONFIG_CHARGING CHARGING_MONITOR
+
+/* define current usage levels */
+/* TODO: #define CURRENT_NORMAL
+ * TODO: #define CURRENT_BACKLIGHT  23
+ */
+
+/* define this if the unit can be powered or charged via USB */
+#define HAVE_USB_POWER
+
+/* USB On-the-go */
+#define CONFIG_USBOTG USBOTG_RK27XX
+
+/* enable these for the experimental usb stack */
+#define HAVE_USBSTACK
+
+#define USE_ROCKBOX_USB
+#define USB_VENDOR_ID 0x071b
+#define USB_PRODUCT_ID 0x3202
+#define HAVE_BOOTLOADER_USB_MODE
+
+/* Define this if your LCD can set contrast */
+/* #define HAVE_LCD_CONTRAST */
+
+/* The exact type of CPU */
+#define CONFIG_CPU RK27XX
+
+/* I2C interface */
+#define CONFIG_I2C I2C_RK27XX
+
+/* Define this to the CPU frequency */
+#define CPU_FREQ        200000000
+
+/* define this if the hardware can be powered off while charging */
+/* #define HAVE_POWEROFF_WHILE_CHARGING */
+
+/* Offset ( in the firmware file's header ) to the file CRC */
+#define FIRMWARE_OFFSET_FILE_CRC 0
+
+/* Offset ( in the firmware file's header ) to the real data */
+#define FIRMWARE_OFFSET_FILE_DATA 8
+
+#define STORAGE_NEEDS_ALIGN
+
+/* Define this if you have adjustable CPU frequency */
+/* #define HAVE_ADJUSTABLE_CPU_FREQ */
+
+#define BOOTFILE_EXT "rk27"
+#define BOOTFILE "rockbox." BOOTFILE_EXT
+#define BOOTDIR "/.rockbox"
diff --git a/firmware/export/tda1543.h b/firmware/export/dummy_codec.h
similarity index 92%
rename from firmware/export/tda1543.h
rename to firmware/export/dummy_codec.h
index 6561f08..b85ec8f 100644
--- a/firmware/export/tda1543.h
+++ b/firmware/export/dummy_codec.h
@@ -19,11 +19,11 @@
  * KIND, either express or implied.
  *
  ****************************************************************************/
-#ifndef __TDA1543_H_
-#define __TDA1543_H_
+#ifndef __DUMMY_CODEC_H_
+#define __DUMMY_CODEC_H_
 
 #define VOLUME_MIN   -1
 #define VOLUME_MAX   0
 
 
-#endif /* __TDA1543_H_ */
+#endif /* __DUMMY_CODEC_H_ */
diff --git a/firmware/target/arm/rk27xx/debug-target.h b/firmware/target/arm/rk27xx/debug-target.h
index c083b92..fb4abae 100644
--- a/firmware/target/arm/rk27xx/debug-target.h
+++ b/firmware/target/arm/rk27xx/debug-target.h
@@ -26,7 +26,7 @@
 
 #ifdef RK27_GENERIC
 #define DEBUG_CANCEL BUTTON_VOL
-#elif defined(HM60X)
+#elif defined(HM60X) || defined(HM801)
 #define DEBUG_CANCEL BUTTON_LEFT
 #endif
 
diff --git a/firmware/target/arm/rk27xx/hm801/button-hm801.c b/firmware/target/arm/rk27xx/hm801/button-hm801.c
new file mode 100644
index 0000000..8e3d46b
--- /dev/null
+++ b/firmware/target/arm/rk27xx/hm801/button-hm801.c
@@ -0,0 +1,68 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2011 Andrew Ryabinin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "system.h"
+#include "button.h"
+#include "adc.h"
+
+void button_init_device(void) {
+    /* setup button gpio as input */
+    GPIO_PCCON &= ~(POWEROFF_BUTTON);
+}
+
+int button_read_device(void) {
+    int adc_val = adc_read(ADC_BUTTONS);
+    int button =  0;
+
+    if (adc_val < 480) { /* middle */
+        if (adc_val < 200) { /* 200 - 0 */
+	    if (adc_val < 30) {
+	        button = BUTTON_UP;
+	    } else {
+	        button =  BUTTON_RIGHT; /* 30 - 200 */
+	    }
+        } else { /* 200 - 480 */
+	    if (adc_val < 370) {
+	        button =  BUTTON_SELECT;
+	    } else {
+ 	        button =  BUTTON_DOWN;
+	    }
+	}
+    } else { /*  > 480 */
+        if (adc_val < 690) { /* 480 - 690 */
+	    if (adc_val < 580) {
+	        button =  BUTTON_LEFT;
+	    } else {
+	        button =  BUTTON_NEXT;
+	    }
+	} else { /* > 680 */
+	    if (adc_val < 840) {
+	        button =  BUTTON_PREV;
+	    } else {
+	        if (adc_val < 920) {
+		    button =  BUTTON_PLAY;
+		}
+	    }
+	}
+    }
+    return button | (GPIO_PCDR & POWEROFF_BUTTON);
+}
diff --git a/firmware/target/arm/rk27xx/hm801/button-target.h b/firmware/target/arm/rk27xx/hm801/button-target.h
new file mode 100644
index 0000000..4af054b
--- /dev/null
+++ b/firmware/target/arm/rk27xx/hm801/button-target.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2011 Andrew Ryabinin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+#include <stdbool.h>
+#include "config.h"
+
+void button_init_device(void);
+int button_read_device(void);
+
+
+#define BUTTON_UP          0x00000001
+#define BUTTON_DOWN        0x00000004
+#define BUTTON_LEFT        0x00000008
+#define BUTTON_RIGHT       0x00000010
+#define BUTTON_SELECT      0x00000020
+#define BUTTON_NEXT        0x00000040
+#define BUTTON_PREV        0x00000080
+#define BUTTON_PLAY        0x00000100
+
+
+#define BUTTON_REMOTE      0
+
+
+#define POWEROFF_BUTTON 0x02
+#define POWEROFF_COUNT 30
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/export/tda1543.h b/firmware/target/arm/rk27xx/hm801/power-hm801.c
similarity index 62%
copy from firmware/export/tda1543.h
copy to firmware/target/arm/rk27xx/hm801/power-hm801.c
index 6561f08..18a0566 100644
--- a/firmware/export/tda1543.h
+++ b/firmware/target/arm/rk27xx/hm801/power-hm801.c
@@ -7,8 +7,7 @@
  *                     \/            \/     \/    \/            \/
  * $Id$
  *
- *
- * Copyright (c) 2011 Andrew Ryabinin
+ * Copyright © 2009 Bertrik Sikken
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -19,11 +18,32 @@
  * KIND, either express or implied.
  *
  ****************************************************************************/
-#ifndef __TDA1543_H_
-#define __TDA1543_H_
+#include <stdbool.h>
+#include "config.h"
+#include "inttypes.h"
+#include "power.h"
+#include "panic.h"
+#include "system.h"
+#include "usb_core.h"   /* for usb_charging_maxcurrent_change */
 
-#define VOLUME_MIN   -1
-#define VOLUME_MAX   0
+void power_off(void)
+{
+    GPIO_PCDR &= ~(1<<0);
+    while(1);
+}
 
+void power_init(void)
+{
+    GPIO_PCDR |= (1<<0);
+    GPIO_PCCON |= (1<<0);
+}
 
-#endif /* __TDA1543_H_ */
+unsigned int power_input_status(void)
+{
+    return (usb_detect() == USB_INSERTED) ? POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE;
+}
+
+bool charging_state(void)
+{
+   return true;
+}
diff --git a/firmware/target/arm/rk27xx/hm801/powermgmt-hm801.c b/firmware/target/arm/rk27xx/hm801/powermgmt-hm801.c
new file mode 100644
index 0000000..a815d89
--- /dev/null
+++ b/firmware/target/arm/rk27xx/hm801/powermgmt-hm801.c
@@ -0,0 +1,60 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright © 2011 Andrew Ryabinin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "adc.h"
+#include "adc-target.h"
+#include "powermgmt.h"
+
+/*  Battery voltage calculation and discharge/charge curves for the HiFiMAN HM-801.
+
+    I don't know how to calculate battery voltage, so all values represented here is just
+    values from adc battery channel, not millivolts.
+    Discharge and charge curves have not been calibrated yet.
+*/
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+    /* OF power off device when this value reached  */
+    430
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+    425
+};
+
+/* adc values of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+    /* TODO: simple uncalibrated curve */
+    { 425, 430, 440, 450, 460, 470,  480, 490, 500, 510, 520 }
+};
+
+/* adc values of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+    /* TODO: simple uncalibrated curve */
+    { 425, 430, 440, 450, 460, 470,  480, 490, 500, 510, 520  };
+
+unsigned int battery_adc_voltage(void)
+{
+    return adc_read(ADC_BATTERY);
+}
diff --git a/firmware/target/arm/rk27xx/hm60x/lcd-hm60x.c b/firmware/target/arm/rk27xx/lcd-hifiman.c
similarity index 100%
rename from firmware/target/arm/rk27xx/hm60x/lcd-hm60x.c
rename to firmware/target/arm/rk27xx/lcd-hifiman.c
diff --git a/firmware/target/arm/rk27xx/lcdif-rk27xx.c b/firmware/target/arm/rk27xx/lcdif-rk27xx.c
index aeee63e..a5e18b0 100644
--- a/firmware/target/arm/rk27xx/lcdif-rk27xx.c
+++ b/firmware/target/arm/rk27xx/lcdif-rk27xx.c
@@ -37,7 +37,7 @@
     /* g = ((data & 0x00000300) >> 2) | ((data & 0x000000e0) >> 3); */
     g = ((data & 0x00000300) << 6) | ((data & 0x000000e0) << 5);
     b = (data & 0x00000001f) << 3;
-#elif defined(HM60X)
+#elif defined(HM60X) || defined(HM801)
     /* 16 bit interface */
     r = (data & 0x0000f800) << 8;
     g = (data & 0x000007e0) << 5;
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index 1742852..f3081d2 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -126,10 +126,16 @@
     MMU_CTRL |= MMU_BUFII_RESET | MMU_BUFI_RESET;
 }
 
-/* My generic device uses PC7 pin, active low */
 static inline bool card_detect_target(void)
 {
+#if defined(RK27_GENERIC)
+/* My generic device uses PC7 pin, active low */
     return !(GPIO_PCDR & 0x80);
+#elif defined(HM60X) || defined(HM801)
+    return !(GPIO_PFDR & (1<<2));
+#else
+#error "Unknown target"
+#endif
 }
 
 /* Send command to the SD card. Command finish is signaled in ISR */
diff --git a/tools/configure b/tools/configure
index 5b84f87..42cd2f8 100755
--- a/tools/configure
+++ b/tools/configure
@@ -1292,6 +1292,7 @@
  202) Nokia N8xx
  203) Nokia N900          ==ROCKCHIP==           ==HiFiMAN==
  204) Pandora             180) rk27xx generic    190) HM-60x
+                                                 191) HM-801
 
 EOF
 
@@ -3054,6 +3055,29 @@
     t_model="hm60x"
     ;;
 
+   191|hifimanhm801)
+    target_id=80
+    modelname="hifimanhm801"
+    target="-DHM801"
+    memory=16
+    arm7ejscc
+    tool="$rootdir/tools/scramble -add=rk27"
+    bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
+    bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
+    output="rockbox.rk27"
+    bootoutput="bootloader.rk27"
+    appextra="recorder:gui"
+    plugins="yes"
+    swcodec="yes"
+    # toolset is the tools within the tools directory that we build for
+    # this particular target.
+    toolset="$genericbitmaptools"
+    # architecture, manufacturer and model for the target-tree build
+    t_cpu="arm"
+    t_manufacturer="rk27xx"
+    t_model="hm801"
+    ;;
+
    200|sdlapp)
     application="yes"
     target_id=73