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

📄 l7205.c

📁 Linux2.4.20针对三星公司的s3c2440内核基础上的一些设备驱动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
						  udc_interrupts, status, rawstatus);				}			}		}	}			// end of loopcount loop}/* ********************************************************************************************* *//* * Start of public functions. *//** * udc_request_udc_irq - request UDC interrupt * * Return non-zero if not successful. */int udc_request_udc_irq (){	// request IRQ 	if (request_irq	    (IRQ_USBF, udc_int_hndlr, SA_INTERRUPT | SA_SAMPLE_RANDOM, "L7205 USBD Bus Interface",	     NULL) != 0) {		dbg_init (0, "Couldn't request USB irq");		return -EINVAL;	}	return 0;}/** * udc_start_in_irq - start transmit * @eendpoint: endpoint instance * * Called by bus interface driver to see if we need to start a data transmission. */void udc_start_in_irq (struct usb_endpoint_instance *endpoint){	if (!(IO_USBF_STATUS & USBF_STATUS_F2BSY)) {		ep2_start ();	}}/** * udc_stall_ep - stall endpoint * @ep: physical endpoint * * Stall the endpoint. */void udc_stall_ep (unsigned int ep){}/** * udc_reset_ep - reset endpoint * @ep: physical endpoint * reset the endpoint. * * returns : 0 if ok, -1 otherwise */void udc_reset_ep (unsigned int ep){	if (ep < UDC_MAX_ENDPOINTS) {		// reset		switch (ep) {		case 0:		case 1:		case 0x82:			/* do nothing */			break;		}	}}/** * udc_endpoint_halted - is endpoint halted * @ep: * * Return non-zero if endpoint is halted */int udc_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. */void udc_set_address (unsigned char address){}static int crc32 (char *s, int length){	/* indices */	int pByte;	int pBit;	const unsigned long poly = 0xedb88320;	unsigned long crc_value = 0xffffffff;	for (pByte = 0; pByte < length; pByte++) {		unsigned char c = *(s++);		for (pBit = 0; pBit < 8; pBit++) {			crc_value = (crc_value >> 1) ^ (((crc_value ^ c) & 0x01) ? poly : 0);			c >>= 1;		}	}	return crc_value;}/** * udc_serial_init - set a serial number if available */int __init udc_serial_init (struct usb_bus_instance *bus){#ifdef CONFIG_IRIS	iris_serial_number_struct serial;	if (!iris_get_serial_number (&serial)	    && (bus->serial_number_str = kmalloc (36, GFP_KERNEL))) {		sprintf (bus->serial_number_str, "%08x-%08x-%08x-%08x", serial.b3, serial.b2,			 serial.b1, serial.b0);		bus->serial_number = crc32 (bus->serial_number_str, 32);		return 0;	}#endif	return -EINVAL;}/** * udc_max_endpoints - max physical endpoints  * * Return number of physical endpoints. */int udc_max_endpoints (void){	return UDC_MAX_ENDPOINTS;}/** * udc_check_ep - check logical endpoint  * @lep: * * Return physical endpoint number to use for this logical endpoint or zero if not valid. */int udc_check_ep (int logical_endpoint, int packetsize){	if (packetsize > 32) {		return 0;	}	switch (logical_endpoint) {	case 1:		return 1;	case 0x82:		return 2;	case 0x83:		return 3;	default:		return 0;	}}/** * udc_set_ep - setup endpoint  * @ep: * @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){	dbg_init (1, "ep: %d", ep);	if (ep < UDC_MAX_ENDPOINTS) {		ep_endpoints[ep] = endpoint;		switch (ep) {		case 0:	// Control			break;		case 1:	// OUT			usbd_fill_rcv (device, endpoint, 10);	// XXX			endpoint->rcv_urb = first_urb_detached (&endpoint->rdy);			ep1_device = device;			ep1_endpoint = endpoint;			break;		case 2:	// IN			ep2_device = device;			ep2_endpoint = endpoint;			break;		}	}}/** * udc_disable_ep - disable endpoint * @ep: * * Disable specified endpoint  */void udc_disable_ep (unsigned int ep){	if (ep < UDC_MAX_ENDPOINTS) {		struct usb_endpoint_instance *endpoint;		switch (ep) {		case 0:	// Control			break;		case 1:	// OUT			ep1_endpoint = NULL;			break;		case 2:	// IN			ep2_device = NULL;			ep2_endpoint = NULL;			break;		}		if ((endpoint = ep_endpoints[ep])) {			ep_endpoints[ep] = NULL;			usbd_flush_ep (endpoint);		}	}}/** * udc_connected - is the USB cable connected * * Return non-zeron if cable is connected. */int udc_connected (){#ifdef CONFIG_IRIS	// Return TRUE if USB cable shows Vbus _and_ AC power present	dbg_pur (0, "Vbus: %x AC: %x", iris_read_usb_sync (), iris_read_ac_sync ());	return (iris_read_usb_sync () && iris_read_ac_sync ());#else	return 1;#endif}/** * udc_connect - enable pullup resistor * * Turn on the USB connection by enabling the pullup resistor. */void udc_connect (void){#ifdef CONFIG_IRIS	// Enable the pullup resistor.	dbg_pur (0, "Enabling IRIS USB pullup resistor");	SET_PB_OUT (USB_PULLUP_GPIO);	SET_PBDR_HI (USB_PULLUP_GPIO);	SET_PBSBSR_LO (USB_PULLUP_GPIO);#endif}/** * udc_disconnect - disable pullup resistor * * Turn off the USB connection by disabling the pullup resistor. */void udc_disconnect (void){#ifdef CONFIG_IRIS	// Disable the pullup resistor.	dbg_pur (0, "Disabling IRIS USB pullup resistor");	SET_PB_OUT (USB_PULLUP_GPIO);	SET_PBDR_LO (USB_PULLUP_GPIO);	SET_PBSBSR_LO (USB_PULLUP_GPIO);#endif}/** * udc_all_interrupts - enable interrupts * * Switch on UDC interrupts. * */void udc_all_interrupts (struct usb_device_instance *device){	dbg_init (1, " ");	// set interrupt mask}/** * udc_suspended_interrupts - enable suspended interrupts * * Switch on only UDC resume interrupt. * */void udc_suspended_interrupts (struct usb_device_instance *device){	dbg_init (1, " ");	// set interrupt mask}/** * udc_disable_interrupts - disable interrupts. * * switch off interrupts */void udc_disable_interrupts (struct usb_device_instance *device){	dbg_init (1, " ");	// reset interrupt mask}/** * udc_ep0_packetsize - return ep0 packetsize */int udc_ep0_packetsize (void){	return EP0_PACKETSIZE;}/** * udc_startup_events - allow udc code to do any additional startup */void udc_startup_events (struct usb_device_instance *device){	usbd_device_event (device, DEVICE_INIT, 0);	usbd_device_event (device, DEVICE_CREATE, 0);	usbd_device_event (device, DEVICE_HUB_CONFIGURED, 0);	// XXX moved to first SOF after HRST	//usbd_device_event(device, DEVICE_RESET, 0);            // XXX should be done from device event	// XXX usbd_device_event(device, DEVICE_ADDRESS_ASSIGNED, 0);	//device->configuration = 0; 	// XXX usbd_device_event(device, DEVICE_CONFIGURED, 0);	//device->interface = 1; 	//device->alternate = 0;	// XXX usbd_device_event(device, DEVICE_SET_INTERFACE, 0);}/** * udc_name - return name of USB Device Controller */char *udc_name (void){	return UDC_NAME;}/** * udc_request_cable_irq - request Cable interrupt * * Return non-zero if not successful. */int udc_request_cable_irq (){	return 0;}#ifdef CONFIG_USBD_PROCFS/* Proc Filesystem *************************************************************************** *//* * * l7205_proc_read - implement proc file system read. * @file * @buf * @count * @pos * * Standard proc file system read function. */static ssize_t l7205_proc_read (struct file *file, char *buf, size_t count, loff_t * pos){	unsigned long page;	int len = 0;	int index;	MOD_INC_USE_COUNT;	// get a page, max 4095 bytes of data...	if (!(page = get_free_page (GFP_KERNEL))) {		MOD_DEC_USE_COUNT;		return -ENOMEM;	}	len = 0;	index = (*pos)++;	if (index == 0) {		len += sprintf ((char *) page + len, "l7205 UDC status\n");	}	if (index == 1) {		len +=		    sprintf ((char *) page + len, "%s\n",			     udc_connected ()? "Connected" : "Not connected");	}	if (len > count) {		len = -EINVAL;	} else if (len > 0 && copy_to_user (buf, (char *) page, len)) {		len = -EFAULT;	}	free_page (page);	MOD_DEC_USE_COUNT;	return len;}/* * * l7205_proc_write - implement proc file system write. * @file * @buf * @count * @pos * * Proc file system write function, used to signal monitor actions complete. * (Hotplug script (or whatever) writes to the file to signal the completion * of the script.)  An ugly hack. */static ssize_t l7205_proc_write (struct file *file, const char *buf, size_t count, loff_t * pos){	size_t n = count;	char command[64];	char *cp = command;	int i = 0;	MOD_INC_USE_COUNT;	//printk(KERN_DEBUG "%s: count=%u\n",__FUNCTION__,count);	while ((n > 0) && (i < 64)) {		// Not too efficient, but it shouldn't matter		if (copy_from_user (cp++, buf + (count - n), 1)) {			count = -EFAULT;			break;		}		*cp = '\0';		i++;		n -= 1;		//printk(KERN_DEBUG "%s: %u/%u %02x\n",__FUNCTION__,count-n,count,c);	}	if (!strncmp (command, "plug", 4)) {		udc_connect ();	} else if (!strncmp (command, "unplug", 6)) {		udc_disconnect ();	}	MOD_DEC_USE_COUNT;	return (count);}static struct file_operations l7205_proc_operations_functions = {	read:l7205_proc_read,	write:l7205_proc_write,};#endif/** * udc_request_udc_io - request UDC io region * * Return non-zero if not successful. */int udc_request_io (){#ifdef CONFIG_USBD_PROCFS	{		struct proc_dir_entry *p;		// create proc filesystem entries		if ((p = create_proc_entry ("l7205", 0, 0)) == NULL) {			return -ENOMEM;		}		p->proc_fops = &l7205_proc_operations_functions;	}#endif	return 0;}/** * udc_release_udc_irq - release UDC irq */void udc_release_udc_irq (){	free_irq (IRQ_USBF, NULL);}/** * udc_release_cable_irq - release Cable irq */void udc_release_cable_irq (){}/** * udc_release_release_io - release UDC io region */void udc_release_io (){#ifdef CONFIG_USBD_PROCFS	remove_proc_entry ("l7205", NULL);#endif}

⌨️ 快捷键说明

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