summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2024-10-10 13:25:47 -0400
committerSolomon Peachy <pizza@shaftnet.org>2024-11-01 14:12:31 -0400
commit51ba8b3eee2ccfede2c766494b38b1b3404b95e4 (patch)
tree9045030858488e25e1241f289a7d732ee2a509f5
parent1c28cb439b0f2838a8132bb951787207bd0fe0f6 (diff)
downloadrockbox-51ba8b3eee.tar.gz
rockbox-51ba8b3eee.zip
erosqhosted: Support HW volume control on rev2+ hardware
This also adds hwrev info to the debug output. Change-Id: Ia75218cacb8f756a23a77334ea6ab69ac3b20d10
-rw-r--r--firmware/drivers/audio/erosqlinux_codec.c81
-rw-r--r--firmware/target/hosted/agptek/debug-agptek.c6
-rw-r--r--firmware/target/hosted/aigo/power-erosq.c26
-rw-r--r--firmware/target/hosted/alsa-controls.h2
4 files changed, 95 insertions, 20 deletions
diff --git a/firmware/drivers/audio/erosqlinux_codec.c b/firmware/drivers/audio/erosqlinux_codec.c
index 02c35e3c00..d1b3e884d3 100644
--- a/firmware/drivers/audio/erosqlinux_codec.c
+++ b/firmware/drivers/audio/erosqlinux_codec.c
@@ -53,11 +53,29 @@
BUFFER_BYTES: [4096 524288]
TICK_TIME: ALL
- Mixer controls:
+ Mixer controls (v1):
numid=1,iface=MIXER,name='Output Port Switch'
; type=INTEGER,access=rw------,values=1,min=0,max=5,step=0
: values=4
+
+ Mixer controls (v2+):
+
+ numid=3,iface=MIXER,name='ES9018_K2M Digital Filter'
+ ; type=INTEGER,access=rw------,values=1,min=0,max=4,step=0
+ : values=0
+ numid=1,iface=MIXER,name='Left Playback Volume'
+ ; type=INTEGER,access=rw------,values=1,min=0,max=255,step=0
+ : values=0
+ numid=4,iface=MIXER,name='Output Port Switch'
+ ; type=INTEGER,access=rw------,values=1,min=0,max=5,step=0
+ : values=0
+ numid=2,iface=MIXER,name='Right Playback Volume'
+ ; type=INTEGER,access=rw------,values=1,min=0,max=255,step=0
+ : values=0
+ numid=5,iface=MIXER,name='isDSD'
+ ; type=BOOLEAN,access=rw------,values=1
+ : values=off
*/
static int hw_init = 0;
@@ -68,6 +86,8 @@ static long int last_ps = -1;
static int muted = -1;
+extern int hwver;
+
void audiohw_mute(int mute)
{
logf("mute %d", mute);
@@ -129,6 +149,13 @@ void audiohw_preinit(void)
logf("hw preinit");
alsa_controls_init("default");
hw_init = 1;
+
+ /* See if we have hw2 or later */
+ if (alsa_controls_find("Left Playback Volume") == -1)
+ hwver = 1;
+ else if (hwver == 1)
+ hwver = 23;
+
audiohw_mute(false); /* No need to stay muted */
}
@@ -154,10 +181,8 @@ void audiohw_set_frequency(int fsel)
const int min_pcm = -740;
const int max_pcm = 0;
-void audiohw_set_volume(int vol_l, int vol_r)
+static void audiohw_set_volume_v1(int vol_l, int vol_r)
{
- logf("hw vol %d %d", vol_l, vol_r);
-
long l,r;
vol_l_hw = vol_l;
@@ -180,6 +205,39 @@ void audiohw_set_volume(int vol_l, int vol_r)
pcm_set_mixer_volume(sw_volume_l / 20, sw_volume_r / 20);
}
+static void audiohw_set_volume_v2(int vol_l, int vol_r)
+{
+ long l,r;
+
+ if (lineout_inserted()) {
+ vol_l_hw = vol_r_hw = global_settings.volume_limit * 10;
+ } else {
+ vol_l_hw = -vol_l;
+ vol_r_hw = -vol_r;
+ }
+
+ if (!hw_init)
+ return;
+
+ l = vol_l_hw / 5;
+ r = vol_l_hw / 5;
+
+ alsa_controls_set_ints("Left Playback Volume", 1, &l);
+ alsa_controls_set_ints("Right Playback Volume", 1, &r);
+
+ /* Dial back PCM mixer to avoid compression */
+ pcm_set_mixer_volume(global_settings.volume_limit / 2, global_settings.volume_limit / 2);
+}
+
+void audiohw_set_volume(int vol_l, int vol_r)
+{
+ if (hwver >= 2) {
+ audiohw_set_volume_v2(vol_l, vol_r);
+ } else {
+ audiohw_set_volume_v1(vol_l, vol_r);
+ }
+}
+
void audiohw_set_lineout_volume(int vol_l, int vol_r)
{
long l,r;
@@ -196,7 +254,16 @@ void audiohw_set_lineout_volume(int vol_l, int vol_r)
r = vol_r_hw;
}
- int sw_volume_l = l <= min_pcm ? min_pcm : MIN(l, max_pcm);
- int sw_volume_r = r <= min_pcm ? min_pcm : MIN(r, max_pcm);
- pcm_set_mixer_volume(sw_volume_l / 20, sw_volume_r / 20);
+ if (hwver >= 2) {
+ if (hw_init) {
+ l /= 5;
+ r /= 5;
+ alsa_controls_set_ints("Left Playback Volume", 1, &l);
+ alsa_controls_set_ints("Right Playback Volume", 1, &r);
+ }
+ } else {
+ int sw_volume_l = l <= min_pcm ? min_pcm : MIN(l, max_pcm);
+ int sw_volume_r = r <= min_pcm ? min_pcm : MIN(r, max_pcm);
+ pcm_set_mixer_volume(sw_volume_l / 20, sw_volume_r / 20);
+ }
}
diff --git a/firmware/target/hosted/agptek/debug-agptek.c b/firmware/target/hosted/agptek/debug-agptek.c
index a9b829f7ec..de4bc946bc 100644
--- a/firmware/target/hosted/agptek/debug-agptek.c
+++ b/firmware/target/hosted/agptek/debug-agptek.c
@@ -37,6 +37,8 @@
static int line = 0;
+extern int hwver;
+
bool dbg_hw_info(void)
{
int btn = 0;
@@ -61,6 +63,10 @@ bool dbg_hw_info(void)
lcd_putsf(0, line++, "Boot ver: %s", verstr);
}
+#ifdef EROS_Q
+ lcd_putsf(0, line++, "hwver: %d", hwver);
+#endif
+
lcd_putsf(0, line++, "pcm srate: %d", pcm_alsa_get_rate());
lcd_putsf(0, line++, "pcm xruns: %d", pcm_alsa_get_xruns());
#ifdef HAVE_HEADPHONE_DETECTION
diff --git a/firmware/target/hosted/aigo/power-erosq.c b/firmware/target/hosted/aigo/power-erosq.c
index 664ee144af..7c4515f616 100644
--- a/firmware/target/hosted/aigo/power-erosq.c
+++ b/firmware/target/hosted/aigo/power-erosq.c
@@ -45,16 +45,16 @@ const char * const sysfs_bat_status[2] = {
"/sys/class/power_supply/axp_battery/status",
};
-static int hwver = 0;
+int hwver = 1; /* Exported */
unsigned int erosq_power_get_battery_voltage(void)
{
int battery_voltage;
- int x = sysfs_get_int(sysfs_bat_voltage[hwver], &battery_voltage);
+ int x = sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage);
- if (!x) {
- hwver ^= 1;
- sysfs_get_int(sysfs_bat_voltage[hwver], &battery_voltage);
+ if (!x && hwver != 4) {
+ hwver = 4;
+ sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage);
}
return battery_voltage/1000;
@@ -63,11 +63,11 @@ unsigned int erosq_power_get_battery_voltage(void)
unsigned int erosq_power_get_battery_capacity(void)
{
int battery_capacity;
- int x = sysfs_get_int(sysfs_bat_capacity[hwver], &battery_capacity);
+ int x = sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity);
- if (!x) {
- hwver ^= 1;
- sysfs_get_int(sysfs_bat_capacity[hwver], &battery_capacity);
+ if (!x && hwver != 4) {
+ hwver = 4;
+ sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity);
}
return battery_capacity;
@@ -81,11 +81,11 @@ bool charging_state(void)
{
if ((current_tick - last_tick) > HZ/2 ) {
char buf[12] = {0};
- int x = sysfs_get_string(sysfs_bat_status[hwver], buf, sizeof(buf));
+ int x = sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf));
- if (!x) {
- hwver ^= 1;
- sysfs_get_string(sysfs_bat_status[hwver], buf, sizeof(buf));
+ if (!x && hwver != 4) {
+ hwver = 4;
+ sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf));
}
last_tick = current_tick;
diff --git a/firmware/target/hosted/alsa-controls.h b/firmware/target/hosted/alsa-controls.h
index af3e584cd9..b868ef52fb 100644
--- a/firmware/target/hosted/alsa-controls.h
+++ b/firmware/target/hosted/alsa-controls.h
@@ -36,6 +36,8 @@ void alsa_controls_close(void);
/* check wether a control exists */
bool alsa_has_control(const char *name);
+/* find a control element ID by name, return -1 of not found or index into array */
+int alsa_controls_find(const char *name);
/* find a control element enum index by name, return -1 if not found */
int alsa_controls_find_enum(const char *name, const char *enum_name);
/* set a control, potentially supports several values */