From 180cef835bf40d0081895773aaa637ac926bb0ac Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Mon, 5 Nov 2018 13:01:55 +0100 Subject: xDuoo X3II and X20 port Provided by Roman Stolyarov Integration, Refactoring, and Upstreaming by Solomon Peachy X3II confirmed working by forum tester, X20 is nearly identical. This includes bootloader, main firmware, and the flash image patcher. Eventual Todo: * Further refactor AGPTek Rocker & xduoo hiby bootloaders * Further refactor AGPTek Rocker & xduoo hosted platform code Change-Id: I34a674051d368efcc75d1d18c725971fe46c3eee --- firmware/target/hosted/agptek/backlight-agptek.c | 64 ------- firmware/target/hosted/agptek/backlight-target.h | 36 ---- firmware/target/hosted/agptek/sysfs.c | 200 ---------------------- firmware/target/hosted/agptek/sysfs.h | 31 ---- firmware/target/hosted/agptek/system-agptek.c | 184 --------------------- firmware/target/hosted/backlight-target.h | 36 ++++ firmware/target/hosted/backlight-unix.c | 64 +++++++ firmware/target/hosted/filesystem-app.c | 6 +- firmware/target/hosted/rtc.c | 2 +- firmware/target/hosted/sdl/sim-ui-defines.h | 16 +- firmware/target/hosted/sysfs.c | 200 ++++++++++++++++++++++ firmware/target/hosted/sysfs.h | 31 ++++ firmware/target/hosted/system-hosted.c | 184 +++++++++++++++++++++ firmware/target/hosted/xduoo/adc-target.h | 0 firmware/target/hosted/xduoo/button-target.h | 46 ++++++ firmware/target/hosted/xduoo/button-xduoo.c | 202 +++++++++++++++++++++++ firmware/target/hosted/xduoo/debug-xduoo.c | 6 + firmware/target/hosted/xduoo/lcd-target.h | 32 ++++ firmware/target/hosted/xduoo/lcd-xduoo.c | 140 ++++++++++++++++ firmware/target/hosted/xduoo/power-xduoo.c | 74 +++++++++ firmware/target/hosted/xduoo/power-xduoo.h | 31 ++++ firmware/target/hosted/xduoo/powermgmt-xduoo.c | 70 ++++++++ firmware/target/hosted/xduoo/system-target.h | 28 ++++ firmware/target/hosted/xduoo/usb-xduoo.c | 118 +++++++++++++ firmware/target/hosted/xduoo/xduoo.make | 52 ++++++ 25 files changed, 1333 insertions(+), 520 deletions(-) delete mode 100644 firmware/target/hosted/agptek/backlight-agptek.c delete mode 100644 firmware/target/hosted/agptek/backlight-target.h delete mode 100644 firmware/target/hosted/agptek/sysfs.c delete mode 100644 firmware/target/hosted/agptek/sysfs.h delete mode 100644 firmware/target/hosted/agptek/system-agptek.c create mode 100644 firmware/target/hosted/backlight-target.h create mode 100644 firmware/target/hosted/backlight-unix.c create mode 100644 firmware/target/hosted/sysfs.c create mode 100644 firmware/target/hosted/sysfs.h create mode 100644 firmware/target/hosted/system-hosted.c create mode 100644 firmware/target/hosted/xduoo/adc-target.h create mode 100644 firmware/target/hosted/xduoo/button-target.h create mode 100644 firmware/target/hosted/xduoo/button-xduoo.c create mode 100644 firmware/target/hosted/xduoo/debug-xduoo.c create mode 100644 firmware/target/hosted/xduoo/lcd-target.h create mode 100644 firmware/target/hosted/xduoo/lcd-xduoo.c create mode 100644 firmware/target/hosted/xduoo/power-xduoo.c create mode 100644 firmware/target/hosted/xduoo/power-xduoo.h create mode 100644 firmware/target/hosted/xduoo/powermgmt-xduoo.c create mode 100644 firmware/target/hosted/xduoo/system-target.h create mode 100644 firmware/target/hosted/xduoo/usb-xduoo.c create mode 100644 firmware/target/hosted/xduoo/xduoo.make (limited to 'firmware/target/hosted') diff --git a/firmware/target/hosted/agptek/backlight-agptek.c b/firmware/target/hosted/agptek/backlight-agptek.c deleted file mode 100644 index 2f00787f72..0000000000 --- a/firmware/target/hosted/agptek/backlight-agptek.c +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** - * __________ __ ___ - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2017 Marcin Bukat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "backlight-target.h" -#include "sysfs.h" -#include "panic.h" - -static const char * const sysfs_bl_brightness = - "/sys/class/backlight/pwm-backlight.0/brightness"; - -static const char * const sysfs_bl_power = - "/sys/class/backlight/pwm-backlight.0/bl_power"; - -bool backlight_hw_init(void) -{ - backlight_hw_on(); - backlight_hw_brightness(DEFAULT_BRIGHTNESS_SETTING); - return true; -} - -void backlight_hw_on(void) -{ - sysfs_set_int(sysfs_bl_power, 0); -} - -void backlight_hw_off(void) -{ - sysfs_set_int(sysfs_bl_power, 1); -} - -void backlight_hw_brightness(int brightness) -{ - /* cap range, just in case */ - if (brightness > MAX_BRIGHTNESS_SETTING) - brightness = MAX_BRIGHTNESS_SETTING; - if (brightness < MIN_BRIGHTNESS_SETTING) - brightness = MIN_BRIGHTNESS_SETTING; - - sysfs_set_int(sysfs_bl_brightness, brightness); -} diff --git a/firmware/target/hosted/agptek/backlight-target.h b/firmware/target/hosted/agptek/backlight-target.h deleted file mode 100644 index e3b8a7bd78..0000000000 --- a/firmware/target/hosted/agptek/backlight-target.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************** - * __________ __ ___ - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2017 Marcin Bukat - * - * 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 _BACKLIGHT_TARGET_H_ -#define _BACKLIGHT_TARGET_H_ - - -#include - - -/* 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 - diff --git a/firmware/target/hosted/agptek/sysfs.c b/firmware/target/hosted/agptek/sysfs.c deleted file mode 100644 index 177f338911..0000000000 --- a/firmware/target/hosted/agptek/sysfs.c +++ /dev/null @@ -1,200 +0,0 @@ -/*************************************************************************** - * __________ __ ___ - * 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 -#include - -#include "config.h" -#include "debug.h" -#include "sysfs.h" - - -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(const char *path, int *value) -{ - *value = -1; - - FILE *f = open_read(path); - if(f == NULL) - { - return false; - } - - bool success = true; - if(fscanf(f, "%d", value) == EOF) - { - DEBUGF("ERROR %s: Read failed for %s.", __func__, path); - success = false; - } - - fclose(f); - return success; -} - - -bool sysfs_set_int(const char *path, int value) -{ - FILE *f = open_write(path); - if(f == NULL) - { - return false; - } - - bool success = true; - if(fprintf(f, "%d", value) < 0) - { - DEBUGF("ERROR %s: Write failed for %s.", __func__, path); - success = false; - } - - fclose(f); - return success; -} - - -bool sysfs_get_char(const char *path, char *value) -{ - int c; - FILE *f = open_read(path); - if(f == NULL) - { - return false; - } - - bool success = true; - c = fgetc(f); - - if(c == EOF) - { - DEBUGF("ERROR %s: Read failed for %s.", __func__, path); - success = false; - } - else - { - *value = c; - } - - fclose(f); - return success; -} - - -bool sysfs_set_char(const char *path, char value) -{ - FILE *f = open_write(path); - if(f == NULL) - { - return false; - } - - bool success = true; - if(fprintf(f, "%c", value) < 1) - { - DEBUGF("ERROR %s: Write failed for %s.", __func__, path); - success = false; - } - - fclose(f); - return success; -} - - -bool sysfs_get_string(const char *path, char *value, int size) -{ - value[0] = '\0'; - FILE *f = open_read(path); - if(f == NULL) - { - return false; - } - - bool success = true; - - /* fgets returns NULL if en error occured OR - * when EOF occurs while no characters have been read. - * - * Empty string is not an error for us. - */ - if(fgets(value, size, f) == NULL && value[0] != '\0') - { - DEBUGF("ERROR %s: Read failed for %s.", __func__, path); - 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(const char *path, char *value) -{ - FILE *f = open_write(path); - if(f == NULL) - { - return false; - } - - bool success = true; - - /* If an output error is encountered, a negative value is returned */ - if(fprintf(f, "%s", value) < 0) - { - DEBUGF("ERROR %s: Write failed for %s.", __func__, path); - success = false; - } - - fclose(f); - return success; -} diff --git a/firmware/target/hosted/agptek/sysfs.h b/firmware/target/hosted/agptek/sysfs.h deleted file mode 100644 index 639cc1c409..0000000000 --- a/firmware/target/hosted/agptek/sysfs.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * __________ __ ___ - * 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 - -bool sysfs_get_int(const char *path, int *value); -bool sysfs_set_int(const char *path, int value); -bool sysfs_get_char(const char *path, char *value); -bool sysfs_set_char(const char *path, char value); -bool sysfs_get_string(const char *path, char *value, int size); -bool sysfs_set_string(const char *path, char *value); diff --git a/firmware/target/hosted/agptek/system-agptek.c b/firmware/target/hosted/agptek/system-agptek.c deleted file mode 100644 index 7f0949daf2..0000000000 --- a/firmware/target/hosted/agptek/system-agptek.c +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2017 Marcin Bukat - * Copyright (C) 2016 Amaury Pouly - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include -#include -#include -#include -#include - -#include "system.h" -#include "mv.h" -#include "font.h" -#include "power.h" -#include "button.h" -#include "backlight-target.h" -#include "lcd.h" - -/* to make thread-internal.h happy */ -uintptr_t *stackbegin; -uintptr_t *stackend; - -static void sig_handler(int sig, siginfo_t *siginfo, void *context) -{ - /* safe guard variable - we call backtrace() only on first - * UIE call. This prevent endless loop if backtrace() touches - * memory regions which cause abort - */ - static bool triggered = false; - - lcd_set_backdrop(NULL); - lcd_set_drawmode(DRMODE_SOLID); - lcd_set_foreground(LCD_BLACK); - lcd_set_background(LCD_WHITE); - unsigned line = 0; - - lcd_setfont(FONT_SYSFIXED); - lcd_set_viewport(NULL); - lcd_clear_display(); - - /* get context info */ - ucontext_t *uc = (ucontext_t *)context; - unsigned long pc = uc->uc_mcontext.pc; - unsigned long sp = uc->uc_mcontext.gregs[29]; - - lcd_putsf(0, line++, "%s at %08x", strsignal(sig), pc); - - if(sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGTRAP) - lcd_putsf(0, line++, "address 0x%08x", siginfo->si_addr); - - if(!triggered) - { - triggered = true; - rb_backtrace(pc, sp, &line); - } - -#ifdef ROCKBOX_HAS_LOGF - lcd_putsf(0, line++, "logf:"); - logf_panic_dump(&line); -#endif - - lcd_update(); - - system_exception_wait(); /* If this returns, try to reboot */ - system_reboot(); - while (1); /* halt */ -} - -void power_off(void) -{ - system("/sbin/poweroff"); -} - -void system_init(void) -{ - int *s; - /* fake stack, to make thread-internal.h happy */ - stackbegin = stackend = (uintptr_t*)&s; - /* catch some signals for easier debugging */ - struct sigaction sa; - sigfillset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = &sig_handler; - sigaction(SIGILL, &sa, NULL); - sigaction(SIGABRT, &sa, NULL); - sigaction(SIGFPE, &sa, NULL); - sigaction(SIGSEGV, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGBUS, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); -} - -void system_reboot(void) -{ - system("/sbin/reboot"); -} - -void system_exception_wait(void) -{ - backlight_hw_on(); - backlight_hw_brightness(DEFAULT_BRIGHTNESS_SETTING); - /* wait until button press and release */ - while(button_read_device() != 0) {} - while(button_read_device() == 0) {} - while(button_read_device() != 0) {} - while(button_read_device() == 0) {} -} - -bool hostfs_removable(IF_MD_NONVOID(int drive)) -{ -#ifdef HAVE_MULTIDRIVE - if (drive > 0) /* Active LOW */ - return true; - else -#endif - return false; /* internal: always present */ -} - -bool hostfs_present(IF_MD_NONVOID(int drive)) -{ -#ifdef HAVE_MULTIDRIVE - if (drive > 0) /* Active LOW */ - return true; //FIXME - else -#endif - return true; /* internal: always present */ -} - -#ifdef HAVE_MULTIDRIVE -int volume_drive(int drive) -{ - return drive; -} -#endif /* HAVE_MULTIDRIVE */ - -#ifdef CONFIG_STORAGE_MULTI -int hostfs_driver_type(int drive) -{ - return drive > 0 ? STORAGE_SD_NUM : STORAGE_HOSTFS_NUM; -} -#endif /* CONFIG_STORAGE_MULTI */ - -int hostfs_init(void) -{ - return 0; -} - -int hostfs_flush(void) -{ - sync(); - return 0; -} - -#ifdef HAVE_HOTSWAP -bool volume_removable(int volume) -{ - /* don't support more than one partition yet, so volume == drive */ - return hostfs_removable(volume); -} - -bool volume_present(int volume) -{ - /* don't support more than one partition yet, so volume == drive */ - return hostfs_present(volume); -} -#endif - diff --git a/firmware/target/hosted/backlight-target.h b/firmware/target/hosted/backlight-target.h new file mode 100644 index 0000000000..e3b8a7bd78 --- /dev/null +++ b/firmware/target/hosted/backlight-target.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * __________ __ ___ + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 Marcin Bukat + * + * 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 _BACKLIGHT_TARGET_H_ +#define _BACKLIGHT_TARGET_H_ + + +#include + + +/* 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 + diff --git a/firmware/target/hosted/backlight-unix.c b/firmware/target/hosted/backlight-unix.c new file mode 100644 index 0000000000..2f00787f72 --- /dev/null +++ b/firmware/target/hosted/backlight-unix.c @@ -0,0 +1,64 @@ +/*************************************************************************** + * __________ __ ___ + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 Marcin Bukat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "backlight-target.h" +#include "sysfs.h" +#include "panic.h" + +static const char * const sysfs_bl_brightness = + "/sys/class/backlight/pwm-backlight.0/brightness"; + +static const char * const sysfs_bl_power = + "/sys/class/backlight/pwm-backlight.0/bl_power"; + +bool backlight_hw_init(void) +{ + backlight_hw_on(); + backlight_hw_brightness(DEFAULT_BRIGHTNESS_SETTING); + return true; +} + +void backlight_hw_on(void) +{ + sysfs_set_int(sysfs_bl_power, 0); +} + +void backlight_hw_off(void) +{ + sysfs_set_int(sysfs_bl_power, 1); +} + +void backlight_hw_brightness(int brightness) +{ + /* cap range, just in case */ + if (brightness > MAX_BRIGHTNESS_SETTING) + brightness = MAX_BRIGHTNESS_SETTING; + if (brightness < MIN_BRIGHTNESS_SETTING) + brightness = MIN_BRIGHTNESS_SETTING; + + sysfs_set_int(sysfs_bl_brightness, brightness); +} diff --git a/firmware/target/hosted/filesystem-app.c b/firmware/target/hosted/filesystem-app.c index d9fcd64e2d..b49412ea48 100644 --- a/firmware/target/hosted/filesystem-app.c +++ b/firmware/target/hosted/filesystem-app.c @@ -36,8 +36,7 @@ #include "rbpaths.h" #include "logf.h" - -#if defined(AGPTEK_ROCKER) && !defined(BOOTLOADER) +#if (defined(AGPTEK_ROCKER) || defined(XDUOO_X3II) || defined(XDUOO_X20)) && !defined(BOOTLOADER) #define PIVOT_ROOT "/mnt/sd_0" #endif @@ -52,7 +51,8 @@ static const char rbhome[] = HOME_DIR; #endif #if !(defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) || defined(DX50) || \ - defined(SONY_NWZ_LINUX) || defined(DX90) || defined(AGPTEK_ROCKER)) && \ + defined(SONY_NWZ_LINUX) || defined(DX90) || defined(AGPTEK_ROCKER) || \ + defined(XDUOO_X3II) || defined(XDUOO_X20)) && \ !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 diff --git a/firmware/target/hosted/rtc.c b/firmware/target/hosted/rtc.c index 178e797a8d..488531c77c 100644 --- a/firmware/target/hosted/rtc.c +++ b/firmware/target/hosted/rtc.c @@ -42,7 +42,7 @@ int rtc_read_datetime(struct tm *tm) int rtc_write_datetime(const struct tm *tm) { -#if defined(AGPTEK_ROCKER) && !defined(WIN32) +#if !defined(WIN32) struct timeval tv; struct tm *tm_time; diff --git a/firmware/target/hosted/sdl/sim-ui-defines.h b/firmware/target/hosted/sdl/sim-ui-defines.h index 99ae062595..1e96383682 100644 --- a/firmware/target/hosted/sdl/sim-ui-defines.h +++ b/firmware/target/hosted/sdl/sim-ui-defines.h @@ -521,6 +521,7 @@ #define UI_HEIGHT 380 #define UI_LCD_POSX 29 #define UI_LCD_POSY 25 + #elif defined(XDUOO_X3) #define UI_TITLE "xDuoo X3" #define UI_WIDTH 192 /* width of GUI window */ @@ -528,6 +529,20 @@ #define UI_LCD_POSX 34 #define UI_LCD_POSY 73 +#elif defined(XDUOO_X3II) +#define UI_TITLE "xDuoo X3ii" +#define UI_WIDTH 322 /* width of GUI window */ +#define UI_HEIGHT 609 /* height of GUI window */ +#define UI_LCD_POSX 43 +#define UI_LCD_POSY 62 + +#elif defined(XDUOO_X20) +#define UI_TITLE "xDuoo X20" +#define UI_WIDTH 322 /* width of GUI window */ +#define UI_HEIGHT 609 /* height of GUI window */ +#define UI_LCD_POSX 43 +#define UI_LCD_POSY 62 + #elif defined(IHIFI770) #define UI_TITLE "iHiFi 770" #define UI_WIDTH 382 /* width of GUI window */ @@ -554,4 +569,3 @@ #endif #endif /* #ifndef __UISDL_H__ */ - diff --git a/firmware/target/hosted/sysfs.c b/firmware/target/hosted/sysfs.c new file mode 100644 index 0000000000..177f338911 --- /dev/null +++ b/firmware/target/hosted/sysfs.c @@ -0,0 +1,200 @@ +/*************************************************************************** + * __________ __ ___ + * 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 +#include + +#include "config.h" +#include "debug.h" +#include "sysfs.h" + + +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(const char *path, int *value) +{ + *value = -1; + + FILE *f = open_read(path); + if(f == NULL) + { + return false; + } + + bool success = true; + if(fscanf(f, "%d", value) == EOF) + { + DEBUGF("ERROR %s: Read failed for %s.", __func__, path); + success = false; + } + + fclose(f); + return success; +} + + +bool sysfs_set_int(const char *path, int value) +{ + FILE *f = open_write(path); + if(f == NULL) + { + return false; + } + + bool success = true; + if(fprintf(f, "%d", value) < 0) + { + DEBUGF("ERROR %s: Write failed for %s.", __func__, path); + success = false; + } + + fclose(f); + return success; +} + + +bool sysfs_get_char(const char *path, char *value) +{ + int c; + FILE *f = open_read(path); + if(f == NULL) + { + return false; + } + + bool success = true; + c = fgetc(f); + + if(c == EOF) + { + DEBUGF("ERROR %s: Read failed for %s.", __func__, path); + success = false; + } + else + { + *value = c; + } + + fclose(f); + return success; +} + + +bool sysfs_set_char(const char *path, char value) +{ + FILE *f = open_write(path); + if(f == NULL) + { + return false; + } + + bool success = true; + if(fprintf(f, "%c", value) < 1) + { + DEBUGF("ERROR %s: Write failed for %s.", __func__, path); + success = false; + } + + fclose(f); + return success; +} + + +bool sysfs_get_string(const char *path, char *value, int size) +{ + value[0] = '\0'; + FILE *f = open_read(path); + if(f == NULL) + { + return false; + } + + bool success = true; + + /* fgets returns NULL if en error occured OR + * when EOF occurs while no characters have been read. + * + * Empty string is not an error for us. + */ + if(fgets(value, size, f) == NULL && value[0] != '\0') + { + DEBUGF("ERROR %s: Read failed for %s.", __func__, path); + 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(const char *path, char *value) +{ + FILE *f = open_write(path); + if(f == NULL) + { + return false; + } + + bool success = true; + + /* If an output error is encountered, a negative value is returned */ + if(fprintf(f, "%s", value) < 0) + { + DEBUGF("ERROR %s: Write failed for %s.", __func__, path); + success = false; + } + + fclose(f); + return success; +} diff --git a/firmware/target/hosted/sysfs.h b/firmware/target/hosted/sysfs.h new file mode 100644 index 0000000000..639cc1c409 --- /dev/null +++ b/firmware/target/hosted/sysfs.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * __________ __ ___ + * 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 + +bool sysfs_get_int(const char *path, int *value); +bool sysfs_set_int(const char *path, int value); +bool sysfs_get_char(const char *path, char *value); +bool sysfs_set_char(const char *path, char value); +bool sysfs_get_string(const char *path, char *value, int size); +bool sysfs_set_string(const char *path, char *value); diff --git a/firmware/target/hosted/system-hosted.c b/firmware/target/hosted/system-hosted.c new file mode 100644 index 0000000000..7f0949daf2 --- /dev/null +++ b/firmware/target/hosted/system-hosted.c @@ -0,0 +1,184 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 Marcin Bukat + * Copyright (C) 2016 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include +#include +#include + +#include "system.h" +#include "mv.h" +#include "font.h" +#include "power.h" +#include "button.h" +#include "backlight-target.h" +#include "lcd.h" + +/* to make thread-internal.h happy */ +uintptr_t *stackbegin; +uintptr_t *stackend; + +static void sig_handler(int sig, siginfo_t *siginfo, void *context) +{ + /* safe guard variable - we call backtrace() only on first + * UIE call. This prevent endless loop if backtrace() touches + * memory regions which cause abort + */ + static bool triggered = false; + + lcd_set_backdrop(NULL); + lcd_set_drawmode(DRMODE_SOLID); + lcd_set_foreground(LCD_BLACK); + lcd_set_background(LCD_WHITE); + unsigned line = 0; + + lcd_setfont(FONT_SYSFIXED); + lcd_set_viewport(NULL); + lcd_clear_display(); + + /* get context info */ + ucontext_t *uc = (ucontext_t *)context; + unsigned long pc = uc->uc_mcontext.pc; + unsigned long sp = uc->uc_mcontext.gregs[29]; + + lcd_putsf(0, line++, "%s at %08x", strsignal(sig), pc); + + if(sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGTRAP) + lcd_putsf(0, line++, "address 0x%08x", siginfo->si_addr); + + if(!triggered) + { + triggered = true; + rb_backtrace(pc, sp, &line); + } + +#ifdef ROCKBOX_HAS_LOGF + lcd_putsf(0, line++, "logf:"); + logf_panic_dump(&line); +#endif + + lcd_update(); + + system_exception_wait(); /* If this returns, try to reboot */ + system_reboot(); + while (1); /* halt */ +} + +void power_off(void) +{ + system("/sbin/poweroff"); +} + +void system_init(void) +{ + int *s; + /* fake stack, to make thread-internal.h happy */ + stackbegin = stackend = (uintptr_t*)&s; + /* catch some signals for easier debugging */ + struct sigaction sa; + sigfillset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = &sig_handler; + sigaction(SIGILL, &sa, NULL); + sigaction(SIGABRT, &sa, NULL); + sigaction(SIGFPE, &sa, NULL); + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGBUS, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); +} + +void system_reboot(void) +{ + system("/sbin/reboot"); +} + +void system_exception_wait(void) +{ + backlight_hw_on(); + backlight_hw_brightness(DEFAULT_BRIGHTNESS_SETTING); + /* wait until button press and release */ + while(button_read_device() != 0) {} + while(button_read_device() == 0) {} + while(button_read_device() != 0) {} + while(button_read_device() == 0) {} +} + +bool hostfs_removable(IF_MD_NONVOID(int drive)) +{ +#ifdef HAVE_MULTIDRIVE + if (drive > 0) /* Active LOW */ + return true; + else +#endif + return false; /* internal: always present */ +} + +bool hostfs_present(IF_MD_NONVOID(int drive)) +{ +#ifdef HAVE_MULTIDRIVE + if (drive > 0) /* Active LOW */ + return true; //FIXME + else +#endif + return true; /* internal: always present */ +} + +#ifdef HAVE_MULTIDRIVE +int volume_drive(int drive) +{ + return drive; +} +#endif /* HAVE_MULTIDRIVE */ + +#ifdef CONFIG_STORAGE_MULTI +int hostfs_driver_type(int drive) +{ + return drive > 0 ? STORAGE_SD_NUM : STORAGE_HOSTFS_NUM; +} +#endif /* CONFIG_STORAGE_MULTI */ + +int hostfs_init(void) +{ + return 0; +} + +int hostfs_flush(void) +{ + sync(); + return 0; +} + +#ifdef HAVE_HOTSWAP +bool volume_removable(int volume) +{ + /* don't support more than one partition yet, so volume == drive */ + return hostfs_removable(volume); +} + +bool volume_present(int volume) +{ + /* don't support more than one partition yet, so volume == drive */ + return hostfs_present(volume); +} +#endif + diff --git a/firmware/target/hosted/xduoo/adc-target.h b/firmware/target/hosted/xduoo/adc-target.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/firmware/target/hosted/xduoo/button-target.h b/firmware/target/hosted/xduoo/button-target.h new file mode 100644 index 0000000000..6cca5c22a0 --- /dev/null +++ b/firmware/target/hosted/xduoo/button-target.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2018 by Roman Stolyarov + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#define HAS_BUTTON_HOLD + +/* Main unit's buttons */ +#define BUTTON_POWER 0x00000001 +#define BUTTON_HOME 0x00000002 +#define BUTTON_OPTION 0x00000004 +#define BUTTON_PREV 0x00000008 +#define BUTTON_NEXT 0x00000010 +#define BUTTON_PLAY 0x00000020 +#define BUTTON_VOL_UP 0x00000040 +#define BUTTON_VOL_DOWN 0x00000080 + +#define BUTTON_LEFT 0 +#define BUTTON_RIGHT 0 + +#define BUTTON_MAIN (BUTTON_POWER | BUTTON_HOME | BUTTON_OPTION | BUTTON_PREV | \ + BUTTON_NEXT | BUTTON_PLAY | BUTTON_VOL_UP | BUTTON_VOL_DOWN) + +/* Software power-off */ +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 25 + +#endif /* _BUTTON_TARGET_H_ */ + diff --git a/firmware/target/hosted/xduoo/button-xduoo.c b/firmware/target/hosted/xduoo/button-xduoo.c new file mode 100644 index 0000000000..9fd1392b89 --- /dev/null +++ b/firmware/target/hosted/xduoo/button-xduoo.c @@ -0,0 +1,202 @@ +/*************************************************************************** + * __________ __ ___ + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 Marcin Bukat + * Copyright (C) 2018 Roman Stolyarov + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +//#include +#include +#include +#include +#include +#include +#include +#include + +#include "sysfs.h" +#include "button.h" +#include "button-target.h" +#include "panic.h" + +#include "kernel.h" +#include "backlight.h" +#include "backlight-target.h" + +static bool soft_hold = false; +#ifndef BOOTLOADER +static unsigned soft_hold_counter = 0; +#define SOFT_HOLD_BUTTON BUTTON_POWER +#define SOFT_HOLD_CNTMAX_1 (HZ) +#define SOFT_HOLD_CNTMAX_2 (HZ*2) +#endif + +#define NR_POLL_DESC 3 +static struct pollfd poll_fds[NR_POLL_DESC]; + +static int button_map(int keycode) +{ + switch(keycode) + { + case KEY_BACK: + return BUTTON_HOME; + + case KEY_MENU: + return BUTTON_OPTION; + + case KEY_UP: + return BUTTON_PREV; + + case KEY_DOWN: + return BUTTON_NEXT; + + case KEY_ENTER: + return BUTTON_PLAY; + + case KEY_VOLUMEUP: + return BUTTON_VOL_UP; + + case KEY_VOLUMEDOWN: + return BUTTON_VOL_DOWN; + + case KEY_POWER: + return BUTTON_POWER; + + default: + return 0; + } +} + +void button_init_device(void) +{ + const char * const input_devs[] = { + "/dev/input/event0", + "/dev/input/event1", + "/dev/input/event2" + }; + + for(int i = 0; i < NR_POLL_DESC; i++) + { + int fd = open(input_devs[i], O_RDWR); + + if(fd < 0) + { + panicf("Cannot open input device: %s\n", input_devs[i]); + } + + poll_fds[i].fd = fd; + poll_fds[i].events = POLLIN; + poll_fds[i].revents = 0; + } +} + +int button_read_device(void) +{ + static int button_bitmap = 0; + struct input_event event; + + /* check if there are any events pending and process them */ + while(poll(poll_fds, NR_POLL_DESC, 0)) + { + for(int i = 0; i < NR_POLL_DESC; i++) + { + /* read only if non-blocking */ + if(poll_fds[i].revents & POLLIN) + { + int size = read(poll_fds[i].fd, &event, sizeof(event)); + if(size == (int)sizeof(event)) + { + int keycode = event.code; + /* event.value == 1 means press + * event.value == 0 means release + */ + bool press = event.value ? true : false; + + /* map linux event code to rockbox button bitmap */ + if(press) + { + button_bitmap |= button_map(keycode); + } + else + { + button_bitmap &= ~button_map(keycode); + } + } + } + } + } + +#ifndef BOOTLOADER + if (button_bitmap == SOFT_HOLD_BUTTON) { + soft_hold_counter++; + if (soft_hold_counter == SOFT_HOLD_CNTMAX_1) { + soft_hold = !soft_hold; + backlight_hold_changed(soft_hold); + } + else + if (soft_hold_counter == SOFT_HOLD_CNTMAX_2) { + soft_hold = false; + backlight_hold_changed(soft_hold); + } + } else { + soft_hold_counter = 0; + } + + if((soft_hold) && (button_bitmap != SOFT_HOLD_BUTTON)) { + return BUTTON_NONE; + } +#endif + + return button_bitmap; +} + +bool headphones_inserted(void) +{ + int status = 0; + const char * const sysfs_lo_switch = "/sys/class/switch/lineout/state"; + const char * const sysfs_hs_switch = "/sys/class/switch/headset/state"; +#ifdef XDUOO_X20 + const char * const sysfs_bal_switch = "/sys/class/switch/balance/state"; +#endif + + sysfs_get_int(sysfs_lo_switch, &status); + if (status) return true; + + sysfs_get_int(sysfs_hs_switch, &status); + if (status) return true; + +#ifdef XDUOO_X20 + sysfs_get_int(sysfs_bal_switch, &status); + if (status) return true; +#endif + + return false; +} + +void button_close_device(void) +{ + /* close descriptors */ + for(int i = 0; i < NR_POLL_DESC; i++) + { + close(poll_fds[i].fd); + } +} + +bool button_hold(void) +{ + return soft_hold; +} diff --git a/firmware/target/hosted/xduoo/debug-xduoo.c b/firmware/target/hosted/xduoo/debug-xduoo.c new file mode 100644 index 0000000000..33f3ac4b97 --- /dev/null +++ b/firmware/target/hosted/xduoo/debug-xduoo.c @@ -0,0 +1,6 @@ +#include + +bool debug_hw_info(void) +{ + return false; +} diff --git a/firmware/target/hosted/xduoo/lcd-target.h b/firmware/target/hosted/xduoo/lcd-target.h new file mode 100644 index 0000000000..bb9b77771b --- /dev/null +++ b/firmware/target/hosted/xduoo/lcd-target.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2016 Amaury Pouly + * + * 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__ + +/* needs special ioctl() to redraw updated framebuffer content */ +#define LCD_OPTIMIZED_UPDATE +#define LCD_OPTIMIZED_UPDATE_RECT + +extern fb_data *framebuffer; /* see lcd-xduoo.c */ +#define LCD_FRAMEBUF_ADDR(col, row) (framebuffer + (row)*LCD_WIDTH + (col)) + +extern void lcd_set_active(bool active); +#endif /* __LCD_TARGET_H__ */ diff --git a/firmware/target/hosted/xduoo/lcd-xduoo.c b/firmware/target/hosted/xduoo/lcd-xduoo.c new file mode 100644 index 0000000000..4b3148da03 --- /dev/null +++ b/firmware/target/hosted/xduoo/lcd-xduoo.c @@ -0,0 +1,140 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 Marcin Bukat + * Copyright (C) 2016 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "lcd.h" +#include "lcd-target.h" +#include "backlight-target.h" +#include "sysfs.h" +#include "panic.h" + +static int fd = -1; +static struct fb_var_screeninfo vinfo; +fb_data *framebuffer = 0; /* global variable, see lcd-target.h */ + +void lcd_init_device(void) +{ + const char * const fb_dev = "/dev/fb0"; + fd = open(fb_dev, O_RDWR); + if(fd < 0) + { + panicf("Cannot open framebuffer: %s\n", fb_dev); + } + + /* get fixed and variable information */ + struct fb_fix_screeninfo finfo; + if(ioctl(fd, FBIOGET_FSCREENINFO, &finfo) < 0) + { + panicf("Cannot read framebuffer fixed information"); + } + + if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) + { + panicf("Cannot read framebuffer variable information"); + } + +#if 0 + /* check resolution and framebuffer size */ + if(vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT || vinfo.bits_per_pixel != LCD_DEPTH) + { + panicf("Unexpected framebuffer resolution: %dx%dx%d\n", vinfo.xres, + vinfo.yres, vinfo.bits_per_pixel); + } +#endif + /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the + * values returned by the driver for line_length */ + + /* map framebuffer */ + framebuffer = mmap(0, FRAMEBUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if((void *)framebuffer == MAP_FAILED) + { + panicf("Cannot map framebuffer"); + } + +#ifdef HAVE_LCD_ENABLE + lcd_set_active(true); +#endif +} + +#ifdef HAVE_LCD_SHUTDOWN +void lcd_shutdown(void) +{ + munmap(framebuffer, FRAMEBUFFER_SIZE); + close(fd); +} +#endif + +void lcd_enable(bool on) +{ + const char * const sysfs_fb_blank = "/sys/class/graphics/fb0/blank"; + + if (lcd_active() != on) + { + sysfs_set_int(sysfs_fb_blank, on ? 0 : 1); + lcd_set_active(on); + + if (on) + { + send_event(LCD_EVENT_ACTIVATION, NULL); + } + } +} + +static void redraw(void) +{ + ioctl(fd, FBIOPAN_DISPLAY, &vinfo); +} + +extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, + int width, int height); + +void lcd_update(void) +{ + /* Copy the Rockbox framebuffer to the second framebuffer */ + lcd_copy_buffer_rect(LCD_FRAMEBUF_ADDR(0, 0), FBADDR(0,0), + LCD_WIDTH*LCD_HEIGHT, 1); + redraw(); +} + +void lcd_update_rect(int x, int y, int width, int height) +{ + fb_data *dst = LCD_FRAMEBUF_ADDR(x, y); + fb_data * src = FBADDR(x,y); + + /* Copy part of the Rockbox framebuffer to the second framebuffer */ + if (width < LCD_WIDTH) + { + /* Not full width - do line-by-line */ + lcd_copy_buffer_rect(dst, src, width, height); + } + else + { + /* Full width - copy as one line */ + lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); + } + redraw(); +} diff --git a/firmware/target/hosted/xduoo/power-xduoo.c b/firmware/target/hosted/xduoo/power-xduoo.c new file mode 100644 index 0000000000..97a8dd4779 --- /dev/null +++ b/firmware/target/hosted/xduoo/power-xduoo.c @@ -0,0 +1,74 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 by Marcin Bukat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include +#include +#include + +#include "system.h" +#include "power-xduoo.h" +#include "power.h" +#include "panic.h" +#include "sysfs.h" + +const char * const sysfs_bat_voltage = + "/sys/class/power_supply/battery/voltage_now"; + +const char * const sysfs_bat_capacity = + "/sys/class/power_supply/battery/capacity"; + +const char * const sysfs_bat_status = + "/sys/class/power_supply/battery/status"; + +const char * const sysfs_pow_supply = + "/sys/class/power_supply/usb/present"; + +unsigned int xduoo_power_input_status(void) +{ + int present = 0; + sysfs_get_int(sysfs_pow_supply, &present); + + return present ? POWER_INPUT_USB_CHARGER : POWER_INPUT_NONE; +} + +bool xduoo_power_charging_status(void) +{ + char buf[12] = {0}; + sysfs_get_string(sysfs_bat_status, buf, sizeof(buf)); + + return (strncmp(buf, "Charging", 8) == 0); +} + +unsigned int xduoo_power_get_battery_voltage(void) +{ + int battery_voltage; + sysfs_get_int(sysfs_bat_voltage, &battery_voltage); + + return battery_voltage/1000; +} + +unsigned int xduoo_power_get_battery_capacity(void) +{ + int battery_capacity; + sysfs_get_int(sysfs_bat_capacity, &battery_capacity); + + return battery_capacity; +} diff --git a/firmware/target/hosted/xduoo/power-xduoo.h b/firmware/target/hosted/xduoo/power-xduoo.h new file mode 100644 index 0000000000..d573865ed2 --- /dev/null +++ b/firmware/target/hosted/xduoo/power-xduoo.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 by Marcin Bukat + * + * 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 _POWER_XDUOO_H_ +#define _POWER_XDUOO_H_ + +#include +#include "config.h" + +unsigned int xduoo_power_input_status(void); +bool xduoo_power_charging_status(void); +unsigned int xduoo_power_get_battery_voltage(void); +unsigned int xduoo_power_get_battery_capacity(void); +#endif /* _POWER_XDUOO_H_ */ + diff --git a/firmware/target/hosted/xduoo/powermgmt-xduoo.c b/firmware/target/hosted/xduoo/powermgmt-xduoo.c new file mode 100644 index 0000000000..30001934ba --- /dev/null +++ b/firmware/target/hosted/xduoo/powermgmt-xduoo.c @@ -0,0 +1,70 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 Marcin Bukat + * + * 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 "powermgmt.h" +#include "power.h" +#include "power-xduoo.h" + +const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = +{ + 3470 +}; + +/* the OF shuts down at this voltage */ +const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = +{ + 3400 +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ +const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = +{ + { 3400, 3639, 3697, 3723, 3757, 3786, 3836, 3906, 3980, 4050, 4159 } +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ +const unsigned short const percent_to_volt_charge[11] = +{ + 3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196 +}; + +unsigned int power_input_status(void) +{ + /* POWER_INPUT_USB_CHARGER, POWER_INPUT_NONE */ + return xduoo_power_input_status(); +} + +#if defined(XDUOO_X3II) +int _battery_voltage(void) +{ + return xduoo_power_get_battery_voltage(); +} +#endif + +#if defined(XDUOO_X20) +int _battery_level(void) +{ + return xduoo_power_get_battery_capacity(); +} +#endif + +bool charging_state(void) +{ + return xduoo_power_charging_status(); +} diff --git a/firmware/target/hosted/xduoo/system-target.h b/firmware/target/hosted/xduoo/system-target.h new file mode 100644 index 0000000000..830f19fde4 --- /dev/null +++ b/firmware/target/hosted/xduoo/system-target.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 Marcin Bukat + * Copyright (C) 2016 Amaury Pouly + * + * 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 __SYSTEM_TARGET_H__ +#define __SYSTEM_TARGET_H__ + +#include "kernel-unix.h" +#include "system-hosted.h" + +#define NEED_GENERIC_BYTESWAPS +#endif /* __SYSTEM_TARGET_H__ */ diff --git a/firmware/target/hosted/xduoo/usb-xduoo.c b/firmware/target/hosted/xduoo/usb-xduoo.c new file mode 100644 index 0000000000..19248ad262 --- /dev/null +++ b/firmware/target/hosted/xduoo/usb-xduoo.c @@ -0,0 +1,118 @@ +/*************************************************************************** + * __________ __ ___ + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2018 by Marcin Bukat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include "config.h" +#include "disk.h" +#include "usb.h" +#include "sysfs.h" +#include "power.h" +#include "power-xduoo.h" + +static bool adb_mode = false; + +/* TODO: implement usb detection properly */ +int usb_detect(void) +{ + return power_input_status() == POWER_INPUT_USB_CHARGER ? USB_INSERTED : USB_EXTRACTED; +} + +void usb_enable(bool on) +{ + /* Ignore usb enable/disable when ADB is enabled so we can fireup adb shell + * without entering ums mode + */ + if (!adb_mode) + { + sysfs_set_int("/sys/class/android_usb/android0/enable", on ? 1 : 0); + } +} + +/* This is called by usb thread after usb extract in order to return + * regular FS access + * + * returns the # of successful mounts +*/ +int disk_mount_all(void) +{ + const char *dev[] = {"/dev/mmcblk0p1", "/dev/mmcblk0"}; + const char *fs[] = {"vfat", "exfat"}; + + sysfs_set_string("/sys/class/android_usb/android0/f_mass_storage/lun/file", ""); + + for (int i=0; i<2; i++) + { + for (int j=0; j<2; j++) + { + if (mount(dev[i], "/mnt/sd_0", fs[j], 0, NULL) == 0) + { + return 1; + } + } + } + + return 0; +} + +/* This is called by usb thread after all threads ACKs usb inserted message + * + * returns the # of successful unmounts + */ +int disk_unmount_all(void) +{ + if (umount("/mnt/sd_0") == 0) + { + sysfs_set_string("/sys/class/android_usb/android0/f_mass_storage/lun/file", "/dev/mmcblk0"); + return 1; + } + + return 0; +} + +void usb_init_device(void) +{ + char functions[32] = {0}; + + /* Check if ADB was activated in bootloader */ + sysfs_get_string("/sys/class/android_usb/android0/functions", functions, sizeof(functions)); + adb_mode = (strstr(functions, "adb") == NULL) ? false : true; + + usb_enable(false); + + if (adb_mode) + { + sysfs_set_string("/sys/class/android_usb/android0/functions", "mass_storage,adb"); + sysfs_set_string("/sys/class/android_usb/android0/idVendor", "18D1"); + sysfs_set_string("/sys/class/android_usb/android0/idProduct", "D002"); + } + else + { + sysfs_set_string("/sys/class/android_usb/android0/functions", "mass_storage"); + sysfs_set_string("/sys/class/android_usb/android0/idVendor", "C502"); + sysfs_set_string("/sys/class/android_usb/android0/idProduct", "0029"); + } + + sysfs_set_string("/sys/class/android_usb/android0/iManufacturer", "Rockbox.org"); + sysfs_set_string("/sys/class/android_usb/android0/iProduct", "Rockbox media player"); + sysfs_set_string("/sys/class/android_usb/android0/iSerial", "0123456789ABCDEF"); + sysfs_set_string("/sys/class/android_usb/android0/f_mass_storage/inquiry_string", "xDuoo 0100"); +} diff --git a/firmware/target/hosted/xduoo/xduoo.make b/firmware/target/hosted/xduoo/xduoo.make new file mode 100644 index 0000000000..5c37d27412 --- /dev/null +++ b/firmware/target/hosted/xduoo/xduoo.make @@ -0,0 +1,52 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +INCLUDES += -I$(FIRMDIR)/include -I$(FIRMDIR)/export $(TARGET_INC) -I$(BUILDDIR) -I$(APPSDIR) + +SIMFLAGS += $(INCLUDES) $(DEFINES) -DHAVE_CONFIG_H $(GCCOPTS) + +# bootloader build is sligtly different +ifneq (,$(findstring bootloader,$(APPSDIR))) + +SRC += $(call preprocess, $(APPSDIR)/SOURCES) +CLEANOBJS += $(BUILDDIR)/bootloader.* + +endif #bootloader + +.SECONDEXPANSION: # $$(OBJ) is not populated until after this + +ifneq (,$(findstring bootloader,$(APPSDIR))) +# bootloader build + +$(BUILDDIR)/bootloader.elf : $$(OBJ) $(FIRMLIB) $(CORE_LIBS) + $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -Os -o $@ $(OBJ) \ + -L$(BUILDDIR)/firmware -lfirmware \ + -L$(BUILDDIR)/lib $(call a2lnk,$(CORE_LIBS)) \ + $(LDOPTS) $(GLOBAL_LDOPTS) -Wl,--gc-sections -Wl,-Map,$(BUILDDIR)/bootloader.map + +$(BUILDDIR)/$(BINARY): $(BUILDDIR)/bootloader.elf + $(call PRINTS,OC $(@F))$(call objcopy,$^,$@) + +else +# rockbox app build + +$(BUILDDIR)/rockbox.elf : $$(OBJ) $(FIRMLIB) $(VOICESPEEXLIB) $(CORE_LIBS) + $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -Os -o $@ $(OBJ) \ + -L$(BUILDDIR)/firmware -lfirmware \ + -L$(RBCODEC_BLD)/codecs $(call a2lnk, $(VOICESPEEXLIB)) \ + -L$(BUILDDIR)/lib $(call a2lnk,$(CORE_LIBS)) \ + $(LDOPTS) $(GLOBAL_LDOPTS) -Wl,-Map,$(BUILDDIR)/rockbox.map + +$(BUILDDIR)/rockbox.x3ii : $(BUILDDIR)/rockbox.elf + $(call PRINTS,OC $(@F))$(call objcopy,$^,$@) + +$(BUILDDIR)/rockbox.x20 : $(BUILDDIR)/rockbox.elf + $(call PRINTS,OC $(@F))$(call objcopy,$^,$@) + +endif -- cgit v1.2.3