summaryrefslogtreecommitdiffstats
path: root/firmware/drivers
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2020-09-30 22:12:35 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-10-01 11:56:57 -0400
commite43726df2cd1cb8275234d60b818d417cfe730b5 (patch)
tree6f1fb0659dccaafd47394c7de860d4dc3e46b0a4 /firmware/drivers
parent6459fa0765745e951a6731974164bbcdc9551dfe (diff)
downloadrockbox-e43726df2cd1cb8275234d60b818d417cfe730b5.tar.gz
rockbox-e43726df2cd1cb8275234d60b818d417cfe730b5.tar.bz2
rockbox-e43726df2cd1cb8275234d60b818d417cfe730b5.zip
hosted pcm-alsa improvements
* xduoo x3ii/x20: Better line out support * less granular volume settings (too many steps before) * Better handling of swiching sample rates * Log actual sample rate in debug menu Most credit goes to Roman Stolyarov Additional integration [re]work by myself Change-Id: I63af3740678cf2ed3170f61534e1029c81826bb6
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/audio/rocker_codec.c30
-rw-r--r--firmware/drivers/audio/xduoolinux_codec.c78
2 files changed, 77 insertions, 31 deletions
diff --git a/firmware/drivers/audio/rocker_codec.c b/firmware/drivers/audio/rocker_codec.c
index 23541a4ddb..5404ff9561 100644
--- a/firmware/drivers/audio/rocker_codec.c
+++ b/firmware/drivers/audio/rocker_codec.c
@@ -29,6 +29,9 @@
static int fd_hw;
+static long int vol_l_hw = 255;
+static long int vol_r_hw = 255;
+
static void hw_open(void)
{
fd_hw = open("/dev/snd/controlC0", O_RDWR);
@@ -41,19 +44,32 @@ static void hw_close(void)
close(fd_hw);
}
-void audiohw_preinit(void)
+void audiohw_mute(int mute)
{
- long int hp = 2;
+ if(mute)
+ {
+ long int ps0 = 0;
+ alsa_controls_set_ints("Output Port Switch", 1, &ps0);
+ }
+ else
+ {
+ long int ps2 = 2;
+ alsa_controls_set_ints("Output Port Switch", 1, &ps2);
+ }
+}
+void audiohw_preinit(void)
+{
alsa_controls_init();
hw_open();
-
- /* Output port switch set to Headphones */
- alsa_controls_set_ints("Output Port Switch", 1, &hp);
}
void audiohw_postinit(void)
{
+ long int hp = 2;
+
+ /* Output port switch set to Headphones */
+ alsa_controls_set_ints("Output Port Switch", 1, &hp);
}
void audiohw_close(void)
@@ -69,8 +85,8 @@ void audiohw_set_frequency(int fsel)
void audiohw_set_volume(int vol_l, int vol_r)
{
- long int vol_l_hw = -vol_l/5;
- long int vol_r_hw = -vol_r/5;
+ vol_l_hw = -vol_l/5;
+ vol_r_hw = -vol_r/5;
alsa_controls_set_ints("Left Playback Volume", 1, &vol_l_hw);
alsa_controls_set_ints("Right Playback Volume", 1, &vol_r_hw);
diff --git a/firmware/drivers/audio/xduoolinux_codec.c b/firmware/drivers/audio/xduoolinux_codec.c
index 5db4902e5f..eedde1d667 100644
--- a/firmware/drivers/audio/xduoolinux_codec.c
+++ b/firmware/drivers/audio/xduoolinux_codec.c
@@ -29,9 +29,14 @@
#include "panic.h"
#include "sysfs.h"
#include "alsa-controls.h"
+#include "pcm-alsa.h"
static int fd_hw;
+static long int vol_l_hw = 255;
+static long int vol_r_hw = 255;
+static long int last_ps = 0;
+
static void hw_open(void)
{
fd_hw = open("/dev/snd/controlC0", O_RDWR);
@@ -44,44 +49,69 @@ static void hw_close(void)
close(fd_hw);
}
-void audiohw_preinit(void)
+void audiohw_mute(int mute)
{
- alsa_controls_init();
- hw_open();
+ if(mute)
+ {
+#if defined(XDUOO_X3II)
+ alsa_controls_set_bool("AK4490 Soft Mute", true);
+#endif
+#if defined(XDUOO_X20)
+ long int ps0 = (last_ps > 1) ? 1 : 2;
+ alsa_controls_set_ints("Output Port Switch", 1, &ps0);
+#endif
+ }
+ else
+ {
+#if defined(XDUOO_X3II)
+ alsa_controls_set_bool("AK4490 Soft Mute", false);
+#endif
+#if defined(XDUOO_X20)
+ alsa_controls_set_ints("Output Port Switch", 1, &last_ps);
+#endif
+ }
}
-void audiohw_postinit(void)
+void audiohw_set_output(void)
{
long int ps = 2; // headset
+
int status = 0;
const char * const sysfs_lo_switch = "/sys/class/switch/lineout/state";
const char * const sysfs_hs_switch = "/sys/class/switch/headset/state";
-#ifdef XDUOO_X20
+#if defined(XDUOO_X20)
const char * const sysfs_bal_switch = "/sys/class/switch/balance/state";
#endif
-#if defined(XDUOO_X3II)
- alsa_controls_set_bool("AK4490 Soft Mute", true);
-#endif
-
sysfs_get_int(sysfs_lo_switch, &status);
if (status) ps = 1; // lineout
sysfs_get_int(sysfs_hs_switch, &status);
if (status) ps = 2; // headset
-#ifdef XDUOO_X20
+#if defined(XDUOO_X20)
sysfs_get_int(sysfs_bal_switch, &status);
if (status) ps = 3; // balance
#endif
- /* Output port switch */
- alsa_controls_set_ints("Output Port Switch", 1, &ps);
+ if (last_ps != ps)
+ {
+ /* Output port switch */
+ last_ps = ps;
+ alsa_controls_set_ints("Output Port Switch", 1, &last_ps);
+ }
+}
-#if defined(XDUOO_X3II)
- alsa_controls_set_bool("AK4490 Soft Mute", false);
-#endif
+void audiohw_preinit(void)
+{
+ alsa_controls_init();
+ hw_open();
+}
+
+void audiohw_postinit(void)
+{
+ audiohw_set_output();
}
void audiohw_close(void)
@@ -97,24 +127,24 @@ void audiohw_set_frequency(int fsel)
void audiohw_set_volume(int vol_l, int vol_r)
{
- long int vol_l_hw = -vol_l/5;
- long int vol_r_hw = -vol_r/5;
-
+ vol_l_hw = -vol_l/5;
+ vol_r_hw = -vol_r/5;
+
alsa_controls_set_ints("Left Playback Volume", 1, &vol_l_hw);
alsa_controls_set_ints("Right Playback Volume", 1, &vol_r_hw);
}
void audiohw_set_filter_roll_off(int value)
{
- /* 0 = fast (sharp);
- 1 = slow;
- 2 = fast2
- 3 = slow2
- 4 = NOS ? */
- long int value_hw = value;
+ /* 0 = Sharp;
+ 1 = Slow;
+ 2 = Short Sharp
+ 3 = Short Slow */
#if defined(XDUOO_X3II)
+ long int value_hw = value;
alsa_controls_set_ints("AK4490 Digital Filter", 1, &value_hw);
#elif defined(XDUOO_X20)
+ long int value_hw = value;
alsa_controls_set_ints("ES9018_K2M Digital Filter", 1, &value_hw);
#else
(void)value;