diff options
author | Dana Conrad <dconrad@fastmail.com> | 2021-06-26 12:07:11 -0500 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2021-07-18 12:14:35 +0000 |
commit | 3e7a09cb0dee0ee04b5c77f427bf89d990ec8d0b (patch) | |
tree | be1eb7e1d4166f60b245a0603e9f7dc11e1f5614 | |
parent | 64a24591aec049682167b193700a07572fc04c4c (diff) | |
download | rockbox-3e7a09cb0dee0ee04b5c77f427bf89d990ec8d0b.tar.gz rockbox-3e7a09cb0dee0ee04b5c77f427bf89d990ec8d0b.zip |
New Port: Eros Q Native
What works:
- LCD: 16-bit RGB565
- all buttons, including scrollwheel
- SD Card
- Battery level and charging/not charging status
- USB
- audio
- sample rate switching
- HP / LO detect, with "safe" fixed LO volume -
LO volume will only be put to user-defined max volume
if headphones are not present.
- rtc
- Plugins build, tried a couple and they seem OK
- Bootloader, installable to nand via usbboot
What doesn't work:
- Dual Boot
- power on/off has intermittent, low volume audio click
(sometimes it's completely silent, sometimes there's
a click)
- Audio uses 16-bit volume scaling, so clicking/popping
is pretty bad at lower volumes - need 32 bit volume
scaling, 24 bit I2S data
- USB HID keys not yet defined
- no jztool support
Unknowns:
- Stereo Switch pins: Direction select, AC_DC
(probably not even hooked up)
- What is the actual purpose of the Stereo Swtich?
- How does the bluetooth module connect?
"Someday" stuff:
- get LCD working at higher bit depth
- Bluetooth
Change-Id: I70dda8fc092c6e3f4352f2245e4164193f803c33
28 files changed, 1283 insertions, 5 deletions
diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c index 98fdb468d3..a0d9b26ec2 100644 --- a/apps/plugins/rockpaint.c +++ b/apps/plugins/rockpaint.c | |||
@@ -407,6 +407,17 @@ | |||
407 | #elif CONFIG_KEYPAD == SHANLING_Q1_PAD | 407 | #elif CONFIG_KEYPAD == SHANLING_Q1_PAD |
408 | /* use touchscreen */ | 408 | /* use touchscreen */ |
409 | 409 | ||
410 | #elif CONFIG_KEYPAD == EROSQ_PAD | ||
411 | #define ROCKPAINT_QUIT BUTTON_POWER | ||
412 | #define ROCKPAINT_DRAW BUTTON_PLAY | ||
413 | #define ROCKPAINT_MENU BUTTON_MENU | ||
414 | #define ROCKPAINT_TOOLBAR BUTTON_VOL_UP | ||
415 | #define ROCKPAINT_TOOLBAR2 BUTTON_VOL_DOWN | ||
416 | #define ROCKPAINT_UP BUTTON_PREV | ||
417 | #define ROCKPAINT_DOWN BUTTON_NEXT | ||
418 | #define ROCKPAINT_LEFT BUTTON_SCROLL_BACK | ||
419 | #define ROCKPAINT_RIGHT BUTTON_SCROLL_FWD | ||
420 | |||
410 | #else | 421 | #else |
411 | #error "Please define keys for this keypad" | 422 | #error "Please define keys for this keypad" |
412 | #endif | 423 | #endif |
diff --git a/bootloader/SOURCES b/bootloader/SOURCES index 6cdcd41ece..86dd64d7d9 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES | |||
@@ -89,6 +89,6 @@ show_logo.c | |||
89 | #elif defined(SANSA_CONNECT) | 89 | #elif defined(SANSA_CONNECT) |
90 | sansaconnect.c | 90 | sansaconnect.c |
91 | show_logo.c | 91 | show_logo.c |
92 | #elif defined(FIIO_M3K) || defined(SHANLING_Q1) | 92 | #elif defined(FIIO_M3K) || defined(SHANLING_Q1) || defined(EROS_QN) |
93 | x1000.c | 93 | x1000.c |
94 | #endif | 94 | #endif |
diff --git a/bootloader/x1000.c b/bootloader/x1000.c index 3467547684..a7c7692ac8 100644 --- a/bootloader/x1000.c +++ b/bootloader/x1000.c | |||
@@ -77,6 +77,17 @@ | |||
77 | # define BL_SELECT_NAME "PLAY" | 77 | # define BL_SELECT_NAME "PLAY" |
78 | # define BL_QUIT_NAME "POWER" | 78 | # define BL_QUIT_NAME "POWER" |
79 | # define BOOTBACKUP_FILE "/shanlingq1-boot.bin" | 79 | # define BOOTBACKUP_FILE "/shanlingq1-boot.bin" |
80 | #elif defined(EROS_QN) | ||
81 | # define BL_RECOVERY BUTTON_VOL_UP | ||
82 | # define BL_UP BUTTON_SCROLL_BACK | ||
83 | # define BL_DOWN BUTTON_SCROLL_FWD | ||
84 | # define BL_SELECT BUTTON_PLAY | ||
85 | # define BL_QUIT BUTTON_POWER | ||
86 | # define BL_UP_NAME "Up" | ||
87 | # define BL_DOWN_NAME "Scroll Down" | ||
88 | # define BL_SELECT_NAME "PLAY" | ||
89 | # define BL_QUIT_NAME "POWER" | ||
90 | # define BOOTBACKUP_FILE "/erosqnative-boot.bin" | ||
80 | #else | 91 | #else |
81 | # error "Missing keymap!" | 92 | # error "Missing keymap!" |
82 | #endif | 93 | #endif |
diff --git a/firmware/SOURCES b/firmware/SOURCES index e055558b57..fc194fe640 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -505,6 +505,8 @@ drivers/audio/cs4398.c | |||
505 | drivers/audio/es9018.c | 505 | drivers/audio/es9018.c |
506 | #elif defined (HAVE_ES9218) | 506 | #elif defined (HAVE_ES9218) |
507 | drivers/audio/es9218.c | 507 | drivers/audio/es9218.c |
508 | #elif defined (HAVE_EROS_QN_CODEC) | ||
509 | drivers/audio/eros_qn_codec.c | ||
508 | #endif /* defined(HAVE_*) */ | 510 | #endif /* defined(HAVE_*) */ |
509 | #else /* PLATFORM_HOSTED */ | 511 | #else /* PLATFORM_HOSTED */ |
510 | #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) | 512 | #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) |
@@ -1727,6 +1729,15 @@ target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c | |||
1727 | target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c | 1729 | target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c |
1728 | #endif /* SHANLING_Q1 */ | 1730 | #endif /* SHANLING_Q1 */ |
1729 | 1731 | ||
1732 | #if defined(EROS_QN) | ||
1733 | target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c | ||
1734 | target/mips/ingenic_x1000/erosqnative/backlight-erosqnative.c | ||
1735 | target/mips/ingenic_x1000/erosqnative/button-erosqnative.c | ||
1736 | target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c | ||
1737 | target/mips/ingenic_x1000/erosqnative/power-erosqnative.c | ||
1738 | target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c | ||
1739 | #endif /* EROS_QN */ | ||
1740 | |||
1730 | #if defined(LYRE_PROTO1) | 1741 | #if defined(LYRE_PROTO1) |
1731 | target/arm/at91sam/lyre_proto1/adc-lyre_proto1.c | 1742 | target/arm/at91sam/lyre_proto1/adc-lyre_proto1.c |
1732 | target/arm/at91sam/lyre_proto1/backlight-lyre_proto1.c | 1743 | target/arm/at91sam/lyre_proto1/backlight-lyre_proto1.c |
diff --git a/firmware/drivers/audio/eros_qn_codec.c b/firmware/drivers/audio/eros_qn_codec.c new file mode 100644 index 0000000000..21347f5fca --- /dev/null +++ b/firmware/drivers/audio/eros_qn_codec.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Andrew Ryabinin, Dana Conrad | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "system.h" | ||
23 | #include "eros_qn_codec.h" | ||
24 | #include "config.h" | ||
25 | #include "audio.h" | ||
26 | #include "audiohw.h" | ||
27 | #include "settings.h" | ||
28 | #include "pcm_sw_volume.h" | ||
29 | |||
30 | static long int vol_l_hw = 0; | ||
31 | static long int vol_r_hw = 0; | ||
32 | |||
33 | void pcm5102_set_outputs(void) | ||
34 | { | ||
35 | audiohw_set_volume(vol_l_hw, vol_r_hw); | ||
36 | } | ||
37 | |||
38 | /* this makes less sense here than it does in the audiohw-*.c file, | ||
39 | * but we need access to settings.h */ | ||
40 | void audiohw_set_volume(int vol_l, int vol_r) | ||
41 | { | ||
42 | int l, r; | ||
43 | |||
44 | vol_l_hw = vol_l; | ||
45 | vol_r_hw = vol_r; | ||
46 | |||
47 | l = vol_l; | ||
48 | r = vol_r; | ||
49 | |||
50 | #if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) | ||
51 | /* make sure headphones aren't present - don't want to | ||
52 | * blow out our eardrums cranking it to full */ | ||
53 | if (lineout_inserted() && !headphones_inserted()) | ||
54 | { | ||
55 | l = r = global_settings.volume_limit * 10; | ||
56 | } | ||
57 | else | ||
58 | { | ||
59 | l = vol_l; | ||
60 | r = vol_r; | ||
61 | } | ||
62 | #endif | ||
63 | |||
64 | pcm_set_master_volume(l, r); | ||
65 | } | ||
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 5b2815149d..5a706da3b8 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h | |||
@@ -210,6 +210,8 @@ struct sound_settings_info | |||
210 | #include "df1704.h" | 210 | #include "df1704.h" |
211 | #elif defined(HAVE_PCM1792_CODEC) | 211 | #elif defined(HAVE_PCM1792_CODEC) |
212 | #include "pcm1792.h" | 212 | #include "pcm1792.h" |
213 | #elif defined(HAVE_EROS_QN_CODEC) | ||
214 | #include "eros_qn_codec.h" | ||
213 | #elif defined(HAVE_NWZ_LINUX_CODEC) | 215 | #elif defined(HAVE_NWZ_LINUX_CODEC) |
214 | #include "nwzlinux_codec.h" | 216 | #include "nwzlinux_codec.h" |
215 | #elif defined(HAVE_CS4398) | 217 | #elif defined(HAVE_CS4398) |
diff --git a/firmware/export/config.h b/firmware/export/config.h index 5e7b2be6e4..702b821856 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -276,6 +276,7 @@ | |||
276 | #define LCD_IHIFI800 68 /* as used by IHIFI 800 */ | 276 | #define LCD_IHIFI800 68 /* as used by IHIFI 800 */ |
277 | #define LCD_FIIOM3K 69 /* as used by the FiiO M3K */ | 277 | #define LCD_FIIOM3K 69 /* as used by the FiiO M3K */ |
278 | #define LCD_SHANLING_Q1 70 /* as used by the Shanling Q1 */ | 278 | #define LCD_SHANLING_Q1 70 /* as used by the Shanling Q1 */ |
279 | #define LCD_EROSQ 71 /* as used by the ErosQ (native) */ | ||
279 | 280 | ||
280 | /* LCD_PIXELFORMAT */ | 281 | /* LCD_PIXELFORMAT */ |
281 | #define HORIZONTAL_PACKING 1 | 282 | #define HORIZONTAL_PACKING 1 |
@@ -596,6 +597,8 @@ Lyre prototype 1 */ | |||
596 | #include "config/aigoerosq.h" | 597 | #include "config/aigoerosq.h" |
597 | #elif defined(SHANLING_Q1) | 598 | #elif defined(SHANLING_Q1) |
598 | #include "config/shanlingq1.h" | 599 | #include "config/shanlingq1.h" |
600 | #elif defined(EROS_QN) | ||
601 | #include "config/erosqnative.h" | ||
599 | #else | 602 | #else |
600 | //#error "unknown hwardware platform!" | 603 | //#error "unknown hwardware platform!" |
601 | #endif | 604 | #endif |
diff --git a/firmware/export/config/erosqnative.h b/firmware/export/config/erosqnative.h new file mode 100644 index 0000000000..1b37b6042a --- /dev/null +++ b/firmware/export/config/erosqnative.h | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * This config file is for the AIGO EROS Q / EROS K (and its clones) | ||
3 | */ | ||
4 | |||
5 | /* For Rolo and boot loader */ | ||
6 | #define MODEL_NAME "AIGO Eros Q Native" | ||
7 | #define MODEL_NUMBER 116 | ||
8 | #define BOOTFILE_EXT "erosq" | ||
9 | #define BOOTFILE "rockbox." BOOTFILE_EXT | ||
10 | #define BOOTDIR "/.rockbox" | ||
11 | #define FIRMWARE_OFFSET_FILE_CRC 0 | ||
12 | #define FIRMWARE_OFFSET_FILE_DATA 8 | ||
13 | |||
14 | /* CPU defines */ | ||
15 | #define CONFIG_CPU X1000 | ||
16 | #define X1000_EXCLK_FREQ 24000000 | ||
17 | #define CPU_FREQ 1008000000 | ||
18 | #define HAVE_FPU | ||
19 | |||
20 | #ifndef SIMULATOR | ||
21 | #define TIMER_FREQ X1000_EXCLK_FREQ | ||
22 | #endif | ||
23 | |||
24 | /* kernel defines */ | ||
25 | #define INCLUDE_TIMEOUT_API | ||
26 | #define HAVE_SEMAPHORE_OBJECTS | ||
27 | |||
28 | /* drivers */ | ||
29 | #define HAVE_I2C_ASYNC | ||
30 | |||
31 | /* Buffers for plugsins and codecs */ | ||
32 | #define PLUGIN_BUFFER_SIZE 0x200000 /* 2 MiB */ | ||
33 | #define CODEC_SIZE 0x100000 /* 1 MiB */ | ||
34 | |||
35 | /* LCD defines */ | ||
36 | #define CONFIG_LCD LCD_EROSQ | ||
37 | #define LCD_WIDTH 320 | ||
38 | #define LCD_HEIGHT 240 | ||
39 | #define LCD_DEPTH 16 /* Future Improvement: 18 or 24 bpp if display supports it */ | ||
40 | #define LCD_PIXELFORMAT RGB565 | ||
41 | /* sqrt(240^2 + 320^2) / 2.0 = 200 */ | ||
42 | #define LCD_DPI 200 | ||
43 | #define HAVE_LCD_COLOR | ||
44 | #define HAVE_LCD_BITMAP | ||
45 | #define HAVE_LCD_ENABLE | ||
46 | #define HAVE_LCD_SHUTDOWN | ||
47 | #define LCD_X1000_FASTSLEEP | ||
48 | //#define LCD_X1000_DMA_WAITFORFRAME | ||
49 | |||
50 | #define HAVE_BACKLIGHT | ||
51 | #define HAVE_BACKLIGHT_BRIGHTNESS | ||
52 | #define MIN_BRIGHTNESS_SETTING 1 | ||
53 | #define MAX_BRIGHTNESS_SETTING 255 | ||
54 | #define BRIGHTNESS_STEP 5 | ||
55 | #define DEFAULT_BRIGHTNESS_SETTING 70 | ||
56 | #define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING | ||
57 | |||
58 | /* RTC settings */ | ||
59 | #define CONFIG_RTC RTC_X1000 | ||
60 | |||
61 | /* Codec / audio hardware defines */ | ||
62 | #define HW_SAMPR_CAPS SAMPR_CAP_ALL_192 | ||
63 | #define HAVE_EROS_QN_CODEC | ||
64 | #define HAVE_SW_TONE_CONTROLS | ||
65 | #define HAVE_SW_VOLUME_CONTROL | ||
66 | |||
67 | /* Button defines */ | ||
68 | #define CONFIG_KEYPAD EROSQ_PAD | ||
69 | #define HAVE_SCROLLWHEEL | ||
70 | #define HAVE_HEADPHONE_DETECTION | ||
71 | #define HAVE_LINEOUT_DETECTION | ||
72 | |||
73 | /* Storage defines */ | ||
74 | #define CONFIG_STORAGE STORAGE_SD | ||
75 | #define HAVE_HOTSWAP | ||
76 | #define HAVE_HOTSWAP_STORAGE_AS_MAIN | ||
77 | #define HAVE_MULTIDRIVE | ||
78 | #define NUM_DRIVES 1 | ||
79 | #define STORAGE_WANTS_ALIGN | ||
80 | #define STORAGE_NEEDS_BOUNCE_BUFFER | ||
81 | |||
82 | /* Power management */ | ||
83 | #define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE | ||
84 | #define CONFIG_CHARGING CHARGING_MONITOR | ||
85 | #define HAVE_SW_POWEROFF | ||
86 | |||
87 | #ifndef SIMULATOR | ||
88 | #define HAVE_AXP_PMU 192 | ||
89 | #define HAVE_POWEROFF_WHILE_CHARGING | ||
90 | #endif | ||
91 | |||
92 | /* Battery */ | ||
93 | #define BATTERY_TYPES_COUNT 1 | ||
94 | #define BATTERY_CAPACITY_DEFAULT 1300 /* default battery capacity */ | ||
95 | #define BATTERY_CAPACITY_MIN 1300 /* min. capacity selectable */ | ||
96 | #define BATTERY_CAPACITY_MAX 1300 /* max. capacity selectable */ | ||
97 | #define BATTERY_CAPACITY_INC 0 /* capacity increment */ | ||
98 | |||
99 | #define CURRENT_NORMAL 100 // 1.7mA * 60s | ||
100 | #define CURRENT_BACKLIGHT 180 | ||
101 | #define CURRENT_MAX_CHG 500 // bursts higher if needed | ||
102 | |||
103 | /* USB support */ | ||
104 | #ifndef SIMULATOR | ||
105 | #define CONFIG_USBOTG USBOTG_DESIGNWARE | ||
106 | #define USB_DW_ARCH_SLAVE | ||
107 | #define USB_DW_TURNAROUND 5 | ||
108 | #define HAVE_USBSTACK | ||
109 | #define USB_VENDOR_ID 0xc502 | ||
110 | #define USB_PRODUCT_ID 0x0023 | ||
111 | #define USB_DEVBSS_ATTR __attribute__((aligned(32))) | ||
112 | #define HAVE_USB_POWER | ||
113 | #define HAVE_USB_CHARGING_ENABLE | ||
114 | #define HAVE_BOOTLOADER_USB_MODE | ||
115 | #endif | ||
116 | |||
117 | /* Rockbox capabilities */ | ||
118 | #define HAVE_VOLUME_IN_LIST | ||
119 | #define HAVE_FAT16SUPPORT | ||
120 | #define HAVE_ALBUMART | ||
121 | #define HAVE_BMP_SCALING | ||
122 | #define HAVE_JPEG | ||
123 | #define HAVE_TAGCACHE | ||
124 | #define HAVE_QUICKSCREEN | ||
125 | #define HAVE_HOTKEY | ||
diff --git a/firmware/export/eros_qn_codec.h b/firmware/export/eros_qn_codec.h new file mode 100644 index 0000000000..15c745c04b --- /dev/null +++ b/firmware/export/eros_qn_codec.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * | ||
11 | * Copyright (c) 2021 Andrew Ryabinin, Dana Conrad | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #ifndef _EROS_QN_CODEC_H | ||
24 | #define _EROS_QN_CODEC_H | ||
25 | |||
26 | #define PCM5102A_VOLUME_MIN -740 | ||
27 | #define PCM5102A_VOLUME_MAX 0 | ||
28 | |||
29 | AUDIOHW_SETTING(VOLUME, "dB", 0, 1, PCM5102A_VOLUME_MIN/10, PCM5102A_VOLUME_MAX/10, 0) | ||
30 | |||
31 | /* this just calls audiohw_set_volume() with the last (locally) known volume, | ||
32 | * used for switching to/from fixed line out volume. */ | ||
33 | void pcm5102_set_outputs(void); | ||
34 | |||
35 | #endif | ||
diff --git a/firmware/target/mips/ingenic_x1000/clk-x1000.c b/firmware/target/mips/ingenic_x1000/clk-x1000.c index 7e254401fb..4988e7c3bf 100644 --- a/firmware/target/mips/ingenic_x1000/clk-x1000.c +++ b/firmware/target/mips/ingenic_x1000/clk-x1000.c | |||
@@ -265,7 +265,7 @@ void clk_init(void) | |||
265 | jz_writef(CPM_APCR, BS(1), PLLM(42 - 1), PLLN(0), PLLOD(0), ENABLE(1)); | 265 | jz_writef(CPM_APCR, BS(1), PLLM(42 - 1), PLLN(0), PLLOD(0), ENABLE(1)); |
266 | while(jz_readf(CPM_APCR, ON) == 0); | 266 | while(jz_readf(CPM_APCR, ON) == 0); |
267 | 267 | ||
268 | #if defined(FIIO_M3K) | 268 | #if (defined(FIIO_M3K) || defined(EROS_QN)) |
269 | /* TODO: Allow targets to define their clock frequencies in their config, | 269 | /* TODO: Allow targets to define their clock frequencies in their config, |
270 | * instead of having this be a random special case. */ | 270 | * instead of having this be a random special case. */ |
271 | if(get_boot_option() == BOOT_OPTION_ROCKBOX) { | 271 | if(get_boot_option() == BOOT_OPTION_ROCKBOX) { |
@@ -296,7 +296,7 @@ void clk_init(void) | |||
296 | CLKMUX_CPU(SCLK_A) | | 296 | CLKMUX_CPU(SCLK_A) | |
297 | CLKMUX_AHB0(MPLL) | | 297 | CLKMUX_AHB0(MPLL) | |
298 | CLKMUX_AHB2(MPLL)); | 298 | CLKMUX_AHB2(MPLL)); |
299 | #if defined(FIIO_M3K) | 299 | #if (defined(FIIO_M3K) || defined(EROS_QN)) |
300 | } | 300 | } |
301 | #endif | 301 | #endif |
302 | 302 | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/adc-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/adc-target.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/adc-target.h | |||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c new file mode 100644 index 0000000000..7bb985650c --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald, Dana Conrad | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "audiohw.h" | ||
23 | #include "system.h" | ||
24 | #include "pcm_sampr.h" | ||
25 | #include "aic-x1000.h" | ||
26 | #include "i2c-x1000.h" | ||
27 | #include "gpio-x1000.h" | ||
28 | #include "logf.h" | ||
29 | |||
30 | /* Audio path appears to be: | ||
31 | * DAC --> HP Amp --> Stereo Switch --> HP OUT | ||
32 | * \--> LO OUT | ||
33 | * | ||
34 | * The real purpose of the Stereo Switch is not clear. | ||
35 | * It appears to switch sources between the HP amp and something, | ||
36 | * likely something unimplemented. */ | ||
37 | |||
38 | void audiohw_init(void) | ||
39 | { | ||
40 | /* explicitly mute everything */ | ||
41 | gpio_set_level(GPIO_MAX97220_SHDN, 0); | ||
42 | gpio_set_level(GPIO_ISL54405_MUTE, 1); | ||
43 | gpio_set_level(GPIO_PCM5102A_XMIT, 0); | ||
44 | |||
45 | aic_set_external_codec(true); | ||
46 | aic_set_i2s_mode(AIC_I2S_MASTER_MODE); | ||
47 | audiohw_set_frequency(HW_FREQ_48); | ||
48 | |||
49 | aic_enable_i2s_master_clock(true); | ||
50 | aic_enable_i2s_bit_clock(true); | ||
51 | |||
52 | mdelay(10); | ||
53 | |||
54 | /* power on DAC and HP Amp */ | ||
55 | gpio_set_level(GPIO_PCM5102A_ANALOG_PWR, 1); | ||
56 | gpio_set_level(GPIO_MAX97220_POWER, 1); | ||
57 | } | ||
58 | |||
59 | void audiohw_postinit(void) | ||
60 | { | ||
61 | /* unmute - attempt to make power-on pop-free */ | ||
62 | gpio_set_level(GPIO_ISL54405_SEL, 0); | ||
63 | gpio_set_level(GPIO_MAX97220_SHDN, 1); | ||
64 | mdelay(10); | ||
65 | gpio_set_level(GPIO_PCM5102A_XMIT, 1); | ||
66 | mdelay(10); | ||
67 | gpio_set_level(GPIO_ISL54405_MUTE, 0); | ||
68 | } | ||
69 | |||
70 | /* TODO: get shutdown just right according to dac datasheet */ | ||
71 | void audiohw_close(void) | ||
72 | { | ||
73 | /* mute - attempt to make power-off pop-free */ | ||
74 | gpio_set_level(GPIO_ISL54405_MUTE, 1); | ||
75 | mdelay(10); | ||
76 | gpio_set_level(GPIO_PCM5102A_XMIT, 0); | ||
77 | mdelay(10); | ||
78 | gpio_set_level(GPIO_MAX97220_SHDN, 0); | ||
79 | } | ||
80 | |||
81 | void audiohw_set_frequency(int fsel) | ||
82 | { | ||
83 | int sampr = hw_freq_sampr[fsel]; | ||
84 | int mult = 256; | ||
85 | |||
86 | aic_enable_i2s_bit_clock(false); | ||
87 | aic_set_i2s_clock(X1000_CLK_SCLK_A, sampr, mult); | ||
88 | aic_enable_i2s_bit_clock(true); | ||
89 | } | ||
90 | |||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/backlight-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/backlight-erosqnative.c new file mode 100644 index 0000000000..2c86a995db --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/backlight-erosqnative.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald, Dana Conrad | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "backlight.h" | ||
23 | #include "backlight-target.h" | ||
24 | #include "lcd.h" | ||
25 | #include "pwm-x1000.h" | ||
26 | |||
27 | #define BL_LCD_CHN 0 | ||
28 | #define BL_LCD_PERIOD 30000 | ||
29 | |||
30 | static int backlight_calc_duty(int period, int min_duty, int brightness) | ||
31 | { | ||
32 | return min_duty + (period - min_duty) * brightness / MAX_BRIGHTNESS_SETTING; | ||
33 | } | ||
34 | |||
35 | bool backlight_hw_init(void) | ||
36 | { | ||
37 | pwm_init(BL_LCD_CHN); | ||
38 | pwm_enable(BL_LCD_CHN); | ||
39 | backlight_hw_brightness(MAX_BRIGHTNESS_SETTING); | ||
40 | return true; | ||
41 | } | ||
42 | |||
43 | void backlight_hw_on(void) | ||
44 | { | ||
45 | pwm_enable(BL_LCD_CHN); | ||
46 | #ifdef HAVE_LCD_ENABLE | ||
47 | lcd_enable(true); | ||
48 | #endif | ||
49 | } | ||
50 | |||
51 | void backlight_hw_off(void) | ||
52 | { | ||
53 | pwm_disable(BL_LCD_CHN); | ||
54 | #ifdef HAVE_LCD_ENABLE | ||
55 | lcd_enable(false); | ||
56 | #endif | ||
57 | } | ||
58 | |||
59 | void backlight_hw_brightness(int brightness) | ||
60 | { | ||
61 | int duty_ns = backlight_calc_duty(BL_LCD_PERIOD, 0, brightness); | ||
62 | pwm_set_period(BL_LCD_CHN, BL_LCD_PERIOD, duty_ns); | ||
63 | } | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/backlight-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/backlight-target.h new file mode 100644 index 0000000000..05d6e36679 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/backlight-target.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald, Dana Conrad | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __BACKLIGHT_TARGET_H__ | ||
23 | #define __BACKLIGHT_TARGET_H__ | ||
24 | |||
25 | #include <stdbool.h> | ||
26 | |||
27 | extern bool backlight_hw_init(void); | ||
28 | |||
29 | extern void backlight_hw_on(void); | ||
30 | extern void backlight_hw_off(void); | ||
31 | extern void backlight_hw_brightness(int brightness); | ||
32 | |||
33 | #endif /* __BACKLIGHT_TARGET_H__ */ | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/boot.make b/firmware/target/mips/ingenic_x1000/erosqnative/boot.make new file mode 100644 index 0000000000..b6d0844cd0 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/boot.make | |||
@@ -0,0 +1,30 @@ | |||
1 | # __________ __ ___. | ||
2 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
3 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
4 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
5 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
6 | # \/ \/ \/ \/ \/ | ||
7 | # $Id$ | ||
8 | # | ||
9 | |||
10 | include $(ROOTDIR)/lib/microtar/microtar.make | ||
11 | |||
12 | .SECONDEXPANSION: | ||
13 | |||
14 | $(BUILDDIR)/spl.erosq: $(BUILDDIR)/spl.bin | ||
15 | $(call PRINTS,MKSPL $(@F))$(TOOLSDIR)/mkspl-x1000 -type=nand -ppb=2 -bpp=2 $< $@ | ||
16 | |||
17 | $(BUILDDIR)/bootloader.ucl: $(BUILDDIR)/bootloader.bin | ||
18 | $(call PRINTS,UCLPACK $(@F))$(TOOLSDIR)/uclpack --nrv2e -9 $< $@ >/dev/null | ||
19 | |||
20 | .PHONY: $(BUILDDIR)/bootloader-info.txt | ||
21 | $(BUILDDIR)/bootloader-info.txt: | ||
22 | $(call PRINTS,GEN $(@F))echo $(SVNVERSION) > $@ | ||
23 | |||
24 | $(BUILDDIR)/$(BINARY): $(BUILDDIR)/spl.erosq \ | ||
25 | $(BUILDDIR)/bootloader.ucl \ | ||
26 | $(BUILDDIR)/bootloader-info.txt | ||
27 | $(call PRINTS,TAR $(@F))tar -C $(BUILDDIR) \ | ||
28 | --numeric-owner --no-acls --no-xattrs --no-selinux \ | ||
29 | --mode=0644 --owner=0 --group=0 \ | ||
30 | -cf $@ $(call full_path_subst,$(BUILDDIR)/%,%,$^) | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c new file mode 100644 index 0000000000..1583db175a --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald, Dana Conrad | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "button.h" | ||
23 | #include "kernel.h" | ||
24 | #include "backlight.h" | ||
25 | #include "powermgmt.h" | ||
26 | #include "panic.h" | ||
27 | #include "axp-pmu.h" | ||
28 | #include "gpio-x1000.h" | ||
29 | #include "irq-x1000.h" | ||
30 | #include "i2c-x1000.h" | ||
31 | #include "eros_qn_codec.h" | ||
32 | #include <string.h> | ||
33 | #include <stdbool.h> | ||
34 | |||
35 | #ifndef BOOTLOADER | ||
36 | # include "lcd.h" | ||
37 | # include "font.h" | ||
38 | #endif | ||
39 | |||
40 | /* =========================================== | ||
41 | * | OLD STATE | NEW STATE | DIRECTION | | ||
42 | * | 0 0 | 0 0 | 0: NO CHANGE | | ||
43 | * | 0 0 | 0 1 | -1: CCW | | ||
44 | * | 0 0 | 1 0 | 1: CW | | ||
45 | * | 0 0 | 1 1 | 0: INVALID | | ||
46 | * | 0 1 | 0 0 | 1: CW | | ||
47 | * | 0 1 | 0 1 | 0: NO CHANGE | | ||
48 | * | 0 1 | 1 0 | 0: INVALID | | ||
49 | * | 0 1 | 1 1 | -1: CCW | | ||
50 | * | 1 0 | 0 0 | -1: CCW | | ||
51 | * | 1 0 | 0 1 | 0: INVALID | | ||
52 | * | 1 0 | 1 0 | 0: NO CHANGE | | ||
53 | * | 1 0 | 1 1 | 1: CW | | ||
54 | * | 1 1 | 0 0 | 0: INVALID | | ||
55 | * | 1 1 | 0 1 | 1: CW | | ||
56 | * | 1 1 | 1 0 | -1: CCW | | ||
57 | * | 1 1 | 1 1 | 0: NO CHANGE | | ||
58 | * =========================================== | ||
59 | * | ||
60 | * Quadrature explanation since it's not plainly obvious how this works: | ||
61 | * | ||
62 | * If either of the quadrature lines change, we can look up the combination | ||
63 | * of previous state and new state in the table above (enc_state[] below) | ||
64 | * and it tells us whether to add 1, subtract 1, or no change from the sum (enc_position). | ||
65 | * This also gives us a nice debounce, since each state can only have 1 pin change | ||
66 | * at a time. I didn't come up with this, but I've used it before and it works well. | ||
67 | * | ||
68 | * Old state is 2 higher bits, new state is 2 lower bits of enc_current_state. */ | ||
69 | |||
70 | /* list of valid quadrature states and their directions */ | ||
71 | signed char enc_state[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; | ||
72 | volatile unsigned char enc_current_state = 0; | ||
73 | volatile signed int enc_position = 0; | ||
74 | |||
75 | /* Value of headphone detect register */ | ||
76 | static uint8_t hp_detect_reg = 0x00; | ||
77 | static uint8_t hp_detect_reg_old = 0x00; | ||
78 | |||
79 | /* Interval to poll the register */ | ||
80 | #define HPD_POLL_TIME (HZ/2) | ||
81 | |||
82 | static int hp_detect_tmo_cb(struct timeout* tmo) | ||
83 | { | ||
84 | i2c_descriptor* d = (i2c_descriptor*)tmo->data; | ||
85 | i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d); | ||
86 | return HPD_POLL_TIME; | ||
87 | } | ||
88 | |||
89 | static void hp_detect_init(void) | ||
90 | { | ||
91 | static struct timeout tmo; | ||
92 | static const uint8_t gpio_reg = AXP192_REG_GPIOSTATE1; | ||
93 | static i2c_descriptor desc = { | ||
94 | .slave_addr = AXP_PMU_ADDR, | ||
95 | .bus_cond = I2C_START | I2C_STOP, | ||
96 | .tran_mode = I2C_READ, | ||
97 | .buffer[0] = (void*)&gpio_reg, | ||
98 | .count[0] = 1, | ||
99 | .buffer[1] = &hp_detect_reg, | ||
100 | .count[1] = 1, | ||
101 | .callback = NULL, | ||
102 | .arg = 0, | ||
103 | .next = NULL, | ||
104 | }; | ||
105 | |||
106 | /* Headphone and LO detects are wired to AXP192 GPIOs 0 and 1, | ||
107 | * set them to inputs. */ | ||
108 | i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO0FUNCTION, 0x01); /* HP detect */ | ||
109 | i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO1FUNCTION, 0x01); /* LO detect */ | ||
110 | |||
111 | /* Get an initial reading before startup */ | ||
112 | int r = i2c_reg_read1(AXP_PMU_BUS, AXP_PMU_ADDR, gpio_reg); | ||
113 | if(r >= 0) | ||
114 | { | ||
115 | hp_detect_reg = r; | ||
116 | hp_detect_reg_old = hp_detect_reg; | ||
117 | } | ||
118 | |||
119 | /* Poll the register every second */ | ||
120 | timeout_register(&tmo, &hp_detect_tmo_cb, HPD_POLL_TIME, (intptr_t)&desc); | ||
121 | } | ||
122 | |||
123 | bool headphones_inserted(void) | ||
124 | { | ||
125 | /* if the status has changed, set the output volume accordingly */ | ||
126 | if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) | ||
127 | { | ||
128 | hp_detect_reg_old = hp_detect_reg; | ||
129 | #if !defined(BOOTLOADER) | ||
130 | pcm5102_set_outputs(); | ||
131 | #endif | ||
132 | } | ||
133 | return hp_detect_reg & 0x10 ? false : true; | ||
134 | } | ||
135 | |||
136 | bool lineout_inserted(void) | ||
137 | { | ||
138 | /* if the status has changed, set the output volume accordingly */ | ||
139 | if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) | ||
140 | { | ||
141 | hp_detect_reg_old = hp_detect_reg; | ||
142 | #if !defined(BOOTLOADER) | ||
143 | pcm5102_set_outputs(); | ||
144 | #endif | ||
145 | } | ||
146 | return hp_detect_reg & 0x20 ? false : true; | ||
147 | } | ||
148 | |||
149 | /* Rockbox interface */ | ||
150 | void button_init_device(void) | ||
151 | { | ||
152 | /* set both quadrature lines to interrupts */ | ||
153 | gpio_set_function(GPIO_BTN_SCROLL_A, GPIOF_IRQ_EDGE(1)); | ||
154 | gpio_set_function(GPIO_BTN_SCROLL_B, GPIOF_IRQ_EDGE(1)); | ||
155 | |||
156 | /* set interrupts to fire on the next edge based on current state */ | ||
157 | gpio_flip_edge_irq(GPIO_BTN_SCROLL_A); | ||
158 | gpio_flip_edge_irq(GPIO_BTN_SCROLL_B); | ||
159 | |||
160 | /* get current state of both encoder gpios */ | ||
161 | enc_current_state = (REG_GPIO_PIN(GPIO_B)>>21) & 0x0c; | ||
162 | |||
163 | /* enable quadrature interrupts */ | ||
164 | gpio_enable_irq(GPIO_BTN_SCROLL_A); | ||
165 | gpio_enable_irq(GPIO_BTN_SCROLL_B); | ||
166 | |||
167 | /* Set up headphone and line out detect polling */ | ||
168 | hp_detect_init(); | ||
169 | } | ||
170 | |||
171 | /* wheel Quadrature line A interrupt */ | ||
172 | void GPIOB24(void) | ||
173 | { | ||
174 | /* fill state with previous (2 higher bits) and current (2 lower bits) */ | ||
175 | enc_current_state = (enc_current_state & 0x0c) | ((REG_GPIO_PIN(GPIO_B)>>23) & 0x03); | ||
176 | |||
177 | /* look up in table */ | ||
178 | enc_position = enc_position + enc_state[(enc_current_state)]; | ||
179 | |||
180 | /* move current state to previous state if valid data */ | ||
181 | if (enc_state[(enc_current_state)] != 0) | ||
182 | enc_current_state = (enc_current_state << 2); | ||
183 | |||
184 | /* we want the other edge next time */ | ||
185 | gpio_flip_edge_irq(GPIO_BTN_SCROLL_A); | ||
186 | } | ||
187 | |||
188 | /* wheel Quadrature line B interrupt */ | ||
189 | void GPIOB23(void) | ||
190 | { | ||
191 | /* fill state with previous (2 higher bits) and current (2 lower bits) */ | ||
192 | enc_current_state = (enc_current_state & 0x0c) | ((REG_GPIO_PIN(GPIO_B)>>23) & 0x03); | ||
193 | |||
194 | /* look up in table */ | ||
195 | enc_position = enc_position + enc_state[(enc_current_state)]; | ||
196 | |||
197 | /* move current state to previous state if valid data */ | ||
198 | if (enc_state[(enc_current_state)] != 0) | ||
199 | enc_current_state = (enc_current_state << 2); | ||
200 | |||
201 | /* we want the other edge next time */ | ||
202 | gpio_flip_edge_irq(GPIO_BTN_SCROLL_B); | ||
203 | } | ||
204 | |||
205 | int button_read_device(void) | ||
206 | { | ||
207 | int r = 0; | ||
208 | |||
209 | /* Read GPIOs for normal buttons */ | ||
210 | uint32_t a = REG_GPIO_PIN(GPIO_A); | ||
211 | uint32_t b = REG_GPIO_PIN(GPIO_B); | ||
212 | uint32_t c = REG_GPIO_PIN(GPIO_C); | ||
213 | uint32_t d = REG_GPIO_PIN(GPIO_D); | ||
214 | |||
215 | /* All buttons are active low */ | ||
216 | if((a & (1 << 16)) == 0) r |= BUTTON_PLAY; | ||
217 | if((a & (1 << 17)) == 0) r |= BUTTON_VOL_UP; | ||
218 | if((a & (1 << 19)) == 0) r |= BUTTON_VOL_DOWN; | ||
219 | |||
220 | if((b & (1 << 7)) == 0) r |= BUTTON_POWER; | ||
221 | if((b & (1 << 28)) == 0) r |= BUTTON_MENU; | ||
222 | if((b & (1 << 28)) == 0) r |= BUTTON_MENU; | ||
223 | |||
224 | if((d & (1 << 4)) == 0) r |= BUTTON_PREV; | ||
225 | |||
226 | if((d & (1 << 5)) == 0) r |= BUTTON_BACK; | ||
227 | if((c & (1 << 24)) == 0) r |= BUTTON_NEXT; | ||
228 | |||
229 | /* check encoder - from testing, each indent is 2 state changes or so */ | ||
230 | if (enc_position > 1) | ||
231 | { | ||
232 | /* need to use queue_post() in order to do BUTTON_SCROLL_*, | ||
233 | * Rockbox treats these buttons differently. */ | ||
234 | queue_post(&button_queue, BUTTON_SCROLL_FWD, 0); | ||
235 | enc_position = 0; | ||
236 | } | ||
237 | else if (enc_position < -1) | ||
238 | { | ||
239 | /* need to use queue_post() in order to do BUTTON_SCROLL_*, | ||
240 | * Rockbox treats these buttons differently. */ | ||
241 | queue_post(&button_queue, BUTTON_SCROLL_BACK, 0); | ||
242 | enc_position = 0; | ||
243 | } | ||
244 | |||
245 | return r; | ||
246 | } | ||
247 | |||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/button-target.h new file mode 100644 index 0000000000..9c39a40296 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-target.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2021 Solomon Peachy, Dana Conrad | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | #ifndef _BUTTON_TARGET_H_ | ||
21 | #define _BUTTON_TARGET_H_ | ||
22 | |||
23 | /* Main unit's buttons */ | ||
24 | #define BUTTON_POWER 0x00000001 | ||
25 | #define BUTTON_MENU 0x00000002 | ||
26 | #define BUTTON_BACK 0x00000004 | ||
27 | #define BUTTON_PLAY 0x00000008 | ||
28 | #define BUTTON_NEXT 0x00000010 | ||
29 | #define BUTTON_PREV 0x00000020 | ||
30 | #define BUTTON_VOL_UP 0x00000040 | ||
31 | #define BUTTON_VOL_DOWN 0x00000080 | ||
32 | #define BUTTON_SCROLL_BACK 0x00000100 | ||
33 | #define BUTTON_SCROLL_FWD 0x00000200 | ||
34 | |||
35 | #define BUTTON_MAIN (BUTTON_POWER | BUTTON_MENU | BUTTON_BACK | BUTTON_PREV | \ | ||
36 | BUTTON_NEXT | BUTTON_PLAY | BUTTON_VOL_UP | BUTTON_VOL_DOWN | BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD) | ||
37 | |||
38 | #define BUTTON_LEFT BUTTON_PREV | ||
39 | #define BUTTON_RIGHT BUTTON_NEXT | ||
40 | |||
41 | /* Software power-off */ | ||
42 | #define POWEROFF_BUTTON BUTTON_POWER | ||
43 | #define POWEROFF_COUNT 25 | ||
44 | |||
45 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h new file mode 100644 index 0000000000..376eae136e --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* -------------------- NOTES ------------------- */ | ||
2 | |||
3 | /* I don't think we have any devices on I2C1, the pins /may/ be reused. */ | ||
4 | /* DEFINE_PINGROUP(I2C1, GPIO_C, 3 << 26, GPIOF_DEVICE(0)) */ | ||
5 | |||
6 | /* OF has SD Card power listed as 0x2a - PB10, but it seems to work without. */ | ||
7 | |||
8 | /* I think BT power reg is pin 0x53 - C19 */ | ||
9 | |||
10 | /* USB_DETECT D3 chosen by trial-and-error. */ | ||
11 | |||
12 | /* I have a suspicion this isn't right for AXP_IRQ, | ||
13 | * and it's not used right now anyway. copied from m3k. */ | ||
14 | /* DEFINE_GPIO(AXP_IRQ, GPIO_PB(10), GPIOF_INPUT) */ | ||
15 | |||
16 | /* ---------------------------------------------- */ | ||
17 | |||
18 | /* Name Port Pins Function */ | ||
19 | DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1)) | ||
20 | DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1)) | ||
21 | DEFINE_PINGROUP(MSC0, GPIO_A, 0x3f << 20, GPIOF_DEVICE(1)) | ||
22 | DEFINE_PINGROUP(SFC, GPIO_A, 0x3f << 26, GPIOF_DEVICE(1)) | ||
23 | DEFINE_PINGROUP(I2S, GPIO_B, 0x1f << 0, GPIOF_DEVICE(1)) | ||
24 | DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1)) | ||
25 | |||
26 | /* Name Pin Function */ | ||
27 | /* mute DAC - 0 - mute, 1 - play. Affects both HP and LO. */ | ||
28 | DEFINE_GPIO(PCM5102A_XMIT, GPIO_PB(12), GPIOF_OUTPUT(0)) | ||
29 | |||
30 | /* mute HP amp, no effect on LO. 0 - mute, 1 - play */ | ||
31 | DEFINE_GPIO(MAX97220_SHDN, GPIO_PB(8), GPIOF_OUTPUT(0)) | ||
32 | |||
33 | /* mute audio mux, only affects Headphone out. | ||
34 | * 0 - play, 1 - mute */ | ||
35 | DEFINE_GPIO(ISL54405_MUTE, GPIO_PB(15), GPIOF_OUTPUT(1)) | ||
36 | |||
37 | /* switches HP on/off - 0 HP on, 1 hp off, has no effect on LO. | ||
38 | * As best I can tell, it switches HP Out sources between HP amp and something | ||
39 | * not implemented - there seem to be resistors missing. */ | ||
40 | DEFINE_GPIO(ISL54405_SEL, GPIO_PB(5), GPIOF_OUTPUT(0)) | ||
41 | |||
42 | /* DAC AVDD */ | ||
43 | DEFINE_GPIO(PCM5102A_ANALOG_PWR, GPIO_PB(9), GPIOF_OUTPUT(0)) | ||
44 | |||
45 | /* Headphone Amp power */ | ||
46 | DEFINE_GPIO(MAX97220_POWER, GPIO_PB(6), GPIOF_OUTPUT(0)) | ||
47 | |||
48 | /* SD card */ | ||
49 | DEFINE_GPIO(MSC0_CD, GPIO_PB(11), GPIOF_INPUT) | ||
50 | |||
51 | /* USB */ | ||
52 | DEFINE_GPIO(USB_DETECT, GPIO_PD(3), GPIOF_INPUT) | ||
53 | DEFINE_GPIO(USB_DRVVBUS, GPIO_PB(25), GPIOF_OUTPUT(0)) | ||
54 | |||
55 | /* LCD */ | ||
56 | DEFINE_GPIO(LCD_PWR, GPIO_PB(14), GPIOF_OUTPUT(0)) | ||
57 | DEFINE_GPIO(LCD_RESET, GPIO_PB(13), GPIOF_OUTPUT(0)) | ||
58 | DEFINE_GPIO(LCD_CE, GPIO_PB(18), GPIOF_OUTPUT(1)) | ||
59 | DEFINE_GPIO(LCD_RD, GPIO_PB(16), GPIOF_OUTPUT(1)) | ||
60 | |||
61 | /* Buttons */ | ||
62 | DEFINE_GPIO(BTN_PLAY, GPIO_PA(16), GPIOF_INPUT) | ||
63 | DEFINE_GPIO(BTN_VOL_UP, GPIO_PA(17), GPIOF_INPUT) | ||
64 | DEFINE_GPIO(BTN_VOL_DOWN, GPIO_PA(19), GPIOF_INPUT) | ||
65 | DEFINE_GPIO(BTN_POWER, GPIO_PB(7), GPIOF_INPUT) | ||
66 | DEFINE_GPIO(BTN_MENU, GPIO_PB(28), GPIOF_INPUT) | ||
67 | DEFINE_GPIO(BTN_BACK, GPIO_PD(5), GPIOF_INPUT) | ||
68 | DEFINE_GPIO(BTN_PREV, GPIO_PD(4), GPIOF_INPUT) | ||
69 | DEFINE_GPIO(BTN_NEXT, GPIO_PC(24), GPIOF_INPUT) | ||
70 | DEFINE_GPIO(BTN_SCROLL_A, GPIO_PB(24), GPIOF_INPUT) | ||
71 | DEFINE_GPIO(BTN_SCROLL_B, GPIO_PB(23), GPIOF_INPUT) | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h new file mode 100644 index 0000000000..8d0b8a6e20 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald, Dana Conrad | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __I2C_TARGET_H__ | ||
23 | #define __I2C_TARGET_H__ | ||
24 | |||
25 | #define I2C_ASYNC_BUS_COUNT 3 | ||
26 | #define I2C_ASYNC_QUEUE_SIZE 4 | ||
27 | |||
28 | #define AXP_PMU_BUS 2 | ||
29 | #define AXP_PMU_ADDR 0x34 | ||
30 | |||
31 | #endif /* __I2C_TARGET_H__ */ | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c new file mode 100644 index 0000000000..073bddb8b4 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c | |||
@@ -0,0 +1,188 @@ | |||
1 | |||
2 | /*************************************************************************** | ||
3 | * __________ __ ___. | ||
4 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
5 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
6 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
7 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
8 | * \/ \/ \/ \/ \/ | ||
9 | * $Id$ | ||
10 | * | ||
11 | * Copyright (C) 2021 Aidan MacDonald, Dana Conrad | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "lcd.h" | ||
24 | #include "kernel.h" | ||
25 | #include "lcd-x1000.h" | ||
26 | #include "gpio-x1000.h" | ||
27 | #include "system.h" | ||
28 | |||
29 | /* for reference on these command/data hex values, see the mipi dcs lcd spec. * | ||
30 | * Not everything here is there, but all the standard stuff is. */ | ||
31 | |||
32 | static const uint32_t erosqnative_lcd_cmd_enable[] = { | ||
33 | /* Set EXTC? */ | ||
34 | LCD_INSTR_CMD, 0xc8, | ||
35 | LCD_INSTR_DAT, 0xff, | ||
36 | LCD_INSTR_DAT, 0x93, | ||
37 | LCD_INSTR_DAT, 0x42, | ||
38 | /* Set Address Mode */ | ||
39 | LCD_INSTR_CMD, 0x36, | ||
40 | LCD_INSTR_DAT, 0xd8, | ||
41 | /* Pixel Format Set */ | ||
42 | LCD_INSTR_CMD, 0x3a, | ||
43 | //LCD_INSTR_DAT, 0x66, /* OF specified 18 bpp */ | ||
44 | LCD_INSTR_DAT, 0x05, /* RB seems to be happier dealing with 16 bits/pixel */ | ||
45 | /* Power Control 1? */ | ||
46 | LCD_INSTR_CMD, 0xc0, | ||
47 | LCD_INSTR_DAT, 0x15, | ||
48 | LCD_INSTR_DAT, 0x15, | ||
49 | /* Power Control 2? */ | ||
50 | LCD_INSTR_CMD, 0xc1, | ||
51 | LCD_INSTR_DAT, 0x01, | ||
52 | /* VCOM? */ | ||
53 | LCD_INSTR_CMD, 0xc5, | ||
54 | LCD_INSTR_DAT, 0xda, | ||
55 | /* ?? */ | ||
56 | LCD_INSTR_CMD, 0xb1, | ||
57 | LCD_INSTR_DAT, 0x00, | ||
58 | LCD_INSTR_DAT, 0x1b, | ||
59 | /* ?? */ | ||
60 | LCD_INSTR_CMD, 0xb4, | ||
61 | LCD_INSTR_DAT, 0x02, | ||
62 | /* Positive gamma correction? */ | ||
63 | LCD_INSTR_CMD, 0xe0, | ||
64 | LCD_INSTR_DAT, 0x0f, | ||
65 | LCD_INSTR_DAT, 0x13, | ||
66 | LCD_INSTR_DAT, 0x17, | ||
67 | LCD_INSTR_DAT, 0x04, | ||
68 | LCD_INSTR_DAT, 0x13, | ||
69 | LCD_INSTR_DAT, 0x07, | ||
70 | LCD_INSTR_DAT, 0x40, | ||
71 | LCD_INSTR_DAT, 0x39, | ||
72 | LCD_INSTR_DAT, 0x4f, | ||
73 | LCD_INSTR_DAT, 0x06, | ||
74 | LCD_INSTR_DAT, 0x0d, | ||
75 | LCD_INSTR_DAT, 0x0a, | ||
76 | LCD_INSTR_DAT, 0x1f, | ||
77 | LCD_INSTR_DAT, 0x22, | ||
78 | LCD_INSTR_DAT, 0x00, | ||
79 | /* Negative gamma correction? */ | ||
80 | LCD_INSTR_CMD, 0xe1, | ||
81 | LCD_INSTR_DAT, 0x00, | ||
82 | LCD_INSTR_DAT, 0x21, | ||
83 | LCD_INSTR_DAT, 0x24, | ||
84 | LCD_INSTR_DAT, 0x03, | ||
85 | LCD_INSTR_DAT, 0x0f, | ||
86 | LCD_INSTR_DAT, 0x05, | ||
87 | LCD_INSTR_DAT, 0x38, | ||
88 | LCD_INSTR_DAT, 0x32, | ||
89 | LCD_INSTR_DAT, 0x49, | ||
90 | LCD_INSTR_DAT, 0x00, | ||
91 | LCD_INSTR_DAT, 0x09, | ||
92 | LCD_INSTR_DAT, 0x08, | ||
93 | LCD_INSTR_DAT, 0x32, | ||
94 | LCD_INSTR_DAT, 0x35, | ||
95 | LCD_INSTR_DAT, 0x0f, | ||
96 | /* Exit Sleep */ | ||
97 | LCD_INSTR_CMD, 0x11, | ||
98 | LCD_INSTR_UDELAY, 120000, | ||
99 | /* Display On */ | ||
100 | LCD_INSTR_CMD, 0x29, | ||
101 | LCD_INSTR_UDELAY, 20000, | ||
102 | }; | ||
103 | |||
104 | /* sleep and wake copied directly from m3k */ | ||
105 | static const uint32_t erosqnative_lcd_cmd_sleep[] = { | ||
106 | /* Display OFF */ | ||
107 | LCD_INSTR_CMD, 0x28, | ||
108 | /* Sleep IN */ | ||
109 | LCD_INSTR_CMD, 0x10, | ||
110 | LCD_INSTR_UDELAY, 5000, | ||
111 | LCD_INSTR_END, | ||
112 | }; | ||
113 | |||
114 | static const uint32_t erosqnative_lcd_cmd_wake[] = { | ||
115 | /* Sleep OUT */ | ||
116 | LCD_INSTR_CMD, 0x11, | ||
117 | LCD_INSTR_UDELAY, 5000, | ||
118 | /* Display ON */ | ||
119 | LCD_INSTR_CMD, 0x29, | ||
120 | LCD_INSTR_END, | ||
121 | }; | ||
122 | |||
123 | /* As far as I can tell, this is a sequence of commands sent before each | ||
124 | * DMA set. Original in OF was: | ||
125 | * {0x2c, 0x2c, 0x2c, 0x2c} | ||
126 | * But this set from the m3k seems to work the same, and makes more sense | ||
127 | * to me: | ||
128 | * {0x00, 0x00, 0x00, 0x2c} | ||
129 | * This command is more than likely going to be the same | ||
130 | * for any old mipi lcd on the market, maybe. I really don't think we need | ||
131 | * to send "write_memory_start four times in a row. */ | ||
132 | static const uint8_t __attribute__((aligned(64))) | ||
133 | erosqnative_lcd_dma_wr_cmd[] = {0x2c, 0x2c, 0x2c, 0x2c}; | ||
134 | |||
135 | const struct lcd_tgt_config lcd_tgt_config = { | ||
136 | .bus_width = 8, | ||
137 | .cmd_width = 8, | ||
138 | .use_6800_mode = 0, | ||
139 | .use_serial = 0, | ||
140 | .clk_polarity = 0, | ||
141 | .dc_polarity = 0, | ||
142 | .wr_polarity = 1, | ||
143 | .te_enable = 0, /* OF had TE enabled (1) */ | ||
144 | .te_polarity = 1, | ||
145 | .te_narrow = 0, | ||
146 | .dma_wr_cmd_buf = &erosqnative_lcd_dma_wr_cmd, | ||
147 | .dma_wr_cmd_size = sizeof(erosqnative_lcd_dma_wr_cmd), | ||
148 | }; | ||
149 | |||
150 | void lcd_tgt_enable(bool enable) | ||
151 | { | ||
152 | if(enable) { | ||
153 | /* power up the panel */ | ||
154 | gpio_set_level(GPIO_LCD_PWR, 1); | ||
155 | mdelay(20); | ||
156 | gpio_set_level(GPIO_LCD_RESET, 1); | ||
157 | mdelay(12); | ||
158 | |||
159 | /* set the clock */ | ||
160 | lcd_set_clock(X1000_CLK_SCLK_A, 20000000); | ||
161 | |||
162 | /* toggle chip select low (active) */ | ||
163 | gpio_set_level(GPIO_LCD_RD, 1); | ||
164 | gpio_set_level(GPIO_LCD_CE, 1); | ||
165 | mdelay(5); | ||
166 | gpio_set_level(GPIO_LCD_CE, 0); | ||
167 | |||
168 | lcd_exec_commands(&erosqnative_lcd_cmd_enable[0]); | ||
169 | } else { | ||
170 | /* doesn't flash white if we don't do anything... */ | ||
171 | #if 0 | ||
172 | lcd_exec_commands(&erosqnative_lcd_cmd_sleep[0]); | ||
173 | |||
174 | mdelay(115); // copied from m3k | ||
175 | |||
176 | gpio_set_level(GPIO_LCD_PWR, 0); | ||
177 | gpio_set_level(GPIO_LCD_RESET, 0); | ||
178 | #endif | ||
179 | } | ||
180 | } | ||
181 | |||
182 | void lcd_tgt_sleep(bool sleep) | ||
183 | { | ||
184 | if(sleep) | ||
185 | lcd_exec_commands(&erosqnative_lcd_cmd_sleep[0]); | ||
186 | else | ||
187 | lcd_exec_commands(&erosqnative_lcd_cmd_wake[0]); | ||
188 | } | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c new file mode 100644 index 0000000000..c466db66b1 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald, Dana Conrad | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | // whole file copied from m3k | ||
23 | |||
24 | #include "power.h" | ||
25 | #include "adc.h" | ||
26 | #include "system.h" | ||
27 | #include "kernel.h" | ||
28 | #ifdef HAVE_USB_CHARGING_ENABLE | ||
29 | # include "usb_core.h" | ||
30 | #endif | ||
31 | #include "axp-pmu.h" | ||
32 | #include "i2c-x1000.h" | ||
33 | |||
34 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
35 | { | ||
36 | 3470 | ||
37 | }; | ||
38 | |||
39 | /* the OF shuts down at this voltage */ | ||
40 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
41 | { | ||
42 | 3400 | ||
43 | }; | ||
44 | |||
45 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
46 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
47 | { | ||
48 | { 3400, 3639, 3697, 3723, 3757, 3786, 3836, 3906, 3980, 4050, 4159 } | ||
49 | }; | ||
50 | |||
51 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
52 | const unsigned short percent_to_volt_charge[11] = | ||
53 | { | ||
54 | 3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196 | ||
55 | }; | ||
56 | |||
57 | void power_init(void) | ||
58 | { | ||
59 | /* Initialize driver */ | ||
60 | i2c_x1000_set_freq(2, I2C_FREQ_400K); | ||
61 | axp_init(); | ||
62 | |||
63 | /* Set lowest sample rate */ | ||
64 | axp_adc_set_rate(AXP_ADC_RATE_25HZ); | ||
65 | |||
66 | /* Ensure battery voltage ADC is enabled */ | ||
67 | int bits = axp_adc_get_enabled(); | ||
68 | bits |= (1 << ADC_BATTERY_VOLTAGE); | ||
69 | axp_adc_set_enabled(bits); | ||
70 | |||
71 | /* Turn on all power outputs */ | ||
72 | i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, | ||
73 | AXP_REG_PWROUTPUTCTRL2, 0, 0x5f, NULL); | ||
74 | i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, | ||
75 | AXP_REG_DCDCWORKINGMODE, 0, 0xc0, NULL); | ||
76 | |||
77 | /* Set the default charging current. This is the same as the | ||
78 | * OF's setting, although it's not strictly within the USB spec. */ | ||
79 | axp_set_charge_current(780); | ||
80 | |||
81 | /* Short delay to give power outputs time to stabilize */ | ||
82 | mdelay(5); | ||
83 | } | ||
84 | |||
85 | #ifdef HAVE_USB_CHARGING_ENABLE | ||
86 | void usb_charging_maxcurrent_change(int maxcurrent) | ||
87 | { | ||
88 | axp_set_charge_current(maxcurrent); | ||
89 | } | ||
90 | #endif | ||
91 | |||
92 | void adc_init(void) | ||
93 | { | ||
94 | } | ||
95 | |||
96 | void power_off(void) | ||
97 | { | ||
98 | axp_power_off(); | ||
99 | while(1); | ||
100 | } | ||
101 | |||
102 | bool charging_state(void) | ||
103 | { | ||
104 | return axp_battery_status() == AXP_BATT_CHARGING; | ||
105 | } | ||
106 | |||
107 | int _battery_voltage(void) | ||
108 | { | ||
109 | return axp_adc_read(ADC_BATTERY_VOLTAGE); | ||
110 | } | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c new file mode 100644 index 0000000000..9d7a1d118a --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "system.h" | ||
23 | #include "clk-x1000.h" | ||
24 | #include "spl-x1000.h" | ||
25 | #include "gpio-x1000.h" | ||
26 | |||
27 | /* TODO: get dual-boot working */ | ||
28 | |||
29 | const struct spl_boot_option spl_boot_options[] = { | ||
30 | [BOOT_OPTION_ROCKBOX] = { | ||
31 | .storage_addr = 0x6800, | ||
32 | .storage_size = 102 * 1024, | ||
33 | .load_addr = X1000_DRAM_BASE, | ||
34 | .exec_addr = X1000_DRAM_BASE, | ||
35 | .flags = BOOTFLAG_UCLPACK, | ||
36 | }, | ||
37 | }; | ||
38 | |||
39 | int spl_get_boot_option(void) | ||
40 | { | ||
41 | return BOOT_OPTION_ROCKBOX; | ||
42 | } | ||
43 | |||
44 | void spl_error(void) | ||
45 | { | ||
46 | const uint32_t pin = (1 << 25); | ||
47 | |||
48 | /* Turn on backlight */ | ||
49 | jz_clr(GPIO_INT(GPIO_C), pin); | ||
50 | jz_set(GPIO_MSK(GPIO_C), pin); | ||
51 | jz_clr(GPIO_PAT1(GPIO_C), pin); | ||
52 | jz_set(GPIO_PAT0(GPIO_C), pin); | ||
53 | |||
54 | while(1) { | ||
55 | /* Turn it off */ | ||
56 | mdelay(100); | ||
57 | jz_set(GPIO_PAT0(GPIO_C), pin); | ||
58 | |||
59 | /* Turn it on */ | ||
60 | mdelay(100); | ||
61 | jz_clr(GPIO_PAT0(GPIO_C), pin); | ||
62 | } | ||
63 | } | ||
diff --git a/firmware/target/mips/ingenic_x1000/lcd-x1000.c b/firmware/target/mips/ingenic_x1000/lcd-x1000.c index 193ff082e0..b66359a598 100644 --- a/firmware/target/mips/ingenic_x1000/lcd-x1000.c +++ b/firmware/target/mips/ingenic_x1000/lcd-x1000.c | |||
@@ -457,6 +457,10 @@ void lcd_update(void) | |||
457 | jz_writef(LCD_MCTRL, DMA_START(1), DMA_MODE(1)); | 457 | jz_writef(LCD_MCTRL, DMA_START(1), DMA_MODE(1)); |
458 | } | 458 | } |
459 | 459 | ||
460 | /* We can do partial updates even though the DMA doesn't seem to handle it well, | ||
461 | * due to the fact that this is actually putting it into a buffer, and then | ||
462 | * it gets transferred via DMA to a secondary buffer, which gets transferred in | ||
463 | * its entirety to the LCD through a different DMA process. */ | ||
460 | void lcd_update_rect(int x, int y, int width, int height) | 464 | void lcd_update_rect(int x, int y, int width, int height) |
461 | { | 465 | { |
462 | /* Clamp the coordinates */ | 466 | /* Clamp the coordinates */ |
diff --git a/firmware/target/mips/ingenic_x1000/msc-x1000.c b/firmware/target/mips/ingenic_x1000/msc-x1000.c index d0359a53e2..dbc1ebbe89 100644 --- a/firmware/target/mips/ingenic_x1000/msc-x1000.c +++ b/firmware/target/mips/ingenic_x1000/msc-x1000.c | |||
@@ -63,6 +63,16 @@ static const msc_config msc_configs[] = { | |||
63 | .cd_active_level = 0, | 63 | .cd_active_level = 0, |
64 | }, | 64 | }, |
65 | /* NOTE: SDIO wifi card is on msc1 */ | 65 | /* NOTE: SDIO wifi card is on msc1 */ |
66 | #elif defined(EROS_QN) | ||
67 | #define MSC_CLOCK_SOURCE X1000_CLK_SCLK_A | ||
68 | { | ||
69 | .msc_nr = 0, | ||
70 | .msc_type = MSC_TYPE_SD, | ||
71 | .bus_width = 4, | ||
72 | .label = "microSD", | ||
73 | .cd_gpio = GPIO_MSC0_CD, | ||
74 | .cd_active_level = 0, | ||
75 | }, | ||
66 | #else | 76 | #else |
67 | # error "Please add X1000 MSC config" | 77 | # error "Please add X1000 MSC config" |
68 | #endif | 78 | #endif |
diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.c b/firmware/target/mips/ingenic_x1000/nand-x1000.c index de6eb2fb67..a818ba10aa 100644 --- a/firmware/target/mips/ingenic_x1000/nand-x1000.c +++ b/firmware/target/mips/ingenic_x1000/nand-x1000.c | |||
@@ -58,7 +58,7 @@ | |||
58 | #define FREG_STATUS_ECC_UNCOR_ERR (2 << 4) | 58 | #define FREG_STATUS_ECC_UNCOR_ERR (2 << 4) |
59 | 59 | ||
60 | const nand_chip supported_nand_chips[] = { | 60 | const nand_chip supported_nand_chips[] = { |
61 | #if defined(FIIO_M3K) || defined(SHANLING_Q1) | 61 | #if defined(FIIO_M3K) || defined(SHANLING_Q1) || defined(EROS_QN) |
62 | { | 62 | { |
63 | /* ATO25D1GA */ | 63 | /* ATO25D1GA */ |
64 | .mf_id = 0x9b, | 64 | .mf_id = 0x9b, |
diff --git a/firmware/target/mips/ingenic_x1000/spl-x1000.c b/firmware/target/mips/ingenic_x1000/spl-x1000.c index 72dc53b2b7..afaf5a7dd6 100644 --- a/firmware/target/mips/ingenic_x1000/spl-x1000.c +++ b/firmware/target/mips/ingenic_x1000/spl-x1000.c | |||
@@ -38,6 +38,10 @@ | |||
38 | # define SPL_DDR_MEMORYSIZE 64 | 38 | # define SPL_DDR_MEMORYSIZE 64 |
39 | # define SPL_DDR_AUTOSR_EN 1 | 39 | # define SPL_DDR_AUTOSR_EN 1 |
40 | # define SPL_DDR_NEED_BYPASS 1 | 40 | # define SPL_DDR_NEED_BYPASS 1 |
41 | #elif defined(EROS_QN) | ||
42 | # define SPL_DDR_MEMORYSIZE 32 | ||
43 | # define SPL_DDR_AUTOSR_EN 1 | ||
44 | # define SPL_DDR_NEED_BYPASS 1 | ||
41 | #else | 45 | #else |
42 | # error "please define DRAM settings" | 46 | # error "please define DRAM settings" |
43 | #endif | 47 | #endif |
diff --git a/tools/configure b/tools/configure index f32c5d514d..eb3a971366 100755 --- a/tools/configure +++ b/tools/configure | |||
@@ -1598,7 +1598,7 @@ cat <<EOF | |||
1598 | ==FiiO== 229) NWZ-S750 series | 1598 | ==FiiO== 229) NWZ-S750 series |
1599 | ==AIGO== 244) M3K Linux | 1599 | ==AIGO== 244) M3K Linux |
1600 | 245) Eros Q / K 246) M3K baremetal ==Shanling== | 1600 | 245) Eros Q / K 246) M3K baremetal ==Shanling== |
1601 | 260) Q1 | 1601 | 247) Eros Q / K native 260) Q1 |
1602 | EOF | 1602 | EOF |
1603 | 1603 | ||
1604 | buildfor=`input`; | 1604 | buildfor=`input`; |
@@ -4133,6 +4133,30 @@ fi | |||
4133 | t_model="shanlingq1" | 4133 | t_model="shanlingq1" |
4134 | ;; | 4134 | ;; |
4135 | 4135 | ||
4136 | 247|erosqnative) | ||
4137 | target_id=116 | ||
4138 | modelname="erosqnative" | ||
4139 | target="EROS_QN" | ||
4140 | memory=32 | ||
4141 | mipsr2elcc | ||
4142 | appextra="recorder:gui" | ||
4143 | plugins="yes" | ||
4144 | tool="$rootdir/tools/scramble -add=erosqnative " | ||
4145 | boottool="" # not used | ||
4146 | output="rockbox.erosq" | ||
4147 | bootoutput="bootloader.erosq" | ||
4148 | sysfontbl="16-Terminus" | ||
4149 | # toolset is the tools within the tools directory that we build for | ||
4150 | # this particular target. | ||
4151 | toolset="$x1000tools" | ||
4152 | bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" | ||
4153 | bmp2rb_native="$rootdir/tools/bmp2rb -f 4" | ||
4154 | # architecture, manufacturer and model for the target-tree build | ||
4155 | t_cpu="mips" | ||
4156 | t_manufacturer="ingenic_x1000" | ||
4157 | t_model="erosqnative" | ||
4158 | ;; | ||
4159 | |||
4136 | *) | 4160 | *) |
4137 | echo "Please select a supported target platform!" | 4161 | echo "Please select a supported target platform!" |
4138 | exit 7 | 4162 | exit 7 |
diff --git a/tools/scramble.c b/tools/scramble.c index a75d6df528..ec79cb8ca2 100644 --- a/tools/scramble.c +++ b/tools/scramble.c | |||
@@ -335,6 +335,8 @@ int main (int argc, char** argv) | |||
335 | modelnum = 114; | 335 | modelnum = 114; |
336 | else if (!strcmp(&argv[1][5], "shq1")) /* Shanling Q1 */ | 336 | else if (!strcmp(&argv[1][5], "shq1")) /* Shanling Q1 */ |
337 | modelnum = 115; | 337 | modelnum = 115; |
338 | else if (!strcmp(&argv[1][5], "erosqnative")) /* Aigo Eros Q Native */ | ||
339 | modelnum = 116; | ||
338 | else { | 340 | else { |
339 | fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); | 341 | fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); |
340 | return 2; | 342 | return 2; |