Introduce IHIFI760/960 targets.

Change-Id: Ie36e48742c0ed9aa3fd6f49aa034a11d2492327c
diff --git a/apps/SOURCES b/apps/SOURCES
index 0e7fc3e..b6bb82f 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -299,5 +299,7 @@
 keymaps/keymap-nwz.c
 #elif CONFIG_KEYPAD == SAMSUNG_YPZ5_PAD
 keymaps/keymap-ypz5.c
+#elif CONFIG_KEYPAD == IHIFI_PAD
+keymaps/keymap-ihifi.c
 #endif
 
diff --git a/apps/keymaps/keymap-ihifi.c b/apps/keymaps/keymap-ihifi.c
new file mode 100644
index 0000000..0d574c1
--- /dev/null
+++ b/apps/keymaps/keymap-ihifi.c
@@ -0,0 +1,229 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2013 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 IHIFI 760/960 targets */
+
+#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_BWD,                  BUTTON_NONE },
+    { ACTION_STD_PREVREPEAT, BUTTON_BWD|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_STD_NEXT,       BUTTON_FWD,                  BUTTON_NONE },
+    { ACTION_STD_NEXTREPEAT, BUTTON_FWD|BUTTON_REPEAT,    BUTTON_NONE },
+
+    { ACTION_STD_CONTEXT,    BUTTON_MENU|BUTTON_REPEAT,   BUTTON_MENU },
+    { ACTION_STD_CANCEL,     BUTTON_RETURN|BUTTON_REL,    BUTTON_RETURN },
+    { ACTION_STD_OK,         BUTTON_PLAY|BUTTON_REL,      BUTTON_PLAY },
+    { ACTION_STD_MENU,       BUTTON_MENU|BUTTON_REL,      BUTTON_MENU },
+
+    LAST_ITEM_IN_LIST
+}; /* button_context_standard */
+
+static const struct button_mapping button_context_wps[] = {
+    { ACTION_WPS_PLAY,      BUTTON_PLAY|BUTTON_REL,       BUTTON_PLAY },
+    { ACTION_WPS_STOP,      BUTTON_PLAY|BUTTON_REPEAT,    BUTTON_PLAY },
+    { ACTION_WPS_SKIPPREV,  BUTTON_BWD|BUTTON_REL,        BUTTON_BWD },
+    { ACTION_WPS_SEEKBACK,  BUTTON_BWD|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,  BUTTON_BWD|BUTTON_REL,        BUTTON_BWD|BUTTON_REPEAT },
+    { ACTION_WPS_SKIPNEXT,  BUTTON_FWD|BUTTON_REL,        BUTTON_FWD },
+    { ACTION_WPS_SEEKFWD,   BUTTON_FWD|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,  BUTTON_FWD|BUTTON_REL,        BUTTON_FWD|BUTTON_REPEAT },
+
+    { ACTION_WPS_ABSETB_NEXTDIR, BUTTON_PLAY|BUTTON_FWD,    BUTTON_PLAY },
+    { ACTION_WPS_ABSETA_PREVDIR, BUTTON_PLAY|BUTTON_BWD,    BUTTON_PLAY },
+    { ACTION_WPS_ABRESET,        BUTTON_PLAY|BUTTON_BWD,    BUTTON_PLAY },
+
+    { ACTION_WPS_BROWSE,         BUTTON_RETURN|BUTTON_REL,    BUTTON_RETURN },
+    { ACTION_WPS_CONTEXT,        BUTTON_RETURN|BUTTON_REPEAT, BUTTON_RETURN },
+    { ACTION_WPS_MENU,           BUTTON_MENU|BUTTON_REL,      BUTTON_MENU },
+    { ACTION_WPS_QUICKSCREEN,    BUTTON_MENU|BUTTON_REPEAT,   BUTTON_MENU },
+
+    LAST_ITEM_IN_LIST
+}; /* button_context_wps */
+
+/** Bookmark Screen **/
+static const struct button_mapping button_context_bmark[] = {
+    { ACTION_BMS_DELETE,       BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
+}; /* button_context_settings_bmark */
+
+
+/** Keyboard **/
+static const struct button_mapping button_context_keyboard[] = {
+    { ACTION_KBD_LEFT,         BUTTON_RETURN,                BUTTON_NONE },
+    { ACTION_KBD_LEFT,         BUTTON_RETURN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_KBD_RIGHT,        BUTTON_MENU,                  BUTTON_NONE },
+    { ACTION_KBD_RIGHT,        BUTTON_MENU|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_KBD_UP,           BUTTON_BWD,                   BUTTON_NONE },
+    { ACTION_KBD_UP,           BUTTON_BWD|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_KBD_DOWN,         BUTTON_FWD,                   BUTTON_NONE },
+    { ACTION_KBD_DOWN,         BUTTON_FWD|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_KBD_SELECT,       BUTTON_PLAY|BUTTON_REL,       BUTTON_PLAY },
+    { ACTION_KBD_DONE,         BUTTON_PLAY|BUTTON_REPEAT,    BUTTON_PLAY },
+    { ACTION_KBD_ABORT,        BUTTON_PLAY|BUTTON_RETURN,    BUTTON_PLAY },
+
+    LAST_ITEM_IN_LIST
+}; /* button_context_keyboard */
+
+/** Pitchscreen **/
+static const struct button_mapping button_context_pitchscreen[] = {
+    { ACTION_PS_INC_SMALL,      BUTTON_BWD,                  BUTTON_NONE },
+    { ACTION_PS_INC_BIG,        BUTTON_BWD|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_PS_DEC_SMALL,      BUTTON_FWD,                  BUTTON_NONE },
+    { ACTION_PS_DEC_BIG,        BUTTON_FWD|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_PS_NUDGE_LEFT,     BUTTON_RETURN,               BUTTON_NONE },
+    { ACTION_PS_NUDGE_LEFTOFF,  BUTTON_RETURN|BUTTON_REL,    BUTTON_NONE },
+    { ACTION_PS_NUDGE_RIGHT,    BUTTON_MENU,                 BUTTON_NONE },
+    { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_MENU|BUTTON_REL,      BUTTON_NONE },
+    { ACTION_PS_TOGGLE_MODE,    BUTTON_PLAY|BUTTON_REL,      BUTTON_PLAY },
+    { ACTION_PS_RESET,          BUTTON_PLAY|BUTTON_REPEAT,   BUTTON_PLAY },
+    { ACTION_PS_EXIT,           BUTTON_PLAY|BUTTON_RETURN,   BUTTON_PLAY },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_pitchscreen */
+
+/** Quickscreen **/
+static const struct button_mapping button_context_quickscreen[] = {
+    { ACTION_QS_TOP,        BUTTON_BWD,                    BUTTON_NONE },
+    { ACTION_QS_TOP,        BUTTON_BWD|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_QS_DOWN,       BUTTON_FWD,                    BUTTON_NONE },
+    { ACTION_QS_DOWN,       BUTTON_FWD|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_QS_LEFT,       BUTTON_RETURN,                 BUTTON_NONE },
+    { ACTION_QS_LEFT,       BUTTON_RETURN|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_QS_RIGHT,      BUTTON_MENU,                   BUTTON_NONE },
+    { ACTION_QS_RIGHT,      BUTTON_MENU|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_STD_CANCEL,    BUTTON_PLAY|BUTTON_REL,        BUTTON_PLAY },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_quickscreen */
+
+/** Settings - General Mappings **/
+static const struct button_mapping button_context_settings[] = {
+    { ACTION_SETTINGS_RESET,     BUTTON_PLAY,                 BUTTON_NONE },
+    { ACTION_SETTINGS_INC,       BUTTON_BWD,                  BUTTON_NONE },
+    { ACTION_SETTINGS_INCREPEAT, BUTTON_BWD|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_SETTINGS_DEC,       BUTTON_FWD,                  BUTTON_NONE },
+    { ACTION_SETTINGS_DECREPEAT, BUTTON_FWD|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_STD_PREV,           BUTTON_RETURN,               BUTTON_NONE },
+    { ACTION_STD_PREVREPEAT,     BUTTON_RETURN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_STD_CANCEL,         BUTTON_MENU|BUTTON_REL,      BUTTON_MENU },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_settings */
+
+/** Settings - Using Sliders **/
+static const struct button_mapping button_context_settings_r_is_inc[] = {
+    { ACTION_SETTINGS_INC,       BUTTON_MENU,                 BUTTON_NONE },
+    { ACTION_SETTINGS_INCREPEAT, BUTTON_MENU|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_SETTINGS_DEC,       BUTTON_RETURN,               BUTTON_NONE },
+    { ACTION_SETTINGS_DECREPEAT, BUTTON_RETURN|BUTTON_REPEAT, BUTTON_NONE },
+
+    { ACTION_STD_PREV,       BUTTON_BWD,                  BUTTON_NONE },
+    { ACTION_STD_PREVREPEAT, BUTTON_BWD|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_STD_NEXT,       BUTTON_FWD,                  BUTTON_NONE },
+    { ACTION_STD_NEXTREPEAT, BUTTON_FWD|BUTTON_REPEAT,    BUTTON_NONE },
+
+    { ACTION_STD_OK,         BUTTON_PLAY|BUTTON_REL,      BUTTON_NONE },
+    { ACTION_STD_CANCEL,     BUTTON_PLAY|BUTTON_REPEAT,   BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST
+}; /* button_context_settings_r_is_inc */
+
+/** Tree **/
+static const struct button_mapping button_context_tree[] = {
+    { ACTION_TREE_WPS,    BUTTON_RETURN|BUTTON_REPEAT,  BUTTON_RETURN },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_tree */
+
+static const struct button_mapping button_context_tree_scroll_lr[] = {
+    { ACTION_TREE_ROOT_INIT,    BUTTON_RETURN|BUTTON_REPEAT,  BUTTON_RETURN },
+    { ACTION_TREE_PGLEFT,       BUTTON_PLAY|BUTTON_BWD,       BUTTON_NONE },
+    { ACTION_TREE_PGRIGHT,      BUTTON_PLAY|BUTTON_FWD,       BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
+}; /* button_context_tree_scroll_lr */
+
+/** Yes/No Screen **/
+static const struct button_mapping button_context_yesnoscreen[] = {
+    { 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)
+    {
+        /* anything that uses button_context_standard */
+        case CONTEXT_LIST:
+        case CONTEXT_STD:
+        default:
+            return button_context_standard;
+
+        /* contexts with special mapping */
+        case CONTEXT_BOOKMARKSCREEN:
+            return button_context_bmark;
+
+        case CONTEXT_KEYBOARD:
+        case CONTEXT_MORSE_INPUT:
+            return button_context_keyboard;
+
+        case CONTEXT_PITCHSCREEN:
+            return button_context_pitchscreen;
+
+        case CONTEXT_QUICKSCREEN:
+            return button_context_quickscreen;
+
+        case CONTEXT_SETTINGS:
+        case CONTEXT_SETTINGS_TIME:
+            return button_context_settings;
+
+        case CONTEXT_SETTINGS_COLOURCHOOSER:
+        case CONTEXT_SETTINGS_EQ:
+        case CONTEXT_SETTINGS_RECTRIGGER:
+            return button_context_settings_r_is_inc;
+
+        case CONTEXT_TREE:
+        case CONTEXT_MAINMENU:
+            if (global_settings.hold_lr_for_scroll_in_list)
+                return button_context_tree_scroll_lr;
+            /* else fall through to CONTEXT_TREE|CONTEXT_CUSTOM */
+        case CONTEXT_TREE|CONTEXT_CUSTOM:
+            return button_context_tree;
+
+        case CONTEXT_WPS:
+            return button_context_wps;
+
+        case CONTEXT_YESNOSCREEN:
+            return button_context_yesnoscreen;
+    }
+}
diff --git a/bootloader/SOURCES b/bootloader/SOURCES
index ffd1b40..4f3cd38 100644
--- a/bootloader/SOURCES
+++ b/bootloader/SOURCES
@@ -68,7 +68,8 @@
 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
 mpio_hd200_hd300.c
 #elif defined(RK27_GENERIC) || defined(HM60X) || defined(HM801) \
-      || defined(MA9) || defined(MA9C) || defined(MA8) || defined(MA8C)
+      || defined(MA9) || defined(MA9C) || defined(MA8) || defined(MA8C) \
+      || defined(IHIFI760) || defined(IHIFI960)
 rk27xx.c
 show_logo.c
 #elif defined(SANSA_CONNECT)
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 64041e4..5591f68 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -709,6 +709,8 @@
 target/arm/s3c2440/lcd-s3c2440.c
 #elif CONFIG_LCD == LCD_ILI9342 || CONFIG_LCD == LCD_ILI9342C
 target/arm/rk27xx/ma/lcd-ma.c
+#elif CONFIG_LCD == LCD_IHIFI
+target/arm/rk27xx/ihifi/lcd-ihifi.c
 #endif
 
 /* USB Stack */
@@ -1765,6 +1767,16 @@
 target/arm/rk27xx/ma/audio-ma.c
 #endif
 
+#if defined(IHIFI760) || defined(IHIFI960)
+target/arm/rk27xx/ihifi/button-ihifi.c
+target/arm/rk27xx/ihifi/power-ihifi.c
+#if defined(IHIFI760)
+target/arm/rk27xx/ihifi/powermgmt-ihifi760.c
+#else
+target/arm/rk27xx/ihifi/powermgmt-ihifi960.c
+#endif
+#endif
+
 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
 target/hosted/kernel-unix.c
 target/hosted/filesystem-unix.c
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 23ee56f..702a588 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -151,6 +151,7 @@
 #define SONY_NWZ_PAD       57
 #define CREATIVE_ZEN_PAD   58
 #define SAMSUNG_YPZ5_PAD   59
+#define IHIFI_PAD          60
 
 /* CONFIG_REMOTE_KEYPAD */
 #define H100_REMOTE   1
@@ -260,6 +261,7 @@
 #define LCD_ILI9342C   57 /* another type of lcd used by HiFi E.T MA9/MA8 */
 #define LCD_CREATIVEZENV  58 /* as used by the Creativr Zen V (Plus) */
 #define LCD_SAMSUNGYPZ5   59 /* as used by Samsung YP-Z5 */
+#define LCD_IHIFI         60 /* as used by IHIFI 760/960 */
 
 /* LCD_PIXELFORMAT */
 #define HORIZONTAL_PACKING 1
@@ -550,6 +552,10 @@
 #include "config/sonynwze360.h"
 #elif defined(SAMSUNG_YPZ5)
 #include "config/samsungypz5.h"
+#elif defined(IHIFI760)
+#include "config/ihifi760.h"
+#elif defined(IHIFI960)
+#include "config/ihifi960.h"
 #else
 /* no known platform */
 #endif
diff --git a/firmware/export/config/ihifi760.h b/firmware/export/config/ihifi760.h
new file mode 100644
index 0000000..ea84a4a
--- /dev/null
+++ b/firmware/export/config/ihifi760.h
@@ -0,0 +1,187 @@
+/*
+ * This config file is for IHIFI 760
+ */
+
+/* For Rolo and boot loader */
+#define MODEL_NUMBER 92
+
+#define MODEL_NAME   "IHIFI 760"
+
+/* Define bitmask of input sources - recordable bitmask can be defined
+   explicitly if different */
+/* #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_FM) */
+
+/* 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 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
+
+#define HAVE_SW_VOLUME_CONTROL
+
+/* commented for now */
+/* #define HAVE_HOTSWAP */
+
+#define NUM_DRIVES 1
+#define SECTOR_SIZE 512
+
+/* for small(ish) SD cards */
+#define HAVE_FAT16SUPPORT
+
+/* LCD dimensions */
+#define LCD_WIDTH  320
+#define LCD_HEIGHT 240
+#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 IHIFI_PAD
+
+/* Define this to enable morse code input */
+#define HAVE_MORSE_INPUT
+
+/* Define this if you do software codec */
+#define CONFIG_CODEC SWCODEC
+
+/* define this if you have a real-time clock */
+/* #define CONFIG_RTC RTC_NANO2G */
+
+/* Define if the device can wake from an RTC alarm */
+/* #define HAVE_RTC_ALARM */
+
+#define CONFIG_LCD LCD_IHIFI
+
+/* Define the type of audio codec */
+/*#define HAVE_RK27XX_CODEC */
+
+/* #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 600 /* default battery capacity */
+#define BATTERY_CAPACITY_MIN     300 /* min. capacity selectable */
+#define BATTERY_CAPACITY_MAX     600 /* max. capacity selectable */
+#define BATTERY_CAPACITY_INC      10 /* capacity increment */
+#define BATTERY_TYPES_COUNT        1 /* only one type */
+
+#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
+
+/* 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
+
+/* Virtual LED (icon) */
+#define CONFIG_LED LED_VIRTUAL
+
+#define RKW_FORMAT
+#define BOOTFILE_EXT "rkw"
+#define BOOTFILE "rockbox." BOOTFILE_EXT
+#define BOOTDIR "/.rockbox"
diff --git a/firmware/export/config/ihifi960.h b/firmware/export/config/ihifi960.h
new file mode 100644
index 0000000..3ef6609
--- /dev/null
+++ b/firmware/export/config/ihifi960.h
@@ -0,0 +1,187 @@
+/*
+ * This config file is for IHIFI 960
+ */
+
+/* For Rolo and boot loader */
+#define MODEL_NUMBER 93
+
+#define MODEL_NAME   "IHIFI 960"
+
+/* Define bitmask of input sources - recordable bitmask can be defined
+   explicitly if different */
+/* #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_FM) */
+
+/* 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 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
+
+#define HAVE_SW_VOLUME_CONTROL
+
+/* commented for now */
+/* #define HAVE_HOTSWAP */
+
+#define NUM_DRIVES 1
+#define SECTOR_SIZE 512
+
+/* for small(ish) SD cards */
+#define HAVE_FAT16SUPPORT
+
+/* LCD dimensions */
+#define LCD_WIDTH  320
+#define LCD_HEIGHT 240
+#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 IHIFI_PAD
+
+/* Define this to enable morse code input */
+#define HAVE_MORSE_INPUT
+
+/* Define this if you do software codec */
+#define CONFIG_CODEC SWCODEC
+
+/* define this if you have a real-time clock */
+/* #define CONFIG_RTC RTC_NANO2G */
+
+/* Define if the device can wake from an RTC alarm */
+/* #define HAVE_RTC_ALARM */
+
+#define CONFIG_LCD LCD_IHIFI
+
+/* Define the type of audio codec */
+/*#define HAVE_RK27XX_CODEC */
+
+/* #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 600 /* default battery capacity */
+#define BATTERY_CAPACITY_MIN     300 /* min. capacity selectable */
+#define BATTERY_CAPACITY_MAX     600 /* max. capacity selectable */
+#define BATTERY_CAPACITY_INC      10 /* capacity increment */
+#define BATTERY_TYPES_COUNT        1 /* only one type */
+
+#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
+
+/* 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
+
+/* Virtual LED (icon) */
+#define CONFIG_LED LED_VIRTUAL
+
+#define RKW_FORMAT
+#define BOOTFILE_EXT "rkw"
+#define BOOTFILE "rockbox." BOOTFILE_EXT
+#define BOOTDIR "/.rockbox"
diff --git a/firmware/target/arm/rk27xx/backlight-rk27xx.c b/firmware/target/arm/rk27xx/backlight-rk27xx.c
index 5d92cd8..361d18c 100644
--- a/firmware/target/arm/rk27xx/backlight-rk27xx.c
+++ b/firmware/target/arm/rk27xx/backlight-rk27xx.c
@@ -68,6 +68,13 @@
     198, 227, 260, 295, 334, 376, 421, 470,
     522, 578, 638, 702, 770, 842, 918, 1000
 };
+#elif defined(IHIFI760) || defined(IHIFI960)
+static const unsigned short lin_brightness[] = {
+    700, 701, 702, 703, 704, 706, 708, 711,
+    714, 717, 721, 726, 731, 737, 743, 751,
+    759, 768, 778, 788, 800, 812, 826, 841,
+    856, 873, 891, 910, 931, 952, 975, 1000
+};
 #endif
 
 bool _backlight_init(void)
diff --git a/firmware/target/arm/rk27xx/debug-rk27xx.c b/firmware/target/arm/rk27xx/debug-rk27xx.c
index 79c7794..83bc1a5 100644
--- a/firmware/target/arm/rk27xx/debug-rk27xx.c
+++ b/firmware/target/arm/rk27xx/debug-rk27xx.c
@@ -32,7 +32,8 @@
 
 #ifdef RK27_GENERIC
 #define DEBUG_CANCEL BUTTON_VOL
-#elif defined(HM60X) || defined(HM801) || (CONFIG_KEYPAD == MA_PAD)
+#elif defined(HM60X) || defined(HM801) || (CONFIG_KEYPAD == MA_PAD) || \
+    (CONFIG_KEYPAD == IHIFI_PAD)
 #define DEBUG_CANCEL BUTTON_LEFT
 #endif
 
diff --git a/firmware/target/arm/rk27xx/ihifi/button-ihifi.c b/firmware/target/arm/rk27xx/ihifi/button-ihifi.c
new file mode 100644
index 0000000..6477400
--- /dev/null
+++ b/firmware/target/arm/rk27xx/ihifi/button-ihifi.c
@@ -0,0 +1,53 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2013 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"
+#include "backlight.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 gpio_btn = GPIO_PCDR & BUTTON_PLAY;
+
+    if (adc_val < 270) {
+        if (adc_val < 110) {             /* 0 - 109 */
+            return BUTTON_RETURN | gpio_btn;
+        } else {                         /* 110 - 269 */
+            return BUTTON_MENU |gpio_btn;
+        }
+    } else {
+        if (adc_val < 420) {                   /* 270 - 419 */
+                return BUTTON_BWD | gpio_btn;
+        } else if (adc_val < 580) {            /* 420 - 579 */
+                return BUTTON_FWD | gpio_btn;
+        }
+    }
+    return gpio_btn;
+}
+
+
diff --git a/firmware/target/arm/rk27xx/ihifi/button-target.h b/firmware/target/arm/rk27xx/ihifi/button-target.h
new file mode 100644
index 0000000..f78727b
--- /dev/null
+++ b/firmware/target/arm/rk27xx/ihifi/button-target.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2013 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_
+
+#define BUTTON_FWD         0x00000001
+#define BUTTON_PLAY        0x00000002
+#define BUTTON_BWD         0x00000004
+#define BUTTON_RETURN      0x00000008
+#define BUTTON_MENU        0x00000010
+
+#define BUTTON_LEFT BUTTON_RETURN
+#define BUTTON_RIGHT BUTTON_MENU
+
+#define BUTTON_MAIN (BUTTON_FWD|BUTTON_PLAY| \
+                     BUTTON_BWD|BUTTON_RETURN| \
+                     BUTTON_MENU)
+
+#define POWEROFF_BUTTON BUTTON_PLAY
+#define POWEROFF_COUNT 30
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/rk27xx/ihifi/lcd-ihifi.c b/firmware/target/arm/rk27xx/ihifi/lcd-ihifi.c
new file mode 100644
index 0000000..d5906b9
--- /dev/null
+++ b/firmware/target/arm/rk27xx/ihifi/lcd-ihifi.c
@@ -0,0 +1,224 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C)  2013 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 "kernel.h"
+#include "lcd.h"
+#include "system.h"
+#include "cpu.h"
+#include "lcdif-rk27xx.h"
+
+static bool display_on = false;
+
+void lcd_display_init(void)
+{
+    unsigned int x, y;
+
+    lcd_cmd(0xEF);
+    lcd_data(0x03);
+    lcd_data(0x80);
+    lcd_data(0x02);
+
+    lcd_cmd(0x00CF);
+    lcd_data(0x00);
+    lcd_data(0xC1);
+    lcd_data(0x30);
+
+    lcd_cmd(0xED);
+    lcd_data(0x67);
+    lcd_data(0x03);
+    lcd_data(0x12);
+    lcd_data(0x81);
+
+    lcd_cmd(0xE8);
+    lcd_data(0x85);
+    lcd_data(0x11);
+    lcd_data(0x79);
+
+    lcd_cmd(0xCB);
+    lcd_data(0x39);
+    lcd_data(0x2C);
+    lcd_data(0x00);
+    lcd_data(0x34);
+    lcd_data(0x06);
+
+    lcd_cmd(0xF7);
+    lcd_data(0x20);
+
+    lcd_cmd(0xEA);
+    lcd_data(0x00);
+    lcd_data(0x00);
+
+    lcd_cmd(0xC0);
+    lcd_data(0x1D);
+
+    lcd_cmd(0xC1);
+    lcd_data(0x12);
+
+    lcd_cmd(0xC5);
+    lcd_data(0x44);
+    lcd_data(0x3C);
+
+    lcd_cmd(0xC7);
+    lcd_data(0x88);
+
+    lcd_cmd(0x3A);
+    lcd_data(0x55);
+
+    lcd_cmd(0x36);
+    lcd_data(0xA8);
+
+    lcd_cmd(0xB1);
+    lcd_data(0x00);
+    lcd_data(0x17);
+
+    lcd_cmd(0xB6);
+    lcd_data(0x0A);
+    lcd_data(0xA2);
+
+    lcd_cmd(0xF2);
+    lcd_data(0x00);
+
+    lcd_cmd(0x26);
+    lcd_data(0x01);
+
+    lcd_cmd(0xE0);
+    lcd_data(0x0F);
+    lcd_data(0x22);
+    lcd_data(0x1C);
+    lcd_data(0x1B);
+    lcd_data(0x08);
+    lcd_data(0x0F);
+    lcd_data(0x48);
+    lcd_data(0xB8);
+    lcd_data(0x34);
+    lcd_data(0x05);
+    lcd_data(0x0C);
+    lcd_data(0x09);
+    lcd_data(0x0F);
+    lcd_data(0x07);
+    lcd_data(0x00);
+
+    lcd_cmd(0xE1);
+    lcd_data(0x00);
+    lcd_data(0x23);
+    lcd_data(0x24);
+    lcd_data(0x07);
+    lcd_data(0x10);
+    lcd_data(0x07);
+    lcd_data(0x38);
+    lcd_data(0x47);
+    lcd_data(0x4B);
+    lcd_data(0x0A);
+    lcd_data(0x13);
+    lcd_data(0x06);
+    lcd_data(0x30);
+    lcd_data(0x38);
+    lcd_data(0x0F);
+
+    lcd_cmd(0x2A);
+    lcd_data(0x00);
+    lcd_data(0x00);
+    lcd_data(0x01);
+    lcd_data(0x3F);
+
+    lcd_cmd(0x2B);
+    lcd_data(0x00);
+    lcd_data(0x00);
+    lcd_data(0x00);
+    lcd_data(0xEF);
+
+    lcd_cmd(0x11);
+
+    udelay(120000);
+
+    lcd_cmd(0x29);
+    lcd_cmd(0x2C);
+
+    for (x = 0; x < LCD_WIDTH; x++)
+        for(y=0; y < LCD_HEIGHT; y++)
+            lcd_data(0x00);
+
+    display_on = true;
+}
+
+void lcd_enable (bool on)
+{
+    if (on == display_on)
+        return;
+
+    lcdctrl_bypass(1);
+    LCDC_CTRL |= RGB24B;
+
+    if (on) {
+        lcd_cmd(0x11);
+        udelay(120000);
+        lcd_cmd(0x29);
+        lcd_cmd(0x2C);
+    } else {
+        lcd_cmd(0x28);
+    }
+
+    display_on = on;
+    LCDC_CTRL &= ~RGB24B;
+}
+
+void lcd_set_gram_area(int x_start, int y_start,
+                       int x_end, int y_end)
+{
+    lcdctrl_bypass(1);
+    LCDC_CTRL |= RGB24B;
+    lcd_cmd(0x002A);
+    lcd_data((x_start&0xff00)>>8);
+    lcd_data(x_start&0x00ff);
+    lcd_data((x_end&0xff00)>>8);
+    lcd_data(x_end&0x00ff);
+    lcd_cmd(0x002B);
+    lcd_data((y_start&0xff00)>>8);
+    lcd_data(y_start&0x00ff);
+    lcd_data((y_end&0xff00)>>8);
+    lcd_data(y_end&0x00ff);
+
+    lcd_cmd(0x2C);
+    LCDC_CTRL &= ~RGB24B;
+
+}
+
+bool lcd_active()
+{
+    return display_on;
+}
+
+/* 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;
+}
diff --git a/firmware/target/arm/rk27xx/ihifi/lcd-target.h b/firmware/target/arm/rk27xx/ihifi/lcd-target.h
new file mode 100644
index 0000000..0d245c8
--- /dev/null
+++ b/firmware/target/arm/rk27xx/ihifi/lcd-target.h
@@ -0,0 +1,26 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C)  2012 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 LCD_TARGET_H
+#define LCD_TARGET_H
+
+#define LCD_DATABUS_WIDTH LCDIF_16BIT
+#endif
diff --git a/firmware/target/arm/rk27xx/ihifi/power-ihifi.c b/firmware/target/arm/rk27xx/ihifi/power-ihifi.c
new file mode 100644
index 0000000..780d476
--- /dev/null
+++ b/firmware/target/arm/rk27xx/ihifi/power-ihifi.c
@@ -0,0 +1,51 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright © 2013 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 <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 */
+
+void power_off(void)
+{
+    GPIO_PCCON &= ~(1<<0);
+    while(1);
+}
+
+void power_init(void)
+{
+    GPIO_PCDR |= (1<<0);
+    GPIO_PCCON |= (1<<0);
+}
+
+unsigned int power_input_status(void)
+{
+    unsigned int status = POWER_INPUT_NONE;
+    /* TODO: implement */
+    return status;
+}
+
+bool charging_state(void)
+{
+    return true;
+}
diff --git a/firmware/target/arm/rk27xx/ihifi/powermgmt-ihifi760.c b/firmware/target/arm/rk27xx/ihifi/powermgmt-ihifi760.c
new file mode 100644
index 0000000..c849bc2
--- /dev/null
+++ b/firmware/target/arm/rk27xx/ihifi/powermgmt-ihifi760.c
@@ -0,0 +1,65 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright © 2013 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-60x.
+
+    Battery voltage is calculated under the assumption that the adc full-scale
+    readout represents 3.00V and that the battery ADC channel is fed with
+    exactly half of the battery voltage (through a resistive divider).
+    Charge curve have not been calibrated yet.
+*/
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+    /* TODO: this is just an initial guess */
+    3350,
+};
+
+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] =
+{
+    /* FIXME: Uncalibrated curve */
+    { 3300, 3350, 3433, 3516, 3600, 3683, 3767, 3850, 3933, 4017, 4100 }
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+    /* TODO: simple copy of discharge curve */
+    { 3300, 3350, 3433, 3516, 3600, 3683, 3767, 3850, 3933, 4017, 4100 };
+
+/* full-scale ADC readout (2^10) in millivolt */
+#define BATTERY_SCALE_FACTOR 6100
+
+/* Returns battery voltage from ADC [millivolts] */
+int _battery_voltage(void)
+{
+    return (adc_read(ADC_BATTERY) * BATTERY_SCALE_FACTOR) >> 10;
+}
diff --git a/firmware/target/arm/rk27xx/ihifi/powermgmt-ihifi960.c b/firmware/target/arm/rk27xx/ihifi/powermgmt-ihifi960.c
new file mode 100644
index 0000000..c8797c0
--- /dev/null
+++ b/firmware/target/arm/rk27xx/ihifi/powermgmt-ihifi960.c
@@ -0,0 +1,65 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright © 2013 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-60x.
+
+    Battery voltage is calculated under the assumption that the adc full-scale
+    readout represents 3.00V and that the battery ADC channel is fed with
+    exactly half of the battery voltage (through a resistive divider).
+    Charge curve have not been calibrated yet.
+*/
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+    /* TODO: this is just an initial guess */
+    7050,
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+    7000,
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+    /* FIXME: Uncalibrated curve */
+    { 7000, 7050, 7100, 7150, 7200, 7250, 7300, 7350, 7400, 7450, 7500 }
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+    /* TODO: simple copy of discharge curve */
+    { 7000, 7050, 7100, 7150, 7200, 7250, 7300, 7350, 7400, 7450, 7500 };
+
+/* full-scale ADC readout (2^10) in millivolt */
+#define BATTERY_SCALE_FACTOR 13000
+
+/* Returns battery voltage from ADC [millivolts] */
+int _battery_voltage(void)
+{
+    return (adc_read(ADC_BATTERY) * BATTERY_SCALE_FACTOR) >> 10;
+}
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index 9f6ba46..deca8a1 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -134,6 +134,9 @@
     return !(GPIO_PFDR & (1<<2));
 #elif defined(MA9) || defined(MA9C) || defined(MA8) || defined(MA8C)
     return (GPIO_PCDR & 0x80);
+#elif defined(IHIFI760) || defined(IHIFI960)
+    /* TODO: find out pin */
+    return true;
 #else
 #error "Unknown target"
 #endif
diff --git a/tools/configure b/tools/configure
index b33c798..08b0e25 100755
--- a/tools/configure
+++ b/tools/configure
@@ -1336,6 +1336,11 @@
  205) Samsung YP-R0       213) MA8C              221) NWZ-E360 series
  206) Android MIPS
  207) Android x86
+
+==IHIFI==
+ 230) 760
+ 231) 960
+
 EOF
 
   buildfor=`input`;
@@ -3648,6 +3653,52 @@
     arm926ejscc
     ;;
 
+   230|ihifi760)
+    target_id=92
+    modelname="ihifi760"
+    target="IHIFI760"
+    memory=16
+    arm7ejscc
+    tool="$rootdir/tools/scramble -rkw -modelnum=92"
+    bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
+    bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
+    output="rockbox.rkw"
+    bootoutput="bootloader.rkw"
+    appextra="recorder:gui"
+    plugins=""
+    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="ihifi"
+    ;;
+
+   231|ihifi960)
+    target_id=93
+    modelname="ihifi960"
+    target="IHIFI960"
+    memory=16
+    arm7ejscc
+    tool="$rootdir/tools/scramble -rkw -modelnum=93"
+    bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
+    bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
+    output="rockbox.rkw"
+    bootoutput="bootloader.rkw"
+    appextra="recorder:gui"
+    plugins=""
+    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="ihifi"
+    ;;
+
    *)
     echo "Please select a supported target platform!"
     exit 7