Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Dec 2004 09:04:22 GMT
From:      Julian Elischer <julian@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 67668 for review
Message-ID:  <200412250904.iBP94MBZ019260@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=67668

Change 67668 by julian@julian_ref on 2004/12/25 09:03:54

	 IFC@67667 to get these changes

Affected files ...

.. //depot/projects/nsched/sys/dev/sound/usb/uaudio.c#3 integrate
.. //depot/projects/nsched/sys/dev/sound/usb/uaudio.h#3 integrate
.. //depot/projects/nsched/sys/dev/sound/usb/uaudio_pcm.c#5 integrate

Differences ...

==== //depot/projects/nsched/sys/dev/sound/usb/uaudio.c#3 (text+ko) ====

@@ -1,5 +1,5 @@
 /*	$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $	*/
-/*	$FreeBSD: src/sys/dev/sound/usb/uaudio.c,v 1.9 2004/12/25 06:20:49 julian Exp $ */
+/*	$FreeBSD: src/sys/dev/sound/usb/uaudio.c,v 1.12 2004/12/25 08:55:52 julian Exp $ */
 
 /*
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -143,8 +143,11 @@
 	u_int		mul;
 #if defined(__FreeBSD__) /* XXXXX */
 	unsigned	ctl;
-#else
+#define MAX_SELECTOR_INPUT_PIN 256
+	u_int8_t	slctrtype[MAX_SELECTOR_INPUT_PIN];
+#endif
 	u_int8_t	class;
+#if !defined(__FreeBSD__)
 	char		ctlname[MAX_AUDIO_DEV_LEN];
 	char		*ctlunit;
 #endif
@@ -262,13 +265,17 @@
 #define UAC_EQUAL	2
 #define UAC_RECORD	3
 #define UAC_NCLASSES	4
-#if !defined(__FreeBSD__)
 #ifdef USB_DEBUG
+#if defined(__FreeBSD__)
+#define AudioCinputs	"inputs"
+#define AudioCoutputs	"outputs"
+#define AudioCrecord	"record"
+#define AudioCequalization	"equalization"
+#endif
 Static const char *uac_names[] = {
 	AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
 };
 #endif
-#endif
 
 Static usbd_status uaudio_identify_ac
 	(struct uaudio_softc *, const usb_config_descriptor_t *);
@@ -306,9 +313,12 @@
 #ifdef USB_DEBUG
 Static const char *uaudio_get_terminal_name(int);
 #endif
-#if !defined(__FreeBSD__)
 Static int	uaudio_determine_class
 	(const struct io_terminal *, struct mixerctl *);
+#if defined(__FreeBSD__)
+Static const int uaudio_feature_name(const struct io_terminal *,
+		    struct mixerctl *);
+#else
 Static const char *uaudio_feature_name
 	(const struct io_terminal *, struct mixerctl *);
 #endif
@@ -737,7 +747,14 @@
 	size_t len;
 	struct mixerctl *nmc;
 
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+	if (mc->class < UAC_NCLASSES) {
+		DPRINTF(("%s: adding %s.%d\n",
+			 __func__, uac_names[mc->class], mc->ctl));
+	} else {
+		DPRINTF(("%s: adding %d\n", __func__, mc->ctl));
+	}
+#else
 	if (mc->class < UAC_NCLASSES) {
 		DPRINTF(("%s: adding %s.%s\n",
 			 __func__, uac_names[mc->class], mc->ctlname));
@@ -946,9 +963,7 @@
 
 	bm = d1->bmControls;
 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
-#if !defined(__FreeBSD__)
 	uaudio_determine_class(&iot[id], &mix);
-#endif
 	mix.type = MIX_SIGNED_16;
 #if !defined(__FreeBSD__)	/* XXXXX */
 	mix.ctlunit = AudioNvolume;
@@ -996,24 +1011,34 @@
 Static void
 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
 {
-#if !defined(__FreeBSD__) || defined(USB_DEBUG)
 	const struct usb_audio_selector_unit *d = iot[id].d.su;
-#endif
+	struct mixerctl mix;
 #if !defined(__FreeBSD__)
-	struct mixerctl mix;
 	int i, wp;
+#else
+	int i;
+	struct mixerctl dummy;
 #endif
 
 	DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
 		    d->bUnitId, d->bNrInPins));
-#if defined(__FreeBSD__)
-	printf("uaudio_add_selector: NOT IMPLEMENTED\n");
-#else
 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 	mix.wValue[0] = MAKE(0, 0);
 	uaudio_determine_class(&iot[id], &mix);
 	mix.nchan = 1;
 	mix.type = MIX_SELECTOR;
+#if defined(__FreeBSD__)
+	mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
+	mix.minval = 1;
+	mix.maxval = d->bNrInPins;
+	mix.mul = mix.maxval - mix.minval;
+	for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
+		mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
+	}
+	for (i = mix.minval; i <= mix.maxval; i++) {
+		mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy);
+	}
+#else
 	mix.ctlunit = "";
 	mix.minval = 1;
 	mix.maxval = d->bNrInPins;
@@ -1025,8 +1050,8 @@
 		if (wp > MAX_AUDIO_DEV_LEN - 1)
 			break;
 	}
+#endif
 	uaudio_mixer_add_ctl(sc, &mix);
-#endif
 }
 
 #ifdef USB_DEBUG
@@ -1106,7 +1131,6 @@
 }
 #endif
 
-#if !defined(__FreeBSD__)
 Static int
 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
 {
@@ -1157,6 +1181,108 @@
 	return terminal_type;
 }
 
+#if defined(__FreeBSD__)
+const int 
+uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
+{
+	int terminal_type;
+
+	terminal_type = uaudio_determine_class(iot, mix);
+	if (mix->class == UAC_RECORD && terminal_type == 0)
+		return SOUND_MIXER_IMIX;
+	DPRINTF(("%s: terminal_type=%s\n", __func__,
+		 uaudio_get_terminal_name(terminal_type)));
+	switch (terminal_type) {
+	case UAT_STREAM:
+		return SOUND_MIXER_PCM;
+
+	case UATI_MICROPHONE:
+	case UATI_DESKMICROPHONE:
+	case UATI_PERSONALMICROPHONE:
+	case UATI_OMNIMICROPHONE:
+	case UATI_MICROPHONEARRAY:
+	case UATI_PROCMICROPHONEARR:
+		return SOUND_MIXER_MIC;
+
+	case UATO_SPEAKER:
+	case UATO_DESKTOPSPEAKER:
+	case UATO_ROOMSPEAKER:
+	case UATO_COMMSPEAKER:
+		return SOUND_MIXER_SPEAKER;
+
+	case UATE_ANALOGCONN:
+	case UATE_LINECONN:
+	case UATE_LEGACYCONN:
+		return SOUND_MIXER_LINE;
+
+	case UATE_DIGITALAUIFC:
+	case UATE_SPDIF:
+	case UATE_1394DA:
+	case UATE_1394DV:
+		return SOUND_MIXER_ALTPCM;
+
+	case UATF_CDPLAYER:
+		return SOUND_MIXER_CD;
+
+	case UATF_SYNTHESIZER:
+		return SOUND_MIXER_SYNTH;
+
+	case UATF_VIDEODISCAUDIO:
+	case UATF_DVDAUDIO:
+	case UATF_TVTUNERAUDIO:
+		return SOUND_MIXER_VIDEO;
+
+/* telephony terminal types */
+	case UATT_UNDEFINED:
+	case UATT_PHONELINE:
+	case UATT_TELEPHONE:
+	case UATT_DOWNLINEPHONE:
+		return SOUND_MIXER_PHONEIN;
+/*		return SOUND_MIXER_PHONEOUT;*/
+
+	case UATF_RADIORECV:
+	case UATF_RADIOXMIT:
+		return SOUND_MIXER_RADIO;
+
+	case UAT_UNDEFINED:
+	case UAT_VENDOR:
+	case UATI_UNDEFINED:
+/* output terminal types */
+	case UATO_UNDEFINED:
+	case UATO_DISPLAYAUDIO:
+	case UATO_SUBWOOFER:
+	case UATO_HEADPHONES:
+/* bidir terminal types */
+	case UATB_UNDEFINED:
+	case UATB_HANDSET:
+	case UATB_HEADSET:
+	case UATB_SPEAKERPHONE:
+	case UATB_SPEAKERPHONEESUP:
+	case UATB_SPEAKERPHONEECANC:
+/* external terminal types */
+	case UATE_UNDEFINED:
+/* embedded function terminal types */
+	case UATF_UNDEFINED:
+	case UATF_CALIBNOISE:
+	case UATF_EQUNOISE:
+	case UATF_DAT:
+	case UATF_DCC:
+	case UATF_MINIDISK:
+	case UATF_ANALOGTAPE:
+	case UATF_PHONOGRAPH:
+	case UATF_VCRAUDIO:
+	case UATF_SATELLITE:
+	case UATF_CABLETUNER:
+	case UATF_DSS:
+	case UATF_MULTITRACK:
+	case 0xffff:
+	default:
+		DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
+		return SOUND_MIXER_VOLUME;
+	}
+	return SOUND_MIXER_VOLUME;
+}
+#else
 Static const char *
 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
 {
@@ -1270,7 +1396,9 @@
 	u_int fumask, mmask, cmask;
 	struct mixerctl mix;
 	int chan, ctl, i, unit;
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+	int mixernumber;
+#else
 	const char *mixername;
 #endif
 
@@ -1315,7 +1443,9 @@
 		}
 #undef GET
 
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+		mixernumber = uaudio_feature_name(&iot[id], &mix);
+#else
 		mixername = uaudio_feature_name(&iot[id], &mix);
 #endif
 		switch (ctl) {
@@ -1332,8 +1462,7 @@
 		case VOLUME_CONTROL:
 			mix.type = MIX_SIGNED_16;
 #if defined(__FreeBSD__)
-			/* mix.ctl = SOUND_MIXER_VOLUME; */
-			mix.ctl = SOUND_MIXER_PCM;
+			mix.ctl = mixernumber;
 #else
 			mix.ctlunit = AudioNvolume;
 			strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
@@ -1441,9 +1570,7 @@
 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 	mix.nchan = 1;
 	mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
-#if !defined(__FreeBSD__)
 	uaudio_determine_class(&iot[id], &mix);
-#endif
 	mix.type = MIX_ON_OFF;	/* XXX */
 #if !defined(__FreeBSD__)
 	mix.ctlunit = "";
@@ -1474,9 +1601,7 @@
 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 		mix.nchan = 1;
 		mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
-#if !defined(__FreeBSD__)
 		uaudio_determine_class(&iot[id], &mix);
-#endif
 		mix.type = MIX_ON_OFF;
 #if !defined(__FreeBSD__)
 		mix.ctlunit = "";
@@ -1522,9 +1647,7 @@
 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 		mix.nchan = 1;
 		mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
-#if !defined(__FreeBSD__)
 		uaudio_determine_class(&iot[id], &mix);
-#endif
 		mix.type = MIX_ON_OFF;
 #if !defined(__FreeBSD__)
 		mix.ctlunit = "";
@@ -3523,6 +3646,9 @@
 	int i, j, enc;
 	int samples_per_frame, sample_size;
 
+	if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL))
+		return (-1);
+
 	switch(ch->format & 0x0000FFFF) {
 	case AFMT_U8:
 		enc = AUDIO_ENCODING_ULINEAR_LE;
@@ -3569,7 +3695,6 @@
 	}
 
 /*	for (mode =  ......	 */
-/*But this function is used for output only */
 		for (i = 0; i < sc->sc_nalts; i++) {
 			const struct usb_audio_streaming_type1_descriptor *a1d =
 				sc->sc_alts[i].asf1desc;
@@ -3611,7 +3736,10 @@
 			}
 		}
 		/* return (EINVAL); */
-		printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate);
+		if (mode == AUMODE_PLAY) 
+			printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate);
+		else
+			printf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate);
 		return (-1);
 
 	found:
@@ -3842,6 +3970,65 @@
 }
 
 int
+uaudio_halt_in_dma(device_t dev)
+{
+	struct uaudio_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->sc_dying)
+		return (EIO);
+
+	DPRINTF(("uaudio_halt_in_dma: enter\n"));
+	if (sc->sc_recchan.pipe != NULL) {
+		uaudio_chan_close(sc, &sc->sc_recchan);
+		sc->sc_recchan.pipe = NULL;
+		uaudio_chan_free_buffers(sc, &sc->sc_recchan);
+/*		sc->sc_recchan.intr = NULL; */
+	}
+	return (0);
+}
+
+int
+uaudio_trigger_input(device_t dev)
+{
+	struct uaudio_softc *sc;
+	struct chan *ch;
+	usbd_status err;
+	int i, s;
+
+	sc = device_get_softc(dev);
+	ch = &sc->sc_recchan;
+
+	if (sc->sc_dying)
+		return (EIO);
+
+/*	uaudio_chan_set_param(ch, start, end, blksize) */
+	if (uaudio_init_params(sc, ch, AUMODE_RECORD))
+		return (EIO);
+
+	err = uaudio_chan_alloc_buffers(sc, ch);
+	if (err)
+		return (EIO);
+
+	err = uaudio_chan_open(sc, ch);
+	if (err) {
+		uaudio_chan_free_buffers(sc, ch);
+		return (EIO);
+	}
+
+/*	ch->intr = intr;
+	ch->arg = arg; */
+
+	s = splusb();
+	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
+		uaudio_chan_rtransfer(ch);
+	splx(s);
+
+	return (0);
+}
+
+int
 uaudio_trigger_output(device_t dev)
 {
 	struct uaudio_softc *sc;
@@ -3896,6 +4083,39 @@
 	return mask;
 }
 
+u_int32_t
+uaudio_query_recsrc_info(device_t dev)
+{
+	int i, rec_selector_id;
+	u_int32_t mask = 0;
+	struct uaudio_softc *sc;
+	struct mixerctl *mc;
+
+	sc = device_get_softc(dev);
+	rec_selector_id = -1;
+	for (i=0; i < sc->sc_nctls; i++) {
+		mc = &sc->sc_ctls[i];
+		if (mc->ctl == SOUND_MIXER_NRDEVICES && 
+		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
+			if (rec_selector_id == -1) {
+				rec_selector_id = i;
+			} else {
+				printf("There are many selectors.  Can't recognize which selector is a record source selector.\n");
+				return mask;
+			}
+		}
+	}
+	if (rec_selector_id == -1)
+		return mask;
+	mc = &sc->sc_ctls[rec_selector_id];
+	for (i = mc->minval; i <= mc->maxval; i++) {
+		if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES)
+			continue;
+		mask |= 1 << mc->slctrtype[i - 1];
+	}
+	return mask;
+}
+
 void
 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
 {
@@ -3918,6 +4138,39 @@
 	return;
 }
 
+u_int32_t
+uaudio_mixer_setrecsrc(device_t dev, u_int32_t src)
+{
+	int i, rec_selector_id;
+	struct uaudio_softc *sc;
+	struct mixerctl *mc;
+
+	sc = device_get_softc(dev);
+	rec_selector_id = -1;
+	for (i=0; i < sc->sc_nctls; i++) {
+		mc = &sc->sc_ctls[i];
+		if (mc->ctl == SOUND_MIXER_NRDEVICES && 
+		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
+			if (rec_selector_id == -1) {
+				rec_selector_id = i;
+			} else {
+				return src; /* Can't recognize which selector is record source selector */
+			}
+		}
+	}
+	if (rec_selector_id == -1)
+		return src;
+	mc = &sc->sc_ctls[rec_selector_id];
+	for (i = mc->minval; i <= mc->maxval; i++) {
+		if (src != (1 << mc->slctrtype[i - 1]))
+			continue;
+		uaudio_ctl_set(sc, SET_CUR, mc, 0, i);
+		return (1 << mc->slctrtype[i - 1]);
+	}
+	uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval);
+	return (1 << mc->slctrtype[mc->minval - 1]);
+}
+
 Static int
 audio_attach_mi(device_t dev)
 {

==== //depot/projects/nsched/sys/dev/sound/usb/uaudio.h#3 (text+ko) ====

@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/sound/usb/uaudio.h,v 1.2 2004/12/25 06:20:49 julian Exp $ */
+/* $FreeBSD: src/sys/dev/sound/usb/uaudio.h,v 1.4 2004/12/25 08:55:52 julian Exp $ */
 
 /*
  * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.org>
@@ -25,7 +25,9 @@
  * SUCH DAMAGE.
  */
 
+#if 0
 #define NO_RECORDING /* XXX: some routines missing from uaudio.c */
+#endif
 
 /* Defined in uaudio.c, used in uaudio_pcm,c */
 
@@ -44,5 +46,7 @@
 int	uaudio_chan_getptr(device_t dev, int);
 void	uaudio_mixer_set(device_t dev, unsigned type, unsigned left,
 		unsigned right);
+u_int32_t uaudio_mixer_setrecsrc(device_t dev, u_int32_t src);
 u_int32_t uaudio_query_mix_info(device_t dev);
+u_int32_t uaudio_query_recsrc_info(device_t dev);
 void	uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt);

==== //depot/projects/nsched/sys/dev/sound/usb/uaudio_pcm.c#5 (text+ko) ====

@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/sound/usb/uaudio_pcm.c,v 1.6 2004/12/25 06:20:49 julian Exp $ */
+/* $FreeBSD: src/sys/dev/sound/usb/uaudio_pcm.c,v 1.8 2004/12/25 08:55:52 julian Exp $ */
 
 /*
  * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.org>
@@ -73,6 +73,7 @@
 	ch->parent = sc;
 	ch->channel = c;
 	ch->buffer = b;
+	ch->dir = dir;
 
 	pa_dev = device_get_parent(sc->sc_dev);
      	/* Create ua_playfmt[] & ua_recfmt[] */
@@ -235,6 +236,9 @@
 	mask = uaudio_query_mix_info(pa_dev);
 	mix_setdevs(m,	mask);
 
+	mask = uaudio_query_recsrc_info(pa_dev);
+	mix_setrecdevs(m, mask);
+
 	return 0;
 }
 
@@ -253,7 +257,11 @@
 static int
 ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src)
 {
-	return src;
+	device_t pa_dev;
+	struct ua_info *ua = mix_getdevinfo(m);
+
+	pa_dev = device_get_parent(ua->sc_dev);
+	return uaudio_mixer_setrecsrc(pa_dev, src);
 }
 
 static kobj_method_t ua_mixer_methods[] = {
@@ -320,7 +328,11 @@
 
 	snprintf(status, SND_STATUSLEN, "at addr ?");
 
+#ifndef NO_RECORDING
+	if (pcm_register(dev, ua, 1, 1)) {
+#else
 	if (pcm_register(dev, ua, 1, 0)) {
+#endif
 		return(ENXIO);
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200412250904.iBP94MBZ019260>