diff --git a/apps/SOURCES b/apps/SOURCES index 918ee1e4fc..f0c9462faf 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -302,5 +302,6 @@ keymaps/keymap-nwz.c keymaps/keymap-ypz5.c #elif CONFIG_KEYPAD == IHIFI_PAD keymaps/keymap-ihifi.c +#elif CONFIG_KEYPAD == SAMSUNG_YPR1_PAD +keymaps/keymap-ypr1.c #endif - diff --git a/apps/audio_path.c b/apps/audio_path.c index 9ef748382f..c4a4d1b277 100644 --- a/apps/audio_path.c +++ b/apps/audio_path.c @@ -42,7 +42,7 @@ #endif #endif -#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0)) +#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)) #ifdef AUDIO_CPU_BOOST static void audio_cpu_boost(bool state) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 7c399350b2..1007c97414 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -78,7 +78,7 @@ #endif #include "power.h" -#if defined(SAMSUNG_YPR0) && defined(CONFIG_TUNER) +#if (defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)) && defined(CONFIG_TUNER) #include "tuner.h" #include "radio.h" #endif diff --git a/apps/keymaps/keymap-ypr1.c b/apps/keymaps/keymap-ypr1.c new file mode 100644 index 0000000000..d47047912b --- /dev/null +++ b/apps/keymaps/keymap-ypr1.c @@ -0,0 +1,171 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: keymap-sdl.c 28704 2010-11-29 11:28:53Z teru $ + * + * Copyright (C) 2013 Lorenzo Miori + * + * 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 Samsung YP-R1 target */ + +#include +#include +#include + +#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_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, + + LAST_ITEM_IN_LIST +}; /* button_context_standard */ + +static const struct button_mapping button_context_wps[] = { + + { ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_KEYLOCK, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, + LAST_ITEM_IN_LIST +}; /* button_context_wps */ + +static const struct button_mapping button_context_list[] = { + +#ifdef HAVE_VOLUME_IN_LIST + { ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_LIST_VOLUP, BUTTON_VOL_UP, BUTTON_NONE }, + { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE }, + { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, +#endif + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_list */ + +static const struct button_mapping button_context_tree[] = { + { ACTION_TREE_STOP, BUTTON_POWER|BUTTON_REPEAT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST) +}; /* button_context_tree */ + +static const struct button_mapping button_context_settings[] = { + + { ACTION_SETTINGS_INC, BUTTON_VOL_UP, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_TREE) +}; /* button_context_settings */ + +static const struct button_mapping button_context_settings_right_is_inc[] = { + { ACTION_SETTINGS_INC, BUTTON_VOL_UP, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT,BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_NONE, BUTTON_VOL_UP|BUTTON_REL, BUTTON_VOL_UP }, + + { ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT,BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_NONE, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_VOL_DOWN }, + + { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), +}; /* button_context_settings_right_is_inc */ + +static const struct button_mapping button_context_yesno[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_settings_yesno */ + +static const struct button_mapping button_context_colorchooser[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS), +}; /* button_context_colorchooser */ + +static const struct button_mapping button_context_eq[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS), +}; /* button_context_eq */ + +/** Bookmark Screen **/ +static const struct button_mapping button_context_bmark[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), +}; /* button_context_bmark */ + +static const struct button_mapping button_context_quickscreen[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_quickscreen */ + +static const struct button_mapping button_context_pitchscreen[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_pitchcreen */ + +static const struct button_mapping button_context_keyboard[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_keyboard */ + +/** FM Radio Screen **/ +static const struct button_mapping button_context_radio[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) +}; /* button_context_radio */ + +const struct button_mapping* target_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_CUSTOM|CONTEXT_TREE: + return button_context_tree; + + case CONTEXT_SETTINGS: + case CONTEXT_SETTINGS_TIME: + return button_context_settings; + case CONTEXT_CUSTOM|CONTEXT_SETTINGS: + case CONTEXT_SETTINGS_COLOURCHOOSER: + case CONTEXT_SETTINGS_EQ: + case CONTEXT_SETTINGS_RECTRIGGER: + return button_context_settings_right_is_inc; + + case CONTEXT_YESNOSCREEN: + return button_context_yesno; + case CONTEXT_FM: + return button_context_radio; + 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 42bc2f36c3..0778ab74d3 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -12368,15 +12368,15 @@ user: core *: none - gigabeats: "Tone Controls" + gigabeats,samsungypr1: "Tone Controls" *: none - gigabeats: "Tone Controls" + gigabeats,samsungypr1: "Tone Controls" *: none - gigabeats: "Tone Controls" + gigabeats,samsungypr1: "Tone Controls" @@ -12385,15 +12385,15 @@ user: core *: none - gigabeats: "Advanced Tone Control Settings" + gigabeats,samsungypr1: "Advanced Tone Control Settings" *: none - gigabeats: "Advanced Tone Control Settings" + gigabeats,samsungypr1: "Advanced Tone Control Settings" *: none - gigabeats: "Advanced Tone Control Settings" + gigabeats,samsungypr1: "Advanced Tone Control Settings" @@ -12402,15 +12402,15 @@ user: core *: none - gigabeats: "Band %d Gain" + gigabeats,samsungypr1: "Band %d Gain" *: none - gigabeats: "Band %d Gain" + gigabeats,samsungypr1: "Band %d Gain" *: none - gigabeats: "Band Gain" + gigabeats,samsungypr1: "Band Gain" @@ -12419,15 +12419,15 @@ user: core *: none - gigabeats: "Band %d Frequency" + gigabeats,samsungypr1: "Band %d Frequency" *: none - gigabeats: "Band %d Frequency" + gigabeats,samsungypr1: "Band %d Frequency" *: none - gigabeats: "Band Frequency" + gigabeats,samsungypr1: "Band Frequency" @@ -12436,15 +12436,15 @@ user: core *: none - gigabeats: "Band %d Width" + gigabeats,samsungypr1: "Band %d Width" *: none - gigabeats: "Band %d Width" + gigabeats,samsungypr1: "Band %d Width" *: none - gigabeats: "Band Width" + gigabeats,samsungypr1: "Band Width" @@ -12453,15 +12453,15 @@ user: core *: none - gigabeats: "Narrow" + gigabeats,samsungypr1: "Narrow" *: none - gigabeats: "Narrow" + gigabeats,samsungypr1: "Narrow" *: none - gigabeats: "Narrow" + gigabeats,samsungypr1: "Narrow" @@ -12470,15 +12470,15 @@ user: core *: none - gigabeats: "Wide" + gigabeats,samsungypr1: "Wide" *: none - gigabeats: "Wide" + gigabeats,samsungypr1: "Wide" *: none - gigabeats: "Wide" + gigabeats,samsungypr1: "Wide" diff --git a/apps/plugins/clix.c b/apps/plugins/clix.c index 14b0b09cda..59cf162b0a 100644 --- a/apps/plugins/clix.c +++ b/apps/plugins/clix.c @@ -221,6 +221,9 @@ #define CLIX_BUTTON_RIGHT BUTTON_RIGHT #define CLIX_BUTTON_CLICK BUTTON_SELECT +#elif (CONFIG_KEYPAD == SAMSUNG_YPR1_PAD) +#define CLIX_BUTTON_QUIT BUTTON_POWER + #else #error "no keymap" #endif diff --git a/apps/plugins/reversi/reversi-gui.h b/apps/plugins/reversi/reversi-gui.h index 47b7ff204d..124cf471bb 100644 --- a/apps/plugins/reversi/reversi-gui.h +++ b/apps/plugins/reversi/reversi-gui.h @@ -283,6 +283,9 @@ #define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT #define REVERSI_BUTTON_MENU BUTTON_POWER +#elif CONFIG_KEYPAD == SAMSUNG_YPR1_PAD +#define REVERSI_BUTTON_QUIT BUTTON_POWER + #else #error No keymap defined! #endif diff --git a/firmware/SOURCES b/firmware/SOURCES index 15f42a4011..f062a015bd 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -101,6 +101,29 @@ target/hosted/samsungypr/radio-ypr.c #endif #endif +#ifdef SAMSUNG_YPR1 +drivers/lcd-memframe.c +target/hosted/kernel-unix.c +target/hosted/filesystem-unix.c +target/hosted/lc-unix.c +target/hosted/samsungypr/ypr1/mcs5000-ypr1.c +target/hosted/samsungypr/ypr1/button-ypr1.c +target/hosted/samsungypr/lcd-ypr.c +target/hosted/samsungypr/ypr1/system-ypr1.c +thread.c +#ifdef HAVE_BACKLIGHT +target/hosted/samsungypr/ypr1/backlight-ypr1.c +#endif +target/hosted/samsungypr/ypr1/powermgmt-ypr1.c +target/hosted/samsungypr/gpio_ypr.c +target/hosted/samsungypr/ypr1/audio-ypr1.c +target/hosted/samsungypr/ypr1/pmu-ypr1.c +target/hosted/samsungypr/ypr1/wmcodec-ypr1.c +#if CONFIG_TUNER +target/hosted/samsungypr/radio-ypr.c +#endif +#endif + /* Maemo specific files */ #if (CONFIG_PLATFORM & PLATFORM_MAEMO) target/hosted/maemo/maemo-thread.c @@ -318,7 +341,7 @@ drivers/rtc/rtc_imx233.c /* Tuner */ #if CONFIG_TUNER tuner.c -#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0)) +#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)) #if (CONFIG_TUNER & LV24020LP) drivers/tuner/lv24020lp.c #endif /* (CONFIG_TUNER & LV24020LP) */ @@ -417,6 +440,9 @@ drivers/audio/pcm1792.c #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) drivers/audio/as3514.c target/hosted/pcm-alsa.c +#elif defined(SAMSUNG_YPR1) && defined(HAVE_WM8978) +drivers/audio/wm8978.c +target/hosted/pcm-alsa.c #elif defined(HAVE_SDL_AUDIO) drivers/audio/sdl.c #if CONFIG_CODEC == SWCODEC diff --git a/firmware/asm/SOURCES b/firmware/asm/SOURCES index 23563d11d8..0cd351efdd 100644 --- a/firmware/asm/SOURCES +++ b/firmware/asm/SOURCES @@ -10,7 +10,7 @@ strlen.c #if (defined(SANSA_E200) || defined(GIGABEAT_F) || defined(GIGABEAT_S) || \ defined(CREATIVE_ZVx) || defined(SANSA_CONNECT) || defined(SANSA_FUZEPLUS) || \ defined(COWON_D2) || defined(MINI2440) || defined(SAMSUNG_YPR0) || \ - (defined(MROBE_500) && !defined(LCD_USE_DMA))) && \ + defined(SAMSUNG_YPR1) || (defined(MROBE_500) && !defined(LCD_USE_DMA))) && \ !defined(SIMULATOR) lcd-as-memframe.c #endif diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c index 1da009b399..a188cf6642 100644 --- a/firmware/common/rbpaths.c +++ b/firmware/common/rbpaths.c @@ -40,7 +40,7 @@ #undef rmdir -#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(SAMSUNG_YPR0) && !defined(__PCTOOL__) +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) && !defined(__PCTOOL__) #include "dir-target.h" #define opendir _opendir #define mkdir _mkdir @@ -63,7 +63,7 @@ extern int sim_rmdir(const char* name); const char *rbhome; #endif -#if !defined(SAMSUNG_YPR0) && !defined(__PCTOOL__) +#if !(defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)) && !defined(__PCTOOL__) /* flags for get_user_file_path() */ /* whether you need write access to that file/dir, especially true diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c index 0730ff5118..adc46c316f 100644 --- a/firmware/drivers/audio/wm8978.c +++ b/firmware/drivers/audio/wm8978.c @@ -499,7 +499,7 @@ void audiohw_enable_depth_3d(bool enable) audiohw_set_depth_3d(wmc_vol.enh_3d); } -#ifdef HAVE_RECORDING +#if defined(HAVE_RECORDING) || defined(SAMSUNG_YPR1) void audiohw_set_recsrc(int source, bool recording) { switch (source) @@ -561,6 +561,23 @@ void audiohw_set_recsrc(int source, bool recording) /* Enable bypass to L/R mixers */ wmc_set(WMC_LEFT_MIXER_CTRL, WMC_BYPL2LMIX); wmc_set(WMC_RIGHT_MIXER_CTRL, WMC_BYPR2RMIX); +#ifdef SAMSUNG_YPR1 + /* On Samsung YP-R1 we have to do some extra steps to select the AUX + * analog input source i.e. where the audio lines of the FM tuner are. + */ + wmc_set(WMC_LEFT_MIXER_CTRL, WMC_AUXL2LMIX); + wmc_set(WMC_RIGHT_MIXER_CTRL, WMC_AUXR2RMIX); + /* Set L/R AUX input gain to 0dB */ + wmc_write_masked(WMC_LEFT_MIXER_CTRL, 0x05 << WMC_AUXLMIXVOL_POS, + WMC_AUXLMIXVOL); + wmc_write_masked(WMC_RIGHT_MIXER_CTRL, 0x05 << WMC_AUXRMIXVOL_POS, + WMC_AUXRMIXVOL); + wmc_set(WMC_LEFT_MIXER_CTRL, WMC_DACL2LMIX); + wmc_set(WMC_RIGHT_MIXER_CTRL, WMC_DACR2RMIX); + wmc_set(WMC_POWER_MANAGEMENT1, WMC_OUT3MIXEN); + wmc_set(WMC_POWER_MANAGEMENT3, WMC_RMIXEN); + wmc_set(WMC_POWER_MANAGEMENT3, WMC_LMIXEN); +#endif } break; } diff --git a/firmware/export/config.h b/firmware/export/config.h index b72aa33fa9..d2e1f6b830 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -152,6 +152,7 @@ #define CREATIVE_ZEN_PAD 58 #define SAMSUNG_YPZ5_PAD 59 #define IHIFI_PAD 60 +#define SAMSUNG_YPR1_PAD 61 /* CONFIG_REMOTE_KEYPAD */ #define H100_REMOTE 1 @@ -263,6 +264,7 @@ #define LCD_SAMSUNGYPZ5 59 /* as used by Samsung YP-Z5 */ #define LCD_IHIFI 60 /* as used by IHIFI 760/960 */ #define LCD_CREATIVEZENXFISTYLE 61 /* as used by Creative Zen X-Fi Style */ +#define LCD_SAMSUNGYPR1 62 /* as used by Samsung YP-R1 */ /* LCD_PIXELFORMAT */ #define HORIZONTAL_PACKING 1 @@ -559,6 +561,8 @@ Lyre prototype 1 */ #include "config/ihifi960.h" #elif defined(CREATIVE_ZENXFISTYLE) #include "config/creativezenxfistyle.h" +#elif defined(SAMSUNG_YPR1) +#include "config/samsungypr1.h" #else /* no known platform */ #endif diff --git a/firmware/export/config/samsungypr1.h b/firmware/export/config/samsungypr1.h new file mode 100644 index 0000000000..a590dd553d --- /dev/null +++ b/firmware/export/config/samsungypr1.h @@ -0,0 +1,152 @@ +/* + * This config file is for the RockBox as application on the Samsung YP-R1 player. + * The target name for ifdefs is: SAMSUNG_YPR1; or CONFIG_PLATFORM & PLAFTORM_YPR1 + */ + +/* We don't run on hardware directly */ +/* YP-R1 need it too of course */ +#define CONFIG_PLATFORM (PLATFORM_HOSTED) + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 101 + +#define MODEL_NAME "Samsung YP-R1" + +#define USB_NONE + +/* 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 the LCD can shut down */ +#define HAVE_LCD_SHUTDOWN + +/* define this if you have LCD enable function */ +#define HAVE_LCD_ENABLE + +/* 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 have access to the quickscreen */ +#define HAVE_QUICKSCREEN + +/* define this if you would like tagcache to build on this target */ +#define HAVE_TAGCACHE + +/* We try to support both orientation, looking forward for a future dynamic switch */ +#define CONFIG_ORIENTATION SCREEN_PORTRAIT + +/* LCD dimensions */ +#if CONFIG_ORIENTATION == SCREEN_PORTRAIT +#define LCD_WIDTH 240 +#define LCD_HEIGHT 400 +#else +#define LCD_WIDTH 400 +#define LCD_HEIGHT 240 +#endif + +#define LCD_DEPTH 16 +/* Calculated value, important for touch sensor */ +#define LCD_DPI 180 +/* Check that but should not matter */ +#define LCD_PIXELFORMAT RGB565 + +/* Capacitive touchscreen */ +#define HAVE_TOUCHSCREEN +#define HAVE_BUTTON_DATA + +/* We have backlight to control */ +#define HAVE_BACKLIGHT + +/* Define this for LCD backlight brightness available */ +#define HAVE_BACKLIGHT_BRIGHTNESS + +/* Main LCD backlight brightness range and defaults */ +/* From 0 to 32. Default is 18, that is set by the bootloader + * We stay a little lower since OF makes a distinction between + * two LCD screens (there is no reason to go further than 25 in any case) + */ +#define MIN_BRIGHTNESS_SETTING 1 +#define MAX_BRIGHTNESS_SETTING 25 +#define DEFAULT_BRIGHTNESS_SETTING 18 + +/* Which backlight fading type? */ +#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING + +/* The number of bytes reserved for loadable codecs */ +#define CODEC_SIZE 0x80000 + +/* The number of bytes reserved for loadable plugins */ +#define PLUGIN_BUFFER_SIZE 0x100000 + +#define AB_REPEAT_ENABLE + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC + +/* R1 KeyPad configuration for plugins */ +#define CONFIG_KEYPAD SAMSUNG_YPR1_PAD +#define BUTTON_DRIVER_CLOSE + +/* We have WM1808, which so far is compatible with the following */ +#define HAVE_WM8978 + +/* For the moment the only supported frequency is 44kHz, + * even if the codec supports more (see wmcodec-ypr1.c) + */ +#define HW_SAMPR_CAPS SAMPR_CAP_44 + +/* define the bitmask of recording sample rates */ +#define REC_SAMPR_CAPS HW_SAMPR_CAPS /* Same as playback */ + +/* We have the Si4709 */ +#define CONFIG_TUNER SI4700 +#define HAVE_TUNER_PWR_CTRL +#define HAVE_RDS_CAP + +/* Define this for FM radio input available */ +#define HAVE_FMRADIO_IN +#define INPUT_SRC_CAPS SRC_CAP_FMRADIO + +/* We have a GPIO pin that detects it */ +#define HAVE_HEADPHONE_DETECTION + +/* R1 has a standard linux RTC driver on /dev/rtc1 (->/dev/rtc) + * The RTC is S35392 A + */ +#define CONFIG_RTC APPLICATION + +#define BATTERY_CAPACITY_DEFAULT 600 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 600 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 600 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 0 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ + +/* Define current usage levels. */ +#define CURRENT_NORMAL 24 /* ~25h, on 600mAh that's about 24mA */ +#define CURRENT_BACKLIGHT 62 /* ~6,5h -> 92mA. Minus 24mA normal that gives us 68mA */ + +/* R1's fuel gauge max17040 can supply both kind of values */ +#define CONFIG_BATTERY_MEASURE PERCENTAGE_MEASURE + +/* Hardware controls charging, we can monitor */ +#define CONFIG_CHARGING CHARGING_MONITOR + +#define CONFIG_LCD LCD_SAMSUNGYPR1 + +/* Define this if you have a software controlled poweroff */ +#define HAVE_SW_POWEROFF + +/* define this if the target has volume keys which can be used in the lists */ +#define HAVE_VOLUME_IN_LIST + +/* This mount point resides in the rootfs, binded to /mnt/media0/.rockbox */ +#define BOOTDIR "/.rockbox" diff --git a/firmware/export/rbpaths.h b/firmware/export/rbpaths.h index d50f66d72d..9fa1d32286 100644 --- a/firmware/export/rbpaths.h +++ b/firmware/export/rbpaths.h @@ -40,9 +40,9 @@ #define ROCKBOX_DIR_LEN (sizeof(ROCKBOX_DIR)-1) #endif /* def __PCTOOL__ */ -#if !defined(APPLICATION) || defined(SAMSUNG_YPR0) +#if !defined(APPLICATION) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) -#ifdef SAMSUNG_YPR0 +#if defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) #define HOME_DIR "/mnt/media0" #else #define HOME_DIR "/" @@ -83,7 +83,7 @@ extern void paths_init(void); #define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos" #define VIEWERS_DIR PLUGIN_DIR "/viewers" -#if defined(APPLICATION) && !defined(SAMSUNG_YPR0) +#if defined(APPLICATION) && !(defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)) #define PLUGIN_DATA_DIR ROCKBOX_DIR "/rocks.data" #define PLUGIN_GAMES_DATA_DIR PLUGIN_DATA_DIR #define PLUGIN_APPS_DATA_DIR PLUGIN_DATA_DIR diff --git a/firmware/include/dir_uncached.h b/firmware/include/dir_uncached.h index 017b86cc39..1f9b8c1a4e 100644 --- a/firmware/include/dir_uncached.h +++ b/firmware/include/dir_uncached.h @@ -74,7 +74,7 @@ typedef struct { #if defined(APPLICATION) && !defined(__PCTOOL__) -#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(SAMSUNG_YPR0) +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) #include "dir-target.h" #endif # undef opendir_uncached diff --git a/firmware/target/hosted/samsungypr/gpio_ypr.c b/firmware/target/hosted/samsungypr/gpio_ypr.c index 40855fba41..1782d4cfe4 100644 --- a/firmware/target/hosted/samsungypr/gpio_ypr.c +++ b/firmware/target/hosted/samsungypr/gpio_ypr.c @@ -6,7 +6,7 @@ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * - * Module wrapper for GPIO, using /dev/r0GPIO (r0Gpio.ko) of Samsung YP-R0 + * Module wrapper for GPIO, using kernel module of Samsung YP-R0/YP-R1 * * Copyright (c) 2011 Lorenzo Miori * @@ -26,23 +26,23 @@ #include /* includes common ioctl device definitions */ #include -static int r0_gpio_dev = 0; +static int gpio_dev = 0; void gpio_init(void) { - r0_gpio_dev = open("/dev/r0GPIO", O_RDONLY); - if (r0_gpio_dev < 0) - printf("/dev/r0GPIO open error!"); + gpio_dev = open(GPIO_DEVICE, O_RDONLY); + if (gpio_dev < 0) + printf("GPIO device open error!"); } void gpio_close(void) { - if (r0_gpio_dev >= 0) - close(r0_gpio_dev); + if (gpio_dev >= 0) + close(gpio_dev); } int gpio_control(int request, int num, int mode, int val) { struct gpio_info r = { .num = num, .mode = mode, .val = val, }; - return ioctl(r0_gpio_dev, request, &r); + return ioctl(gpio_dev, request, &r); } diff --git a/firmware/target/hosted/samsungypr/ypr0/gpio-target.h b/firmware/target/hosted/samsungypr/ypr0/gpio-target.h index c27e07bf40..f27b176195 100644 --- a/firmware/target/hosted/samsungypr/ypr0/gpio-target.h +++ b/firmware/target/hosted/samsungypr/ypr0/gpio-target.h @@ -53,6 +53,7 @@ #define GPIO_LEFT_KEY GPIO2_28 #define GPIO_RIGHT_KEY GPIO3_7 +#define GPIO_DEVICE "/dev/r0GPIO" void gpio_init(void); void gpio_close(void); diff --git a/firmware/target/hosted/samsungypr/ypr1/audio-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/audio-ypr1.c new file mode 100644 index 0000000000..05b77a8ff2 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/audio-ypr1.c @@ -0,0 +1,76 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Nils Wallménius + * + * 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 "audiohw.h" +#include "audio.h" + +void audiohw_enable_tone_controls(bool enable); +void audiohw_enable_depth_3d(bool enable); + +/* Set the audio source for IIS TX */ +void audio_set_output_source(int source) +{ + switch (source) + { + default: + case AUDIO_SRC_PLAYBACK: + /* + audiohw_enable_tone_controls(true); + audiohw_enable_depth_3d(true); + */ + break; + + case AUDIO_SRC_FMRADIO: + /* Analog path doesn't support these and digital radio playback + * cannot be done without mixing on the MCU if voice is to be + * heard. Any recording should match what is heard. */ + audiohw_enable_tone_controls(false); + audiohw_enable_depth_3d(false); + break; + } +} + +void audio_input_mux(int source, unsigned int flags) +{ + /* Prevent pops from unneeded switching */ + static int last_source = AUDIO_SRC_PLAYBACK; + bool recording = flags & SRCF_RECORDING; + static bool last_recording = false; + + switch (source) + { + default: + source = AUDIO_SRC_PLAYBACK; + /* Fallthrough */ + case AUDIO_SRC_PLAYBACK: /* playback - no recording */ + if (source != last_source) + audiohw_set_recsrc(AUDIO_SRC_PLAYBACK, false); + break; + + case AUDIO_SRC_FMRADIO: /* recording and playback */ + if (source != last_source || recording != last_recording) + audiohw_set_recsrc(AUDIO_SRC_FMRADIO, recording); + break; + } + + last_source = source; + last_recording = recording; +} diff --git a/firmware/target/hosted/samsungypr/ypr1/backlight-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/backlight-ypr1.c new file mode 100644 index 0000000000..e4f0457cf9 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/backlight-ypr1.c @@ -0,0 +1,66 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2013 by Lorenzo Miori + * + * 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 "backlight.h" +#include "backlight-target.h" +#include "lcd.h" +#include "lcd-target.h" +#include "pmu-ypr1.h" + +static bool backlight_on_status = true; /* Is on or off? */ + +bool _backlight_init(void) +{ + /* We have nothing to do */ + return true; +} + +void _backlight_on(void) +{ + if (!backlight_on_status) { + _backlight_set_brightness(backlight_brightness); + } + + backlight_on_status = true; + +} + +void _backlight_off(void) +{ + if (backlight_on_status) { + _backlight_set_brightness(0); + } + + backlight_on_status = false; +} + +void _backlight_set_brightness(int brightness) +{ + /* Just another check... */ + if (brightness > MAX_BRIGHTNESS_SETTING) { + brightness = MAX_BRIGHTNESS_SETTING; + } + if (brightness < 0) { + brightness = MIN_BRIGHTNESS_SETTING; + } + /* Do the appropriate ioctl on the linux module */ + pmu_ioctl(MAX8819_IOCTL_LCD_DIM_CTRL, &brightness); +} diff --git a/firmware/target/hosted/samsungypr/ypr1/button-target.h b/firmware/target/hosted/samsungypr/ypr1/button-target.h new file mode 100644 index 0000000000..fc618258c0 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/button-target.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2013 by Lorenzo Miori + * + * 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_ + +void button_close_device(void); + +/* Logical buttons key codes */ +#define BUTTON_VOL_UP 0x00000001 +#define BUTTON_VOL_DOWN 0x00000002 +#define BUTTON_POWER 0x00000004 +#define BUTTON_RIGHT 0x00000008 +#define BUTTON_LEFT 0x00000012 + +/* Touch Screen Area Buttons */ +#define BUTTON_TOPLEFT 0x00000010 +#define BUTTON_TOPMIDDLE 0x00000020 +#define BUTTON_TOPRIGHT 0x00000040 +#define BUTTON_MIDLEFT 0x00000080 +#define BUTTON_CENTER 0x00000100 +#define BUTTON_MIDRIGHT 0x00000200 +#define BUTTON_BOTTOMLEFT 0x00000400 +#define BUTTON_BOTTOMMIDDLE 0x00000800 +#define BUTTON_BOTTOMRIGHT 0x00001000 + +/* All the buttons */ +#define BUTTON_MAIN (BUTTON_VOL_UP | BUTTON_VOL_DOWN | BUTTON_POWER | \ + BUTTON_RIGHT|BUTTON_LEFT| BUTTON_TOPLEFT | BUTTON_TOPMIDDLE | \ + BUTTON_TOPRIGHT | BUTTON_MIDLEFT | BUTTON_CENTER | \ + BUTTON_MIDRIGHT | BUTTON_BOTTOMLEFT | BUTTON_BOTTOMMIDDLE | \ + BUTTON_BOTTOMRIGHT) /* all buttons */ + +/* Default touchscreen calibration + * TODO this is not 100% accurate. X-AXIS must be slightly moved to the right + */ +#define DEFAULT_TOUCHSCREEN_CALIBRATION {.A=0x0000AD7C, .B=0xFFFFFC70, \ + .C=0xFF6632E0, .D=0xFFFFFF1A, .E=0xFFFF5D08, \ + .F=0xFFFC4230, .divider=0xFFFF54E0} + +/* Software power-off */ +#define POWEROFF_BUTTON BUTTON_POWER +/* About 3 seconds */ +#define POWEROFF_COUNT 10 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c new file mode 100644 index 0000000000..09891cfaf6 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c @@ -0,0 +1,130 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: button-sdl.c 30482 2011-09-08 14:53:28Z kugel $ + * + * Copyright (C) 2013 Lorenzo Miori + * + * 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 "button.h" +#include "kernel.h" +#include "system.h" +#include "button-target.h" + +#include /* For headphones sense and buttons */ +#include "mcs5000.h" /* Touchscreen controller */ +#include "ioctl-ypr1.h" + +enum { + STATE_UNKNOWN, + STATE_UP, + STATE_DOWN, +}; + +static int last_x = 0; +static int last_y = 0; +static int last_touch_state = STATE_UNKNOWN; + +int button_read_device(int *data) +{ + int key = BUTTON_NONE; + int read_size; + struct mcs5000_raw_data touchpad_data; + + /* Check for all the keys */ + if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_UP_KEY, 0, 0)) { + key |= BUTTON_VOL_UP; + } + if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_DOWN_KEY, 0, 0)) { + key |= BUTTON_VOL_DOWN; + } + if (gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_POWER_KEY, 0, 0)) { + key |= BUTTON_POWER; + } + + read_size = mcs5000_read(&touchpad_data); + + if (read_size == sizeof(struct mcs5000_raw_data)) { + /* Generate UP and DOWN events */ + if (touchpad_data.inputInfo & INPUT_TYPE_SINGLE) { + last_touch_state = STATE_DOWN; + } + else { + last_touch_state = STATE_UP; + } + /* Swap coordinates here */ +#if CONFIG_ORIENTATION == SCREEN_PORTRAIT + last_x = (touchpad_data.yHigh << 8) | touchpad_data.yLow; + last_y = (touchpad_data.xHigh << 8) | touchpad_data.xLow; +#else + last_x = (touchpad_data.xHigh << 8) | touchpad_data.xLow; + last_y = (touchpad_data.yHigh << 8) | touchpad_data.yLow; +#endif + } + + int tkey = touchscreen_to_pixels(last_x, last_y, data); + + if (last_touch_state == STATE_DOWN) { + key |= tkey; + } + + return key; +} + +#ifndef HAS_BUTTON_HOLD +void touchscreen_enable_device(bool en) +{ + if (en) { + mcs5000_power(); + } + else { + mcs5000_shutdown(); + } +} +#endif + +bool headphones_inserted(void) +{ + /* GPIO low - 0 - means headphones inserted */ + return !gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_HEADPHONE_SENSE, 0, 0); +} + +void button_init_device(void) +{ + /* Setup GPIO pin for headphone sense, copied from OF + * Pins for the other buttons are already set up by OF button module + */ + gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_HEADPHONE_SENSE, 4, 0); + gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_HEADPHONE_SENSE, 4, 0); + + /* Turn on touchscreen */ + mcs5000_init(); + mcs5000_power(); + mcs5000_set_hand(RIGHT_HAND); +} + +#ifdef BUTTON_DRIVER_CLOSE +/* I'm not sure it's called at shutdown...give a check! */ +void button_close_device(void) +{ + gpio_control(DEV_CTRL_GPIO_UNSET_MUX, GPIO_HEADPHONE_SENSE, 0, 0); + + /* Turn off touchscreen device */ + mcs5000_shutdown(); + mcs5000_close(); +} +#endif /* BUTTON_DRIVER_CLOSE */ diff --git a/firmware/target/hosted/samsungypr/ypr1/gpio-target.h b/firmware/target/hosted/samsungypr/ypr1/gpio-target.h new file mode 100644 index 0000000000..f439e786de --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/gpio-target.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Module wrapper for GPIO, using /dev/r1GPIO (r1Gpio.ko) of Samsung YP-R1 + * + * Copyright (c) 2013 Lorenzo Miori + * + * 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 GPIO_TARGET_H +#define GPIO_TARGET_H + +#include "ioctl-ypr1.h" + +/* Some meaningful pins used in the YP-R1 */ + +#define GPIO_HEADPHONE_SENSE GPIO1_31 +/* I2C bus for the SI4079 FM, WM1808 codec and RTC radio chip */ +#define GPIO_I2C_CLK1 GPIO1_0 +#define GPIO_I2C_DAT1 GPIO1_1 +/* I2C bus for the fuel gauge MAX17040 */ +#define GPIO_I2C_CLK2 GPIO2_12 +#define GPIO_I2C_DAT2 GPIO2_13 +/* SI4079 pins - powerup and interrupt */ +#define GPIO_FM_SEARCH GPIO1_4 +#define GPIO_FM_BUS_EN GPIO1_10 +#define GPIO_MUTE GPIO2_17 +#define EXT_POWER_DET GPIO1_26 +/* Low disabled, high enabled */ +#define TV_OUT_ENABLE GPIO1_17 +/* Battery charging */ +#define CHARGE_ENABLE GPIO1_18 +#define CHARGE_STATUS GPIO_D13 +/* This should be high when connecting a special port to the board... */ +#define PBA_CHECK_ENABLED GPIO2_1 +/* TODO see if this is the source of massive battery drain + * touchscreen and usb 3.3v power control line + */ +#define POWER_3V3_LINE_CONTROL GPIO1_16 + +/* Keypad */ + +#define GPIO_VOL_UP_KEY GPIO1_20 +#define GPIO_VOL_DOWN_KEY GPIO1_21 +#define GPIO_POWER_KEY GPIO2_16 + +#define GPIO_DEVICE "/dev/r1Gpio" + +void gpio_init(void); +void gpio_close(void); +int gpio_control_struct(int request, struct gpio_info pin); +int gpio_control(int request, int num, int mode, int val); + +#endif /* GPIO_TARGET_H */ diff --git a/firmware/target/hosted/samsungypr/ypr1/ioctl-ypr1.h b/firmware/target/hosted/samsungypr/ypr1/ioctl-ypr1.h new file mode 100644 index 0000000000..4ac7a1c4b5 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/ioctl-ypr1.h @@ -0,0 +1,230 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2013 Lorenzo Miori + * + * 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 __DEV_IOCTL_YPR0_H__ +#define __DEV_IOCTL_YPR0_H__ + +#include +#include "stdint.h" + +/** + * This is the wrapper to r1Bat.ko module with the possible + * ioctl calls, retrieved by RE + * The "Fuel gauge" - battery controller - is the MAX17040GT + */ + +/* A typical read spans 2 registers */ +typedef struct { + uint8_t addr; + uint8_t reg1; + uint8_t reg2; +}__attribute__((packed)) max17040_request; + +/* Registers are 16-bit wide */ +#define MAX17040_GET_BATTERY_VOLTAGE 0x80045800 +#define MAX17040_GET_BATTERY_CAPACITY 0x80045801 +#define MAX17040_READ_REG 0x80035803 +#define MAX17040_WRITE_REG 0x40035802 + +void max17040_init(void); +void max17040_close(void); +int max17040_ioctl(int request, int *data); + +/** + * This is the wrapper to r1Gpio.ko module with the possible + * ioctl calls + * TODO move this into a more generic file for ypr platform + */ + +struct gpio_info { + int num; + int mode; + int val; +} __attribute__((packed)); + +/* Strangely for whatever reason magic differs from R0 (A vs. G) */ +#define IOCTL_GPIO_MAGIC 'A' + +#define E_IOCTL_GPIO_SET_MUX 0 +#define E_IOCTL_GPIO_UNSET_MUX 1 +#define E_IOCTL_GPIO_SET_TYPE 2 +#define E_IOCTL_GPIO_SET_OUTPUT 3 +#define E_IOCTL_GPIO_SET_INPUT 4 +#define E_IOCTL_GPIO_SET_HIGH 5 +#define E_IOCTL_GPIO_SET_LOW 6 +#define E_IOCTL_GPIO_GET_VAL 7 +#define E_IOCTL_GPIO_IS_HIGH 8 +#define E_IOCTL_GPIO_MAX_NR 9 + +#define DEV_CTRL_GPIO_SET_MUX _IOW(IOCTL_GPIO_MAGIC, 0, struct gpio_info) +#define DEV_CTRL_GPIO_UNSET_MUX _IOW(IOCTL_GPIO_MAGIC, 1, struct gpio_info) +#define DEV_CTRL_GPIO_SET_TYPE _IOW(IOCTL_GPIO_MAGIC, 2, struct gpio_info) +#define DEV_CTRL_GPIO_SET_OUTPUT _IOW(IOCTL_GPIO_MAGIC, 3, struct gpio_info) +#define DEV_CTRL_GPIO_SET_INPUT _IOW(IOCTL_GPIO_MAGIC, 4, struct gpio_info) +#define DEV_CTRL_GPIO_SET_HIGH _IOW(IOCTL_GPIO_MAGIC, 5, struct gpio_info) +#define DEV_CTRL_GPIO_SET_LOW _IOW(IOCTL_GPIO_MAGIC, 6, struct gpio_info) +#define DEV_CTRL_GPIO_GET_VAL _IOW(IOCTL_GPIO_MAGIC, 7, struct gpio_info) +#define DEV_CTRL_GPIO_IS_HIGH _IOW(IOCTL_GPIO_MAGIC, 8, struct gpio_info) + + +typedef enum +{ + GPIO1_0 = 0, /* GPIO group 1 start */ + GPIO1_1, + GPIO1_2, + GPIO1_3, + GPIO1_4, + GPIO1_5, + GPIO1_6, + GPIO1_7, + GPIO1_8, + GPIO1_9, + GPIO1_10, + GPIO1_11, + GPIO1_12, + GPIO1_13, + GPIO1_14, + GPIO1_15, + GPIO1_16, + GPIO1_17, + GPIO1_18, + GPIO1_19, + GPIO1_20, + GPIO1_21, + GPIO1_22, + GPIO1_23, + GPIO1_24, + GPIO1_25, + GPIO1_26, + GPIO1_27, + GPIO1_28, + GPIO1_29, + GPIO1_30, + GPIO1_31, + GPIO2_0, /* GPIO group 2 start */ + GPIO2_1, + GPIO2_2, + GPIO2_3, + GPIO2_4, + GPIO2_5, + GPIO2_6, + GPIO2_7, + GPIO2_8, + GPIO2_9, + GPIO2_10, + GPIO2_11, + GPIO2_12, + GPIO2_13, + GPIO2_14, + GPIO2_15, + GPIO2_16, + GPIO2_17, + GPIO2_18, + GPIO2_19, + GPIO2_20, + GPIO2_21, + GPIO2_22, + GPIO2_23, + GPIO2_24, + GPIO2_25, + GPIO2_26, + GPIO2_27, + GPIO2_28, + GPIO2_29, + GPIO2_30, + GPIO2_31, + GPIO3_0, /* GPIO group 3 start */ + GPIO3_1, + GPIO3_2, + GPIO3_3, + GPIO3_4, + GPIO3_5, + GPIO3_6, + GPIO3_7, + GPIO3_8, + GPIO3_9, + GPIO3_10, + GPIO3_11, + GPIO3_12, + GPIO3_13, + GPIO3_14, + GPIO3_15, + GPIO3_16, + GPIO3_17, + GPIO3_18, + GPIO3_19, + GPIO3_20, + GPIO3_21, + GPIO3_22, + GPIO3_23, + GPIO3_24, + GPIO3_25, + GPIO3_26, + GPIO3_27, + GPIO3_28, + GPIO3_29, + GPIO3_30, + GPIO3_31, +}R0_MX37_GPIO; + +typedef enum +{ + CONFIG_ALT0, + CONFIG_ALT1, + CONFIG_ALT2, + CONFIG_ALT3, + CONFIG_ALT4, + CONFIG_ALT5, + CONFIG_ALT6, + CONFIG_ALT7, + CONFIG_GPIO, + CONFIG_SION = 0x01 << 4, + CONFIG_DEFAULT +} R0_MX37_PIN_CONFIG; + +#ifndef __MACH_MX37_IOMUX_H__ +typedef enum +{ + PAD_CTL_SRE_SLOW = 0x0 << 0, + PAD_CTL_SRE_FAST = 0x1 << 0, + PAD_CTL_DRV_LOW = 0x0 << 1, + PAD_CTL_DRV_MEDIUM = 0x1 << 1, + PAD_CTL_DRV_HIGH = 0x2 << 1, + PAD_CTL_DRV_MAX = 0x3 << 1, + PAD_CTL_ODE_OPENDRAIN_NONE = 0x0 << 3, + PAD_CTL_ODE_OPENDRAIN_ENABLE = 0x1 << 3, + PAD_CTL_100K_PD = 0x0 << 4, + PAD_CTL_47K_PU = 0x1 << 4, + PAD_CTL_100K_PU = 0x2 << 4, + PAD_CTL_22K_PU = 0x3 << 4, + PAD_CTL_PUE_KEEPER = 0x0 << 6, + PAD_CTL_PUE_PULL = 0x1 << 6, + PAD_CTL_PKE_NONE = 0x0 << 7, + PAD_CTL_PKE_ENABLE = 0x1 << 7, + PAD_CTL_HYS_NONE = 0x0 << 8, + PAD_CTL_HYS_ENABLE = 0x1 << 8, + PAD_CTL_DDR_INPUT_CMOS = 0x0 << 9, + PAD_CTL_DDR_INPUT_DDR = 0x1 << 9, + PAD_CTL_DRV_VOT_LOW = 0x0 << 13, + PAD_CTL_DRV_VOT_HIGH = 0x1 << 13, +} R0_MX37_PAD_CONFIG; +#endif + +#endif /* __DEV_IOCTL_YPR0_H__ */ diff --git a/firmware/target/hosted/samsungypr/ypr1/mcs5000-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/mcs5000-ypr1.c new file mode 100644 index 0000000000..bfd9922768 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/mcs5000-ypr1.c @@ -0,0 +1,94 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (c) 2013 Lorenzo Miori + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include "sys/ioctl.h" + +#include "mcs5000.h" +#include "ioctl-ypr1.h" + +/* TODO Settings like hand and sensitivity will be lost when shutting device off!! */ + +static int mcs5000_dev = -1; +static int mcs5000_hand_setting = RIGHT_HAND; + +void mcs5000_init(void) +{ + mcs5000_dev = open("/dev/r1Touch", O_RDONLY); +} + +void mcs5000_close(void) +{ + if (mcs5000_dev > 0) + close(mcs5000_dev); +} + +void mcs5000_power(void) +{ + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_ON); + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_IDLE); + mcs5000_set_hand(mcs5000_hand_setting); +} + +void mcs5000_shutdown(void) +{ + /* save setting before shutting down the device */ + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_FLUSH); + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_RESET); + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_OFF); +} + +void mcs5000_set_hand(int hand) +{ + switch (hand) + { + case RIGHT_HAND: + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_RIGHTHAND); + break; + case LEFT_HAND: + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_LEFTHAND); + break; + default: + break; + } + mcs5000_hand_setting = hand; +} + +void mcs5000_set_sensitivity(int level) +{ + ioctl(mcs5000_dev, DEV_CTRL_TOUCH_SET_SENSE, &level); +} + +int mcs5000_read(struct mcs5000_raw_data *touchData) +{ + /* work around GCC bug: aligned attribute is not applied to automatic + * variables, and apparently this structure has a large alignment requirement + * (if it's only automatic with implicit 8-byte alignment then the + * touchscreen misbehaves). The bug seems fixed in gcc 4.6.x + * See http://http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16660 + * Also: packet and aligned attributes don't really work together so + * the aligned attribute cannot be attached to the struct declaration */ + static struct mcs5000_raw_data touchpad_data __attribute__((aligned(256))); + ssize_t ret; + ret = read(mcs5000_dev, &touchpad_data, sizeof(struct mcs5000_raw_data)); + *touchData = touchpad_data; + return ret; +} diff --git a/firmware/target/hosted/samsungypr/ypr1/mcs5000.h b/firmware/target/hosted/samsungypr/ypr1/mcs5000.h new file mode 100644 index 0000000000..45cce19a32 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/mcs5000.h @@ -0,0 +1,189 @@ + /* + * Unfortunately I couldn't find any datasheet for this touch controller nor + * any other information. I tried to send Melfas an email but their servers + * seem to be full in this period. The best thing I could find is a Linux + * driver written by Samsung. + * In the opensource package for YP-R1 there are also some more information + * in the file r1TouchMelfasReg.h, which at the moment are not used (I2C stuff + * and error codes) + * + * The rest, function definitions, are written by me (Lorenzo Miori) + * + * mcs5000_ts.c - Touchscreen driver for MELFAS MCS-5000 controller + * + * Copyright (C) 2009 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + * + * Based on wm97xx-core.c + * + * 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 is the wrapper to r1Touch.ko module with the possible + * ioctl calls + * The touchscreen controller is the Melfas MCS5000 + */ + +#define MCS5000_IOCTL_MAGIC 'X' + +#define MCS5000_IOCTL_TOUCH_RESET 0 +#define MCS5000_IOCTL_TOUCH_ON 1 +#define MCS5000_IOCTL_TOUCH_OFF 2 +#define MCS5000_IOCTL_TOUCH_FLUSH 3 +#define MCS5000_IOCTL_TOUCH_SLEEP 4 +#define MCS5000_IOCTL_TOUCH_WAKE 5 +#define MCS5000_IOCTL_TOUCH_ENTER_FWUPG_MODE 6 +#define MCS5000_IOCTL_TOUCH_I2C_READ 7 +#define MCS5000_IOCTL_TOUCH_I2C_WRITE 8 +#define MCS5000_IOCTL_TOUCH_RESET_AFTER_FWUPG 9 +#define MCS5000_IOCTL_TOUCH_RIGHTHAND 10 +#define MCS5000_IOCTL_TOUCH_LEFTHAND 11 +#define MCS5000_IOCTL_TOUCH_IDLE 12 +#define MCS5000_IOCTL_TOUCH_SET_SENSE 13 +#define MCS5000_IOCTL_TOUCH_GET_VER 14 +#define MCS5000_IOCTL_TOUCH_SET_REP_RATE 15 +#define MCS5000_IOCTL_TOUCH_ENABLE_WDOG 16 +#define MCS5000_IOCTL_TOUCH_DISABLE_WDOG 17 + +struct mcs5000_i2c_data +{ + int count; + unsigned char addr; + unsigned char pData[256]; +} __attribute__((packed)); + +#define DEV_CTRL_TOUCH_RESET _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_RESET) +#define DEV_CTRL_TOUCH_ON _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_ON) +#define DEV_CTRL_TOUCH_OFF _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_OFF) +#define DEV_CTRL_TOUCH_FLUSH _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_FLUSH) +#define DEV_CTRL_TOUCH_SLEEP _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_SLEEP) +#define DEV_CTRL_TOUCH_WAKE _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_WAKE) +#define DEV_CTRL_TOUCH_ENTER_FWUPG_MODE _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_ENTER_FWUPG_MODE) +#define DEV_CTRL_TOUCH_I2C_READ _IOWR(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_I2C_READ, mcs5000_i2c_data) +#define DEV_CTRL_TOUCH_I2C_WRITE _IOWR(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_I2C_WRITE, mcs5000_i2c_data) +#define DEV_CTRL_TOUCH_RESET_AFTER_FWUPG _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_RESET_AFTER_FWUPG) +#define DEV_CTRL_TOUCH_RIGHTHAND _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_RIGHTHAND) +#define DEV_CTRL_TOUCH_LEFTHAND _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_LEFTHAND) +#define DEV_CTRL_TOUCH_IDLE _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_IDLE) +#define DEV_CTRL_TOUCH_SET_SENSE _IOW(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_SET_SENSE, int) +#define DEV_CTRL_TOUCH_GET_VER _IOR(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_GET_VER, int) +#define DEV_CTRL_TOUCH_SET_REP_RATE _IOW(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_SET_REP_RATE, int) +#define DEV_CTRL_TOUCH_ENABLE_WDOG _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_ENABLE_WDOG) +#define DEV_CTRL_TOUCH_DISABLE_WDOG _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_DISABLE_WDOG) +#define DEV_CTRL_TOUCH_MAX_NR 18 + +/* Register definitions */ +#define MCS5000_TS_STATUS 0x00 +#define STATUS_OFFSET 0 +#define STATUS_NO (0 << STATUS_OFFSET) +#define STATUS_INIT (1 << STATUS_OFFSET) +#define STATUS_SENSING (2 << STATUS_OFFSET) +#define STATUS_COORD (3 << STATUS_OFFSET) +#define STATUS_GESTURE (4 << STATUS_OFFSET) +#define ERROR_OFFSET 4 +#define ERROR_NO (0 << ERROR_OFFSET) +#define ERROR_POWER_ON_RESET (1 << ERROR_OFFSET) +#define ERROR_INT_RESET (2 << ERROR_OFFSET) +#define ERROR_EXT_RESET (3 << ERROR_OFFSET) +#define ERROR_INVALID_REG_ADDRESS (8 << ERROR_OFFSET) +#define ERROR_INVALID_REG_VALUE (9 << ERROR_OFFSET) + +#define MCS5000_TS_OP_MODE 0x01 +#define RESET_OFFSET 0 +#define RESET_NO (0 << RESET_OFFSET) +#define RESET_EXT_SOFT (1 << RESET_OFFSET) +#define OP_MODE_OFFSET 1 +#define OP_MODE_SLEEP (0 << OP_MODE_OFFSET) +#define OP_MODE_ACTIVE (1 << OP_MODE_OFFSET) +#define GESTURE_OFFSET 4 +#define GESTURE_DISABLE (0 << GESTURE_OFFSET) +#define GESTURE_ENABLE (1 << GESTURE_OFFSET) +#define PROXIMITY_OFFSET 5 +#define PROXIMITY_DISABLE (0 << PROXIMITY_OFFSET) +#define PROXIMITY_ENABLE (1 << PROXIMITY_OFFSET) +#define SCAN_MODE_OFFSET 6 +#define SCAN_MODE_INTERRUPT (0 << SCAN_MODE_OFFSET) +#define SCAN_MODE_POLLING (1 << SCAN_MODE_OFFSET) +#define REPORT_RATE_OFFSET 7 +#define REPORT_RATE_40 (0 << REPORT_RATE_OFFSET) +#define REPORT_RATE_80 (1 << REPORT_RATE_OFFSET) + +#define MCS5000_TS_SENS_CTL 0x02 +#define MCS5000_TS_FILTER_CTL 0x03 +#define PRI_FILTER_OFFSET 0 +#define SEC_FILTER_OFFSET 4 + +#define MCS5000_TS_X_SIZE_UPPER 0x08 +#define MCS5000_TS_X_SIZE_LOWER 0x09 +#define MCS5000_TS_Y_SIZE_UPPER 0x0A +#define MCS5000_TS_Y_SIZE_LOWER 0x0B + +#define MCS5000_TS_INPUT_INFO 0x10 +#define INPUT_TYPE_OFFSET 0 +#define INPUT_TYPE_NONTOUCH (0 << INPUT_TYPE_OFFSET) +#define INPUT_TYPE_SINGLE (1 << INPUT_TYPE_OFFSET) +#define INPUT_TYPE_DUAL (2 << INPUT_TYPE_OFFSET) +#define INPUT_TYPE_PALM (3 << INPUT_TYPE_OFFSET) +#define INPUT_TYPE_PROXIMITY (7 << INPUT_TYPE_OFFSET) +#define GESTURE_CODE_OFFSET 3 +#define GESTURE_CODE_NO (0 << GESTURE_CODE_OFFSET) + +#define MCS5000_TS_X_POS_UPPER 0x11 +#define MCS5000_TS_X_POS_LOWER 0x12 +#define MCS5000_TS_Y_POS_UPPER 0x13 +#define MCS5000_TS_Y_POS_LOWER 0x14 +#define MCS5000_TS_Z_POS 0x15 +#define MCS5000_TS_WIDTH 0x16 +#define MCS5000_TS_GESTURE_VAL 0x17 +#define MCS5000_TS_MODULE_REV 0x20 +#define MCS5000_TS_FIRMWARE_VER 0x21 + +/* Touchscreen absolute values */ +#define MCS5000_MAX_XC 0x3ff +#define MCS5000_MAX_YC 0x3ff + +/* this struct also seems to have an alignment requirement (256-byte aligned?). + * touchscreen won't work correctly with 8-byte alignment. The aligned attribute + * cannot be attached here because it would make the struct larger and packed + * be ignored. + * See also mcs5000_read() */ +struct mcs5000_raw_data +{ + unsigned char inputInfo; + unsigned char xHigh; + unsigned char xLow; + unsigned char yHigh; + unsigned char yLow; + unsigned char z; + unsigned char width; + unsigned char gesture; +} __attribute__((packed)); + +/** + * Two possibilities for hand usage + */ +enum +{ + RIGHT_HAND, + LEFT_HAND, +}; + +/* Open device */ +void mcs5000_init(void); +/* Close device */ +void mcs5000_close(void); +/* Power up the chip (voltages) */ +void mcs5000_power(void); +/* Shutdown the chip (voltages) */ +void mcs5000_shutdown(void); +/* Set user hand usage */ +void mcs5000_set_hand(int hand_setting); +/* Set touchscreen sensitivity. Valid values are 1,2,4,8 */ +void mcs5000_set_sensitivity(int level); +/* Read controller's data */ +int mcs5000_read(struct mcs5000_raw_data *touchData); diff --git a/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.c new file mode 100644 index 0000000000..8a2a724ca4 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.c @@ -0,0 +1,51 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2013 Lorenzo Miori + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include + +#include "pmu-ypr1.h" +#include "panic.h" + +static int pmu_dev = -1; + +void pmu_init(void) +{ + pmu_dev = open("/dev/r1Pmu", O_RDONLY); + if (pmu_dev < 0) + panicf("/dev/r1Pmu open error!"); +} + +void pmu_close(void) +{ + if (pmu_dev >= 0) + close(pmu_dev); +} + +int pmu_get_dev(void) +{ + return pmu_dev; +} + +int pmu_ioctl(int request, int *data) +{ + return ioctl(pmu_dev, request, data); +} diff --git a/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.h b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.h new file mode 100644 index 0000000000..e8103f22c9 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2013 Lorenzo Miori + * + * 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 __PMU_YPR1_H__ +#define __PMU_YPR1_H__ + +#include "sys/ioctl.h" + +/** + * This is the wrapper to r1Pmu.ko module with the possible + * ioctl calls + * The PMU controller is the MAX8819 + */ + +#define MAX8819_IOCTL_MAGIC 'A' + +#define E_MAX8819_IOCTL_GET_BATT_LVL 0 +#define E_MAX8819_IOCTL_GET_CHG_STATUS 1 +#define E_MAX8819_IOCTL_IS_EXT_PWR 2 +#define E_MAX8819_IOCTL_STOP_CHG 3 +#define E_MAX8819_IOCTL_START_CHG 4 +#define E_MAX8819_IOCTL_IS_EXT_PWR_OVP 5 +#define E_MAX8819_IOCTL_LCD_DIM_CTRL 6 +#define E_MAX8819_IOCTL_CORE_CTL_HIGH 7 +#define E_MAX8819_IOCTL_CORE_CTL_LOW 8 +#define E_MAX8819_IOCTL_TSP_USB_PWR_OFF 9 + +#define MAX8819_IOCTL_GET_BATT_LVL _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_GET_BATT_LVL) +#define MAX8819_IOCTL_GET_CHG_STATUS _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_GET_CHG_STATUS) +#define MAX8819_IOCTL_IS_EXT_PWR _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_IS_EXT_PWR) +#define MAX8819_IOCTL_STOP_CHG _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_STOP_CHG) +#define MAX8819_IOCTL_START_CHG _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_START_CHG) +#define MAX8819_IOCTL_IS_EXT_PWR_OVP _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_IS_EXT_PWR_OVP) +#define MAX8819_IOCTL_LCD_DIM_CTRL _IOW(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_LCD_DIM_CTRL, int) +#define MAX8819_IOCTL_CORE_CTL_HIGH _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_CORE_CTL_HIGH) +#define MAX8819_IOCTL_CORE_CTL_LOW _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_CORE_CTL_LOW) +#define MAX8819_IOCTL_TSP_USB_PWR_OFF _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_TSP_USB_PWR_OFF) + +#define MAX8819_IOCTL_MAX_NR (E_MAX8819_IOCTL_TSP_USB_PWR_OFF+1) + +enum +{ + EXT_PWR_UNPLUGGED = 0, + EXT_PWR_PLUGGED, + EXT_PWR_NOT_OVP, + EXT_PWR_OVP, +}; + +enum +{ + PMU_CHARGING = 0, + PMU_NOT_CHARGING, + PMU_FULLY_CHARGED, +}; + +enum +{ + BATT_LVL_OFF = 0, + BATT_LVL_WARN, + BATT_LVL_1, + BATT_LVL_2, + BATT_LVL_3, + BATT_LVL_4, +}; + +void pmu_init(void); +void pmu_close(void); +int pmu_get_dev(void); +int pmu_ioctl(int request, int *data); + +#endif diff --git a/firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c new file mode 100644 index 0000000000..9a8f9747ae --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c @@ -0,0 +1,153 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2013 Lorenzo Miori + * + * 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 +#include "kernel.h" +#include "powermgmt.h" +#include "power.h" +#include "file.h" +#include "adc.h" +#include "radio-ypr.h" +#include "pmu-ypr1.h" +#include "ioctl-ypr1.h" +#include "stdio.h" +#include "unistd.h" +#include "fcntl.h" +#include "system.h" + +#define MAX17040_VCELL 0x02 +#define MAX17040_SOC 0x04 +#define MAX17040_MODE 0x06 +#define MAX17040_VERSION 0x08 +#define MAX17040_RCOMP 0x0C +#define MAX17040_COMMAND 0xFE + +static int max17040_dev = -1; + +void max17040_init(void) +{ + max17040_dev = open("/dev/r1Batt", O_RDONLY); + if (max17040_dev < 0) + printf("/dev/r1Batt open error!"); +} + +void max17040_close(void) +{ + if (max17040_dev >= 0) + close(max17040_dev); +} + +#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE +const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = +{ + 3470 +}; + +/* the OF shuts down at this voltage */ +const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = +{ + 3450 +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ +const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = +{ + { 3450, 3502, 3550, 3587, 3623, 3669, 3742, 3836, 3926, 4026, 4200 } +}; +#endif + +#if CONFIG_CHARGING +/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ +const unsigned short const percent_to_volt_charge[11] = +{ + 3450, 3670, 3721, 3751, 3782, 3821, 3876, 3941, 4034, 4125, 4200 +}; + +unsigned int power_input_status(void) +{ + unsigned status = POWER_INPUT_NONE; + if (pmu_ioctl(MAX8819_IOCTL_IS_EXT_PWR, NULL) > 0) + status = POWER_INPUT_MAIN_CHARGER; + return status; +} + +#endif /* CONFIG_CHARGING */ + +/* Returns battery voltage from MAX17040 VCELL ADC [millivolts steps], + * adc returns voltage in 1.25mV steps */ +/* + * TODO this would be interesting to be mixed with battery percentage, for information + * and completition purpouses + */ +#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE +int _battery_voltage(void) +{ + int level = 4000; + max17040_request ret = { .addr = 2, .reg1 = 0, .reg2 = 0 }; + if (ioctl(max17040_dev, MAX17040_READ_REG, &ret) >= 0) + { + int step = (ret.reg1 << 4) | (ret.reg2 >> 4); + level = step + (step >> 2); + } + return level; +} +#elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE +int _battery_level(void) +{ + int level = 100; + max17040_request ret = { .addr = 4, .reg1 = 0, .reg2 = 0 }; + if (ioctl(max17040_dev, MAX17040_READ_REG, &ret) >= 0) + level = MIN(ret.reg1, 100); + return level; +} +#endif + +bool charging_state(void) +{ + int ret = pmu_ioctl(MAX8819_IOCTL_GET_CHG_STATUS, NULL); + if (ret == PMU_FULLY_CHARGED) + return true; + return false; +} + +#if CONFIG_TUNER +static bool tuner_on = false; + +bool tuner_power(bool status) +{ + if (status != tuner_on) + { + tuner_on = status; + status = !status; + if (tuner_on) + radiodev_open(); + else + radiodev_close(); + } + + return status; +} + +bool tuner_powered(void) +{ + return tuner_on; +} +#endif /* #if CONFIG_TUNER */ diff --git a/firmware/target/hosted/samsungypr/ypr1/system-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/system-ypr1.c new file mode 100644 index 0000000000..d0cbddc55a --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/system-ypr1.c @@ -0,0 +1,67 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2013 Lorenzo Miori + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include "system.h" +#include "panic.h" +#include "debug.h" + +#include "gpio-target.h" +#include "pmu-ypr1.h" +#include "ioctl-ypr1.h" +#include "audiohw.h" +#include "button-target.h" + +void power_off(void) +{ + /* Something that we need to do before exit on our platform */ + pmu_close(); + max17040_close(); + button_close_device(); + gpio_close(); + exit(EXIT_SUCCESS); +} + +uintptr_t *stackbegin; +uintptr_t *stackend; +void system_init(void) +{ + int *s; + /* fake stack, OS manages size (and growth) */ + stackbegin = stackend = (uintptr_t*)&s; + + /* Here begins our platform specific initilization for various things */ + audiohw_init(); + gpio_init(); + max17040_init(); + pmu_init(); +} + +void system_reboot(void) +{ + power_off(); +} + +void system_exception_wait(void) +{ + system_reboot(); +} diff --git a/firmware/target/hosted/samsungypr/ypr1/wmcodec-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/wmcodec-ypr1.c new file mode 100644 index 0000000000..f38c33ada1 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/wmcodec-ypr1.c @@ -0,0 +1,90 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * I2C bus wrapper for WM1808 codec on SAMSUNG YP-R1 + * + * Copyright (c) 2013 Lorenzo Miori + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include + +#include "system.h" +#include "audiohw.h" +#include "wmcodec.h" +#include "audio.h" +#include "panic.h" +#include "logf.h" + + +#define I2C_SLAVE 0x0703 + +/** + * YP-R1's kernel has ALSA implementation of the WM1808, but it + * unfortunately doesn't export any function to play with register. + * For that reason we control the I2C bus directly, letting RB driver to do the rest + * Assumption: no other ALSA applications are using the mixer! + */ + +static int wmcodec_dev = -1; + +/* The ONLY tested freq for now is 44100, others are just stubs!! */ +const struct wmc_srctrl_entry wmc_srctrl_table[HW_NUM_FREQ] = +{ + /* TODO fix PLL frequencies also for the other available rates */ + [HW_FREQ_44] = /* PLL = on */ + { + .plln = 3 | (1 << 3), + .pllk1 = 0x18, /* 11289600 */ + .pllk2 = 0x111, + .pllk3 = 0x139, + .mclkdiv = WMC_MCLKDIV_2, + .filter = WMC_SR_48KHZ, + }, +}; + +void audiohw_init(void) +{ + /* First of all we need to open the device */ + wmcodec_dev = open("/dev/i2c-1", O_RDWR); + if (wmcodec_dev < 0) + panicf("Failed to open /dev/i2c-1 device!\n"); + + /* Let's set the slave address and if no error we are ready!*/ + int addr = 0x1a; + if (ioctl(wmcodec_dev, I2C_SLAVE, addr) < 0) + logf("Failed to set slave address!\n"); +} + +void wmcodec_write(int reg, int data) +{ + unsigned char data2[2]; + /* |aaaaaaad|dddddddd| */ + data2[0] = (reg << 0x1) | ((data >> 8) & 0x1); + data2[1] = data; + + if (write(wmcodec_dev, data2, 2) < 0) + panicf("I2C device write error!\n"); +} + +void audiohw_enable_headphone_jack(bool enable) +{ + /* We don't use this facility: we have a separate GPIO for that */ + (void)enable; +} diff --git a/firmware/target/hosted/samsungypr/ypr1/ypr1.make b/firmware/target/hosted/samsungypr/ypr1/ypr1.make new file mode 100644 index 0000000000..67ff326de0 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/ypr1.make @@ -0,0 +1,24 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +INCLUDES += -I$(FIRMDIR)/include -I$(FIRMDIR)/export $(TARGET_INC) -I$(BUILDDIR) -I$(APPSDIR) + +SIMFLAGS += $(INCLUDES) $(DEFINES) -DHAVE_CONFIG_H $(GCCOPTS) + +.SECONDEXPANSION: # $$(OBJ) is not populated until after this + +$(BUILDDIR)/rockbox.elf : $$(OBJ) $(FIRMLIB) $(VOICESPEEXLIB) $(CORE_LIBS) + $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -Os -o $@ $(OBJ) \ + -L$(BUILDDIR)/firmware -lfirmware \ + -L$(RBCODEC_BLD)/codecs $(call a2lnk, $(VOICESPEEXLIB)) \ + -L$(BUILDDIR)/lib $(call a2lnk,$(CORE_LIBS)) \ + $(LDOPTS) $(GLOBAL_LDOPTS) -Wl,-Map,$(BUILDDIR)/rockbox.map + +$(BUILDDIR)/rockbox : $(BUILDDIR)/rockbox.elf + $(call PRINTS,OC $(@F))$(call objcopy,$^,$@) diff --git a/tools/buildzip.pl b/tools/buildzip.pl index 56bbe6de1a..1fd242e12c 100755 --- a/tools/buildzip.pl +++ b/tools/buildzip.pl @@ -375,7 +375,7 @@ sub buildzip { close(IGNORE); # the samsung ypr0 has a loader script that's needed in the zip - if ($modelname =~ /samsungypr0/) { + if ($modelname =~ /samsungypr[01]/) { glob_copy("$ROOT/utils/ypr0tools/rockbox.sh", "$temp_dir/"); } # add .nomedia on Android @@ -695,4 +695,3 @@ elsif($exe eq "librockbox.so") { } runone($exe, $incfonts); - diff --git a/tools/configure b/tools/configure index 0f897836c9..dfe84a9e93 100755 --- a/tools/configure +++ b/tools/configure @@ -1340,6 +1340,7 @@ cat <