summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDana Conrad <dconrad@fastmail.com>2023-12-03 15:07:26 -0600
committerAidan MacDonald <amachronic@protonmail.com>2024-01-02 08:19:23 -0500
commit8cc7476735dd3f9f9e3f5b1356eadc4ef40c23b4 (patch)
tree23891c54ebb8e6adaea8b8382830c7e29ad7475d
parenta3fe07ff128e521051aee8bc91add071724d6538 (diff)
downloadrockbox-8cc7476735.tar.gz
rockbox-8cc7476735.zip
ErosQ Native ES9018K2M: Add digital filters capability
Setting not yet hidden for older hardware revision. Change-Id: Iaaa5727e63c38de578a6bbc73498ae1073180e65
-rw-r--r--apps/features.txt4
-rw-r--r--firmware/drivers/audio/es9018k2m.c48
-rw-r--r--firmware/export/config/erosqnative.h2
-rw-r--r--firmware/export/es9018k2m.h14
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c10
5 files changed, 70 insertions, 8 deletions
diff --git a/apps/features.txt b/apps/features.txt
index 1356d20e34..a43172932f 100644
--- a/apps/features.txt
+++ b/apps/features.txt
@@ -186,7 +186,7 @@ depth_3d
#endif
/* This should be AUDIOHW_HAVE_FILTER_ROLL_OFF but that is only defined later */
-#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)
+#if defined(DX50) || defined(HAVE_DF1704_CODEC) || defined(HAVE_PCM1792_CODEC) || defined(HAVE_CS4398) || defined(HAVE_WM8740) || defined(HAVE_ES9018)|| defined(HAVE_EROS_QN_CODEC) || defined(HAVE_XDUOO_LINUX_CODEC) || defined(HAVE_FIIO_LINUX_CODEC) || defined(HAVE_AK4376) || defined(HAVE_ES9218)
filter_roll_off
#endif
@@ -195,7 +195,7 @@ filter_roll_off
dac_power_mode
#endif
-#if defined(HAVE_ES9018)
+#if defined(HAVE_ES9018) || defined(HAVE_EROS_QN_CODEC)
es9018
#endif
diff --git a/firmware/drivers/audio/es9018k2m.c b/firmware/drivers/audio/es9018k2m.c
index e19cf6e8a9..3f14aaea39 100644
--- a/firmware/drivers/audio/es9018k2m.c
+++ b/firmware/drivers/audio/es9018k2m.c
@@ -55,15 +55,20 @@ static int vol_tenthdb2hw(const int tdb)
* static uint8_t reg4_automute_time = 0x00; // Automute time. Default = disabled
* static uint8_t reg5_automute_level = 0x68; // Automute level. Default is some level
* static uint8_t reg6_deemphasis = 0x4A; // Deemphasis. Default = disabled
- * static uint8_t reg7_general_settings = 0x80; // General settings. Default sharp fir, pcm iir and unmuted
+ */
+static uint8_t reg7_general_settings = 0x80; // General settings. Default sharp fir, pcm iir and unmuted
+/*
* static uint8_t reg8_gpio_configuration = 0x10; // GPIO configuration
* static uint8_t reg10_master_mode_control = 0x05; // Master Mode Control. Default value: master mode off
* static uint8_t reg11_channel_mapping = 0x02; // Channel Mapping. Default stereo is Ch1=left, Ch2=right
* static uint8_t reg12_dpll_settings = 0x5A; // DPLL Settings. Default = 5 for I2S, A for DSD
* static uint8_t reg13_thd_comp = 0x40; // THD Compensation
* static uint8_t reg14_softstart_settings = 0x8A; // Soft Start Settings
- * static uint8_t reg21_gpio_input_selection = 0x00; // Oversampling filter. Default: oversampling ON
*/
+static uint8_t reg21_gpio_input_selection = 0x00; // Oversampling filter. Default: oversampling ON
+
+#define bitSet(value, bit) ((value) |= (1UL << (bit)))
+#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
static uint8_t vol_reg_l = ES9018K2M_REG15_VOLUME_L;
static uint8_t reg15_vol_l = 0;
@@ -95,7 +100,7 @@ i2c_descriptor vol_desc_r = {
.next = NULL,
};
-void es9018k2m_set_volume(int vol_l, int vol_r)
+void es9018k2m_set_volume_async(int vol_l, int vol_r)
{
/* Queue writes to the DAC's volume.
* Note that this needs to be done asynchronously. From testing, calling
@@ -106,6 +111,43 @@ void es9018k2m_set_volume(int vol_l, int vol_r)
i2c_async_queue(ES9018K2M_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, &vol_desc_r);
}
+void es9018k2m_set_filter_roll_off(int value)
+{
+ /* Note: the ihifi800 implementation manipulates
+ * bit 0 of reg21, but I think that is incorrect?
+ * Bit 2 is the bypass for the IIR digital filters,
+ * Whereas Bit 0 is the oversampling filter, which
+ * the datasheet seems to say should be left on. */
+
+ /* 0 = "Sharp" / Fast Rolloff (Default)
+ 1 = Slow Rolloff
+ 2 = "Short" / Minimum Phase
+ 3 = Bypass */
+ switch(value)
+ {
+ case 0:
+ bitClear(reg7_general_settings, 5);
+ bitClear(reg7_general_settings, 6);
+ bitClear(reg21_gpio_input_selection, 2);
+ break;
+ case 1:
+ bitSet(reg7_general_settings, 5);
+ bitClear(reg7_general_settings, 6);
+ bitClear(reg21_gpio_input_selection, 2);
+ break;
+ case 2:
+ bitClear(reg7_general_settings, 5);
+ bitSet(reg7_general_settings, 6);
+ bitClear(reg21_gpio_input_selection, 2);
+ break;
+ case 3:
+ bitSet(reg21_gpio_input_selection, 2);
+ break;
+ }
+ es9018k2m_write_reg(ES9018K2M_REG7_GENERAL_SETTINGS, reg7_general_settings);
+ es9018k2m_write_reg(ES9018K2M_REG21_GPIO_INPUT_SELECT, reg21_gpio_input_selection);
+}
+
/* returns I2C_STATUS_OK upon success, I2C_STATUS_* errors upon error */
int es9018k2m_write_reg(uint8_t reg, uint8_t val)
{
diff --git a/firmware/export/config/erosqnative.h b/firmware/export/config/erosqnative.h
index c71f7ade49..4f87282f1f 100644
--- a/firmware/export/config/erosqnative.h
+++ b/firmware/export/config/erosqnative.h
@@ -63,6 +63,8 @@
#define HAVE_EROS_QN_CODEC
#define HAVE_SW_TONE_CONTROLS
#define HAVE_SW_VOLUME_CONTROL
+#define AUDIOHW_CAPS (FILTER_ROLL_OFF_CAP)
+#define AUDIOHW_HAVE_SHORT_ROLL_OFF
/* use high-bitdepth volume scaling */
#define PCM_NATIVE_BITDEPTH 24
diff --git a/firmware/export/es9018k2m.h b/firmware/export/es9018k2m.h
index 035a607030..2824fed505 100644
--- a/firmware/export/es9018k2m.h
+++ b/firmware/export/es9018k2m.h
@@ -25,6 +25,13 @@
//======================================================================================
// ES9018K2M support stuff
+// Implement audiohw_* functions in audiohw-*.c. These functions are utilities which
+// may be used there.
+
+// AUDIOHW_SETTING(VOLUME, *) not set here, probably best to put it in device-specific *_codec.h
+#ifdef AUDIOHW_HAVE_SHORT_ROLL_OFF
+AUDIOHW_SETTING(FILTER_ROLL_OFF, "", 0, 1, 0, 3, 0)
+#endif
#ifndef ES9018K2M_VOLUME_MIN
# define ES9018K2M_VOLUME_MIN -1270
@@ -50,8 +57,11 @@
#define ES9018K2M_REG16_VOLUME_R 16
#define ES9018K2M_REG21_GPIO_INPUT_SELECT 21
-/* writes volume levels to DAC over I2C */
-void es9018k2m_set_volume(int vol_l, int vol_r);
+/* writes volume levels to DAC over I2C, asynchronously */
+void es9018k2m_set_volume_async(int vol_l, int vol_r);
+
+/* write filter roll-off setting to DAC over I2C, synchronously */
+void es9018k2m_set_filter_roll_off(int value);
/* writes a single register */
/* returns I2C_STATUS_OK upon success, I2C_STATUS_* errors upon error */
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
index 1e3e7f0b7f..df97aba0c8 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
@@ -162,7 +162,7 @@ void audiohw_set_volume(int vol_l, int vol_r)
/* set software volume just below unity due to
* DAC offset. We don't want to overflow the PCM system. */
pcm_set_master_volume(-1, -1);
- es9018k2m_set_volume(l, r);
+ es9018k2m_set_volume_async(l, r);
}
else /* PCM5102A */
{
@@ -171,4 +171,12 @@ void audiohw_set_volume(int vol_l, int vol_r)
pcm_set_master_volume(l, r);
}
+}
+
+void audiohw_set_filter_roll_off(int value)
+{
+ if (es9018k2m_present_flag)
+ {
+ es9018k2m_set_filter_roll_off(value);
+ }
} \ No newline at end of file