Add USB Audio 1.0 support

Original commit credit to Amaury Pouly, Moshe Piekarski
Pushed across the finish line by Dana Conrad

To enable, see setting under General Settings --> System --> USB-DAC.
On devices with few endpoints, this may not work while HID and/or
mass storage is enabled.

Adds new dedicated mixer channel.

setting usb-dac can have values:
- never (0)
- always (1)
- while_charge_only (2)
- while_mass_storage (3)

Relevant devices are DWC2 and ARC usb controller devices. That being:
x1000 Native targets (m3k, erosqnative, q1, others...?),
sansac200, creativezenxfi2, vibe500, ipodmini2g,
ipod4g, creativezenxfi, creativezenxfi3, sansaview, ipodcolor,
creativezenxfistyle, samsungypz5, sansafuzeplus, iriverh10_5gb,
tatungtpj1022, gigabeats, faketarget, samsungyh820, gogearhdd1630, samsungyh925, ipodmini1g, ipodvideo, creativezenmozaic, sonynwze370, creativezen, gogearsa9200, gogearhdd6330, sonynwze360, sansae200, mrobe100, iriverh10, creativezenv, ipodnano1g, samsungyh920

USB Driver-wise, it should be noted that this patch requires some
slight changes:
- proper blocking on control OUT transfers, to make sure the data is
  received *before* using it, the usb_core should probably use that too
- drivers can now support interface alternate settings
- drivers can be notified of completion by a new fast handler, which
  is called directly from the driver; this is is necessary for
  isochronous transfers because going through the usb queue is way too
  slow

Designware changes:

- enable for USBOTG_DESIGNWARE
- set maxpacketsize to 1023 for ISO endpoints

Change-Id: I570871884a4e4820b4312b203b07701f06ecacc6
This commit is contained in:
Dana Conrad 2022-09-09 15:36:27 -05:00 committed by Solomon Peachy
parent af42428037
commit 9ce66e088e
20 changed files with 1867 additions and 35 deletions

View file

@ -599,11 +599,22 @@ int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length)
return prime_transfer(EP_NUM(endpoint), ptr, length, false, false);
}
int usb_drv_recv_blocking(int endpoint, void* ptr, int length)
{
return prime_transfer(EP_NUM(endpoint), ptr, length, false, true);
}
int usb_drv_port_speed(void)
{
return (REG_PORTSC1 & 0x08000000) ? 1 : 0;
}
int usb_drv_get_frame_number(void)
{
/* the lower 3 bits store the microframe (in HS mode), discard them */
return (REG_FRINDEX & USB_FRINDEX_MASKS) >> 3;
}
bool usb_drv_connected(void)
{
return (REG_PORTSC1 &
@ -970,10 +981,8 @@ static void init_control_queue_heads(void)
/* manual: 32.14.4.1 Queue Head Initialization */
static void init_queue_heads(void)
{
/* FIXME the packetsize for isochronous transfers is 1023 : 1024 but
* the current code only support one type of packet size so we restrict
* isochronous packet size for now also */
int packetsize = (usb_drv_port_speed() ? 512 : 64);
int isopacketsize = (usb_drv_port_speed() ? 1024 : 1024);
int i;
/* TODO: this should take ep_allocation into account */
@ -982,7 +991,7 @@ static void init_queue_heads(void)
/* OUT */
if(endpoints[i].type[DIR_OUT] == USB_ENDPOINT_XFER_ISOC)
/* FIXME: we can adjust the number of packets per frame, currently use one */
qh_array[i*2].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL | 1 << QH_MULT_POS;
qh_array[i*2].max_pkt_length = isopacketsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL | 1 << QH_MULT_POS;
else
qh_array[i*2].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
@ -991,7 +1000,7 @@ static void init_queue_heads(void)
/* IN */
if(endpoints[i].type[DIR_IN] == USB_ENDPOINT_XFER_ISOC)
/* FIXME: we can adjust the number of packets per frame, currently use one */
qh_array[i*2+1].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL | 1 << QH_MULT_POS;
qh_array[i*2+1].max_pkt_length = isopacketsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL | 1 << QH_MULT_POS;
else
qh_array[i*2+1].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;