A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

New port: Shanling Q1 native

- Audio playback works
- Touchscreen and buttons work
- Bootloader works and is capable of dual boot
- Plugins are working
- Cabbiev2 theme has been ported
- Stable for general usage

Thanks to Marc Aarts for porting Cabbiev2 and plugin bitmaps.

There's a few minor known issues:

- Bootloader must be installed manually using 'usbboot' as there is
no support in jztool yet.

- Keymaps may be lacking, need further testing and feedback.

- Some plugins may not be fully adapted to the screen size and could
benefit from further tweaking.

- LCD shows abnormal effects under some circumstances: for example,
after viewing a mostly black screen an afterimage appears briefly
when going back to a brightly-lit screen. Sudden power-off without
proper shutdown of the backlight causes a "dissolving" effect.

- CW2015 battery reporting driver is buggy, and disabled for now.
Battery reporting is currently voltage-based using the AXP192.

Change-Id: I635e83f02a880192c5a82cb0861ad3a61c137c3a

+2843 -15
+2
apps/SOURCES
··· 298 298 keymaps/keymap-fiiom3k.c 299 299 #elif CONFIG_KEYPAD == EROSQ_PAD 300 300 keymaps/keymap-erosq.c 301 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 302 + keymaps/keymap-shanlingq1.c 301 303 #endif
+6 -2
apps/features.txt
··· 182 182 #endif 183 183 184 184 /* This should be AUDIOHW_HAVE_FILTER_ROLL_OFF but that is only defined later */ 185 - #if defined(DX50) || defined(HAVE_DF1704_CODEC) || defined(HAVE_PCM1792_CODEC) || defined(HAVE_CS4398) || defined(HAVE_WM8740) || defined(HAVE_ES9018) || defined(HAVE_XDUOO_LINUX_CODEC) || defined(HAVE_FIIO_LINUX_CODEC) || defined(HAVE_AK4376) 185 + #if defined(DX50) || defined(HAVE_DF1704_CODEC) || defined(HAVE_PCM1792_CODEC) || defined(HAVE_CS4398) || defined(HAVE_WM8740) || defined(HAVE_ES9018) || defined(HAVE_XDUOO_LINUX_CODEC) || defined(HAVE_FIIO_LINUX_CODEC) || defined(HAVE_AK4376) || defined(HAVE_ES9218) 186 186 filter_roll_off 187 187 #endif 188 188 189 189 /* This should be AUDIOHW_HAVE_POWER_MODE but that is not defined yet */ 190 - #if defined(HAVE_AK4376) 190 + #if defined(HAVE_AK4376) || defined(HAVE_ES9218) 191 191 dac_power_mode 192 192 #endif 193 193 194 194 #if defined(HAVE_ES9018) 195 195 es9018 196 + #endif 197 + 198 + #if defined(HAVE_ES9218) 199 + es9218 196 200 #endif 197 201 198 202 /* These features are only used by the manual so they won't break binary
+77
apps/keymaps/keymap-shanlingq1.c
··· 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 + /* Button Code Definitions for Shanling Q1 target */ 23 + 24 + #include "config.h" 25 + #include "action.h" 26 + #include "button.h" 27 + #include "settings.h" 28 + 29 + /* {Action Code, Button code, Prereq button code } */ 30 + 31 + static const struct button_mapping button_context_standard[] = { 32 + {ACTION_STD_PREV, BUTTON_PREV, BUTTON_NONE}, 33 + {ACTION_STD_NEXT, BUTTON_NEXT, BUTTON_NONE}, 34 + {ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY}, 35 + {ACTION_STD_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_POWER}, 36 + LAST_ITEM_IN_LIST 37 + }; /* button_context_standard */ 38 + 39 + static const struct button_mapping button_context_wps[] = { 40 + {ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY}, 41 + {ACTION_WPS_STOP, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, 42 + {ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE}, 43 + {ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE}, 44 + {ACTION_WPS_SKIPNEXT, BUTTON_NEXT|BUTTON_REL, BUTTON_NEXT}, 45 + {ACTION_WPS_SKIPPREV, BUTTON_PREV|BUTTON_REL, BUTTON_PREV}, 46 + {ACTION_WPS_SEEKFWD, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE}, 47 + {ACTION_WPS_STOPSEEK, BUTTON_NEXT|BUTTON_REL, BUTTON_NEXT|BUTTON_REPEAT}, 48 + {ACTION_WPS_SEEKBACK, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE}, 49 + {ACTION_WPS_STOPSEEK, BUTTON_PREV|BUTTON_REL, BUTTON_PREV|BUTTON_REPEAT}, 50 + {ACTION_STD_KEYLOCK, BUTTON_POWER|BUTTON_REL, BUTTON_POWER}, 51 + LAST_ITEM_IN_LIST 52 + }; /* button_context_wps */ 53 + 54 + static const struct button_mapping button_context_list[] = { 55 + {ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE}, 56 + {ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE}, 57 + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) 58 + }; /* button_context_list */ 59 + 60 + const struct button_mapping* target_get_context_mapping(int context) 61 + { 62 + switch (context) 63 + { 64 + default: 65 + case CONTEXT_STD: 66 + return button_context_standard; 67 + case CONTEXT_WPS: 68 + return button_context_wps; 69 + case CONTEXT_TREE: 70 + case CONTEXT_CUSTOM|CONTEXT_TREE: 71 + case CONTEXT_MAINMENU: 72 + case CONTEXT_BOOKMARKSCREEN: 73 + //return button_context_tree; 74 + case CONTEXT_LIST: 75 + return button_context_list; 76 + } 77 + }
+145
apps/lang/english.lang
··· 12205 12205 </voice> 12206 12206 </phrase> 12207 12207 <phrase> 12208 + id: LANG_FILTER_LINEAR_FAST 12209 + desc: in sound settings 12210 + user: core 12211 + <source> 12212 + *: none 12213 + es9218: "Linear Fast" 12214 + </source> 12215 + <dest> 12216 + *: none 12217 + es9218: "Linear Fast" 12218 + </dest> 12219 + <voice> 12220 + *: none 12221 + es9218: "Linear Fast" 12222 + </voice> 12223 + </phrase> 12224 + <phrase> 12225 + id: LANG_FILTER_LINEAR_SLOW 12226 + desc: in sound settings 12227 + user: core 12228 + <source> 12229 + *: none 12230 + es9218: "Linear Slow" 12231 + </source> 12232 + <dest> 12233 + *: none 12234 + es9218: "Linear Slow" 12235 + </dest> 12236 + <voice> 12237 + *: none 12238 + es9218: "Linear Slow" 12239 + </voice> 12240 + </phrase> 12241 + <phrase> 12242 + id: LANG_FILTER_MINIMUM_FAST 12243 + desc: in sound settings 12244 + user: core 12245 + <source> 12246 + *: none 12247 + es9218: "Minimum Fast" 12248 + </source> 12249 + <dest> 12250 + *: none 12251 + es9218: "Minimum Fast" 12252 + </dest> 12253 + <voice> 12254 + *: none 12255 + es9218: "Minimum Fast" 12256 + </voice> 12257 + </phrase> 12258 + <phrase> 12259 + id: LANG_FILTER_MINIMUM_SLOW 12260 + desc: in sound settings 12261 + user: core 12262 + <source> 12263 + *: none 12264 + es9218: "Minimum Slow" 12265 + </source> 12266 + <dest> 12267 + *: none 12268 + es9218: "Minimum Slow" 12269 + </dest> 12270 + <voice> 12271 + *: none 12272 + es9218: "Minimum Slow" 12273 + </voice> 12274 + </phrase> 12275 + <phrase> 12276 + id: LANG_FILTER_APODIZING_1 12277 + desc: in sound settings 12278 + user: core 12279 + <source> 12280 + *: none 12281 + es9218: "Apodizing type 1" 12282 + </source> 12283 + <dest> 12284 + *: none 12285 + es9218: "Apodizing type 1" 12286 + </dest> 12287 + <voice> 12288 + *: none 12289 + es9218: "Apodizing type 1" 12290 + </voice> 12291 + </phrase> 12292 + <phrase> 12293 + id: LANG_FILTER_APODIZING_2 12294 + desc: in sound settings 12295 + user: core 12296 + <source> 12297 + *: none 12298 + es9218: "Apodizing type 2" 12299 + </source> 12300 + <dest> 12301 + *: none 12302 + es9218: "Apodizing type 2" 12303 + </dest> 12304 + <voice> 12305 + *: none 12306 + es9218: "Apodizing type 2" 12307 + </voice> 12308 + </phrase> 12309 + <phrase> 12310 + id: LANG_FILTER_HYBRID_FAST 12311 + desc: in sound settings 12312 + user: core 12313 + <source> 12314 + *: none 12315 + es9218: "Hybrid Fast" 12316 + </source> 12317 + <dest> 12318 + *: none 12319 + es9218: "Hybrid Fast" 12320 + </dest> 12321 + <voice> 12322 + *: none 12323 + es9218: "Hybrid Fast" 12324 + </voice> 12325 + </phrase> 12326 + <phrase> 12327 + id: LANG_FILTER_BRICK_WALL 12328 + desc: in sound settings 12329 + user: core 12330 + <source> 12331 + *: none 12332 + es9218: "Brick Wall" 12333 + </source> 12334 + <dest> 12335 + *: none 12336 + es9218: "Brick Wall" 12337 + </dest> 12338 + <voice> 12339 + *: none 12340 + es9218: "Brick Wall" 12341 + </voice> 12342 + </phrase> 12343 + <phrase> 12208 12344 id: LANG_DAC_POWER_MODE 12209 12345 desc: in sound settings 12210 12346 user: core 12211 12347 <source> 12212 12348 *: none 12213 12349 dac_power_mode: "DAC's power mode" 12350 + es9218: "DAC's output level" 12214 12351 </source> 12215 12352 <dest> 12216 12353 *: none 12217 12354 dac_power_mode: "DAC's power mode" 12355 + es9218: "DAC's output level" 12218 12356 </dest> 12219 12357 <voice> 12220 12358 *: none 12221 12359 dac_power_mode: "DAC's power mode" 12360 + es9218: "DAC's output level" 12222 12361 </voice> 12223 12362 </phrase> 12224 12363 <phrase> ··· 12228 12367 <source> 12229 12368 *: none 12230 12369 dac_power_mode: "High performance" 12370 + es9218: "High Gain (2 Vrms)" 12231 12371 </source> 12232 12372 <dest> 12233 12373 *: none 12234 12374 dac_power_mode: "High performance" 12375 + es9218: "High Gain (2 Vrms)" 12235 12376 </dest> 12236 12377 <voice> 12237 12378 *: none 12238 12379 dac_power_mode: "High performance" 12380 + es9218: "High Gain (2 Vrms)" 12239 12381 </voice> 12240 12382 </phrase> 12241 12383 <phrase> ··· 12245 12387 <source> 12246 12388 *: none 12247 12389 dac_power_mode: "Save battery" 12390 + es9218: "Low Gain (1 Vrms)" 12248 12391 </source> 12249 12392 <dest> 12250 12393 *: none 12251 12394 dac_power_mode: "Save battery" 12395 + es9218: "Low Gain (1 Vrms)" 12252 12396 </dest> 12253 12397 <voice> 12254 12398 *: none 12255 12399 dac_power_mode: "Save battery" 12400 + es9218: "Low Gain (1 Vrms)" 12256 12401 </voice> 12257 12402 </phrase> 12258 12403 <phrase>
+3
apps/plugins/battery_bench.c
··· 234 234 #define BATTERY_ON_TXT "Play" 235 235 #define BATTERY_OFF_TXT "Power" 236 236 237 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 238 + /* use touchscreen */ 239 + 237 240 #else 238 241 #error "No keymap defined!" 239 242 #endif
+2 -1
apps/plugins/bitmaps/mono/SOURCES
··· 19 19 ((LCD_WIDTH == 176) && (LCD_HEIGHT == 220)) 20 20 bubbles_bubble.220x176x1.bmp 21 21 #elif ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \ 22 - ((LCD_WIDTH == 240) && (LCD_HEIGHT >= 320)) 22 + ((LCD_WIDTH == 240) && (LCD_HEIGHT >= 320)) || \ 23 + ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) 23 24 bubbles_bubble.320x240x1.bmp 24 25 #elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \ 25 26 ((LCD_WIDTH == 480) && (LCD_HEIGHT == 640))
+20 -2
apps/plugins/bitmaps/native/SOURCES
··· 158 158 ((LCD_WIDTH >= 480) && (LCD_HEIGHT >= 640)) 159 159 bubbles_emblem.640x480x16.bmp 160 160 bubbles_background.640x480x16.bmp 161 + #elif (LCD_WIDTH >= 360) && (LCD_HEIGHT >= 400) 162 + bubbles_emblem.360x400x16.bmp 163 + bubbles_background.360x400x16.bmp 161 164 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 162 165 bubbles_emblem.320x240x16.bmp 163 166 bubbles_background.320x240x16.bmp ··· 388 391 invadrox_ufo.16x7x16.bmp 389 392 invadrox_ufo_explode.21x8x16.bmp 390 393 invadrox_numbers.50x7x16.bmp 391 - #if LCD_WIDTH == 320 394 + #if LCD_WIDTH == 360 && LCD_HEIGHT == 400 395 + invadrox_background.360x400x16.bmp 396 + #elif LCD_WIDTH == 320 392 397 invadrox_background.320x240x16.bmp 393 398 #elif LCD_WIDTH == 240 394 399 invadrox_background.240x320x16.bmp ··· 457 462 jewels.320x240x16.bmp 458 463 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) 459 464 jewels.320x240x16.bmp 465 + #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400) 466 + jewels.360x400x16.bmp 460 467 #elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \ 461 468 ((LCD_WIDTH == 480) && (LCD_HEIGHT == 640)) 462 469 jewels.640x480x16.bmp ··· 546 553 #if LCD_DEPTH >= 16 /* colour versions*/ 547 554 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480) 548 555 rockblox_background.640x480x16.bmp 556 + #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400) 557 + rockblox_background.360x400x16.bmp 549 558 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 550 559 rockblox_background.320x240x16.bmp 551 560 #elif (LCD_WIDTH == 240) && (LCD_HEIGHT >= 320) ··· 603 612 snake2_left.640x480x16.bmp 604 613 snake2_right.640x480x16.bmp 605 614 snake2_bottom.640x480x16.bmp 615 + #elif (LCD_WIDTH >= 360) && (LCD_HEIGHT >= 400) && (LCD_DEPTH >= 16) 616 + snake2_header1.360x400x16.bmp 617 + snake2_header2.360x400x16.bmp 618 + snake2_left.360x400x16.bmp 619 + snake2_right.360x400x16.bmp 620 + snake2_bottom.360x400x16.bmp 606 621 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) && (LCD_DEPTH >= 16) 607 622 snake2_header1.320x240x16.bmp 608 623 snake2_header2.320x240x16.bmp ··· 874 889 #elif (LCD_WIDTH == 320 && LCD_HEIGHT == 240) 875 890 superdom_boarditems.320x240x16.bmp 876 891 #elif ((LCD_WIDTH == 240) && (LCD_HEIGHT == 320)) || \ 877 - ((LCD_WIDTH == 240) && (LCD_HEIGHT == 400)) 892 + ((LCD_WIDTH == 240) && (LCD_HEIGHT == 400)) || \ 893 + ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) 878 894 superdom_boarditems.240x320x16.bmp 879 895 #elif (LCD_WIDTH == 480 && LCD_HEIGHT == 640) 880 896 superdom_boarditems.480x640x16.bmp ··· 911 927 sliding_puzzle.176x176x16.bmp 912 928 #elif SMALLER_DIMENSION <= 240 913 929 sliding_puzzle.240x240x16.bmp 930 + #elif SMALLER_DIMENSION <= 360 931 + sliding_puzzle.360x360x16.bmp 914 932 #elif SMALLER_DIMENSION <= 480 915 933 sliding_puzzle.480x480x16.bmp 916 934 #endif
apps/plugins/bitmaps/native/bubbles_background.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/bubbles_emblem.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/invadrox_background.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/jewels.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/rockblox_background.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/sliding_puzzle.360x360x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/snake2_bottom.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/snake2_header1.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/snake2_header2.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/snake2_left.360x400x16.bmp

This is a binary file and will not be displayed.

apps/plugins/bitmaps/native/snake2_right.360x400x16.bmp

This is a binary file and will not be displayed.

+4
apps/plugins/blackjack.c
··· 607 607 #define BJACK_RIGHT BUTTON_RIGHT 608 608 #define BJACK_LEFT BUTTON_LEFT 609 609 610 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 611 + #define BJACK_QUIT BUTTON_POWER 612 + #define BJACK_QUIT_NAME "QUIT" 613 + 610 614 #else 611 615 #error No keymap defined! 612 616 #endif
+3
apps/plugins/brickmania.c
··· 350 350 #define UP BUTTON_UP 351 351 #define DOWN BUTTON_DOWN 352 352 353 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 354 + #define QUIT BUTTON_POWER 355 + 353 356 #else 354 357 #error No keymap defined! 355 358 #endif
+11
apps/plugins/bubbles.c
··· 120 120 #define XOFS 128 121 121 #define MAX_FPS 40 122 122 123 + #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400) 124 + #define XOFS 86 125 + #define YOFS 100 126 + #define SCORE_TXT_X 28 127 + #define SCORE_TXT_WIDTH 32 128 + #define SCORE_TXT_Y 48 129 + #define LEVEL_TXT_X 27 130 + #define LEVEL_TXT_WIDTH 32 131 + #define LEVEL_TXT_Y 5 132 + #define MAX_FPS 40 133 + 123 134 /* 22x22 bubbles (iPod Video) */ 124 135 #elif (LCD_HEIGHT == 240) && (LCD_WIDTH == 320) 125 136 #define XOFS 72
+3
apps/plugins/calculator.c
··· 533 533 #define CALCULATOR_CALC BUTTON_MENU 534 534 #define CALCULATOR_CLEAR BUTTON_BACK 535 535 536 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 537 + #define CALCULATOR_QUIT BUTTON_POWER 538 + 536 539 #else 537 540 #error No keymap defined! 538 541 #endif
+3
apps/plugins/calendar.c
··· 421 421 #define CALENDAR_NEXT_MONTH BUTTON_VOL_UP 422 422 #define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN 423 423 424 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 425 + /* use touchscreen */ 426 + 424 427 #else 425 428 #error "No keypad setting." 426 429 #endif
+3
apps/plugins/chessbox/chessbox_pgn.h
··· 581 581 #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) 582 582 #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) 583 583 584 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 585 + /* use touchscreen */ 586 + 584 587 #else 585 588 #error No keymap defined! 586 589 #endif
+3
apps/plugins/chessclock.c
··· 395 395 #define CHC_SETTINGS_OK BUTTON_SELECT 396 396 #define CHC_SETTINGS_CANCEL BUTTON_POWER 397 397 398 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 399 + #define CHC_QUIT BUTTON_POWER 400 + 398 401 #else 399 402 #error No keymap defined! 400 403 #endif
+3
apps/plugins/chip8.c
··· 1291 1291 #define CHIP8_KEY6 BUTTON_RIGHT 1292 1292 #define CHIP8_KEY8 BUTTON_BACK 1293 1293 1294 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 1295 + /* use touchscreen */ 1296 + 1294 1297 #else 1295 1298 #error No keymap defined! 1296 1299 #endif
+3
apps/plugins/clix.c
··· 316 316 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT 317 317 #define CLIX_BUTTON_CLICK BUTTON_SELECT 318 318 319 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 320 + #define CLIX_BUTTON_QUIT BUTTON_POWER 321 + 319 322 #else 320 323 #error "no keymap" 321 324 #endif
+3
apps/plugins/cube.c
··· 400 400 #define CUBE_PAUSE BUTTON_PLAY 401 401 #define CUBE_HIGHSPEED BUTTON_BACK 402 402 403 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 404 + /* use touchscreen */ 405 + 403 406 #else 404 407 #error No keymap defined! 405 408 #endif
+4
apps/plugins/doom/i_video.c
··· 614 614 #define DOOMBUTTON_WEAPON BUTTON_VOL_UP 615 615 #define DOOMBUTTON_MAP BUTTON_VOL_DOWN 616 616 617 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 618 + #define DOOMBUTTON_ESC BUTTON_POWER 619 + #define DOOMBUTTON_MAP BUTTON_PREV 620 + 617 621 #else 618 622 #error Keymap not defined! 619 623 #endif
+3
apps/plugins/flipit.c
··· 496 496 #define FLIPIT_STEP_BY_STEP BUTTON_VOL_UP 497 497 #define FLIPIT_TOGGLE BUTTON_SELECT 498 498 499 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 500 + /* use touchscreen */ 501 + 499 502 #else 500 503 #error No keymap defined! 501 504 #endif
+3
apps/plugins/fractals/fractal.h
··· 504 504 #define FRACTAL_PRECISION_DEC BUTTON_BACK 505 505 #define FRACTAL_RESET BUTTON_PLAY 506 506 507 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 508 + #define FRACTAL_QUIT BUTTON_POWER 509 + 507 510 #else 508 511 #error No keymap defined! 509 512 #endif
+3
apps/plugins/imageviewer/imageviewer_button.h
··· 539 539 #define IMGVIEW_MENU BUTTON_POWER 540 540 #define IMGVIEW_SLIDE_SHOW BUTTON_PLAY 541 541 542 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 543 + /* use touchscreen */ 544 + 542 545 #else 543 546 #error No keymap defined! 544 547 #endif
+20
apps/plugins/invadrox.c
··· 296 296 #define RIGHT BUTTON_RIGHT 297 297 #define FIRE BUTTON_SELECT 298 298 299 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 300 + /* use touchscreen */ 301 + 299 302 #else 300 303 #error INVADROX: Unsupported keypad 301 304 #endif ··· 648 651 #define LIVES_X 8 649 652 #define MAX_Y 15 650 653 654 + #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400) 655 + 656 + /* Shanling Q1 657 + */ 658 + #define ARCADISH_GRAPHICS 659 + #define PLAYFIELD_X 32 660 + #define SHIP_Y (PLAYFIELD_Y - 3 * SHIP_HEIGHT) 661 + #define ALIEN_START_Y (UFO_Y + 3 * ALIEN_HEIGHT) 662 + /* Redefine SCORE_Y */ 663 + #undef SCORE_Y 664 + #define SCORE_Y 80 665 + #define SCORENUM_X (PLAYFIELD_X + NUMBERS_WIDTH) 666 + #define SCORENUM_Y SCORE_Y + (2 * (FONT_HEIGHT + 1) + 1) 667 + #define HISCORENUM_X (LCD_WIDTH - PLAYFIELD_X - 1 - 6 * NUMBERS_WIDTH - 5 * NUM_SPACING) 668 + #define SHIELD_Y (PLAYFIELD_Y - 6 * SHIP_HEIGHT) 669 + #define LIVES_X 10 670 + #define MAX_Y 18 651 671 652 672 #else 653 673 #error INVADROX: Unsupported LCD type
+3
apps/plugins/jewels.c
··· 377 377 #define HK_SELECT "SELECT" 378 378 #define HK_CANCEL "BACK" 379 379 380 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 381 + /* use touchscreen */ 382 + 380 383 #else 381 384 #error No keymap defined! 382 385 #endif
+11 -1
apps/plugins/lib/keymaps.h
··· 255 255 #define BTN_FIRE BUTTON_SELECT 256 256 #define BTN_PAUSE BUTTON_POWER 257 257 258 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 259 + #define BTN_FIRE BUTTON_CENTER 260 + #define BTN_PAUSE BUTTON_POWER 261 + #define BTN_HAVE_DIAGONAL 262 + #define BTN_DOWN_LEFT BUTTON_BOTTOMLEFT 263 + #define BTN_DOWN_RIGHT BUTTON_BOTTOMRIGHT 264 + #define BTN_UP_LEFT BUTTON_TOPLEFT 265 + #define BTN_UP_RIGHT BUTTON_TOPRIGHT 266 + 258 267 #else 259 268 #error Unsupported keypad 260 269 #endif ··· 272 281 #elif (CONFIG_KEYPAD != COWON_D2_PAD) && \ 273 282 (CONFIG_KEYPAD != DX50_PAD) && \ 274 283 (CONFIG_KEYPAD != ONDAVX777_PAD) && \ 275 - (CONFIG_KEYPAD != CREATIVE_ZENXFI2_PAD) 284 + (CONFIG_KEYPAD != CREATIVE_ZENXFI2_PAD) && \ 285 + (CONFIG_KEYPAD != SHANLING_Q1_PAD) 276 286 #define BTN_FIRE BUTTON_BOTTOMLEFT 277 287 #define BTN_PAUSE BUTTON_TOPLEFT 278 288 #endif
+2
apps/plugins/lib/pluginlib_actions.c
··· 499 499 {PLA_SELECT, BUTTON_SELECT, BUTTON_NONE}, 500 500 {PLA_SELECT_REL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT}, 501 501 {PLA_SELECT_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, 502 + #elif (CONFIG_KEYPAD == SHANLING_Q1_PAD) 503 + {PLA_EXIT, BUTTON_POWER, BUTTON_NONE}, 502 504 #else 503 505 # ifndef HAVE_TOUCHSCREEN 504 506 # error pluginlib_actions: No actions defined
+3
apps/plugins/midi/midiplay.c
··· 325 325 #define MIDI_VOL_DOWN BUTTON_VOL_DOWN 326 326 #define MIDI_PLAYPAUSE BUTTON_PLAY 327 327 328 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 329 + /* use touchscreen */ 330 + 328 331 #else 329 332 #error No keymap defined! 330 333 #endif
+3
apps/plugins/minesweeper.c
··· 443 443 # define MINESWP_DISCOVER (BUTTON_SELECT|BUTTON_REPEAT) 444 444 # define MINESWP_INFO BUTTON_MENU 445 445 446 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 447 + /* use touchscreen */ 448 + 446 449 #else 447 450 #error No keymap defined! 448 451 #endif
+3
apps/plugins/mp3_encoder.c
··· 2580 2580 #define MP3ENC_DONE BUTTON_POWER 2581 2581 #define MP3ENC_SELECT BUTTON_SELECT 2582 2582 2583 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 2584 + /* use touchscreen */ 2585 + 2583 2586 #else 2584 2587 #error No keymap defined! 2585 2588 #endif
+3
apps/plugins/mpegplayer/mpeg_settings.c
··· 354 354 #define MPEG_START_TIME_DOWN BUTTON_DOWN 355 355 #define MPEG_START_TIME_EXIT BUTTON_POWER 356 356 357 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 358 + #define MPEG_START_TIME_EXIT BUTTON_POWER 359 + 357 360 #else 358 361 #error No keymap defined! 359 362 #endif
+3
apps/plugins/mpegplayer/mpegplayer.c
··· 486 486 #define MPEG_RW BUTTON_LEFT 487 487 #define MPEG_FF BUTTON_RIGHT 488 488 489 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 490 + /* use touchscreen */ 491 + 489 492 #else 490 493 #error No keymap defined! 491 494 #endif
+3
apps/plugins/oscilloscope.c
··· 548 548 #define OSCILLOSCOPE_VOL_UP BUTTON_VOL_UP 549 549 #define OSCILLOSCOPE_VOL_DOWN BUTTON_VOL_DOWN 550 550 551 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 552 + /* use touchscreen */ 553 + 551 554 #else 552 555 #error No keymap defined! 553 556 #endif
+10
apps/plugins/pacbox/pacbox.h
··· 398 398 #define PACMAN_1UP BUTTON_VOL_UP 399 399 #define PACMAN_COIN BUTTON_PLAY 400 400 401 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 402 + #define PACMAN_UP BUTTON_TOPMIDDLE 403 + #define PACMAN_DOWN BUTTON_BOTTOMMIDDLE 404 + #define PACMAN_LEFT BUTTON_MIDLEFT 405 + #define PACMAN_RIGHT BUTTON_MIDRIGHT 406 + #define PACMAN_MENU BUTTON_TOPLEFT 407 + #define PACMAN_1UP BUTTON_BOTTOMLEFT 408 + #define PACMAN_2UP BUTTON_BOTTOMRIGHT 409 + #define PACMAN_COIN BUTTON_CENTER 410 + 401 411 #else 402 412 403 413 #error Keymap not defined!
+3
apps/plugins/pegbox.c
··· 711 711 #define LVL_UP_TEXT "VOL+" 712 712 #define LVL_DOWN_TEXT "VOL-" 713 713 714 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 715 + /* use touchscreen */ 716 + 714 717 #else 715 718 #error "Unsupported keymap!" 716 719 #endif
+3
apps/plugins/pong.c
··· 325 325 #define PONG_RIGHT_UP BUTTON_BACK 326 326 #define PONG_RIGHT_DOWN BUTTON_RIGHT 327 327 328 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 329 + /* use touchscreen */ 330 + 328 331 #else 329 332 #error No keymap defined! 330 333 #endif
+3
apps/plugins/reversi/reversi-gui.h
··· 361 361 #define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT 362 362 #define REVERSI_BUTTON_MENU BUTTON_MENU 363 363 364 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 365 + /* use touchscreen */ 366 + 364 367 #else 365 368 #error No keymap defined! 366 369 #endif
+19
apps/plugins/rockblox.c
··· 465 465 #define ROCKBLOX_DROP BUTTON_PLAY 466 466 #define ROCKBLOX_RESTART BUTTON_BACK 467 467 468 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 469 + /* use touchscreen */ 470 + 468 471 #else 469 472 #error No keymap defined! 470 473 #endif ··· 533 536 #define SCORE_Y 58 534 537 #define LEVEL_Y 142 535 538 #define LINES_Y 218 539 + 540 + #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400) 541 + 542 + #define BLOCK_WIDTH 19 543 + #define BLOCK_HEIGHT 19 544 + #define BOARD_X 27 545 + #define BOARD_Y 0 546 + #define LABEL_X 258 547 + #define SCORE_Y 40 548 + #define LEVEL_Y 92 549 + #define LINES_Y 140 550 + #define HIGH_LABEL_X 258 551 + #define HIGH_SCORE_Y 200 552 + #define HIGH_LEVEL_Y 258 553 + #define PREVIEW_X 258 554 + #define PREVIEW_Y 300 536 555 537 556 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) 538 557
+3
apps/plugins/rockboy/rockboy.c
··· 468 468 options.SELECT = BUTTON_VOL_UP; 469 469 options.MENU = BUTTON_POWER; 470 470 471 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 472 + /* use touchscreen */ 473 + 471 474 #else 472 475 #error No Keymap Defined! 473 476 #endif
+3
apps/plugins/rockpaint.c
··· 404 404 #define ROCKPAINT_LEFT BUTTON_LEFT 405 405 #define ROCKPAINT_RIGHT BUTTON_RIGHT 406 406 407 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 408 + /* use touchscreen */ 409 + 407 410 #else 408 411 #error "Please define keys for this keypad" 409 412 #endif
+3
apps/plugins/sliding_puzzle.c
··· 357 357 #define PUZZLE_SHUFFLE BUTTON_BACK 358 358 #define PUZZLE_PICTURE BUTTON_PLAY 359 359 360 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 361 + /* use touchscreen */ 362 + 360 363 #else 361 364 #error No keymap defined! 362 365 #endif
+3
apps/plugins/snake.c
··· 313 313 #define SNAKE_DOWN BUTTON_DOWN 314 314 #define SNAKE_PLAYPAUSE BUTTON_PLAY 315 315 316 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 317 + /* use touchscreen */ 318 + 316 319 #else 317 320 #error No keymap defined! 318 321 #endif
+15
apps/plugins/snake2.c
··· 62 62 #define TOP_X4 548 /* x-coord of the lowerright item (hi-score) */ 63 63 #define TOP_Y1 8 /* y-coord of the top row of items */ 64 64 #define TOP_Y2 50 /* y-coord of the bottom row of items */ 65 + #elif (LCD_WIDTH >= 360) && (LCD_HEIGHT >= 400) 66 + #define MULTIPLIER 12 /*Modifier for porting on other screens*/ 67 + #define MODIFIER_1 12 68 + #define MODIFIER_2 10 69 + #define CENTER_X 12 70 + #define CENTER_Y 40 71 + #define TOP_X1 34 /* x-coord of the upperleft item (game type) */ 72 + #define TOP_X2 320 /* x-coord of the upperright item (maze type) */ 73 + #define TOP_X3 42 /* x-coord of the lowerleft item (speed) */ 74 + #define TOP_X4 314 /* x-coord of the lowerright item (hi-score) */ 75 + #define TOP_Y1 4 /* y-coord of the top row of items */ 76 + #define TOP_Y2 25 /* y-coord of the bottom row of items */ 65 77 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 66 78 #define MULTIPLIER 10 /*Modifier for porting on other screens*/ 67 79 #define MODIFIER_1 10 ··· 445 457 #define SNAKE2_QUIT BUTTON_POWER 446 458 #define SNAKE2_PLAYPAUSE BUTTON_PLAY 447 459 #define SNAKE2_PLAYPAUSE_TEXT "PLAY" 460 + 461 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 462 + /* use touchscreen */ 448 463 449 464 #else 450 465 #error No keymap defined!
+3
apps/plugins/sokoban.c
··· 696 696 #define BUTTON_SAVE BUTTON_BACK 697 697 #define BUTTON_SAVE_NAME "BACK" 698 698 699 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 700 + /* use touchscreen */ 701 + 699 702 #else 700 703 #error No keymap defined! 701 704 #endif
+3
apps/plugins/solitaire.c
··· 741 741 # define HK_CUR2STACK "HOLD SELECT" 742 742 # define HK_REM2STACK "VOL+" 743 743 744 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 745 + # define SOL_QUIT BUTTON_POWER 746 + 744 747 #else 745 748 #error No keymap defined! 746 749 #endif
+3
apps/plugins/spacerocks.c
··· 372 372 #define AST_RIGHT BUTTON_RIGHT 373 373 #define AST_FIRE BUTTON_PLAY 374 374 375 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 376 + /* use touchscreen */ 377 + 375 378 #else 376 379 #error No keymap defined! 377 380 #endif
+4
apps/plugins/star.c
··· 668 668 #define STAR_LEVEL_DOWN_NAME "VOL-" 669 669 #define STAR_LEVEL_REPEAT_NAME "BACK" 670 670 671 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 672 + #define STAR_QUIT BUTTON_POWER 673 + #define STAR_QUIT_NAME "POWER" 674 + 671 675 #else 672 676 #error No keymap defined! 673 677 #endif
+1 -1
apps/plugins/stopwatch.lua
··· 280 280 end 281 281 end 282 282 283 - rb.touchscreen_set_mode(rb.TOUCHSCREEN_POINT) 283 + rb.touchscreen_mode(rb.TOUCHSCREEN_POINT) 284 284 285 285 LapsView:init() 286 286
+3
apps/plugins/sudoku/sudoku.h
··· 460 460 #define SUDOKU_BUTTON_MENU BUTTON_MENU 461 461 #define SUDOKU_BUTTON_POSSIBLE BUTTON_BACK 462 462 463 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 464 + /* use touchscreen */ 465 + 463 466 #else 464 467 #error No keymap defined! 465 468 #endif
+5
apps/plugins/test_touchscreen.c
··· 37 37 #elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD 38 38 #define TOUCHSCREEN_QUIT BUTTON_POWER 39 39 #define TOUCHSCREEN_TOGGLE BUTTON_MENU 40 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 41 + #define TOUCHSCREEN_QUIT BUTTON_POWER 42 + #define TOUCHSCREEN_TOGGLE BUTTON_PLAY 40 43 #elif (CONFIG_KEYPAD == ANDROID_PAD) 41 44 #define TOUCHSCREEN_QUIT BUTTON_BACK 42 45 #define TOUCHSCREEN_TOGGLE BUTTON_MENU 43 46 #elif (CONFIG_KEYPAD == SDL_PAD) 44 47 #define TOUCHSCREEN_QUIT BUTTON_MIDLEFT 45 48 #define TOUCHSCREEN_TOGGLE BUTTON_CENTER 49 + #else 50 + # error "No keymap defined!" 46 51 #endif 47 52 48 53 /* plugin entry point */
+3
apps/plugins/text_viewer/tv_button.h
··· 572 572 #define TV_LINE_DOWN BUTTON_SCROLL_FWD 573 573 #define TV_BOOKMARK BUTTON_PLAY 574 574 575 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 576 + #define TV_BOOKMARK BUTTON_PLAY 577 + 575 578 #else 576 579 #error No keymap defined! 577 580 #endif
+3
apps/plugins/vu_meter.c
··· 452 452 #define LABEL_MENU "MENU" 453 453 #define LABEL_VOLUME "VOL+/VOL-" 454 454 455 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 456 + /* use touchscreen */ 457 + 455 458 #else 456 459 #error No keymap defined! 457 460 #endif
+5 -1
apps/plugins/wormlet.c
··· 407 407 #define BTN_QUIT BUTTON_POWER 408 408 #define BTN_STOPRESET BUTTON_BACK 409 409 410 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 411 + /* use touchscreen */ 412 + 410 413 #else 411 414 #error No keymap defined! 412 415 #endif ··· 492 495 #define SPEED 4 493 496 #define MAX_WORM_SEGMENTS 512 494 497 #elif ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \ 495 - ((LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))) 498 + ((LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))) || \ 499 + ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) 496 500 #define FOOD_SIZE 7 497 501 #define ARGH_SIZE 8 498 502 #define SPEED 4
+3
apps/plugins/xobox.c
··· 351 351 #define DOWN BUTTON_DOWN 352 352 #define PAUSE BUTTON_PLAY 353 353 354 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 355 + /* use touchscreen */ 356 + 354 357 #else 355 358 #error "No keymap defined!" 356 359 #endif
+3
apps/plugins/zxbox/keymaps.h
··· 290 290 #define ZX_UP BUTTON_UP 291 291 #define ZX_DOWN BUTTON_DOWN 292 292 293 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 294 + /* use touchscreen */ 295 + 293 296 #else 294 297 #error Keymap not defined! 295 298
+9 -2
apps/settings_list.c
··· 242 242 #define DEFAULT_FONT_HEIGHT 12 243 243 #elif LCD_HEIGHT <= 320 244 244 #define DEFAULT_FONT_HEIGHT 15 245 + #elif defined(SHANLING_Q1) 246 + /* 16pt font looks pretty aliased & ugly */ 247 + #define DEFAULT_FONT_HEIGHT 18 245 248 #elif LCD_HEIGHT <= 400 246 249 #define DEFAULT_FONT_HEIGHT 16 247 250 #elif LCD_HEIGHT <= 480 && LCD_WIDTH < 800 ··· 261 264 #endif 262 265 263 266 #ifdef HAVE_LCD_COLOR 264 - #if DEFAULT_FONT_HEIGHT >= 31 267 + #if DEFAULT_FONT_HEIGHT >= 31 || defined(SHANLING_Q1) 265 268 #define DEFAULT_ICONSET "tango_icons.32x32" 266 269 #define DEFAULT_VIEWERS_ICONSET "tango_icons_viewers.32x32" 267 270 #elif DEFAULT_FONT_HEIGHT >= 23 ··· 848 851 849 852 #ifdef AUDIOHW_HAVE_FILTER_ROLL_OFF 850 853 CHOICE_SETTING(F_SOUNDSETTING, roll_off, LANG_FILTER_ROLL_OFF, 0, 851 - #if defined(AUDIOHW_HAVE_SHORT2_ROLL_OFF) 854 + #if defined(AUDIOHW_HAVE_ES9218_ROLL_OFF) 855 + "roll_off", "linear fast,linear slow,minimum fast,minimum slow,apodizing 1,apodizing 2,hybrid fast,brick wall", sound_set_filter_roll_off, 856 + 8, ID2P(LANG_FILTER_LINEAR_FAST), ID2P(LANG_FILTER_LINEAR_SLOW), ID2P(LANG_FILTER_MINIMUM_FAST), ID2P(LANG_FILTER_MINIMUM_SLOW), 857 + ID2P(LANG_FILTER_APODIZING_1), ID2P(LANG_FILTER_APODIZING_2), ID2P(LANG_FILTER_HYBRID_FAST), ID2P(LANG_FILTER_BRICK_WALL)), 858 + #elif defined(AUDIOHW_HAVE_SHORT2_ROLL_OFF) 852 859 "roll_off", "sharp,slow,short sharp,short slow", sound_set_filter_roll_off, 853 860 4, ID2P(LANG_FILTER_SHARP), ID2P(LANG_FILTER_SLOW), ID2P(LANG_FILTER_SHORT_SHARP), ID2P(LANG_FILTER_SHORT_SLOW)), 854 861 #elif defined(AUDIOHW_HAVE_SHORT_ROLL_OFF)
backdrops/cabbiev2.360x400x16.bmp

This is a binary file and will not be displayed.

+1 -1
bootloader/SOURCES
··· 89 89 #elif defined(SANSA_CONNECT) 90 90 sansaconnect.c 91 91 show_logo.c 92 - #elif defined(FIIO_M3K) 92 + #elif defined(FIIO_M3K) || defined(SHANLING_Q1) 93 93 x1000.c 94 94 #endif
+11
bootloader/x1000.c
··· 66 66 # define BL_SELECT_NAME "PLAY" 67 67 # define BL_QUIT_NAME "POWER" 68 68 # define BOOTBACKUP_FILE "/fiiom3k-boot.bin" 69 + #elif defined(SHANLING_Q1) 70 + # define BL_RECOVERY BUTTON_NEXT 71 + # define BL_UP BUTTON_PREV 72 + # define BL_DOWN BUTTON_NEXT 73 + # define BL_SELECT BUTTON_PLAY 74 + # define BL_QUIT BUTTON_POWER 75 + # define BL_UP_NAME "PREV" 76 + # define BL_DOWN_NAME "NEXT" 77 + # define BL_SELECT_NAME "PLAY" 78 + # define BL_QUIT_NAME "POWER" 79 + # define BOOTBACKUP_FILE "/shanlingq1-boot.bin" 69 80 #else 70 81 # error "Missing keymap!" 71 82 #endif
+1
docs/CREDITS
··· 706 706 Spencer Brennessel 707 707 Dana Conrad 708 708 Albert Song 709 + Marc Aarts 709 710 710 711 The libmad team 711 712 The wavpack team
+14
firmware/SOURCES
··· 503 503 drivers/audio/cs4398.c 504 504 #elif defined (HAVE_ES9018) 505 505 drivers/audio/es9018.c 506 + #elif defined (HAVE_ES9218) 507 + drivers/audio/es9218.c 506 508 #endif /* defined(HAVE_*) */ 507 509 #else /* PLATFORM_HOSTED */ 508 510 #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) ··· 1716 1718 target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c 1717 1719 #endif /* FIIO_M3K */ 1718 1720 1721 + #if defined(SHANLING_Q1) 1722 + target/mips/ingenic_x1000/shanlingq1/audiohw-shanlingq1.c 1723 + target/mips/ingenic_x1000/shanlingq1/backlight-shanlingq1.c 1724 + target/mips/ingenic_x1000/shanlingq1/button-shanlingq1.c 1725 + target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c 1726 + target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c 1727 + target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c 1728 + #endif /* SHANLING_Q1 */ 1729 + 1719 1730 #if defined(LYRE_PROTO1) 1720 1731 target/arm/at91sam/lyre_proto1/adc-lyre_proto1.c 1721 1732 target/arm/at91sam/lyre_proto1/backlight-lyre_proto1.c ··· 1947 1958 #endif 1948 1959 #ifdef HAVE_FT6x06 1949 1960 drivers/ft6x06.c 1961 + #endif 1962 + #ifdef HAVE_CW2015 1963 + drivers/cw2015.c 1950 1964 #endif 1951 1965 #endif 1952 1966
+226
firmware/drivers/audio/es9218.c
··· 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 "audiohw.h" 23 + #include "system.h" 24 + #include "i2c-async.h" 25 + 26 + struct es9218_state { 27 + enum es9218_clock_gear clk_gear; 28 + uint32_t fsr; 29 + uint32_t nco; 30 + }; 31 + 32 + static struct es9218_state es9218; 33 + 34 + void es9218_open(void) 35 + { 36 + /* Enable power supply */ 37 + es9218_set_power_pin(1); 38 + 39 + /* "Wiggle" reset pin to get the internal oscillator to stabilize. 40 + * This should also work if using an external powered oscillator, 41 + * although in that case it's unnecessary to do this dance. */ 42 + es9218_set_reset_pin(1); 43 + udelay(75); 44 + es9218_set_reset_pin(0); 45 + udelay(50); 46 + es9218_set_reset_pin(1); 47 + mdelay(2); 48 + 49 + /* Initialize driver state */ 50 + es9218.clk_gear = ES9218_CLK_GEAR_1; 51 + es9218.fsr = 0; 52 + es9218.nco = 0; 53 + } 54 + 55 + void es9218_close(void) 56 + { 57 + /* Turn off power supply */ 58 + es9218_set_power_pin(0); 59 + es9218_set_reset_pin(0); 60 + } 61 + 62 + static void recalc_nco(void) 63 + { 64 + /* nco * CLK * 65 + * fsr = --------- * 66 + * 2**32 */ 67 + 68 + uint32_t clk = es9218_get_mclk(); 69 + clk >>= (int)es9218.clk_gear; 70 + 71 + uint64_t nco64 = es9218.fsr; 72 + nco64 <<= 32; 73 + nco64 /= clk; 74 + 75 + /* let's just ignore overflow... */ 76 + uint32_t nco = nco64; 77 + if(nco != es9218.nco) { 78 + es9218.nco = nco; 79 + 80 + /* registers must be written in this order */ 81 + es9218_write(ES9218_REG_PROG_NCO_BIT0_7, (nco >> 0) & 0xff); 82 + es9218_write(ES9218_REG_PROG_NCO_BIT8_15, (nco >> 8) & 0xff); 83 + es9218_write(ES9218_REG_PROG_NCO_BIT16_23, (nco >> 16) & 0xff); 84 + es9218_write(ES9218_REG_PROG_NCO_BIT24_31, (nco >> 24) & 0xff); 85 + } 86 + } 87 + 88 + void es9218_set_clock_gear(enum es9218_clock_gear gear) 89 + { 90 + if(gear != es9218.clk_gear) { 91 + es9218.clk_gear = gear; 92 + es9218_update(ES9218_REG_SYSTEM, 0x0c, (uint8_t)(gear & 3) << 2); 93 + recalc_nco(); 94 + } 95 + } 96 + 97 + void es9218_set_nco_frequency(uint32_t fsr) 98 + { 99 + if(fsr != es9218.fsr) { 100 + es9218.fsr = fsr; 101 + recalc_nco(); 102 + } 103 + } 104 + 105 + void es9218_recompute_nco(void) 106 + { 107 + recalc_nco(); 108 + } 109 + 110 + void es9218_set_amp_mode(enum es9218_amp_mode mode) 111 + { 112 + es9218_update(ES9218_REG_AMP_CONFIG, 0x03, (uint8_t)mode & 3); 113 + } 114 + 115 + void es9218_set_amp_powered(bool en) 116 + { 117 + /* this doesn't seem to be necessary..? */ 118 + es9218_update(ES9218_REG_ANALOG_CTRL, 0x40, en ? 0x40 : 0x00); 119 + } 120 + 121 + void es9218_set_iface_role(enum es9218_iface_role role) 122 + { 123 + /* asrc is used to lock onto the incoming audio frequency and is 124 + * only used in aysnchronous slave mode. In synchronous operation, 125 + * including master mode, it can be disabled to save power. */ 126 + int asrc_en = (role == ES9218_IFACE_ROLE_SLAVE ? 1 : 0); 127 + int master_mode = (role == ES9218_IFACE_ROLE_MASTER ? 1 : 0); 128 + 129 + es9218_update(ES9218_REG_MASTER_MODE_CONFIG, 1 << 7, master_mode << 7); 130 + es9218_update(ES9218_REG_GENERAL_CONFIG, 1 << 7, asrc_en << 7); 131 + } 132 + 133 + void es9218_set_iface_format(enum es9218_iface_format fmt, 134 + enum es9218_iface_bits bits) 135 + { 136 + uint8_t val = 0; 137 + val |= ((uint8_t)bits & 3) << 6; 138 + val |= ((uint8_t)fmt & 3) << 4; 139 + /* keep low 4 bits zero -> use normal I2S mode, disable DSD mode */ 140 + es9218_write(ES9218_REG_INPUT_SEL, val); 141 + } 142 + 143 + static int dig_vol_to_hw(int x) 144 + { 145 + x = MIN(x, ES9218_DIG_VOLUME_MAX); 146 + x = MAX(x, ES9218_DIG_VOLUME_MIN); 147 + return 0xff - (x - ES9218_DIG_VOLUME_MIN) / ES9218_DIG_VOLUME_STEP; 148 + } 149 + 150 + static int amp_vol_to_hw(int x) 151 + { 152 + x = MIN(x, ES9218_AMP_VOLUME_MAX); 153 + x = MAX(x, ES9218_AMP_VOLUME_MIN); 154 + return 24 - (x - ES9218_AMP_VOLUME_MIN) / ES9218_AMP_VOLUME_STEP; 155 + } 156 + 157 + void es9218_set_dig_volume(int vol_l, int vol_r) 158 + { 159 + es9218_write(ES9218_REG_VOLUME_LEFT, dig_vol_to_hw(vol_l)); 160 + es9218_write(ES9218_REG_VOLUME_RIGHT, dig_vol_to_hw(vol_r)); 161 + } 162 + 163 + void es9218_set_amp_volume(int vol) 164 + { 165 + es9218_update(ES9218_REG_ANALOG_VOL, 0x1f, amp_vol_to_hw(vol)); 166 + } 167 + 168 + void es9218_mute(bool en) 169 + { 170 + es9218_update(ES9218_REG_FILTER_SYS_MUTE, 1, en ? 1 : 0); 171 + } 172 + 173 + void es9218_set_filter(enum es9218_filter_type filt) 174 + { 175 + es9218_update(ES9218_REG_FILTER_SYS_MUTE, 0xe0, ((int)filt & 7) << 5); 176 + } 177 + 178 + void es9218_set_automute_time(int time) 179 + { 180 + if(time < 0) time = 0; 181 + if(time > 255) time = 255; 182 + es9218_write(ES9218_REG_AUTOMUTE_TIME, time); 183 + } 184 + 185 + void es9218_set_automute_level(int dB) 186 + { 187 + es9218_update(ES9218_REG_AUTOMUTE_LEVEL, 0x7f, dB); 188 + } 189 + 190 + void es9218_set_automute_fast_mode(bool en) 191 + { 192 + es9218_update(ES9218_REG_MIX_AUTOMUTE, 0x10, en ? 0x10 : 0x00); 193 + } 194 + 195 + void es9218_set_dpll_bandwidth(int knob) 196 + { 197 + es9218_update(ES9218_REG_ASRC_DPLL_BANDWIDTH, 0xf0, (knob & 0xf) << 4); 198 + } 199 + 200 + void es9218_set_thd_compensation(bool en) 201 + { 202 + es9218_update(ES9218_REG_THD_COMP_BYPASS, 0x40, en ? 0x40 : 0); 203 + } 204 + 205 + void es9218_set_thd_coeffs(uint16_t c2, uint16_t c3) 206 + { 207 + es9218_write(ES9218_REG_THD_COMP_C2_LO, c2 & 0xff); 208 + es9218_write(ES9218_REG_THD_COMP_C2_HI, (c2 >> 8) & 0xff); 209 + es9218_write(ES9218_REG_THD_COMP_C3_LO, c3 & 0xff); 210 + es9218_write(ES9218_REG_THD_COMP_C3_HI, (c3 >> 8) & 0xff); 211 + } 212 + 213 + int es9218_read(int reg) 214 + { 215 + return i2c_reg_read1(ES9218_BUS, ES9218_ADDR, reg); 216 + } 217 + 218 + void es9218_write(int reg, uint8_t val) 219 + { 220 + i2c_reg_write1(ES9218_BUS, ES9218_ADDR, reg, val); 221 + } 222 + 223 + void es9218_update(int reg, uint8_t msk, uint8_t val) 224 + { 225 + i2c_reg_modify1(ES9218_BUS, ES9218_ADDR, reg, msk, val, NULL); 226 + }
+191
firmware/drivers/cw2015.c
··· 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 "cw2015.h" 23 + #include "i2c-async.h" 24 + #include <string.h> 25 + #include "system.h" 26 + 27 + /* Headers for the debug menu */ 28 + #ifndef BOOTLOADER 29 + # include "action.h" 30 + # include "list.h" 31 + # include <stdio.h> 32 + #endif 33 + 34 + /* Battery profile info is an opaque blob. According to this, 35 + * https://lore.kernel.org/linux-pm/20200503154855.duwj2djgqfiyleq5@earth.universe/T/#u 36 + * the blob only comes from Cellwise testing a physical battery and cannot be 37 + * obtained any other way. It's specific to a given battery so each target has 38 + * its own profile. 39 + * 40 + * Profile data seems to be retained on the chip so it's not a hard requirement 41 + * to define this. Provided you don't lose power in the meantime, it should be 42 + * enough to just boot the OF, then boot Rockbox and read out the battery info 43 + * from the CW2015 debug screen. 44 + */ 45 + #if defined(SHANLING_Q1) 46 + static const uint8_t device_batinfo[CW2015_SIZE_BATINFO] = { 47 + 0x15, 0x7E, 0x61, 0x59, 0x57, 0x55, 0x56, 0x4C, 48 + 0x4E, 0x4D, 0x50, 0x4C, 0x45, 0x3A, 0x2D, 0x27, 49 + 0x22, 0x1E, 0x19, 0x1E, 0x2A, 0x3C, 0x48, 0x45, 50 + 0x1D, 0x94, 0x08, 0xF6, 0x15, 0x29, 0x48, 0x51, 51 + 0x5D, 0x60, 0x63, 0x66, 0x45, 0x1D, 0x83, 0x38, 52 + 0x09, 0x43, 0x16, 0x42, 0x76, 0x98, 0xA5, 0x1B, 53 + 0x41, 0x76, 0x99, 0xBF, 0x80, 0xC0, 0xEF, 0xCB, 54 + 0x2F, 0x00, 0x64, 0xA5, 0xB5, 0x0E, 0x30, 0x29, 55 + }; 56 + #else 57 + # define NO_BATINFO 58 + #endif 59 + 60 + static uint8_t chip_batinfo[CW2015_SIZE_BATINFO]; 61 + 62 + /* TODO: Finish implementing this 63 + * 64 + * Although this chip might give a better battery estimate than voltage does, 65 + * the mainline linux driver has a lot of weird hacks due to oddities like the 66 + * SoC getting stuck during charging, and from limited testing it seems this 67 + * may occur for the Q1 too. 68 + */ 69 + 70 + static int cw2015_read_bat_info(uint8_t* data) 71 + { 72 + for(int i = 0; i < CW2015_SIZE_BATINFO; ++i) { 73 + int r = i2c_reg_read1(CW2015_BUS, CW2015_ADDR, CW2015_REG_BATINFO + i); 74 + if(r < 0) 75 + return r; 76 + 77 + data[i] = r & 0xff; 78 + } 79 + 80 + return 0; 81 + } 82 + 83 + void cw2015_init(void) 84 + { 85 + /* mdelay(100); */ 86 + int rc = cw2015_read_bat_info(&chip_batinfo[0]); 87 + if(rc < 0) 88 + memset(chip_batinfo, 0, sizeof(chip_batinfo)); 89 + } 90 + 91 + int cw2015_get_vcell(void) 92 + { 93 + int vcell_msb = i2c_reg_read1(CW2015_BUS, CW2015_ADDR, CW2015_REG_VCELL); 94 + int vcell_lsb = i2c_reg_read1(CW2015_BUS, CW2015_ADDR, CW2015_REG_VCELL+1); 95 + 96 + if(vcell_msb < 0 || vcell_lsb < 0) 97 + return -1; 98 + 99 + /* 14 bits, resolution 305 uV */ 100 + int v_raw = ((vcell_msb & 0x3f) << 8) | vcell_lsb; 101 + return v_raw * 61 / 200; 102 + } 103 + 104 + int cw2015_get_soc(void) 105 + { 106 + int soc_msb = i2c_reg_read1(CW2015_BUS, CW2015_ADDR, CW2015_REG_SOC); 107 + 108 + if(soc_msb < 0) 109 + return -1; 110 + 111 + /* MSB is the state of charge in percentage. 112 + * the LSB contains fractional information not useful to Rockbox. */ 113 + return soc_msb & 0xff; 114 + } 115 + 116 + int cw2015_get_rrt(void) 117 + { 118 + int rrt_msb = i2c_reg_read1(CW2015_BUS, CW2015_ADDR, CW2015_REG_RRT_ALERT); 119 + int rrt_lsb = i2c_reg_read1(CW2015_BUS, CW2015_ADDR, CW2015_REG_RRT_ALERT+1); 120 + 121 + if(rrt_msb < 0 || rrt_lsb < 0) 122 + return -1; 123 + 124 + /* 13 bits, resolution 1 minute */ 125 + return ((rrt_msb & 0x1f) << 8) | rrt_lsb; 126 + } 127 + 128 + const uint8_t* cw2015_get_bat_info(void) 129 + { 130 + return &chip_batinfo[0]; 131 + } 132 + 133 + #ifndef BOOTLOADER 134 + enum { 135 + CW2015_DEBUG_VCELL = 0, 136 + CW2015_DEBUG_SOC, 137 + CW2015_DEBUG_RRT, 138 + CW2015_DEBUG_BATINFO, 139 + CW2015_DEBUG_BATINFO_LAST = CW2015_DEBUG_BATINFO + 7, 140 + CW2015_DEBUG_NUM_ENTRIES, 141 + }; 142 + 143 + static int cw2015_debug_menu_cb(int action, struct gui_synclist* lists) 144 + { 145 + (void)lists; 146 + 147 + if(action == ACTION_NONE) 148 + action = ACTION_REDRAW; 149 + 150 + return action; 151 + } 152 + 153 + static const char* cw2015_debug_menu_get_name(int item, void* data, 154 + char* buf, size_t buflen) 155 + { 156 + (void)data; 157 + 158 + /* hexdump of battery info */ 159 + if(item >= CW2015_DEBUG_BATINFO && item <= CW2015_DEBUG_BATINFO_LAST) { 160 + int i = item - CW2015_DEBUG_BATINFO; 161 + const uint8_t* batinfo = cw2015_get_bat_info(); 162 + snprintf(buf, buflen, "BatInfo%d: %02x %02x %02x %02x %02x %02x %02x %02x", i, 163 + batinfo[8*i + 0], batinfo[8*i + 1], batinfo[8*i + 2], batinfo[8*i + 3], 164 + batinfo[8*i + 4], batinfo[8*i + 5], batinfo[8*i + 6], batinfo[8*i + 7]); 165 + return buf; 166 + } 167 + 168 + switch(item) { 169 + case CW2015_DEBUG_VCELL: 170 + snprintf(buf, buflen, "VCell: %d mV", cw2015_get_vcell()); 171 + return buf; 172 + case CW2015_DEBUG_SOC: 173 + snprintf(buf, buflen, "SOC: %d%%", cw2015_get_soc()); 174 + return buf; 175 + case CW2015_DEBUG_RRT: 176 + snprintf(buf, buflen, "Runtime: %d min", cw2015_get_rrt()); 177 + return buf; 178 + default: 179 + return "---"; 180 + } 181 + } 182 + 183 + bool cw2015_debug_menu(void) 184 + { 185 + struct simplelist_info info; 186 + simplelist_info_init(&info, "CW2015 debug", CW2015_DEBUG_NUM_ENTRIES, NULL); 187 + info.action_callback = cw2015_debug_menu_cb; 188 + info.get_name = cw2015_debug_menu_get_name; 189 + return simplelist_show_list(&info); 190 + } 191 + #endif
+2
firmware/export/audiohw.h
··· 216 216 #include "cs4398.h" 217 217 #elif defined(HAVE_ES9018) 218 218 #include "es9018.h" 219 + #elif defined(HAVE_ES9218) 220 + #include "es9218.h" 219 221 #elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO \ 220 222 | PLATFORM_PANDORA | PLATFORM_SDL)) 221 223 #include "hosted_codec.h"
+4
firmware/export/config.h
··· 160 160 #define FIIO_M3K_LINUX_PAD 71 161 161 #define EROSQ_PAD 72 162 162 #define FIIO_M3K_PAD 73 163 + #define SHANLING_Q1_PAD 74 163 164 164 165 /* CONFIG_REMOTE_KEYPAD */ 165 166 #define H100_REMOTE 1 ··· 274 275 #define LCD_IHIFI770C 67 /* as used by IHIFI 770C */ 275 276 #define LCD_IHIFI800 68 /* as used by IHIFI 800 */ 276 277 #define LCD_FIIOM3K 69 /* as used by the FiiO M3K */ 278 + #define LCD_SHANLING_Q1 70 /* as used by the Shanling Q1 */ 277 279 278 280 /* LCD_PIXELFORMAT */ 279 281 #define HORIZONTAL_PACKING 1 ··· 592 594 #include "config/fiiom3k.h" 593 595 #elif defined(EROS_Q) 594 596 #include "config/aigoerosq.h" 597 + #elif defined(SHANLING_Q1) 598 + #include "config/shanlingq1.h" 595 599 #else 596 600 //#error "unknown hwardware platform!" 597 601 #endif
+119
firmware/export/config/shanlingq1.h
··· 1 + /* RoLo-related defines */ 2 + #define MODEL_NAME "Shanling Q1" 3 + #define MODEL_NUMBER 115 4 + #define BOOTFILE_EXT "q1" 5 + #define BOOTFILE "rockbox." BOOTFILE_EXT 6 + #define BOOTDIR "/.rockbox" 7 + #define FIRMWARE_OFFSET_FILE_CRC 0 8 + #define FIRMWARE_OFFSET_FILE_DATA 8 9 + 10 + /* CPU defines */ 11 + #define CONFIG_CPU X1000 12 + #define X1000_EXCLK_FREQ 24000000 13 + #define CPU_FREQ 1008000000 14 + 15 + #ifndef SIMULATOR 16 + #define TIMER_FREQ X1000_EXCLK_FREQ 17 + #endif 18 + 19 + /* Kernel defines */ 20 + #define INCLUDE_TIMEOUT_API 21 + #define HAVE_SEMAPHORE_OBJECTS 22 + 23 + /* Drivers */ 24 + #define HAVE_I2C_ASYNC 25 + 26 + /* Buffer for plugins and codecs. */ 27 + #define PLUGIN_BUFFER_SIZE 0x200000 /* 2 MiB */ 28 + #define CODEC_SIZE 0x100000 /* 1 MiB */ 29 + 30 + /* LCD defines */ 31 + #define CONFIG_LCD LCD_SHANLING_Q1 32 + #define LCD_WIDTH 360 33 + #define LCD_HEIGHT 400 34 + #define LCD_DEPTH 16 35 + #define LCD_PIXELFORMAT RGB565 36 + #define LCD_DPI 200 37 + #define HAVE_LCD_COLOR 38 + #define HAVE_LCD_BITMAP 39 + #define HAVE_LCD_ENABLE 40 + #define LCD_X1000_FASTSLEEP 41 + #define LCD_X1000_DMA_WAIT_FOR_FRAME 42 + 43 + /* Backlight defines */ 44 + #define HAVE_BACKLIGHT 45 + #define HAVE_BACKLIGHT_BRIGHTNESS 46 + #define MIN_BRIGHTNESS_SETTING 1 47 + #define MAX_BRIGHTNESS_SETTING 100 48 + #define BRIGHTNESS_STEP 5 49 + #define DEFAULT_BRIGHTNESS_SETTING 70 50 + #define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING 51 + 52 + /* Codec / audio hardware defines */ 53 + #define HW_SAMPR_CAPS SAMPR_CAP_ALL_192 54 + #define HAVE_ES9218 55 + #define HAVE_SW_TONE_CONTROLS 56 + 57 + /* Button defines */ 58 + #define CONFIG_KEYPAD SHANLING_Q1_PAD 59 + #define HAVE_TOUCHSCREEN 60 + #define HAVE_BUTTON_DATA 61 + #define HAVE_FT6x06 62 + #define HAVE_HEADPHONE_DETECTION 63 + 64 + /* Storage defines */ 65 + #define CONFIG_STORAGE STORAGE_SD 66 + #define HAVE_HOTSWAP 67 + #define HAVE_HOTSWAP_STORAGE_AS_MAIN 68 + #define HAVE_MULTIDRIVE 69 + #define NUM_DRIVES 1 70 + #define STORAGE_WANTS_ALIGN 71 + #define STORAGE_NEEDS_BOUNCE_BUFFER 72 + 73 + /* RTC settings */ 74 + #define CONFIG_RTC RTC_X1000 75 + /* TODO: implement HAVE_RTC_ALARM */ 76 + 77 + /* Power management */ 78 + #define CONFIG_BATTERY_MEASURE (VOLTAGE_MEASURE) 79 + #define CONFIG_CHARGING CHARGING_MONITOR 80 + #define HAVE_SW_POWEROFF 81 + 82 + #ifndef SIMULATOR 83 + /* TODO: get the CW2015 driver working correctly */ 84 + /* #define HAVE_CW2015 */ 85 + #define HAVE_AXP_PMU 192 /* Presumed */ 86 + #define HAVE_POWEROFF_WHILE_CHARGING 87 + #endif 88 + 89 + /* Only one battery type */ 90 + #define BATTERY_CAPACITY_DEFAULT 1100 91 + #define BATTERY_CAPACITY_MIN 1100 92 + #define BATTERY_CAPACITY_MAX 1100 93 + #define BATTERY_CAPACITY_INC 0 94 + #define BATTERY_TYPES_COUNT 1 95 + 96 + /* USB support */ 97 + #ifndef SIMULATOR 98 + #define CONFIG_USBOTG USBOTG_DESIGNWARE 99 + #define USB_DW_ARCH_SLAVE 100 + #define USB_DW_TURNAROUND 5 101 + #define HAVE_USBSTACK 102 + #define USB_VENDOR_ID 0x0525 /* Same as the xDuuo X3, for some reason. */ 103 + #define USB_PRODUCT_ID 0xa4a5 /* Nb. DAC mode uses 20b1:301f 'XMOS Ltd' */ 104 + #define USB_DEVBSS_ATTR __attribute__((aligned(32))) 105 + #define HAVE_USB_POWER 106 + #define HAVE_USB_CHARGING_ENABLE 107 + #define HAVE_BOOTLOADER_USB_MODE 108 + #endif 109 + 110 + /* Rockbox capabilities */ 111 + #define HAVE_FAT16SUPPORT 112 + #define HAVE_ALBUMART 113 + #define HAVE_BMP_SCALING 114 + #define HAVE_JPEG 115 + #define HAVE_TAGCACHE 116 + #define HAVE_VOLUME_IN_LIST 117 + #define HAVE_QUICKSCREEN 118 + #define HAVE_HOTKEY 119 + #define AB_REPEAT_ENABLE
+57
firmware/export/cw2015.h
··· 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 + #ifndef __CW2015_H__ 23 + #define __CW2015_H__ 24 + 25 + #include <stdint.h> 26 + #include <stdbool.h> 27 + 28 + /* Driver for I2C battery fuel gauge IC CW2015. */ 29 + 30 + #define CW2015_REG_VERSION 0x00 31 + #define CW2015_REG_VCELL 0x02 /* 14 bits, registers 0x02 - 0x03 */ 32 + #define CW2015_REG_SOC 0x04 /* 16 bits, registers 0x04 - 0x05 */ 33 + #define CW2015_REG_RRT_ALERT 0x06 /* 13 bit RRT + alert flag, 0x06-0x07 */ 34 + #define CW2015_REG_CONFIG 0x08 35 + #define CW2015_REG_MODE 0x0a 36 + #define CW2015_REG_BATINFO 0x10 /* cf. mainline Linux CW2015 driver */ 37 + #define CW2015_SIZE_BATINFO 64 38 + 39 + extern void cw2015_init(void); 40 + 41 + /* Read the battery terminal voltage, converted to millivolts. */ 42 + extern int cw2015_get_vcell(void); 43 + 44 + /* Read the SOC, in percent (0-100%). */ 45 + extern int cw2015_get_soc(void); 46 + 47 + /* Get the estimated remaining run time, in minutes. 48 + * Not a linearly varying quantity, according to the datasheet. */ 49 + extern int cw2015_get_rrt(void); 50 + 51 + /* Read the current battery profile */ 52 + extern const uint8_t* cw2015_get_bat_info(void); 53 + 54 + /* Debug screen */ 55 + extern bool cw2015_debug_menu(void); 56 + 57 + #endif /* __CW2015_H__ */
+230
firmware/export/es9218.h
··· 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 + #ifndef __ES9218_H__ 23 + #define __ES9218_H__ 24 + 25 + #include <stdbool.h> 26 + #include <stdint.h> 27 + 28 + #define AUDIOHW_CAPS (FILTER_ROLL_OFF_CAP|POWER_MODE_CAP) 29 + #define AUDIOHW_HAVE_ES9218_ROLL_OFF 30 + 31 + #define ES9218_DIG_VOLUME_MIN (-1275) 32 + #define ES9218_DIG_VOLUME_MAX 0 33 + #define ES9218_DIG_VOLUME_STEP 5 34 + 35 + #define ES9218_AMP_VOLUME_MIN (-240) 36 + #define ES9218_AMP_VOLUME_MAX 0 37 + #define ES9218_AMP_VOLUME_STEP 10 38 + 39 + AUDIOHW_SETTING(VOLUME, "dB", 1, ES9218_DIG_VOLUME_STEP, 40 + ES9218_DIG_VOLUME_MIN, ES9218_DIG_VOLUME_MAX, -200) 41 + AUDIOHW_SETTING(FILTER_ROLL_OFF, "", 0, 1, 0, 7, 0) 42 + AUDIOHW_SETTING(POWER_MODE, "", 0, 1, 0, 1, 0) 43 + 44 + /* Register addresses */ 45 + #define ES9218_REG_SYSTEM 0x00 46 + #define ES9218_REG_INPUT_SEL 0x01 47 + #define ES9218_REG_MIX_AUTOMUTE 0x02 48 + #define ES9218_REG_ANALOG_VOL 0x03 49 + #define ES9218_REG_AUTOMUTE_TIME 0x04 50 + #define ES9218_REG_AUTOMUTE_LEVEL 0x05 51 + #define ES9218_REG_DOP_VOLUME_RAMP 0x06 52 + #define ES9218_REG_FILTER_SYS_MUTE 0x07 53 + #define ES9218_REG_GPIO1_2_CONFIG 0x08 54 + #define ES9218_REG_RESERVED_1 0x09 55 + #define ES9218_REG_MASTER_MODE_CONFIG 0x0a 56 + #define ES9218_REG_OVERCURRENT_PROT 0x0b 57 + #define ES9218_REG_ASRC_DPLL_BANDWIDTH 0x0c 58 + #define ES9218_REG_THD_COMP_BYPASS 0x0d 59 + #define ES9218_REG_SOFT_START_CONFIG 0x0e 60 + #define ES9218_REG_VOLUME_LEFT 0x0f 61 + #define ES9218_REG_VOLUME_RIGHT 0x10 62 + #define ES9218_REG_MASTER_TRIM_BIT0_7 0x11 63 + #define ES9218_REG_MASTER_TRIM_BIT8_15 0x12 64 + #define ES9218_REG_MASTER_TRIM_BIT16_23 0x13 65 + #define ES9218_REG_MASTER_TRIM_BIT24_31 0x14 66 + #define ES9218_REG_GPIO_INPUT_SEL 0x15 67 + #define ES9218_REG_THD_COMP_C2_LO 0x16 68 + #define ES9218_REG_THD_COMP_C2_HI 0x17 69 + #define ES9218_REG_THD_COMP_C3_LO 0x18 70 + #define ES9218_REG_THD_COMP_C3_HI 0x19 71 + #define ES9218_REG_CHARGE_PUMP_SS_DELAY 0x1a 72 + #define ES9218_REG_GENERAL_CONFIG 0x1b 73 + #define ES9218_REG_RESERVED_2 0x1c 74 + #define ES9218_REG_GPIO_INV_CLOCK_GEAR 0x1d 75 + #define ES9218_REG_CHARGE_PUMP_CLK_LO 0x1e 76 + #define ES9218_REG_CHARGE_PUMP_CLK_HI 0x1f 77 + #define ES9218_REG_AMP_CONFIG 0x20 78 + #define ES9218_REG_INTERRUPT_MASK 0x21 79 + #define ES9218_REG_PROG_NCO_BIT0_7 0x22 80 + #define ES9218_REG_PROG_NCO_BIT8_15 0x23 81 + #define ES9218_REG_PROG_NCO_BIT16_23 0x24 82 + #define ES9218_REG_PROG_NCO_BIT24_31 0x25 83 + #define ES9218_REG_RESERVED_3 0x27 84 + #define ES9218_REG_FIR_RAM_ADDR 0x28 85 + #define ES9218_REG_FIR_DATA_BIT0_7 0x29 86 + #define ES9218_REG_FIR_DATA_BIT8_15 0x2a 87 + #define ES9218_REG_FIR_DATA_BIT16_23 0x2b 88 + #define ES9218_REG_PROG_FIR_CONFIG 0x2c 89 + #define ES9218_REG_ANALOG_OVERRIDE_1 0x2d 90 + #define ES9218_REG_ANALOG_OVERRIDE_2 0x2e 91 + #define ES9218_REG_ANALOG_OVERRIDE_3 0x2f 92 + #define ES9218_REG_ANALOG_CTRL 0x30 93 + #define ES9218_REG_CLKGEAR_CFG_BIT0_7 0x31 94 + #define ES9218_REG_CLKGEAR_CFG_BIT8_15 0x32 95 + #define ES9218_REG_CLKGEAR_CFG_BIT16_23 0x33 96 + #define ES9218_REG_RESERVED_4 0x34 97 + #define ES9218_REG_THD_COMP_C2_CH2_LO 0x35 98 + #define ES9218_REG_THD_COMP_C2_CH2_HI 0x36 99 + #define ES9218_REG_THD_COMP_C3_CH2_LO 0x37 100 + #define ES9218_REG_THD_COMP_C3_CH2_HI 0x38 101 + #define ES9218_REG_RESERVED_5 0x39 102 + #define ES9218_REG_RESERVED_6 0x3a 103 + #define ES9218_REG_RESERVED_7 0x3b 104 + #define ES9218_REG_RESERVED_8 0x3c 105 + #define ES9218_REG_CHIP_ID_AND_STATUS 0x40 106 + #define ES9218_REG_GPIO_AND_CLOCK_GEAR 0x41 107 + #define ES9218_REG_DPLL_NUMBER_BIT0_7 0x42 108 + #define ES9218_REG_DPLL_NUMBER_BIT8_15 0x43 109 + #define ES9218_REG_DPLL_NUMBER_BIT16_23 0x44 110 + #define ES9218_REG_DPLL_NUMBER_BIT24_31 0x45 111 + #define ES9218_REG_INPUT_MUTE_STATUS 0x48 112 + #define ES9218_REG_FIR_READ_BIT0_7 0x49 113 + #define ES9218_REG_FIR_READ_BIT8_15 0x4a 114 + #define ES9218_REG_FIR_READ_BIT16_23 0x4b 115 + 116 + enum es9218_clock_gear { 117 + ES9218_CLK_GEAR_1 = 0, /* CLK = XI/1 */ 118 + ES9218_CLK_GEAR_2 = 1, /* CLK = XI/2 */ 119 + ES9218_CLK_GEAR_4 = 2, /* CLK = XI/4 */ 120 + ES9218_CLK_GEAR_8 = 3, /* CLK = XI/8 */ 121 + }; 122 + 123 + enum es9218_amp_mode { 124 + ES9218_AMP_MODE_CORE_ON = 0, 125 + ES9218_AMP_MODE_LOWFI = 1, 126 + ES9218_AMP_MODE_1VRMS = 2, 127 + ES9218_AMP_MODE_2VRMS = 3, 128 + }; 129 + 130 + enum es9218_iface_role { 131 + ES9218_IFACE_ROLE_SLAVE = 0, 132 + ES9218_IFACE_ROLE_MASTER = 1, 133 + }; 134 + 135 + enum es9218_iface_format { 136 + ES9218_IFACE_FORMAT_I2S = 0, 137 + ES9218_IFACE_FORMAT_LJUST = 1, 138 + ES9218_IFACE_FORMAT_RJUST = 2, 139 + }; 140 + 141 + enum es9218_iface_bits { 142 + ES9218_IFACE_BITS_16 = 0, 143 + ES9218_IFACE_BITS_24 = 1, 144 + ES9218_IFACE_BITS_32 = 2, 145 + }; 146 + 147 + enum es9218_filter_type { 148 + ES9218_FILTER_LINEAR_FAST = 0, 149 + ES9218_FILTER_LINEAR_SLOW = 1, 150 + ES9218_FILTER_MINIMUM_FAST = 2, 151 + ES9218_FILTER_MINIMUM_SLOW = 3, 152 + ES9218_FILTER_APODIZING_1 = 4, 153 + ES9218_FILTER_APODIZING_2 = 5, 154 + ES9218_FILTER_HYBRID_FAST = 6, 155 + ES9218_FILTER_BRICK_WALL = 7, 156 + }; 157 + 158 + /* Power DAC on or off */ 159 + extern void es9218_open(void); 160 + extern void es9218_close(void); 161 + 162 + /* Clock controls 163 + * 164 + * - Clock gear divides the input master clock to produce the DAC's clock. 165 + * Frequency can be lowered to save power when using lower sample rates. 166 + * 167 + * - NCO (numerically controller oscillator), according to the datasheet, 168 + * defines the ratio between the DAC's clock and the FSR (for PCM modes, 169 + * this is I2S frame clock = sample rate). In master mode it effectively 170 + * controls the sampling frequency by setting the I2S frame clock output. 171 + * It can also be used in slave mode, but other parts of the datasheet 172 + * say contradictory things about synchronous operation in slave mode. 173 + * 174 + * - If using NCO mode and a varying MCLK input (eg. input from the SoC) then 175 + * you will need to call es9218_recompute_nco() when changing MCLK in order 176 + * to refresh the NCO setting. 177 + */ 178 + extern void es9218_set_clock_gear(enum es9218_clock_gear gear); 179 + extern void es9218_set_nco_frequency(uint32_t fsr); 180 + extern void es9218_recompute_nco(void); 181 + 182 + /* Amplifier controls */ 183 + extern void es9218_set_amp_mode(enum es9218_amp_mode mode); 184 + extern void es9218_set_amp_powered(bool en); 185 + 186 + /* Interface selection */ 187 + extern void es9218_set_iface_role(enum es9218_iface_role role); 188 + extern void es9218_set_iface_format(enum es9218_iface_format fmt, 189 + enum es9218_iface_bits bits); 190 + 191 + /* Volume controls, all volumes given in units of dB/10 */ 192 + extern void es9218_set_dig_volume(int vol_l, int vol_r); 193 + extern void es9218_set_amp_volume(int vol); 194 + 195 + /* System mute */ 196 + extern void es9218_mute(bool muted); 197 + 198 + /* Oversampling filter */ 199 + extern void es9218_set_filter(enum es9218_filter_type filt); 200 + 201 + /* Automute settings */ 202 + extern void es9218_set_automute_time(int time); 203 + extern void es9218_set_automute_level(int dB); 204 + extern void es9218_set_automute_fast_mode(bool en); 205 + 206 + /* DPLL bandwidth setting (knob = 0-15) */ 207 + extern void es9218_set_dpll_bandwidth(int knob); 208 + 209 + /* THD compensation */ 210 + extern void es9218_set_thd_compensation(bool en); 211 + extern void es9218_set_thd_coeffs(uint16_t c2, uint16_t c3); 212 + 213 + /* Direct register read/write/update operations */ 214 + extern int es9218_read(int reg); 215 + extern void es9218_write(int reg, uint8_t val); 216 + extern void es9218_update(int reg, uint8_t msk, uint8_t val); 217 + 218 + /* GPIO pin setting callbacks */ 219 + extern void es9218_set_power_pin(int level); 220 + extern void es9218_set_reset_pin(int level); 221 + 222 + /* XI(MCLK) getter -- supplied by the target. 223 + * 224 + * Note: when changing the supplied MCLK frequency, the NCO will need to be 225 + * reprogrammed for the new master clock. Call es9218_recompute_nco() to 226 + * force this. Not necessary if you're not using NCO mode. 227 + */ 228 + extern uint32_t es9218_get_mclk(void); 229 + 230 + #endif /* __ES9218_H__ */
+8
firmware/target/hosted/sdl/sim-ui-defines.h
··· 529 529 #define UI_LCD_POSY 15 530 530 531 531 532 + #elif defined(SHANLING_Q1) 533 + #define UI_TITLE "Shanling Q1" 534 + #define UI_WIDTH 466 535 + #define UI_HEIGHT 526 536 + #define UI_LCD_POSX 46 537 + #define UI_LCD_POSY 61 538 + 539 + 532 540 #elif defined(SIMULATOR) 533 541 #error no UI defines 534 542 #endif
+6
firmware/target/mips/ingenic_x1000/debug-x1000.c
··· 152 152 #ifdef HAVE_AXP_PMU 153 153 extern bool axp_debug_menu(void); 154 154 #endif 155 + #ifdef HAVE_CW2015 156 + extern bool cw2015_debug_menu(void); 157 + #endif 155 158 156 159 /* Menu definition */ 157 160 static const struct { ··· 169 172 #endif 170 173 #ifdef HAVE_AXP_PMU 171 174 {"Power stats", &axp_debug_menu}, 175 + #endif 176 + #ifdef HAVE_CW2015 177 + {"CW2015 debug", &cw2015_debug_menu}, 172 178 #endif 173 179 }; 174 180
+12 -1
firmware/target/mips/ingenic_x1000/msc-x1000.c
··· 42 42 #define DEBOUNCE_TIME (HZ/10) 43 43 44 44 static const msc_config msc_configs[] = { 45 - #ifdef FIIO_M3K 45 + #if defined(FIIO_M3K) 46 46 #define MSC_CLOCK_SOURCE X1000_CLK_SCLK_A 47 47 { 48 48 .msc_nr = 0, ··· 52 52 .cd_gpio = GPIO_MSC0_CD, 53 53 .cd_active_level = 0, 54 54 }, 55 + #elif defined(SHANLING_Q1) 56 + #define MSC_CLOCK_SOURCE X1000_CLK_MPLL 57 + { 58 + .msc_nr = 0, 59 + .msc_type = MSC_TYPE_SD, 60 + .bus_width = 4, 61 + .label = "microSD", 62 + .cd_gpio = GPIO_MSC0_CD, 63 + .cd_active_level = 0, 64 + }, 65 + /* NOTE: SDIO wifi card is on msc1 */ 55 66 #else 56 67 # error "Please add X1000 MSC config" 57 68 #endif
+1 -1
firmware/target/mips/ingenic_x1000/nand-x1000.c
··· 58 58 #define FREG_STATUS_ECC_UNCOR_ERR (2 << 4) 59 59 60 60 const nand_chip supported_nand_chips[] = { 61 - #if defined(FIIO_M3K) 61 + #if defined(FIIO_M3K) || defined(SHANLING_Q1) 62 62 { 63 63 /* ATO25D1GA */ 64 64 .mf_id = 0x9b,
firmware/target/mips/ingenic_x1000/shanlingq1/adc-target.h

This is a binary file and will not be displayed.

+191
firmware/target/mips/ingenic_x1000/shanlingq1/audiohw-shanlingq1.c
··· 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 "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 "x1000/aic.h" 29 + #include "x1000/cpm.h" 30 + 31 + /* Codec has an dedicated oscillator connected, so it can operate 32 + * as i2s master or slave. I can't distinguish any difference in 33 + * terms of audio quality or power consumption. Code is left here 34 + * for reference in case it proves useful to change it. */ 35 + #define CODEC_MASTER_MODE 0 36 + 37 + static int cur_fsel = HW_FREQ_48; 38 + static int cur_vol_l = 0, cur_vol_r = 0; 39 + static int cur_filter = 0; 40 + static enum es9218_amp_mode cur_amp_mode = ES9218_AMP_MODE_1VRMS; 41 + 42 + static void codec_start(void) 43 + { 44 + es9218_open(); 45 + es9218_mute(true); 46 + es9218_set_iface_role(CODEC_MASTER_MODE ? ES9218_IFACE_ROLE_MASTER 47 + : ES9218_IFACE_ROLE_SLAVE); 48 + es9218_set_iface_format(ES9218_IFACE_FORMAT_I2S, ES9218_IFACE_BITS_32); 49 + es9218_set_dpll_bandwidth(10); 50 + es9218_set_thd_compensation(true); 51 + es9218_set_thd_coeffs(0, 0); 52 + audiohw_set_filter_roll_off(cur_filter); 53 + audiohw_set_frequency(cur_fsel); 54 + audiohw_set_volume(cur_vol_l, cur_vol_r); 55 + es9218_set_amp_mode(cur_amp_mode); 56 + } 57 + 58 + static void codec_stop(void) 59 + { 60 + es9218_mute(true); 61 + es9218_close(); 62 + mdelay(1); 63 + } 64 + 65 + void audiohw_init(void) 66 + { 67 + /* Configure AIC */ 68 + aic_set_external_codec(true); 69 + aic_set_i2s_mode(CODEC_MASTER_MODE ? AIC_I2S_SLAVE_MODE 70 + : AIC_I2S_MASTER_MODE); 71 + aic_enable_i2s_bit_clock(true); 72 + 73 + /* Open DAC driver */ 74 + i2c_x1000_set_freq(1, I2C_FREQ_400K); 75 + codec_start(); 76 + } 77 + 78 + void audiohw_postinit(void) 79 + { 80 + es9218_mute(false); 81 + } 82 + 83 + void audiohw_close(void) 84 + { 85 + codec_stop(); 86 + } 87 + 88 + void audiohw_set_frequency(int fsel) 89 + { 90 + int sampr = hw_freq_sampr[fsel]; 91 + 92 + /* choose clock gear setting, in line with the OF */ 93 + enum es9218_clock_gear clkgear; 94 + if(sampr <= 48000) 95 + clkgear = ES9218_CLK_GEAR_4; 96 + else if(sampr <= 96000) 97 + clkgear = ES9218_CLK_GEAR_2; 98 + else 99 + clkgear = ES9218_CLK_GEAR_1; 100 + 101 + aic_enable_i2s_bit_clock(false); 102 + es9218_set_clock_gear(clkgear); 103 + 104 + if(CODEC_MASTER_MODE) 105 + es9218_set_nco_frequency(sampr); 106 + else 107 + aic_set_i2s_clock(X1000_CLK_SCLK_A, sampr, 64); 108 + 109 + aic_enable_i2s_bit_clock(true); 110 + 111 + /* save frequency selection */ 112 + cur_fsel = fsel; 113 + } 114 + 115 + static int round_step_up(int x, int step) 116 + { 117 + int rem = x % step; 118 + if(rem > 0) 119 + rem -= step; 120 + return x - rem; 121 + } 122 + 123 + void audiohw_set_volume(int vol_l, int vol_r) 124 + { 125 + /* save volume */ 126 + cur_vol_l = vol_l; 127 + cur_vol_r = vol_r; 128 + 129 + /* adjust the amp setting first */ 130 + int amp = round_step_up(MAX(vol_l, vol_r), ES9218_AMP_VOLUME_STEP); 131 + amp = MIN(amp, ES9218_AMP_VOLUME_MAX); 132 + amp = MAX(amp, ES9218_AMP_VOLUME_MIN); 133 + 134 + /* adjust digital volumes */ 135 + vol_l -= amp; 136 + vol_l = MIN(vol_l, ES9218_DIG_VOLUME_MAX); 137 + vol_l = MAX(vol_l, ES9218_DIG_VOLUME_MIN); 138 + 139 + vol_r -= amp; 140 + vol_r = MIN(vol_r, ES9218_DIG_VOLUME_MAX); 141 + vol_r = MAX(vol_r, ES9218_DIG_VOLUME_MIN); 142 + 143 + /* program DAC */ 144 + es9218_set_amp_volume(amp); 145 + es9218_set_dig_volume(vol_l, vol_r); 146 + } 147 + 148 + void audiohw_set_filter_roll_off(int value) 149 + { 150 + cur_filter = value; 151 + es9218_set_filter(value); 152 + } 153 + 154 + void audiohw_set_power_mode(int mode) 155 + { 156 + enum es9218_amp_mode new_amp_mode; 157 + if(mode == 0) 158 + new_amp_mode = ES9218_AMP_MODE_2VRMS; 159 + else 160 + new_amp_mode = ES9218_AMP_MODE_1VRMS; 161 + 162 + if(new_amp_mode != cur_amp_mode) { 163 + codec_stop(); 164 + cur_amp_mode = new_amp_mode; 165 + codec_start(); 166 + es9218_mute(false); 167 + } 168 + } 169 + 170 + void es9218_set_power_pin(int level) 171 + { 172 + gpio_set_level(GPIO_ES9218_POWER, level ? 1 : 0); 173 + } 174 + 175 + void es9218_set_reset_pin(int level) 176 + { 177 + gpio_set_level(GPIO_ES9218_RESET, level ? 1 : 0); 178 + } 179 + 180 + uint32_t es9218_get_mclk(void) 181 + { 182 + /* Measured by running the DAC in asynchronous I2S slave mode, 183 + * and reading back the DPLL number from regs 0x42-0x45 while 184 + * playing back 44.1 KHz audio. 185 + * 186 + * CLK = (44_100 * 2**32) / 0x4b46e5 187 + * = 38_393_403.29532737 188 + * ~ 38.4 Mhz 189 + */ 190 + return 38400000; 191 + }
+63
firmware/target/mips/ingenic_x1000/shanlingq1/backlight-shanlingq1.c
··· 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 "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 10000 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 + }
+33
firmware/target/mips/ingenic_x1000/shanlingq1/backlight-target.h
··· 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 + #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__ */
+31
firmware/target/mips/ingenic_x1000/shanlingq1/boot.make
··· 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 + # FIXME(q1): verify NAND parameters 15 + $(BUILDDIR)/spl.q1: $(BUILDDIR)/spl.bin 16 + $(call PRINTS,MKSPL $(@F))$(TOOLSDIR)/mkspl-x1000 -type=nand -ppb=2 -bpp=2 $< $@ 17 + 18 + $(BUILDDIR)/bootloader.ucl: $(BUILDDIR)/bootloader.bin 19 + $(call PRINTS,UCLPACK $(@F))$(TOOLSDIR)/uclpack --nrv2e -9 $< $@ >/dev/null 20 + 21 + .PHONY: $(BUILDDIR)/bootloader-info.txt 22 + $(BUILDDIR)/bootloader-info.txt: 23 + $(call PRINTS,GEN $(@F))echo $(SVNVERSION) > $@ 24 + 25 + $(BUILDDIR)/$(BINARY): $(BUILDDIR)/spl.q1 \ 26 + $(BUILDDIR)/bootloader.ucl \ 27 + $(BUILDDIR)/bootloader-info.txt 28 + $(call PRINTS,TAR $(@F))tar -C $(BUILDDIR) \ 29 + --numeric-owner --no-acls --no-xattrs --no-selinux \ 30 + --mode=0644 --owner=0 --group=0 \ 31 + -cf $@ $(call full_path_subst,$(BUILDDIR)/%,%,$^)
+195
firmware/target/mips/ingenic_x1000/shanlingq1/button-shanlingq1.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2021 Aidan MacDonald 11 + * Copyright (C) 2021 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 "button.h" 24 + #include "touchscreen.h" 25 + #include "ft6x06.h" 26 + #include "axp-pmu.h" 27 + #include "kernel.h" 28 + #include "backlight.h" 29 + #include "powermgmt.h" 30 + #include "gpio-x1000.h" 31 + #include "irq-x1000.h" 32 + #include "i2c-x1000.h" 33 + #include <stdbool.h> 34 + 35 + /* Volume wheel rotation */ 36 + static volatile int wheel_pos = 0; 37 + 38 + /* Value of headphone detect register */ 39 + static uint8_t hp_detect_reg = 0x00; 40 + 41 + /* Interval to poll the register */ 42 + #define HPD_POLL_TIME (HZ/2) 43 + 44 + static int hp_detect_tmo_cb(struct timeout* tmo) 45 + { 46 + i2c_descriptor* d = (i2c_descriptor*)tmo->data; 47 + i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d); 48 + return HPD_POLL_TIME; 49 + } 50 + 51 + static void hp_detect_init(void) 52 + { 53 + /* TODO: replace this copy paste cruft with an API in axp-pmu */ 54 + static struct timeout tmo; 55 + static const uint8_t gpio_reg = AXP192_REG_GPIOSTATE1; 56 + static i2c_descriptor desc = { 57 + .slave_addr = AXP_PMU_ADDR, 58 + .bus_cond = I2C_START | I2C_STOP, 59 + .tran_mode = I2C_READ, 60 + .buffer[0] = (void*)&gpio_reg, 61 + .count[0] = 1, 62 + .buffer[1] = &hp_detect_reg, 63 + .count[1] = 1, 64 + .callback = NULL, 65 + .arg = 0, 66 + .next = NULL, 67 + }; 68 + 69 + /* Headphone detect is wired to AXP192 GPIO: set it to input state */ 70 + i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO1FUNCTION, 0x01); 71 + 72 + /* Get an initial reading before startup */ 73 + int r = i2c_reg_read1(AXP_PMU_BUS, AXP_PMU_ADDR, gpio_reg); 74 + if(r >= 0) 75 + hp_detect_reg = r; 76 + 77 + /* Poll the register every second */ 78 + timeout_register(&tmo, &hp_detect_tmo_cb, HPD_POLL_TIME, (intptr_t)&desc); 79 + } 80 + 81 + void button_init_device(void) 82 + { 83 + /* Setup interrupts for the volume wheel */ 84 + gpio_set_function(GPIO_WHEEL1, GPIOF_IRQ_EDGE(0)); 85 + gpio_set_function(GPIO_WHEEL2, GPIOF_IRQ_EDGE(0)); 86 + gpio_flip_edge_irq(GPIO_WHEEL1); 87 + gpio_flip_edge_irq(GPIO_WHEEL2); 88 + gpio_enable_irq(GPIO_WHEEL1); 89 + gpio_enable_irq(GPIO_WHEEL2); 90 + 91 + /* Init touchscreen driver */ 92 + i2c_x1000_set_freq(FT6x06_BUS, I2C_FREQ_400K); 93 + ft6x06_init(); 94 + 95 + /* Reset touch controller */ 96 + gpio_set_level(GPIO_FT6x06_POWER, 1); 97 + gpio_set_level(GPIO_FT6x06_RESET, 0); 98 + mdelay(5); 99 + gpio_set_level(GPIO_FT6x06_RESET, 1); 100 + 101 + /* Enable ft6x06 interrupt */ 102 + system_set_irq_handler(GPIO_TO_IRQ(GPIO_FT6x06_INTERRUPT), ft6x06_irq_handler); 103 + gpio_set_function(GPIO_FT6x06_INTERRUPT, GPIOF_IRQ_EDGE(0)); 104 + gpio_enable_irq(GPIO_FT6x06_INTERRUPT); 105 + 106 + /* Headphone detection */ 107 + hp_detect_init(); 108 + } 109 + 110 + int button_read_device(int* data) 111 + { 112 + int r = 0; 113 + 114 + /* Read GPIO buttons, these are all active low */ 115 + uint32_t b = REG_GPIO_PIN(GPIO_B); 116 + if((b & (1 << 21)) == 0) r |= BUTTON_PREV; 117 + if((b & (1 << 22)) == 0) r |= BUTTON_NEXT; 118 + if((b & (1 << 28)) == 0) r |= BUTTON_PLAY; 119 + if((b & (1 << 31)) == 0) r |= BUTTON_POWER; 120 + 121 + /* Check the wheel */ 122 + int wheel_btn = 0; 123 + int whpos = wheel_pos; 124 + if(whpos > 3) 125 + wheel_btn = BUTTON_VOL_DOWN; 126 + else if(whpos < -3) 127 + wheel_btn = BUTTON_VOL_UP; 128 + 129 + if(wheel_btn) { 130 + wheel_pos = 0; 131 + 132 + /* Post the event (rapid motion is more reliable this way) */ 133 + queue_post(&button_queue, wheel_btn, 0); 134 + queue_post(&button_queue, wheel_btn|BUTTON_REL, 0); 135 + 136 + /* Poke the backlight */ 137 + backlight_on(); 138 + reset_poweroff_timer(); 139 + } 140 + 141 + /* Handle touchscreen 142 + * 143 + * TODO: Support 2-point multitouch (useful for 3x3 grid mode) 144 + * TODO: Support simple gestures by converting them to fake buttons 145 + */ 146 + int t = touchscreen_to_pixels(ft6x06_state.pos_x, ft6x06_state.pos_y, data); 147 + if(ft6x06_state.event == FT6x06_EVT_PRESS || 148 + ft6x06_state.event == FT6x06_EVT_CONTACT) { 149 + /* Only set the button bit if the screen is being touched. */ 150 + r |= t; 151 + } 152 + 153 + return r; 154 + } 155 + 156 + void touchscreen_enable_device(bool en) 157 + { 158 + ft6x06_enable(en); 159 + /* TODO: check if it's worth shutting off the power pin */ 160 + } 161 + 162 + bool headphones_inserted(void) 163 + { 164 + /* TODO: Also check if the headset button is detectable via an ADC. 165 + * The AXP driver should probably get proper interrupt handling, 166 + * that would be useful for more things than just GPIO polling. */ 167 + return hp_detect_reg & 0x20 ? true : false; 168 + } 169 + 170 + static void handle_wheel_irq(void) 171 + { 172 + /* Wheel stuff adapted from button-erosqnative.c */ 173 + static const int delta[16] = { 0, -1, 1, 0, 174 + 1, 0, 0, -1, 175 + -1, 0, 0, 1, 176 + 0, 1, -1, 0 }; 177 + static uint32_t state = 0; 178 + state <<= 2; 179 + state |= (REG_GPIO_PIN(GPIO_D) >> 2) & 3; 180 + state &= 0xf; 181 + 182 + wheel_pos += delta[state]; 183 + } 184 + 185 + void GPIOD02(void) 186 + { 187 + handle_wheel_irq(); 188 + gpio_flip_edge_irq(GPIO_WHEEL1); 189 + } 190 + 191 + void GPIOD03(void) 192 + { 193 + handle_wheel_irq(); 194 + gpio_flip_edge_irq(GPIO_WHEEL2); 195 + }
+56
firmware/target/mips/ingenic_x1000/shanlingq1/button-target.h
··· 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 + #ifndef __BUTTON_TARGET_H__ 23 + #define __BUTTON_TARGET_H__ 24 + 25 + #include <stdbool.h> 26 + 27 + /* physical buttons */ 28 + #define BUTTON_POWER 0x00000001 29 + #define BUTTON_VOL_UP 0x00000002 /* up = wheel clockwise */ 30 + #define BUTTON_VOL_DOWN 0x00000004 31 + #define BUTTON_PLAY 0x00000008 /* circle */ 32 + #define BUTTON_NEXT 0x00000010 /* down */ 33 + #define BUTTON_PREV 0x00000020 /* up */ 34 + 35 + /* compatibility hacks */ 36 + #define BUTTON_LEFT BUTTON_MIDLEFT 37 + #define BUTTON_RIGHT BUTTON_MIDRIGHT 38 + 39 + /* touchscreen "buttons" */ 40 + #define BUTTON_TOPLEFT 0x00000040 41 + #define BUTTON_TOPMIDDLE 0x00000080 42 + #define BUTTON_TOPRIGHT 0x00000100 43 + #define BUTTON_MIDLEFT 0x00000200 44 + #define BUTTON_CENTER 0x00000400 45 + #define BUTTON_MIDRIGHT 0x00000800 46 + #define BUTTON_BOTTOMLEFT 0x00001000 47 + #define BUTTON_BOTTOMMIDDLE 0x00002000 48 + #define BUTTON_BOTTOMRIGHT 0x00004000 49 + 50 + #define BUTTON_MAIN (BUTTON_POWER|BUTTON_VOL_UP|BUTTON_VOL_DOWN|\ 51 + BUTTON_PLAY|BUTTON_NEXT|BUTTON_PREV) 52 + 53 + #define POWEROFF_BUTTON BUTTON_POWER 54 + #define POWEROFF_COUNT 30 55 + 56 + #endif /* __BUTTON_TARGET_H__ */
+32
firmware/target/mips/ingenic_x1000/shanlingq1/gpio-target.h
··· 1 + /* Name Port Pins Function */ 2 + DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1)) 3 + DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1)) 4 + DEFINE_PINGROUP(MSC0, GPIO_A, 0x3f << 20, GPIOF_DEVICE(1)) 5 + DEFINE_PINGROUP(SFC, GPIO_A, 0x3f << 26, GPIOF_DEVICE(1)) 6 + DEFINE_PINGROUP(I2S, GPIO_B, 0x1f << 0, GPIOF_DEVICE(1)) 7 + DEFINE_PINGROUP(I2C0, GPIO_B, 3 << 23, GPIOF_DEVICE(0)) 8 + DEFINE_PINGROUP(I2C1, GPIO_C, 3 << 26, GPIOF_DEVICE(0)) 9 + DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1)) 10 + 11 + /* Name Pin Function */ 12 + DEFINE_GPIO(FT6x06_INTERRUPT, GPIO_PA(16), GPIOF_INPUT) 13 + DEFINE_GPIO(USB_DETECT, GPIO_PA(17), GPIOF_INPUT) 14 + DEFINE_GPIO(FT6x06_RESET, GPIO_PA(19), GPIOF_OUTPUT(0)) 15 + DEFINE_GPIO(LCD_PWR, GPIO_PB(6), GPIOF_OUTPUT(1)) 16 + DEFINE_GPIO(FT6x06_POWER, GPIO_PB(8), GPIOF_OUTPUT(0)) 17 + DEFINE_GPIO(MSC0_CD, GPIO_PB(9), GPIOF_INPUT) 18 + DEFINE_GPIO(ES9218_POWER, GPIO_PB(13), GPIOF_OUTPUT(0)) 19 + DEFINE_GPIO(LCD_RST, GPIO_PB(15), GPIOF_OUTPUT(1)) 20 + DEFINE_GPIO(LCD_RD, GPIO_PB(16), GPIOF_OUTPUT(1)) 21 + DEFINE_GPIO(LCD_CE, GPIO_PB(18), GPIOF_OUTPUT(1)) 22 + DEFINE_GPIO(BTN_PREV, GPIO_PB(21), GPIOF_INPUT) 23 + DEFINE_GPIO(BTN_NEXT, GPIO_PB(22), GPIOF_INPUT) 24 + DEFINE_GPIO(USB_DRVVBUS, GPIO_PB(25), GPIOF_OUTPUT(0)) 25 + DEFINE_GPIO(BTN_PLAY, GPIO_PB(28), GPIOF_INPUT) 26 + DEFINE_GPIO(BTN_POWER, GPIO_PB(31), GPIOF_INPUT) 27 + DEFINE_GPIO(AXP_IRQ, GPIO_PC(21), GPIOF_INPUT) 28 + DEFINE_GPIO(USB_ID, GPIO_PC(23), GPIOF_INPUT) 29 + DEFINE_GPIO(WHEEL1, GPIO_PD(2), GPIOF_INPUT) 30 + DEFINE_GPIO(WHEEL2, GPIO_PD(3), GPIOF_INPUT) 31 + DEFINE_GPIO(ES9218_GPIO2, GPIO_PD(4), GPIOF_OUTPUT(0)) 32 + DEFINE_GPIO(ES9218_RESET, GPIO_PD(5), GPIOF_OUTPUT(0))
+40
firmware/target/mips/ingenic_x1000/shanlingq1/i2c-target.h
··· 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 + #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 FT6x06_BUS 0 29 + #define FT6x06_ADDR 0x38 30 + 31 + #define ES9218_BUS 1 32 + #define ES9218_ADDR 0x48 33 + 34 + #define AXP_PMU_BUS 2 35 + #define AXP_PMU_ADDR 0x34 36 + 37 + #define CW2015_BUS 2 38 + #define CW2015_ADDR 0x62 39 + 40 + #endif /* __I2C_TARGET_H__ */
+399
firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c
··· 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 "lcd.h" 23 + #include "system.h" 24 + #include "lcd-x1000.h" 25 + #include "gpio-x1000.h" 26 + 27 + /* LCD controller is probably an RM68090. 28 + */ 29 + 30 + static const uint32_t q1_lcd_cmd_enable[] = { 31 + LCD_INSTR_CMD, 0x00, 32 + LCD_INSTR_CMD, 0xbe, 33 + LCD_INSTR_DAT, 0xc3, 34 + LCD_INSTR_DAT, 0x29, 35 + 36 + LCD_INSTR_CMD, 0x00, 37 + LCD_INSTR_CMD, 0x01, 38 + LCD_INSTR_DAT, 0x01, 39 + LCD_INSTR_DAT, 0x04, 40 + 41 + LCD_INSTR_CMD, 0x00, 42 + LCD_INSTR_CMD, 0x02, 43 + LCD_INSTR_DAT, 0x01, 44 + LCD_INSTR_DAT, 0x00, 45 + 46 + LCD_INSTR_CMD, 0x00, 47 + LCD_INSTR_CMD, 0x03, 48 + LCD_INSTR_DAT, 0x00, 49 + LCD_INSTR_DAT, 0x10, 50 + 51 + LCD_INSTR_CMD, 0x00, 52 + LCD_INSTR_CMD, 0x05, 53 + LCD_INSTR_DAT, 0x00, 54 + LCD_INSTR_DAT, 0x00, 55 + 56 + LCD_INSTR_CMD, 0x00, 57 + LCD_INSTR_CMD, 0x06, 58 + LCD_INSTR_DAT, 0x00, 59 + LCD_INSTR_DAT, 0x00, 60 + 61 + LCD_INSTR_CMD, 0x00, 62 + LCD_INSTR_CMD, 0x07, 63 + LCD_INSTR_DAT, 0x01, 64 + LCD_INSTR_DAT, 0x03, 65 + 66 + LCD_INSTR_CMD, 0x00, 67 + LCD_INSTR_CMD, 0x08, 68 + LCD_INSTR_DAT, 0x03, 69 + LCD_INSTR_DAT, 0x03, 70 + 71 + LCD_INSTR_CMD, 0x00, 72 + LCD_INSTR_CMD, 0x0d, 73 + LCD_INSTR_DAT, 0x00, 74 + LCD_INSTR_DAT, 0x00, 75 + 76 + LCD_INSTR_CMD, 0x00, 77 + LCD_INSTR_CMD, 0x10, 78 + LCD_INSTR_DAT, 0x00, 79 + LCD_INSTR_DAT, 0xc1, 80 + 81 + LCD_INSTR_CMD, 0x00, 82 + LCD_INSTR_CMD, 0x11, 83 + LCD_INSTR_DAT, 0xb1, 84 + LCD_INSTR_DAT, 0x08, 85 + 86 + LCD_INSTR_CMD, 0x00, 87 + LCD_INSTR_CMD, 0x12, 88 + LCD_INSTR_DAT, 0xb1, 89 + LCD_INSTR_DAT, 0x08, 90 + 91 + LCD_INSTR_CMD, 0x00, 92 + LCD_INSTR_CMD, 0x13, 93 + LCD_INSTR_DAT, 0x00, 94 + LCD_INSTR_DAT, 0x0f, 95 + 96 + LCD_INSTR_CMD, 0x00, 97 + LCD_INSTR_CMD, 0x14, 98 + LCD_INSTR_DAT, 0x00, 99 + LCD_INSTR_DAT, 0x14, 100 + 101 + LCD_INSTR_CMD, 0x00, 102 + LCD_INSTR_CMD, 0x15, 103 + LCD_INSTR_DAT, 0x00, 104 + LCD_INSTR_DAT, 0x04, 105 + 106 + LCD_INSTR_CMD, 0x00, 107 + LCD_INSTR_CMD, 0x16, 108 + LCD_INSTR_DAT, 0x00, 109 + LCD_INSTR_DAT, 0x00, 110 + 111 + LCD_INSTR_CMD, 0x00, 112 + LCD_INSTR_CMD, 0x22, 113 + LCD_INSTR_DAT, 0x00, 114 + LCD_INSTR_DAT, 0x00, 115 + 116 + LCD_INSTR_CMD, 0x00, 117 + LCD_INSTR_CMD, 0x23, 118 + LCD_INSTR_DAT, 0x00, 119 + LCD_INSTR_DAT, 0x00, 120 + 121 + LCD_INSTR_CMD, 0x00, 122 + LCD_INSTR_CMD, 0x30, 123 + LCD_INSTR_DAT, 0x7c, 124 + LCD_INSTR_DAT, 0x3f, 125 + 126 + LCD_INSTR_CMD, 0x00, 127 + LCD_INSTR_CMD, 0x32, 128 + LCD_INSTR_DAT, 0x00, 129 + LCD_INSTR_DAT, 0x00, 130 + 131 + LCD_INSTR_CMD, 0x00, 132 + LCD_INSTR_CMD, 0x70, 133 + LCD_INSTR_DAT, 0x00, 134 + LCD_INSTR_DAT, 0x01, 135 + 136 + LCD_INSTR_CMD, 0x00, 137 + LCD_INSTR_CMD, 0x91, 138 + LCD_INSTR_DAT, 0x01, 139 + LCD_INSTR_DAT, 0x00, 140 + 141 + LCD_INSTR_CMD, 0x00, 142 + LCD_INSTR_CMD, 0xe0, 143 + LCD_INSTR_DAT, 0x00, 144 + LCD_INSTR_DAT, 0x01, 145 + 146 + LCD_INSTR_CMD, 0x00, 147 + LCD_INSTR_CMD, 0xe1, 148 + LCD_INSTR_DAT, 0x00, 149 + LCD_INSTR_DAT, 0x61, 150 + 151 + LCD_INSTR_CMD, 0x01, 152 + LCD_INSTR_CMD, 0x00, 153 + LCD_INSTR_DAT, 0x10, 154 + LCD_INSTR_DAT, 0x30, 155 + 156 + LCD_INSTR_CMD, 0x01, 157 + LCD_INSTR_CMD, 0x01, 158 + LCD_INSTR_DAT, 0xf6, 159 + LCD_INSTR_DAT, 0x3f, 160 + 161 + LCD_INSTR_CMD, 0x01, 162 + LCD_INSTR_CMD, 0x02, 163 + LCD_INSTR_DAT, 0x50, 164 + LCD_INSTR_DAT, 0x1f, 165 + 166 + LCD_INSTR_CMD, 0x01, 167 + LCD_INSTR_CMD, 0x03, 168 + LCD_INSTR_DAT, 0x00, 169 + LCD_INSTR_DAT, 0x30, 170 + 171 + LCD_INSTR_CMD, 0x01, 172 + LCD_INSTR_CMD, 0x08, 173 + LCD_INSTR_DAT, 0x03, 174 + LCD_INSTR_DAT, 0x00, 175 + 176 + LCD_INSTR_CMD, 0x01, 177 + LCD_INSTR_CMD, 0x11, 178 + LCD_INSTR_DAT, 0x00, 179 + LCD_INSTR_DAT, 0x01, 180 + 181 + LCD_INSTR_CMD, 0x01, 182 + LCD_INSTR_CMD, 0x35, 183 + LCD_INSTR_DAT, 0x76, 184 + LCD_INSTR_DAT, 0x66, 185 + 186 + LCD_INSTR_CMD, 0x01, 187 + LCD_INSTR_CMD, 0x39, 188 + LCD_INSTR_DAT, 0x00, 189 + LCD_INSTR_DAT, 0x26, 190 + 191 + LCD_INSTR_CMD, 0x04, 192 + LCD_INSTR_CMD, 0x00, 193 + LCD_INSTR_DAT, 0x00, 194 + LCD_INSTR_DAT, 0xc7, 195 + 196 + LCD_INSTR_CMD, 0x04, 197 + LCD_INSTR_CMD, 0x01, 198 + LCD_INSTR_DAT, 0x00, 199 + LCD_INSTR_DAT, 0x00, 200 + 201 + LCD_INSTR_CMD, 0x06, 202 + LCD_INSTR_CMD, 0x06, 203 + LCD_INSTR_DAT, 0x00, 204 + LCD_INSTR_DAT, 0x00, 205 + 206 + LCD_INSTR_CMD, 0x03, 207 + LCD_INSTR_CMD, 0x00, 208 + LCD_INSTR_DAT, 0x0d, 209 + LCD_INSTR_DAT, 0x0e, 210 + 211 + LCD_INSTR_CMD, 0x03, 212 + LCD_INSTR_CMD, 0x01, 213 + LCD_INSTR_DAT, 0x00, 214 + LCD_INSTR_DAT, 0x03, 215 + 216 + LCD_INSTR_CMD, 0x03, 217 + LCD_INSTR_CMD, 0x02, 218 + LCD_INSTR_DAT, 0x08, 219 + LCD_INSTR_DAT, 0x08, 220 + 221 + LCD_INSTR_CMD, 0x03, 222 + LCD_INSTR_CMD, 0x03, 223 + LCD_INSTR_DAT, 0x02, 224 + LCD_INSTR_DAT, 0x01, 225 + 226 + LCD_INSTR_CMD, 0x03, 227 + LCD_INSTR_CMD, 0x04, 228 + LCD_INSTR_DAT, 0x03, 229 + LCD_INSTR_DAT, 0x01, 230 + 231 + LCD_INSTR_CMD, 0x03, 232 + LCD_INSTR_CMD, 0x05, 233 + LCD_INSTR_DAT, 0x00, 234 + LCD_INSTR_DAT, 0x04, 235 + 236 + LCD_INSTR_CMD, 0x03, 237 + LCD_INSTR_CMD, 0x06, 238 + LCD_INSTR_DAT, 0x1b, 239 + LCD_INSTR_DAT, 0x21, 240 + 241 + LCD_INSTR_CMD, 0x03, 242 + LCD_INSTR_CMD, 0x07, 243 + LCD_INSTR_DAT, 0x0f, 244 + LCD_INSTR_DAT, 0x0e, 245 + 246 + LCD_INSTR_CMD, 0x03, 247 + LCD_INSTR_CMD, 0x08, 248 + LCD_INSTR_DAT, 0x01, 249 + LCD_INSTR_DAT, 0x04, 250 + 251 + LCD_INSTR_CMD, 0x03, 252 + LCD_INSTR_CMD, 0x09, 253 + LCD_INSTR_DAT, 0x08, 254 + LCD_INSTR_DAT, 0x08, 255 + 256 + LCD_INSTR_CMD, 0x03, 257 + LCD_INSTR_CMD, 0x0a, 258 + LCD_INSTR_DAT, 0x02, 259 + LCD_INSTR_DAT, 0x01, 260 + 261 + LCD_INSTR_CMD, 0x03, 262 + LCD_INSTR_CMD, 0x0b, 263 + LCD_INSTR_DAT, 0x03, 264 + LCD_INSTR_DAT, 0x01, 265 + 266 + LCD_INSTR_CMD, 0x03, 267 + LCD_INSTR_CMD, 0x0c, 268 + LCD_INSTR_DAT, 0x00, 269 + LCD_INSTR_DAT, 0x03, 270 + 271 + LCD_INSTR_CMD, 0x03, 272 + LCD_INSTR_CMD, 0x0d, 273 + LCD_INSTR_DAT, 0x31, 274 + LCD_INSTR_DAT, 0x34, 275 + 276 + /* X start */ 277 + LCD_INSTR_CMD, 0x02, 278 + LCD_INSTR_CMD, 0x10, 279 + LCD_INSTR_DAT, 0x00, 280 + LCD_INSTR_DAT, 0x1e, /* 30 */ 281 + 282 + /* X end */ 283 + LCD_INSTR_CMD, 0x02, 284 + LCD_INSTR_CMD, 0x11, 285 + LCD_INSTR_DAT, 0x01, 286 + LCD_INSTR_DAT, 0x85, /* 389 */ 287 + 288 + /* Y start */ 289 + LCD_INSTR_CMD, 0x02, 290 + LCD_INSTR_CMD, 0x12, 291 + LCD_INSTR_DAT, 0x00, 292 + LCD_INSTR_DAT, 0x00, /* 0 */ 293 + 294 + /* Y end */ 295 + LCD_INSTR_CMD, 0x02, 296 + LCD_INSTR_CMD, 0x13, 297 + LCD_INSTR_DAT, 0x01, 298 + LCD_INSTR_DAT, 0x8f, /* 399 */ 299 + 300 + /* RAM write start X? */ 301 + LCD_INSTR_CMD, 0x02, 302 + LCD_INSTR_CMD, 0x00, 303 + LCD_INSTR_DAT, 0x00, 304 + LCD_INSTR_DAT, 0x1e, 305 + 306 + /* RAM write start Y? */ 307 + LCD_INSTR_CMD, 0x02, 308 + LCD_INSTR_CMD, 0x01, 309 + LCD_INSTR_DAT, 0x00, 310 + LCD_INSTR_DAT, 0x00, 311 + 312 + LCD_INSTR_CMD, 0x00, 313 + LCD_INSTR_CMD, 0x03, 314 + LCD_INSTR_DAT, 0x00, 315 + LCD_INSTR_DAT, 0x30, 316 + 317 + LCD_INSTR_CMD, 0x02, 318 + LCD_INSTR_CMD, 0x02, 319 + LCD_INSTR_END, 320 + }; 321 + 322 + /* NOTE this sleep mode may not be saving power, but it gets rid of the 323 + * ghost image that would otherwise remain on the display */ 324 + static const uint32_t q1_lcd_cmd_sleep[] = { 325 + LCD_INSTR_CMD, 0x00, 326 + LCD_INSTR_CMD, 0x10, 327 + LCD_INSTR_DAT, 0x00, 328 + LCD_INSTR_DAT, 0x03, 329 + 330 + LCD_INSTR_CMD, 0x00, 331 + LCD_INSTR_CMD, 0x07, 332 + LCD_INSTR_DAT, 0x01, 333 + LCD_INSTR_DAT, 0x01, 334 + 335 + LCD_INSTR_END, 336 + }; 337 + 338 + static const uint32_t q1_lcd_cmd_wake[] = { 339 + LCD_INSTR_CMD, 0x00, 340 + LCD_INSTR_CMD, 0x07, 341 + LCD_INSTR_DAT, 0x01, 342 + LCD_INSTR_DAT, 0x03, 343 + 344 + LCD_INSTR_CMD, 0x00, 345 + LCD_INSTR_CMD, 0x10, 346 + LCD_INSTR_DAT, 0x00, 347 + LCD_INSTR_DAT, 0xc1, 348 + 349 + LCD_INSTR_END, 350 + }; 351 + 352 + static const uint8_t __attribute__((aligned(64))) 353 + q1_lcd_dma_wr_cmd[] = {0x02, 0x02, 0x02, 0x02}; 354 + 355 + const struct lcd_tgt_config lcd_tgt_config = { 356 + .bus_width = 8, 357 + .cmd_width = 8, 358 + .use_6800_mode = 0, 359 + .use_serial = 0, 360 + .clk_polarity = 0, 361 + .dc_polarity = 0, 362 + .wr_polarity = 1, 363 + .te_enable = 0, 364 + .big_endian = 1, 365 + .dma_wr_cmd_buf = &q1_lcd_dma_wr_cmd, 366 + .dma_wr_cmd_size = sizeof(q1_lcd_dma_wr_cmd), 367 + }; 368 + 369 + void lcd_tgt_enable(bool enable) 370 + { 371 + if(enable) { 372 + /* power on the panel */ 373 + gpio_set_level(GPIO_LCD_PWR, 1); 374 + gpio_set_level(GPIO_LCD_RST, 1); 375 + gpio_set_level(GPIO_LCD_CE, 1); 376 + gpio_set_level(GPIO_LCD_RD, 1); 377 + mdelay(50); 378 + gpio_set_level(GPIO_LCD_RST, 0); 379 + mdelay(100); 380 + gpio_set_level(GPIO_LCD_RST, 1); 381 + mdelay(50); 382 + gpio_set_level(GPIO_LCD_CE, 0); 383 + 384 + /* Start the controller */ 385 + lcd_set_clock(X1000_CLK_MPLL, 50000000); 386 + lcd_exec_commands(q1_lcd_cmd_enable); 387 + } else { 388 + /* FIXME: Shanling Q1 LCD power down sequence 389 + * not important because we don't use it but it'd be nice to know */ 390 + } 391 + } 392 + 393 + void lcd_tgt_sleep(bool sleep) 394 + { 395 + if(sleep) 396 + lcd_exec_commands(q1_lcd_cmd_sleep); 397 + else 398 + lcd_exec_commands(q1_lcd_cmd_wake); 399 + }
+140
firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c
··· 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 "power.h" 23 + #include "adc.h" 24 + #include "system.h" 25 + #include "axp-pmu.h" 26 + #ifdef HAVE_CW2015 27 + # include "cw2015.h" 28 + #endif 29 + #ifdef HAVE_USB_CHARGING_ENABLE 30 + # include "usb_core.h" 31 + #endif 32 + 33 + #include "i2c-x1000.h" 34 + 35 + /* TODO: Better(?) battery reporting for Q1 using CW2015 driver 36 + * 37 + * The CW2015 has its own quirks so the driver has to be more complicated 38 + * than "read stuff from I2C," unfortunately. Without fixing the quirks it 39 + * is probably worse than the simple voltage-based method. 40 + * 41 + * A bigger problem is that it shares an I2C bus with the AXP192, but when 42 + * we attempt to communicate with both chips, they start returning bogus 43 + * data intermittently. Ususally, reads will return 0 but sometimes they 44 + * can return other nonzero bogus data. It could be that one or the other is 45 + * pulling the bus line down inappropriately, or maybe the hardware does not 46 + * respect the bus free time between start/stop conditions and one of the 47 + * devices is getting confused. 48 + */ 49 + 50 + const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = 51 + { 52 + 3470 53 + }; 54 + 55 + /* the OF shuts down at this voltage */ 56 + const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = 57 + { 58 + 3400 59 + }; 60 + 61 + /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ 62 + const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = 63 + { 64 + { 3400, 3639, 3697, 3723, 3757, 3786, 3836, 3906, 3980, 4050, 4159 } 65 + }; 66 + 67 + /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ 68 + const unsigned short percent_to_volt_charge[11] = 69 + { 70 + 3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196 71 + }; 72 + 73 + void power_init(void) 74 + { 75 + i2c_x1000_set_freq(AXP_PMU_BUS, I2C_FREQ_400K); 76 + axp_init(); 77 + #ifdef HAVE_CW2015 78 + cw2015_init(); 79 + #endif 80 + 81 + /* Change supply voltage from the default of 1250 mV to 1200 mV, 82 + * this matches the original firmware's settings. Didn't observe 83 + * any obviously bad behavior at 1250 mV, but better to be safe. */ 84 + axp_supply_set_voltage(AXP_SUPPLY_DCDC2, 1200); 85 + 86 + /* For now, just turn everything on... definitely the touchscreen 87 + * is powered by one of the outputs */ 88 + i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, 89 + AXP_REG_PWROUTPUTCTRL1, 0, 0x05, NULL); 90 + i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, 91 + AXP_REG_PWROUTPUTCTRL2, 0, 0x0f, NULL); 92 + i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, 93 + AXP_REG_DCDCWORKINGMODE, 0, 0xc0, NULL); 94 + 95 + /* Delay to give power output time to stabilize */ 96 + mdelay(20); 97 + } 98 + 99 + #ifdef HAVE_USB_CHARGING_ENABLE 100 + void usb_charging_maxcurrent_change(int maxcurrent) 101 + { 102 + axp_set_charge_current(maxcurrent); 103 + } 104 + #endif 105 + 106 + void power_off(void) 107 + { 108 + axp_power_off(); 109 + while(1); 110 + } 111 + 112 + bool charging_state(void) 113 + { 114 + return axp_battery_status() == AXP_BATT_CHARGING; 115 + } 116 + 117 + int _battery_voltage(void) 118 + { 119 + /* CW2015 can also read battery voltage, but the AXP consistently 120 + * reads ~20-30 mV higher so I suspect it's the "real" voltage. */ 121 + return axp_adc_read(ADC_BATTERY_VOLTAGE); 122 + } 123 + 124 + #if defined(HAVE_CW2015) && (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) != 0 125 + int _battery_level(void) 126 + { 127 + return cw2015_get_soc(); 128 + } 129 + #endif 130 + 131 + #if defined(HAVE_CW2015) && (CONFIG_BATTERY_MEASURE & TIME_MEASURE) != 0 132 + int _battery_time(void) 133 + { 134 + return cw2015_get_rrt(); 135 + } 136 + #endif 137 + 138 + void adc_init(void) 139 + { 140 + }
+116
firmware/target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c
··· 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 + #define CMDLINE_COMMON \ 28 + "mem=64M@0x0 no_console_suspend console=ttyS2,115200n8 lpj=5009408 ip=off" 29 + #define CMDLINE_NORMAL \ 30 + " init=/linuxrc ubi.mtd=5 root=ubi0:rootfs ubi.mtd=6 rootfstype=ubifs rw" 31 + 32 + static int dualboot_setup(void) 33 + { 34 + spl_dualboot_init_clocktree(); 35 + spl_dualboot_init_uart2(); 36 + 37 + /* load PDMA MCU firmware */ 38 + jz_writef(CPM_CLKGR, PDMA(0)); 39 + return spl_storage_read(0x4000, 0x2000, (void*)0xb3422000); 40 + } 41 + 42 + const struct spl_boot_option spl_boot_options[] = { 43 + [BOOT_OPTION_ROCKBOX] = { 44 + .storage_addr = 0x6800, 45 + .storage_size = 102 * 1024, 46 + .load_addr = X1000_DRAM_BASE, 47 + .exec_addr = X1000_DRAM_BASE, 48 + .flags = BOOTFLAG_UCLPACK, 49 + }, 50 + [BOOT_OPTION_OFW_PLAYER] = { 51 + .storage_addr = 0x140000, 52 + .storage_size = 8 * 1024 * 1024, 53 + .load_addr = 0x80efffc0, 54 + .exec_addr = 0x80f00000, 55 + .cmdline = CMDLINE_COMMON CMDLINE_NORMAL, 56 + .cmdline_addr = 0x80004000, 57 + .setup = dualboot_setup, 58 + }, 59 + [BOOT_OPTION_OFW_RECOVERY] = { 60 + .storage_addr = 0x940000, 61 + .storage_size = 10 * 1024 * 1024, 62 + .load_addr = 0x80efffc0, 63 + .exec_addr = 0x80f00000, 64 + .cmdline = CMDLINE_COMMON, 65 + .cmdline_addr = 0x80004000, 66 + .setup = dualboot_setup, 67 + }, 68 + }; 69 + 70 + int spl_get_boot_option(void) 71 + { 72 + /* Button debounce time in OST clock cycles */ 73 + const uint32_t btn_stable_time = 100 * (X1000_EXCLK_FREQ / 4000); 74 + 75 + /* Buttons to poll */ 76 + const unsigned port = GPIO_B; 77 + const uint32_t recov_pin = (1 << 22); /* Next */ 78 + const uint32_t orig_fw_pin = (1 << 21); /* Prev */ 79 + 80 + uint32_t pin = -1, lastpin = 0; 81 + uint32_t deadline = 0; 82 + int iter_count = 30; /* to avoid an infinite loop */ 83 + 84 + /* set GPIOs to input state */ 85 + gpioz_configure(port, recov_pin|orig_fw_pin, GPIOF_INPUT); 86 + 87 + /* Poll until we get a stable reading */ 88 + do { 89 + lastpin = pin; 90 + pin = ~REG_GPIO_PIN(port) & (recov_pin|orig_fw_pin); 91 + if(pin != lastpin) { 92 + deadline = __ost_read32() + btn_stable_time; 93 + iter_count -= 1; 94 + } 95 + } while(iter_count > 0 && __ost_read32() < deadline); 96 + 97 + if(iter_count >= 0 && (pin & orig_fw_pin)) { 98 + if(pin & recov_pin) 99 + return BOOT_OPTION_OFW_RECOVERY; 100 + else 101 + return BOOT_OPTION_OFW_PLAYER; 102 + } 103 + 104 + return BOOT_OPTION_ROCKBOX; 105 + } 106 + 107 + void spl_error(void) 108 + { 109 + /* Flash the backlight */ 110 + int level = 0; 111 + while(1) { 112 + gpio_set_function(GPIO_PC(25), GPIOF_OUTPUT(level)); 113 + mdelay(100); 114 + level = 1 - level; 115 + } 116 + }
+1 -1
firmware/target/mips/ingenic_x1000/spl-x1000.c
··· 34 34 #include "ucl_decompress.h" 35 35 #include <string.h> 36 36 37 - #ifdef FIIO_M3K 37 + #if defined(FIIO_M3K) || defined(SHANLING_Q1) 38 38 # define SPL_DDR_MEMORYSIZE 64 39 39 # define SPL_DDR_AUTOSR_EN 1 40 40 # define SPL_DDR_NEED_BYPASS 1
+26 -1
tools/configure
··· 1597 1597 240) Rocker 228) NWZ-A860 series 1598 1598 ==FiiO== 229) NWZ-S750 series 1599 1599 ==AIGO== 244) M3K Linux 1600 - 245) Eros Q / K 246) M3K baremetal 1600 + 245) Eros Q / K 246) M3K baremetal ==Shanling== 1601 + 260) Q1 1601 1602 EOF 1602 1603 1603 1604 buildfor=`input`; ··· 4106 4107 t_cpu="mips" 4107 4108 t_manufacturer="ingenic_x1000" 4108 4109 t_model="fiiom3k" 4110 + ;; 4111 + 4112 + 260|shanlingq1) 4113 + target_id=115 4114 + modelname="shanlingq1" 4115 + target="SHANLING_Q1" 4116 + memory=64 4117 + mipsr2elcc 4118 + appextra="recorder:gui" 4119 + plugins="yes" 4120 + tool="$rootdir/tools/scramble -add=shq1 " 4121 + boottool="" # not used 4122 + output="rockbox.q1" 4123 + bootoutput="bootloader.q1" 4124 + sysfontbl="16-Terminus" 4125 + # toolset is the tools within the tools directory that we build for 4126 + # this particular target. 4127 + toolset="$x1000tools" 4128 + bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" 4129 + bmp2rb_native="$rootdir/tools/bmp2rb -f 4" 4130 + # architecture, manufacturer and model for the target-tree build 4131 + t_cpu="mips" 4132 + t_manufacturer="ingenic_x1000" 4133 + t_model="shanlingq1" 4109 4134 ;; 4110 4135 4111 4136 *)
+2
tools/scramble.c
··· 333 333 modelnum = 109; 334 334 else if (!strcmp(&argv[1][5], "fiiom3k")) /* FiiO M3K */ 335 335 modelnum = 114; 336 + else if (!strcmp(&argv[1][5], "shq1")) /* Shanling Q1 */ 337 + modelnum = 115; 336 338 else { 337 339 fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); 338 340 return 2;
uisimulator/bitmaps/UI-shanlingq1.bmp

This is a binary file and will not be displayed.

+2
uisimulator/buttonmap/SOURCES
··· 85 85 erosq.c 86 86 #elif CONFIG_KEYPAD == FIIO_M3K_PAD 87 87 fiio-m3k.c 88 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 89 + shanling-q1.c 88 90 #endif 89 91 #endif /* SIMULATOR */
+72
uisimulator/buttonmap/shanling-q1.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2021 by 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 + 23 + #include <SDL.h> 24 + #include "button.h" 25 + #include "buttonmap.h" 26 + 27 + int key_to_button(int keyboard_button) 28 + { 29 + int new_btn = BUTTON_NONE; 30 + switch (keyboard_button) 31 + { 32 + case SDLK_KP8: 33 + case SDLK_UP: 34 + new_btn = BUTTON_PREV; 35 + break; 36 + 37 + case SDLK_KP2: 38 + case SDLK_DOWN: 39 + new_btn = BUTTON_NEXT; 40 + break; 41 + 42 + case SDLK_KP5: 43 + case SDLK_RETURN: 44 + case SDLK_SPACE: 45 + new_btn = BUTTON_PLAY; 46 + break; 47 + 48 + case SDLK_ESCAPE: 49 + new_btn = BUTTON_POWER; 50 + break; 51 + 52 + case SDLK_KP_PLUS: 53 + case SDLK_EQUALS: 54 + new_btn = BUTTON_VOL_UP; 55 + break; 56 + 57 + case SDLK_KP_MINUS: 58 + case SDLK_MINUS: 59 + new_btn = BUTTON_VOL_DOWN; 60 + break; 61 + } 62 + return new_btn; 63 + } 64 + 65 + struct button_map bm[] = { 66 + { SDLK_KP_PLUS, 426, 140, 40, "Volume +" }, 67 + { SDLK_KP_MINUS, 426, 180, 40, "Volume -" }, 68 + { SDLK_SPACE, 0, 244, 40, "Play" }, 69 + { SDLK_UP, 0, 133, 40, "Previous" }, 70 + { SDLK_DOWN, 0, 357, 40, "Next" }, 71 + { 0, 0, 0, 0, "None" } 72 + };
+1
wps/AUTHORS
··· 16 16 Johannes Voggenthaler 17 17 Jonathan Gordon 18 18 Keith Perri 19 + Marc Aarts 19 20 Marc Guay 20 21 Marcin Bukat 21 22 Marianne Arnold
+5
wps/WPSLIST
··· 82 82 wps.800x480x(16|24): cabbiev2.800x480x16.wps 83 83 wps.480x800x(16|24): cabbiev2.480x800x16.wps 84 84 wps.400x240x(16|24): cabbiev2.400x240x16.wps 85 + wps.360x400x16: cabbiev2.360x400x16.wps 85 86 wps.320x480x(16|24): cabbiev2.320x480x16.wps 86 87 wps.320x240x(16|24|32): cabbiev2.320x240x16.wps 87 88 wps.240x400x(16|24): cabbiev2.240x400x16.wps ··· 111 112 Font.800x480x(16|24): 35-Adobe-Helvetica.fnt 112 113 Font.480x800x(16|24): 35-Adobe-Helvetica.fnt 113 114 Font.400x240x(16|24): 15-Adobe-Helvetica.fnt 115 + Font.360x400x16: 18-Adobe-Helvetica.fnt 114 116 Font.320x480x(16|24): 27-Adobe-Helvetica.fnt 115 117 Font.320x240x(16|24): 15-Adobe-Helvetica.fnt 116 118 Font.240x400x(16|24): 16-Adobe-Helvetica.fnt ··· 144 146 backdrop.800x480x(16|24): backdrops/cabbiev2.800x480x16.bmp 145 147 backdrop.480x800x(16|24): backdrops/cabbiev2.480x800x16.bmp 146 148 backdrop.400x240x(16|24): backdrops/cabbiev2.400x240x16.bmp 149 + backdrop.360x400x16: backdrops/cabbiev2.360x400x16.bmp 147 150 backdrop.320x480x(16|24): backdrops/cabbiev2.320x480x16.bmp 148 151 backdrop.320x240x(16|24): backdrops/cabbiev2.320x240x16.bmp 149 152 backdrop.128x128x(16|24): backdrops/cabbiev2.128x128x16.bmp ··· 170 173 iconset.800x480x(16|24): icons/tango_icons.32x32.bmp 171 174 iconset.480x800x(16|24): icons/tango_icons.32x32.bmp 172 175 iconset.400x240x(16|24): icons/tango_icons.16x16.bmp 176 + iconset.360x400x16: icons/tango_icons.32x32.bmp 173 177 iconset.320x480x(16|24): icons/tango_icons.24x24.bmp 174 178 iconset.320x240x(16|24|32): icons/tango_icons.16x16.bmp 175 179 iconset.128x128x(16|24): icons/tango_icons.12x12.bmp ··· 189 193 viewers iconset.800x480x(16|24): icons/tango_icons_viewers.32x32.bmp 190 194 viewers iconset.480x800x(16|24): icons/tango_icons_viewers.32x32.bmp 191 195 viewers iconset.400x240x(16|24): icons/tango_icons_viewers.16x16.bmp 196 + viewers iconset.360x400x16: icons/tango_icons_viewers.32x32.bmp 192 197 viewers iconset.320x480x(16|24): icons/tango_icons_viewers.24x24.bmp 193 198 viewers iconset.320x240x(16|24): icons/tango_icons_viewers.16x16.bmp 194 199 viewers iconset.128x128x(16|24): icons/tango_icons_viewers.12x12.bmp
+81
wps/cabbiev2.360x400x16.wps
··· 1 + # Cabbie v2.0 2 + # (C) 2007-2012 The Authors (see /rockbox/wps/AUTHORS) 3 + # Derived from "cabbie" (C) Yohann Misquitta 4 + # 5 + # Disable Status Bar 6 + %wd 7 + # 8 + # Load Backdrop 9 + %X(wpsbackdrop-360x400x16.bmp) 10 + # 11 + # Preload Images 12 + %xl(A,lock-360x400x16.bmp,0,0,2) 13 + %xl(B,battery-360x400x16.bmp,0,0,10) 14 + %xl(C,volume-360x400x16.bmp,0,0,10) 15 + %xl(D,shuffle-360x400x16.bmp,0,0) 16 + %xl(E,repeat-360x400x16.bmp,0,0,4) 17 + %xl(F,playmode-360x400x16.bmp,0,0,5) 18 + # 19 + # Album Art/Info Viewport Conditional 20 + %?C<%Vd(a)|%Vd(b)> 21 + # 22 + # Progress Bar 23 + %V(33,316,300,20,-) 24 + %pb(0,0,-,20,pb-360x400x16.bmp) 25 + # 26 + # Hold 27 + %V(16,365,38,29,-) 28 + %?mh<%xd(Aa)|%xd(Ab)> 29 + # 30 + # Battery 31 + %V(69,365,66,29,-) 32 + %?bp<%?bc<%xd(Ba)|%xd(Bb)>|%?bl<|%xd(Bc)|%xd(Bd)|%xd(Be)|%xd(Bf)|%xd(Bg)|%xd(Bh)|%xd(Bi)|%xd(Bj)>> 33 + # 34 + # Volume 35 + %V(147,365,50,29,-) 36 + %?pv<%xd(Ca)|%xd(Cb)|%xd(Cc)|%xd(Cd)|%xd(Ce)|%xd(Cf)|%xd(Cg)|%xd(Ch)|%xd(Ci)|%xd(Cj)> 37 + # 38 + # Shuffle 39 + %V(208,365,55,29,-) 40 + %?ps<%xd(D)> 41 + # 42 + # Repeat 43 + %V(273,365,27,29,-) 44 + %?mm<|%xd(Ea)|%xd(Eb)|%xd(Ec)|%xd(Ed)> 45 + # 46 + # Playmode 47 + %V(309,365,36,29,-) 48 + %?mp<%xd(Fa)|%xd(Fb)|%xd(Fc)|%xd(Fd)|%xd(Fe)> 49 + # 50 + # Time Elapsed/Remaining 51 + %V(32,339,300,20,-) 52 + %al%pc%ac%?Sr<%pe %Sx(of) %pp|%pp %Sx(of) %pe>%ar%pr 53 + # 54 + # Album Art 55 + %ax%Vl(a,82,38,195,161,-) 56 + %Cl(0,0,195,161,c,c) 57 + %Cd 58 + # 59 + # Track Info - Album Art 60 + %ax%Vl(a,0,206,-,98,1) 61 + %s%ac%?it<%it|%fn> 62 + %s%ac%?ia<%ia|%?iA<%iA|%?d(2)<%d(2)|%(root%)>>> 63 + %s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>> 64 + 65 + %s%ac%Sx(Next:) %?Ia<%Ia|%?IA<%IA|%?D(2)<%D(2)|%(root%)>>> - %?It<%It|%Fn> 66 + # 67 + # Track Info - No Album Art 68 + %Vl(b,0,56,-,247,1) 69 + %s%ac%?it<%it|%fn> 70 + %s%ac%?ia<%ia|%?iA<%iA|%?d(2)<%d(2)|%(root%)>>> 71 + %s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>> 72 + %ac%?iy<%iy|> 73 + 74 + %ac%?ig<%ig|> 75 + %ac%?fv<%(vbr%) |>%fb kbit/s %fc 76 + 77 + 78 + %ac%Sx(Next Track:) 79 + %ac%s%?It<%It|%Fn> 80 + %s%ac%?Ia<%Ia|%?IA<%IA|%?D(2)<%D(2)|%(root%)>>> 81 + %s%ac%?Id<%Id|%?D(1)<%D(1)|%(root%)>>
wps/cabbiev2/battery-360x400x16.bmp

This is a binary file and will not be displayed.

wps/cabbiev2/lock-360x400x16.bmp

This is a binary file and will not be displayed.

wps/cabbiev2/pb-360x400x16.bmp

This is a binary file and will not be displayed.

wps/cabbiev2/playmode-360x400x16.bmp

This is a binary file and will not be displayed.

wps/cabbiev2/repeat-360x400x16.bmp

This is a binary file and will not be displayed.

wps/cabbiev2/shuffle-360x400x16.bmp

This is a binary file and will not be displayed.

wps/cabbiev2/volume-360x400x16.bmp

This is a binary file and will not be displayed.

wps/cabbiev2/wpsbackdrop-360x400x16.bmp

This is a binary file and will not be displayed.