⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 ep9315平台下USB驱动的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	        g += srate - sratehi;	return(g);}static int find_format(struct audioformat *afp, unsigned int nr, 			  unsigned int fmt, unsigned int srate){	unsigned int i, g, gb = ~0;	int j = -1; /* default to failure */	/* find "best" format (according to format_goodness) */	for (i = 0; i < nr; i++) {		g = format_goodness(&afp[i], fmt, srate);		if (g >= gb) continue;		j = i;		gb = g;	}       	return j;}static int set_format_in(struct usb_audiodev *as){	struct usb_device *dev = as->state->usbdev;	struct usb_config_descriptor *config = dev->actconfig;	struct usb_interface_descriptor *alts;	struct usb_interface *iface;	struct usbin *u = &as->usbin;	struct dmabuf *d = &u->dma;	struct audioformat *fmt;	unsigned int ep;	unsigned char data[3];	int fmtnr, ret;	if (u->interface < 0 || u->interface >= config->bNumInterfaces)		return 0;	iface = &config->interface[u->interface];	fmtnr = find_format(as->fmtin, as->numfmtin, d->format, d->srate);	if (fmtnr < 0) {		printk(KERN_ERR "usbaudio: set_format_in(): failed to find desired format/speed combination.\n");		return -1;	}	fmt = as->fmtin + fmtnr;	alts = &iface->altsetting[fmt->altsetting];	u->format = fmt->format;	u->datapipe = usb_rcvisocpipe(dev, alts->endpoint[0].bEndpointAddress & 0xf);	u->syncpipe = u->syncinterval = 0;	if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x08) {		if (alts->bNumEndpoints < 2 ||		    alts->endpoint[1].bmAttributes != 0x01 ||		    alts->endpoint[1].bSynchAddress != 0 ||		    alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress & 0x7f)) {			printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n",			       dev->devnum, u->interface, fmt->altsetting);			return -1;		}		u->syncpipe = usb_sndisocpipe(dev, alts->endpoint[1].bEndpointAddress & 0xf);		u->syncinterval = alts->endpoint[1].bRefresh;	}	if (d->srate < fmt->sratelo)		d->srate = fmt->sratelo;	if (d->srate > fmt->sratehi)		d->srate = fmt->sratehi;	dprintk((KERN_DEBUG "usbaudio: set_format_in: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));	if (usb_set_interface(dev, alts->bInterfaceNumber, fmt->altsetting) < 0) {		printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",		       dev->devnum, u->interface, fmt->altsetting);		return -1;	}	if (fmt->sratelo == fmt->sratehi)		return 0;	ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN);	/* if endpoint has pitch control, enable it */	if (fmt->attributes & 0x02) {		data[0] = 1;		if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 					   PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {			printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n",			       ret, dev->devnum, u->interface, ep, d->srate);			return -1;		}	}	/* if endpoint has sampling rate control, set it */	if (fmt->attributes & 0x01) {		data[0] = d->srate;		data[1] = d->srate >> 8;		data[2] = d->srate >> 16;		if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {			printk(KERN_ERR "usbaudio: failure (error %d) to set input sampling frequency device %d interface %u endpoint 0x%x to %u\n",			       ret, dev->devnum, u->interface, ep, d->srate);			return -1;		}		if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {			printk(KERN_ERR "usbaudio: failure (error %d) to get input sampling frequency device %d interface %u endpoint 0x%x\n",			       ret, dev->devnum, u->interface, ep);			return -1;		}		dprintk((KERN_DEBUG "usbaudio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n",		        dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)));		d->srate = data[0] | (data[1] << 8) | (data[2] << 16);	}	dprintk((KERN_DEBUG "usbaudio: set_format_in: USB format 0x%x, DMA format 0x%x srate %u\n", u->format, d->format, d->srate));	return 0;}static int set_format_out(struct usb_audiodev *as){	struct usb_device *dev = as->state->usbdev;	struct usb_config_descriptor *config = dev->actconfig;	struct usb_interface_descriptor *alts;	struct usb_interface *iface;		struct usbout *u = &as->usbout;	struct dmabuf *d = &u->dma;	struct audioformat *fmt;	unsigned int ep;	unsigned char data[3];	int fmtnr, ret;	if (u->interface < 0 || u->interface >= config->bNumInterfaces)		return 0;	iface = &config->interface[u->interface];	fmtnr = find_format(as->fmtout, as->numfmtout, d->format, d->srate);	if (fmtnr < 0) {		printk(KERN_ERR "usbaudio: set_format_out(): failed to find desired format/speed combination.\n");		return -1;	}	fmt = as->fmtout + fmtnr;	u->format = fmt->format;	alts = &iface->altsetting[fmt->altsetting];	u->datapipe = usb_sndisocpipe(dev, alts->endpoint[0].bEndpointAddress & 0xf);	u->syncpipe = u->syncinterval = 0;	if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x04) {#if 0		printk(KERN_DEBUG "bNumEndpoints 0x%02x endpoint[1].bmAttributes 0x%02x\n"		       KERN_DEBUG "endpoint[1].bSynchAddress 0x%02x endpoint[1].bEndpointAddress 0x%02x\n"		       KERN_DEBUG "endpoint[0].bSynchAddress 0x%02x\n", alts->bNumEndpoints,		       alts->endpoint[1].bmAttributes, alts->endpoint[1].bSynchAddress,		       alts->endpoint[1].bEndpointAddress, alts->endpoint[0].bSynchAddress);#endif		if (alts->bNumEndpoints < 2 ||		    alts->endpoint[1].bmAttributes != 0x01 ||		    alts->endpoint[1].bSynchAddress != 0 ||		    alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress | 0x80)) {			printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n",			       dev->devnum, u->interface, fmt->altsetting);			return -1;		}		u->syncpipe = usb_rcvisocpipe(dev, alts->endpoint[1].bEndpointAddress & 0xf);		u->syncinterval = alts->endpoint[1].bRefresh;	}	if (d->srate < fmt->sratelo)		d->srate = fmt->sratelo;	if (d->srate > fmt->sratehi)		d->srate = fmt->sratehi;	dprintk((KERN_DEBUG "usbaudio: set_format_out: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));	if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) {		printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",		       dev->devnum, u->interface, fmt->altsetting);		return -1;	}	if (fmt->sratelo == fmt->sratehi)		return 0;	ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN);	/* if endpoint has pitch control, enable it */	if (fmt->attributes & 0x02) {		data[0] = 1;		if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 					   PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {			printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n",			       ret, dev->devnum, u->interface, ep, d->srate);			return -1;		}	}	/* if endpoint has sampling rate control, set it */	if (fmt->attributes & 0x01) {		data[0] = d->srate;		data[1] = d->srate >> 8;		data[2] = d->srate >> 16;		if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {			printk(KERN_ERR "usbaudio: failure (error %d) to set output sampling frequency device %d interface %u endpoint 0x%x to %u\n",			       ret, dev->devnum, u->interface, ep, d->srate);			return -1;		}		if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {			printk(KERN_ERR "usbaudio: failure (error %d) to get output sampling frequency device %d interface %u endpoint 0x%x\n",			       ret, dev->devnum, u->interface, ep);			return -1;		}		dprintk((KERN_DEBUG "usbaudio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n",		        dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)));		d->srate = data[0] | (data[1] << 8) | (data[2] << 16);	}	dprintk((KERN_DEBUG "usbaudio: set_format_out: USB format 0x%x, DMA format 0x%x srate %u\n", u->format, d->format, d->srate));	return 0;}static int set_format(struct usb_audiodev *s, unsigned int fmode, unsigned int fmt, unsigned int srate){	int ret1 = 0, ret2 = 0;	if (!(fmode & (FMODE_READ|FMODE_WRITE)))		return -EINVAL;	if (fmode & FMODE_READ) {		usbin_stop(s);		s->usbin.dma.ready = 0;		if (fmt == AFMT_QUERY)			fmt = s->usbin.dma.format;		else			s->usbin.dma.format = fmt;		if (!srate)			srate = s->usbin.dma.srate;		else			s->usbin.dma.srate = srate;	}	if (fmode & FMODE_WRITE) {		usbout_stop(s);		s->usbout.dma.ready = 0;		if (fmt == AFMT_QUERY)			fmt = s->usbout.dma.format;		else			s->usbout.dma.format = fmt;		if (!srate)			srate = s->usbout.dma.srate;		else			s->usbout.dma.srate = srate;	}	if (fmode & FMODE_READ)		ret1 = set_format_in(s);	if (fmode & FMODE_WRITE)		ret2 = set_format_out(s);	return ret1 ? ret1 : ret2;}/* --------------------------------------------------------------------- */static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value){	struct usb_device *dev = ms->state->usbdev;	unsigned char data[2];	struct mixerchannel *ch;	int v1, v2, v3;	if (mixch >= ms->numch)		return -1;	ch = &ms->ch[mixch];	v3 = ch->maxval - ch->minval;	v1 = value & 0xff;	v2 = (value >> 8) & 0xff;	if (v1 > 100)		v1 = 100;	if (v2 > 100)		v2 = 100;	if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))		v2 = v1;	ch->value = v1 | (v2 << 8);	v1 = (v1 * v3) / 100 + ch->minval;	v2 = (v2 * v3) / 100 + ch->minval;	switch (ch->selector) {	case 0:  /* mixer unit request */		data[0] = v1;		data[1] = v1 >> 8;		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,				    (ch->chnum << 8) | 1, ms->iface | (ch->unitid << 8), data, 2, HZ) < 0)			goto err;		if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))			return 0;		data[0] = v2;		data[1] = v2 >> 8;		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,				    ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)),				    ms->iface | (ch->unitid << 8), data, 2, HZ) < 0)			goto err;		return 0;		/* various feature unit controls */	case VOLUME_CONTROL:		data[0] = v1;		data[1] = v1 >> 8;		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,				    (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 2, HZ) < 0)			goto err;		if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))			return 0;		data[0] = v2;		data[1] = v2 >> 8;		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,				    (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 2, HZ) < 0)			goto err;		return 0;                	case BASS_CONTROL:	case MID_CONTROL:	case TREBLE_CONTROL:		data[0] = v1 >> 8;		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,				    (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 1, HZ) < 0)			goto err;		if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))			return 0;		data[0] = v2 >> 8;		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,				    (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 1, HZ) < 0)			goto err;		return 0;	default:		return -1;	}	return 0; err:	printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n", 		dev->devnum, ms->iface, ch->unitid, ch->chnum, ch->selector);	return -1;}static int get_rec_src(struct usb_mixerdev *ms){	struct usb_device *dev = ms->state->usbdev;	unsigned int mask = 0, retmask = 0;	unsigned int i, j;	unsigned char buf;	int err = 0;	for (i = 0; i < ms->numch; i++) {		if (!ms->ch[i].slctunitid || (mask & (1 << i)))			continue;		if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,				    0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, HZ) < 0) {			err = -EIO;			printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n", 			       dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff);			continue;		}		for (j = i; j < ms->numch; j++) {			if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)				continue;			mask |= 1 << j;			if (buf == (ms->ch[j].slctunitid >> 8))				retmask |= 1 << ms->ch[j].osschannel;		}	}	if (err)		return -EIO;	return retmask;}static int set_rec_src(struct usb_mixerdev *ms, int srcmask){	struct usb_device *dev = ms->state->usbdev;	unsigned int mask = 0, smask, bmask;	unsigned int i, j;	unsigned char buf;	int err = 0;	for (i = 0; i < ms->numch; i++) {		if (!ms->ch[i].slctunitid || (mask & (1 << i)))			continue;		if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,				    0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, HZ) < 0) {			err = -EIO;			printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n", 			       dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff);			continue;		}		/* first generate smask */		smask = bmask = 0;		for (j = i; j < ms->numch; j++) {			if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)				continue;			smask |= 1 << ms->ch[j].osschannel;			if (buf == (ms->ch[j].slctunitid >> 8))				bmask |= 1 << ms->ch[j].osschannel;			mask |= 1 << j;		}		/* check for multiple set sources */		j = hweight32(srcmask & smask);		if (j == 0)			continue;		if (j > 1)			srcmask &= ~bmask;		for (j = i; j < ms->numch; j++) {			if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)				continue;			if (!(srcmask & (1 << ms->ch[j].osschannel)))				continue;			buf = ms->ch[j].slctunitid >> 8;			if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,				    0, ms->iface | (ms->ch[j].slctunitid << 8), &buf, 1, HZ) < 0) {				err = -EIO;				printk(KERN_ERR "usbaudio: selector write request device %u if %u unit %u failed\n", 				       dev->devnum, ms->iface, ms->ch[j].slctunitid & 0xff);				continue;			}		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -