rockbox/firmware/usbstack/usb_class_driver.h
Dana Conrad 9ce66e088e 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
2025-11-15 07:30:15 -05:00

118 lines
4.6 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 Frank Gevaerts
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _USB_CLASS_DRIVER_H_
#define _USB_CLASS_DRIVER_H_
#include "usb_ch9.h"
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
/* Common api, implemented by all class drivers */
struct usb_class_driver {
/* First some runtime data */
bool enabled;
int first_interface;
int last_interface;
/* Driver api starts here */
/* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
bool needs_exclusive_storage;
/* Let the driver request endpoints it need. Returns zero on success */
int (*request_endpoints)(struct usb_class_driver *);
/* Tells the driver what its first interface number will be. The driver
returns the number of the first available interface for the next driver
(i.e. a driver with one interface will return interface+1)
A driver must have at least one interface
Mandatory function */
int (*set_first_interface)(int interface);
/* Asks the driver to put the interface descriptor and all other
needed descriptor for this driver at dest.
Returns the number of bytes taken by these descriptors.
Mandatory function */
int (*get_config_descriptor)(unsigned char *dest, int max_packet_size);
/* Tells the driver that a usb connection has been set up and is now
ready to use.
Optional function */
void (*init_connection)(void);
/* Initialises the driver. This can be called multiple times,
and should not perform any action that can disturb other threads
(like getting the audio buffer)
Optional function */
void (*init)(void);
/* Tells the driver that the usb connection is no longer active
Optional function */
void (*disconnect)(void);
/* Tells the driver that a usb transfer has been completed. Note that "dir"
is relative to the host
Optional function */
void (*transfer_complete)(int ep, int dir, int status, int length);
/* Similar to transfer_complete but called directly instead of going through
* the usb queue. Since it might be called in an interrupt context,
* processing should be kept to a minimum. This is mainly intended for
* isochronous transfers.
* The function must return true if it handled the completion, and false
* otherwise so that it is dispatched to the normal handler
* Optional function */
bool (*fast_transfer_complete)(int ep, int dir, int status, int length);
/* Tells the driver that a control request has come in. If the driver is
able to handle it, it should ack the request, and return true. Otherwise
it should return false.
Optional function */
bool (*control_request)(struct usb_ctrlrequest* req, void* reqdata, unsigned char *dest);
#ifdef HAVE_HOTSWAP
/* Tells the driver that a hotswappable disk/card was inserted or
extracted
Optional function */
void (*notify_hotswap)(int volume, bool inserted);
#endif
/* Tells the driver to select an alternate setting for a specific interface.
* Returns 0 on success and -1 on error.
* Mandatory function if alternate interface support is needed */
int (*set_interface)(int interface, int alt_setting);
/* Asks the driver what is the current alternate setting for a specific interface.
* Returns value on success and -1 on error.
* Mandatory function if alternate interface support is needed */
int (*get_interface)(int interface);
};
#define PACK_DATA(dest, data) pack_data(dest, &(data), sizeof(data))
static inline void pack_data(uint8_t **dest, const void *data, size_t size)
{
memcpy(*dest, data, size);
*dest += size;
}
#endif