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

📄 omap.c

📁 Linux2.4.20针对三星公司的s3c2440内核基础上的一些设备驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		 */#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);			UDCDBG("IN endpoint %d reset", ep_num);		}#endif	}	local_irq_restore(flags);}/** * udc_endpoint_halted - is endpoint halted * @ep: * * Return non-zero if endpoint is halted */intudc_endpoint_halted(unsigned int ep){	return 0;}/** * udc_set_address - set the USB address for this device * @address: * * Called from control endpoint function after it decodes a set address setup packet. */voidudc_set_address(unsigned char address){	UDCDBG("setting address %x", address);	usb_address = address;}#if 1/** * udc_serial_init - set a serial number if available */int __initudc_serial_init(struct usb_bus_instance *bus){	return -EINVAL;}#endif/* ************************************************************************** *//* * udc_max_endpoints - max physical endpoints  * * Return number of physical endpoints. */intudc_max_endpoints(void){	return UDC_MAX_ENDPOINTS;}/** * udc_check_ep - check logical endpoint  * * Return physical endpoint number to use for this logical endpoint or zero if not valid. */intudc_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);}/* * udc_setup_ep - setup endpoint * * Associate a physical endpoint with endpoint_instance */voidudc_setup_ep(struct usb_device_instance *device,	     unsigned int ep, struct usb_endpoint_instance *endpoint){	/* 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) {		omap_deconfigure_device();		omap_configure_device(device);	}	UDCDBG("setting up physical endpoint %d", ep);	if (endpoint && (ep < UDC_MAX_ENDPOINTS)) {		int ep_addr = PHYS_EP_TO_EP_ADDR(ep);		if (!ep) {			/* 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) {				/* Why are we pre-allocating 5 urbs?  Because 				 * most of the other existing USB controller 				 * drivers pre-allocate 5 urbs.  We must 				 * allocate enough urbs so that we never run 				 * out of urbs in our endpoint->rdy queue 				 * because the function driver hasn't had a 				 * chance to process an urb from the 				 * endpoint->rcv queue and recycle it back to 				 * the rdy queue.				 */				usbd_fill_rcv(device, endpoint, 5);				endpoint->rcv_urb =				    first_urb_detached(&endpoint->rdy);				omap_prepare_endpoint_for_rx(ep);			}		}	}}/** * udc_disable_ep - disable endpoint * @ep: * * Disable specified endpoint */voidudc_disable_ep(unsigned int ep){	int ep_addr = PHYS_EP_TO_EP_ADDR(ep);	int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;	struct usb_endpoint_instance *endpoint =	    udc_device->bus->endpoint_array + ep;	UDCDBG("disable ep %d", ep);	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);		}	} else {		if (endpoint->rcv_packetSize) {			/* we have a valid rx endpoint */			usbd_flush_rcv(endpoint);		}	}}/* ************************************************************************** *//** * udc_connected - is the USB cable connected * * Return non-zero if cable is connected. */intudc_connected(void){	return ((inw(UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);}/* Turn on the USB connection by enabling the pullup resistor */voidudc_connect(void){	UDCDBG("connect, enable Pullup");	outw(inw(UDC_SYSCON1) | UDC_Pullup_En, UDC_SYSCON1);	UDCREG(UDC_SYSCON1);#ifdef CONFIG_OMAP_H2	usbd_do_connect = 1;	up(&usbd_connect_lock);#endif}/* Turn off the USB connection by disabling the pullup resistor */voidudc_disconnect(void){	UDCDBG("disconnect, disable Pullup");	outw(inw(UDC_SYSCON1) & ~UDC_Pullup_En, UDC_SYSCON1);	UDCREG(UDC_SYSCON1);#ifdef CONFIG_OMAP_H2	down(&usbd_i2c_lock);	usbd_do_connect = 0;	if (usbd_connected) {		/*disable pull-up resistor on D+ */		i2c_write(0xC, ISP1301_I2C_OTG_CONTROL_1);		i2c_write(~0xC,			  ISP1301_I2C_OTG_CONTROL_1 |			  ISP1301_I2C_REG_CLEAR_ADDR);		usbd_connected = 0;	}	up(&usbd_i2c_lock);#endif}/* ************************************************************************** *//** * udc_enable_interrupts - enable interrupts * * Switch on UDC interrupts. * */voidudc_all_interrupts(struct usb_device_instance *device){	UDCDBG("enabling all endpoint interrupts");	outw( /* UDC_Sof_IE | */ UDC_EPn_RX_IE | UDC_EPn_TX_IE | UDC_DS_Chg_IE	     | UDC_EP0_IE, UDC_IRQ_EN);}/** * udc_suspended_interrupts - enable suspended interrupts * * Switch on only UDC resume interrupt. * */voidudc_suspended_interrupts(struct usb_device_instance *device){	UDCDBG("enabling resume interrupt (DS_Chg)");	outw(UDC_DS_Chg_IE, UDC_IRQ_EN);}/* * udc_disable_interrupts - disable interrupts * switch off interrupts */voidudc_disable_interrupts(struct usb_device_instance *device){	UDCDBG("disabling all interrupts");	outw(0, UDC_IRQ_EN);}/* ************************************************************************** *//** * udc_ep0_packetsize - return ep0 packetsize */intudc_ep0_packetsize(void){	return EP0_PACKETSIZE;}/* Switch on the UDC */voidudc_enable(struct usb_device_instance *device){	UDCDBG("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) {		if (!(ep0_urb = usbd_alloc_urb(device,					       device->function_instance_array,					       0, 512))) {			printk(KERN_ERR "udc_enable: usbd_alloc_urb failed\n");		}	} else {		printk(KERN_ERR "udc_enable: ep0_urb already allocated\n");	}	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);#ifdef CONFIG_ARCH_OMAP1610	//OTG_CTRL.18 = 1 (BSESSVLD) //1 = host attached (VBUS present)	outl((1 << 18), OTG_CTRL);#endif	omap_configure_device(device);}/* Switch off the UDC */voidudc_disable(void){	UDCDBG("disable UDC");	omap_deconfigure_device();#ifdef CONFIG_ARCH_OMAP1610	//OTG_CTRL.18 = 0 (BSESSVLD) //1 = host attached (VBUS present)	outl(0, OTG_CTRL);#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);	/* 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 */voidudc_startup_events(struct usb_device_instance *device){	/* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */	usbd_device_event(device, DEVICE_INIT, 0);	/* The DEVICE_CREATE event puts the USB device in the state 	 * STATE_ATTACHED.	 */	usbd_device_event(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.	 */}/* ************************************************************************** *//* Return name of this UDC */char *udc_name(void){	return UDC_NAME;}/* Request all UDC interrups */intudc_request_udc_irq(void){	UDCDBG("installing interrupt handlers");	/* Request general USB interrupt */	if (request_irq(UDC_IRQ, omap_udc_irq, SA_INTERRUPT |			SA_SAMPLE_RANDOM, UDC_NAME " Bus Interface", NULL)) {		printk(KERN_ERR UDC_NAME		       ": couldn't register USB interrupt handler\n");		goto request_irq_failed;	}	/* Request non-ISO endpoint-specific interrupt */	if (request_irq(UDC_NONISO_IRQ, omap_udc_noniso_irq, SA_INTERRUPT |			SA_SAMPLE_RANDOM, UDC_NAME " non-ISO endpoints",			NULL)) {		printk(KERN_ERR UDC_NAME		       ": couldn't register USB non-ISO interrupt handler\n");		goto request_noniso_irq_failed;	}	/* Request Start-of-Frame interrupt for ISO transactions */	if (request_irq(UDC_SOF_IRQ, omap_udc_sof_irq, SA_INTERRUPT |			SA_SAMPLE_RANDOM, UDC_NAME " SOF ISO", NULL)) {		printk(KERN_ERR UDC_NAME		       ": couldn't register USB SOF ISO interrupt handler\n");		goto request_sof_irq_failed;	}	return 0;      request_sof_irq_failed:	free_irq(UDC_NONISO_IRQ, NULL);      request_noniso_irq_failed:	free_irq(UDC_IRQ, NULL);      request_irq_failed:	return -EINVAL;}/* Release all UDC interrupts */voidudc_release_udc_irq(void){	UDCDBG("release all interrupts");	free_irq(UDC_IRQ, NULL);	free_irq(UDC_NONISO_IRQ, NULL);	free_irq(UDC_SOF_IRQ, NULL);}/* Request UDC IO region */intudc_request_io(void){#ifdef CONFIG_OMAP_H2	int tmp = (int) request_region(OTG_BASE, OTG_IOSIZE, "OMAP H2 USBD BI");	if (!tmp) {		printk(KERN_ERR UDC_NAME ": OTG is already in use\n");		udc_release_io();		return -ENODEV;	}	initstate_region = 1;	tmp = i2c_configure();	if (tmp < 0) {		udc_release_io();		return tmp;	}	/*init thread */	connect_thread_terminating = 0;	tmp =	    kernel_thread(&usbd_connect_thread, NULL,			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND);	if (tmp < 0) {		printk(KERN_ERR UDC_NAME ": could not start thread\n");		udc_release_io();		return tmp;	}	initstate_thread = 1;	isp1301_configure();#endif	return 0;}/* Release UDC IO region */voidudc_release_io(void){#ifdef CONFIG_OMAP_H2	//OTG_CTRL.18 = 0 (BSESSVLD) //1 = host attached (VBUS present)	outl(0, OTG_CTRL);	if (initstate_thread) {		connect_thread_terminating = 1;		up(&usbd_connect_lock);		wait_for_completion(&connect_thread_exit);	}	i2c_close();	if (initstate_region) {		release_region(OTG_BASE, OTG_IOSIZE);		initstate_region = 0;	}#endif}/* Request UDC cable interrupt */intudc_request_cable_irq(void){	/* Cable events are handled via the Ds_Chg ISR, so we don't need to 	 * install a separate handler here.	 */	return 0;}/* Release UDC cable interrupt */voidudc_release_cable_irq(void){}/* Dump all UDC registers */voidudc_regs(void){	UDCDBG("** ALL UDC registers **");	UDCREG(UDC_REV);	UDCREG(UDC_EP_NUM);	UDCREG(UDC_SYSCON1);	UDCREG(UDC_DEVSTAT);	UDCREG(UDC_SOF);	UDCREG(UDC_IRQ_EN);	UDCREG(UDC_DMA_IRQ_EN);	UDCREG(UDC_IRQ_SRC);	UDCREG(UDC_EPN_STAT);	UDCREG(UDC_DMAN_STAT);}

⌨️ 快捷键说明

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