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 keymaps/keymap-fiiom3k.c 299 #elif CONFIG_KEYPAD == EROSQ_PAD 300 keymaps/keymap-erosq.c 301 #endif
··· 298 keymaps/keymap-fiiom3k.c 299 #elif CONFIG_KEYPAD == EROSQ_PAD 300 keymaps/keymap-erosq.c 301 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 302 + keymaps/keymap-shanlingq1.c 303 #endif
+6 -2
apps/features.txt
··· 182 #endif 183 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) 186 filter_roll_off 187 #endif 188 189 /* This should be AUDIOHW_HAVE_POWER_MODE but that is not defined yet */ 190 - #if defined(HAVE_AK4376) 191 dac_power_mode 192 #endif 193 194 #if defined(HAVE_ES9018) 195 es9018 196 #endif 197 198 /* These features are only used by the manual so they won't break binary
··· 182 #endif 183 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) || defined(HAVE_ES9218) 186 filter_roll_off 187 #endif 188 189 /* This should be AUDIOHW_HAVE_POWER_MODE but that is not defined yet */ 190 + #if defined(HAVE_AK4376) || defined(HAVE_ES9218) 191 dac_power_mode 192 #endif 193 194 #if defined(HAVE_ES9018) 195 es9018 196 + #endif 197 + 198 + #if defined(HAVE_ES9218) 199 + es9218 200 #endif 201 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 </voice> 12206 </phrase> 12207 <phrase> 12208 id: LANG_DAC_POWER_MODE 12209 desc: in sound settings 12210 user: core 12211 <source> 12212 *: none 12213 dac_power_mode: "DAC's power mode" 12214 </source> 12215 <dest> 12216 *: none 12217 dac_power_mode: "DAC's power mode" 12218 </dest> 12219 <voice> 12220 *: none 12221 dac_power_mode: "DAC's power mode" 12222 </voice> 12223 </phrase> 12224 <phrase> ··· 12228 <source> 12229 *: none 12230 dac_power_mode: "High performance" 12231 </source> 12232 <dest> 12233 *: none 12234 dac_power_mode: "High performance" 12235 </dest> 12236 <voice> 12237 *: none 12238 dac_power_mode: "High performance" 12239 </voice> 12240 </phrase> 12241 <phrase> ··· 12245 <source> 12246 *: none 12247 dac_power_mode: "Save battery" 12248 </source> 12249 <dest> 12250 *: none 12251 dac_power_mode: "Save battery" 12252 </dest> 12253 <voice> 12254 *: none 12255 dac_power_mode: "Save battery" 12256 </voice> 12257 </phrase> 12258 <phrase>
··· 12205 </voice> 12206 </phrase> 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> 12344 id: LANG_DAC_POWER_MODE 12345 desc: in sound settings 12346 user: core 12347 <source> 12348 *: none 12349 dac_power_mode: "DAC's power mode" 12350 + es9218: "DAC's output level" 12351 </source> 12352 <dest> 12353 *: none 12354 dac_power_mode: "DAC's power mode" 12355 + es9218: "DAC's output level" 12356 </dest> 12357 <voice> 12358 *: none 12359 dac_power_mode: "DAC's power mode" 12360 + es9218: "DAC's output level" 12361 </voice> 12362 </phrase> 12363 <phrase> ··· 12367 <source> 12368 *: none 12369 dac_power_mode: "High performance" 12370 + es9218: "High Gain (2 Vrms)" 12371 </source> 12372 <dest> 12373 *: none 12374 dac_power_mode: "High performance" 12375 + es9218: "High Gain (2 Vrms)" 12376 </dest> 12377 <voice> 12378 *: none 12379 dac_power_mode: "High performance" 12380 + es9218: "High Gain (2 Vrms)" 12381 </voice> 12382 </phrase> 12383 <phrase> ··· 12387 <source> 12388 *: none 12389 dac_power_mode: "Save battery" 12390 + es9218: "Low Gain (1 Vrms)" 12391 </source> 12392 <dest> 12393 *: none 12394 dac_power_mode: "Save battery" 12395 + es9218: "Low Gain (1 Vrms)" 12396 </dest> 12397 <voice> 12398 *: none 12399 dac_power_mode: "Save battery" 12400 + es9218: "Low Gain (1 Vrms)" 12401 </voice> 12402 </phrase> 12403 <phrase>
+3
apps/plugins/battery_bench.c
··· 234 #define BATTERY_ON_TXT "Play" 235 #define BATTERY_OFF_TXT "Power" 236 237 #else 238 #error "No keymap defined!" 239 #endif
··· 234 #define BATTERY_ON_TXT "Play" 235 #define BATTERY_OFF_TXT "Power" 236 237 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 238 + /* use touchscreen */ 239 + 240 #else 241 #error "No keymap defined!" 242 #endif
+2 -1
apps/plugins/bitmaps/mono/SOURCES
··· 19 ((LCD_WIDTH == 176) && (LCD_HEIGHT == 220)) 20 bubbles_bubble.220x176x1.bmp 21 #elif ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \ 22 - ((LCD_WIDTH == 240) && (LCD_HEIGHT >= 320)) 23 bubbles_bubble.320x240x1.bmp 24 #elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \ 25 ((LCD_WIDTH == 480) && (LCD_HEIGHT == 640))
··· 19 ((LCD_WIDTH == 176) && (LCD_HEIGHT == 220)) 20 bubbles_bubble.220x176x1.bmp 21 #elif ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \ 22 + ((LCD_WIDTH == 240) && (LCD_HEIGHT >= 320)) || \ 23 + ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) 24 bubbles_bubble.320x240x1.bmp 25 #elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \ 26 ((LCD_WIDTH == 480) && (LCD_HEIGHT == 640))
+20 -2
apps/plugins/bitmaps/native/SOURCES
··· 158 ((LCD_WIDTH >= 480) && (LCD_HEIGHT >= 640)) 159 bubbles_emblem.640x480x16.bmp 160 bubbles_background.640x480x16.bmp 161 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 162 bubbles_emblem.320x240x16.bmp 163 bubbles_background.320x240x16.bmp ··· 388 invadrox_ufo.16x7x16.bmp 389 invadrox_ufo_explode.21x8x16.bmp 390 invadrox_numbers.50x7x16.bmp 391 - #if LCD_WIDTH == 320 392 invadrox_background.320x240x16.bmp 393 #elif LCD_WIDTH == 240 394 invadrox_background.240x320x16.bmp ··· 457 jewels.320x240x16.bmp 458 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) 459 jewels.320x240x16.bmp 460 #elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \ 461 ((LCD_WIDTH == 480) && (LCD_HEIGHT == 640)) 462 jewels.640x480x16.bmp ··· 546 #if LCD_DEPTH >= 16 /* colour versions*/ 547 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480) 548 rockblox_background.640x480x16.bmp 549 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 550 rockblox_background.320x240x16.bmp 551 #elif (LCD_WIDTH == 240) && (LCD_HEIGHT >= 320) ··· 603 snake2_left.640x480x16.bmp 604 snake2_right.640x480x16.bmp 605 snake2_bottom.640x480x16.bmp 606 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) && (LCD_DEPTH >= 16) 607 snake2_header1.320x240x16.bmp 608 snake2_header2.320x240x16.bmp ··· 874 #elif (LCD_WIDTH == 320 && LCD_HEIGHT == 240) 875 superdom_boarditems.320x240x16.bmp 876 #elif ((LCD_WIDTH == 240) && (LCD_HEIGHT == 320)) || \ 877 - ((LCD_WIDTH == 240) && (LCD_HEIGHT == 400)) 878 superdom_boarditems.240x320x16.bmp 879 #elif (LCD_WIDTH == 480 && LCD_HEIGHT == 640) 880 superdom_boarditems.480x640x16.bmp ··· 911 sliding_puzzle.176x176x16.bmp 912 #elif SMALLER_DIMENSION <= 240 913 sliding_puzzle.240x240x16.bmp 914 #elif SMALLER_DIMENSION <= 480 915 sliding_puzzle.480x480x16.bmp 916 #endif
··· 158 ((LCD_WIDTH >= 480) && (LCD_HEIGHT >= 640)) 159 bubbles_emblem.640x480x16.bmp 160 bubbles_background.640x480x16.bmp 161 + #elif (LCD_WIDTH >= 360) && (LCD_HEIGHT >= 400) 162 + bubbles_emblem.360x400x16.bmp 163 + bubbles_background.360x400x16.bmp 164 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 165 bubbles_emblem.320x240x16.bmp 166 bubbles_background.320x240x16.bmp ··· 391 invadrox_ufo.16x7x16.bmp 392 invadrox_ufo_explode.21x8x16.bmp 393 invadrox_numbers.50x7x16.bmp 394 + #if LCD_WIDTH == 360 && LCD_HEIGHT == 400 395 + invadrox_background.360x400x16.bmp 396 + #elif LCD_WIDTH == 320 397 invadrox_background.320x240x16.bmp 398 #elif LCD_WIDTH == 240 399 invadrox_background.240x320x16.bmp ··· 462 jewels.320x240x16.bmp 463 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) 464 jewels.320x240x16.bmp 465 + #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400) 466 + jewels.360x400x16.bmp 467 #elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \ 468 ((LCD_WIDTH == 480) && (LCD_HEIGHT == 640)) 469 jewels.640x480x16.bmp ··· 553 #if LCD_DEPTH >= 16 /* colour versions*/ 554 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480) 555 rockblox_background.640x480x16.bmp 556 + #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400) 557 + rockblox_background.360x400x16.bmp 558 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 559 rockblox_background.320x240x16.bmp 560 #elif (LCD_WIDTH == 240) && (LCD_HEIGHT >= 320) ··· 612 snake2_left.640x480x16.bmp 613 snake2_right.640x480x16.bmp 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 621 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) && (LCD_DEPTH >= 16) 622 snake2_header1.320x240x16.bmp 623 snake2_header2.320x240x16.bmp ··· 889 #elif (LCD_WIDTH == 320 && LCD_HEIGHT == 240) 890 superdom_boarditems.320x240x16.bmp 891 #elif ((LCD_WIDTH == 240) && (LCD_HEIGHT == 320)) || \ 892 + ((LCD_WIDTH == 240) && (LCD_HEIGHT == 400)) || \ 893 + ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) 894 superdom_boarditems.240x320x16.bmp 895 #elif (LCD_WIDTH == 480 && LCD_HEIGHT == 640) 896 superdom_boarditems.480x640x16.bmp ··· 927 sliding_puzzle.176x176x16.bmp 928 #elif SMALLER_DIMENSION <= 240 929 sliding_puzzle.240x240x16.bmp 930 + #elif SMALLER_DIMENSION <= 360 931 + sliding_puzzle.360x360x16.bmp 932 #elif SMALLER_DIMENSION <= 480 933 sliding_puzzle.480x480x16.bmp 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 #define BJACK_RIGHT BUTTON_RIGHT 608 #define BJACK_LEFT BUTTON_LEFT 609 610 #else 611 #error No keymap defined! 612 #endif
··· 607 #define BJACK_RIGHT BUTTON_RIGHT 608 #define BJACK_LEFT BUTTON_LEFT 609 610 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 611 + #define BJACK_QUIT BUTTON_POWER 612 + #define BJACK_QUIT_NAME "QUIT" 613 + 614 #else 615 #error No keymap defined! 616 #endif
+3
apps/plugins/brickmania.c
··· 350 #define UP BUTTON_UP 351 #define DOWN BUTTON_DOWN 352 353 #else 354 #error No keymap defined! 355 #endif
··· 350 #define UP BUTTON_UP 351 #define DOWN BUTTON_DOWN 352 353 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 354 + #define QUIT BUTTON_POWER 355 + 356 #else 357 #error No keymap defined! 358 #endif
+11
apps/plugins/bubbles.c
··· 120 #define XOFS 128 121 #define MAX_FPS 40 122 123 /* 22x22 bubbles (iPod Video) */ 124 #elif (LCD_HEIGHT == 240) && (LCD_WIDTH == 320) 125 #define XOFS 72
··· 120 #define XOFS 128 121 #define MAX_FPS 40 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 + 134 /* 22x22 bubbles (iPod Video) */ 135 #elif (LCD_HEIGHT == 240) && (LCD_WIDTH == 320) 136 #define XOFS 72
+3
apps/plugins/calculator.c
··· 533 #define CALCULATOR_CALC BUTTON_MENU 534 #define CALCULATOR_CLEAR BUTTON_BACK 535 536 #else 537 #error No keymap defined! 538 #endif
··· 533 #define CALCULATOR_CALC BUTTON_MENU 534 #define CALCULATOR_CLEAR BUTTON_BACK 535 536 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 537 + #define CALCULATOR_QUIT BUTTON_POWER 538 + 539 #else 540 #error No keymap defined! 541 #endif
+3
apps/plugins/calendar.c
··· 421 #define CALENDAR_NEXT_MONTH BUTTON_VOL_UP 422 #define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN 423 424 #else 425 #error "No keypad setting." 426 #endif
··· 421 #define CALENDAR_NEXT_MONTH BUTTON_VOL_UP 422 #define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN 423 424 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 425 + /* use touchscreen */ 426 + 427 #else 428 #error "No keypad setting." 429 #endif
+3
apps/plugins/chessbox/chessbox_pgn.h
··· 581 #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) 582 #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) 583 584 #else 585 #error No keymap defined! 586 #endif
··· 581 #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) 582 #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) 583 584 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 585 + /* use touchscreen */ 586 + 587 #else 588 #error No keymap defined! 589 #endif
+3
apps/plugins/chessclock.c
··· 395 #define CHC_SETTINGS_OK BUTTON_SELECT 396 #define CHC_SETTINGS_CANCEL BUTTON_POWER 397 398 #else 399 #error No keymap defined! 400 #endif
··· 395 #define CHC_SETTINGS_OK BUTTON_SELECT 396 #define CHC_SETTINGS_CANCEL BUTTON_POWER 397 398 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 399 + #define CHC_QUIT BUTTON_POWER 400 + 401 #else 402 #error No keymap defined! 403 #endif
+3
apps/plugins/chip8.c
··· 1291 #define CHIP8_KEY6 BUTTON_RIGHT 1292 #define CHIP8_KEY8 BUTTON_BACK 1293 1294 #else 1295 #error No keymap defined! 1296 #endif
··· 1291 #define CHIP8_KEY6 BUTTON_RIGHT 1292 #define CHIP8_KEY8 BUTTON_BACK 1293 1294 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 1295 + /* use touchscreen */ 1296 + 1297 #else 1298 #error No keymap defined! 1299 #endif
+3
apps/plugins/clix.c
··· 316 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT 317 #define CLIX_BUTTON_CLICK BUTTON_SELECT 318 319 #else 320 #error "no keymap" 321 #endif
··· 316 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT 317 #define CLIX_BUTTON_CLICK BUTTON_SELECT 318 319 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 320 + #define CLIX_BUTTON_QUIT BUTTON_POWER 321 + 322 #else 323 #error "no keymap" 324 #endif
+3
apps/plugins/cube.c
··· 400 #define CUBE_PAUSE BUTTON_PLAY 401 #define CUBE_HIGHSPEED BUTTON_BACK 402 403 #else 404 #error No keymap defined! 405 #endif
··· 400 #define CUBE_PAUSE BUTTON_PLAY 401 #define CUBE_HIGHSPEED BUTTON_BACK 402 403 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 404 + /* use touchscreen */ 405 + 406 #else 407 #error No keymap defined! 408 #endif
+4
apps/plugins/doom/i_video.c
··· 614 #define DOOMBUTTON_WEAPON BUTTON_VOL_UP 615 #define DOOMBUTTON_MAP BUTTON_VOL_DOWN 616 617 #else 618 #error Keymap not defined! 619 #endif
··· 614 #define DOOMBUTTON_WEAPON BUTTON_VOL_UP 615 #define DOOMBUTTON_MAP BUTTON_VOL_DOWN 616 617 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 618 + #define DOOMBUTTON_ESC BUTTON_POWER 619 + #define DOOMBUTTON_MAP BUTTON_PREV 620 + 621 #else 622 #error Keymap not defined! 623 #endif
+3
apps/plugins/flipit.c
··· 496 #define FLIPIT_STEP_BY_STEP BUTTON_VOL_UP 497 #define FLIPIT_TOGGLE BUTTON_SELECT 498 499 #else 500 #error No keymap defined! 501 #endif
··· 496 #define FLIPIT_STEP_BY_STEP BUTTON_VOL_UP 497 #define FLIPIT_TOGGLE BUTTON_SELECT 498 499 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 500 + /* use touchscreen */ 501 + 502 #else 503 #error No keymap defined! 504 #endif
+3
apps/plugins/fractals/fractal.h
··· 504 #define FRACTAL_PRECISION_DEC BUTTON_BACK 505 #define FRACTAL_RESET BUTTON_PLAY 506 507 #else 508 #error No keymap defined! 509 #endif
··· 504 #define FRACTAL_PRECISION_DEC BUTTON_BACK 505 #define FRACTAL_RESET BUTTON_PLAY 506 507 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 508 + #define FRACTAL_QUIT BUTTON_POWER 509 + 510 #else 511 #error No keymap defined! 512 #endif
+3
apps/plugins/imageviewer/imageviewer_button.h
··· 539 #define IMGVIEW_MENU BUTTON_POWER 540 #define IMGVIEW_SLIDE_SHOW BUTTON_PLAY 541 542 #else 543 #error No keymap defined! 544 #endif
··· 539 #define IMGVIEW_MENU BUTTON_POWER 540 #define IMGVIEW_SLIDE_SHOW BUTTON_PLAY 541 542 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 543 + /* use touchscreen */ 544 + 545 #else 546 #error No keymap defined! 547 #endif
+20
apps/plugins/invadrox.c
··· 296 #define RIGHT BUTTON_RIGHT 297 #define FIRE BUTTON_SELECT 298 299 #else 300 #error INVADROX: Unsupported keypad 301 #endif ··· 648 #define LIVES_X 8 649 #define MAX_Y 15 650 651 652 #else 653 #error INVADROX: Unsupported LCD type
··· 296 #define RIGHT BUTTON_RIGHT 297 #define FIRE BUTTON_SELECT 298 299 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 300 + /* use touchscreen */ 301 + 302 #else 303 #error INVADROX: Unsupported keypad 304 #endif ··· 651 #define LIVES_X 8 652 #define MAX_Y 15 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 671 672 #else 673 #error INVADROX: Unsupported LCD type
+3
apps/plugins/jewels.c
··· 377 #define HK_SELECT "SELECT" 378 #define HK_CANCEL "BACK" 379 380 #else 381 #error No keymap defined! 382 #endif
··· 377 #define HK_SELECT "SELECT" 378 #define HK_CANCEL "BACK" 379 380 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 381 + /* use touchscreen */ 382 + 383 #else 384 #error No keymap defined! 385 #endif
+11 -1
apps/plugins/lib/keymaps.h
··· 255 #define BTN_FIRE BUTTON_SELECT 256 #define BTN_PAUSE BUTTON_POWER 257 258 #else 259 #error Unsupported keypad 260 #endif ··· 272 #elif (CONFIG_KEYPAD != COWON_D2_PAD) && \ 273 (CONFIG_KEYPAD != DX50_PAD) && \ 274 (CONFIG_KEYPAD != ONDAVX777_PAD) && \ 275 - (CONFIG_KEYPAD != CREATIVE_ZENXFI2_PAD) 276 #define BTN_FIRE BUTTON_BOTTOMLEFT 277 #define BTN_PAUSE BUTTON_TOPLEFT 278 #endif
··· 255 #define BTN_FIRE BUTTON_SELECT 256 #define BTN_PAUSE BUTTON_POWER 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 + 267 #else 268 #error Unsupported keypad 269 #endif ··· 281 #elif (CONFIG_KEYPAD != COWON_D2_PAD) && \ 282 (CONFIG_KEYPAD != DX50_PAD) && \ 283 (CONFIG_KEYPAD != ONDAVX777_PAD) && \ 284 + (CONFIG_KEYPAD != CREATIVE_ZENXFI2_PAD) && \ 285 + (CONFIG_KEYPAD != SHANLING_Q1_PAD) 286 #define BTN_FIRE BUTTON_BOTTOMLEFT 287 #define BTN_PAUSE BUTTON_TOPLEFT 288 #endif
+2
apps/plugins/lib/pluginlib_actions.c
··· 499 {PLA_SELECT, BUTTON_SELECT, BUTTON_NONE}, 500 {PLA_SELECT_REL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT}, 501 {PLA_SELECT_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, 502 #else 503 # ifndef HAVE_TOUCHSCREEN 504 # error pluginlib_actions: No actions defined
··· 499 {PLA_SELECT, BUTTON_SELECT, BUTTON_NONE}, 500 {PLA_SELECT_REL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT}, 501 {PLA_SELECT_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, 502 + #elif (CONFIG_KEYPAD == SHANLING_Q1_PAD) 503 + {PLA_EXIT, BUTTON_POWER, BUTTON_NONE}, 504 #else 505 # ifndef HAVE_TOUCHSCREEN 506 # error pluginlib_actions: No actions defined
+3
apps/plugins/midi/midiplay.c
··· 325 #define MIDI_VOL_DOWN BUTTON_VOL_DOWN 326 #define MIDI_PLAYPAUSE BUTTON_PLAY 327 328 #else 329 #error No keymap defined! 330 #endif
··· 325 #define MIDI_VOL_DOWN BUTTON_VOL_DOWN 326 #define MIDI_PLAYPAUSE BUTTON_PLAY 327 328 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 329 + /* use touchscreen */ 330 + 331 #else 332 #error No keymap defined! 333 #endif
+3
apps/plugins/minesweeper.c
··· 443 # define MINESWP_DISCOVER (BUTTON_SELECT|BUTTON_REPEAT) 444 # define MINESWP_INFO BUTTON_MENU 445 446 #else 447 #error No keymap defined! 448 #endif
··· 443 # define MINESWP_DISCOVER (BUTTON_SELECT|BUTTON_REPEAT) 444 # define MINESWP_INFO BUTTON_MENU 445 446 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 447 + /* use touchscreen */ 448 + 449 #else 450 #error No keymap defined! 451 #endif
+3
apps/plugins/mp3_encoder.c
··· 2580 #define MP3ENC_DONE BUTTON_POWER 2581 #define MP3ENC_SELECT BUTTON_SELECT 2582 2583 #else 2584 #error No keymap defined! 2585 #endif
··· 2580 #define MP3ENC_DONE BUTTON_POWER 2581 #define MP3ENC_SELECT BUTTON_SELECT 2582 2583 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 2584 + /* use touchscreen */ 2585 + 2586 #else 2587 #error No keymap defined! 2588 #endif
+3
apps/plugins/mpegplayer/mpeg_settings.c
··· 354 #define MPEG_START_TIME_DOWN BUTTON_DOWN 355 #define MPEG_START_TIME_EXIT BUTTON_POWER 356 357 #else 358 #error No keymap defined! 359 #endif
··· 354 #define MPEG_START_TIME_DOWN BUTTON_DOWN 355 #define MPEG_START_TIME_EXIT BUTTON_POWER 356 357 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 358 + #define MPEG_START_TIME_EXIT BUTTON_POWER 359 + 360 #else 361 #error No keymap defined! 362 #endif
+3
apps/plugins/mpegplayer/mpegplayer.c
··· 486 #define MPEG_RW BUTTON_LEFT 487 #define MPEG_FF BUTTON_RIGHT 488 489 #else 490 #error No keymap defined! 491 #endif
··· 486 #define MPEG_RW BUTTON_LEFT 487 #define MPEG_FF BUTTON_RIGHT 488 489 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 490 + /* use touchscreen */ 491 + 492 #else 493 #error No keymap defined! 494 #endif
+3
apps/plugins/oscilloscope.c
··· 548 #define OSCILLOSCOPE_VOL_UP BUTTON_VOL_UP 549 #define OSCILLOSCOPE_VOL_DOWN BUTTON_VOL_DOWN 550 551 #else 552 #error No keymap defined! 553 #endif
··· 548 #define OSCILLOSCOPE_VOL_UP BUTTON_VOL_UP 549 #define OSCILLOSCOPE_VOL_DOWN BUTTON_VOL_DOWN 550 551 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 552 + /* use touchscreen */ 553 + 554 #else 555 #error No keymap defined! 556 #endif
+10
apps/plugins/pacbox/pacbox.h
··· 398 #define PACMAN_1UP BUTTON_VOL_UP 399 #define PACMAN_COIN BUTTON_PLAY 400 401 #else 402 403 #error Keymap not defined!
··· 398 #define PACMAN_1UP BUTTON_VOL_UP 399 #define PACMAN_COIN BUTTON_PLAY 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 + 411 #else 412 413 #error Keymap not defined!
+3
apps/plugins/pegbox.c
··· 711 #define LVL_UP_TEXT "VOL+" 712 #define LVL_DOWN_TEXT "VOL-" 713 714 #else 715 #error "Unsupported keymap!" 716 #endif
··· 711 #define LVL_UP_TEXT "VOL+" 712 #define LVL_DOWN_TEXT "VOL-" 713 714 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 715 + /* use touchscreen */ 716 + 717 #else 718 #error "Unsupported keymap!" 719 #endif
+3
apps/plugins/pong.c
··· 325 #define PONG_RIGHT_UP BUTTON_BACK 326 #define PONG_RIGHT_DOWN BUTTON_RIGHT 327 328 #else 329 #error No keymap defined! 330 #endif
··· 325 #define PONG_RIGHT_UP BUTTON_BACK 326 #define PONG_RIGHT_DOWN BUTTON_RIGHT 327 328 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 329 + /* use touchscreen */ 330 + 331 #else 332 #error No keymap defined! 333 #endif
+3
apps/plugins/reversi/reversi-gui.h
··· 361 #define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT 362 #define REVERSI_BUTTON_MENU BUTTON_MENU 363 364 #else 365 #error No keymap defined! 366 #endif
··· 361 #define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT 362 #define REVERSI_BUTTON_MENU BUTTON_MENU 363 364 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 365 + /* use touchscreen */ 366 + 367 #else 368 #error No keymap defined! 369 #endif
+19
apps/plugins/rockblox.c
··· 465 #define ROCKBLOX_DROP BUTTON_PLAY 466 #define ROCKBLOX_RESTART BUTTON_BACK 467 468 #else 469 #error No keymap defined! 470 #endif ··· 533 #define SCORE_Y 58 534 #define LEVEL_Y 142 535 #define LINES_Y 218 536 537 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) 538
··· 465 #define ROCKBLOX_DROP BUTTON_PLAY 466 #define ROCKBLOX_RESTART BUTTON_BACK 467 468 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 469 + /* use touchscreen */ 470 + 471 #else 472 #error No keymap defined! 473 #endif ··· 536 #define SCORE_Y 58 537 #define LEVEL_Y 142 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 555 556 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) 557
+3
apps/plugins/rockboy/rockboy.c
··· 468 options.SELECT = BUTTON_VOL_UP; 469 options.MENU = BUTTON_POWER; 470 471 #else 472 #error No Keymap Defined! 473 #endif
··· 468 options.SELECT = BUTTON_VOL_UP; 469 options.MENU = BUTTON_POWER; 470 471 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 472 + /* use touchscreen */ 473 + 474 #else 475 #error No Keymap Defined! 476 #endif
+3
apps/plugins/rockpaint.c
··· 404 #define ROCKPAINT_LEFT BUTTON_LEFT 405 #define ROCKPAINT_RIGHT BUTTON_RIGHT 406 407 #else 408 #error "Please define keys for this keypad" 409 #endif
··· 404 #define ROCKPAINT_LEFT BUTTON_LEFT 405 #define ROCKPAINT_RIGHT BUTTON_RIGHT 406 407 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 408 + /* use touchscreen */ 409 + 410 #else 411 #error "Please define keys for this keypad" 412 #endif
+3
apps/plugins/sliding_puzzle.c
··· 357 #define PUZZLE_SHUFFLE BUTTON_BACK 358 #define PUZZLE_PICTURE BUTTON_PLAY 359 360 #else 361 #error No keymap defined! 362 #endif
··· 357 #define PUZZLE_SHUFFLE BUTTON_BACK 358 #define PUZZLE_PICTURE BUTTON_PLAY 359 360 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 361 + /* use touchscreen */ 362 + 363 #else 364 #error No keymap defined! 365 #endif
+3
apps/plugins/snake.c
··· 313 #define SNAKE_DOWN BUTTON_DOWN 314 #define SNAKE_PLAYPAUSE BUTTON_PLAY 315 316 #else 317 #error No keymap defined! 318 #endif
··· 313 #define SNAKE_DOWN BUTTON_DOWN 314 #define SNAKE_PLAYPAUSE BUTTON_PLAY 315 316 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 317 + /* use touchscreen */ 318 + 319 #else 320 #error No keymap defined! 321 #endif
+15
apps/plugins/snake2.c
··· 62 #define TOP_X4 548 /* x-coord of the lowerright item (hi-score) */ 63 #define TOP_Y1 8 /* y-coord of the top row of items */ 64 #define TOP_Y2 50 /* y-coord of the bottom row of items */ 65 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 66 #define MULTIPLIER 10 /*Modifier for porting on other screens*/ 67 #define MODIFIER_1 10 ··· 445 #define SNAKE2_QUIT BUTTON_POWER 446 #define SNAKE2_PLAYPAUSE BUTTON_PLAY 447 #define SNAKE2_PLAYPAUSE_TEXT "PLAY" 448 449 #else 450 #error No keymap defined!
··· 62 #define TOP_X4 548 /* x-coord of the lowerright item (hi-score) */ 63 #define TOP_Y1 8 /* y-coord of the top row of items */ 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 */ 77 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) 78 #define MULTIPLIER 10 /*Modifier for porting on other screens*/ 79 #define MODIFIER_1 10 ··· 457 #define SNAKE2_QUIT BUTTON_POWER 458 #define SNAKE2_PLAYPAUSE BUTTON_PLAY 459 #define SNAKE2_PLAYPAUSE_TEXT "PLAY" 460 + 461 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 462 + /* use touchscreen */ 463 464 #else 465 #error No keymap defined!
+3
apps/plugins/sokoban.c
··· 696 #define BUTTON_SAVE BUTTON_BACK 697 #define BUTTON_SAVE_NAME "BACK" 698 699 #else 700 #error No keymap defined! 701 #endif
··· 696 #define BUTTON_SAVE BUTTON_BACK 697 #define BUTTON_SAVE_NAME "BACK" 698 699 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 700 + /* use touchscreen */ 701 + 702 #else 703 #error No keymap defined! 704 #endif
+3
apps/plugins/solitaire.c
··· 741 # define HK_CUR2STACK "HOLD SELECT" 742 # define HK_REM2STACK "VOL+" 743 744 #else 745 #error No keymap defined! 746 #endif
··· 741 # define HK_CUR2STACK "HOLD SELECT" 742 # define HK_REM2STACK "VOL+" 743 744 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 745 + # define SOL_QUIT BUTTON_POWER 746 + 747 #else 748 #error No keymap defined! 749 #endif
+3
apps/plugins/spacerocks.c
··· 372 #define AST_RIGHT BUTTON_RIGHT 373 #define AST_FIRE BUTTON_PLAY 374 375 #else 376 #error No keymap defined! 377 #endif
··· 372 #define AST_RIGHT BUTTON_RIGHT 373 #define AST_FIRE BUTTON_PLAY 374 375 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 376 + /* use touchscreen */ 377 + 378 #else 379 #error No keymap defined! 380 #endif
+4
apps/plugins/star.c
··· 668 #define STAR_LEVEL_DOWN_NAME "VOL-" 669 #define STAR_LEVEL_REPEAT_NAME "BACK" 670 671 #else 672 #error No keymap defined! 673 #endif
··· 668 #define STAR_LEVEL_DOWN_NAME "VOL-" 669 #define STAR_LEVEL_REPEAT_NAME "BACK" 670 671 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 672 + #define STAR_QUIT BUTTON_POWER 673 + #define STAR_QUIT_NAME "POWER" 674 + 675 #else 676 #error No keymap defined! 677 #endif
+1 -1
apps/plugins/stopwatch.lua
··· 280 end 281 end 282 283 - rb.touchscreen_set_mode(rb.TOUCHSCREEN_POINT) 284 285 LapsView:init() 286
··· 280 end 281 end 282 283 + rb.touchscreen_mode(rb.TOUCHSCREEN_POINT) 284 285 LapsView:init() 286
+3
apps/plugins/sudoku/sudoku.h
··· 460 #define SUDOKU_BUTTON_MENU BUTTON_MENU 461 #define SUDOKU_BUTTON_POSSIBLE BUTTON_BACK 462 463 #else 464 #error No keymap defined! 465 #endif
··· 460 #define SUDOKU_BUTTON_MENU BUTTON_MENU 461 #define SUDOKU_BUTTON_POSSIBLE BUTTON_BACK 462 463 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 464 + /* use touchscreen */ 465 + 466 #else 467 #error No keymap defined! 468 #endif
+5
apps/plugins/test_touchscreen.c
··· 37 #elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD 38 #define TOUCHSCREEN_QUIT BUTTON_POWER 39 #define TOUCHSCREEN_TOGGLE BUTTON_MENU 40 #elif (CONFIG_KEYPAD == ANDROID_PAD) 41 #define TOUCHSCREEN_QUIT BUTTON_BACK 42 #define TOUCHSCREEN_TOGGLE BUTTON_MENU 43 #elif (CONFIG_KEYPAD == SDL_PAD) 44 #define TOUCHSCREEN_QUIT BUTTON_MIDLEFT 45 #define TOUCHSCREEN_TOGGLE BUTTON_CENTER 46 #endif 47 48 /* plugin entry point */
··· 37 #elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD 38 #define TOUCHSCREEN_QUIT BUTTON_POWER 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 43 #elif (CONFIG_KEYPAD == ANDROID_PAD) 44 #define TOUCHSCREEN_QUIT BUTTON_BACK 45 #define TOUCHSCREEN_TOGGLE BUTTON_MENU 46 #elif (CONFIG_KEYPAD == SDL_PAD) 47 #define TOUCHSCREEN_QUIT BUTTON_MIDLEFT 48 #define TOUCHSCREEN_TOGGLE BUTTON_CENTER 49 + #else 50 + # error "No keymap defined!" 51 #endif 52 53 /* plugin entry point */
+3
apps/plugins/text_viewer/tv_button.h
··· 572 #define TV_LINE_DOWN BUTTON_SCROLL_FWD 573 #define TV_BOOKMARK BUTTON_PLAY 574 575 #else 576 #error No keymap defined! 577 #endif
··· 572 #define TV_LINE_DOWN BUTTON_SCROLL_FWD 573 #define TV_BOOKMARK BUTTON_PLAY 574 575 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 576 + #define TV_BOOKMARK BUTTON_PLAY 577 + 578 #else 579 #error No keymap defined! 580 #endif
+3
apps/plugins/vu_meter.c
··· 452 #define LABEL_MENU "MENU" 453 #define LABEL_VOLUME "VOL+/VOL-" 454 455 #else 456 #error No keymap defined! 457 #endif
··· 452 #define LABEL_MENU "MENU" 453 #define LABEL_VOLUME "VOL+/VOL-" 454 455 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 456 + /* use touchscreen */ 457 + 458 #else 459 #error No keymap defined! 460 #endif
+5 -1
apps/plugins/wormlet.c
··· 407 #define BTN_QUIT BUTTON_POWER 408 #define BTN_STOPRESET BUTTON_BACK 409 410 #else 411 #error No keymap defined! 412 #endif ··· 492 #define SPEED 4 493 #define MAX_WORM_SEGMENTS 512 494 #elif ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \ 495 - ((LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))) 496 #define FOOD_SIZE 7 497 #define ARGH_SIZE 8 498 #define SPEED 4
··· 407 #define BTN_QUIT BUTTON_POWER 408 #define BTN_STOPRESET BUTTON_BACK 409 410 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 411 + /* use touchscreen */ 412 + 413 #else 414 #error No keymap defined! 415 #endif ··· 495 #define SPEED 4 496 #define MAX_WORM_SEGMENTS 512 497 #elif ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \ 498 + ((LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))) || \ 499 + ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) 500 #define FOOD_SIZE 7 501 #define ARGH_SIZE 8 502 #define SPEED 4
+3
apps/plugins/xobox.c
··· 351 #define DOWN BUTTON_DOWN 352 #define PAUSE BUTTON_PLAY 353 354 #else 355 #error "No keymap defined!" 356 #endif
··· 351 #define DOWN BUTTON_DOWN 352 #define PAUSE BUTTON_PLAY 353 354 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 355 + /* use touchscreen */ 356 + 357 #else 358 #error "No keymap defined!" 359 #endif
+3
apps/plugins/zxbox/keymaps.h
··· 290 #define ZX_UP BUTTON_UP 291 #define ZX_DOWN BUTTON_DOWN 292 293 #else 294 #error Keymap not defined! 295
··· 290 #define ZX_UP BUTTON_UP 291 #define ZX_DOWN BUTTON_DOWN 292 293 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 294 + /* use touchscreen */ 295 + 296 #else 297 #error Keymap not defined! 298
+9 -2
apps/settings_list.c
··· 242 #define DEFAULT_FONT_HEIGHT 12 243 #elif LCD_HEIGHT <= 320 244 #define DEFAULT_FONT_HEIGHT 15 245 #elif LCD_HEIGHT <= 400 246 #define DEFAULT_FONT_HEIGHT 16 247 #elif LCD_HEIGHT <= 480 && LCD_WIDTH < 800 ··· 261 #endif 262 263 #ifdef HAVE_LCD_COLOR 264 - #if DEFAULT_FONT_HEIGHT >= 31 265 #define DEFAULT_ICONSET "tango_icons.32x32" 266 #define DEFAULT_VIEWERS_ICONSET "tango_icons_viewers.32x32" 267 #elif DEFAULT_FONT_HEIGHT >= 23 ··· 848 849 #ifdef AUDIOHW_HAVE_FILTER_ROLL_OFF 850 CHOICE_SETTING(F_SOUNDSETTING, roll_off, LANG_FILTER_ROLL_OFF, 0, 851 - #if defined(AUDIOHW_HAVE_SHORT2_ROLL_OFF) 852 "roll_off", "sharp,slow,short sharp,short slow", sound_set_filter_roll_off, 853 4, ID2P(LANG_FILTER_SHARP), ID2P(LANG_FILTER_SLOW), ID2P(LANG_FILTER_SHORT_SHARP), ID2P(LANG_FILTER_SHORT_SLOW)), 854 #elif defined(AUDIOHW_HAVE_SHORT_ROLL_OFF)
··· 242 #define DEFAULT_FONT_HEIGHT 12 243 #elif LCD_HEIGHT <= 320 244 #define DEFAULT_FONT_HEIGHT 15 245 + #elif defined(SHANLING_Q1) 246 + /* 16pt font looks pretty aliased & ugly */ 247 + #define DEFAULT_FONT_HEIGHT 18 248 #elif LCD_HEIGHT <= 400 249 #define DEFAULT_FONT_HEIGHT 16 250 #elif LCD_HEIGHT <= 480 && LCD_WIDTH < 800 ··· 264 #endif 265 266 #ifdef HAVE_LCD_COLOR 267 + #if DEFAULT_FONT_HEIGHT >= 31 || defined(SHANLING_Q1) 268 #define DEFAULT_ICONSET "tango_icons.32x32" 269 #define DEFAULT_VIEWERS_ICONSET "tango_icons_viewers.32x32" 270 #elif DEFAULT_FONT_HEIGHT >= 23 ··· 851 852 #ifdef AUDIOHW_HAVE_FILTER_ROLL_OFF 853 CHOICE_SETTING(F_SOUNDSETTING, roll_off, LANG_FILTER_ROLL_OFF, 0, 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) 859 "roll_off", "sharp,slow,short sharp,short slow", sound_set_filter_roll_off, 860 4, ID2P(LANG_FILTER_SHARP), ID2P(LANG_FILTER_SLOW), ID2P(LANG_FILTER_SHORT_SHARP), ID2P(LANG_FILTER_SHORT_SLOW)), 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 #elif defined(SANSA_CONNECT) 90 sansaconnect.c 91 show_logo.c 92 - #elif defined(FIIO_M3K) 93 x1000.c 94 #endif
··· 89 #elif defined(SANSA_CONNECT) 90 sansaconnect.c 91 show_logo.c 92 + #elif defined(FIIO_M3K) || defined(SHANLING_Q1) 93 x1000.c 94 #endif
+11
bootloader/x1000.c
··· 66 # define BL_SELECT_NAME "PLAY" 67 # define BL_QUIT_NAME "POWER" 68 # define BOOTBACKUP_FILE "/fiiom3k-boot.bin" 69 #else 70 # error "Missing keymap!" 71 #endif
··· 66 # define BL_SELECT_NAME "PLAY" 67 # define BL_QUIT_NAME "POWER" 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" 80 #else 81 # error "Missing keymap!" 82 #endif
+1
docs/CREDITS
··· 706 Spencer Brennessel 707 Dana Conrad 708 Albert Song 709 710 The libmad team 711 The wavpack team
··· 706 Spencer Brennessel 707 Dana Conrad 708 Albert Song 709 + Marc Aarts 710 711 The libmad team 712 The wavpack team
+14
firmware/SOURCES
··· 503 drivers/audio/cs4398.c 504 #elif defined (HAVE_ES9018) 505 drivers/audio/es9018.c 506 #endif /* defined(HAVE_*) */ 507 #else /* PLATFORM_HOSTED */ 508 #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) ··· 1716 target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c 1717 #endif /* FIIO_M3K */ 1718 1719 #if defined(LYRE_PROTO1) 1720 target/arm/at91sam/lyre_proto1/adc-lyre_proto1.c 1721 target/arm/at91sam/lyre_proto1/backlight-lyre_proto1.c ··· 1947 #endif 1948 #ifdef HAVE_FT6x06 1949 drivers/ft6x06.c 1950 #endif 1951 #endif 1952
··· 503 drivers/audio/cs4398.c 504 #elif defined (HAVE_ES9018) 505 drivers/audio/es9018.c 506 + #elif defined (HAVE_ES9218) 507 + drivers/audio/es9218.c 508 #endif /* defined(HAVE_*) */ 509 #else /* PLATFORM_HOSTED */ 510 #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) ··· 1718 target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c 1719 #endif /* FIIO_M3K */ 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 + 1730 #if defined(LYRE_PROTO1) 1731 target/arm/at91sam/lyre_proto1/adc-lyre_proto1.c 1732 target/arm/at91sam/lyre_proto1/backlight-lyre_proto1.c ··· 1958 #endif 1959 #ifdef HAVE_FT6x06 1960 drivers/ft6x06.c 1961 + #endif 1962 + #ifdef HAVE_CW2015 1963 + drivers/cw2015.c 1964 #endif 1965 #endif 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 #include "cs4398.h" 217 #elif defined(HAVE_ES9018) 218 #include "es9018.h" 219 #elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO \ 220 | PLATFORM_PANDORA | PLATFORM_SDL)) 221 #include "hosted_codec.h"
··· 216 #include "cs4398.h" 217 #elif defined(HAVE_ES9018) 218 #include "es9018.h" 219 + #elif defined(HAVE_ES9218) 220 + #include "es9218.h" 221 #elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO \ 222 | PLATFORM_PANDORA | PLATFORM_SDL)) 223 #include "hosted_codec.h"
+4
firmware/export/config.h
··· 160 #define FIIO_M3K_LINUX_PAD 71 161 #define EROSQ_PAD 72 162 #define FIIO_M3K_PAD 73 163 164 /* CONFIG_REMOTE_KEYPAD */ 165 #define H100_REMOTE 1 ··· 274 #define LCD_IHIFI770C 67 /* as used by IHIFI 770C */ 275 #define LCD_IHIFI800 68 /* as used by IHIFI 800 */ 276 #define LCD_FIIOM3K 69 /* as used by the FiiO M3K */ 277 278 /* LCD_PIXELFORMAT */ 279 #define HORIZONTAL_PACKING 1 ··· 592 #include "config/fiiom3k.h" 593 #elif defined(EROS_Q) 594 #include "config/aigoerosq.h" 595 #else 596 //#error "unknown hwardware platform!" 597 #endif
··· 160 #define FIIO_M3K_LINUX_PAD 71 161 #define EROSQ_PAD 72 162 #define FIIO_M3K_PAD 73 163 + #define SHANLING_Q1_PAD 74 164 165 /* CONFIG_REMOTE_KEYPAD */ 166 #define H100_REMOTE 1 ··· 275 #define LCD_IHIFI770C 67 /* as used by IHIFI 770C */ 276 #define LCD_IHIFI800 68 /* as used by IHIFI 800 */ 277 #define LCD_FIIOM3K 69 /* as used by the FiiO M3K */ 278 + #define LCD_SHANLING_Q1 70 /* as used by the Shanling Q1 */ 279 280 /* LCD_PIXELFORMAT */ 281 #define HORIZONTAL_PACKING 1 ··· 594 #include "config/fiiom3k.h" 595 #elif defined(EROS_Q) 596 #include "config/aigoerosq.h" 597 + #elif defined(SHANLING_Q1) 598 + #include "config/shanlingq1.h" 599 #else 600 //#error "unknown hwardware platform!" 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 #define UI_LCD_POSY 15 530 531 532 #elif defined(SIMULATOR) 533 #error no UI defines 534 #endif
··· 529 #define UI_LCD_POSY 15 530 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 + 540 #elif defined(SIMULATOR) 541 #error no UI defines 542 #endif
+6
firmware/target/mips/ingenic_x1000/debug-x1000.c
··· 152 #ifdef HAVE_AXP_PMU 153 extern bool axp_debug_menu(void); 154 #endif 155 156 /* Menu definition */ 157 static const struct { ··· 169 #endif 170 #ifdef HAVE_AXP_PMU 171 {"Power stats", &axp_debug_menu}, 172 #endif 173 }; 174
··· 152 #ifdef HAVE_AXP_PMU 153 extern bool axp_debug_menu(void); 154 #endif 155 + #ifdef HAVE_CW2015 156 + extern bool cw2015_debug_menu(void); 157 + #endif 158 159 /* Menu definition */ 160 static const struct { ··· 172 #endif 173 #ifdef HAVE_AXP_PMU 174 {"Power stats", &axp_debug_menu}, 175 + #endif 176 + #ifdef HAVE_CW2015 177 + {"CW2015 debug", &cw2015_debug_menu}, 178 #endif 179 }; 180
+12 -1
firmware/target/mips/ingenic_x1000/msc-x1000.c
··· 42 #define DEBOUNCE_TIME (HZ/10) 43 44 static const msc_config msc_configs[] = { 45 - #ifdef FIIO_M3K 46 #define MSC_CLOCK_SOURCE X1000_CLK_SCLK_A 47 { 48 .msc_nr = 0, ··· 52 .cd_gpio = GPIO_MSC0_CD, 53 .cd_active_level = 0, 54 }, 55 #else 56 # error "Please add X1000 MSC config" 57 #endif
··· 42 #define DEBOUNCE_TIME (HZ/10) 43 44 static const msc_config msc_configs[] = { 45 + #if defined(FIIO_M3K) 46 #define MSC_CLOCK_SOURCE X1000_CLK_SCLK_A 47 { 48 .msc_nr = 0, ··· 52 .cd_gpio = GPIO_MSC0_CD, 53 .cd_active_level = 0, 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 */ 66 #else 67 # error "Please add X1000 MSC config" 68 #endif
+1 -1
firmware/target/mips/ingenic_x1000/nand-x1000.c
··· 58 #define FREG_STATUS_ECC_UNCOR_ERR (2 << 4) 59 60 const nand_chip supported_nand_chips[] = { 61 - #if defined(FIIO_M3K) 62 { 63 /* ATO25D1GA */ 64 .mf_id = 0x9b,
··· 58 #define FREG_STATUS_ECC_UNCOR_ERR (2 << 4) 59 60 const nand_chip supported_nand_chips[] = { 61 + #if defined(FIIO_M3K) || defined(SHANLING_Q1) 62 { 63 /* ATO25D1GA */ 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 #include "ucl_decompress.h" 35 #include <string.h> 36 37 - #ifdef FIIO_M3K 38 # define SPL_DDR_MEMORYSIZE 64 39 # define SPL_DDR_AUTOSR_EN 1 40 # define SPL_DDR_NEED_BYPASS 1
··· 34 #include "ucl_decompress.h" 35 #include <string.h> 36 37 + #if defined(FIIO_M3K) || defined(SHANLING_Q1) 38 # define SPL_DDR_MEMORYSIZE 64 39 # define SPL_DDR_AUTOSR_EN 1 40 # define SPL_DDR_NEED_BYPASS 1
+26 -1
tools/configure
··· 1597 240) Rocker 228) NWZ-A860 series 1598 ==FiiO== 229) NWZ-S750 series 1599 ==AIGO== 244) M3K Linux 1600 - 245) Eros Q / K 246) M3K baremetal 1601 EOF 1602 1603 buildfor=`input`; ··· 4106 t_cpu="mips" 4107 t_manufacturer="ingenic_x1000" 4108 t_model="fiiom3k" 4109 ;; 4110 4111 *)
··· 1597 240) Rocker 228) NWZ-A860 series 1598 ==FiiO== 229) NWZ-S750 series 1599 ==AIGO== 244) M3K Linux 1600 + 245) Eros Q / K 246) M3K baremetal ==Shanling== 1601 + 260) Q1 1602 EOF 1603 1604 buildfor=`input`; ··· 4107 t_cpu="mips" 4108 t_manufacturer="ingenic_x1000" 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" 4134 ;; 4135 4136 *)
+2
tools/scramble.c
··· 333 modelnum = 109; 334 else if (!strcmp(&argv[1][5], "fiiom3k")) /* FiiO M3K */ 335 modelnum = 114; 336 else { 337 fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); 338 return 2;
··· 333 modelnum = 109; 334 else if (!strcmp(&argv[1][5], "fiiom3k")) /* FiiO M3K */ 335 modelnum = 114; 336 + else if (!strcmp(&argv[1][5], "shq1")) /* Shanling Q1 */ 337 + modelnum = 115; 338 else { 339 fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); 340 return 2;
uisimulator/bitmaps/UI-shanlingq1.bmp

This is a binary file and will not be displayed.

+2
uisimulator/buttonmap/SOURCES
··· 85 erosq.c 86 #elif CONFIG_KEYPAD == FIIO_M3K_PAD 87 fiio-m3k.c 88 #endif 89 #endif /* SIMULATOR */
··· 85 erosq.c 86 #elif CONFIG_KEYPAD == FIIO_M3K_PAD 87 fiio-m3k.c 88 + #elif CONFIG_KEYPAD == SHANLING_Q1_PAD 89 + shanling-q1.c 90 #endif 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 Johannes Voggenthaler 17 Jonathan Gordon 18 Keith Perri 19 Marc Guay 20 Marcin Bukat 21 Marianne Arnold
··· 16 Johannes Voggenthaler 17 Jonathan Gordon 18 Keith Perri 19 + Marc Aarts 20 Marc Guay 21 Marcin Bukat 22 Marianne Arnold
+5
wps/WPSLIST
··· 82 wps.800x480x(16|24): cabbiev2.800x480x16.wps 83 wps.480x800x(16|24): cabbiev2.480x800x16.wps 84 wps.400x240x(16|24): cabbiev2.400x240x16.wps 85 wps.320x480x(16|24): cabbiev2.320x480x16.wps 86 wps.320x240x(16|24|32): cabbiev2.320x240x16.wps 87 wps.240x400x(16|24): cabbiev2.240x400x16.wps ··· 111 Font.800x480x(16|24): 35-Adobe-Helvetica.fnt 112 Font.480x800x(16|24): 35-Adobe-Helvetica.fnt 113 Font.400x240x(16|24): 15-Adobe-Helvetica.fnt 114 Font.320x480x(16|24): 27-Adobe-Helvetica.fnt 115 Font.320x240x(16|24): 15-Adobe-Helvetica.fnt 116 Font.240x400x(16|24): 16-Adobe-Helvetica.fnt ··· 144 backdrop.800x480x(16|24): backdrops/cabbiev2.800x480x16.bmp 145 backdrop.480x800x(16|24): backdrops/cabbiev2.480x800x16.bmp 146 backdrop.400x240x(16|24): backdrops/cabbiev2.400x240x16.bmp 147 backdrop.320x480x(16|24): backdrops/cabbiev2.320x480x16.bmp 148 backdrop.320x240x(16|24): backdrops/cabbiev2.320x240x16.bmp 149 backdrop.128x128x(16|24): backdrops/cabbiev2.128x128x16.bmp ··· 170 iconset.800x480x(16|24): icons/tango_icons.32x32.bmp 171 iconset.480x800x(16|24): icons/tango_icons.32x32.bmp 172 iconset.400x240x(16|24): icons/tango_icons.16x16.bmp 173 iconset.320x480x(16|24): icons/tango_icons.24x24.bmp 174 iconset.320x240x(16|24|32): icons/tango_icons.16x16.bmp 175 iconset.128x128x(16|24): icons/tango_icons.12x12.bmp ··· 189 viewers iconset.800x480x(16|24): icons/tango_icons_viewers.32x32.bmp 190 viewers iconset.480x800x(16|24): icons/tango_icons_viewers.32x32.bmp 191 viewers iconset.400x240x(16|24): icons/tango_icons_viewers.16x16.bmp 192 viewers iconset.320x480x(16|24): icons/tango_icons_viewers.24x24.bmp 193 viewers iconset.320x240x(16|24): icons/tango_icons_viewers.16x16.bmp 194 viewers iconset.128x128x(16|24): icons/tango_icons_viewers.12x12.bmp
··· 82 wps.800x480x(16|24): cabbiev2.800x480x16.wps 83 wps.480x800x(16|24): cabbiev2.480x800x16.wps 84 wps.400x240x(16|24): cabbiev2.400x240x16.wps 85 + wps.360x400x16: cabbiev2.360x400x16.wps 86 wps.320x480x(16|24): cabbiev2.320x480x16.wps 87 wps.320x240x(16|24|32): cabbiev2.320x240x16.wps 88 wps.240x400x(16|24): cabbiev2.240x400x16.wps ··· 112 Font.800x480x(16|24): 35-Adobe-Helvetica.fnt 113 Font.480x800x(16|24): 35-Adobe-Helvetica.fnt 114 Font.400x240x(16|24): 15-Adobe-Helvetica.fnt 115 + Font.360x400x16: 18-Adobe-Helvetica.fnt 116 Font.320x480x(16|24): 27-Adobe-Helvetica.fnt 117 Font.320x240x(16|24): 15-Adobe-Helvetica.fnt 118 Font.240x400x(16|24): 16-Adobe-Helvetica.fnt ··· 146 backdrop.800x480x(16|24): backdrops/cabbiev2.800x480x16.bmp 147 backdrop.480x800x(16|24): backdrops/cabbiev2.480x800x16.bmp 148 backdrop.400x240x(16|24): backdrops/cabbiev2.400x240x16.bmp 149 + backdrop.360x400x16: backdrops/cabbiev2.360x400x16.bmp 150 backdrop.320x480x(16|24): backdrops/cabbiev2.320x480x16.bmp 151 backdrop.320x240x(16|24): backdrops/cabbiev2.320x240x16.bmp 152 backdrop.128x128x(16|24): backdrops/cabbiev2.128x128x16.bmp ··· 173 iconset.800x480x(16|24): icons/tango_icons.32x32.bmp 174 iconset.480x800x(16|24): icons/tango_icons.32x32.bmp 175 iconset.400x240x(16|24): icons/tango_icons.16x16.bmp 176 + iconset.360x400x16: icons/tango_icons.32x32.bmp 177 iconset.320x480x(16|24): icons/tango_icons.24x24.bmp 178 iconset.320x240x(16|24|32): icons/tango_icons.16x16.bmp 179 iconset.128x128x(16|24): icons/tango_icons.12x12.bmp ··· 193 viewers iconset.800x480x(16|24): icons/tango_icons_viewers.32x32.bmp 194 viewers iconset.480x800x(16|24): icons/tango_icons_viewers.32x32.bmp 195 viewers iconset.400x240x(16|24): icons/tango_icons_viewers.16x16.bmp 196 + viewers iconset.360x400x16: icons/tango_icons_viewers.32x32.bmp 197 viewers iconset.320x480x(16|24): icons/tango_icons_viewers.24x24.bmp 198 viewers iconset.320x240x(16|24): icons/tango_icons_viewers.16x16.bmp 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.