summaryrefslogtreecommitdiff
path: root/firmware
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 /firmware
parent1c28cb439b0f2838a8132bb951787207bd0fe0f6 (diff)
downloadrockbox-51ba8b3eee2ccfede2c766494b38b1b3404b95e4.tar.gz
rockbox-51ba8b3eee2ccfede2c766494b38b1b3404b95e4.zip
erosqhosted: Support HW volume control on rev2+ hardware
This also adds hwrev info to the debug output. Change-Id: Ia75218cacb8f756a23a77334ea6ab69ac3b20d10
Diffstat (limited to 'firmware')
-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 @@
53 BUFFER_BYTES: [4096 524288] 53 BUFFER_BYTES: [4096 524288]
54 TICK_TIME: ALL 54 TICK_TIME: ALL
55 55
56 Mixer controls: 56 Mixer controls (v1):
57 57
58 numid=1,iface=MIXER,name='Output Port Switch' 58 numid=1,iface=MIXER,name='Output Port Switch'
59 ; type=INTEGER,access=rw------,values=1,min=0,max=5,step=0 59 ; type=INTEGER,access=rw------,values=1,min=0,max=5,step=0
60 : values=4 60 : values=4
61
62 Mixer controls (v2+):
63
64 numid=3,iface=MIXER,name='ES9018_K2M Digital Filter'
65 ; type=INTEGER,access=rw------,values=1,min=0,max=4,step=0
66 : values=0
67 numid=1,iface=MIXER,name='Left Playback Volume'
68 ; type=INTEGER,access=rw------,values=1,min=0,max=255,step=0
69 : values=0
70 numid=4,iface=MIXER,name='Output Port Switch'
71 ; type=INTEGER,access=rw------,values=1,min=0,max=5,step=0
72 : values=0
73 numid=2,iface=MIXER,name='Right Playback Volume'
74 ; type=INTEGER,access=rw------,values=1,min=0,max=255,step=0
75 : values=0
76 numid=5,iface=MIXER,name='isDSD'
77 ; type=BOOLEAN,access=rw------,values=1
78 : values=off
61*/ 79*/
62 80
63static int hw_init = 0; 81static int hw_init = 0;
@@ -68,6 +86,8 @@ static long int last_ps = -1;
68 86
69static int muted = -1; 87static int muted = -1;
70 88
89extern int hwver;
90
71void audiohw_mute(int mute) 91void audiohw_mute(int mute)
72{ 92{
73 logf("mute %d", mute); 93 logf("mute %d", mute);
@@ -129,6 +149,13 @@ void audiohw_preinit(void)
129 logf("hw preinit"); 149 logf("hw preinit");
130 alsa_controls_init("default"); 150 alsa_controls_init("default");
131 hw_init = 1; 151 hw_init = 1;
152
153 /* See if we have hw2 or later */
154 if (alsa_controls_find("Left Playback Volume") == -1)
155 hwver = 1;
156 else if (hwver == 1)
157 hwver = 23;
158
132 audiohw_mute(false); /* No need to stay muted */ 159 audiohw_mute(false); /* No need to stay muted */
133} 160}
134 161
@@ -154,10 +181,8 @@ void audiohw_set_frequency(int fsel)
154const int min_pcm = -740; 181const int min_pcm = -740;
155const int max_pcm = 0; 182const int max_pcm = 0;
156 183
157void audiohw_set_volume(int vol_l, int vol_r) 184static void audiohw_set_volume_v1(int vol_l, int vol_r)
158{ 185{
159 logf("hw vol %d %d", vol_l, vol_r);
160
161 long l,r; 186 long l,r;
162 187
163 vol_l_hw = vol_l; 188 vol_l_hw = vol_l;
@@ -180,6 +205,39 @@ void audiohw_set_volume(int vol_l, int vol_r)
180 pcm_set_mixer_volume(sw_volume_l / 20, sw_volume_r / 20); 205 pcm_set_mixer_volume(sw_volume_l / 20, sw_volume_r / 20);
181} 206}
182 207
208static void audiohw_set_volume_v2(int vol_l, int vol_r)
209{
210 long l,r;
211
212 if (lineout_inserted()) {
213 vol_l_hw = vol_r_hw = global_settings.volume_limit * 10;
214 } else {
215 vol_l_hw = -vol_l;
216 vol_r_hw = -vol_r;
217 }
218
219 if (!hw_init)
220 return;
221
222 l = vol_l_hw / 5;
223 r = vol_l_hw / 5;
224
225 alsa_controls_set_ints("Left Playback Volume", 1, &l);
226 alsa_controls_set_ints("Right Playback Volume", 1, &r);
227
228 /* Dial back PCM mixer to avoid compression */
229 pcm_set_mixer_volume(global_settings.volume_limit / 2, global_settings.volume_limit / 2);
230}
231
232void audiohw_set_volume(int vol_l, int vol_r)
233{
234 if (hwver >= 2) {
235 audiohw_set_volume_v2(vol_l, vol_r);
236 } else {
237 audiohw_set_volume_v1(vol_l, vol_r);
238 }
239}
240
183void audiohw_set_lineout_volume(int vol_l, int vol_r) 241void audiohw_set_lineout_volume(int vol_l, int vol_r)
184{ 242{
185 long l,r; 243 long l,r;
@@ -196,7 +254,16 @@ void audiohw_set_lineout_volume(int vol_l, int vol_r)
196 r = vol_r_hw; 254 r = vol_r_hw;
197 } 255 }
198 256
199 int sw_volume_l = l <= min_pcm ? min_pcm : MIN(l, max_pcm); 257 if (hwver >= 2) {
200 int sw_volume_r = r <= min_pcm ? min_pcm : MIN(r, max_pcm); 258 if (hw_init) {
201 pcm_set_mixer_volume(sw_volume_l / 20, sw_volume_r / 20); 259 l /= 5;
260 r /= 5;
261 alsa_controls_set_ints("Left Playback Volume", 1, &l);
262 alsa_controls_set_ints("Right Playback Volume", 1, &r);
263 }
264 } else {
265 int sw_volume_l = l <= min_pcm ? min_pcm : MIN(l, max_pcm);
266 int sw_volume_r = r <= min_pcm ? min_pcm : MIN(r, max_pcm);
267 pcm_set_mixer_volume(sw_volume_l / 20, sw_volume_r / 20);
268 }
202} 269}
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 @@
37 37
38static int line = 0; 38static int line = 0;
39 39
40extern int hwver;
41
40bool dbg_hw_info(void) 42bool dbg_hw_info(void)
41{ 43{
42 int btn = 0; 44 int btn = 0;
@@ -61,6 +63,10 @@ bool dbg_hw_info(void)
61 lcd_putsf(0, line++, "Boot ver: %s", verstr); 63 lcd_putsf(0, line++, "Boot ver: %s", verstr);
62 } 64 }
63 65
66#ifdef EROS_Q
67 lcd_putsf(0, line++, "hwver: %d", hwver);
68#endif
69
64 lcd_putsf(0, line++, "pcm srate: %d", pcm_alsa_get_rate()); 70 lcd_putsf(0, line++, "pcm srate: %d", pcm_alsa_get_rate());
65 lcd_putsf(0, line++, "pcm xruns: %d", pcm_alsa_get_xruns()); 71 lcd_putsf(0, line++, "pcm xruns: %d", pcm_alsa_get_xruns());
66#ifdef HAVE_HEADPHONE_DETECTION 72#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] = {
45 "/sys/class/power_supply/axp_battery/status", 45 "/sys/class/power_supply/axp_battery/status",
46}; 46};
47 47
48static int hwver = 0; 48int hwver = 1; /* Exported */
49 49
50unsigned int erosq_power_get_battery_voltage(void) 50unsigned int erosq_power_get_battery_voltage(void)
51{ 51{
52 int battery_voltage; 52 int battery_voltage;
53 int x = sysfs_get_int(sysfs_bat_voltage[hwver], &battery_voltage); 53 int x = sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage);
54 54
55 if (!x) { 55 if (!x && hwver != 4) {
56 hwver ^= 1; 56 hwver = 4;
57 sysfs_get_int(sysfs_bat_voltage[hwver], &battery_voltage); 57 sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage);
58 } 58 }
59 59
60 return battery_voltage/1000; 60 return battery_voltage/1000;
@@ -63,11 +63,11 @@ unsigned int erosq_power_get_battery_voltage(void)
63unsigned int erosq_power_get_battery_capacity(void) 63unsigned int erosq_power_get_battery_capacity(void)
64{ 64{
65 int battery_capacity; 65 int battery_capacity;
66 int x = sysfs_get_int(sysfs_bat_capacity[hwver], &battery_capacity); 66 int x = sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity);
67 67
68 if (!x) { 68 if (!x && hwver != 4) {
69 hwver ^= 1; 69 hwver = 4;
70 sysfs_get_int(sysfs_bat_capacity[hwver], &battery_capacity); 70 sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity);
71 } 71 }
72 72
73 return battery_capacity; 73 return battery_capacity;
@@ -81,11 +81,11 @@ bool charging_state(void)
81{ 81{
82 if ((current_tick - last_tick) > HZ/2 ) { 82 if ((current_tick - last_tick) > HZ/2 ) {
83 char buf[12] = {0}; 83 char buf[12] = {0};
84 int x = sysfs_get_string(sysfs_bat_status[hwver], buf, sizeof(buf)); 84 int x = sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf));
85 85
86 if (!x) { 86 if (!x && hwver != 4) {
87 hwver ^= 1; 87 hwver = 4;
88 sysfs_get_string(sysfs_bat_status[hwver], buf, sizeof(buf)); 88 sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf));
89 } 89 }
90 90
91 last_tick = current_tick; 91 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);
36 36
37/* check wether a control exists */ 37/* check wether a control exists */
38bool alsa_has_control(const char *name); 38bool alsa_has_control(const char *name);
39/* find a control element ID by name, return -1 of not found or index into array */
40int alsa_controls_find(const char *name);
39/* find a control element enum index by name, return -1 if not found */ 41/* find a control element enum index by name, return -1 if not found */
40int alsa_controls_find_enum(const char *name, const char *enum_name); 42int alsa_controls_find_enum(const char *name, const char *enum_name);
41/* set a control, potentially supports several values */ 43/* set a control, potentially supports several values */