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
This commit is contained in:
Aidan MacDonald 2021-05-23 17:30:58 +01:00
parent 3abb7c5dd5
commit 4c60bc9e68
110 changed files with 2843 additions and 15 deletions

View file

@ -216,6 +216,8 @@ struct sound_settings_info
#include "cs4398.h"
#elif defined(HAVE_ES9018)
#include "es9018.h"
#elif defined(HAVE_ES9218)
#include "es9218.h"
#elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO \
| PLATFORM_PANDORA | PLATFORM_SDL))
#include "hosted_codec.h"

View file

@ -160,6 +160,7 @@
#define FIIO_M3K_LINUX_PAD 71
#define EROSQ_PAD 72
#define FIIO_M3K_PAD 73
#define SHANLING_Q1_PAD 74
/* CONFIG_REMOTE_KEYPAD */
#define H100_REMOTE 1
@ -274,6 +275,7 @@
#define LCD_IHIFI770C 67 /* as used by IHIFI 770C */
#define LCD_IHIFI800 68 /* as used by IHIFI 800 */
#define LCD_FIIOM3K 69 /* as used by the FiiO M3K */
#define LCD_SHANLING_Q1 70 /* as used by the Shanling Q1 */
/* LCD_PIXELFORMAT */
#define HORIZONTAL_PACKING 1
@ -592,6 +594,8 @@ Lyre prototype 1 */
#include "config/fiiom3k.h"
#elif defined(EROS_Q)
#include "config/aigoerosq.h"
#elif defined(SHANLING_Q1)
#include "config/shanlingq1.h"
#else
//#error "unknown hwardware platform!"
#endif

View file

@ -0,0 +1,119 @@
/* RoLo-related defines */
#define MODEL_NAME "Shanling Q1"
#define MODEL_NUMBER 115
#define BOOTFILE_EXT "q1"
#define BOOTFILE "rockbox." BOOTFILE_EXT
#define BOOTDIR "/.rockbox"
#define FIRMWARE_OFFSET_FILE_CRC 0
#define FIRMWARE_OFFSET_FILE_DATA 8
/* CPU defines */
#define CONFIG_CPU X1000
#define X1000_EXCLK_FREQ 24000000
#define CPU_FREQ 1008000000
#ifndef SIMULATOR
#define TIMER_FREQ X1000_EXCLK_FREQ
#endif
/* Kernel defines */
#define INCLUDE_TIMEOUT_API
#define HAVE_SEMAPHORE_OBJECTS
/* Drivers */
#define HAVE_I2C_ASYNC
/* Buffer for plugins and codecs. */
#define PLUGIN_BUFFER_SIZE 0x200000 /* 2 MiB */
#define CODEC_SIZE 0x100000 /* 1 MiB */
/* LCD defines */
#define CONFIG_LCD LCD_SHANLING_Q1
#define LCD_WIDTH 360
#define LCD_HEIGHT 400
#define LCD_DEPTH 16
#define LCD_PIXELFORMAT RGB565
#define LCD_DPI 200
#define HAVE_LCD_COLOR
#define HAVE_LCD_BITMAP
#define HAVE_LCD_ENABLE
#define LCD_X1000_FASTSLEEP
#define LCD_X1000_DMA_WAIT_FOR_FRAME
/* Backlight defines */
#define HAVE_BACKLIGHT
#define HAVE_BACKLIGHT_BRIGHTNESS
#define MIN_BRIGHTNESS_SETTING 1
#define MAX_BRIGHTNESS_SETTING 100
#define BRIGHTNESS_STEP 5
#define DEFAULT_BRIGHTNESS_SETTING 70
#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING
/* Codec / audio hardware defines */
#define HW_SAMPR_CAPS SAMPR_CAP_ALL_192
#define HAVE_ES9218
#define HAVE_SW_TONE_CONTROLS
/* Button defines */
#define CONFIG_KEYPAD SHANLING_Q1_PAD
#define HAVE_TOUCHSCREEN
#define HAVE_BUTTON_DATA
#define HAVE_FT6x06
#define HAVE_HEADPHONE_DETECTION
/* Storage defines */
#define CONFIG_STORAGE STORAGE_SD
#define HAVE_HOTSWAP
#define HAVE_HOTSWAP_STORAGE_AS_MAIN
#define HAVE_MULTIDRIVE
#define NUM_DRIVES 1
#define STORAGE_WANTS_ALIGN
#define STORAGE_NEEDS_BOUNCE_BUFFER
/* RTC settings */
#define CONFIG_RTC RTC_X1000
/* TODO: implement HAVE_RTC_ALARM */
/* Power management */
#define CONFIG_BATTERY_MEASURE (VOLTAGE_MEASURE)
#define CONFIG_CHARGING CHARGING_MONITOR
#define HAVE_SW_POWEROFF
#ifndef SIMULATOR
/* TODO: get the CW2015 driver working correctly */
/* #define HAVE_CW2015 */
#define HAVE_AXP_PMU 192 /* Presumed */
#define HAVE_POWEROFF_WHILE_CHARGING
#endif
/* Only one battery type */
#define BATTERY_CAPACITY_DEFAULT 1100
#define BATTERY_CAPACITY_MIN 1100
#define BATTERY_CAPACITY_MAX 1100
#define BATTERY_CAPACITY_INC 0
#define BATTERY_TYPES_COUNT 1
/* USB support */
#ifndef SIMULATOR
#define CONFIG_USBOTG USBOTG_DESIGNWARE
#define USB_DW_ARCH_SLAVE
#define USB_DW_TURNAROUND 5
#define HAVE_USBSTACK
#define USB_VENDOR_ID 0x0525 /* Same as the xDuuo X3, for some reason. */
#define USB_PRODUCT_ID 0xa4a5 /* Nb. DAC mode uses 20b1:301f 'XMOS Ltd' */
#define USB_DEVBSS_ATTR __attribute__((aligned(32)))
#define HAVE_USB_POWER
#define HAVE_USB_CHARGING_ENABLE
#define HAVE_BOOTLOADER_USB_MODE
#endif
/* Rockbox capabilities */
#define HAVE_FAT16SUPPORT
#define HAVE_ALBUMART
#define HAVE_BMP_SCALING
#define HAVE_JPEG
#define HAVE_TAGCACHE
#define HAVE_VOLUME_IN_LIST
#define HAVE_QUICKSCREEN
#define HAVE_HOTKEY
#define AB_REPEAT_ENABLE

57
firmware/export/cw2015.h Normal file
View file

@ -0,0 +1,57 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 Aidan MacDonald
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __CW2015_H__
#define __CW2015_H__
#include <stdint.h>
#include <stdbool.h>
/* Driver for I2C battery fuel gauge IC CW2015. */
#define CW2015_REG_VERSION 0x00
#define CW2015_REG_VCELL 0x02 /* 14 bits, registers 0x02 - 0x03 */
#define CW2015_REG_SOC 0x04 /* 16 bits, registers 0x04 - 0x05 */
#define CW2015_REG_RRT_ALERT 0x06 /* 13 bit RRT + alert flag, 0x06-0x07 */
#define CW2015_REG_CONFIG 0x08
#define CW2015_REG_MODE 0x0a
#define CW2015_REG_BATINFO 0x10 /* cf. mainline Linux CW2015 driver */
#define CW2015_SIZE_BATINFO 64
extern void cw2015_init(void);
/* Read the battery terminal voltage, converted to millivolts. */
extern int cw2015_get_vcell(void);
/* Read the SOC, in percent (0-100%). */
extern int cw2015_get_soc(void);
/* Get the estimated remaining run time, in minutes.
* Not a linearly varying quantity, according to the datasheet. */
extern int cw2015_get_rrt(void);
/* Read the current battery profile */
extern const uint8_t* cw2015_get_bat_info(void);
/* Debug screen */
extern bool cw2015_debug_menu(void);
#endif /* __CW2015_H__ */

230
firmware/export/es9218.h Normal file
View file

@ -0,0 +1,230 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 Aidan MacDonald
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __ES9218_H__
#define __ES9218_H__
#include <stdbool.h>
#include <stdint.h>
#define AUDIOHW_CAPS (FILTER_ROLL_OFF_CAP|POWER_MODE_CAP)
#define AUDIOHW_HAVE_ES9218_ROLL_OFF
#define ES9218_DIG_VOLUME_MIN (-1275)
#define ES9218_DIG_VOLUME_MAX 0
#define ES9218_DIG_VOLUME_STEP 5
#define ES9218_AMP_VOLUME_MIN (-240)
#define ES9218_AMP_VOLUME_MAX 0
#define ES9218_AMP_VOLUME_STEP 10
AUDIOHW_SETTING(VOLUME, "dB", 1, ES9218_DIG_VOLUME_STEP,
ES9218_DIG_VOLUME_MIN, ES9218_DIG_VOLUME_MAX, -200)
AUDIOHW_SETTING(FILTER_ROLL_OFF, "", 0, 1, 0, 7, 0)
AUDIOHW_SETTING(POWER_MODE, "", 0, 1, 0, 1, 0)
/* Register addresses */
#define ES9218_REG_SYSTEM 0x00
#define ES9218_REG_INPUT_SEL 0x01
#define ES9218_REG_MIX_AUTOMUTE 0x02
#define ES9218_REG_ANALOG_VOL 0x03
#define ES9218_REG_AUTOMUTE_TIME 0x04
#define ES9218_REG_AUTOMUTE_LEVEL 0x05
#define ES9218_REG_DOP_VOLUME_RAMP 0x06
#define ES9218_REG_FILTER_SYS_MUTE 0x07
#define ES9218_REG_GPIO1_2_CONFIG 0x08
#define ES9218_REG_RESERVED_1 0x09
#define ES9218_REG_MASTER_MODE_CONFIG 0x0a
#define ES9218_REG_OVERCURRENT_PROT 0x0b
#define ES9218_REG_ASRC_DPLL_BANDWIDTH 0x0c
#define ES9218_REG_THD_COMP_BYPASS 0x0d
#define ES9218_REG_SOFT_START_CONFIG 0x0e
#define ES9218_REG_VOLUME_LEFT 0x0f
#define ES9218_REG_VOLUME_RIGHT 0x10
#define ES9218_REG_MASTER_TRIM_BIT0_7 0x11
#define ES9218_REG_MASTER_TRIM_BIT8_15 0x12
#define ES9218_REG_MASTER_TRIM_BIT16_23 0x13
#define ES9218_REG_MASTER_TRIM_BIT24_31 0x14
#define ES9218_REG_GPIO_INPUT_SEL 0x15
#define ES9218_REG_THD_COMP_C2_LO 0x16
#define ES9218_REG_THD_COMP_C2_HI 0x17
#define ES9218_REG_THD_COMP_C3_LO 0x18
#define ES9218_REG_THD_COMP_C3_HI 0x19
#define ES9218_REG_CHARGE_PUMP_SS_DELAY 0x1a
#define ES9218_REG_GENERAL_CONFIG 0x1b
#define ES9218_REG_RESERVED_2 0x1c
#define ES9218_REG_GPIO_INV_CLOCK_GEAR 0x1d
#define ES9218_REG_CHARGE_PUMP_CLK_LO 0x1e
#define ES9218_REG_CHARGE_PUMP_CLK_HI 0x1f
#define ES9218_REG_AMP_CONFIG 0x20
#define ES9218_REG_INTERRUPT_MASK 0x21
#define ES9218_REG_PROG_NCO_BIT0_7 0x22
#define ES9218_REG_PROG_NCO_BIT8_15 0x23
#define ES9218_REG_PROG_NCO_BIT16_23 0x24
#define ES9218_REG_PROG_NCO_BIT24_31 0x25
#define ES9218_REG_RESERVED_3 0x27
#define ES9218_REG_FIR_RAM_ADDR 0x28
#define ES9218_REG_FIR_DATA_BIT0_7 0x29
#define ES9218_REG_FIR_DATA_BIT8_15 0x2a
#define ES9218_REG_FIR_DATA_BIT16_23 0x2b
#define ES9218_REG_PROG_FIR_CONFIG 0x2c
#define ES9218_REG_ANALOG_OVERRIDE_1 0x2d
#define ES9218_REG_ANALOG_OVERRIDE_2 0x2e
#define ES9218_REG_ANALOG_OVERRIDE_3 0x2f
#define ES9218_REG_ANALOG_CTRL 0x30
#define ES9218_REG_CLKGEAR_CFG_BIT0_7 0x31
#define ES9218_REG_CLKGEAR_CFG_BIT8_15 0x32
#define ES9218_REG_CLKGEAR_CFG_BIT16_23 0x33
#define ES9218_REG_RESERVED_4 0x34
#define ES9218_REG_THD_COMP_C2_CH2_LO 0x35
#define ES9218_REG_THD_COMP_C2_CH2_HI 0x36
#define ES9218_REG_THD_COMP_C3_CH2_LO 0x37
#define ES9218_REG_THD_COMP_C3_CH2_HI 0x38
#define ES9218_REG_RESERVED_5 0x39
#define ES9218_REG_RESERVED_6 0x3a
#define ES9218_REG_RESERVED_7 0x3b
#define ES9218_REG_RESERVED_8 0x3c
#define ES9218_REG_CHIP_ID_AND_STATUS 0x40
#define ES9218_REG_GPIO_AND_CLOCK_GEAR 0x41
#define ES9218_REG_DPLL_NUMBER_BIT0_7 0x42
#define ES9218_REG_DPLL_NUMBER_BIT8_15 0x43
#define ES9218_REG_DPLL_NUMBER_BIT16_23 0x44
#define ES9218_REG_DPLL_NUMBER_BIT24_31 0x45
#define ES9218_REG_INPUT_MUTE_STATUS 0x48
#define ES9218_REG_FIR_READ_BIT0_7 0x49
#define ES9218_REG_FIR_READ_BIT8_15 0x4a
#define ES9218_REG_FIR_READ_BIT16_23 0x4b
enum es9218_clock_gear {
ES9218_CLK_GEAR_1 = 0, /* CLK = XI/1 */
ES9218_CLK_GEAR_2 = 1, /* CLK = XI/2 */
ES9218_CLK_GEAR_4 = 2, /* CLK = XI/4 */
ES9218_CLK_GEAR_8 = 3, /* CLK = XI/8 */
};
enum es9218_amp_mode {
ES9218_AMP_MODE_CORE_ON = 0,
ES9218_AMP_MODE_LOWFI = 1,
ES9218_AMP_MODE_1VRMS = 2,
ES9218_AMP_MODE_2VRMS = 3,
};
enum es9218_iface_role {
ES9218_IFACE_ROLE_SLAVE = 0,
ES9218_IFACE_ROLE_MASTER = 1,
};
enum es9218_iface_format {
ES9218_IFACE_FORMAT_I2S = 0,
ES9218_IFACE_FORMAT_LJUST = 1,
ES9218_IFACE_FORMAT_RJUST = 2,
};
enum es9218_iface_bits {
ES9218_IFACE_BITS_16 = 0,
ES9218_IFACE_BITS_24 = 1,
ES9218_IFACE_BITS_32 = 2,
};
enum es9218_filter_type {
ES9218_FILTER_LINEAR_FAST = 0,
ES9218_FILTER_LINEAR_SLOW = 1,
ES9218_FILTER_MINIMUM_FAST = 2,
ES9218_FILTER_MINIMUM_SLOW = 3,
ES9218_FILTER_APODIZING_1 = 4,
ES9218_FILTER_APODIZING_2 = 5,
ES9218_FILTER_HYBRID_FAST = 6,
ES9218_FILTER_BRICK_WALL = 7,
};
/* Power DAC on or off */
extern void es9218_open(void);
extern void es9218_close(void);
/* Clock controls
*
* - Clock gear divides the input master clock to produce the DAC's clock.
* Frequency can be lowered to save power when using lower sample rates.
*
* - NCO (numerically controller oscillator), according to the datasheet,
* defines the ratio between the DAC's clock and the FSR (for PCM modes,
* this is I2S frame clock = sample rate). In master mode it effectively
* controls the sampling frequency by setting the I2S frame clock output.
* It can also be used in slave mode, but other parts of the datasheet
* say contradictory things about synchronous operation in slave mode.
*
* - If using NCO mode and a varying MCLK input (eg. input from the SoC) then
* you will need to call es9218_recompute_nco() when changing MCLK in order
* to refresh the NCO setting.
*/
extern void es9218_set_clock_gear(enum es9218_clock_gear gear);
extern void es9218_set_nco_frequency(uint32_t fsr);
extern void es9218_recompute_nco(void);
/* Amplifier controls */
extern void es9218_set_amp_mode(enum es9218_amp_mode mode);
extern void es9218_set_amp_powered(bool en);
/* Interface selection */
extern void es9218_set_iface_role(enum es9218_iface_role role);
extern void es9218_set_iface_format(enum es9218_iface_format fmt,
enum es9218_iface_bits bits);
/* Volume controls, all volumes given in units of dB/10 */
extern void es9218_set_dig_volume(int vol_l, int vol_r);
extern void es9218_set_amp_volume(int vol);
/* System mute */
extern void es9218_mute(bool muted);
/* Oversampling filter */
extern void es9218_set_filter(enum es9218_filter_type filt);
/* Automute settings */
extern void es9218_set_automute_time(int time);
extern void es9218_set_automute_level(int dB);
extern void es9218_set_automute_fast_mode(bool en);
/* DPLL bandwidth setting (knob = 0-15) */
extern void es9218_set_dpll_bandwidth(int knob);
/* THD compensation */
extern void es9218_set_thd_compensation(bool en);
extern void es9218_set_thd_coeffs(uint16_t c2, uint16_t c3);
/* Direct register read/write/update operations */
extern int es9218_read(int reg);
extern void es9218_write(int reg, uint8_t val);
extern void es9218_update(int reg, uint8_t msk, uint8_t val);
/* GPIO pin setting callbacks */
extern void es9218_set_power_pin(int level);
extern void es9218_set_reset_pin(int level);
/* XI(MCLK) getter -- supplied by the target.
*
* Note: when changing the supplied MCLK frequency, the NCO will need to be
* reprogrammed for the new master clock. Call es9218_recompute_nco() to
* force this. Not necessary if you're not using NCO mode.
*/
extern uint32_t es9218_get_mclk(void);
#endif /* __ES9218_H__ */