hibyr1: add USB DAC scaffolding

Introduce the generic, target-agnostic pieces for a gadget-driven USB
Audio Class DAC, gated by the HAVE_HOST_USB_AUDIO target flag so they stay
inert unless a target opts in.

Rather than adding a new USB mode, reuse the existing usb_audio setting
(never / always / while charge-only / while mass-storage) with its
LANG_USB_DAC string, usb_set_audio() callback and the
PCM_MIXER_CHAN_USBAUDIO mixer channel. HAVE_HOST_USB_AUDIO becomes the
umbrella capability flag for this common code; USB_ENABLE_AUDIO stays the
native usbstack class-driver contract (which needs HAVE_USBSTACK and so
cannot be used by hosted ports whose kernel owns the USB controller).

usb_set_audio() is declared here and implemented by the target (natively
by the usbstack driver, or in the hosted port for gadget targets, as with
usb_audio_get_active()), and applied at settings load. The playback
interlock in wps.c/playback.c keeps local playback from mixing with host
audio while the DAC is active. Simulator stubs for usb_set_audio() and
usb_audio_get_active() keep sim builds linking.

Co-Authored-By: Claude Opus 4.8
Change-Id: I5b7738508c24721d91d4c32379102a1ac7c6228b
This commit is contained in:
Michael McAllister 2026-07-21 00:38:53 +01:00 • committed by Solomon Peachy
parent 8acd1c14d6
commit ea775fa501
10 changed files with 35 additions and 10 deletions

View file

@ -313,7 +313,7 @@ codec_aac_he
lto
#endif
#if defined(USB_ENABLE_AUDIO)
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
usbdac
#endif

View file

@ -696,7 +696,7 @@ static inline int action_wpsab_single(long button)
long gui_wps_show(void)
{
/* NOTE: if USBAudio ever gets its own DSP channel, this block can go away! */
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
if (usb_audio_get_active())
{
splash(HZ*2, ID2P(LANG_USB_DAC_ACTIVE));

View file

@ -368,7 +368,7 @@ MENUITEM_SETTING(lineout_onoff, &global_settings.lineout_active, NULL);
MENUITEM_SETTING(usb_hid, &global_settings.usb_hid, NULL);
MENUITEM_SETTING(usb_keypad_mode, &global_settings.usb_keypad_mode, NULL);
#endif
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
MENUITEM_SETTING(usb_audio, &global_settings.usb_audio, NULL);
#endif
#if defined(USB_ENABLE_STORAGE) && defined(HAVE_MULTIDRIVE)
@ -421,7 +421,7 @@ MAKE_MENU(usb_menu, ID2P(LANG_USB_MENU), 0, Icon_NOICON,
&usb_hid,
&usb_keypad_mode,
#endif
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
&usb_audio,
#endif
#if defined(USB_ENABLE_STORAGE) && defined(HAVE_MULTIDRIVE)
@ -480,7 +480,7 @@ MAKE_MENU(system_menu, ID2P(LANG_SYSTEM),
&sel_softlock,
#endif
#if defined(USB_ENABLE_HID) || \
defined(USB_ENABLE_AUDIO) || \
defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO) || \
(defined(USB_ENABLE_STORAGE) && defined(HAVE_MULTIDRIVE)) || \
defined(HAVE_USB_MODE)
&usb_menu,

View file

@ -66,8 +66,11 @@
#include <strings.h> /* For strncasecmp() */
#endif
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
#ifdef USB_ENABLE_AUDIO
#include "usbstack/usb_audio.h"
#endif
#include "usb.h"
#include "splash.h"
#include "lang.h"
#endif
@ -2993,7 +2996,7 @@ static void audio_start_playback(const struct audio_resume_info *resume_info,
* a splash message to the user.
* NOTE: if USBAudio ever gets its own DSP channel, this block can go away!
*/
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
if (usb_audio_get_active())
{
queue_reply(&audio_queue, 0);

View file

@ -1128,6 +1128,9 @@ void settings_apply(bool read_disk)
#if !defined(SIMULATOR) && !defined(USB_NONE) && (defined(HAVE_USB_ADB) || defined(HAVE_USB_POWER))
usb_set_mode(global_settings.usb_mode);
#endif
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
usb_set_audio(global_settings.usb_audio);
#endif
#if defined(HAVE_GENERAL_PURPOSE_LED)
led_hw_on();
#endif

View file

@ -814,7 +814,7 @@ struct user_settings
int usb_keypad_mode;
#endif
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
int usb_audio;
#endif

View file

@ -2310,7 +2310,7 @@ const struct settings_list settings[] = {
), /* CHOICE_SETTING( usb_keypad_mode ) */
#endif
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
CHOICE_SETTING(0, usb_audio, LANG_USB_DAC, 0, "usb-dac", "never,always,while_charge_only,while_mass_storage", usb_set_audio, 4,
ID2P(LANG_NEVER), ID2P(LANG_ALWAYS), ID2P(LANG_WHILE_USB_CHARGE_ONLY), ID2P(LANG_WHILE_MASS_STORAGE_USB_ONLY)),
#endif

View file

@ -71,7 +71,7 @@
enum pcm_mixer_channel
{
PCM_MIXER_CHAN_PLAYBACK = 0,
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
PCM_MIXER_CHAN_USBAUDIO,
#endif
PCM_MIXER_CHAN_VOICE,

View file

@ -272,8 +272,15 @@ void usb_firewire_connect_event(void);
void usb_set_hid(bool enable);
#endif
#ifdef USB_ENABLE_AUDIO
#if defined(USB_ENABLE_AUDIO) || defined(HAVE_HOST_USB_AUDIO)
/* Select when the USB Audio (DAC) function is active. Values follow the
* usb_audio setting: 0 never, 1 always, 2 while charge-only, 3 while
* mass-storage. Native targets use the usbstack driver; hosted targets
* (HiBy) drive their configfs gadget. */
void usb_set_audio(int value);
/* true while host-PCM (USB-DAC) playback is active */
bool usb_audio_get_active(void);
#endif
#if defined(USB_ENABLE_STORAGE) && defined(HAVE_MULTIDRIVE)

View file

@ -202,6 +202,18 @@ bool usb_charging_enable(bool on)
}
#endif
#if defined(HAVE_HOST_USB_AUDIO)
void usb_set_audio(int value)
{
(void)value;
}
bool usb_audio_get_active(void)
{
return false;
}
#endif
#ifdef HAVE_REMOTE_LCD_TICKING
void lcd_remote_emireduce(bool state)
{