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

📄 dwc_otg_hcd.c

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 C
📖 第 1 页 / 共 5 页
字号:
		haint.d32 = dwc_read_reg32(&hc_global_regs->haint);		//fprintf(stderr, "HAINT: %08x\n", haint.d32);		/* Read HCINT */		hcint.d32 = dwc_read_reg32(&hc_regs->hcint);		//fprintf(stderr, "HCINT: %08x\n", hcint.d32);		/* Read HCCHAR */		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);		//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);		/* Clear HCINT */		dwc_write_reg32(&hc_regs->hcint, hcint.d32);		/* Clear HAINT */		dwc_write_reg32(&hc_global_regs->haint, haint.d32);		/* Clear GINTSTS */		dwc_write_reg32(&global_regs->gintsts, gintsts.d32);		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);		//if (hcchar.b.chen) {		//      fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);		//}	}	/* Set HCTSIZ */	hctsiz.d32 = 0;	hctsiz.b.xfersize = 8;	hctsiz.b.pktcnt = 1;	hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;	dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);	/* Set HCCHAR */	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);	hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;	hcchar.b.epdir = 1;	hcchar.b.epnum = 0;	hcchar.b.mps = 8;	hcchar.b.chen = 1;	dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);	gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	//fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);	/* Wait for receive status queue interrupt */	do {		gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	} while (gintsts.b.rxstsqlvl == 0);	//fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);	/* Read RXSTS */	grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);	//fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);	/* Clear RXSTSQLVL in GINTSTS */	gintsts.d32 = 0;	gintsts.b.rxstsqlvl = 1;	dwc_write_reg32(&global_regs->gintsts, gintsts.d32);	switch (grxsts.b.pktsts) {	case DWC_GRXSTS_PKTSTS_IN:		/* Read the data into the host buffer */		if (grxsts.b.bcnt > 0) {			int i;			int word_count = (grxsts.b.bcnt + 3) / 4;			data_fifo = (uint32_t *) ((char *) global_regs + 0x1000);			for (i = 0; i < word_count; i++) {				(void) dwc_read_reg32(data_fifo++);			}		}		//fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);		break;	default:		//fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");		break;	}	gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	//fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);	/* Wait for receive status queue interrupt */	do {		gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	} while (gintsts.b.rxstsqlvl == 0);	//fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);	/* Read RXSTS */	grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);	//fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);	/* Clear RXSTSQLVL in GINTSTS */	gintsts.d32 = 0;	gintsts.b.rxstsqlvl = 1;	dwc_write_reg32(&global_regs->gintsts, gintsts.d32);	switch (grxsts.b.pktsts) {	case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:		break;	default:		//fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");		break;	}	gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	//fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);	/* Wait for host channel interrupt */	do {		gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	} while (gintsts.b.hcintr == 0);	//fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);	/* Read HAINT */	haint.d32 = dwc_read_reg32(&hc_global_regs->haint);	//fprintf(stderr, "HAINT: %08x\n", haint.d32);	/* Read HCINT */	hcint.d32 = dwc_read_reg32(&hc_regs->hcint);	//fprintf(stderr, "HCINT: %08x\n", hcint.d32);	/* Read HCCHAR */	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);	//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);	/* Clear HCINT */	dwc_write_reg32(&hc_regs->hcint, hcint.d32);	/* Clear HAINT */	dwc_write_reg32(&hc_global_regs->haint, haint.d32);	/* Clear GINTSTS */	dwc_write_reg32(&global_regs->gintsts, gintsts.d32);	/* Read GINTSTS */	gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);//      usleep(100000);//      mdelay(100);	mdelay(1);	/*	 * Send handshake packet	 */	/* Read HAINT */	haint.d32 = dwc_read_reg32(&hc_global_regs->haint);	//fprintf(stderr, "HAINT: %08x\n", haint.d32);	/* Read HCINT */	hcint.d32 = dwc_read_reg32(&hc_regs->hcint);	//fprintf(stderr, "HCINT: %08x\n", hcint.d32);	/* Read HCCHAR */	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);	//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);	/* Clear HCINT */	dwc_write_reg32(&hc_regs->hcint, hcint.d32);	/* Clear HAINT */	dwc_write_reg32(&hc_global_regs->haint, haint.d32);	/* Clear GINTSTS */	dwc_write_reg32(&global_regs->gintsts, gintsts.d32);	/* Read GINTSTS */	gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);	/* Make sure channel is disabled */	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);	if (hcchar.b.chen) {		//fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);		hcchar.b.chdis = 1;		hcchar.b.chen = 1;		dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);		//sleep(1);		mdelay(1000);		/* Read GINTSTS */		gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);		//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);		/* Read HAINT */		haint.d32 = dwc_read_reg32(&hc_global_regs->haint);		//fprintf(stderr, "HAINT: %08x\n", haint.d32);		/* Read HCINT */		hcint.d32 = dwc_read_reg32(&hc_regs->hcint);		//fprintf(stderr, "HCINT: %08x\n", hcint.d32);		/* Read HCCHAR */		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);		//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);		/* Clear HCINT */		dwc_write_reg32(&hc_regs->hcint, hcint.d32);		/* Clear HAINT */		dwc_write_reg32(&hc_global_regs->haint, haint.d32);		/* Clear GINTSTS */		dwc_write_reg32(&global_regs->gintsts, gintsts.d32);		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);		//if (hcchar.b.chen) {		//      fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);		//}	}	/* Set HCTSIZ */	hctsiz.d32 = 0;	hctsiz.b.xfersize = 0;	hctsiz.b.pktcnt = 1;	hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;	dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);	/* Set HCCHAR */	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);	hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;	hcchar.b.epdir = 0;	hcchar.b.epnum = 0;	hcchar.b.mps = 8;	hcchar.b.chen = 1;	dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);	gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	//fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);	/* Wait for host channel interrupt */	do {		gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	} while (gintsts.b.hcintr == 0);	//fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);	/* Disable HCINTs */	dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);	/* Disable HAINTs */	dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);	/* Read HAINT */	haint.d32 = dwc_read_reg32(&hc_global_regs->haint);	//fprintf(stderr, "HAINT: %08x\n", haint.d32);	/* Read HCINT */	hcint.d32 = dwc_read_reg32(&hc_regs->hcint);	//fprintf(stderr, "HCINT: %08x\n", hcint.d32);	/* Read HCCHAR */	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);	//fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);	/* Clear HCINT */	dwc_write_reg32(&hc_regs->hcint, hcint.d32);	/* Clear HAINT */	dwc_write_reg32(&hc_global_regs->haint, haint.d32);	/* Clear GINTSTS */	dwc_write_reg32(&global_regs->gintsts, gintsts.d32);	/* Read GINTSTS */	gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);	//fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);}#endif				/* DWC_HS_ELECT_TST *//** Handles hub class-specific requests.*/int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, u16 _typeReq, u16 _wValue,				u16 _wIndex, char *_buf, u16 _wLength){	int retval = 0;	dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);	dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd(_hcd)->core_if;	struct usb_hub_descriptor *desc;	hprt0_data_t hprt0 = {.d32 = 0 };	uint32_t port_status;	switch (_typeReq) {	case ClearHubFeature:		DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "			    "ClearHubFeature 0x%x\n", _wValue);		switch (_wValue) {		case C_HUB_LOCAL_POWER:		case C_HUB_OVER_CURRENT:			/* Nothing required here */			break;		default:			retval = -EINVAL;			DWC_ERROR("DWC OTG HCD - "				  "ClearHubFeature request %xh unknown\n", _wValue);		}		break;	case ClearPortFeature:		if (!_wIndex || _wIndex > 1)			goto error;		switch (_wValue) {		case USB_PORT_FEAT_ENABLE:			DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_ENABLE\n");			hprt0.d32 = dwc_otg_read_hprt0(core_if);			hprt0.b.prtena = 1;			dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);			break;		case USB_PORT_FEAT_SUSPEND:			printk("DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");			hprt0.d32 = dwc_otg_read_hprt0(core_if);			hprt0.b.prtres = 1;			dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);			/* Clear Resume bit */			mdelay(100);			hprt0.b.prtres = 0;			dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);			break;		case USB_PORT_FEAT_POWER:			DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_POWER\n");			hprt0.d32 = dwc_otg_read_hprt0(core_if);			hprt0.b.prtpwr = 0;			dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);			break;		case USB_PORT_FEAT_INDICATOR:			DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");			/* Port inidicator not supported */			break;		case USB_PORT_FEAT_C_CONNECTION:			/* Clears drivers internal connect status change			 * flag */			DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");			dwc_otg_hcd->flags.b.port_connect_status_change = 0;			break;		case USB_PORT_FEAT_C_RESET:			/* Clears the driver's internal Port Reset Change			 * flag */			DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_C_RESET\n");			dwc_otg_hcd->flags.b.port_reset_change = 0;			break;		case USB_PORT_FEAT_C_ENABLE:			/* Clears the driver's internal Port			 * Enable/Disable Change flag */			DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");			dwc_otg_hcd->flags.b.port_enable_change = 0;			break;		case USB_PORT_FEAT_C_SUSPEND:			/* Clears the driver's internal Port Suspend			 * Change flag, which is set when resume signaling on			 * the host port is complete */			DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");			dwc_otg_hcd->flags.b.port_suspend_change = 0;			break;		case USB_PORT_FEAT_C_OVER_CURRENT:			DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "				    "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");			dwc_otg_hcd->flags.b.port_over_current_change = 0;			break;		default:			retval = -EINVAL;			DWC_ERROR("DWC OTG HCD - "				  "ClearPortFeature request %xh "				  "unknown or unsupported\n", _wValue);		}		break;	case GetHubDescriptor:		DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "GetHubDescriptor\n");		desc = (struct usb_hub_descriptor *) _buf;		desc->bDescLength = 9;		desc->bDescriptorType = 0x29;		desc->bNbrPorts = 1;		desc->wHubCharacteristics = 0x08;		desc->bPwrOn2PwrGood = 1;		desc->bHubContrCurrent = 0;		desc->bitmap[0] = 0;		desc->bitmap[1] = 0xff;		break;	case GetHubStatus:		DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "GetHubStatus\n");		memset(_buf, 0, 4);		break;	case GetPortStatus:		DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "GetPortStatus\n");		if (!_wIndex || _wIndex > 1)			goto error;		port_status = 0;		if (dwc_otg_hcd->flags.b.port_connect_status_change)			port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);		if (dwc_otg_hcd->flags.b.port_enable_change)			port_status |= (1 << USB_PORT_FEAT_C_ENABLE);		if (dwc_otg_hcd->flags.b.port_suspend_change)			port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);		if (dwc_otg_hcd->flags.b.port_reset_change)			port_status |= (1 << USB_PORT_FEAT_C_RESET);		if (dwc_otg_hcd->flags.b.port_over_current_change) {			DWC_ERROR("Device Not Supported\n");			port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);		}		if (!dwc_otg_hcd->flags.b.port_connect_status) {			/*			 * The port is disconnected, which means the core is			 * either in device mode or it soon will be. Just			 * return 0's for the remainder of the port status			 * since the port register can't be read if the core			 * is in device mode.			 */			*((__le32 *) _buf) = cpu_to_le32(port_status);			break;		}		hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);		DWC_DEBUGPL(DBG_HCDV, "  HPRT0: 0x%08x\n", hprt0.d32);		if (hprt0.b.prtconnsts)			port_status |= (1 << USB_PORT_FEAT_CONNECTION);		if (hprt0.b.prtena)			port_status |= (1 << USB_PORT_FEAT_ENABLE);		if (hprt0.b.prtsusp)			port_status |= (1 << USB_PORT_FEAT_SUSPEND);

⌨️ 快捷键说明

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