-/* $OpenBSD: uaudio.c,v 1.74 2010/07/15 03:43:12 jakemsr Exp $ */
+/* $OpenBSD: uaudio.c,v 1.75 2010/07/19 05:08:37 jakemsr Exp $ */
/* $NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $ */
/*
#include <dev/auconv.h>
#include <dev/usb/usb.h>
+#include <dev/usb/usbdevs.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
#include <dev/usb/uaudioreg.h>
struct uaudio_softc *sc; /* our softc */
};
+#define UAUDIO_FLAG_BAD_AUDIO 0x0001 /* claims audio class, but isn't */
+#define UAUDIO_FLAG_NO_FRAC 0x0002 /* don't use fractional samples */
+#define UAUDIO_FLAG_NO_XU 0x0004 /* has broken extension unit */
+#define UAUDIO_FLAG_BAD_ADC 0x0008 /* bad audio spec version number */
+
+struct uaudio_devs {
+ struct usb_devno uv_dev;
+ int flags;
+} uaudio_devs[] = {
+ { { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70 },
+ UAUDIO_FLAG_BAD_ADC } ,
+ { { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495 },
+ UAUDIO_FLAG_BAD_AUDIO },
+ { { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502 },
+ UAUDIO_FLAG_NO_XU | UAUDIO_FLAG_BAD_ADC },
+ { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBDLX },
+ UAUDIO_FLAG_BAD_AUDIO },
+ { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRONB },
+ UAUDIO_FLAG_BAD_AUDIO },
+ { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO4K },
+ UAUDIO_FLAG_BAD_AUDIO },
+ { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMZOOM },
+ UAUDIO_FLAG_BAD_AUDIO },
+ { { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1 },
+ UAUDIO_FLAG_NO_FRAC }
+};
+#define uaudio_lookup(v, p) \
+ ((struct uaudio_devs *)usb_lookup(uaudio_devs, v, p))
+
struct uaudio_softc {
struct device sc_dev; /* base device */
usbd_device_handle sc_udev; /* USB device */
int sc_nctls; /* # of mixer controls */
struct device *sc_audiodev;
char sc_dying;
+ int sc_quirks;
};
struct terminal_list {
{
struct usb_attach_arg *uaa = aux;
usb_interface_descriptor_t *id;
+ struct uaudio_devs *quirk;
+ int flags;
if (uaa->iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa->iface);
- /* Trigger on the control interface. */
- if (id == NULL ||
- id->bInterfaceClass != UICLASS_AUDIO ||
- id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
- (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
+ if (id == NULL)
return (UMATCH_NONE);
- return (UMATCH_IFACECLASS_IFACESUBCLASS);
+ quirk = uaudio_lookup(uaa->vendor, uaa->product);
+ if (quirk)
+ flags = quirk->flags;
+
+ if (id->bInterfaceClass == UICLASS_AUDIO &&
+ id->bInterfaceSubClass == UISUBCLASS_AUDIOCONTROL &&
+ !(flags & UAUDIO_FLAG_BAD_AUDIO))
+ return (UMATCH_VENDOR_PRODUCT_CONF_IFACE);
+
+ return (UMATCH_NONE);
}
void
{
struct uaudio_softc *sc = (struct uaudio_softc *)self;
struct usb_attach_arg *uaa = aux;
+ struct uaudio_devs *quirk;
usb_interface_descriptor_t *id;
usb_config_descriptor_t *cdesc;
usbd_status err;
sc->sc_udev = uaa->device;
+ quirk = uaudio_lookup(uaa->vendor, uaa->product);
+ if (quirk)
+ sc->sc_quirks = quirk->flags;
+
cdesc = usbd_get_config_descriptor(sc->sc_udev);
if (cdesc == NULL) {
printf("%s: failed to get configuration descriptor\n",
sc->sc_playchan.altidx = -1;
sc->sc_recchan.altidx = -1;
- if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
+ if (sc->sc_quirks & UAUDIO_FLAG_NO_FRAC)
sc->sc_altflags |= UA_NOFRAC;
printf(", %d mixer controls\n", sc->sc_nctls);
DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
d->bUnitId, d->bNrInPins));
- if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
+ if (sc->sc_quirks & UAUDIO_FLAG_NO_XU)
return;
if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
if (offs + aclen > size)
return (USBD_INVAL);
- if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
+ if (!(sc->sc_quirks & UAUDIO_FLAG_BAD_ADC) &&
UGETW(acdp->bcdADC) != UAUDIO_VERSION)
return (USBD_INVAL);
-/* $OpenBSD: usb_quirks.c,v 1.57 2010/07/15 15:45:48 sthen Exp $ */
+/* $OpenBSD: usb_quirks.c,v 1.58 2010/07/19 05:08:37 jakemsr Exp $ */
/* $NetBSD: usb_quirks.c,v 1.45 2003/05/10 17:47:14 hamajima Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $ */
{ USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, 0x100, { UQ_NO_SET_PROTO}},
{ USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
0x094, { UQ_SWAP_UNICODE}},
- { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_BAD_ADC }},
- { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_AU_NO_XU }},
- { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, { UQ_BAD_ADC }},
- { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, 0x000, { UQ_BAD_AUDIO }},
- { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBDLX,
- 0x100, { UQ_BAD_AUDIO }},
- { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRONB,
- 0x000, { UQ_BAD_AUDIO }},
- { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO4K,
- 0x000, { UQ_BAD_AUDIO }},
- { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMZOOM,
- 0x000, { UQ_BAD_AUDIO }},
{ USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, { UQ_SPUR_BUT_UP }},
{ USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, 0x001, { UQ_SPUR_BUT_UP }},
{ USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, 0x102, { UQ_BUS_POWERED }},
ANY, { UQ_ASSUME_CM_OVER_DATA }},
{ USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, { UQ_POWER_CLAIM }},
- { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, { UQ_AU_NO_FRAC }},
/* XXX These should have a revision number, but I don't know what they are. */
{ USB_VENDOR_HP, USB_PRODUCT_HP_895C, ANY, { UQ_BROKEN_BIDIR }},
-/* $OpenBSD: usb_quirks.h,v 1.15 2010/04/07 20:52:56 sthen Exp $ */
+/* $OpenBSD: usb_quirks.h,v 1.16 2010/07/19 05:08:37 jakemsr Exp $ */
/* $NetBSD: usb_quirks.h,v 1.20 2001/04/15 09:38:01 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_quirks.h,v 1.9 1999/11/12 23:31:03 n_hibma Exp $ */
#define UQ_SWAP_UNICODE 0x00000002 /* some Unicode strings swapped */
#define UQ_MS_REVZ 0x00000004 /* mouse has Z-axis reversed */
#define UQ_NO_STRINGS 0x00000008 /* string descriptors are broken */
-#define UQ_BAD_ADC 0x00000010 /* bad audio spec version number */
#define UQ_BUS_POWERED 0x00000020 /* is bus-powered, despite claim */
-#define UQ_BAD_AUDIO 0x00000040 /* claims audio class, but isn't */
#define UQ_SPUR_BUT_UP 0x00000080 /* spurious mouse button up events */
-#define UQ_AU_NO_XU 0x00000100 /* audio device has broken
- extension unit */
#define UQ_POWER_CLAIM 0x00000200 /* hub lies about power status */
-#define UQ_AU_NO_FRAC 0x00000400 /* don't adjust for fractional
- samples */
#define UQ_ASSUME_CM_OVER_DATA 0x00001000 /* modem device breaks on cm
over data */
#define UQ_BROKEN_BIDIR 0x00002000 /* printer has broken bidir mode */