iBasso DX50/DX90: Major code cleanup and reorganization.

Reorganization

- Separated iBasso devices from PLATFORM_ANDROID. These are now standlone
  hosted targets. Most device specific code is in the
  firmware/target/hosted/ibasso directory.
- No dependency on Android SDK, only the Android NDK is needed.
  32 bit Android NDK and Android API Level 16.
- Separate implementation for each device where feasible.

Code cleanup

- Rewrite of existing code, from simple reformat to complete reimplementation.
- New backlight interface, seperating backlight from touchscreen.
- Rewrite of device button handler, removing unneeded code and fixing memory
  leaks.
- New Debug messages interface logging to Android adb logcat (DEBUGF, panicf,
  logf).
- Rewrite of lcd device handler, removing unneeded code and fixing memory leaks.
- Rewrite of audiohw device handler/pcm interface, removing unneeded code and
  fixing memory leaks, enabling 44.1/48kHz pthreaded playback.
- Rewrite of power and powermng, proper shutdown, using batterylog results
  (see http://gerrit.rockbox.org/r/#/c/1047/).
- Rewrite of configure (Android NDK) and device specific config.
- Rewrite of the Android NDK specific Makefile.

Misc

- All plugins/games/demos activated.
- Update tinyalsa to latest from https://github.com/tinyalsa/tinyalsa.

Includes

- http://gerrit.rockbox.org/r/#/c/993/
- http://gerrit.rockbox.org/r/#/c/1010/
- http://gerrit.rockbox.org/r/#/c/1035/

Does not include http://gerrit.rockbox.org/r/#/c/1007/ due to new backlight
interface and new option for hold switch, touchscreen, physical button
interaction.

Rockbox needs the iBasso DX50/DX90 loader for startup, see
http://gerrit.rockbox.org/r/#/c/1099/

The loader expects Rockbox to be installed in /mnt/sdcard/.rockbox/. If
/mnt/sdcard/ is accessed as USB mass storage device, Rockbox will exit
gracefully and the loader will restart Rockbox on USB disconnect.

Tested on iBasso DX50.
Compiled (not tested) for iBasso DX90.
Compiled (not tested) for PLATFORM_ANDROID.

Change-Id: I5f5e22e68f5b4cf29c28e2b40b2c265f2beb7ab7
This commit is contained in:
Udo Schläpfer 2015-02-02 21:44:29 +01:00
parent cef17e3d59
commit dbabd0d9c3
69 changed files with 3909 additions and 1402 deletions

View File

@ -100,7 +100,7 @@ gui/statusbar.c
#ifdef HAVE_LCD_BITMAP
gui/statusbar-skinned.c
#endif
#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined (DX50) && !defined(DX90)
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
hosted/android/yesno.c
hosted/android/notification.c
#else
@ -129,7 +129,7 @@ player/keyboard.c
#ifdef HAVE_LCD_BITMAP
recorder/bmp.c
recorder/icons.c
#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined (DX50) && !defined(DX90)
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
hosted/android/keyboard.c
#else
recorder/keyboard.c

View File

@ -77,6 +77,10 @@ static inline int do_button_check(const struct button_mapping *items,
{
if (items[i].button_code == button)
{
/*
CAVEAT: This will allways return the action without pre_button_code if it has a
lower index in the list.
*/
if ((items[i].pre_button_code == BUTTON_NONE)
|| (items[i].pre_button_code == last_button))
{

View File

@ -1,13 +1,15 @@
/***************************************************************************
* __________ __ ___.
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2010 Maurus Cuelenaere
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -19,7 +21,6 @@
*
****************************************************************************/
/* Button Code Definitions for iBasso DX50 & DX90 */
#include <stdio.h>
#include <string.h>
@ -30,190 +31,214 @@
#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
*/
Button Code Definitions for iBasso DX50 & DX90.
static const struct button_mapping button_context_standard[] = {
{ ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
{ ACTION_STD_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE },
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.
CAVEAT: The action without prereq button code will allways be choosen if it has a
lower index in the list.
Insert LAST_ITEM_IN_LIST at the end of each mapping
*/
static const struct button_mapping button_context_standard[] =
{
{ ACTION_STD_CONTEXT, BUTTON_PLAY | BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_STD_OK, BUTTON_PLAY | BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_LEFT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_RIGHT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
LAST_ITEM_IN_LIST
}; /* button_context_standard */
};
static const struct button_mapping button_context_wps[] =
{
{ ACTION_WPS_MENU, BUTTON_POWER, BUTTON_NONE },
{ ACTION_WPS_CONTEXT, BUTTON_PLAY | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_PLAY, BUTTON_PLAY | BUTTON_REL, BUTTON_NONE },
{ ACTION_WPS_SEEKBACK, BUTTON_LEFT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_SEEKFWD, BUTTON_RIGHT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_LEFT | BUTTON_REL, BUTTON_LEFT | BUTTON_REPEAT },
{ ACTION_WPS_STOPSEEK, BUTTON_RIGHT | BUTTON_REL, BUTTON_RIGHT | BUTTON_REPEAT },
{ ACTION_WPS_SKIPNEXT, BUTTON_RIGHT | BUTTON_REL, BUTTON_NONE },
{ ACTION_WPS_SKIPPREV, BUTTON_LEFT | BUTTON_REL, BUTTON_NONE },
{ 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 },
static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_MENU, BUTTON_POWER, BUTTON_NONE },
{ ACTION_WPS_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE },
{ ACTION_WPS_SKIPNEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
{ ACTION_WPS_SKIPPREV, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE },
{ ACTION_WPS_SEEKBACK, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_SEEKFWD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT },
{ ACTION_WPS_STOPSEEK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT },
{ 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 },
LAST_ITEM_IN_LIST
}; /* button_context_wps */
};
static const struct button_mapping button_context_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 },
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[] = {
static const struct button_mapping button_context_tree[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
}; /* button_context_tree */
static const struct button_mapping button_context_listtree_scroll_with_combo[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
};
static const struct button_mapping button_context_listtree_scroll_without_combo[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
static const struct button_mapping button_context_listtree_scroll_with_combo[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM | CONTEXT_TREE),
};
static const struct button_mapping button_context_settings[] = {
{ ACTION_SETTINGS_INC, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
}; /* button_context_settings */
static const struct button_mapping button_context_settings_right_is_inc[] = {
static const struct button_mapping button_context_listtree_scroll_without_combo[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM | CONTEXT_TREE),
};
static const struct button_mapping button_context_settings[] =
{
{ ACTION_SETTINGS_INC, BUTTON_VOL_UP | BUTTON_REL, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_VOL_UP | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN | BUTTON_REL, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_VOL_DOWN | BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
}; /* button_context_settingsgraphical */
};
static const struct button_mapping button_context_mainmenu[] = {
static const struct button_mapping button_context_settings_right_is_inc[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
};
static const struct button_mapping button_context_mainmenu[] =
{
{ ACTION_TREE_WPS, BUTTON_POWER, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_TREE),
}; /* button_context_mainmenu */
};
static const struct button_mapping button_context_yesno[] = {
{ ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE },
static const struct button_mapping button_context_yesno[] =
{
{ ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE },
{ ACTION_YESNO_ACCEPT, BUTTON_LEFT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
}; /* button_context_settings_yesno */
};
static const struct button_mapping button_context_colorchooser[] = {
static const struct button_mapping button_context_colorchooser[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
}; /* button_context_colorchooser */
};
static const struct button_mapping button_context_eq[] = {
static const struct button_mapping button_context_eq[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
}; /* button_context_eq */
};
static const struct button_mapping button_context_keyboard[] = {
{ ACTION_KBD_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_KBD_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_PLAY|BUTTON_LEFT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_PLAY|BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY|BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_SELECT, BUTTON_PLAY, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
static const struct button_mapping button_context_keyboard[] =
{
{ ACTION_KBD_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_KBD_LEFT, BUTTON_LEFT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_PLAY | BUTTON_LEFT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_PLAY | BUTTON_LEFT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY | BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY | BUTTON_RIGHT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_SELECT, BUTTON_PLAY, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_VOL_UP | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_VOL_DOWN | BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST
}; /* button_context_keyboard */
};
/** Bookmark Screen **/
static const struct button_mapping button_context_bmark[] = {
static const struct button_mapping button_context_bmark[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
}; /* button_context_bmark */
};
static const struct button_mapping button_context_time[] = {
static const struct button_mapping button_context_time[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
}; /* button_context_time */
};
static const struct button_mapping button_context_quickscreen[] = {
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[] = {
{ ACTION_PS_INC_SMALL, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_DEC_SMALL, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE },
static const struct button_mapping button_context_pitchscreen[] =
{
{ ACTION_PS_INC_SMALL, BUTTON_VOL_UP | BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_DEC_SMALL, BUTTON_VOL_DOWN |BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_pitchcreen */
};
static const struct button_mapping button_context_radio[] = {
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)
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:
return button_context_mainmenu;
case CONTEXT_STD: { return button_context_standard; }
case CONTEXT_WPS: { return button_context_wps; }
case CONTEXT_LIST: { return button_context_list; }
case CONTEXT_MAINMENU: { return button_context_mainmenu; }
case CONTEXT_CUSTOM | CONTEXT_TREE: { return button_context_tree; }
case CONTEXT_SETTINGS: { return button_context_settings; }
case CONTEXT_SETTINGS_COLOURCHOOSER: { return button_context_colorchooser; }
case CONTEXT_SETTINGS_EQ: { return button_context_eq; }
case CONTEXT_SETTINGS_TIME: { return button_context_time; }
case CONTEXT_KEYBOARD: { return button_context_keyboard; }
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_CUSTOM | CONTEXT_SETTINGS:
case CONTEXT_SETTINGS_RECTRIGGER: { return button_context_settings_right_is_inc; }
case CONTEXT_TREE:
if (global_settings.hold_lr_for_scroll_in_list)
{
if(global_settings.hold_lr_for_scroll_in_list)
{
return button_context_listtree_scroll_without_combo;
else
return button_context_listtree_scroll_with_combo;
case CONTEXT_CUSTOM|CONTEXT_TREE:
return button_context_tree;
case CONTEXT_SETTINGS:
return button_context_settings;
case CONTEXT_CUSTOM|CONTEXT_SETTINGS:
case CONTEXT_SETTINGS_RECTRIGGER:
return button_context_settings_right_is_inc;
case CONTEXT_SETTINGS_COLOURCHOOSER:
return button_context_colorchooser;
case CONTEXT_SETTINGS_EQ:
return button_context_eq;
case CONTEXT_SETTINGS_TIME:
return button_context_time;
case CONTEXT_KEYBOARD:
return button_context_keyboard;
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;
}
return button_context_listtree_scroll_with_combo;
}
}
return button_context_standard;
}

View File

@ -171,6 +171,13 @@ static const struct button_mapping button_context_settings_right_is_inc[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM2|CONTEXT_CUSTOM|CONTEXT_SETTINGS)
}; /* button_context_settingsgraphical */
static const struct button_mapping button_context_mainmenu[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM2 | CONTEXT_MAINMENU)
};
static const struct button_mapping button_context_yesno[] = {
{ ACTION_YESNO_ACCEPT, BUTTON_TOPRIGHT, BUTTON_NONE },
{ ACTION_YESNO_ACCEPT, BUTTON_BOTTOMLEFT, BUTTON_NONE },
@ -389,7 +396,12 @@ const struct button_mapping* get_context_mapping(int context)
case CONTEXT_LIST:
return button_context_list;
case CONTEXT_MAINMENU:
{
return button_context_mainmenu;
}
case CONTEXT_TREE:
if (global_settings.hold_lr_for_scroll_in_list)
return button_context_listtree_scroll_without_combo;

View File

@ -37,7 +37,9 @@
#include "menu.h"
#include "usb.h"
#include "powermgmt.h"
#if !defined(DX50) && !defined(DX90)
#include "adc.h"
#endif
#include "i2c.h"
#ifndef DEBUG
#include "serial.h"
@ -340,7 +342,7 @@ static void init(void)
#ifdef SIMULATOR
sim_tasks_init();
#endif
#if (CONFIG_PLATFORM & PLATFORM_ANDROID) && !defined(DX50) && !defined(DX90)
#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
notification_init();
#endif
lang_init(core_language_builtin, language_strings,

View File

@ -1961,7 +1961,7 @@ static int audio_finish_load_track(struct track_info *info)
resume_rewind_adjust_progress(track_id3, &elapsed, &offset);
logf("%s: Set resume for %s to %lu %lX", __func__,
id3->title, elapsed, offset);
track_id3->title, elapsed, offset);
enum data_type audiotype = rbcodec_format_is_atomic(track_id3->codectype) ?
TYPE_ATOMIC_AUDIO : TYPE_PACKET_AUDIO;

View File

@ -1,4 +1,4 @@
#ifndef HAVE_TOUCHSCREEN
#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90)
/* In devices running RockBox as an application, but having a keypad */
#include "SOURCES"
#else

View File

@ -1,4 +1,4 @@
#ifndef HAVE_TOUCHSCREEN
#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90)
/* This is for devices having a keypad, running RockBox as an application */
#include "SUBDIRS"

View File

@ -262,10 +262,10 @@
#define BATTERY_OFF_TXT "Power"
#elif CONFIG_KEYPAD == DX50_PAD
#define BATTERY_ON BUTTON_PLAY
#define BATTERY_OFF BUTTON_POWER
#define BATTERY_OFF_TXT "POWER"
#define BATTERY_ON_TXT "PLAY - start"
#define BATTERY_ON BUTTON_PLAY
#define BATTERY_OFF BUTTON_POWER_LONG
#define BATTERY_OFF_TXT "Power Long"
#define BATTERY_ON_TXT "Play - start"
#else
#error No keymap defined!

View File

@ -11,11 +11,9 @@
is_app_build =
ifdef APP_TYPE
ifneq ($(APP_TYPE),sdl-sim)
ifeq (,$(findstring standalone, $(APP_TYPE)))
is_app_build = yes
endif
endif
endif
ifdef is_app_build
PLUGINS_SRC = $(call preprocess, $(APPSDIR)/plugins/SOURCES.app_build)

View File

@ -792,13 +792,13 @@ void root_menu(void)
case GO_TO_ROOT:
if (last_screen != GO_TO_ROOT)
selected = get_selection(last_screen);
#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined(DX50) && !defined(DX90)
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
/* When we are in the main menu we want the hardware BACK
* button to be handled by Android instead of rockbox */
android_ignore_back_button(true);
#endif
next_screen = do_menu(&root_menu_, &selected, NULL, false);
#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined(DX50) && !defined(DX90)
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
android_ignore_back_button(false);
#endif
if (next_screen != GO_TO_PREVIOUS)

View File

@ -78,7 +78,7 @@ static void get_scrobbler_filename(char *path, size_t size)
used = snprintf(path, size, "/home/user/MyDocs/%s", BASE_FILENAME);
#elif (CONFIG_PLATFORM & PLATFORM_ANDROID)
used = snprintf(path, size, "/sdcard/%s", BASE_FILENAME);
#elif defined (SAMSUNG_YPR0)
#elif defined (SAMSUNG_YPR0) || defined(DX50) || defined(DX90)
used = snprintf(path, size, "%s/%s", HOME_DIR, BASE_FILENAME);
#else /* SDL/unknown RaaA build */
used = snprintf(path, size, "%s/%s", ROCKBOX_DIR, BASE_FILENAME);

View File

@ -291,7 +291,7 @@ struct user_settings
/* audio settings */
int volume; /* audio output volume in decibels range depends on the dac */
int balance; /* stereo balance: 0-100 0=left 50=bal 100=right */
int balance; /* stereo balance: -100 - +100 -100=left 0=bal +100=right */
int bass; /* bass boost/cut in decibels */
int treble; /* treble boost/cut in decibels */
int channel_config; /* Stereo, Mono, Custom, Mono left, Mono right, Karaoke */

View File

@ -20,6 +20,7 @@ target/hosted/rtc.c
#endif
#if (CONFIG_PLATFORM & PLATFORM_ANDROID) == 0 && \
!defined(DX50) && !defined(DX90) && \
(defined(DEBUG) || defined(SIMULATOR)) /* sim should define DEBUG instead */
target/hosted/debug-hosted.c
#endif
@ -1814,31 +1815,53 @@ target/arm/rk27xx/ihifi/powermgmt-ihifi960.c
target/hosted/kernel-unix.c
target/hosted/filesystem-unix.c
target/hosted/lc-unix.c
#if !defined(DX50) && !defined(DX90)
target/hosted/android/lcd-android.c
target/hosted/android/button-android.c
#ifdef DEBUG
target/hosted/android/debug-android.c
#endif
target/hosted/android/pcm-android.c
target/hosted/android/powermgmt-android.c
target/hosted/android/system-android.c
target/hosted/android/telephony-android.c
#ifdef APPLICATION
target/hosted/android/app/button-application.c
#endif
#else
drivers/lcd-memframe.c
target/hosted/android/dx50/pcm-dx50.c
target/hosted/android/dx50/tinyalsa/pcm.c
target/hosted/android/dx50/powermgmt-dx50.c
target/hosted/android/dx50/backlight-dx50.c
target/hosted/android/dx50/button-dx50.c
target/hosted/android/dx50/lcd-dx50.c
#endif
#ifdef DEBUG
target/hosted/android/debug-android.c
#endif
target/hosted/android/system-android.c
drivers/audio/android.c
#endif
#if defined(DX50) || defined(DX90)
drivers/lcd-memframe.c
target/hosted/kernel-unix.c
target/hosted/filesystem-unix.c
target/hosted/lc-unix.c
target/hosted/ibasso/audiohw-ibasso.c
target/hosted/ibasso/backlight-ibasso.c
target/hosted/ibasso/button-ibasso.c
#ifdef DEBUG
target/hosted/ibasso/debug-ibasso.c
#endif
target/hosted/ibasso/hostfs-ibasso.c
target/hosted/ibasso/lcd-ibasso.c
target/hosted/ibasso/pcm-ibasso.c
target/hosted/ibasso/power-ibasso.c
target/hosted/ibasso/powermgmt-ibasso.c
target/hosted/ibasso/sysfs-ibasso.c
target/hosted/ibasso/system-ibasso.c
target/hosted/ibasso/usb-ibasso.c
target/hosted/ibasso/vold-ibasso.c
target/hosted/ibasso/tinyalsa/mixer.c
target/hosted/ibasso/tinyalsa/pcm.c
#ifdef DX50
target/hosted/ibasso/dx50/audiohw-dx50.c
target/hosted/ibasso/dx50/button-dx50.c
#endif
#ifdef DX90
target/hosted/ibasso/dx90/audiohw-dx90.c
target/hosted/ibasso/dx90/button-dx90.c
#endif
#endif
#else /* defined(SIMULATOR) */
#ifdef WIN32

View File

@ -42,6 +42,13 @@
#endif
#ifndef SIMULATOR
/*
Device specific implementation:
bool backlight_hw_init(void);
void backlight_hw_on(void);
void backlight_hw_off(void);
void backlight_hw_brightness(int brightness);
*/
#include "backlight-target.h"
#else
#include "backlight-sim.h"

View File

@ -22,34 +22,12 @@
#include "config.h"
#include "audiohw.h"
#if defined(DX50) || defined(DX90)
#include "system.h"
#include "pcm_sw_volume.h"
#endif
#if defined(DX50) || defined(DX90)
void audiohw_set_volume(int vol_l, int vol_r)
{
int hw_volume;
hw_volume = MAX(vol_l, vol_r);
#ifdef HAVE_SW_VOLUME_CONTROL
vol_l-=hw_volume;
vol_r-=hw_volume;
pcm_set_master_volume(vol_l, vol_r);
#endif
extern void pcm_set_mixer_volume(int);
pcm_set_mixer_volume(hw_volume);
}
#else
void audiohw_set_volume(int volume)
{
extern void pcm_set_mixer_volume(int);
pcm_set_mixer_volume(volume);
}
#endif
void audiohw_set_balance(int balance)
{
@ -58,8 +36,6 @@ void audiohw_set_balance(int balance)
void audiohw_close(void)
{
#if !defined(DX50) && !defined(DX90)
extern void pcm_shutdown(void);
pcm_shutdown();
#endif
}

View File

@ -215,6 +215,27 @@ static void button_tick(void)
}
else /* repeat? */
{
#if defined(DX50) || defined(DX90)
/*
Power button on these devices reports two distinct key codes, which are
triggerd by a short or medium duration press. Additionlly a long duration press
will trigger a hard reset, which is hardwired.
The time delta between medium and long duration press is not large enough to
register here as power off repeat. A hard reset is triggered before Rockbox
can power off.
To cirumvent the hard reset, Rockbox will shutdown on the first POWEROFF_BUTTON
repeat. POWEROFF_BUTTON is associated with the a medium duration press of the
power button.
*/
if(btn & POWEROFF_BUTTON)
{
sys_poweroff();
}
#endif
if ( repeat )
{
if (!post)

View File

@ -114,6 +114,10 @@ struct sound_settings_info
#elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO\
| PLATFORM_PANDORA | PLATFORM_SDL))
#include "hosted_codec.h"
#elif defined(DX50)
#include "codec-dx50.h"
#elif defined(DX90)
#include "codec-dx90.h"
#endif
/* convert caps into defines */

View File

@ -1,14 +1,35 @@
/*
* This config file is for Rockbox as an application on Android
*/
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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.
*
****************************************************************************/
/* This config file is for Rockbox as an application on Android without JVM. */
/* We don't run on hardware directly */
#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_ANDROID)
#define CONFIG_PLATFORM PLATFORM_HOSTED
/* For Rolo and boot loader */
#define MODEL_NUMBER 94
#define MODEL_NAME "iBasso DX50"
#define MODEL_NAME "iBasso DX50"
#define USB_NONE
@ -41,16 +62,15 @@
#define LCD_PIXELFORMAT RGB565
#define HAVE_LCD_ENABLE
#define HAVE_LCD_SLEEP
#define HAVE_LCD_SLEEP_SETTING
/*#define HAVE_LCD_FLIP*/
#define HAVE_LCD_SHUTDOWN
/* define this to indicate your device's keypad */
#define HAVE_TOUCHSCREEN
#define HAVE_BUTTON_DATA
/* define this if you have RTC RAM available for settings */
//#define HAVE_RTC_RAM
/* define this if you have a real-time clock */
//#define CONFIG_RTC APPLICATION
#define HAS_BUTTON_HOLD
/* Define this if you have a software controlled poweroff */
#define HAVE_SW_POWEROFF
@ -77,6 +97,10 @@
/* Define this if you do software codec */
#define CONFIG_CODEC SWCODEC
#define HAVE_SW_TONE_CONTROLS
#define HAVE_SW_VOLUME_CONTROL
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
#define HAVE_PLAY_FREQ
//#define HAVE_MULTIMEDIA_KEYS
#define CONFIG_KEYPAD DX50_PAD
@ -84,39 +108,26 @@
/* define this if the target has volume keys which can be used in the lists */
#define HAVE_VOLUME_IN_LIST
/* define this if the host platform can change volume outside of rockbox */
//#define PLATFORM_HAS_VOLUME_CHANGE
#define HAVE_SW_TONE_CONTROLS
#define HAVE_SW_VOLUME_CONTROL
#define BATTERY_CAPACITY_DEFAULT 2100 /* default battery capacity */
#define BATTERY_CAPACITY_MIN 1700 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
#define BATTERY_TYPES_COUNT 1 /* only one type */
#define BATTERY_CAPACITY_MIN 1700 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
#define BATTERY_TYPES_COUNT 1 /* only one type */
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
#define CONFIG_CHARGING CHARGING_MONITOR
#define CONFIG_CHARGING CHARGING_MONITOR
#define NO_LOW_BATTERY_SHUTDOWN
/* Define current usage levels. */
#define CURRENT_NORMAL 210 /* 10 hours from a 2100 mAh battery */
#define CURRENT_BACKLIGHT 30 /* TBD */
#define CURRENT_RECORD 0 /* no recording */
/* Define this to the CPU frequency */
/*
#define CPU_FREQ 48000000
10 hours from a 2100 mAh battery
Based on battery bench with stock Samsung battery.
*/
#define CURRENT_NORMAL 210
#define CURRENT_BACKLIGHT 30 /* TBD */
#define CURRENT_RECORD 0 /* no recording */
/* 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
@ -128,9 +139,6 @@
/* Define this if a programmable hotkey is mapped */
#define HAVE_HOTKEY
#define BOOTDIR "/.rockbox"
/* No special storage */
#define CONFIG_STORAGE STORAGE_HOSTFS
#define HAVE_STORAGE_FLUSH

View File

@ -1,9 +1,30 @@
/*
* This config file is for Rockbox as an application on Android
*/
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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.
*
****************************************************************************/
/* This config file is for Rockbox as an application on Android without JVM. */
/* We don't run on hardware directly */
#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_ANDROID)
#define CONFIG_PLATFORM PLATFORM_HOSTED
/* For Rolo and boot loader */
#define MODEL_NUMBER 95
@ -41,16 +62,14 @@
#define LCD_PIXELFORMAT RGB565
#define HAVE_LCD_ENABLE
#define HAVE_LCD_SHUTDOWN
#define HAVE_LCD_SLEEP
#define HAVE_LCD_SLEEP_SETTING
/* define this to indicate your device's keypad */
#define HAVE_TOUCHSCREEN
#define HAVE_BUTTON_DATA
/* define this if you have RTC RAM available for settings */
//#define HAVE_RTC_RAM
/* define this if you have a real-time clock */
//#define CONFIG_RTC APPLICATION
#define HAS_BUTTON_HOLD
/* Define this if you have a software controlled poweroff */
#define HAVE_SW_POWEROFF
@ -77,6 +96,10 @@
/* Define this if you do software codec */
#define CONFIG_CODEC SWCODEC
#define HAVE_SW_TONE_CONTROLS
#define HAVE_SW_VOLUME_CONTROL
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
#define HAVE_PLAY_FREQ
//#define HAVE_MULTIMEDIA_KEYS
#define CONFIG_KEYPAD DX50_PAD
@ -84,13 +107,6 @@
/* define this if the target has volume keys which can be used in the lists */
#define HAVE_VOLUME_IN_LIST
/* define this if the host platform can change volume outside of rockbox */
//#define PLATFORM_HAS_VOLUME_CHANGE
#define HAVE_SW_TONE_CONTROLS
#define HAVE_SW_VOLUME_CONTROL
#define BATTERY_CAPACITY_DEFAULT 2100 /* default battery capacity */
#define BATTERY_CAPACITY_MIN 1700 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
@ -101,22 +117,14 @@
#define CONFIG_CHARGING CHARGING_MONITOR
#define NO_LOW_BATTERY_SHUTDOWN
/* Define current usage levels. */
#define CURRENT_NORMAL 210 /* 10 hours from a 2100 mAh battery */
#define CURRENT_BACKLIGHT 30 /* TBD */
#define CURRENT_RECORD 0 /* no recording */
/* Define this to the CPU frequency */
/*
#define CPU_FREQ 48000000
*/
/* 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
@ -128,9 +136,6 @@
/* Define this if a programmable hotkey is mapped */
#define HAVE_HOTKEY
#define BOOTDIR "/.rockbox"
/* No special storage */
#define CONFIG_STORAGE STORAGE_HOSTFS
#define HAVE_STORAGE_FLUSH

View File

@ -25,9 +25,7 @@
&& !(CONFIG_PLATFORM & PLATFORM_MAEMO5)
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -80, 0, 0)
#else
#if !defined(DX50) && !defined(DX90)
#define AUDIOHW_CAPS (MONO_VOL_CAP)
#endif
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -99, 0, 0)
#endif /* CONFIG_PLATFORM & PLATFORM_SDL */

View File

@ -30,13 +30,15 @@
#if CONFIG_CPU == PP5002
/* There's far less time to do mixing because HW FIFOs are short */
#define MIX_FRAME_SAMPLES 64
#elif (CONFIG_PLATFORM & PLATFORM_MAEMO5)
#elif (CONFIG_PLATFORM & PLATFORM_MAEMO5) || defined(DX50) || defined(DX90)
/* Maemo 5 needs 2048 samples for decent performance.
Otherwise the locking overhead inside gstreamer costs too much */
/* iBasso Devices: Match Rockbox PCM buffer size to ALSA PCM buffer size
to minimize memory transfers. */
#define MIX_FRAME_SAMPLES 2048
#else
/* Assume HW DMA engine is available or sufficient latency exists in the
PCM pathway */
#else
#define MIX_FRAME_SAMPLES 256
#endif

View File

@ -40,10 +40,13 @@
#define ROCKBOX_DIR_LEN (sizeof(ROCKBOX_DIR)-1)
#endif /* def __PCTOOL__ */
#if !defined(APPLICATION) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)
#if !defined(APPLICATION) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) || defined(DX50) || defined(DX90)
#if defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)
#define HOME_DIR "/mnt/media0"
#elif defined(DX50) || defined(DX90)
/* Where to put save files like recordings, playlists, screen dumps ...*/
#define HOME_DIR "/mnt/sdcard"
#else
#define HOME_DIR "/"
#endif
@ -80,7 +83,7 @@
#define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos"
#define VIEWERS_DIR PLUGIN_DIR "/viewers"
#if defined(APPLICATION) && !(defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1))
#if defined(APPLICATION) && !(defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) || defined(DX50) || defined(DX90))
#define PLUGIN_DATA_DIR ROCKBOX_DIR "/rocks.data"
#define PLUGIN_GAMES_DATA_DIR PLUGIN_DATA_DIR
#define PLUGIN_APPS_DATA_DIR PLUGIN_DATA_DIR

View File

@ -24,7 +24,9 @@
#include "kernel.h"
#include "thread.h"
#include "debug.h"
#if !defined(DX50) && !defined(DX90)
#include "adc.h"
#endif
#include "string.h"
#include "storage.h"
#include "power.h"

View File

@ -1,76 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2011 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 <fcntl.h>
#include <stdio.h>
#include "unistd.h"
bool backlight_hw_init(void)
{
/* We have nothing to do */
return true;
}
void backlight_hw_on(void)
{
FILE *f = fopen("/sys/power/state", "w");
fputs("on", f);
fclose(f);
lcd_enable(true);
}
void backlight_hw_off(void)
{
FILE * f;
/* deny the player to sleep deep */
f = fopen("/sys/power/wake_lock", "w");
fputs("player", f);
fclose(f);
/* deny the player to mute */
f = fopen("/sys/class/codec/wm8740_mute", "w");
fputc(0, f);
fclose(f);
/* turn off backlight */
f = fopen("/sys/power/state", "w");
fputs("mem", f);
fclose(f);
}
void backlight_hw_brightness(int brightness)
{
/* Just another check... */
if (brightness > MAX_BRIGHTNESS_SETTING)
brightness = MAX_BRIGHTNESS_SETTING;
if (brightness < MIN_BRIGHTNESS_SETTING)
brightness = MIN_BRIGHTNESS_SETTING;
FILE *f = fopen("/sys/devices/platform/rk29_backlight/backlight/rk28_bl/brightness", "w");
fprintf(f, "%d", brightness);
fclose(f);
}

View File

@ -1,316 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (c) 2010 Thomas Martitz
*
* 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 "button.h"
#include "buttonmap.h"
#include "config.h"
#include "kernel.h"
#include "system.h"
#include "touchscreen.h"
#include "powermgmt.h"
#include "backlight.h"
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/inotify.h>
#include <sys/limits.h>
#include <sys/poll.h>
#include <errno.h>
static struct pollfd *ufds;
static char **device_names;
static int nfds;
enum {
PRINT_DEVICE_ERRORS = 1U << 0,
PRINT_DEVICE = 1U << 1,
PRINT_DEVICE_NAME = 1U << 2,
PRINT_DEVICE_INFO = 1U << 3,
PRINT_VERSION = 1U << 4,
PRINT_POSSIBLE_EVENTS = 1U << 5,
PRINT_INPUT_PROPS = 1U << 6,
PRINT_HID_DESCRIPTOR = 1U << 7,
PRINT_ALL_INFO = (1U << 8) - 1,
PRINT_LABELS = 1U << 16,
};
static int last_y, last_x;
static int last_btns;
static enum {
STATE_UNKNOWN,
STATE_UP,
STATE_DOWN
} last_touch_state = STATE_UNKNOWN;
static int open_device(const char *device, int print_flags)
{
int fd;
struct pollfd *new_ufds;
char **new_device_names;
fd = open(device, O_RDWR);
if(fd < 0) {
if(print_flags & PRINT_DEVICE_ERRORS)
fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));
return -1;
}
new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));
if(new_ufds == NULL) {
fprintf(stderr, "out of memory\n");
close(fd);
return -1;
}
ufds = new_ufds;
new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));
if(new_device_names == NULL) {
fprintf(stderr, "out of memory\n");
close(fd);
return -1;
}
device_names = new_device_names;
ufds[nfds].fd = fd;
ufds[nfds].events = POLLIN;
device_names[nfds] = strdup(device);
nfds++;
return 0;
}
static int scan_dir(const char *dirname, int print_flags)
{
char devname[PATH_MAX];
char *filename;
DIR *dir;
struct dirent *de;
dir = opendir(dirname);
if(dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
while((de = readdir(dir))) {
if(de->d_name[0] == '.' &&
(de->d_name[1] == '\0' ||
(de->d_name[1] == '.' && de->d_name[2] == '\0')))
continue;
strcpy(filename, de->d_name);
open_device(devname, print_flags);
}
closedir(dir);
return 0;
}
bool _hold;
bool button_hold()
{
FILE *f = fopen("/sys/class/axppower/holdkey", "r");
char x;
fscanf(f, "%c", &x);
fclose(f);
_hold = !(x&STATE_UNLOCKED);
return _hold;
}
void button_init_device(void)
{
int res;
int print_flags = 0;
const char *device = NULL;
const char *device_path = "/dev/input";
nfds = 1;
ufds = calloc(1, sizeof(ufds[0]));
ufds[0].fd = inotify_init();
ufds[0].events = POLLIN;
if(device) {
res = open_device(device, print_flags);
if(res < 0) {
// return 1;
}
} else {
res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
if(res < 0) {
fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno));
// return 1;
}
res = scan_dir(device_path, print_flags);
if(res < 0) {
fprintf(stderr, "scan dir failed for %s\n", device_path);
// return 1;
}
}
button_hold(); //store state
set_rockbox_ready();
}
void touchscreen_enable_device(bool en)
{
(void)en; /* FIXME: do something smart */
}
int keycode_to_button(int keyboard_key)
{
switch(keyboard_key){
case KEYCODE_PWR:
return BUTTON_POWER;
case KEYCODE_PWR_LONG:
return BUTTON_POWER_LONG;
case KEYCODE_VOLPLUS:
return BUTTON_VOL_UP;
case KEYCODE_VOLMINUS:
return BUTTON_VOL_DOWN;
case KEYCODE_PREV:
return BUTTON_LEFT;
case KEYCODE_NEXT:
return BUTTON_RIGHT;
case KEYCODE_PLAY:
return BUTTON_PLAY;
case KEYCODE_HOLD:
button_hold(); /* store state */
backlight_hold_changed(_hold);
return BUTTON_NONE;
default:
return BUTTON_NONE;
}
}
int button_read_device(int *data)
{
int i;
int res;
struct input_event event;
int read_more;
unsigned button = 0;
if(last_btns & BUTTON_POWER_LONG)
{
return last_btns; /* simulate repeat */
}
do {
read_more = 0;
poll(ufds, nfds, 10);
for(i = 1; i < nfds; i++) {
if(ufds[i].revents & POLLIN) {
res = read(ufds[i].fd, &event, sizeof(event));
if(res < (int)sizeof(event)) {
fprintf(stderr, "could not get event\n");
}
switch(event.type)
{
case 1: /* HW-Button */
button = keycode_to_button(event.code);
if (_hold) /* we have to wait for keycode_to_button() first to maybe clear hold state */
break;
if (button == BUTTON_NONE)
{
last_btns = button;
break;
}
/* workaround for a wrong feedback, only present with DX90 */
#if defined(DX90)
if (button == BUTTON_RIGHT && (last_btns & BUTTON_LEFT == BUTTON_LEFT) && !event.value)
{
button = BUTTON_LEFT;
}
#endif
if (event.value)
last_btns |= button;
else
last_btns &= (~button);
break;
case 3: /* Touchscreen */
if(_hold)
break;
switch(event.code)
{
case 53: /* x -> next will be y */
last_x = event.value;
read_more = 1;
break;
case 54: /* y */
last_y = event.value;
break;
case 57: /* press -> next will be x */
if(event.value==1)
{
last_touch_state = STATE_DOWN;
read_more = 1;
}
else
last_touch_state = STATE_UP;
break;
}
break;
}
}
}
} while(read_more);
/* Get grid button/coordinates based on the current touchscreen mode
*
* Caveat: the caller seemingly depends on *data always being filled with
* the last known touchscreen position, so always call
* touchscreen_to_pixels() */
int touch = touchscreen_to_pixels(last_x, last_y, data);
if (last_touch_state == STATE_DOWN)
return last_btns | touch;
return last_btns;
}

View File

@ -1,120 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: lcd-bitmap.c 29248 2011-02-08 20:05:25Z thomasjfox $
*
* Copyright (C) 2011 Lorenzo Miori, Thomas Martitz
* 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 <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "config.h"
#include "file.h"
#include "debug.h"
#include "system.h"
#include "screendump.h"
#include "lcd.h"
#include "lcd-target.h"
static int dev_fd = 0;
fb_data *dev_fb = 0;
#ifdef HAVE_LCD_SHUTDOWN
void lcd_shutdown(void)
{
printf("FB closed.");
munmap(dev_fb, FRAMEBUFFER_SIZE);
close(dev_fd);
}
#endif
void lcd_init_device(void)
{
size_t screensize;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
/* Open the framebuffer device */
dev_fd = open("/dev/graphics/fb0", O_RDWR);
if (dev_fd == -1) {
perror("Error: cannot open framebuffer device");
exit(1);
}
/* Get the fixed properties */
if (ioctl(dev_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
perror("Error reading fixed information");
exit(2);
}
/* Now we get the settable settings, and we set 16 bit bpp */
if (ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
perror("Error reading variable information");
exit(3);
}
/* framebuffer does not fit the screen, a bug of iBassos Firmware, not rockbox.
cannot be solved with parameters */
vinfo.bits_per_pixel = LCD_DEPTH;
vinfo.xres = vinfo.xres_virtual = vinfo.width = LCD_WIDTH;
vinfo.yres = vinfo.yres_virtual = vinfo.height = LCD_HEIGHT;
if (ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo)) {
perror("fbset(ioctl)");
exit(4);
}
/* Figure out the size of the screen in bytes */
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
if (screensize != FRAMEBUFFER_SIZE) {
exit(4);
perror("Display and framebuffer mismatch!\n");
}
/* Map the device to memory */
dev_fb = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
if ((int)dev_fb == -1) {
perror("Error: failed to map framebuffer device to memory");
exit(4);
}
/* Be sure to turn on display at startup */
ioctl(dev_fd, FBIOBLANK, VESA_NO_BLANKING);
#ifdef HAVE_LCD_ENABLE
lcd_set_active(true);
#endif
}
#ifdef HAVE_LCD_ENABLE
void lcd_enable(bool enable)
{
if (lcd_active() == enable)
return;
lcd_set_active(enable);
/* Turn on or off the display using Linux interface */
ioctl(dev_fd, FBIOBLANK, enable ? VESA_NO_BLANKING : VESA_POWERDOWN);
if (enable)
send_event(LCD_EVENT_ACTIVATION, NULL);
}
#endif

View File

@ -1,364 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2010 Thomas Martitz
*
* 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.
*
****************************************************************************/
/*
* Based, but heavily modified, on the example given at
* http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html
*
* This driver uses the so-called unsafe async callback method and hardcoded device
* names. It fails when the audio device is busy by other apps.
*
* To make the async callback safer, an alternative stack is installed, since
* it's run from a signal hanlder (which otherwise uses the user stack). If
* tick tasks are run from a signal handler too, please install
* an alternative stack for it too.
*
* TODO: Rewrite this to do it properly with multithreading
*
* Alternatively, a version using polling in a tick task is provided. While
* supposedly safer, it appears to use more CPU (however I didn't measure it
* accurately, only looked at htop). At least, in this mode the "default"
* device works which doesnt break with other apps running.
*/
#include "autoconf.h"
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <errno.h>
#include "tinyalsa/asoundlib.h"
#include "tinyalsa/asound.h"
#include "system.h"
#include "debug.h"
#include "kernel.h"
#include "pcm.h"
#include "pcm-internal.h"
#include "pcm_mixer.h"
#include "pcm_sampr.h"
#include "audiohw.h"
#include <pthread.h>
#include <signal.h>
static const snd_pcm_format_t format = PCM_FORMAT_S16_LE; /* sample format */
static const int channels = 2; /* count of channels */
static unsigned int rate = 44100; /* stream rate */
typedef struct pcm snd_pcm_t;
static snd_pcm_t *handle;
struct pcm_config config;
static snd_pcm_sframes_t period_size = 512; /* if set to >= 1024, all timers become even slower */
static char *frames;
static const void *pcm_data = 0;
static size_t pcm_size = 0;
static int recursion;
static int set_hwparams(snd_pcm_t *handle)
{
int err;
if (!frames)
frames = malloc(pcm_frames_to_bytes(handle, pcm_get_buffer_size(handle)));
err = 0; /* success */
return err;
}
/* copy pcm samples to a spare buffer, suitable for snd_pcm_writei() */
static bool fill_frames(void)
{
size_t copy_n, frames_left = period_size;
bool new_buffer = false;
while (frames_left > 0)
{
if (!pcm_size)
{
new_buffer = true;
if (!pcm_play_dma_complete_callback(PCM_DMAST_OK, &pcm_data,
&pcm_size))
{
return false;
}
}
copy_n = MIN((size_t)pcm_size, pcm_frames_to_bytes(handle, frames_left));
memcpy(&frames[pcm_frames_to_bytes(handle, period_size-frames_left)], pcm_data, copy_n);
pcm_data += copy_n;
pcm_size -= copy_n;
frames_left -= pcm_bytes_to_frames(handle, copy_n);
if (new_buffer)
{
new_buffer = false;
pcm_play_dma_status_callback(PCM_DMAST_STARTED);
}
}
return true;
}
static void pcm_tick(void)
{
if (fill_frames())
{
if (pcm_write(handle, frames, pcm_frames_to_bytes(handle, period_size))) {
printf("Error playing sample\n");
return;//break;
}
}
else
{
DEBUGF("%s: No Data.\n", __func__);
return;//break;
}
}
static int async_rw(snd_pcm_t *handle)
{
int err;
snd_pcm_sframes_t sample_size;
char *samples;
/* fill buffer with silence to initiate playback without noisy click */
sample_size = pcm_frames_to_bytes(handle, pcm_get_buffer_size(handle));
samples = malloc(sample_size);
memset(samples, 0, sample_size);
err = pcm_write(handle, samples, sample_size);
free(samples);
if (err != 0)
{
DEBUGF("Initial write error: %d\n", err);
return err;
}
if (pcm_state(handle) == PCM_STATE_PREPARED)
{
err = pcm_start(handle);
if (err < 0)
{
DEBUGF("Start error: %d\n", err);
return err;
}
}
return 0;
}
void cleanup(void)
{
free(frames);
frames = NULL;
pcm_close(handle);
}
void pcm_play_dma_init(void)
{
config.channels = channels;
config.rate = rate;
config.period_size = period_size;
config.period_count = 4;
config.format = format;
config.start_threshold = 0;
config.stop_threshold = 0;
config.silence_threshold = 0;
handle = pcm_open(0, 0, PCM_OUT, &config);
if (!handle || !pcm_is_ready(handle)) {
printf("Unable to open PCM device: %s\n", pcm_get_error(handle));
return;
}
pcm_dma_apply_settings();
tick_add_task(pcm_tick);
atexit(cleanup);
return;
}
void pcm_play_lock(void)
{
if (recursion++ == 0)
tick_remove_task(pcm_tick);
}
void pcm_play_unlock(void)
{
if (--recursion == 0)
tick_add_task(pcm_tick);
}
static void pcm_dma_apply_settings_nolock(void)
{
set_hwparams(handle);
}
void pcm_dma_apply_settings(void)
{
pcm_play_lock();
pcm_dma_apply_settings_nolock();
pcm_play_unlock();
}
void pcm_play_dma_pause(bool pause)
{
(void)pause;
}
void pcm_play_dma_stop(void)
{
pcm_stop(handle);
}
void pcm_play_dma_start(const void *addr, size_t size)
{
#if defined(DX50) || defined(DX90)
/* headphone output relay: if this is done at startup already, a loud click is audible on headphones. Here, some time later,
the output caps are charged a bit and the click is much softer */
system("/system/bin/muteopen");
#endif
pcm_dma_apply_settings_nolock();
pcm_data = addr;
pcm_size = size;
while (1)
{
snd_pcm_state_t state = pcm_state(handle);
switch (state)
{
case PCM_STATE_RUNNING:
return;
case PCM_STATE_XRUN:
{
printf("No handler for STATE_XRUN!\n");
continue;
}
case PCM_STATE_PREPARED:
{ /* prepared state, we need to fill the buffer with silence before
* starting */
int err = async_rw(handle);
if (err < 0)
printf("Start error: %d\n", err);
return;
}
case PCM_STATE_PAUSED:
{ /* paused, simply resume */
pcm_play_dma_pause(0);
return;
}
case PCM_STATE_DRAINING:
/* run until drained */
continue;
default:
DEBUGF("Unhandled state: %d\n", state);
return;
}
}
}
size_t pcm_get_bytes_waiting(void)
{
return pcm_size;
}
const void * pcm_play_dma_get_peak_buffer(int *count)
{
uintptr_t addr = (uintptr_t)pcm_data;
*count = pcm_size / 4;
return (void *)((addr + 3) & ~3);
}
void pcm_play_dma_postinit(void)
{
return;
}
void pcm_set_mixer_volume(int volume)
{
#if defined(DX50) || defined(DX90)
/* -990 to 0 -> 0 to 255 */
int val = (volume+990)*255/990;
#if defined(DX50)
FILE *f = fopen("/dev/codec_volume", "w");
#else /* DX90 */
FILE *f = fopen("/sys/class/codec/es9018_volume", "w");
#endif /* DX50 */
fprintf(f, "%d", val);
fclose(f);
#else
(void)volume;
#endif /* DX50 || DX90 */
}
#ifdef HAVE_RECORDING
void pcm_rec_lock(void)
{
}
void pcm_rec_unlock(void)
{
}
void pcm_rec_dma_init(void)
{
}
void pcm_rec_dma_close(void)
{
}
void pcm_rec_dma_start(void *start, size_t size)
{
(void)start;
(void)size;
}
void pcm_rec_dma_stop(void)
{
}
const void * pcm_rec_dma_get_peak_buffer(void)
{
return NULL;
}
void audiohw_set_recvol(int left, int right, int type)
{
(void)left;
(void)right;
(void)type;
}
#endif /* HAVE_RECORDING */

View File

@ -1,97 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2010 by Thomas Martitz
*
* 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 <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "power.h"
#include "powermgmt.h"
unsigned int power_input_status(void)
{
int val;
FILE *f = fopen("/sys/class/power_supply/ac/present", "r");
fscanf(f, "%d", &val);
fclose(f);
return val?POWER_INPUT_MAIN_CHARGER:POWER_INPUT_NONE;
}
/* Returns true, if battery is charging, false else. */
bool charging_state( void )
{
/* Full, Charging, Discharging */
char state[9];
/* true if charging. */
bool charging = false;
FILE *f = fopen( "/sys/class/power_supply/battery/status", "r" );
if( f != NULL )
{
if( fgets( state, 9, f ) != NULL )
{
charging = ( strcmp( state, "Charging" ) == 0 );
}
}
fclose( f );
return charging;
}
/* Values for stock PISEN battery. TODO: Needs optimization */
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
3380
};
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
3100
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
{ 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4090, 4190 }
};
/* Voltages (millivolt) of 0%, 10%, ... 100% when charging is enabled. */
const unsigned short percent_to_volt_charge[11] =
{
3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4090, 4190
};
/* Returns battery voltage from android measurement [millivolts] */
int _battery_voltage(void)
{
int val;
FILE *f = fopen("/sys/class/power_supply/battery/voltage_now", "r");
fscanf(f, "%d", &val);
fclose(f);
return (val/1000);
}

View File

@ -23,12 +23,6 @@
#include <setjmp.h>
#include <jni.h>
#include <pthread.h>
#if defined(DX50) || defined(DX90)
#include <stdlib.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <stdio.h>
#endif /* DX50 || DX90 */
#include <unistd.h>
#include "config.h"
#include "system.h"
@ -37,83 +31,40 @@
#if !defined(DX50) && !defined(DX90)
/* global fields for use with various JNI calls */
static JavaVM *vm_ptr;
JNIEnv *env_ptr;
jobject RockboxService_instance;
jclass RockboxService_class;
#endif /* !DX50 && !DX90 */
uintptr_t *stackbegin;
uintptr_t *stackend;
extern int main(void);
#if !defined(DX50) && !defined(DX90)
extern void telephony_init_device(void);
#endif
void system_exception_wait(void)
{
#if defined(DX50) || defined(DX90)
while(1);
#else
intptr_t dummy = 0;
while(button_read_device(&dummy) != BUTTON_BACK);
#endif /* DX50 || DX90 */
}
void system_reboot(void)
{
#if defined(DX50) || defined(DX90)
reboot(RB_AUTOBOOT);
#else
power_off();
#endif /* DX50 || DX90 */
}
#if !defined(DX50) && !defined(DX90)
/* this is used to return from the entry point of the native library. */
static jmp_buf poweroff_buf;
#endif
void power_off(void)
{
#if defined(DX50) || defined(DX90)
reboot(RB_POWER_OFF);
#else
longjmp(poweroff_buf, 1);
#endif /* DX50 || DX90 */
}
void system_init(void)
{
#if defined(DX50) || defined(DX90)
volatile uintptr_t stack = 0;
stackbegin = stackend = (uintptr_t*) &stack;
struct stat m1, m2;
stat("/mnt/", &m1);
do
{
/* waiting for storage to get mounted */
stat("/sdcard/", &m2);
usleep(100000);
}
while(m1.st_dev == m2.st_dev);
/* here would be the correct place for 'system("/system/bin/muteopen");' (headphone-out relay) but in pcm-dx50.c, pcm_play_dma_start()
the output capacitors are charged already a bit and the click of the headphone-connection-relay is softer */
#if defined(DX90)
/* DAC needs to be unmuted on DX90 */
FILE * f = fopen("/sys/class/codec/wm8740_mute", "w");
fputc(0, f);
fclose(f);
#endif /* DX90 */
#else
/* no better place yet */
telephony_init_device();
#endif /* DX50 || DX90 */
}
int hostfs_init(void)
@ -128,7 +79,6 @@ int hostfs_flush(void)
return 0;
}
#if !defined(DX50) && !defined(DX90)
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void* reserved)
{
@ -169,7 +119,7 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this)
/* simply return here. this will allow the VM to clean up objects and do
* garbage collection */
}
#endif /* !DX50 && !DX90 */
/* below is the facility for external (from other java threads) to safely call
* into our snative code. When extracting rockbox.zip the main function is

View File

@ -47,7 +47,7 @@ static const char *rbhome;
static const char rbhome[] = HOME_DIR;
#endif
#if !(defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1)) && !defined(__PCTOOL__)
#if !(defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) || defined(DX50) || defined(DX90)) && !defined(__PCTOOL__)
/* Special dirs are user-accessible (and user-writable) dirs which take priority
* over the ones where Rockbox is installed to. Classic example would be
* $HOME/.config/rockbox.org vs /usr/share/rockbox */

View File

@ -0,0 +1,49 @@
# __________ __ ___
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
#
# Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
# Copyright (C) 2014 by Mario Basister: iBasso DX90 port
# Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
# Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
#
# 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.
# This is a glibc compatibility hack to provide a get_nprocs() replacement.
# The NDK ships cpu-features.c which has a compatible function android_getCpuCount()
CPUFEAT = $(ANDROID_NDK_PATH)/sources/android/cpufeatures
CPUFEAT_BUILD = $(BUILDDIR)/android-ndk/sources/android/cpufeatures
INCLUDES += -I$(CPUFEAT)
OTHER_SRC += $(CPUFEAT)/cpu-features.c
CLEANOBJS += $(CPUFEAT_BUILD)/cpu-features.o
$(CPUFEAT_BUILD)/cpu-features.o: $(CPUFEAT)/cpu-features.c
$(SILENT)mkdir -p $(dir $@)
$(call PRINTS,CC $(subst $(CPUFEAT)/,,$<))$(CC) -o $@ -c $(CPUFEAT)/cpu-features.c $(GCCOPTS) -Wno-unused
.SECONDEXPANSION:
.PHONY: clean dirs
DIRS += $(CPUFEAT_BUILD)
.PHONY:
$(BUILDDIR)/$(BINARY): $$(OBJ) $(FIRMLIB) $(VOICESPEEXLIB) $(CORE_LIBS) $(CPUFEAT_BUILD)/cpu-features.o
$(call PRINTS,LD $(BINARY))$(CC) -o $@ $^ $(LDOPTS) $(GLOBAL_LDOPTS) -Wl,-Map,$(BUILDDIR)/rockbox.map
$(call PRINTS,OC $(@F))$(call objcopy,$@,$@)
$(DIRS):
$(SILENT)mkdir -p $@
dirs: $(DIRS)
clean::
$(SILENT)rm -rf $(BUILDDIR)/android-ndk

View File

@ -0,0 +1,81 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 "debug.h"
#include "pcm_sw_volume.h"
#include "settings.h"
#include "debug-ibasso.h"
#include "pcm-ibasso.h"
void audiohw_close(void)
{
TRACE;
pcm_close_device();
}
void set_software_volume(void)
{
/* -73dB (?) minimum software volume in decibels. See pcm-internal.h. */
static const int SW_VOLUME_MIN = 730;
int sw_volume_l = 0;
int sw_volume_r = 0;
if(global_settings.balance > 0)
{
if(global_settings.balance == 100)
{
sw_volume_l = PCM_MUTE_LEVEL;
}
else
{
sw_volume_l -= SW_VOLUME_MIN * global_settings.balance / 100;
}
}
else if(global_settings.balance < 0)
{
if(global_settings.balance == -100)
{
sw_volume_r = PCM_MUTE_LEVEL;
}
else
{
sw_volume_r = SW_VOLUME_MIN * global_settings.balance / 100;
}
}
DEBUGF("DEBUG %s: global_settings.balance: %d, sw_volume_l: %d, sw_volume_r: %d.",
__func__,
global_settings.balance,
sw_volume_l,
sw_volume_r);
/* Emulate balance with software volume. */
pcm_set_master_volume(sw_volume_l, sw_volume_r);
}

View File

@ -0,0 +1,132 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 "debug.h"
#include "lcd.h"
#include "panic.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
/*
Prevent excessive backlight_hw_on usage.
Required for proper seeking.
*/
static bool _backlight_enabled = false;
bool backlight_hw_init(void)
{
TRACE;
/*
/sys/devices/platform/rk29_backlight/backlight/rk28_bl/bl_power
0: backlight on
*/
if(! sysfs_set_int(SYSFS_BACKLIGHT_POWER, 0))
{
DEBUGF("ERROR %s: Can not enable backlight.", __func__);
panicf("ERROR %s: Can not enable backlight.", __func__);
return false;
}
_backlight_enabled = true;
return true;
}
void backlight_hw_on(void)
{
if(! _backlight_enabled)
{
backlight_hw_init();
lcd_enable(true);
}
}
void backlight_hw_off(void)
{
TRACE;
/*
/sys/devices/platform/rk29_backlight/backlight/rk28_bl/bl_power
1: backlight off
*/
if(! sysfs_set_int(SYSFS_BACKLIGHT_POWER, 1))
{
DEBUGF("ERROR %s: Can not disable backlight.", __func__);
return;
}
lcd_enable(false);
_backlight_enabled = false;
}
/*
Prevent excessive backlight_hw_brightness usage.
Required for proper seeking.
*/
static int _current_brightness = -1;
void backlight_hw_brightness(int brightness)
{
if(brightness > MAX_BRIGHTNESS_SETTING)
{
DEBUGF("DEBUG %s: Adjusting brightness from %d to MAX.", __func__, brightness);
brightness = MAX_BRIGHTNESS_SETTING;
}
if(brightness < MIN_BRIGHTNESS_SETTING)
{
DEBUGF("DEBUG %s: Adjusting brightness from %d to MIN.", __func__, brightness);
brightness = MIN_BRIGHTNESS_SETTING;
}
if(_current_brightness == brightness)
{
return;
}
TRACE;
_current_brightness = brightness;
/*
/sys/devices/platform/rk29_backlight/backlight/rk28_bl/max_brightness
0 ... 255
*/
if(! sysfs_set_int(SYSFS_BACKLIGHT_BRIGHTNESS, _current_brightness))
{
DEBUGF("ERROR %s: Can not set brightness.", __func__);
return;
}
}

View File

@ -1,13 +1,15 @@
/***************************************************************************
* __________ __ ___.
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Maurus Cuelenaere
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -18,14 +20,20 @@
* KIND, either express or implied.
*
****************************************************************************/
#ifndef BACKLIGHT_TARGET_H
#define BACKLIGHT_TARGET_H
#ifndef _BACKLIGHT_TARGET_H_
#define _BACKLIGHT_TARGET_H_
#include <stdbool.h>
/* See backlight.c */
bool backlight_hw_init(void);
void backlight_hw_on(void);
void backlight_hw_off(void);
void backlight_hw_brightness(int brightness);
#endif /* BACKLIGHT_TARGET_H */
#endif

View File

@ -0,0 +1,420 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/inotify.h>
#include <sys/limits.h>
#include <sys/poll.h>
#include "config.h"
#include "backlight.h"
#include "button.h"
#include "debug.h"
#include "panic.h"
#include "settings.h"
#include "touchscreen.h"
#include "button-ibasso.h"
#include "button-target.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
#define EVENT_TYPE_BUTTON 1
/* /dev/input/event0 */
#define EVENT_CODE_BUTTON_LINEOUT 113
#define EVENT_CODE_BUTTON_SPDIF 114
#define EVENT_CODE_BUTTON_HOLD 115
/* /dev/input/event1 */
#define EVENT_CODE_BUTTON_SDCARD 143
#define EVENT_TYPE_TOUCHSCREEN 3
/* /dev/input/event2 */
#define EVENT_CODE_TOUCHSCREEN_X 53
#define EVENT_CODE_TOUCHSCREEN_Y 54
#define EVENT_CODE_TOUCHSCREEN 57
#define EVENT_VALUE_TOUCHSCREEN_PRESS 1
#define EVENT_VALUE_TOUCHSCREEN_RELEASE -1
/*
Changing bit, when hold switch is toggled.
Bit is off when hold switch is engaged.
*/
#define HOLD_SWITCH_BIT 16
/*
Changing bit, when coaxial out is plugged.
Bit is off when coaxial out is plugged in.
*/
#define COAX_BIT 32
/*
Changing bit, when line out is plugged.
Bit is off when line out is plugged in.
*/
#define SPDIF_BIT 64
/* State of the hold switch; true: hold switch engaged. */
static bool _hold = false;
/* See button.h. */
bool button_hold(void)
{
char hold_state;
if(! sysfs_get_char(SYSFS_HOLDKEY, &hold_state))
{
DEBUGF("ERROR %s: Can not get hold switch state.", __func__);
hold_state = HOLD_SWITCH_BIT;
}
/*DEBUGF("%s: hold_state: %d, %c.", __func__, hold_state, hold_state);*/
/*bool coax_connected = ! (hold_state & COAX_BIT);
bool spdif_connected = ! (hold_state & SPDIF_BIT);*/
_hold = ! (hold_state & HOLD_SWITCH_BIT);
/*DEBUGF("%s: _hold: %d, coax_connected: %d, spdif_connected: %d.", __func__, _hold, coax_connected, spdif_connected);*/
return _hold;
}
/* Input devices monitored with poll API. */
static struct pollfd* _fds = NULL;
/* Number of input devices monitored with poll API. */
static nfds_t _nfds = 0;
/* The names of the devices in _fds. */
static char** _device_names = NULL;
/* Open device device_name and add it to the list of polled devices. */
static bool open_device(const char* device_name)
{
int fd = open(device_name, O_RDONLY);
if(fd == -1)
{
DEBUGF("ERROR %s: open failed on %s.", __func__, device_name);
return false;
}
struct pollfd* new_fds = realloc(_fds, sizeof(struct pollfd) * (_nfds + 1));
if(new_fds == NULL)
{
DEBUGF("ERROR %s: realloc for _fds failed.", __func__);
panicf("ERROR %s: realloc for _fds failed.", __func__);
return false;
}
_fds = new_fds;
_fds[_nfds].fd = fd;
_fds[_nfds].events = POLLIN;
char** new_device_names = realloc(_device_names, sizeof(char*) * (_nfds + 1));
if(new_device_names == NULL)
{
DEBUGF("ERROR %s: realloc for _device_names failed.", __func__);
panicf("ERROR %s: realloc for _device_names failed.", __func__);
return false;
}
_device_names = new_device_names;
_device_names[_nfds] = strdup(device_name);
if(_device_names[_nfds] == NULL)
{
DEBUGF("ERROR %s: strdup failed.", __func__);
panicf("ERROR %s: strdup failed.", __func__);
return false;
}
++_nfds;
DEBUGF("DEBUG %s: Opened device %s.", __func__, device_name);
return true;
}
/* See button.h. */
void button_init_device(void)
{
TRACE;
if((_fds != NULL) || (_nfds != 0) || (_device_names != NULL))
{
DEBUGF("ERROR %s: Allready initialized.", __func__);
panicf("ERROR %s: Allready initialized.", __func__);
return;
}
/* The input device directory. */
static const char device_path[] = "/dev/input";
/* Path delimeter. */
static const char delimeter[] = "/";
/* Open all devices in device_path. */
DIR* dir = opendir(device_path);
if(dir == NULL)
{
DEBUGF("ERROR %s: opendir failed: errno: %d.", __func__, errno);
panicf("ERROR %s: opendir failed: errno: %d.", __func__, errno);
return;
}
char device_name[PATH_MAX];
strcpy(device_name, device_path);
strcat(device_name, delimeter);
char* device_name_idx = device_name + strlen(device_name);
struct dirent* dir_entry;
while((dir_entry = readdir(dir)))
{
if( ((dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '\0'))
|| ((dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '.') && (dir_entry->d_name[2] == '\0')))
{
continue;
}
strcpy(device_name_idx, dir_entry->d_name);
/* Open and add device to _fds. */
open_device(device_name);
}
closedir(dir);
/* Sanity check. */
if(_nfds < 2)
{
DEBUGF("ERROR %s: No input devices.", __func__);
panicf("ERROR %s: No input devices.", __func__);
return;
}
/*
Hold switch has a separate interface for its state.
Input events just report that it has been toggled, but not the state.
*/
button_hold();
}
/* Last known touchscreen coordinates. */
static int _last_x = 0;
static int _last_y = 0;
/* Last known touchscreen state. */
static enum
{
TOUCHSCREEN_STATE_UNKNOWN = 0,
TOUCHSCREEN_STATE_UP,
TOUCHSCREEN_STATE_DOWN
} _last_touch_state = TOUCHSCREEN_STATE_UNKNOWN;
static bool handle_touchscreen_event(__u16 code, __s32 value)
{
bool read_more = false;
switch(code)
{
case EVENT_CODE_TOUCHSCREEN_X:
{
_last_x = value;
/* x -> next will be y. */
read_more = true;
break;
}
case EVENT_CODE_TOUCHSCREEN_Y:
{
_last_y = value;
break;
}
case EVENT_CODE_TOUCHSCREEN:
{
if(value == EVENT_VALUE_TOUCHSCREEN_PRESS)
{
_last_touch_state = TOUCHSCREEN_STATE_DOWN;
/* Press -> next will be x. */
read_more = true;
}
else
{
_last_touch_state = TOUCHSCREEN_STATE_UP;
}
break;
}
}
return read_more;
}
/* Last known hardware buttons pressed. */
static int _last_btns = BUTTON_NONE;
/* See button.h. */
int button_read_device(int *data)
{
bool read_more = true;
while(read_more)
{
read_more = false;
/* Poll all input devices. */
poll(_fds, _nfds, 0);
for(nfds_t fds_idx = 0; fds_idx < _nfds; ++fds_idx)
{
if(! (_fds[fds_idx].revents & POLLIN))
{
continue;
}
struct input_event event;
if(read(_fds[fds_idx].fd, &event, sizeof(event)) < (int) sizeof(event))
{
DEBUGF("ERROR %s: Read of input devices failed.", __func__);
continue;
}
/*DEBUGF("DEBUG %s: device: %s, event.type: %d, event.code: %d, event.value: %d", __func__, _device_names[fds_idx], event.type, event.code, event.value);*/
switch(event.type)
{
case EVENT_TYPE_BUTTON:
{
if(event.code == EVENT_CODE_BUTTON_HOLD)
{
/* Hold switch toggled, update hold switch state. */
button_hold();
backlight_hold_changed(_hold);
_last_btns = BUTTON_NONE;
break;
}
_last_btns = handle_button_event(event.code, event.value, _last_btns);
if(_hold)
{
/* Hold switch engaged. Ignore all button events. */
_last_btns = BUTTON_NONE;
}
/*DEBUGF("DEBUG %s: _last_btns: %#8.8x", __func__, _last_btns);*/
break;
}
case EVENT_TYPE_TOUCHSCREEN:
{
if(_hold)
{
/* Hold switch engaged, ignore all touchscreen events. */
_last_touch_state = TOUCHSCREEN_STATE_UNKNOWN;
_last_btns = BUTTON_NONE;
}
else
{
read_more = handle_touchscreen_event(event.code, event.value);
/*DEBUGF("DEBUG %s: _last_touch_state: %d, _last_x: %d, _last_y: %d, read_more: %s", __func__, _last_touch_state, _last_x, _last_y, read_more ? "true" : "false");*/
}
break;
}
}
}
}
/*
Get grid button/coordinates based on the current touchscreen mode
Caveat: The caller seemingly depends on *data always being filled with
the last known touchscreen position, so always call
touchscreen_to_pixels().
*/
int touch = touchscreen_to_pixels(_last_x, _last_y, data);
if(_last_touch_state == TOUCHSCREEN_STATE_DOWN)
{
return _last_btns | touch;
}
/*DEBUGF("DEBUG %s: _last_btns: %#8.8x.", __func__, _last_btns);*/
return _last_btns;
}
void button_close_device(void)
{
TRACE;
if(_fds)
{
for(nfds_t fds_idx = 0; fds_idx < _nfds; ++fds_idx)
{
close(_fds[fds_idx].fd);
}
free(_fds);
_fds = NULL;
}
if(_device_names)
{
for(nfds_t fds_idx = 0; fds_idx < _nfds; ++fds_idx)
{
free(_device_names[fds_idx]);
}
free(_device_names);
_device_names = NULL;
}
_nfds = 0;
}

View File

@ -0,0 +1,61 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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_IBASSO_H_
#define _BUTTON_IBASSO_H_
#include <sys/types.h>
/* /dev/input/event0 */
#define EVENT_CODE_BUTTON_PWR 116
#define EVENT_CODE_BUTTON_PWR_LONG 117
/* /dev/input/event1 */
#define EVENT_CODE_BUTTON_VOLPLUS 158
#define EVENT_CODE_BUTTON_VOLMINUS 159
#define EVENT_CODE_BUTTON_REV 160
#define EVENT_CODE_BUTTON_PLAY 161
#define EVENT_CODE_BUTTON_NEXT 162
#define EVENT_VALUE_BUTTON_PRESS 1
#define EVENT_VALUE_BUTTON_RELEASE 0
/*
Handle hardware button events.
code: Input event code.
value: Input event value.
last_btns: Last known pressed buttons.
Returns: Currently pressed buttons as bitmask (BUTTON_ values in button-target.h).
*/
int handle_button_event(__u16 code, __s32 value, int last_btns);
/* Clean up the button device handler. */
void button_close_device(void);
#endif

View File

@ -1,32 +1,32 @@
/***************************************************************************
* __________ __ ___.
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Rob Purchase
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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.r
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _BUTTON_TARGET_H_
#define _BUTTON_TARGET_H_
#include <stdbool.h>
#define HAS_BUTTON_HOLD
/* Main unit's buttons */
/* Hardware buttons. */
#define BUTTON_LEFT 0x00000001
#define BUTTON_RIGHT 0x00000002
#define BUTTON_PLAY 0x00000004
@ -35,25 +35,15 @@
#define BUTTON_VOL_DOWN 0x00000020
#define BUTTON_POWER_LONG 0x00000040
#define BUTTON_MAIN (BUTTON_LEFT|BUTTON_VOL_UP|BUTTON_VOL_DOWN\
|BUTTON_RIGHT|BUTTON_PLAY|BUTTON_POWER|BUTTON_POWER_LONG)
#define BUTTON_MAIN ( BUTTON_LEFT | BUTTON_VOL_UP | BUTTON_VOL_DOWN | BUTTON_RIGHT \
| BUTTON_PLAY | BUTTON_POWER | BUTTON_POWER_LONG)
#define KEYCODE_LINEOUT 113
#define KEYCODE_SPDIF 114
#define KEYCODE_HOLD 115
#define KEYCODE_PWR 116
#define KEYCODE_PWR_LONG 117
#define KEYCODE_SD 143
#define KEYCODE_VOLPLUS 158
#define KEYCODE_VOLMINUS 159
#define KEYCODE_PREV 160
#define KEYCODE_NEXT 162
#define KEYCODE_PLAY 161
#define STATE_UNLOCKED 16
#define STATE_SPDIF_UNPLUGGED 32
#define STATE_SPDIF_UNPLUGGED 32
#define STATE_LINEOUT_UNPLUGGED 64
/* Touch Screen Area Buttons */
/* Touchscreen area buttons 3x3 grid. */
#define BUTTON_TOPLEFT 0x00001000
#define BUTTON_TOPMIDDLE 0x00002000
#define BUTTON_TOPRIGHT 0x00004000
@ -65,8 +55,9 @@
#define BUTTON_BOTTOMRIGHT 0x00100000
/* Software power-off */
#define POWEROFF_BUTTON BUTTON_POWER_LONG
#define POWEROFF_COUNT 0
/* Power-off */
#define POWEROFF_BUTTON BUTTON_POWER_LONG
#define POWEROFF_COUNT 0
#endif /* _BUTTON_TARGET_H_ */
#endif

View File

@ -0,0 +1,70 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <android/log.h>
#include "config.h"
#include "debug.h"
#include "debug-ibasso.h"
static const char log_tag[] = "Rockbox";
void debug_init(void)
{}
void debugf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
__android_log_vprint(ANDROID_LOG_DEBUG, log_tag, fmt, ap);
va_end(ap);
}
void ldebugf(const char* file, int line, const char *fmt, ...)
{
va_list ap;
/* 13: 5 literal chars and 8 chars for the line number. */
char buf[strlen(file) + strlen(fmt) + 13];
snprintf(buf, sizeof(buf), "%s (%d): %s", file, line, fmt);
va_start(ap, fmt);
__android_log_vprint(ANDROID_LOG_DEBUG, log_tag, buf, ap);
va_end(ap);
}
void debug_trace(const char* function)
{
static const char trace_tag[] = "TRACE: ";
char msg[strlen(trace_tag) + strlen(function) + 1];
snprintf(msg, sizeof(msg), "%s%s", trace_tag, function);
__android_log_write(ANDROID_LOG_DEBUG, log_tag, msg);
}

View File

@ -0,0 +1,38 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 _DEBUG_IBASSO_H_
#define _DEBUG_IBASSO_H_
void debug_trace(const char* function);
#ifdef DEBUG
#define TRACE debug_trace(__func__)
#else
#define TRACE
#endif
#endif

View File

@ -0,0 +1,68 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 "debug.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
extern void set_software_volume(void);
void audiohw_set_volume(int volume)
{
set_software_volume();
/*
See codec-dx50.h.
-128db -> -1 (adjusted to 0, mute)
-127dB to 0dB -> 1 to 255 in steps of 2
volume is in centibels (tenth-decibels).
*/
int volume_adjusted = (volume / 10) * 2 + 255;
DEBUGF("DEBUG %s: volume: %d, volume_adjusted: %d.", __func__, volume, volume_adjusted);
if(volume_adjusted > 255)
{
DEBUGF("DEBUG %s: Adjusting volume from %d to 255.", __func__, volume);
volume_adjusted = 255;
}
if(volume_adjusted < 0)
{
DEBUGF("DEBUG %s: Adjusting volume from %d to 0.", __func__, volume);
volume_adjusted = 0;
}
/*
/dev/codec_volume
0 ... 255
*/
if(! sysfs_set_int(SYSFS_DX50_CODEC_VOLUME, volume_adjusted))
{
DEBUGF("ERROR %s: Can not set volume.", __func__);
}
}

View File

@ -0,0 +1,96 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 "button-ibasso.h"
int handle_button_event(__u16 code, __s32 value, int last_btns)
{
int button = BUTTON_NONE;
switch(code)
{
case EVENT_CODE_BUTTON_PWR:
{
button = BUTTON_POWER;
break;
}
case EVENT_CODE_BUTTON_PWR_LONG:
{
button = BUTTON_POWER_LONG;
break;
}
case EVENT_CODE_BUTTON_VOLPLUS:
{
button = BUTTON_VOL_UP;
break;
}
case EVENT_CODE_BUTTON_VOLMINUS:
{
button = BUTTON_VOL_DOWN;
break;
}
case EVENT_CODE_BUTTON_REV:
{
button = BUTTON_LEFT;
break;
}
case EVENT_CODE_BUTTON_PLAY:
{
button = BUTTON_PLAY;
break;
}
case EVENT_CODE_BUTTON_NEXT:
{
button = BUTTON_RIGHT;
break;
}
default:
{
return BUTTON_NONE;
}
}
int buttons = last_btns;
if(value == EVENT_VALUE_BUTTON_PRESS)
{
buttons = (last_btns | button);
}
else
{
buttons = (last_btns & (~ button));
}
return buttons;
}

View File

@ -0,0 +1,51 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 _CODEC_DX50_H_
#define _CODEC_DX50_H_
#define AUDIOHW_CAPS MONO_VOL_CAP
/*
http://www.wolfsonmicro.com/media/76425/WM8740.pdf
0.5 * ( x - 255 ) = ydB 1 <= x <= 255
mute x = 0
x = 255 -> 0dB
.
.
.
x = 2 -> -126.5dB
x = 1 -> -127dB
x = 0 -> -128dB
See audiohw.h, sound.c.
*/
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -128, 0, -30)
#endif

View File

@ -0,0 +1,63 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 "debug.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
extern void set_software_volume(void);
void audiohw_set_volume(int volume)
{
set_software_volume();
/* See codec-dx90.h. -2550 to 0 -> 0 to 255 */
int volume_adjusted = ((volume + 2550) / 10);
DEBUGF("DEBUG %s: volume: %d, volume_adjusted: %d.", __func__, volume, volume_adjusted);
if(volume_adjusted > 255)
{
DEBUGF("DEBUG %s: Adjusting volume from %d to 255.", __func__, volume);
volume_adjusted = 255;
}
if(volume_adjusted < 0)
{
DEBUGF("DEBUG %s: Adjusting volume from %d to 0.", __func__, volume);
volume_adjusted = 0;
}
/*
/sys/class/codec/es9018_volume
0 ... 255
*/
if(! sysfs_set_int(SYSFS_DX90_ES9018_VOLUME, volume_adjusted))
{
DEBUGF("ERROR %s: Can not set volume.", __func__);
}
}

View File

@ -0,0 +1,104 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 "button-ibasso.h"
int handle_button_event(__u16 code, __s32 value, int last_btns)
{
int button = BUTTON_NONE;
switch(code)
{
case EVENT_CODE_BUTTON_PWR:
{
button = BUTTON_POWER;
break;
}
case EVENT_CODE_BUTTON_PWR_LONG:
{
button = BUTTON_POWER_LONG;
break;
}
case EVENT_CODE_BUTTON_VOLPLUS:
{
button = BUTTON_VOL_UP;
break;
}
case EVENT_CODE_BUTTON_VOLMINUS:
{
button = BUTTON_VOL_DOWN;
break;
}
case EVENT_CODE_BUTTON_REV:
{
button = BUTTON_LEFT;
break;
}
case EVENT_CODE_BUTTON_PLAY:
{
button = BUTTON_PLAY;
break;
}
case EVENT_CODE_BUTTON_NEXT:
{
button = BUTTON_RIGHT;
break;
}
default:
{
return BUTTON_NONE;
}
}
if( (button == BUTTON_RIGHT)
&& ((last_btns & BUTTON_LEFT) == BUTTON_LEFT)
&& (value == EVENT_VALUE_BUTTON_RELEASE))
{
/* Workaround for a wrong feedback, only present with DX90. */
button = BUTTON_LEFT;
}
int buttons = last_btns;
if(value == EVENT_VALUE_BUTTON_PRESS)
{
buttons = (last_btns | button);
}
else
{
buttons = (last_btns & (~button));
}
return buttons;
}

View File

@ -0,0 +1,35 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 _CODEC_DX90_H_
#define _CODEC_DX90_H_
#define AUDIOHW_CAPS MONO_VOL_CAP
AUDIOHW_SETTING(VOLUME, "", 0, 1, -255, 0, -128)
#endif

View File

@ -0,0 +1,47 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <unistd.h>
#include "debug-ibasso.h"
/* See hostfs.h. */
int hostfs_init(void)
{
TRACE;
return 0;
}
int hostfs_flush(void)
{
TRACE;
sync();
return 0;
}

View File

@ -0,0 +1,195 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "config.h"
#include "debug.h"
#include "events.h"
#include "panic.h"
#include "debug-ibasso.h"
#include "lcd-target.h"
#include "sysfs-ibasso.h"
fb_data *dev_fb = 0;
/* Framebuffer device handle. */
static int dev_fd = 0;
void lcd_init_device(void)
{
TRACE;
dev_fd = open("/dev/graphics/fb0", O_RDWR);
if(dev_fd == -1)
{
DEBUGF("ERROR %s: open failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
exit(errno);
}
/* Get the changeable information. */
struct fb_var_screeninfo vinfo;
if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
{
DEBUGF("ERROR %s: ioctl FBIOGET_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
exit(errno);
}
DEBUGF("DEBUG %s: bits_per_pixel: %u, width: %u, height: %u.", __func__, vinfo.bits_per_pixel, vinfo.width, vinfo.height);
/*
Framebuffer does not fit the screen, a bug of iBassos Firmware, not Rockbox.
Cannot be solved with parameters.
*/
/*vinfo.bits_per_pixel = LCD_DEPTH;
vinfo.xres = LCD_WIDTH;
vinfo.xres_virtual = LCD_WIDTH;
vinfo.width = LCD_WIDTH;
vinfo.yres = LCD_HEIGHT;
vinfo.yres_virtual = LCD_HEIGHT;
vinfo.height = LCD_HEIGHT;
vinfo.activate = FB_ACTIVATE_NOW;
if(ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo) == -1)
{
DEBUGF("ERROR %s: ioctl FBIOPUT_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
exit(EXIT_FAILURE);
}*/
/* Sanity check: Does framebuffer config match Rockbox config? */
size_t screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
if(screensize != FRAMEBUFFER_SIZE)
{
DEBUGF("ERROR %s: Screen size does not match config: %d != %d.", __func__, screensize, FRAMEBUFFER_SIZE);
exit(EXIT_FAILURE);
}
/* Map the device to memory. */
dev_fb = mmap(0, FRAMEBUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
if(dev_fb == MAP_FAILED)
{
DEBUGF("ERROR %s: mmap failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
exit(errno);
}
/* Activate Rockbox LCD. */
lcd_enable(true);
}
void lcd_shutdown(void)
{
TRACE;
lcd_set_active(false);
munmap(dev_fb, FRAMEBUFFER_SIZE);
close(dev_fd) ;
}
/*
Left as reference. Unblanking does not work as expected, will not enable LCD after a few
seconds of power down.
Instead the backlight power is toggled.
*/
/*void lcd_power_on(void)
{
TRACE;
if(ioctl(dev_fd, FBIOBLANK, VESA_NO_BLANKING) == -1)
{
DEBUGF("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
panicf("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
return;
}
lcd_set_active(true);
send_event(LCD_EVENT_ACTIVATION, NULL);
}
void lcd_power_off(void)
{
TRACE;
lcd_set_active(false);
if(ioctl(dev_fd, FBIOBLANK, VESA_POWERDOWN) == -1)
{
DEBUGF("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
panicf("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
return;
}
}*/
void lcd_enable(bool on)
{
TRACE;
lcd_set_active(on);
if(on)
{
/*
/sys/power/state
on: Cancel suspend.
*/
if(! sysfs_set_string(SYSFS_POWER_STATE, "on"))
{
DEBUGF("ERROR %s: Can not set power state.", __func__);
}
send_event(LCD_EVENT_ACTIVATION, NULL);
}
}
void lcd_sleep(void)
{
TRACE;
/*
See system_init(). Without suspend blocker und mute prevention this will interrupt playback.
Essentially, we are turning off the touch screen.
/sys/power/state
mem: Suspend to RAM.
*/
if(! sysfs_set_string(SYSFS_POWER_STATE, "mem"))
{
DEBUGF("ERROR %s: Can not set power state.", __func__);
}
}

View File

@ -0,0 +1,44 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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__
#include "lcd.h"
/*
Framebuffer device and framebuffer access.
See lcd-memframe.c
*/
extern fb_data *dev_fb;
#define LCD_FRAMEBUF_ADDR(col, row) (dev_fb + row * LCD_WIDTH + col)
/* See lcd-memframe.c */
extern void lcd_set_active(bool active);
#endif

View File

@ -0,0 +1,488 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <pthread.h>
#include <stdbool.h>
#include <unistd.h>
#include "config.h"
#include "debug.h"
#include "panic.h"
#include "pcm.h"
#include "pcm-internal.h"
#include "sound/asound.h"
#include "tinyalsa/asoundlib.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
/* Tiny alsa handle. */
static struct pcm* _alsa_handle = NULL;
/* Bytes left in the Rockbox PCM frame buffer. */
static size_t _pcm_buffer_size = 0;
/* Rockbox PCM frame buffer. */
static const void *_pcm_buffer = NULL;
/*
1: PCM thread suspended.
0: PCM thread running.
These are used by pcm_play_[lock|unlock] or pcm_play_dma_[start|stop|pause]. These need to be
separated because of nested calls for locking and stopping.
*/
static volatile sig_atomic_t _dma_stopped = 1;
static volatile sig_atomic_t _dma_locked = 1;
/* Mutex for PCM thread suspend/unsuspend. */
static pthread_mutex_t _dma_suspended_mtx = PTHREAD_MUTEX_INITIALIZER;
/* Signal condition for PCM thread suspend/unsuspend. */
static pthread_cond_t _dma_suspended_cond = PTHREAD_COND_INITIALIZER;
static void* pcm_thread_run(void* nothing)
{
(void) nothing;
DEBUGF("DEBUG %s: Thread start.", __func__);
while(true)
{
pthread_mutex_lock(&_dma_suspended_mtx);
while((_dma_stopped == 1) || (_dma_locked == 1))
{
DEBUGF("DEBUG %s: Playback suspended.", __func__);
pthread_cond_wait(&_dma_suspended_cond, &_dma_suspended_mtx);
DEBUGF("DEBUG %s: Playback resumed.", __func__);
}
pthread_mutex_unlock(&_dma_suspended_mtx);
if(_pcm_buffer_size == 0)
{
/* Retrive a new PCM buffer from Rockbox. */
if(! pcm_play_dma_complete_callback(PCM_DMAST_OK, &_pcm_buffer, &_pcm_buffer_size))
{
DEBUGF("DEBUG %s: No new buffer.", __func__);
usleep( 10000 );
continue;
}
}
pcm_play_dma_status_callback(PCM_DMAST_STARTED);
/* This relies on Rockbox PCM frame buffer size == ALSA PCM frame buffer size. */
if(pcm_write(_alsa_handle, _pcm_buffer, _pcm_buffer_size) != 0)
{
DEBUGF("ERROR %s: pcm_write failed: %s.", __func__, pcm_get_error(_alsa_handle));
usleep( 10000 );
continue;
}
_pcm_buffer_size = 0;
/*DEBUGF("DEBUG %s: Thread running.", __func__);*/
}
DEBUGF("DEBUG %s: Thread end.", __func__);
return 0;
}
#ifdef DEBUG
/* https://github.com/tinyalsa/tinyalsa/blob/master/tinypcminfo.c */
static const char* format_lookup[] =
{
/*[0] =*/ "S8",
"U8",
"S16_LE",
"S16_BE",
"U16_LE",
"U16_BE",
"S24_LE",
"S24_BE",
"U24_LE",
"U24_BE",
"S32_LE",
"S32_BE",
"U32_LE",
"U32_BE",
"FLOAT_LE",
"FLOAT_BE",
"FLOAT64_LE",
"FLOAT64_BE",
"IEC958_SUBFRAME_LE",
"IEC958_SUBFRAME_BE",
"MU_LAW",
"A_LAW",
"IMA_ADPCM",
"MPEG",
/*[24] =*/ "GSM",
[31] = "SPECIAL",
"S24_3LE",
"S24_3BE",
"U24_3LE",
"U24_3BE",
"S20_3LE",
"S20_3BE",
"U20_3LE",
"U20_3BE",
"S18_3LE",
"S18_3BE",
"U18_3LE",
/*[43] =*/ "U18_3BE"
};
static const char* pcm_get_format_name(unsigned int bit_index)
{
return(bit_index < 43 ? format_lookup[bit_index] : NULL);
}
#endif
/* Thread that copies the Rockbox PCM buffer to ALSA. */
static pthread_t _pcm_thread;
/* ALSA card and device. */
static const unsigned int CARD = 0;
static const unsigned int DEVICE = 0;
/* ALSA config. */
static struct pcm_config _config;
void pcm_play_dma_init(void)
{
TRACE;
#ifdef DEBUG
/*
DEBUG pcm_play_dma_init: Access: 0x000009
DEBUG pcm_play_dma_init: Format[0]: 0x000044
DEBUG pcm_play_dma_init: Format[1]: 0x000010
DEBUG pcm_play_dma_init: Format: S16_LE
DEBUG pcm_play_dma_init: Format: S24_LE
DEBUG pcm_play_dma_init: Format: S20_3LE
DEBUG pcm_play_dma_init: Subformat: 0x000001
DEBUG pcm_play_dma_init: Rate: min = 8000Hz, max = 192000Hz
DEBUG pcm_play_dma_init: Channels: min = 2, max = 2
DEBUG pcm_play_dma_init: Sample bits: min=16, max=32
DEBUG pcm_play_dma_init: Period size: min=8, max=10922
DEBUG pcm_play_dma_init: Period count: min=3, max=128
DEBUG pcm_play_dma_init: 0 mixer controls.
*/
struct pcm_params* params = pcm_params_get(CARD, DEVICE, PCM_OUT);
if(params == NULL)
{
DEBUGF("ERROR %s: Card/device does not exist.", __func__);
panicf("ERROR %s: Card/device does not exist.", __func__);
return;
}
struct pcm_mask* m = pcm_params_get_mask(params, PCM_PARAM_ACCESS);
if(m)
{
DEBUGF("DEBUG %s: Access: %#08x", __func__, m->bits[0]);
}
m = pcm_params_get_mask(params, PCM_PARAM_FORMAT);
if(m)
{
DEBUGF("DEBUG %s: Format[0]: %#08x", __func__, m->bits[0]);
DEBUGF("DEBUG %s: Format[1]: %#08x", __func__, m->bits[1]);
unsigned int j;
unsigned int k;
const unsigned int bitcount = sizeof(m->bits[0]) * 8;
for(k = 0; k < 2; ++k)
{
for(j = 0; j < bitcount; ++j)
{
const char* name;
if(m->bits[k] & (1 << j))
{
name = pcm_get_format_name(j + (k * bitcount));
if(name)
{
DEBUGF("DEBUG %s: Format: %s", __func__, name);
}
}
}
}
}
m = pcm_params_get_mask(params, PCM_PARAM_SUBFORMAT);
if(m)
{
DEBUGF("DEBUG %s: Subformat: %#08x", __func__, m->bits[0]);
}
unsigned int min = pcm_params_get_min(params, PCM_PARAM_RATE);
unsigned int max = pcm_params_get_max(params, PCM_PARAM_RATE) ;
DEBUGF("DEBUG %s: Rate: min = %uHz, max = %uHz", __func__, min, max);
min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
DEBUGF("DEBUG %s: Channels: min = %u, max = %u", __func__, min, max);
min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
DEBUGF("DEBUG %s: Sample bits: min=%u, max=%u", __func__, min, max);
min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
DEBUGF("DEBUG %s: Period size: min=%u, max=%u", __func__, min, max);
min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
DEBUGF("DEBUG %s: Period count: min=%u, max=%u", __func__, min, max);
pcm_params_free(params);
struct mixer* mixer = mixer_open(CARD);
if(! mixer)
{
DEBUGF("ERROR %s: Failed to open mixer.", __func__);
}
else
{
int num_ctls = mixer_get_num_ctls(mixer);
DEBUGF("DEBUG %s: %d mixer controls.", __func__, num_ctls);
mixer_close(mixer);
}
#endif
if(_alsa_handle != NULL)
{
DEBUGF("ERROR %s: Allready initialized.", __func__);
panicf("ERROR %s: Allready initialized.", __func__);
return;
}
/*
Rockbox outputs 16 Bit/44.1kHz stereo by default.
ALSA frame buffer size = config.period_count * config.period_size * config.channels * (16 \ 8)
= 4 * 256 * 2 * 2
= 4096
= Rockbox PCM buffer size
pcm_thread_run relies on this size match. See pcm_mixer.h.
*/
_config.channels = 2;
_config.rate = 44100;
_config.period_size = 256;
_config.period_count = 4;
_config.format = PCM_FORMAT_S16_LE;
_config.start_threshold = 0;
_config.stop_threshold = 0;
_config.silence_threshold = 0;
_alsa_handle = pcm_open(CARD, DEVICE, PCM_OUT, &_config);
if(! pcm_is_ready(_alsa_handle))
{
DEBUGF("ERROR %s: pcm_open failed: %s.", __func__, pcm_get_error(_alsa_handle));
panicf("ERROR %s: pcm_open failed: %s.", __func__, pcm_get_error(_alsa_handle));
return;
}
DEBUGF("DEBUG %s: ALSA PCM frame buffer size: %d.", __func__, pcm_frames_to_bytes(_alsa_handle, pcm_get_buffer_size(_alsa_handle)));
/* Create pcm thread in the suspended state. */
pthread_mutex_lock(&_dma_suspended_mtx);
_dma_stopped = 1;
_dma_locked = 1;
pthread_create(&_pcm_thread, NULL, pcm_thread_run, NULL);
pthread_mutex_unlock(&_dma_suspended_mtx);
}
void pcm_play_dma_start(const void *addr, size_t size)
{
TRACE;
/*
DX50
/sys/class/codec/mute
Mute: echo 'A' > /sys/class/codec/mute
Unmute: echo 'B' > /sys/class/codec/mute
DX90?
*/
if(! sysfs_set_char(SYSFS_MUTE, 'B'))
{
DEBUGF("ERROR %s: Could not unmute.", __func__);
panicf("ERROR %s: Could not unmute.", __func__);
}
_pcm_buffer = addr;
_pcm_buffer_size = size;
pthread_mutex_lock(&_dma_suspended_mtx);
_dma_stopped = 0;
pthread_cond_signal(&_dma_suspended_cond);
pthread_mutex_unlock(&_dma_suspended_mtx);
}
/* TODO: Why is this in the API if it gets never called? */
void pcm_play_dma_pause(bool pause)
{
TRACE;
pthread_mutex_lock(&_dma_suspended_mtx);
_dma_stopped = pause ? 1 : 0;
if(_dma_stopped == 0)
{
pthread_cond_signal(&_dma_suspended_cond);
}
pthread_mutex_unlock(&_dma_suspended_mtx);
}
void pcm_play_dma_stop(void)
{
TRACE;
pthread_mutex_lock(&_dma_suspended_mtx);
_dma_stopped = 1;
pcm_stop(_alsa_handle);
pthread_mutex_unlock(&_dma_suspended_mtx);
}
/* Unessecary play locks before pcm_play_dma_postinit. */
static int _play_lock_recursion_count = -10000;
void pcm_play_dma_postinit(void)
{
TRACE;
_play_lock_recursion_count = 0;
}
void pcm_play_lock(void)
{
TRACE;
++_play_lock_recursion_count;
if(_play_lock_recursion_count == 1)
{
pthread_mutex_lock(&_dma_suspended_mtx);
_dma_locked = 1;
pthread_mutex_unlock(&_dma_suspended_mtx);
}
}
void pcm_play_unlock(void)
{
TRACE;
--_play_lock_recursion_count;
if(_play_lock_recursion_count == 0)
{
pthread_mutex_lock(&_dma_suspended_mtx);
_dma_locked = 0;
pthread_cond_signal(&_dma_suspended_cond);
pthread_mutex_unlock(&_dma_suspended_mtx);
}
}
void pcm_dma_apply_settings(void)
{
unsigned int rate = pcm_get_frequency();
DEBUGF("DEBUG %s: Current sample rate: %u, next sampe rate: %u.", __func__, _config.rate, rate);
if(( _config.rate != rate) && (rate >= 8000) && (rate <= 192000))
{
_config.rate = rate;
pcm_close(_alsa_handle);
_alsa_handle = pcm_open(CARD, DEVICE, PCM_OUT, &_config);
if(! pcm_is_ready(_alsa_handle))
{
DEBUGF("ERROR %s: pcm_open failed: %s.", __func__, pcm_get_error(_alsa_handle));
panicf("ERROR %s: pcm_open failed: %s.", __func__, pcm_get_error(_alsa_handle));
}
}
}
size_t pcm_get_bytes_waiting(void)
{
TRACE;
return _pcm_buffer_size;
}
/* TODO: WTF */
const void* pcm_play_dma_get_peak_buffer(int* count)
{
TRACE;
uintptr_t addr = (uintptr_t) _pcm_buffer;
*count = _pcm_buffer_size / 4;
return (void*) ((addr + 3) & ~3);
}
void pcm_close_device(void)
{
TRACE;
pthread_mutex_lock(&_dma_suspended_mtx);
_dma_stopped = 1;
pthread_mutex_unlock(&_dma_suspended_mtx);
pcm_close(_alsa_handle);
_alsa_handle = NULL;
}

View File

@ -0,0 +1,33 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 __PCM_IBASSO_H__
#define __PCM_IBASSO_H__
/* Clean up the audio device handler. */
void pcm_close_device(void);
#endif

View File

@ -0,0 +1,97 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <stdlib.h>
#include <sys/reboot.h>
#include "config.h"
#include "debug.h"
#include "power.h"
#include "button-ibasso.h"
#include "debug-ibasso.h"
#include "pcm-ibasso.h"
#include "sysfs-ibasso.h"
#include "vold-ibasso.h"
unsigned int power_input_status(void)
{
/*TRACE;*/
/*
/sys/class/power_supply/usb/present
0: No external power supply connected.
1: External power supply connected.
*/
int val = 0;
if(! sysfs_get_int(SYSFS_USB_POWER_PRESENT, &val))
{
DEBUGF("ERROR %s: Can not get power supply status.", __func__);
return POWER_INPUT_NONE;
}
return val ? POWER_INPUT_USB_CHARGER : POWER_INPUT_NONE;
}
void power_off(void)
{
TRACE;
button_close_device();
if(vold_monitor_forced_close_imminent())
{
/*
We are here, because Android Vold is going to kill Rockbox. Instead of powering off,
we exit into the loader.
*/
DEBUGF("DEBUG %s: Exit Rockbox.", __func__);
exit(42);
}
reboot(RB_POWER_OFF);
}
/* Returns true, if battery is charging, false else. */
bool charging_state(void)
{
/*TRACE;*/
/*
/sys/class/power_supply/battery/status
"Full", "Charging", "Discharging"
*/
char state[9];
if(! sysfs_get_string(SYSFS_BATTERY_STATUS, state, 9))
{
DEBUGF("ERROR %s: Can not get battery charging state.", __func__);
return false;
}
return(strcmp(state, "Charging") == 0);;
}

View File

@ -0,0 +1,122 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <stdio.h>
#include "config.h"
#include "debug.h"
#include "panic.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
/* Based on batterymonitor with PISEN and Samsung SIII battery. */
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
3600
};
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
3500
};
/*
Averages at percent of running time from five measuremnts with PISEN and Samsung SIII battery
during normal usage.
Mongo default values (?)
< 3660 (0%), < 3730 (1% - 10%), < 3780 (11% - 20%), < 3830 (21% - 40%), < 3950 (41% - 60%),
< 4080 (61% - 80%), > 4081 (81% - 100%)
*/
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
{ 3522, 3660, 3720, 3752, 3784, 3827, 3896, 3978, 4072, 4168, 4255 }
};
/* Copied from percent_to_volt_discharge. */
const unsigned short percent_to_volt_charge[11] =
{
3500, 3544, 3578, 3623, 3660, 3773, 3782, 3853, 3980, 4130, 4360
};
static int _battery_present = -1;
int _battery_voltage(void)
{
/*TRACE;*/
if( (_battery_present == -1)
&& (! sysfs_get_int(SYSFS_BATTERY_PRESENT, &_battery_present)))
{
/* This check is only done once at startup. */
DEBUGF("ERROR %s: Can not get current battery availabilty.", __func__);
_battery_present = 1;
}
int val;
if(_battery_present == 1)
{
/* Battery is present. */
/*
/sys/class/power_supply/battery/voltage_now
Voltage in microvolt.
*/
if(! sysfs_get_int(SYSFS_BATTERY_VOLTAGE_NOW, &val))
{
DEBUGF("ERROR %s: Can not get current battery voltage.", __func__);
return 0;
}
}
else
{
/*
No battery, so we have to be running solely from USB power.
This will prevent Rockbox from forcing shutdown due to low power.
*/
/*
/sys/class/power_supply/usb/voltage_now
Voltage in microvolt.
*/
if(! sysfs_get_int(SYSFS_USB_POWER_VOLTAGE_NOW, &val))
{
DEBUGF("ERROR %s: Can not get current USB voltage.", __func__);
return 0;
}
}
return(val / 1000);
}

View File

@ -0,0 +1,404 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <stdio.h>
#include <string.h>
#include "config.h"
#include "debug.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
static const char* SYSFS_PATHS[] =
{
/* SYSFS_DX50_CODEC_VOLUME */
"/dev/codec_volume",
/* SYSFS_HOLDKEY */
"/sys/class/axppower/holdkey",
/* SYSFS_DX90_ES9018_VOLUME */
"/sys/class/codec/es9018_volume",
/* SYSFS_MUTE */
"/sys/class/codec/mute",
/* SYSFS_WM8740_MUTE */
"/sys/class/codec/wm8740_mute",
/* SYSFS_BATTERY_CAPACITY */
"/sys/class/power_supply/battery/capacity",
/* SYSFS_BATTERY_CURRENT_NOW */
"/sys/class/power_supply/battery/current_now",
/* SYSFS_BATTERY_ENERGY_FULL_DESIGN */
"/sys/class/power_supply/battery/energy_full_design",
/* SYSFS_BATTERY_HEALTH */
"/sys/class/power_supply/battery/health",
/* SYSFS_BATTERY_MODEL_NAME */
"/sys/class/power_supply/battery/model_name",
/* SYSFS_BATTERY_ONLINE */
"/sys/class/power_supply/battery/online",
/* SYSFS_BATTERY_PRESENT */
"/sys/class/power_supply/battery/present",
/* SYSFS_BATTERY_STATUS */
"/sys/class/power_supply/battery/status",
/* SYSFS_BATTERY_TECHNOLOGY */
"/sys/class/power_supply/battery/technology",
/* SYSFS_BATTERY_TEMP */
"/sys/class/power_supply/battery/temp",
/* SYSFS_BATTERY_TYPE */
"/sys/class/power_supply/battery/type",
/* SYSFS_BATTERY_VOLTAGE_MAX_DESIGN */
"/sys/class/power_supply/battery/voltage_max_design",
/* SYSFS_BATTERY_VOLTAGE_MIN_DESIGN */
"/sys/class/power_supply/battery/voltage_min_design",
/* SYSFS_BATTERY_VOLTAGE_NOW */
"/sys/class/power_supply/battery/voltage_now",
/* SYSFS_USB_POWER_CURRENT_NOW */
"/sys/class/power_supply/usb/current_now",
/* SYSFS_USB_POWER_ONLINE */
"/sys/class/power_supply/usb/online",
/* SYSFS_USB_POWER_PRESENT */
"/sys/class/power_supply/usb/present",
/* SYSFS_USB_POWER_VOLTAGE_NOW */
"/sys/class/power_supply/usb/voltage_now",
/* SYSFS_BACKLIGHT_POWER */
"/sys/devices/platform/rk29_backlight/backlight/rk28_bl/bl_power",
/* SYSFS_BACKLIGHT_BRIGHTNESS */
"/sys/devices/platform/rk29_backlight/backlight/rk28_bl/brightness",
/* SYSFS_POWER_STATE */
"/sys/power/state",
/* SYSFS_POWER_WAKE_LOCK */
"/sys/power/wake_lock"
};
static FILE* open_read(const char* file_name)
{
FILE *f = fopen(file_name, "r");
if(f == NULL)
{
DEBUGF("ERROR %s: Can not open %s for reading.", __func__, file_name);
}
return f;
}
static FILE* open_write(const char* file_name)
{
FILE *f = fopen(file_name, "w");
if(f == NULL)
{
DEBUGF("ERROR %s: Can not open %s for writing.", __func__, file_name);
}
return f;
}
bool sysfs_get_int(enum sys_fs_interface_id id, int* value)
{
*value = -1;
switch(id)
{
case SYSFS_BATTERY_CAPACITY:
case SYSFS_BATTERY_CURRENT_NOW:
case SYSFS_BATTERY_ENERGY_FULL_DESIGN:
case SYSFS_BATTERY_ONLINE:
case SYSFS_BATTERY_PRESENT:
case SYSFS_BATTERY_TEMP:
case SYSFS_BATTERY_VOLTAGE_MAX_DESIGN:
case SYSFS_BATTERY_VOLTAGE_MIN_DESIGN:
case SYSFS_BATTERY_VOLTAGE_NOW:
case SYSFS_USB_POWER_CURRENT_NOW:
case SYSFS_USB_POWER_VOLTAGE_NOW:
case SYSFS_USB_POWER_ONLINE:
case SYSFS_USB_POWER_PRESENT:
{
break;
}
default:
{
DEBUGF("ERROR %s: Unknown interface id: %d.", __func__, id);
return false;
}
}
const char* interface = SYSFS_PATHS[id];
/*DEBUGF("%s: interface: %s.", __func__, interface);*/
FILE *f = open_read(interface);
if(f == NULL)
{
return false;
}
bool success = true;
if(fscanf(f, "%d", value) == EOF)
{
DEBUGF("ERROR %s: Read failed for %s.", __func__, interface);
success = false;
}
fclose(f);
return success;
}
bool sysfs_set_int(enum sys_fs_interface_id id, int value)
{
switch(id)
{
case SYSFS_BACKLIGHT_POWER:
case SYSFS_BACKLIGHT_BRIGHTNESS:
case SYSFS_DX50_CODEC_VOLUME:
case SYSFS_DX90_ES9018_VOLUME:
{
break;
}
default:
{
DEBUGF("ERROR %s: Unknown interface id: %d.", __func__, id);
return false;
}
}
const char* interface = SYSFS_PATHS[id];
/*DEBUGF("%s: interface: %s, value: %d.", __func__, interface, value);*/
FILE *f = open_write(interface);
if(f == NULL)
{
return false;
}
bool success = true;
if(fprintf(f, "%d", value) < 1)
{
DEBUGF("ERROR %s: Write failed for %s.", __func__, interface);
success = false;
}
fclose(f);
return success;
}
bool sysfs_get_char(enum sys_fs_interface_id id, char* value)
{
*value = '\0';
switch(id)
{
case SYSFS_HOLDKEY:
{
break;
}
default:
{
DEBUGF("ERROR %s: Unknown interface id: %d.", __func__, id);
return false;
}
}
const char* interface = SYSFS_PATHS[id];
/*DEBUGF("%s: interface: %s.", __func__, interface);*/
FILE *f = open_read(interface);
if(f == NULL)
{
return false;
}
bool success = true;
if(fscanf(f, "%c", value) == EOF)
{
DEBUGF("ERROR %s: Read failed for %s.", __func__, interface);
success = false;
}
fclose(f);
return success;
}
bool sysfs_set_char(enum sys_fs_interface_id id, char value)
{
switch(id)
{
case SYSFS_MUTE:
case SYSFS_WM8740_MUTE:
{
break;
}
default:
{
DEBUGF("ERROR %s: Unknown interface id: %d.", __func__, id);
return false;
}
}
const char* interface = SYSFS_PATHS[id];
/*DEBUGF("%s: interface: %s, value: %c.", __func__, interface, value);*/
FILE *f = open_write(interface);
if(f == NULL)
{
return false;
}
bool success = true;
if(fprintf(f, "%c", value) < 1)
{
DEBUGF("ERROR %s: Write failed for %s.", __func__, interface);
success = false;
}
fclose(f);
return success;
}
bool sysfs_get_string(enum sys_fs_interface_id id, char* value, int size)
{
value[0] = '\0';
switch(id)
{
case SYSFS_BATTERY_STATUS:
case SYSFS_BATTERY_HEALTH:
case SYSFS_BATTERY_MODEL_NAME:
case SYSFS_BATTERY_TECHNOLOGY:
case SYSFS_BATTERY_TYPE:
{
break;
}
default:
{
DEBUGF("ERROR %s: Unknown interface id: %d.", __func__, id);
return false;
}
}
const char* interface = SYSFS_PATHS[id];
/*DEBUGF("%s: interface: %s, size: %d.", __func__, interface, size);*/
FILE *f = open_read(interface);
if(f == NULL)
{
return false;
}
bool success = true;
if(fgets(value, size, f) == NULL)
{
DEBUGF("ERROR %s: Read failed for %s.", __func__, interface);
success = false;
}
else
{
size_t length = strlen(value);
if((length > 0) && value[length - 1] == '\n')
{
value[length - 1] = '\0';
}
}
fclose(f);
return success;
}
bool sysfs_set_string(enum sys_fs_interface_id id, char* value)
{
switch(id)
{
case SYSFS_POWER_STATE:
case SYSFS_POWER_WAKE_LOCK:
{
break;
}
default:
{
DEBUGF("ERROR %s: Unknown interface id: %d.", __func__, id);
return false;
}
}
const char* interface = SYSFS_PATHS[id];
/*DEBUGF("%s: interface: %s, value: %s.", __func__, interface, value);*/
FILE *f = open_write(interface);
if(f == NULL)
{
return false;
}
bool success = true;
if(fprintf(f, "%s", value) < 1)
{
DEBUGF("ERROR %s: Write failed for %s.", __func__, interface);
success = false;
}
fclose(f);
return success;
}

View File

@ -0,0 +1,111 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 _SYSFS_IBASSO_H_
#define _SYSFS_IBASSO_H_
#include <stdbool.h>
/*
Sys FS path identifiers.
See SYSFS_PATHS in sysfs-ibasso.c.
*/
enum sys_fs_interface_id
{
SYSFS_DX50_CODEC_VOLUME = 0,
SYSFS_HOLDKEY,
SYSFS_DX90_ES9018_VOLUME,
SYSFS_MUTE,
SYSFS_WM8740_MUTE,
SYSFS_BATTERY_CAPACITY,
SYSFS_BATTERY_CURRENT_NOW,
SYSFS_BATTERY_ENERGY_FULL_DESIGN,
SYSFS_BATTERY_HEALTH,
SYSFS_BATTERY_MODEL_NAME,
SYSFS_BATTERY_ONLINE,
SYSFS_BATTERY_PRESENT,
SYSFS_BATTERY_STATUS,
SYSFS_BATTERY_TECHNOLOGY,
SYSFS_BATTERY_TEMP,
SYSFS_BATTERY_TYPE,
SYSFS_BATTERY_VOLTAGE_MAX_DESIGN,
SYSFS_BATTERY_VOLTAGE_MIN_DESIGN,
SYSFS_BATTERY_VOLTAGE_NOW,
SYSFS_USB_POWER_CURRENT_NOW,
SYSFS_USB_POWER_ONLINE,
SYSFS_USB_POWER_PRESENT,
SYSFS_USB_POWER_VOLTAGE_NOW,
SYSFS_BACKLIGHT_POWER,
SYSFS_BACKLIGHT_BRIGHTNESS,
SYSFS_POWER_STATE,
SYSFS_POWER_WAKE_LOCK
};
/*
Read a integer value from the sys fs interface given by id.
Returns true on success, false else.
*/
bool sysfs_get_int(enum sys_fs_interface_id id, int* value);
/*
Write a integer value to the sys fs interface given by id.
Returns true on success, false else.
*/
bool sysfs_set_int(enum sys_fs_interface_id id, int value);
/*
Read a char value from the sys fs interface given by id.
Returns true on success, false else.
*/
bool sysfs_get_char(enum sys_fs_interface_id id, char* value);
/*
Write a char value to the sys fs interface given by id.
Returns true on success, false else.
*/
bool sysfs_set_char(enum sys_fs_interface_id id, char value);
/*
Read a single line of text from the sys fs interface given by id.
A newline will be discarded.
size: The size of value.
Returns true on success, false else.
*/
bool sysfs_get_string(enum sys_fs_interface_id id, char* value, int size);
/*
Write text to the sys fs interface given by id.
Returns true on success, false else.
*/
bool sysfs_set_string(enum sys_fs_interface_id id, char* value);
#endif

View File

@ -0,0 +1,101 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <stdint.h>
#include <stdlib.h>
#include <sys/reboot.h>
#include "config.h"
#include "cpufreq-linux.h"
#include "debug.h"
#include "button-ibasso.h"
#include "debug-ibasso.h"
#include "sysfs-ibasso.h"
#include "usb-ibasso.h"
#include "vold-ibasso.h"
/* Fake stack. */
uintptr_t* stackbegin;
uintptr_t* stackend;
void system_init(void)
{
TRACE;
/* Fake stack. */
volatile uintptr_t stack = 0;
stackbegin = stackend = (uintptr_t*) &stack;
cpufreq_set_governor("powersave", CPUFREQ_ALL_CPUS);
vold_monitor_start();
ibasso_set_usb_mode(USB_MODE_MASS_STORAGE);
/*
Prevent device from deep sleeping, which will interrupt playback.
/sys/power/wake_lock
*/
if(! sysfs_set_string(SYSFS_POWER_WAKE_LOCK, "rockbox"))
{
DEBUGF("ERROR %s: Can not set suspend blocker.", __func__);
}
/*
Prevent device to mute, which will cause tinyalsa pcm_writes to fail.
/sys/class/codec/wm8740_mute
*/
if(! sysfs_set_char(SYSFS_WM8740_MUTE, '0'))
{
DEBUGF("ERROR %s: Can not set WM8740 lock.", __func__);
}
}
void system_reboot(void)
{
TRACE;
button_close_device();
if(vold_monitor_forced_close_imminent())
{
/*
We are here, because Android Vold is going to kill Rockbox. Instead of powering off,
we exit into the loader.
*/
exit(42);
}
reboot(RB_AUTOBOOT);
}
void system_exception_wait(void)
{
TRACE;
while(1) {};
}

View File

@ -1,11 +1,15 @@
/***************************************************************************
* __________ __ ___.
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,13 +21,13 @@
*
****************************************************************************/
#ifndef __LCD_TARGET_H__
#define __LCD_TARGET_H__
extern fb_data *dev_fb;
#define LCD_FRAMEBUF_ADDR(col, row) (dev_fb + row*LCD_WIDTH + col)
#ifdef HAVE_LCD_ENABLE
extern void lcd_set_active(bool active);
extern void lcd_enable(bool enable);
#endif
#ifndef __SYSTEM_TARGET_H__
#define __SYSTEM_TARGET_H__
#include "kernel-unix.h"
#include "system-hosted.h"
#endif

View File

@ -818,4 +818,3 @@ struct snd_ctl_event {
#define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what
#endif

View File

@ -55,17 +55,14 @@ struct pcm;
* second call to pcm_write will attempt to
* restart the stream.
*/
#define PCM_MONOTONIC 0x00000008 /* see pcm_get_htimestamp */
/* PCM runtime states */
#define PCM_STATE_OPEN 0
#define PCM_STATE_SETUP 1
#define PCM_STATE_PREPARED 2
#define PCM_STATE_RUNNING 3
#define PCM_STATE_XRUN 4
#define PCM_STATE_DRAINING 5
#define PCM_STATE_PAUSED 6
#define PCM_STATE_SUSPENDED 7
#define PCM_STATE_DISCONNECTED 8
#define PCM_STATE_RUNNING 3
#define PCM_STATE_XRUN 4
#define PCM_STATE_DRAINING 5
#define PCM_STATE_SUSPENDED 7
#define PCM_STATE_DISCONNECTED 8
/* Bit formats */
enum pcm_format {
@ -77,6 +74,11 @@ enum pcm_format {
PCM_FORMAT_MAX,
};
/* Bitmask has 256 bits (32 bytes) in asound.h */
struct pcm_mask {
unsigned int bits[32 / sizeof(unsigned int)];
};
/* Configuration for a stream */
struct pcm_config {
unsigned int channels;
@ -101,6 +103,11 @@ struct pcm_config {
/* PCM parameters */
enum pcm_param
{
/* mask parameters */
PCM_PARAM_ACCESS,
PCM_PARAM_FORMAT,
PCM_PARAM_SUBFORMAT,
/* interval parameters */
PCM_PARAM_SAMPLE_BITS,
PCM_PARAM_FRAME_BITS,
PCM_PARAM_CHANNELS,
@ -138,15 +145,14 @@ int pcm_is_ready(struct pcm *pcm);
struct pcm_params *pcm_params_get(unsigned int card, unsigned int device,
unsigned int flags);
void pcm_params_free(struct pcm_params *pcm_params);
struct pcm_mask *pcm_params_get_mask(struct pcm_params *pcm_params,
enum pcm_param param);
unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
enum pcm_param param);
unsigned int pcm_params_get_max(struct pcm_params *pcm_params,
enum pcm_param param);
/* Set and get config */
int pcm_get_config(struct pcm *pcm, struct pcm_config *config);
int pcm_set_config(struct pcm *pcm, struct pcm_config *config);
/* Returns a human readable reason for the last error */
const char *pcm_get_error(struct pcm *pcm);
@ -162,10 +168,9 @@ unsigned int pcm_get_buffer_size(struct pcm *pcm);
unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames);
unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes);
/* Returns the pcm latency in ms */
unsigned int pcm_get_latency(struct pcm *pcm);
/* Returns available frames in pcm buffer and corresponding time stamp.
* The clock is CLOCK_MONOTONIC if flag PCM_MONOTONIC was specified in pcm_open,
* otherwise the clock is CLOCK_REALTIME.
* For an input stream, frames available are frames ready for the
* application to read.
* For an output stream, frames available are the number of empty frames available
@ -185,11 +190,13 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count);
* mmap() support.
*/
int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count);
int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count);
int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
unsigned int *frames);
int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
/* Prepare the PCM substream to be triggerable */
int pcm_prepare(struct pcm *pcm);
/* Start and stop a PCM channel that doesn't transfer data */
int pcm_start(struct pcm *pcm);
int pcm_stop(struct pcm *pcm);
@ -197,10 +204,6 @@ int pcm_stop(struct pcm *pcm);
/* Interrupt driven API */
int pcm_wait(struct pcm *pcm, int timeout);
int pcm_avail_update(struct pcm *pcm);
int pcm_state(struct pcm *pcm);
/*
* MIXER API

View File

@ -40,7 +40,7 @@
#define __force
#define __bitwise
#define __user
#include <tinyalsa/asound.h>
#include <sound/asound.h>
#include <tinyalsa/asoundlib.h>
@ -259,14 +259,11 @@ unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl)
static int percent_to_int(struct snd_ctl_elem_info *ei, int percent)
{
int range;
if ((percent > 100) || (percent < 0)) {
return -EINVAL;
}
if (percent > 100)
percent = 100;
else if (percent < 0)
percent = 0;
range = (ei->value.integer.max - ei->value.integer.min);
int range = (ei->value.integer.max - ei->value.integer.min);
return ei->value.integer.min + (range * percent) / 100;
}
@ -389,6 +386,11 @@ int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
break;
case SNDRV_CTL_ELEM_TYPE_INTEGER:
if ((value < mixer_ctl_get_range_min(ctl)) ||
(value > mixer_ctl_get_range_max(ctl))) {
return -EINVAL;
}
ev.value.integer.value[id] = value;
break;
@ -396,6 +398,10 @@ int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
ev.value.enumerated.item[id] = value;
break;
case SNDRV_CTL_ELEM_TYPE_BYTES:
ev.value.bytes.data[id] = value;
break;
default:
return -EINVAL;
}
@ -494,4 +500,3 @@ int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string)
return -EINVAL;
}

View File

@ -44,7 +44,7 @@
#define __force
#define __bitwise
#define __user
#include <tinyalsa/asound.h>
#include <sound/asound.h>
#include <tinyalsa/asoundlib.h>
@ -159,6 +159,7 @@ struct pcm {
int fd;
unsigned int flags;
int running:1;
int prepared:1;
int underruns;
unsigned int buffer_size;
unsigned int boundary;
@ -300,7 +301,7 @@ static void pcm_hw_munmap_status(struct pcm *pcm) {
}
static int pcm_areas_copy(struct pcm *pcm, unsigned int pcm_offset,
const char *src, unsigned int src_offset,
char *buf, unsigned int src_offset,
unsigned int frames)
{
int size_bytes = pcm_frames_to_bytes(pcm, frames);
@ -308,12 +309,18 @@ static int pcm_areas_copy(struct pcm *pcm, unsigned int pcm_offset,
int src_offset_bytes = pcm_frames_to_bytes(pcm, src_offset);
/* interleaved only atm */
memcpy((char*)pcm->mmap_buffer + pcm_offset_bytes,
src + src_offset_bytes, size_bytes);
if (pcm->flags & PCM_IN)
memcpy(buf + src_offset_bytes,
(char*)pcm->mmap_buffer + pcm_offset_bytes,
size_bytes);
else
memcpy((char*)pcm->mmap_buffer + pcm_offset_bytes,
buf + src_offset_bytes,
size_bytes);
return 0;
}
static int pcm_mmap_write_areas(struct pcm *pcm, const char *src,
static int pcm_mmap_transfer_areas(struct pcm *pcm, char *buf,
unsigned int offset, unsigned int size)
{
void *pcm_areas;
@ -323,7 +330,7 @@ static int pcm_mmap_write_areas(struct pcm *pcm, const char *src,
while (size > 0) {
frames = size;
pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
pcm_areas_copy(pcm, pcm_offset, src, offset, frames);
pcm_areas_copy(pcm, pcm_offset, buf, offset, frames);
commit = pcm_mmap_commit(pcm, pcm_offset, frames);
if (commit < 0) {
oops(pcm, commit, "failed to commit %d frames\n", frames);
@ -386,14 +393,16 @@ int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
for (;;) {
if (!pcm->running) {
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE))
return oops(pcm, errno, "cannot prepare channel");
int prepare_error = pcm_prepare(pcm);
if (prepare_error)
return prepare_error;
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x))
return oops(pcm, errno, "cannot write initial data");
pcm->running = 1;
return 0;
}
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
pcm->prepared = 0;
pcm->running = 0;
if (errno == EPIPE) {
/* we failed to make our window -- try to restart if we are
@ -429,6 +438,7 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count)
}
}
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
pcm->prepared = 0;
pcm->running = 0;
if (errno == EPIPE) {
/* we failed to make our window -- try to restart */
@ -494,6 +504,12 @@ void pcm_params_free(struct pcm_params *pcm_params)
static int pcm_param_to_alsa(enum pcm_param param)
{
switch (param) {
case PCM_PARAM_ACCESS:
return SNDRV_PCM_HW_PARAM_ACCESS;
case PCM_PARAM_FORMAT:
return SNDRV_PCM_HW_PARAM_FORMAT;
case PCM_PARAM_SUBFORMAT:
return SNDRV_PCM_HW_PARAM_SUBFORMAT;
case PCM_PARAM_SAMPLE_BITS:
return SNDRV_PCM_HW_PARAM_SAMPLE_BITS;
break;
@ -536,6 +552,23 @@ static int pcm_param_to_alsa(enum pcm_param param)
}
}
struct pcm_mask *pcm_params_get_mask(struct pcm_params *pcm_params,
enum pcm_param param)
{
int p;
struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
if (params == NULL) {
return NULL;
}
p = pcm_param_to_alsa(param);
if (p < 0 || !param_is_mask(p)) {
return NULL;
}
return (struct pcm_mask *)param_to_mask(params, p);
}
unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
enum pcm_param param)
{
@ -582,6 +615,7 @@ int pcm_close(struct pcm *pcm)
if (pcm->fd >= 0)
close(pcm->fd);
pcm->prepared = 0;
pcm->running = 0;
pcm->buffer_size = 0;
pcm->fd = -1;
@ -706,7 +740,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
pcm->boundary = sparams.boundary = pcm->buffer_size;
while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size)
pcm->boundary *= 2;
pcm->boundary *= 2;
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) {
oops(pcm, errno, "cannot set sw params");
@ -719,6 +753,17 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
goto fail;
}
#ifdef SNDRV_PCM_IOCTL_TTSTAMP
if (pcm->flags & PCM_MONOTONIC) {
int arg = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
rc = ioctl(pcm->fd, SNDRV_PCM_IOCTL_TTSTAMP, &arg);
if (rc < 0) {
oops(pcm, rc, "cannot set timestamp type");
goto fail;
}
}
#endif
pcm->underruns = 0;
return pcm;
@ -736,13 +781,26 @@ int pcm_is_ready(struct pcm *pcm)
return pcm->fd >= 0;
}
int pcm_start(struct pcm *pcm)
int pcm_prepare(struct pcm *pcm)
{
if (pcm->prepared)
return 0;
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE) < 0)
return oops(pcm, errno, "cannot prepare channel");
pcm->prepared = 1;
return 0;
}
int pcm_start(struct pcm *pcm)
{
int prepare_error = pcm_prepare(pcm);
if (prepare_error)
return prepare_error;
if (pcm->flags & PCM_MMAP)
pcm_sync_ptr(pcm, 0);
pcm_sync_ptr(pcm, 0);
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START) < 0)
return oops(pcm, errno, "cannot start channel");
@ -756,6 +814,7 @@ int pcm_stop(struct pcm *pcm)
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0)
return oops(pcm, errno, "cannot stop channel");
pcm->prepared = 0;
pcm->running = 0;
return 0;
}
@ -831,7 +890,7 @@ int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames)
{
(void)offset;
(void) offset;
/* update the application pointer in userspace and kernel */
pcm_mmap_appl_forward(pcm, frames);
pcm_sync_ptr(pcm, 0);
@ -895,7 +954,7 @@ int pcm_wait(struct pcm *pcm, int timeout)
return 1;
}
int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int bytes)
{
int err = 0, frames, avail;
unsigned int offset = 0, count;
@ -915,7 +974,7 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
}
/* start the audio if we reach the threshold */
if (!pcm->running &&
if (!pcm->running &&
(pcm->buffer_size - avail) >= pcm->config.start_threshold) {
if (pcm_start(pcm) < 0) {
fprintf(stderr, "start error: hw 0x%x app 0x%x avail 0x%x\n",
@ -937,6 +996,7 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
err = pcm_wait(pcm, time);
if (err < 0) {
pcm->prepared = 0;
pcm->running = 0;
fprintf(stderr, "wait error: hw 0x%x app 0x%x avail 0x%x\n",
(unsigned int)pcm->mmap_status->hw_ptr,
@ -956,7 +1016,7 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
break;
/* copy frames from buffer */
frames = pcm_mmap_write_areas(pcm, buffer, offset, frames);
frames = pcm_mmap_transfer_areas(pcm, (void *)buffer, offset, frames);
if (frames < 0) {
fprintf(stderr, "write error: hw 0x%x app 0x%x avail 0x%x\n",
(unsigned int)pcm->mmap_status->hw_ptr,
@ -971,3 +1031,19 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
return 0;
}
int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count)
{
if ((~pcm->flags) & (PCM_OUT | PCM_MMAP))
return -ENOSYS;
return pcm_mmap_transfer(pcm, (void *)data, count);
}
int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count)
{
if ((~pcm->flags) & (PCM_IN | PCM_MMAP))
return -ENOSYS;
return pcm_mmap_transfer(pcm, data, count);
}

View File

@ -0,0 +1,92 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <stdlib.h>
#include "config.h"
#include "debug.h"
#include "debug-ibasso.h"
#include "usb-ibasso.h"
static void usb_enable_adb(void)
{
TRACE;
if(system(NULL))
{
system("setprop persist.sys.usb.config adb");
system("setprop persist.usb.debug 1");
return;
}
DEBUGF("ERROR %s: No command processor available.", __func__);
}
static void usb_enable_mass_storage(void)
{
TRACE;
if(system(NULL))
{
system("setprop persist.sys.usb.config mass_storage");
system("setprop persist.usb.debug 0");
return;
}
DEBUGF("ERROR %s: No command processor available.", __func__);
}
/* Default at boot not known. */
static int _last_usb_mode = -1;
void ibasso_set_usb_mode(int mode)
{
DEBUGF("DEBUG %s: _last_usb_mode: %d, mode: %d.", __func__, _last_usb_mode, mode);
if(_last_usb_mode != mode)
{
switch(mode)
{
case USB_MODE_MASS_STORAGE:
{
_last_usb_mode = mode;
usb_enable_mass_storage();
break;
}
case USB_MODE_CHARGE: /* Work around. */
case USB_MODE_ADB:
{
_last_usb_mode = mode;
usb_enable_adb();
break;
}
}
}
}

View File

@ -0,0 +1,54 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 _USB_DX50_H_
#define _USB_DX50_H_
/* Supported usb modes. */
enum ibasso_usb_mode
{
/*
USB mass storage mode. On USB connection, Rockbox will terminate and the internel and
external storage gets exported to the connected client.
*/
USB_MODE_MASS_STORAGE = 0,
/*
Actually the same, since we to not have proper USB detection.
Starts the adb server and enables adb connection over USB. Rockbox will continue to run.
*/
USB_MODE_CHARGE,
USB_MODE_ADB
};
/*
Set the usb mode.
mode: ibasso_usb_mode
*/
void ibasso_set_usb_mode(int mode);
#endif

View File

@ -0,0 +1,203 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 <pthread.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include "config.h"
#include "debug.h"
#include "powermgmt.h"
#include "debug-ibasso.h"
/*
Without this socket iBasso Vold will not start.
iBasso Vold uses this to send status messages about storage devices.
*/
static const char VOLD_MONITOR_SOCKET_NAME[] = "UNIX_domain";
static int _vold_monitor_socket_fd = -1;
static void vold_monitor_open_socket(void)
{
TRACE;
unlink(VOLD_MONITOR_SOCKET_NAME);
_vold_monitor_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(_vold_monitor_socket_fd < 0)
{
_vold_monitor_socket_fd = -1;
return;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, VOLD_MONITOR_SOCKET_NAME, sizeof(addr.sun_path) -1);
if(bind(_vold_monitor_socket_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
{
close(_vold_monitor_socket_fd);
unlink(VOLD_MONITOR_SOCKET_NAME);
_vold_monitor_socket_fd = -1;
return;
}
if(listen(_vold_monitor_socket_fd, 1) < 0)
{
close(_vold_monitor_socket_fd);
unlink(VOLD_MONITOR_SOCKET_NAME);
_vold_monitor_socket_fd = -1;
return;
}
}
/*
bionic does not have pthread_cancel.
0: Vold monitor thread stopped/ending.
1: Vold monitor thread started/running.
*/
static volatile sig_atomic_t _vold_monitor_active = 0;
/*
1: /mnt/sdcard is unmounting
0: else
*/
static volatile sig_atomic_t _vold_monitor_forced_close_imminent = 0;
static void* vold_monitor_run(void* nothing)
{
_vold_monitor_active = 1;
(void) nothing;
DEBUGF("DEBUG %s: Thread start.", __func__);
vold_monitor_open_socket();
if(_vold_monitor_socket_fd < 0)
{
DEBUGF("ERROR %s: Thread end: No socket.", __func__);
_vold_monitor_active = 0;
return 0;
}
struct pollfd fds[1];
fds[0].fd = _vold_monitor_socket_fd;
fds[0].events = POLLIN;
while(_vold_monitor_active == 1)
{
poll(fds, 1, 10);
if(! (fds[0].revents & POLLIN))
{
continue;
}
int socket_fd = accept(_vold_monitor_socket_fd, NULL, NULL);
if(socket_fd < 0)
{
DEBUGF("ERROR %s: accept failed.", __func__);
continue;
}
while(true)
{
char msg[1024];
memset(msg, 0, sizeof(msg));
int length = read(socket_fd, msg, sizeof(msg));
if(length <= 0)
{
close(socket_fd);
break;
}
DEBUGF("%s: msg: %s", __func__, msg);
if(strcmp(msg, "Volume flash /mnt/sdcard state changed from 4 (Mounted) to 5 (Unmounting)") == 0)
{
/* We are losing /mnt/sdcard, shutdown Rockbox before it is forced closed. */
_vold_monitor_forced_close_imminent = 1;
sys_poweroff();
_vold_monitor_active = 0;
}
else if(strcmp(msg, "Volume sdcard /mnt/external_sd state changed from 4 (Mounted) to 5 (Unmounting)") == 0)
{
/* We are loosing the external sdcard, inform Rockbox. */
}
else if(strcmp(msg, "Volume sdcard /mnt/external_sd state changed from 3 (Checking) to 4 (Mounted)") == 0)
{
/* The external sdcard is back, inform Rockbox. */
}
}
}
close(_vold_monitor_socket_fd);
unlink(VOLD_MONITOR_SOCKET_NAME);
_vold_monitor_socket_fd = -1;
DEBUGF("%s: Thread end.", __func__);
_vold_monitor_active = 0;
return 0;
}
/* Vold monitor thread. */
static pthread_t _vold_monitor_thread;
void vold_monitor_start(void)
{
TRACE;
if(_vold_monitor_active == 0)
{
pthread_create(&_vold_monitor_thread, NULL, vold_monitor_run, NULL);
}
}
bool vold_monitor_forced_close_imminent(void)
{
TRACE;
return(_vold_monitor_forced_close_imminent == 1);
}

View File

@ -0,0 +1,42 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* 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 __VOLD_IBASSO_H__
#define __VOLD_IBASSO_H__
/* Start the vold monitor thread. */
void vold_monitor_start(void);
/*
Used to change Rockbox shutdown from reboot/power off to program exit.
true: vold monitor has detected, that vold is remounting /mnt/sdcard for USB mass storage
access.
false: else.
*/
bool vold_monitor_forced_close_imminent(void);
#endif

View File

@ -185,7 +185,7 @@ static bool compressor_update(struct dsp_config *dsp,
auto_gain ? "Auto" : "Off");
}
if (settings->ratio != cur_set.ratio)
if (settings->ratio != curr_set.ratio)
{
if (ratio)
{ logf(" Compressor Ratio: %d:1", ratio); }
@ -193,16 +193,16 @@ static bool compressor_update(struct dsp_config *dsp,
{ logf(" Compressor Ratio: Limit"); }
}
if (settings->knee != cur_set.knee)
if (settings->knee != curr_set.knee)
{
logf(" Compressor Knee: %s", soft_knee?"Soft":"Hard");
}
if (settings->release_time != cur_set.release_time)
if (settings->release_time != curr_set.release_time)
{
logf(" Compressor Release: %d", release);
}
if (settings->attack_time != cur_set.attack_time)
if (settings->attack_time != curr_set.attack_time)
{
logf(" Compressor Attack: %d", attack);
}
@ -357,7 +357,7 @@ static bool compressor_update(struct dsp_config *dsp,
for (int i = 1; i <= 65; i++)
{
DEBUGF("%02d: %.6f ", i, (float)comp_curve[i] / UNITY);
if (i % 4 == 0) DEBUGF("\n");
if (i % 4 == 0) { DEBUGF("\n"); }
}
DEBUGF("\n");

83
tools/configure vendored
View File

@ -726,6 +726,58 @@ androidcc () {
prefixtools $gcctarget
}
androidndkcc()
{
if ! [ -d "$ANDROID_NDK_PATH" ]; then
echo "ERROR: You need the Android NDK installed (r16 or higher) and have the ANDROID_NDK_PATH"
echo "environment variable point to the root directory of the Android NDK."
exit
fi
make_toolchain="${ANDROID_NDK_PATH}/build/tools/make-standalone-toolchain.sh"
if ! [ -e "${make_toolchain}" ]; then
echo "ERROR: ${make_toolchain} could not be found."
exit
fi
buildhost=$(uname -s | tr "[:upper:]" "[:lower:]")
buildhost="${buildhost}-$(uname -m)"
GCCOPTS=`echo $CCOPTS | sed -e s/-ffreestanding// -e s/-nostdlib// -e s/-Wundef//`
LDOPTS="$LDOPTS -ldl -llog"
SHARED_LDFLAG="-shared"
SHARED_CFLAGS=''
GLOBAL_LDOPTS="-Wl,-z,defs -Wl,-z,noexecstack"
# arch dependant stuff
case $1 in
armeabi)
endian="little"
gccchoice="4.6"
gcctarget="arm-linux-androideabi-"
echo "${make_toolchain} --system=${buildhost} --toolchain=arm-linux-androideabi-4.6 --platform=android-16 --install-dir=${pwd}/android-toolchain"
${make_toolchain} --system=${buildhost} --toolchain=arm-linux-androideabi-4.6 --platform=android-16 --install-dir=${pwd}/android-toolchain
if [ ${?} != 0 ]; then
exit
fi
GCCOPTS="$GCCOPTS -march=armv5te -mtune=xscale -msoft-float -fomit-frame-pointer --sysroot=${pwd}/android-toolchain/sysroot"
LDOPTS="$LDOPTS --sysroot=${pwd}/android-toolchain/sysroot"
;;
*)
echo "ERROR: androidndkcc(): Unknown target architecture"
exit
;;
esac
echo "Using endian ${endian}"
echo "Using gccchoice ${gccchoice}"
echo "Using gcctarget ${gcctarget}"
PATH=$PATH:${pwd}/android-toolchain/bin
prefixtools $gcctarget
}
whichadvanced () {
atype=`echo "$1" | cut -c 2-`
##################################################################
@ -3751,26 +3803,24 @@ fi
target_id=94
modelname="ibassodx50"
target="DX50"
app_type="android_standalone"
app_type="android_ndk"
lcd_orientation="landscape"
sharedir="/system/rockbox/app_rockbox/rockbox"
bindir="/system/rockbox/lib"
libdir="/system/rockbox/app_rockbox"
memory=32
# Actually 408260kB
memory=256
uname=`uname`
androidcc armeabi
androidndkcc armeabi
tool="cp "
boottool="cp "
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
output="rockbox"
bootoutput="rockbox"
appextra="recorder:gui:radio:hosted/android"
appextra="recorder:gui:hosted"
plugins="yes"
swcodec="yes"
# architecture, manufacturer and model for the target-tree build
t_cpu="hosted"
t_manufacturer="android"
t_manufacturer="ibasso"
t_model="dx50"
;;
@ -3779,27 +3829,24 @@ fi
target_id=95
modelname="ibassodx90"
target="DX90"
app_type="android_standalone"
app_type="android_ndk"
lcd_orientation="landscape"
sharedir="/system/rockbox/app_rockbox/rockbox"
bindir="/system/rockbox/lib"
libdir="/system/rockbox/app_rockbox"
memory=32
memory=256
uname=`uname`
androidcc armeabi
androidndkcc armeabi
tool="cp "
boottool="cp "
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
output="rockbox"
bootoutput="rockbox"
appextra="recorder:gui:radio:hosted/android"
appextra="recorder:gui:hosted"
plugins="yes"
swcodec="yes"
# architecture, manufacturer and model for the target-tree build
t_cpu="hosted"
t_manufacturer="android"
t_model="dx50"
t_manufacturer="ibasso"
t_model="dx90"
;;
*)
@ -4333,6 +4380,8 @@ if test -n "$t_cpu"; then
elif [ "$simulator" = "yes" ]; then # a few more includes for the sim target tree
TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/hosted/sdl"
TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/hosted"
elif [ "$t_manufacturer" = "ibasso" ]; then
TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/hosted/ibasso/tinyalsa/include"
fi
TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/$t_cpu/$t_manufacturer"

View File

@ -132,8 +132,12 @@ else # core
include $(ROOTDIR)/firmware/target/hosted/samsungypr/ypr1/ypr1.make
endif
ifneq (,$(findstring android, $(APP_TYPE)))
include $(ROOTDIR)/android/android.make
ifneq (,$(findstring android_ndk, $(APP_TYPE)))
include $(ROOTDIR)/firmware/target/hosted/ibasso/android_ndk.make
else
ifneq (,$(findstring android, $(APP_TYPE)))
include $(ROOTDIR)/android/android.make
endif
endif
ifneq (,$(findstring pandora, $(MODELNAME)))