summaryrefslogtreecommitdiff
path: root/firmware/target/mips
diff options
context:
space:
mode:
authorDana Conrad <dconrad@fastmail.com>2023-11-21 19:28:51 -0600
committerAidan MacDonald <amachronic@protonmail.com>2024-01-02 06:51:07 -0500
commita3fe07ff128e521051aee8bc91add071724d6538 (patch)
tree9e3eb34908a4571f85686877085d9f5b200d1c2a /firmware/target/mips
parent161c861153f67c2436affc11860ed932a0d21c30 (diff)
downloadrockbox-a3fe07ff128e521051aee8bc91add071724d6538.tar.gz
rockbox-a3fe07ff128e521051aee8bc91add071724d6538.zip
ErosQ New Revision HW volume
Add HW volume control via ES9018K2M, and reorganize eros_qn_codec.c/.h, audiohw-erosqnative.c. This automatically detects the presence of the new DAC and uses its hardware volume scaling. If not present, use same SWVOL we have been using so far. Add debug menu readout of SWVOL/I2C result. Break out es9018k2m stuff into its own file so that maybe it can be useful to other ports. Note that we may need to get smarter about detecting the DAC type if/when another model emerges. Change-Id: I586a1cf7f150dd6b4e221157859825952840af56
Diffstat (limited to 'firmware/target/mips')
-rw-r--r--firmware/target/mips/ingenic_x1000/debug-x1000.c13
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c77
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c4
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h6
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h3
5 files changed, 94 insertions, 9 deletions
diff --git a/firmware/target/mips/ingenic_x1000/debug-x1000.c b/firmware/target/mips/ingenic_x1000/debug-x1000.c
index 236442a880..827bb37855 100644
--- a/firmware/target/mips/ingenic_x1000/debug-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/debug-x1000.c
@@ -121,6 +121,9 @@ extern volatile unsigned aic_tx_underruns;
121#ifdef HAVE_RECORDING 121#ifdef HAVE_RECORDING
122extern volatile unsigned aic_rx_overruns; 122extern volatile unsigned aic_rx_overruns;
123#endif 123#endif
124#ifdef HAVE_EROS_QN_CODEC
125extern int es9018k2m_present_flag;
126#endif
124 127
125static bool dbg_audio(void) 128static bool dbg_audio(void)
126{ 129{
@@ -130,6 +133,16 @@ static bool dbg_audio(void)
130#ifdef HAVE_RECORDING 133#ifdef HAVE_RECORDING
131 lcd_putsf(0, 1, "RX overruns: %u", aic_rx_overruns); 134 lcd_putsf(0, 1, "RX overruns: %u", aic_rx_overruns);
132#endif 135#endif
136#ifdef HAVE_EROS_QN_CODEC
137 if (es9018k2m_present_flag)
138 {
139 lcd_putsf(0, 2, "(%d) ES9018K2M HWVOL", es9018k2m_present_flag);
140 }
141 else
142 {
143 lcd_putsf(0, 2, "(%d) SWVOL", es9018k2m_present_flag);
144 }
145#endif
133 lcd_update(); 146 lcd_update();
134 } while(get_action(CONTEXT_STD, HZ) != ACTION_STD_CANCEL); 147 } while(get_action(CONTEXT_STD, HZ) != ACTION_STD_CANCEL);
135 148
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
index c53da728ff..1e3e7f0b7f 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
@@ -19,13 +19,19 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "audiohw.h"
23#include "system.h" 22#include "system.h"
23#include "audiohw.h"
24#include "pcm_sw_volume.h"
24#include "pcm_sampr.h" 25#include "pcm_sampr.h"
26#include "i2c-target.h"
27#include "button.h"
28
29// #define LOGF_ENABLE
30#include "logf.h"
31
25#include "aic-x1000.h" 32#include "aic-x1000.h"
26#include "i2c-x1000.h" 33#include "i2c-x1000.h"
27#include "gpio-x1000.h" 34#include "gpio-x1000.h"
28#include "logf.h"
29 35
30/* 36/*
31 * Earlier devices audio path appears to be: 37 * Earlier devices audio path appears to be:
@@ -42,7 +48,7 @@ void audiohw_init(void)
42 /* explicitly mute everything */ 48 /* explicitly mute everything */
43 gpio_set_level(GPIO_HPAMP_SHDN, 0); 49 gpio_set_level(GPIO_HPAMP_SHDN, 0);
44 gpio_set_level(GPIO_STEREOSW_MUTE, 1); 50 gpio_set_level(GPIO_STEREOSW_MUTE, 1);
45 gpio_set_level(GPIO_DAC_XMIT, 0); 51 gpio_set_level(GPIO_DAC_PWR, 0);
46 52
47 aic_set_play_last_sample(true); 53 aic_set_play_last_sample(true);
48 aic_set_external_codec(true); 54 aic_set_external_codec(true);
@@ -81,18 +87,34 @@ void audiohw_postinit(void)
81 gpio_set_level(GPIO_STEREOSW_SEL, 0); 87 gpio_set_level(GPIO_STEREOSW_SEL, 0);
82 gpio_set_level(GPIO_HPAMP_SHDN, 1); 88 gpio_set_level(GPIO_HPAMP_SHDN, 1);
83 mdelay(10); 89 mdelay(10);
84 gpio_set_level(GPIO_DAC_XMIT, 1); 90 gpio_set_level(GPIO_DAC_PWR, 1);
85 mdelay(10); 91 mdelay(10);
86 gpio_set_level(GPIO_STEREOSW_MUTE, 0); 92 gpio_set_level(GPIO_STEREOSW_MUTE, 0);
93
94 i2c_x1000_set_freq(ES9018K2M_BUS, I2C_FREQ_400K);
95
96 int ret = es9018k2m_read_reg(ES9018K2M_REG0_SYSTEM_SETTINGS);
97 if (ret >= 0) /* Detected ES9018K2M DAC */
98 {
99 logf("ES9018K2M found: ret=%d", ret);
100 es9018k2m_present_flag = 1;
101
102 /* Default is 32-bit data, and it works ok. Enabling the following
103 * causes issue. Which is weird, I definitely thought AIC was configured
104 * for 24-bit data... */
105 // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data
106
107 } else { /* Default to SWVOL for PCM5102A DAC */
108 logf("Default to SWVOL: ret=%d", ret);
109 }
87} 110}
88 111
89/* TODO: get shutdown just right according to dac datasheet */
90void audiohw_close(void) 112void audiohw_close(void)
91{ 113{
92 /* mute - attempt to make power-off pop-free */ 114 /* mute - attempt to make power-off pop-free */
93 gpio_set_level(GPIO_STEREOSW_MUTE, 1); 115 gpio_set_level(GPIO_STEREOSW_MUTE, 1);
94 mdelay(10); 116 mdelay(10);
95 gpio_set_level(GPIO_DAC_XMIT, 0); 117 gpio_set_level(GPIO_DAC_PWR, 0);
96 mdelay(10); 118 mdelay(10);
97 gpio_set_level(GPIO_HPAMP_SHDN, 0); 119 gpio_set_level(GPIO_HPAMP_SHDN, 0);
98} 120}
@@ -107,3 +129,46 @@ void audiohw_set_frequency(int fsel)
107 aic_enable_i2s_bit_clock(true); 129 aic_enable_i2s_bit_clock(true);
108} 130}
109 131
132void audiohw_set_volume(int vol_l, int vol_r)
133{
134 int l, r;
135
136 eros_qn_set_last_vol(vol_l, vol_r);
137
138 l = vol_l;
139 r = vol_r;
140
141#if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION))
142 /* make sure headphones aren't present - don't want to
143 * blow out our eardrums cranking it to full */
144 if (lineout_inserted() && !headphones_inserted())
145 {
146 eros_qn_switch_output(1);
147
148 l = r = eros_qn_get_volume_limit();
149 }
150 else
151 {
152 eros_qn_switch_output(0);
153 }
154#endif
155
156 if (es9018k2m_present_flag) /* ES9018K2M */
157 {
158 /* Same volume range and mute point for both DACs, so use PCM5102A_VOLUME_MIN */
159 l = l <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : l;
160 r = r <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : r;
161
162 /* set software volume just below unity due to
163 * DAC offset. We don't want to overflow the PCM system. */
164 pcm_set_master_volume(-1, -1);
165 es9018k2m_set_volume(l, r);
166 }
167 else /* PCM5102A */
168 {
169 l = l <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : (l / 20);
170 r = r <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : (r / 20);
171
172 pcm_set_master_volume(l, r);
173 }
174} \ No newline at end of file
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
index d82cb5b5dc..0d2207af2a 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
@@ -127,7 +127,7 @@ bool headphones_inserted(void)
127 { 127 {
128 hp_detect_reg_old = hp_detect_reg; 128 hp_detect_reg_old = hp_detect_reg;
129#if !defined(BOOTLOADER) 129#if !defined(BOOTLOADER)
130 dac_set_outputs(); 130 eros_qn_set_outputs();
131#endif 131#endif
132 } 132 }
133 return hp_detect_reg & 0x10 ? false : true; 133 return hp_detect_reg & 0x10 ? false : true;
@@ -140,7 +140,7 @@ bool lineout_inserted(void)
140 { 140 {
141 hp_detect_reg_old = hp_detect_reg; 141 hp_detect_reg_old = hp_detect_reg;
142#if !defined(BOOTLOADER) 142#if !defined(BOOTLOADER)
143 dac_set_outputs(); 143 eros_qn_set_outputs();
144#endif 144#endif
145 } 145 }
146 return hp_detect_reg & 0x20 ? false : true; 146 return hp_detect_reg & 0x20 ? false : true;
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h
index 3318a39786..72052c261f 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h
@@ -15,17 +15,21 @@
15 15
16/* ---------------------------------------------- */ 16/* ---------------------------------------------- */
17 17
18
18/* Name Port Pins Function */ 19/* Name Port Pins Function */
19DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1)) 20DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1))
20DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1)) 21DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1))
21DEFINE_PINGROUP(MSC0, GPIO_A, 0x3f << 20, GPIOF_DEVICE(1)) 22DEFINE_PINGROUP(MSC0, GPIO_A, 0x3f << 20, GPIOF_DEVICE(1))
22DEFINE_PINGROUP(SFC, GPIO_A, 0x3f << 26, GPIOF_DEVICE(1)) 23DEFINE_PINGROUP(SFC, GPIO_A, 0x3f << 26, GPIOF_DEVICE(1))
23DEFINE_PINGROUP(I2S, GPIO_B, 0x1f << 0, GPIOF_DEVICE(1)) 24DEFINE_PINGROUP(I2S, GPIO_B, 0x1f << 0, GPIOF_DEVICE(1))
25DEFINE_PINGROUP(I2C1, GPIO_C, 3 << 26, GPIOF_DEVICE(0))
24DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1)) 26DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1))
25 27
26/* Name Pin Function */ 28/* Name Pin Function */
27/* mute DAC: 0 - mute, 1 - play */ 29/* mute DAC: 0 - mute, 1 - play */
28DEFINE_GPIO(DAC_XMIT, GPIO_PB(12), GPIOF_OUTPUT(0)) 30/* Note: This seems to actually be power to the DAC in general,
31 * at least on the ES9018K2M devices. Was "DAC_XMIT". */
32DEFINE_GPIO(DAC_PWR, GPIO_PB(12), GPIOF_OUTPUT(0))
29 33
30/* mute HP amp: 0 - mute, 1 - play */ 34/* mute HP amp: 0 - mute, 1 - play */
31DEFINE_GPIO(HPAMP_SHDN, GPIO_PB(8), GPIOF_OUTPUT(0)) 35DEFINE_GPIO(HPAMP_SHDN, GPIO_PB(8), GPIOF_OUTPUT(0))
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h
index 8d0b8a6e20..89d995f33a 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h
@@ -25,6 +25,9 @@
25#define I2C_ASYNC_BUS_COUNT 3 25#define I2C_ASYNC_BUS_COUNT 3
26#define I2C_ASYNC_QUEUE_SIZE 4 26#define I2C_ASYNC_QUEUE_SIZE 4
27 27
28#define ES9018K2M_BUS 1
29#define ES9018K2M_ADDR 0x48
30
28#define AXP_PMU_BUS 2 31#define AXP_PMU_BUS 2
29#define AXP_PMU_ADDR 0x34 32#define AXP_PMU_ADDR 0x34
30 33