Date: Tue, 14 Mar 2017 15:19:15 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r315248 - in stable/11: share/man/man4 sys/dev/sound/usb sys/dev/usb sys/dev/usb/quirk Message-ID: <201703141519.v2EFJFrH099661@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Tue Mar 14 15:19:14 2017 New Revision: 315248 URL: https://svnweb.freebsd.org/changeset/base/315248 Log: MFC r312338: Add USB audio support for S/PDIF output with C-Media CM6206 devices. Submitted by: Julien Nadeau <vedge@hypertriton.com> PR: 216131 Modified: stable/11/share/man/man4/usb_quirk.4 stable/11/sys/dev/sound/usb/uaudio.c stable/11/sys/dev/usb/quirk/usb_quirk.c stable/11/sys/dev/usb/quirk/usb_quirk.h stable/11/sys/dev/usb/usbdevs Directory Properties: stable/11/ (props changed) Modified: stable/11/share/man/man4/usb_quirk.4 ============================================================================== --- stable/11/share/man/man4/usb_quirk.4 Tue Mar 14 15:15:37 2017 (r315247) +++ stable/11/share/man/man4/usb_quirk.4 Tue Mar 14 15:19:14 2017 (r315248) @@ -16,7 +16,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 4, 2016 +.Dd January 17, 2017 .Dt USB_QUIRK 4 .Os .Sh NAME @@ -52,6 +52,10 @@ input is async despite claim of adaptive do not adjust for fractional samples .It UQ_AU_NO_XU audio device has broken extension unit +.It UQ_AU_VENDOR_CLASS +audio device uses vendor class to identify itself +.It UQ_AU_SET_SPDIF_CM6206 +audio device needs special programming to enable S/PDIF audio output .It UQ_BAD_ADC bad audio spec version number .It UQ_BAD_AUDIO Modified: stable/11/sys/dev/sound/usb/uaudio.c ============================================================================== --- stable/11/sys/dev/sound/usb/uaudio.c Tue Mar 14 15:15:37 2017 (r315247) +++ stable/11/sys/dev/sound/usb/uaudio.c Tue Mar 14 15:19:14 2017 (r315248) @@ -337,6 +337,11 @@ struct uaudio_hid { uint8_t mute_id; }; +#define UAUDIO_SPDIF_OUT 0x01 /* Enable S/PDIF output */ +#define UAUDIO_SPDIF_OUT_48K 0x02 /* Out sample rate = 48K */ +#define UAUDIO_SPDIF_OUT_96K 0x04 /* Out sample rate = 96K */ +#define UAUDIO_SPDIF_IN_MIX 0x10 /* Input mix enable */ + struct uaudio_softc { struct sbuf sc_sndstat; struct sndcard_func sc_sndcard_func; @@ -354,6 +359,7 @@ struct uaudio_softc { struct usb_xfer *sc_mixer_xfer[1]; struct uaudio_mixer_node *sc_mixer_root; struct uaudio_mixer_node *sc_mixer_curr; + int (*sc_set_spdif_fn) (struct uaudio_softc *, int); uint32_t sc_mix_info; uint32_t sc_recsrc_info; @@ -885,6 +891,46 @@ uaudio_probe(device_t dev) return (ENXIO); } +/* + * Set Cmedia CM6206 S/PDIF settings + * Source: CM6206 Datasheet v2.3. + */ +static int +uaudio_set_spdif_cm6206(struct uaudio_softc *sc, int flags) +{ + uint8_t cmd[2][4] = { + {0x20, 0x20, 0x00, 0}, + {0x20, 0x30, 0x02, 1} + }; + int i; + + if (flags & UAUDIO_SPDIF_OUT) + cmd[1][1] = 0x00; + else + cmd[1][1] = 0x02; + + if (flags & UAUDIO_SPDIF_OUT_96K) + cmd[0][1] = 0x60; /* 96K: 3'b110 */ + + if (flags & UAUDIO_SPDIF_IN_MIX) + cmd[1][1] = 0x03; /* SPDIFMIX */ + + for (i = 0; i < 2; i++) { + if (usbd_req_set_report(sc->sc_udev, NULL, + cmd[i], sizeof(cmd[0]), + sc->sc_mixer_iface_index, UHID_OUTPUT_REPORT, 0) != 0) { + return (ENXIO); + } + } + return (0); +} + +static int +uaudio_set_spdif_dummy(struct uaudio_softc *sc, int flags) +{ + return (0); +} + static int uaudio_attach(device_t dev) { @@ -919,6 +965,12 @@ uaudio_attach(device_t dev) if (usb_test_quirk(uaa, UQ_AU_VENDOR_CLASS)) sc->sc_uq_au_vendor_class = 1; + /* set S/PDIF function */ + if (usb_test_quirk(uaa, UQ_AU_SET_SPDIF_CM6206)) + sc->sc_set_spdif_fn = uaudio_set_spdif_cm6206; + else + sc->sc_set_spdif_fn = uaudio_set_spdif_dummy; + umidi_init(dev); device_set_usb_desc(dev); @@ -1055,6 +1107,11 @@ uaudio_attach(device_t dev) /* reload all mixer settings */ uaudio_mixer_reload_all(sc); + /* enable S/PDIF output, if any */ + if (sc->sc_set_spdif_fn(sc, + UAUDIO_SPDIF_OUT | UAUDIO_SPDIF_OUT_48K) != 0) { + device_printf(dev, "Failed to enable S/PDIF at 48K\n"); + } return (0); /* success */ detach: @@ -1139,6 +1196,9 @@ uaudio_detach_sub(device_t dev) struct uaudio_softc *sc = device_get_softc(device_get_parent(dev)); int error = 0; + /* disable S/PDIF output, if any */ + (void) sc->sc_set_spdif_fn(sc, 0); + repeat: if (sc->sc_pcm_registered) { error = pcm_unregister(dev); Modified: stable/11/sys/dev/usb/quirk/usb_quirk.c ============================================================================== --- stable/11/sys/dev/usb/quirk/usb_quirk.c Tue Mar 14 15:15:37 2017 (r315247) +++ stable/11/sys/dev/usb/quirk/usb_quirk.c Tue Mar 14 15:19:14 2017 (r315248) @@ -519,6 +519,7 @@ static struct usb_quirk_entry usb_quirks /* Non-standard USB AUDIO devices */ USB_QUIRK(MAUDIO, FASTTRACKULTRA, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), USB_QUIRK(MAUDIO, FASTTRACKULTRA8R, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), + USB_QUIRK(CMEDIA, CM6206, 0x0000, 0xffff, UQ_AU_SET_SPDIF_CM6206), /* * Quirks for manufacturers which USB devices does not respond @@ -605,6 +606,7 @@ static const char *usb_quirk_str[USB_QUI [UQ_AU_VENDOR_CLASS] = "UQ_AU_VENDOR_CLASS", [UQ_SINGLE_CMD_MIDI] = "UQ_SINGLE_CMD_MIDI", [UQ_MSC_DYMO_EJECT] = "UQ_MSC_DYMO_EJECT", + [UQ_AU_SET_SPDIF_CM6206] = "UQ_AU_SET_SPDIF_CM6206", }; /*------------------------------------------------------------------------* Modified: stable/11/sys/dev/usb/quirk/usb_quirk.h ============================================================================== --- stable/11/sys/dev/usb/quirk/usb_quirk.h Tue Mar 14 15:15:37 2017 (r315247) +++ stable/11/sys/dev/usb/quirk/usb_quirk.h Tue Mar 14 15:19:14 2017 (r315248) @@ -109,6 +109,7 @@ enum { UQ_AU_VENDOR_CLASS, /* audio device uses vendor and not audio class */ UQ_SINGLE_CMD_MIDI, /* at most one command per USB packet */ UQ_MSC_DYMO_EJECT, /* ejects Dymo MSC device */ + UQ_AU_SET_SPDIF_CM6206, /* enable S/PDIF audio output */ USB_QUIRK_MAX }; Modified: stable/11/sys/dev/usb/usbdevs ============================================================================== --- stable/11/sys/dev/usb/usbdevs Tue Mar 14 15:15:37 2017 (r315247) +++ stable/11/sys/dev/usb/usbdevs Tue Mar 14 15:19:14 2017 (r315248) @@ -1439,6 +1439,9 @@ product CLIPSAL 5000CT2 0x0304 5000CT2 product CLIPSAL C5000CT2 0x0305 C5000CT2 C-Bus Touch Screen product CLIPSAL L51xx 0x0401 L51xx C-Bus Dimmer +/* C-Media products */ +product CMEDIA CM6206 0x0102 CM106 compatible sound device + /* CMOTECH products */ product CMOTECH CNU510 0x5141 CDMA Technologies USB modem product CMOTECH CNU550 0x5543 CDMA 2000 1xRTT/1xEVDO USB modem
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703141519.v2EFJFrH099661>