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

📄 usbdcore_omap1510.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* Determine the endpoint number for this interrupt */		epnum = (inw (UDC_EPN_STAT) & 0x0f00) >> 8;		UDCDBGA ("RX on ep %x", epnum);		/* acknowledge interrupt */		outw (UDC_EPn_RX, UDC_IRQ_SRC);		if (epnum) {			/* select the endpoint FIFO */			outw (UDC_EP_Sel | epnum, UDC_EP_NUM);			omap1510_udc_epn_rx (epnum);			/* deselect the endpoint FIFO */			outw (epnum, UDC_EP_NUM);		}		valid_irq++;	}	if (irq_src & UDC_EPn_TX) {	/* Endpoint N IN transaction */		/* Determine the endpoint number for this interrupt */		epnum = (inw (UDC_EPN_STAT) & 0x000f) | USB_DIR_IN;		UDCDBGA ("TX on ep %x", epnum);		/* acknowledge interrupt */		outw (UDC_EPn_TX, UDC_IRQ_SRC);		if (epnum) {			/* select the endpoint FIFO */			outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);			omap1510_udc_epn_tx (epnum);			/* deselect the endpoint FIFO */			outw (UDC_EP_Dir | epnum, UDC_EP_NUM);		}		valid_irq++;	}	if (!valid_irq)		serial_printf (": unknown non-ISO interrupt, IRQ_SRC %.4x\n",			       irq_src);}/*-------------------------------------------------------------------------------*//* * Start of public functions. *//* Called to start packet transmission. */void udc_endpoint_write (struct usb_endpoint_instance *endpoint){	unsigned short epnum =		endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;	UDCDBGA ("Starting transmit on ep %x", epnum);	if (endpoint->tx_urb) {		/* select the endpoint FIFO */		outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);		/* write data to FIFO */		omap1510_write_noniso_tx_fifo (endpoint);		/* enable tx FIFO to start transmission */		outw (UDC_Set_FIFO_En, UDC_CTRL);		/* deselect the endpoint FIFO */		outw (UDC_EP_Dir | epnum, UDC_EP_NUM);	}}/* Start to initialize h/w stuff */int udc_init (void){	u16 udc_rev;	uchar value;	ulong gpio;	int i;	/* Let the device settle down before we start */	for (i = 0; i < UDC_INIT_MDELAY; i++) udelay(1000);	udc_device = NULL;	UDCDBG ("starting");	/* Check peripheral reset. Must be 1 to make sure	   MPU TIPB peripheral reset is inactive */	UDCREG (ARM_RSTCT2);	/* Set and check clock control.	 * We might ought to be using the clock control API to do	 * this instead of fiddling with the clock registers directly	 * here.	 */	outw ((1 << 4) | (1 << 5), CLOCK_CTRL);	UDCREG (CLOCK_CTRL);	/* Set and check APLL */	outw (0x0008, APLL_CTRL);	UDCREG (APLL_CTRL);	/* Set and check DPLL */	outw (0x2210, DPLL_CTRL);	UDCREG (DPLL_CTRL);	/* Set and check SOFT */	outw ((1 << 4) | (1 << 3) | 1, SOFT_REQ);	/* Short delay to wait for DPLL */	udelay (1000);	/* Print banner with device revision */	udc_rev = inw (UDC_REV) & 0xff;	printf ("USB:   TI OMAP1510 USB function module rev %d.%d\n",		udc_rev >> 4, udc_rev & 0xf);#ifdef CONFIG_OMAP_SX1	i2c_read (0x32, 0x04, 1, &value, 1);	value |= 0x04;	i2c_write (0x32, 0x04, 1, &value, 1);	i2c_read (0x32, 0x03, 1, &value, 1);	value |= 0x01;	i2c_write (0x32, 0x03, 1, &value, 1);	gpio = inl(GPIO_PIN_CONTROL_REG);	gpio |=  0x0002; /* A_IRDA_OFF */	gpio |=  0x0800; /* A_SWITCH   */	gpio |=  0x8000; /* A_USB_ON   */	outl (gpio, GPIO_PIN_CONTROL_REG);	gpio = inl(GPIO_DIR_CONTROL_REG);	gpio &= ~0x0002; /* A_IRDA_OFF */	gpio &= ~0x0800; /* A_SWITCH   */	gpio &= ~0x8000; /* A_USB_ON   */	outl (gpio, GPIO_DIR_CONTROL_REG);	gpio = inl(GPIO_DATA_OUTPUT_REG);	gpio |=  0x0002; /* A_IRDA_OFF */	gpio &= ~0x0800; /* A_SWITCH   */	gpio &= ~0x8000; /* A_USB_ON   */	outl (gpio, GPIO_DATA_OUTPUT_REG);#endif	/* The VBUS_MODE bit selects whether VBUS detection is done via	 * software (1) or hardware (0).  When software detection is	 * selected, VBUS_CTRL selects whether USB is not connected (0)	 * or connected (1).	 */	outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);	outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);	UDCREGL (FUNC_MUX_CTRL_0);	/*	 * At this point, device is ready for configuration...	 */	UDCDBG ("disable USB interrupts");	outw (0, UDC_IRQ_EN);	UDCREG (UDC_IRQ_EN);	UDCDBG ("disable USB DMA");	outw (0, UDC_DMA_IRQ_EN);	UDCREG (UDC_DMA_IRQ_EN);	UDCDBG ("initialize SYSCON1");	outw (UDC_Self_Pwr | UDC_Pullup_En, UDC_SYSCON1);	UDCREG (UDC_SYSCON1);	return 0;}/* Stall endpoint */static void udc_stall_ep (unsigned int ep_addr){	/*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */	int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;	UDCDBGA ("stall ep_addr %d", ep_addr);	/* REVISIT?	 * The OMAP TRM section 14.2.4.2 says we must check that the FIFO	 * is empty before halting the endpoint.  The current implementation	 * doesn't check that the FIFO is empty.	 */	if (!ep_num) {		outw (UDC_Stall_Cmd, UDC_SYSCON2);	} else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {		if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {			/* we have a valid rx endpoint, so halt it */			outw (UDC_EP_Sel | ep_num, UDC_EP_NUM);			outw (UDC_Set_Halt, UDC_CTRL);			outw (ep_num, UDC_EP_NUM);		}	} else {		if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {			/* we have a valid tx endpoint, so halt it */			outw (UDC_EP_Sel | UDC_EP_Dir | ep_num, UDC_EP_NUM);			outw (UDC_Set_Halt, UDC_CTRL);			outw (ep_num, UDC_EP_NUM);		}	}}/* Reset endpoint */#if 0static void udc_reset_ep (unsigned int ep_addr){	/*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */	int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;	UDCDBGA ("reset ep_addr %d", ep_addr);	if (!ep_num) {		/* control endpoint 0 can't be reset */	} else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {		UDCDBGA ("UDC_EP_RX(%d) = 0x%04x", ep_num,			 inw (UDC_EP_RX (ep_num)));		if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {			/* we have a valid rx endpoint, so reset it */			outw (ep_num | UDC_EP_Sel, UDC_EP_NUM);			outw (UDC_Reset_EP, UDC_CTRL);			outw (ep_num, UDC_EP_NUM);			UDCDBGA ("OUT endpoint %d reset", ep_num);		}	} else {		UDCDBGA ("UDC_EP_TX(%d) = 0x%04x", ep_num,			 inw (UDC_EP_TX (ep_num)));		/* Resetting of tx endpoints seems to be causing the USB function		 * module to fail, which causes problems when the driver is		 * uninstalled.	 We'll skip resetting tx endpoints for now until		 * we figure out what the problem is.		 */#if 0		if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {			/* we have a valid tx endpoint, so reset it */			outw (ep_num | UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);			outw (UDC_Reset_EP, UDC_CTRL);			outw (ep_num | UDC_EP_Dir, UDC_EP_NUM);			UDCDBGA ("IN endpoint %d reset", ep_num);		}#endif	}}#endif/* ************************************************************************** *//** * udc_check_ep - check logical endpoint  * * Return physical endpoint number to use for this logical endpoint or zero if not valid. */#if 0int udc_check_ep (int logical_endpoint, int packetsize){	if ((logical_endpoint == 0x80) ||	    ((logical_endpoint & 0x8f) != logical_endpoint)) {		return 0;	}	switch (packetsize) {	case 8:	case 16:	case 32:	case 64:	case 128:	case 256:	case 512:		break;	default:		return 0;	}	return EP_ADDR_TO_PHYS_EP (logical_endpoint);}#endif/* * udc_setup_ep - setup endpoint * * Associate a physical endpoint with endpoint_instance */void udc_setup_ep (struct usb_device_instance *device,		   unsigned int ep, struct usb_endpoint_instance *endpoint){	UDCDBGA ("setting up endpoint addr %x", endpoint->endpoint_address);	/* This routine gets called by bi_modinit for endpoint 0 and from	 * bi_config for all of the other endpoints.  bi_config gets called	 * during the DEVICE_CREATE, DEVICE_CONFIGURED, and	 * DEVICE_SET_INTERFACE events.	 We need to reconfigure the OMAP packet	 * RAM after bi_config scans the selected device configuration and	 * initializes the endpoint structures, but before this routine enables	 * the OUT endpoint FIFOs.  Since bi_config calls this routine in a	 * loop for endpoints 1 through UDC_MAX_ENDPOINTS, we reconfigure our	 * packet RAM here when ep==1.	 * I really hate to do this here, but it seems like the API exported	 * by the USB bus interface controller driver to the usbd-bi module	 * isn't quite right so there is no good place to do this.	 */	if (ep == 1) {		omap1510_deconfigure_device ();		omap1510_configure_device (device);	}	if (endpoint && (ep < UDC_MAX_ENDPOINTS)) {		int ep_addr = endpoint->endpoint_address;		if (!ep_addr) {			/* nothing to do for endpoint 0 */		} else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {			/* nothing to do for IN (tx) endpoints */		} else {	/* OUT (rx) endpoint */			if (endpoint->rcv_packetSize) {				/*struct urb* urb = &(urb_out_array[ep&0xFF]); */				/*urb->endpoint = endpoint; */				/*urb->device = device; */				/*urb->buffer_length = sizeof(urb->buffer); */				/*endpoint->rcv_urb = urb; */				omap1510_prepare_endpoint_for_rx (ep_addr);			}		}	}}/** * udc_disable_ep - disable endpoint * @ep: * * Disable specified endpoint */#if 0void udc_disable_ep (unsigned int ep_addr){	/*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */	int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;	struct usb_endpoint_instance *endpoint = omap1510_find_ep (ep_addr);	/*udc_device->bus->endpoint_array + ep; */	UDCDBGA ("disable ep_addr %d", ep_addr);	if (!ep_num) {		/* nothing to do for endpoint 0 */ ;	} else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {		if (endpoint->tx_packetSize) {			/* we have a valid tx endpoint */			/*usbd_flush_tx(endpoint); */			endpoint->tx_urb = NULL;		}	} else {		if (endpoint->rcv_packetSize) {			/* we have a valid rx endpoint */			/*usbd_flush_rcv(endpoint); */			endpoint->rcv_urb = NULL;		}	}}#endif/* ************************************************************************** *//** * udc_connected - is the USB cable connected * * Return non-zero if cable is connected. */#if 0int udc_connected (void){	return ((inw (UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);}#endif/* Turn on the USB connection by enabling the pullup resistor */void udc_connect (void){	UDCDBG ("connect, enable Pullup");	outl (0x00000018, FUNC_MUX_CTRL_D);}/* Turn off the USB connection by disabling the pullup resistor */void udc_disconnect (void){	UDCDBG ("disconnect, disable Pullup");	outl (0x00000000, FUNC_MUX_CTRL_D);}/* ************************************************************************** *//* * udc_disable_interrupts - disable interrupts * switch off interrupts */#if 0void udc_disable_interrupts (struct usb_device_instance *device){	UDCDBG ("disabling all interrupts");	outw (0, UDC_IRQ_EN);}#endif/* ************************************************************************** *//** * udc_ep0_packetsize - return ep0 packetsize */#if 0int udc_ep0_packetsize (void){	return EP0_PACKETSIZE;}#endif/* Switch on the UDC */void udc_enable (struct usb_device_instance *device){	UDCDBGA ("enable device %p, status %d", device, device->status);	/* initialize driver state variables */	udc_devstat = 0;	/* Save the device structure pointer */	udc_device = device;	/* Setup ep0 urb */	if (!ep0_urb) {		ep0_urb =			usbd_alloc_urb (udc_device,					udc_device->bus->endpoint_array);	} else {		serial_printf ("udc_enable: ep0_urb already allocated %p\n",			       ep0_urb);	}	UDCDBG ("Check clock status");	UDCREG (STATUS_REQ);	/* The VBUS_MODE bit selects whether VBUS detection is done via	 * software (1) or hardware (0).  When software detection is	 * selected, VBUS_CTRL selects whether USB is not connected (0)	 * or connected (1).	 */	outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_CTRL | UDC_VBUS_MODE,	      FUNC_MUX_CTRL_0);	UDCREGL (FUNC_MUX_CTRL_0);	omap1510_configure_device (device);}/* Switch off the UDC */void udc_disable (void){	UDCDBG ("disable UDC");	omap1510_deconfigure_device ();	/* The VBUS_MODE bit selects whether VBUS detection is done via	 * software (1) or hardware (0).  When software detection is	 * selected, VBUS_CTRL selects whether USB is not connected (0)	 * or connected (1).	 */	outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);	outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);	UDCREGL (FUNC_MUX_CTRL_0);	/* Free ep0 URB */	if (ep0_urb) {		/*usbd_dealloc_urb(ep0_urb); */		ep0_urb = NULL;	}	/* Reset device pointer.	 * We ought to do this here to balance the initialization of udc_device	 * in udc_enable, but some of our other exported functions get called	 * by the bus interface driver after udc_disable, so we have to hang on	 * to the device pointer to avoid a null pointer dereference. */	/* udc_device = NULL; */}/** * udc_startup - allow udc code to do any additional startup */void udc_startup_events (struct usb_device_instance *device){	/* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */	usbd_device_event_irq (device, DEVICE_INIT, 0);	/* The DEVICE_CREATE event puts the USB device in the state	 * STATE_ATTACHED.	 */	usbd_device_event_irq (device, DEVICE_CREATE, 0);	/* Some USB controller driver implementations signal	 * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.	 * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,	 * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.	 * The OMAP USB client controller has the capability to detect when the	 * USB cable is connected to a powered USB bus via the ATT bit in the	 * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and	 * DEVICE_RESET events until later.	 */	udc_enable (device);}#endif

⌨️ 快捷键说明

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