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

📄 dummy_audio.c

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 C
📖 第 1 页 / 共 3 页
字号:
	.bNumConfigurations =	2,};struct usb_cs_as_general_descriptor {	__u8  bLength;	__u8  bDescriptorType;	__u8  bDescriptorSubType;	__u8  bTerminalLink;	__u8  bDelay;	__u16  wFormatTag;} __attribute__ ((packed));struct usb_cs_as_format_descriptor {	__u8  bLength;	__u8  bDescriptorType;	__u8  bDescriptorSubType;	__u8  bFormatType;	__u8  bNrChannels;	__u8  bSubframeSize;	__u8  bBitResolution;	__u8  bSamfreqType;	__u8  tLowerSamFreq[3];	__u8  tUpperSamFreq[3];} __attribute__ ((packed));static const struct usb_interface_descriptorz_audio_control_if_desc = {	.bLength =		sizeof z_audio_control_if_desc,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber = 0,	.bAlternateSetting = 0,	.bNumEndpoints = 0,	.bInterfaceClass = USB_CLASS_AUDIO,	.bInterfaceSubClass = 0x1,	.bInterfaceProtocol = 0,	.iInterface = 0,};static const struct usb_interface_descriptorz_audio_if_desc = {	.bLength =		sizeof z_audio_if_desc,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber = 1,	.bAlternateSetting = 0,	.bNumEndpoints = 0,	.bInterfaceClass = USB_CLASS_AUDIO,	.bInterfaceSubClass = 0x2,	.bInterfaceProtocol = 0,	.iInterface = 0,};static const struct usb_interface_descriptorz_audio_if_desc2 = {	.bLength =		sizeof z_audio_if_desc,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber = 1,	.bAlternateSetting = 1,	.bNumEndpoints = 1,	.bInterfaceClass = USB_CLASS_AUDIO,	.bInterfaceSubClass = 0x2,	.bInterfaceProtocol = 0,	.iInterface = 0,};static const struct usb_cs_as_general_descriptorz_audio_cs_as_if_desc = {	.bLength = 7,	.bDescriptorType = 0x24,		.bDescriptorSubType = 0x01,	.bTerminalLink = 0x01,	.bDelay = 0x0,	.wFormatTag = __constant_cpu_to_le16 (0x0001)};static const struct usb_cs_as_format_descriptor z_audio_cs_as_format_desc = {	.bLength = 0xe,	.bDescriptorType = 0x24,		.bDescriptorSubType = 2,	.bFormatType = 1,	.bNrChannels = 1,	.bSubframeSize = 1,	.bBitResolution = 8,	.bSamfreqType = 0,	.tLowerSamFreq = {0x7e, 0x13, 0x00},	.tUpperSamFreq = {0xe2, 0xd6, 0x00},};static const struct usb_endpoint_descriptor z_iso_ep = {	.bLength = 0x09,	.bDescriptorType = 0x05,	.bEndpointAddress = 0x04,	.bmAttributes = 0x09,	.wMaxPacketSize = 0x0038,	.bInterval = 0x01,	.bRefresh = 0x00,	.bSynchAddress = 0x00,	};static char z_iso_ep2[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};// 9 bytesstatic char z_ac_interface_header_desc[] = { 0x09, 0x24, 0x01, 0x00, 0x01, 0x2b, 0x00, 0x01, 0x01 };// 12 bytesstatic char z_0[] = {0x0c, 0x24, 0x02, 0x01, 0x01, 0x01, 0x00, 0x02, 		     0x03, 0x00, 0x00, 0x00};// 13 bytesstatic char z_1[] = {0x0d, 0x24, 0x06, 0x02, 0x01, 0x02, 0x15, 0x00, 		     0x02, 0x00, 0x02, 0x00, 0x00};// 9 bytesstatic char z_2[] = {0x09, 0x24, 0x03, 0x03, 0x01, 0x03, 0x00, 0x02, 		     0x00};static char za_0[] = {0x09, 0x04, 0x01, 0x02, 0x01, 0x01, 0x02, 0x00, 		      0x00};static char za_1[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};static char za_2[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x01, 0x08, 0x00, 		      0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};static char za_3[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00,		      0x00};static char za_4[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};static char za_5[] = {0x09, 0x04, 0x01, 0x03, 0x01, 0x01, 0x02, 0x00,		      0x00};static char za_6[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};static char za_7[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x00,		      0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};static char za_8[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00,		      0x00};static char za_9[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};static char za_10[] = {0x09, 0x04, 0x01, 0x04, 0x01, 0x01, 0x02, 0x00,		       0x00};static char za_11[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};static char za_12[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x00,		       0x73, 0x13, 0x00, 0xe2, 0xd6, 0x00};static char za_13[] = {0x09, 0x05, 0x04, 0x09, 0xe0, 0x00, 0x01, 0x00,		       0x00};static char za_14[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};static char za_15[] = {0x09, 0x04, 0x01, 0x05, 0x01, 0x01, 0x02, 0x00, 		       0x00};static char za_16[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};static char za_17[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x03, 0x14, 0x00, 		       0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};static char za_18[] = {0x09, 0x05, 0x04, 0x09, 0xa8, 0x00, 0x01, 0x00,		       0x00};static char za_19[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};static char za_20[] = {0x09, 0x04, 0x01, 0x06, 0x01, 0x01, 0x02, 0x00,		       0x00};static char za_21[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};static char za_22[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x03, 0x14, 0x00, 		       0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};static char za_23[] = {0x09, 0x05, 0x04, 0x09, 0x50, 0x01, 0x01, 0x00,		       0x00};static char za_24[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};static const struct usb_descriptor_header *z_function [] = {	(struct usb_descriptor_header *) &z_audio_control_if_desc,	(struct usb_descriptor_header *) &z_ac_interface_header_desc,	(struct usb_descriptor_header *) &z_0,	(struct usb_descriptor_header *) &z_1,	(struct usb_descriptor_header *) &z_2,	(struct usb_descriptor_header *) &z_audio_if_desc,	(struct usb_descriptor_header *) &z_audio_if_desc2,	(struct usb_descriptor_header *) &z_audio_cs_as_if_desc,	(struct usb_descriptor_header *) &z_audio_cs_as_format_desc,	(struct usb_descriptor_header *) &z_iso_ep,	(struct usb_descriptor_header *) &z_iso_ep2,	(struct usb_descriptor_header *) &za_0,	(struct usb_descriptor_header *) &za_1,	(struct usb_descriptor_header *) &za_2,	(struct usb_descriptor_header *) &za_3,	(struct usb_descriptor_header *) &za_4,	(struct usb_descriptor_header *) &za_5,	(struct usb_descriptor_header *) &za_6,	(struct usb_descriptor_header *) &za_7,	(struct usb_descriptor_header *) &za_8,	(struct usb_descriptor_header *) &za_9,	(struct usb_descriptor_header *) &za_10,	(struct usb_descriptor_header *) &za_11,	(struct usb_descriptor_header *) &za_12,	(struct usb_descriptor_header *) &za_13,	(struct usb_descriptor_header *) &za_14,	(struct usb_descriptor_header *) &za_15,	(struct usb_descriptor_header *) &za_16,	(struct usb_descriptor_header *) &za_17,	(struct usb_descriptor_header *) &za_18,	(struct usb_descriptor_header *) &za_19,	(struct usb_descriptor_header *) &za_20,	(struct usb_descriptor_header *) &za_21,	(struct usb_descriptor_header *) &za_22,	(struct usb_descriptor_header *) &za_23,	(struct usb_descriptor_header *) &za_24,	NULL,};/* maxpacket and other transfer characteristics vary by speed. */#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))#else/* if there's no high speed support, maxpacket doesn't change. */#define ep_desc(g,hs,fs) fs#endif	/* !CONFIG_USB_GADGET_DUALSPEED */static char				manufacturer [40];//static char				serial [40];static char				serial [] = "Ser 00 em";/* static strings, in UTF-8 */static struct usb_string		strings [] = {	{ STRING_MANUFACTURER, manufacturer, },	{ STRING_PRODUCT, longname, },	{ STRING_SERIAL, serial, },	{ STRING_LOOPBACK, loopback, },	{ STRING_SOURCE_SINK, source_sink, },	{  }			/* end of list */};static struct usb_gadget_strings	stringtab = {	.language	= 0x0409,	/* en-us */	.strings	= strings,};/* * config descriptors are also handcrafted.  these must agree with code * that sets configurations, and with code managing interfaces and their * altsettings.  other complexity may come from: * *  - high speed support, including "other speed config" rules *  - multiple configurations *  - interfaces with alternate settings *  - embedded class or vendor-specific descriptors * * this handles high speed, and has a second config that could as easily * have been an alternate interface setting (on most hardware). * * NOTE:  to demonstrate (and test) more USB capabilities, this driver * should include an altsetting to test interrupt transfers, including * high bandwidth modes at high speed.  (Maybe work like Intel's test * device?) */static intconfig_buf (struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index){	int len;	const struct usb_descriptor_header **function;		function = z_function;	len = usb_gadget_config_buf (&z_config, buf, USB_BUFSIZ, function);	if (len < 0)		return len;	((struct usb_config_descriptor *) buf)->bDescriptorType = type;	return len;}/*-------------------------------------------------------------------------*/static struct usb_request *alloc_ep_req (struct usb_ep *ep, unsigned length){	struct usb_request	*req;	req = usb_ep_alloc_request (ep, GFP_ATOMIC);	if (req) {		req->length = length;		req->buf = usb_ep_alloc_buffer (ep, length,				&req->dma, GFP_ATOMIC);		if (!req->buf) {			usb_ep_free_request (ep, req);			req = NULL;		}	}	return req;}static void free_ep_req (struct usb_ep *ep, struct usb_request *req){	if (req->buf)		usb_ep_free_buffer (ep, req->buf, req->dma, req->length);	usb_ep_free_request (ep, req);}/*-------------------------------------------------------------------------*//* optionally require specific source/sink data patterns  */static intcheck_read_data (	struct zero_dev		*dev,	struct usb_ep		*ep,	struct usb_request	*req){	unsigned	i;	u8		*buf = req->buf;	for (i = 0; i < req->actual; i++, buf++) {		switch (pattern) {		/* all-zeroes has no synchronization issues */		case 0:			if (*buf == 0)				continue;			break;		/* mod63 stays in sync with short-terminated transfers,		 * or otherwise when host and gadget agree on how large		 * each usb transfer request should be.  resync is done		 * with set_interface or set_config.		 */		case 1:			if (*buf == (u8)(i % 63))				continue;			break;		}		ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf);		usb_ep_set_halt (ep);		return -EINVAL;	}	return 0;}/*-------------------------------------------------------------------------*/static void zero_reset_config (struct zero_dev *dev){	if (dev->config == 0)		return;	DBG (dev, "reset config\n");	/* just disable endpoints, forcing completion of pending i/o.	 * all our completion handlers free their requests in this case.	 */	if (dev->in_ep) {		usb_ep_disable (dev->in_ep);		dev->in_ep = NULL;	}	if (dev->out_ep) {		usb_ep_disable (dev->out_ep);		dev->out_ep = NULL;	}	dev->config = 0;	del_timer (&dev->resume);}#define _write(f, buf, sz) (f->f_op->write(f, buf, sz, &f->f_pos))static void zero_isoc_complete (struct usb_ep *ep, struct usb_request *req){	struct zero_dev	*dev = ep->driver_data;	int		status = req->status;	int i, j;	switch (status) {	case 0: 			/* normal completion? */		//printk ("\nzero ---------------> isoc normal completion %d bytes\n", req->actual);		for (i=0, j=rbuf_start; i<req->actual; i++) {			//printk ("%02x ", ((__u8*)req->buf)[i]);			rbuf[j] = ((__u8*)req->buf)[i];			j++;			if (j >= RBUF_LEN) j=0;		}		rbuf_start = j;		//printk ("\n\n");		if (rbuf_len < RBUF_LEN) {			rbuf_len += req->actual;			if (rbuf_len > RBUF_LEN) {				rbuf_len = RBUF_LEN;			}		}		break;	/* this endpoint is normally active while we're configured */	case -ECONNABORTED: 		/* hardware forced ep reset */	case -ECONNRESET:		/* request dequeued */	case -ESHUTDOWN:		/* disconnect from host */		VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status,				req->actual, req->length);		if (ep == dev->out_ep)			check_read_data (dev, ep, req);		free_ep_req (ep, req);		return;	case -EOVERFLOW:		/* buffer overrun on read means that					 * we didn't provide a big enough					 * buffer.					 */	default:#if 1		DBG (dev, "%s complete --> %d, %d/%d\n", ep->name,				status, req->actual, req->length);#endif	case -EREMOTEIO:		/* short read */		break;	}	status = usb_ep_queue (ep, req, GFP_ATOMIC);	if (status) {		ERROR (dev, "kill %s:  resubmit %d bytes --> %d\n",				ep->name, req->length, status);		usb_ep_set_halt (ep);		/* FIXME recover later ... somehow */	}}static struct usb_request *zero_start_isoc_ep (struct usb_ep *ep, int gfp_flags){	struct usb_request	*req;	int			status;	req = alloc_ep_req (ep, 512);	if (!req)		return NULL;	req->complete = zero_isoc_complete;	status = usb_ep_queue (ep, req, gfp_flags);	if (status) {		struct zero_dev	*dev = ep->driver_data;		ERROR (dev, "start %s --> %d\n", ep->name, status);		free_ep_req (ep, req);		req = NULL;	}	return req;}/* change our operational config.  this code must agree with the code * that returns config descriptors, and altsetting code. * * it's also responsible for power management interactions. some * configurations might not work with our current power sources. * * note that some device controller hardware will constrain what this * code can do, perhaps by disallowing more than one configuration or * by limiting configuration choices (like the pxa2xx). */static intzero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags){	int			result = 0;	struct usb_gadget	*gadget = dev->gadget;	const struct usb_endpoint_descriptor	*d;	struct usb_ep		*ep;	if (number == dev->config)		return 0;	zero_reset_config (dev);	gadget_for_each_ep (ep, gadget) {		if (strcmp (ep->name, "ep4") == 0) {			d = (struct usb_endpoint_descripter *)&za_23; // isoc ep desc for audio i/f alt setting 6			result = usb_ep_enable (ep, d);			if (result == 0) {				ep->driver_data = dev;				dev->in_ep = ep;				if (zero_start_isoc_ep (ep, gfp_flags) != 0) {					dev->in_ep = ep;					continue;				}				usb_ep_disable (ep);				result = -EIO;			}		}	}	dev->config = number;	return result;}/*-------------------------------------------------------------------------*/static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req){	if (req->status || req->actual != req->length)		DBG ((struct zero_dev *) ep->driver_data,				"setup complete --> %d, %d/%d\n",

⌨️ 快捷键说明

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