summaryrefslogtreecommitdiff
path: root/firmware/drivers/audio/xduoolinux_codec.c
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/audio/xduoolinux_codec.c
parent6459fa0765745e951a6731974164bbcdc9551dfe (diff)
downloadrockbox-e43726df2cd1cb8275234d60b818d417cfe730b5.tar.gz
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/audio/xduoolinux_codec.c')
-rw-r--r--firmware/drivers/audio/xduoolinux_codec.c78
1 files changed, 54 insertions, 24 deletions
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 @@
29#include "panic.h" 29#include "panic.h"
30#include "sysfs.h" 30#include "sysfs.h"
31#include "alsa-controls.h" 31#include "alsa-controls.h"
32#include "pcm-alsa.h"
32 33
33static int fd_hw; 34static int fd_hw;
34 35
36static long int vol_l_hw = 255;
37static long int vol_r_hw = 255;
38static long int last_ps = 0;
39
35static void hw_open(void) 40static void hw_open(void)
36{ 41{
37 fd_hw = open("/dev/snd/controlC0", O_RDWR); 42 fd_hw = open("/dev/snd/controlC0", O_RDWR);
@@ -44,44 +49,69 @@ static void hw_close(void)
44 close(fd_hw); 49 close(fd_hw);
45} 50}
46 51
47void audiohw_preinit(void) 52void audiohw_mute(int mute)
48{ 53{
49 alsa_controls_init(); 54 if(mute)
50 hw_open(); 55 {
56#if defined(XDUOO_X3II)
57 alsa_controls_set_bool("AK4490 Soft Mute", true);
58#endif
59#if defined(XDUOO_X20)
60 long int ps0 = (last_ps > 1) ? 1 : 2;
61 alsa_controls_set_ints("Output Port Switch", 1, &ps0);
62#endif
63 }
64 else
65 {
66#if defined(XDUOO_X3II)
67 alsa_controls_set_bool("AK4490 Soft Mute", false);
68#endif
69#if defined(XDUOO_X20)
70 alsa_controls_set_ints("Output Port Switch", 1, &last_ps);
71#endif
72 }
51} 73}
52 74
53void audiohw_postinit(void) 75void audiohw_set_output(void)
54{ 76{
55 long int ps = 2; // headset 77 long int ps = 2; // headset
78
56 int status = 0; 79 int status = 0;
57 80
58 const char * const sysfs_lo_switch = "/sys/class/switch/lineout/state"; 81 const char * const sysfs_lo_switch = "/sys/class/switch/lineout/state";
59 const char * const sysfs_hs_switch = "/sys/class/switch/headset/state"; 82 const char * const sysfs_hs_switch = "/sys/class/switch/headset/state";
60#ifdef XDUOO_X20 83#if defined(XDUOO_X20)
61 const char * const sysfs_bal_switch = "/sys/class/switch/balance/state"; 84 const char * const sysfs_bal_switch = "/sys/class/switch/balance/state";
62#endif 85#endif
63 86
64#if defined(XDUOO_X3II)
65 alsa_controls_set_bool("AK4490 Soft Mute", true);
66#endif
67
68 sysfs_get_int(sysfs_lo_switch, &status); 87 sysfs_get_int(sysfs_lo_switch, &status);
69 if (status) ps = 1; // lineout 88 if (status) ps = 1; // lineout
70 89
71 sysfs_get_int(sysfs_hs_switch, &status); 90 sysfs_get_int(sysfs_hs_switch, &status);
72 if (status) ps = 2; // headset 91 if (status) ps = 2; // headset
73 92
74#ifdef XDUOO_X20 93#if defined(XDUOO_X20)
75 sysfs_get_int(sysfs_bal_switch, &status); 94 sysfs_get_int(sysfs_bal_switch, &status);
76 if (status) ps = 3; // balance 95 if (status) ps = 3; // balance
77#endif 96#endif
78 97
79 /* Output port switch */ 98 if (last_ps != ps)
80 alsa_controls_set_ints("Output Port Switch", 1, &ps); 99 {
100 /* Output port switch */
101 last_ps = ps;
102 alsa_controls_set_ints("Output Port Switch", 1, &last_ps);
103 }
104}
81 105
82#if defined(XDUOO_X3II) 106void audiohw_preinit(void)
83 alsa_controls_set_bool("AK4490 Soft Mute", false); 107{
84#endif 108 alsa_controls_init();
109 hw_open();
110}
111
112void audiohw_postinit(void)
113{
114 audiohw_set_output();
85} 115}
86 116
87void audiohw_close(void) 117void audiohw_close(void)
@@ -97,24 +127,24 @@ void audiohw_set_frequency(int fsel)
97 127
98void audiohw_set_volume(int vol_l, int vol_r) 128void audiohw_set_volume(int vol_l, int vol_r)
99{ 129{
100 long int vol_l_hw = -vol_l/5; 130 vol_l_hw = -vol_l/5;
101 long int vol_r_hw = -vol_r/5; 131 vol_r_hw = -vol_r/5;
102 132
103 alsa_controls_set_ints("Left Playback Volume", 1, &vol_l_hw); 133 alsa_controls_set_ints("Left Playback Volume", 1, &vol_l_hw);
104 alsa_controls_set_ints("Right Playback Volume", 1, &vol_r_hw); 134 alsa_controls_set_ints("Right Playback Volume", 1, &vol_r_hw);
105} 135}
106 136
107void audiohw_set_filter_roll_off(int value) 137void audiohw_set_filter_roll_off(int value)
108{ 138{
109 /* 0 = fast (sharp); 139 /* 0 = Sharp;
110 1 = slow; 140 1 = Slow;
111 2 = fast2 141 2 = Short Sharp
112 3 = slow2 142 3 = Short Slow */
113 4 = NOS ? */
114 long int value_hw = value;
115#if defined(XDUOO_X3II) 143#if defined(XDUOO_X3II)
144 long int value_hw = value;
116 alsa_controls_set_ints("AK4490 Digital Filter", 1, &value_hw); 145 alsa_controls_set_ints("AK4490 Digital Filter", 1, &value_hw);
117#elif defined(XDUOO_X20) 146#elif defined(XDUOO_X20)
147 long int value_hw = value;
118 alsa_controls_set_ints("ES9018_K2M Digital Filter", 1, &value_hw); 148 alsa_controls_set_ints("ES9018_K2M Digital Filter", 1, &value_hw);
119#else 149#else
120 (void)value; 150 (void)value;