summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/erosqnative
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/erosqnative')
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c40
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c26
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c146
3 files changed, 201 insertions, 11 deletions
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
index df97aba0c8..6968a19a1c 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
@@ -104,6 +104,30 @@ void audiohw_postinit(void)
104 * for 24-bit data... */ 104 * for 24-bit data... */
105 // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data 105 // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data
106 106
107 /* Datasheet: Sets the number os FSR edges that must occur before *
108 * the DPLL and ASRC can lock on to the the incoming Signal. *
109 * When Samplerates >= 96khz could be used, STOP_DIV should be set *
110 * to 0 (= 16384 FSR Edges). *
111 * Reg #10 [3:0] (0x05 default, 2730 FSR Edges) */
112 es9018k2m_write_reg(ES9018K2M_REG10_MASTER_MODE_CTRL, 0x00);
113
114 /* Datasheet: The ES90x8Q2M/K2M contains a Jitter Eliminator block, *
115 * which employs the use of a digital phase locked loop (DPLL) to *
116 * lock to the incoming audio clock rate. When in I2S or SPDIF mode, *
117 * the DPLL will lock to the frame clock (1 x fs). However, when in *
118 * DSD mode, the DPLL has no frame clock information, and must in- *
119 * stead lock to the bit clock rate (BCK). For this reason, there are *
120 * two bandwidth settings for the DPLL. *
121 Reg #12 [7:4] (0x05 default) bandwidth for I2S / SPDIF mode.
122 Reg #12 [3:0] (0x0A default) bandwidth for DSD mode.
123 * The DPLL bandwidth sets how quickly the DPLL can adjust its intern *
124 * representation of the audio clock. The higher the jitter or *
125 * frequency drift on the audio clock, the higher the bandwidth must *
126 * be so that the DPLL can react. *
127 * ! If the bandwidth is “too low”, the DPLL will loose lock and you *
128 * ! will hear random dropouts. (Fixed my SurfansF20 v3.2 dropouts) */
129 es9018k2m_write_reg(ES9018K2M_REG12_DPLL_SETTINGS, 0xda);
130
107 } else { /* Default to SWVOL for PCM5102A DAC */ 131 } else { /* Default to SWVOL for PCM5102A DAC */
108 logf("Default to SWVOL: ret=%d", ret); 132 logf("Default to SWVOL: ret=%d", ret);
109 } 133 }
@@ -139,17 +163,19 @@ void audiohw_set_volume(int vol_l, int vol_r)
139 r = vol_r; 163 r = vol_r;
140 164
141#if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) 165#if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION))
142 /* make sure headphones aren't present - don't want to 166 /* Due to the hardware's detection method, make the Line-Out
143 * blow out our eardrums cranking it to full */ 167 * the default. The LO can only be detected if it is active
144 if (lineout_inserted() && !headphones_inserted()) 168 * (assuming a high-impedance device is attached). HP takes priority
169 * if both are present. */
170 if (headphones_inserted())
145 { 171 {
146 eros_qn_switch_output(1); 172 eros_qn_switch_output(0);
147
148 l = r = eros_qn_get_volume_limit();
149 } 173 }
150 else 174 else
151 { 175 {
152 eros_qn_switch_output(0); 176 eros_qn_switch_output(1);
177
178 l = r = eros_qn_get_volume_limit();
153 } 179 }
154#endif 180#endif
155 181
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
index 0d2207af2a..707dc372a8 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
@@ -75,12 +75,26 @@ volatile signed int enc_position = 0;
75/* Value of headphone detect register */ 75/* Value of headphone detect register */
76static uint8_t hp_detect_reg = 0x00; 76static uint8_t hp_detect_reg = 0x00;
77static uint8_t hp_detect_reg_old = 0x00; 77static uint8_t hp_detect_reg_old = 0x00;
78static uint8_t hp_detect_debounce1 = 0x00;
79static uint8_t hp_detect_debounce2 = 0x00;
80static uint8_t debounce_count = 0;
78 81
79/* Interval to poll the register */ 82/* Interval to poll the register */
80#define HPD_POLL_TIME (HZ/2) 83#define HPD_POLL_TIME (HZ/4)
81 84
82static int hp_detect_tmo_cb(struct timeout* tmo) 85static int hp_detect_tmo_cb(struct timeout* tmo)
83{ 86{
87 if (hp_detect_debounce1 == hp_detect_debounce2){
88 if (debounce_count >= 2){
89 debounce_count = 2;
90 } else {
91 debounce_count = debounce_count + 1;
92 }
93 } else {
94 debounce_count = 0;
95 hp_detect_debounce2 = hp_detect_debounce1;
96 }
97
84 i2c_descriptor* d = (i2c_descriptor*)tmo->data; 98 i2c_descriptor* d = (i2c_descriptor*)tmo->data;
85 i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d); 99 i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d);
86 return HPD_POLL_TIME; 100 return HPD_POLL_TIME;
@@ -96,7 +110,7 @@ static void hp_detect_init(void)
96 .tran_mode = I2C_READ, 110 .tran_mode = I2C_READ,
97 .buffer[0] = (void*)&gpio_reg, 111 .buffer[0] = (void*)&gpio_reg,
98 .count[0] = 1, 112 .count[0] = 1,
99 .buffer[1] = &hp_detect_reg, 113 .buffer[1] = &hp_detect_debounce1,
100 .count[1] = 1, 114 .count[1] = 1,
101 .callback = NULL, 115 .callback = NULL,
102 .arg = 0, 116 .arg = 0,
@@ -113,6 +127,8 @@ static void hp_detect_init(void)
113 if(r >= 0) 127 if(r >= 0)
114 { 128 {
115 hp_detect_reg = r; 129 hp_detect_reg = r;
130 hp_detect_debounce1 = r;
131 hp_detect_debounce2 = r;
116 hp_detect_reg_old = hp_detect_reg; 132 hp_detect_reg_old = hp_detect_reg;
117 } 133 }
118 134
@@ -122,6 +138,9 @@ static void hp_detect_init(void)
122 138
123bool headphones_inserted(void) 139bool headphones_inserted(void)
124{ 140{
141 if (debounce_count > 1){
142 hp_detect_reg = hp_detect_debounce2;
143 }
125 /* if the status has changed, set the output volume accordingly */ 144 /* if the status has changed, set the output volume accordingly */
126 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) 145 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30))
127 { 146 {
@@ -135,6 +154,9 @@ bool headphones_inserted(void)
135 154
136bool lineout_inserted(void) 155bool lineout_inserted(void)
137{ 156{
157 if (debounce_count > 1){
158 hp_detect_reg = hp_detect_debounce2;
159 }
138 /* if the status has changed, set the output volume accordingly */ 160 /* if the status has changed, set the output volume accordingly */
139 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) 161 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30))
140 { 162 {
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c
index 0d43a3f010..bcc30a71bd 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c
@@ -25,11 +25,138 @@
25#include "lcd-x1000.h" 25#include "lcd-x1000.h"
26#include "gpio-x1000.h" 26#include "gpio-x1000.h"
27#include "system.h" 27#include "system.h"
28#include "devicedata.h"
28 29
29/* for reference on these command/data hex values, see the mipi dcs lcd spec. * 30/* for reference on these command/data hex values, see the mipi dcs lcd spec. *
30 * Not everything here is there, but all the standard stuff is. */ 31 * Not everything here is there, but all the standard stuff is. */
31 32
32static const uint32_t erosqnative_lcd_cmd_enable[] = { 33/* New Display Eroq 2.1 / Hifiwalker 1.7+ / Surfans v3.2, unknown Controller *
34 * (partially GC9A01 register compatible) *
35 * https://espruino.microcosm.app/api/v1/files/ \ *
36 * 9dc1b976d621a2ab3854312cce862c4a9a50dc1b.html#GC9A01 , *
37 * https://www.buydisplay.com/download/ic/GC9A01A.pdf , *
38 * https://lcddisplay.co/wp-content/uploads/2023/02/GC9A01.pdf *
39 * Init sequence From 'EROS Q (c口)_V2.1_20231209固件.zip' *
40 * update.upt/.iso -> In 'uboot.bin' at 0x52da0-0x5305f *
41 * http://www.eroshifi.com/download/firmware/122.html */
42static const uint32_t erosqnative_lcd_cmd_enable_v3[] = {
43
44 /* Unlock EXTC? */
45 LCD_INSTR_CMD, 0xfe, // Inter Register Enable1
46 LCD_INSTR_CMD, 0xef, // Inter Register Enable2
47
48 LCD_INSTR_CMD, 0x36, // Memory Access Control
49/* Bit7 1:vertical flip 0:no vertical flip
50 Bit6 1:horizontal flip 0:no horizontal flip
51 Bit3 1:BGR 0:RGB */
52 LCD_INSTR_DAT, 0x90,
53 /* Pixel Format Set */
54 LCD_INSTR_CMD, 0x3a,
55 LCD_INSTR_DAT, 0x55, /* Rockbox uses 16pp, OF specified 18 bpp */
56
57 LCD_INSTR_CMD, 0x84, // ?? (undocumented)
58 LCD_INSTR_DAT, 0x04,
59 LCD_INSTR_CMD, 0x86, // ??
60 LCD_INSTR_DAT, 0xfb,
61 LCD_INSTR_CMD, 0x87, // ??
62 LCD_INSTR_DAT, 0x79,
63 LCD_INSTR_CMD, 0x89, // ??
64 LCD_INSTR_DAT, 0x0b,
65 LCD_INSTR_CMD, 0x8a, // ??
66 LCD_INSTR_DAT, 0x20,
67 LCD_INSTR_CMD, 0x8b, // ??
68 LCD_INSTR_DAT, 0x80,
69 LCD_INSTR_CMD, 0x8d, // ??
70 LCD_INSTR_DAT, 0x3b,
71 LCD_INSTR_CMD, 0x8e, // ??
72 LCD_INSTR_DAT, 0xcf,
73
74 LCD_INSTR_CMD, 0xec, // Charge Pump Frequent Control
75 LCD_INSTR_DAT, 0x33,
76 LCD_INSTR_DAT, 0x02,
77 LCD_INSTR_DAT, 0x4c,
78
79 LCD_INSTR_CMD, 0x98, // ?? (undocumented)
80 LCD_INSTR_DAT, 0x3e,
81 LCD_INSTR_CMD, 0x9c, // ??
82 LCD_INSTR_DAT, 0x4b,
83 LCD_INSTR_CMD, 0x99, // ??
84 LCD_INSTR_DAT, 0x3e,
85 LCD_INSTR_CMD, 0x9d, // ??
86 LCD_INSTR_DAT, 0x4b,
87 LCD_INSTR_CMD, 0x9b, // ??
88 LCD_INSTR_DAT, 0x55,
89
90 LCD_INSTR_CMD, 0xe8, // Frame Rate
91 LCD_INSTR_DAT, 0x11,
92 LCD_INSTR_DAT, 0x00,
93
94 LCD_INSTR_CMD, 0xff, // ?? (Adafruit & Co lib. C:0xFF, D:0x60, D:0x01, D:0x04)
95 LCD_INSTR_DAT, 0x62, // LCD_INSTR_DAT, 0x01, LCD_INSTR_DAT, 0x04,
96 LCD_INSTR_CMD, 0xc3, // Vreg1a voltage Control
97 LCD_INSTR_DAT, 0x20,
98 LCD_INSTR_CMD, 0xc4, // Vreg1b voltage Control
99 LCD_INSTR_DAT, 0x03,
100 LCD_INSTR_CMD, 0xc9, // Vreg2a voltage Control
101 LCD_INSTR_DAT, 0x2a,
102
103 LCD_INSTR_CMD, 0xf0, // SET_GAMMA1
104 LCD_INSTR_DAT, 0x4a,
105 LCD_INSTR_DAT, 0x10,
106 LCD_INSTR_DAT, 0x0a,
107 LCD_INSTR_DAT, 0x0a,
108 LCD_INSTR_DAT, 0x26,
109 LCD_INSTR_DAT, 0x39,
110
111 LCD_INSTR_CMD, 0xf2, // SET_GAMMA3
112 LCD_INSTR_DAT, 0x4a,
113 LCD_INSTR_DAT, 0x10,
114 LCD_INSTR_DAT, 0x0a,
115 LCD_INSTR_DAT, 0x0a,
116 LCD_INSTR_DAT, 0x26,
117 LCD_INSTR_DAT, 0x39,
118
119 LCD_INSTR_CMD, 0xf1, // SET_GAMMA2
120 LCD_INSTR_DAT, 0x50,
121 LCD_INSTR_DAT, 0x8f,
122 LCD_INSTR_DAT, 0xaf,
123 LCD_INSTR_DAT, 0x3b,
124 LCD_INSTR_DAT, 0x3f,
125 LCD_INSTR_DAT, 0x7f,
126
127 LCD_INSTR_CMD, 0xf3, // SET_GAMMA4
128 LCD_INSTR_DAT, 0x50,
129 LCD_INSTR_DAT, 0x8f,
130 LCD_INSTR_DAT, 0xaf,
131 LCD_INSTR_DAT, 0x3b,
132 LCD_INSTR_DAT, 0x3f,
133 LCD_INSTR_DAT, 0x7f,
134
135 LCD_INSTR_CMD, 0xba, // TE Control
136 LCD_INSTR_DAT, 0x0a,
137
138#ifdef BOOTLOADER
139 LCD_INSTR_CMD, 0x35, // Tearing Effect Line ON
140 LCD_INSTR_DAT, 0x00,
141#endif
142
143 LCD_INSTR_CMD, 0x21, /* Invert */
144
145 /* Lock EXTC? */
146 LCD_INSTR_CMD, 0xfe, // Inter Register Enable1
147 LCD_INSTR_CMD, 0xee,
148
149 /* Exit Sleep */
150 LCD_INSTR_CMD, 0x11,
151 LCD_INSTR_UDELAY, 120000,
152 /* Display On */
153 LCD_INSTR_CMD, 0x29,
154 LCD_INSTR_UDELAY, 20000,
155 LCD_INSTR_END,
156};
157
158/* Original Display / Hifiwalker -1.5 / Surfans -2.7 */
159static const uint32_t erosqnative_lcd_cmd_enable_v1[] = {
33 /* Set EXTC? */ 160 /* Set EXTC? */
34 LCD_INSTR_CMD, 0xc8, 161 LCD_INSTR_CMD, 0xc8,
35 LCD_INSTR_DAT, 0xff, 162 LCD_INSTR_DAT, 0xff,
@@ -179,7 +306,22 @@ void lcd_tgt_enable(bool enable)
179 mdelay(5); 306 mdelay(5);
180 gpio_set_level(GPIO_LCD_CE, 0); 307 gpio_set_level(GPIO_LCD_CE, 0);
181 308
182 lcd_exec_commands(&erosqnative_lcd_cmd_enable[0]); 309#ifdef BOOTLOADER
310# if EROSQN_VER == 3
311 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]);
312# else
313 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]);
314# endif
315#else
316 if (device_data.lcd_version == 3)
317 {
318 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]);
319 }
320 else
321 {
322 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]);
323 }
324#endif
183 } else { 325 } else {
184 /* doesn't flash white if we don't do anything... */ 326 /* doesn't flash white if we don't do anything... */
185#if 0 327#if 0