PERFORCE change 67668 for review
Julian Elischer
julian at FreeBSD.org
Sat Dec 25 01:04:24 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=67668
Change 67668 by julian at julian_ref on 2004/12/25 09:03:54
IFC at 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 at 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 at 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);
}
More information about the p4-projects
mailing list