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

📄 sa1100.c

📁 Linux2.4.20针对三星公司的s3c2440内核基础上的一些设备驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/** * udc_endpoint_halted - is endpoint halted * @ep: * * Return non-zero if endpoint is halted */int udc_endpoint_halted (unsigned int ep){	switch (ep) {	case 0:		return (udc (UDCCS0) & UDCCS0_FST) != 0;	case 1:		return (udc (UDCCS1) & UDCCS1_FST) != 0;	case 2:		return (udc (UDCCS2) & UDCCS2_FST) != 0;	}	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){	usb_address = address;#if 0        int ok;	// address can be setup, udc will wait until ack received	dbg_udc(1, "%02d", address);        IOIOIO(UDCAR, usb_address, *(UDCAR) = address , (udc(UDCAR) != address), ok);        if (*(UDCAR) != address) {                dbg_udc(0, "AA %02d %02d ok: %d", udc(UDCAR), address, ok);                udelay(20);                IOIOIO(UDCAR, usb_address, *(UDCAR) = address , (udc(UDCAR) != address), ok);                if (*(UDCAR) != address) {                        dbg_udc(0, "BB %02d %02d ok: %d", udc(UDCAR), address, ok);                        udelay(40);                        IOIOIO(UDCAR, usb_address, *(UDCAR) = address , (udc(UDCAR) != address), ok);                }        }        dbg_udc(0, "CC %02d %02d ok: %d", udc(UDCAR), address, ok);#endif}#ifdef CONFIG_SA1100_BITSYstatic 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;}#endif/** * udc_serial_init - set a serial number if available */int __init udc_serial_init (struct usb_bus_instance *bus){#if defined(SHOW_CPU_STEPPING)	char *stepping;	u32 id = getCPUID (&stepping);	dbg_init (0, "CPU ID #%08x stepping %s",id,stepping);#else	dbg_init (2, "serial number");#endif#ifdef CONFIG_SA1100_BITSY	if (machine_is_bitsy ()) {		char serial_number[22];		int i;		int j;		memset (&serial_number, 0, sizeof (serial_number));		for (i = 0, j = 0; i < 20; i++, j++) {			char buf[4];			h3600_eeprom_read (5 + i, buf, 2);			serial_number[j] = buf[1];		}		serial_number[j] = '\0';		bus->serial_number = crc32 (serial_number, 22);		if (bus->serial_number_str = kmalloc (strlen (serial_number) + 1, GFP_KERNEL)) {			strcpy (bus->serial_number_str, serial_number);		}		//dbg_udc(0,  "serial: %s %08x", bus->serial_number_str, bus->serial_number);		return 0;	}#endif#ifdef CONFIG_SA1100_CALYPSO	if (machine_is_calypso ()) {		__u32 eerom_serial;		int i;		if ((i =		     CalypsoIicGet (IIC_ADDRESS_SERIAL0, (unsigned char *) &eerom_serial,				    sizeof (eerom_serial)))) {			bus->serial_number = eerom_serial;		}		if (bus->serial_number_str = kmalloc (9, GFP_KERNEL)) {			sprintf (bus->serial_number_str, "%08X", eerom_serial & 0xffffffff);		}		//dbg_udc(0,  "serial: %s %08x", bus->serial_number_str, bus->serial_number);		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  * @logical_endpoint: * * 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 > 64) {		return 0;	}	switch (logical_endpoint) {	case 1:		return 1;	case 0x82:		return 2;	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_udc (1, "[%d]:", ep);	if (ep < UDC_MAX_ENDPOINTS) {		ep_endpoints[ep] = endpoint;                dbg_udc (1, "[%d] ep_endpoint %p endpoint: %p", ep, ep_endpoints[ep], endpoint);		if (endpoint) {			switch (ep) {			case 0:	// Control				ep0_enable (device, endpoint);				break;			case 1:	// OUT                                dbg_udc (1, "[%d]: CHECKING rcv_urb: %p", ep, endpoint->rcv_urb);				// XXX XXX                                 if (!endpoint->rcv_urb) {                                        usbd_fill_rcv (device, endpoint, 5);                                        endpoint->rcv_urb = first_urb_detached (&endpoint->rdy);                                        dbg_udc (1, "[%d]: SETTING rcv_urb: %p", ep, endpoint->rcv_urb);                                }				ep1_enable (device, endpoint, usbd_rcv_dma);				break;			case 2:	// IN				ep2_enable (device, endpoint, usbd_tx_dma);				break;			}		}	}}/** * udc_disable_ep - disable endpoint * @ep: * * Disable specified endpoint  */void udc_disable_ep (unsigned int ep){	dbg_udc (1, "[%d]:", ep);	if (ep < UDC_MAX_ENDPOINTS) {		struct usb_endpoint_instance *endpoint;		if ((endpoint = ep_endpoints[ep])) {			ep_endpoints[ep] = NULL;			usbd_flush_ep (endpoint);		}		switch (ep) {		case 0:			ep0_disable ();			break;		case 1:			ep1_disable ();			break;		case 2:			ep2_disable ();			break;		}	}}/* ********************************************************************************************* *//** * udc_incradle - is the USB cable connected * * Return non-zeron if cable is connected. */int udc_connected (){	int rc = 1;#ifdef CONFIG_SA1100_USBCABLE_GPIO#ifdef CONFIG_SA1100_USBCABLE_ACTIVE_HIGH	rc = (GPLR & GPIO_GPIO (23)) != 0;	dbg_udc (1, "udc_connected: ACTIVE_HIGH: %d", rc);#else	rc = (GPLR & GPIO_GPIO (23)) == 0;	dbg_udc (1, "udc_connected: ACTIVE_LOW: %d", rc);#endif#else#warning UDC_CONNECTED not implemented#endif	return rc;}/** * udc_connect - enable pullup resistor * * Turn on the USB connection by enabling the pullup resistor. */void udc_connect (void){#if defined(CONFIG_SA1100_COLLIE)	// XXX change to 5500        #warning COLLIE CONNECT        if (ucb1200_test_io(TC35143_GPIO_VERSION0) != 0 ||                        ucb1200_test_io(TC35143_GPIO_VERSION1) != 0) {                SCP_REG_GPCR |= SCP_GPCR_PA19;    /* direction : out mode */                SCP_REG_GPWR |= SCP_GPCR_PA19;    /* set Hi */                dbg_udc(1, "udc_connect: %d GPCR: %x GPWR: %x GPRR: %x",                                SCP_GPCR_PA19, SCP_REG_GPCR, SCP_REG_GPWR, SCP_REG_GPRR);        }#elif defined(CONFIG_SA1100_CONNECT_GPIO)	GAFR |= GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO);	GPDR |= GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO);        #ifdef CONFIG_SA1100_CONNECT_ACTIVE_HIGH	GPSR = GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO);	dbg_udc (1, "udc_connect: %d ACTIVE_HIGH %x %x %x", CONFIG_SA1100_CONNECT_GPIO,		 GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO), GPDR, GPLR);        #else	GPCR = GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO);	dbg_udc (1, "udc_connect: %d ACTIVE_LOW %x %x %x", CONFIG_SA1100_CONNECT_GPIO,		 GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO), GPDR, GPLR);        #endif#else				/* defined(CONFIG_SA1100_CONNECT_GPIO) */#warning UDC_CONNECT not implemented#endif}/** * udc_disconnect - disable pullup resistor * * Turn off the USB connection by disabling the pullup resistor. */void udc_disconnect (void){#if defined(CONFIG_SA1100_COLLIE)	// XXX change to 5500        if (ucb1200_test_io(TC35143_GPIO_VERSION0) != 0 ||                        ucb1200_test_io(TC35143_GPIO_VERSION1) != 0) {                SCP_REG_GPWR &= ~SCP_GPCR_PA19;    /* set Hi */                SCP_REG_GPCR &= ~SCP_GPCR_PA19;    /* direction : out mode */                dbg_udc(1, "udc_disconnect: %d GPCR: %x GPWR: %x GPRR: %x",                                SCP_GPCR_PA19, SCP_REG_GPCR, SCP_REG_GPWR, SCP_REG_GPRR);        }#elif defined(CONFIG_SA1100_CONNECT_GPIO)#ifdef CONFIG_SA1100_CONNECT_ACTIVE_HIGH	GPCR = GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO);	dbg_udc (1, "udc_disconnect: %d ACTIVE_HIGH", CONFIG_SA1100_CONNECT_GPIO);#else	GPSR = GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO);	dbg_udc (1, "udc_disconnect: %d ACTIVE_LOW", CONFIG_SA1100_CONNECT_GPIO);#endif	GPDR &= ~GPIO_GPIO (CONFIG_SA1100_CONNECT_GPIO);#endif}/* ********************************************************************************************* */static __inline__ void set_interrupts (int flags){	int ok;	//dbg_udc(1, "udc_set_interrupts: %02x", flags);	// set interrupt mask	SET_AND_TEST ((*(UDCCR) = flags), (udc (UDCCR) != flags), ok);	if (!ok) {		dbg_intr (0, "failed to set UDCCR %02x to %02x", *(UDCCR), flags);	}}/** * udc_enable_interrupts - enable interrupts * * Switch on UDC interrupts. * */void udc_all_interrupts (struct usb_device_instance *device){	set_interrupts (0);	dbg_udc (1, "%02x", *(UDCCR));	// setup tick#ifdef USE_ADD_DEL_TIMER_FOR_USBADDR_CHECK	if (!usb_addr_check_initialized) {		init_timer (&sa1100_usb_dev_addr_check);		usb_addr_check_initialized = 1;		sa1100_usb_dev_addr_check.function = sa1100_tick;		sa1100_usb_dev_addr_check.data = 1;		sa1100_usb_dev_addr_check.expires = jiffies + CHECK_INTERVAL;		add_timer (&sa1100_usb_dev_addr_check);	}#else	// XXX sa1100_tq.sync = 0;	sa1100_tq.routine = sa1100_tick;	sa1100_tq.data = &udc_saw_sof;	queue_task (&sa1100_tq, &tq_timer);#endif}/** * udc_suspended_interrupts - enable suspended interrupts * * Switch on only UDC resume interrupt. * */void udc_suspended_interrupts (struct usb_device_instance *device){	set_interrupts (UDCCR_SRM);	dbg_udc (1, "%02x", *(UDCCR));}/** * udc_disable_interrupts - disable interrupts. * * switch off interrupts */void udc_disable_interrupts (struct usb_device_instance *device){	set_interrupts (UDCCR_SRM | UDCCR_EIM | UDCCR_RIM | UDCCR_TIM | UDCCR_SRM | UDCCR_REM);	dbg_udc (1, "%02x", *(UDCCR));}/* ********************************************************************************************* *//** * udc_ep0_packetsize - return ep0 packetsize */int udc_ep0_packetsize (void){	return EP0_PACKETSIZE;}/** * udc_enable - enable the UDC * * Switch on the UDC */void udc_enable (struct usb_device_instance *device){	int ok;	dbg_udc (1, "************************* udc_enable:");	//dbg_udc(0, "");	//dbg_udc(0, "udc_enable: device: %p", device);	// save the device structure pointer	udc_device = device;	// enable UDC	for (ok = 0; (*(UDCCR) & UDCCR_UDA) && ok < 100000; ok++);	if (ok > 10000) {		dbg_udc (0, "Waiting too long to go inactive: UDCCR: %02x", *(UDCCR));	}	// set UDD	SET_AND_TEST ((*(UDCCR) |= UDCCR_UDD), (!udc (UDCCR) & UDCCR_UDD), ok);	if (!ok) {		dbg_udc (0, "Waiting too long to disable: UDCCR: %02x", *(UDCCR));	}	// reset UDD	SET_AND_TEST ((*(UDCCR) &= ~UDCCR_UDD), (udc (UDCCR) & UDCCR_UDD), ok);	if (!ok) {		dbg_udc (0, "can't enable udc, FAILED: %02x", *(UDCCR));	}}/** * udc_disable - disable the UDC * * Switch off the UDC */void udc_disable (void){	int ok;	dbg_udc (1, "************************* udc_disable:");	// tell tick task to stop#ifdef USE_ADD_DEL_TIMER_FOR_USBADDR_CHECK	del_timer (&sa1100_usb_dev_addr_check);	sa1100_usb_dev_addr_check.data = 0;	usb_addr_check_initialized = 0;#else	sa1100_tq.data = NULL;	while (sa1100_tq.sync) {		//printk(KERN_DEBUG"waiting for sa1100_tq to stop\n");		schedule_timeout (10 * HZ);	}#endif	// disable UDC	for (ok = 0; (*(UDCCR) & UDCCR_UDA) && ok < 100000; ok++);	if (ok > 10000) {		dbg_udc (0, "Waiting too long to go inactive: UDCCR: %02x", *(UDCCR));	}	// set UDD	SET_AND_TEST ((*(UDCCR) |= UDCCR_UDD), (!udc (UDCCR) & UDCCR_UDD), ok);	if (!ok) {		dbg_udc (0, "Waiting too long to disable: UDCCR: %02x", *(UDCCR));	}	dbg_udc (7, "CCR: %02x", *(UDCCR));	// reset device pointer	udc_device = NULL;}/** * udc_startup - 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);	usbd_device_event (device, DEVICE_RESET, 0);	// XXX should be done from device event}/* ********************************************************************************************* *//** * udc_name - return name of USB Device Controller */char *udc_name (void){	return UDC_NAME;}/** * udc_request_udc_irq - request UDC interrupt * * Return non-zero if not successful. */int udc_request_udc_irq (){	// request IRQ and two dma channels	// XXX GPDR &= ~GPIO_GPIO(23);	// XXX set_GPIO_IRQ_edge(GPIO_GPIO(CONFIG_SA1100_USBCABLE_GPIO), GPIO_BOTH_EDGES);	dbg_init (2, "requesting udc irq: %d %d", 13, IRQ_Ser0UDC);	return request_irq (IRQ_Ser0UDC, int_hndlr_device, SA_INTERRUPT | SA_SAMPLE_RANDOM,			    "SA1100 USBD Bus Interface", NULL);}/** * udc_request_cable_irq - request Cable interrupt * * Return non-zero if not successful. */int udc_request_cable_irq (){#ifdef CONFIG_SA1100_USBCABLE_GPIO	dbg_init (2, "requesting cable irq: %d %d",		  CONFIG_SA1100_USBCABLE_GPIO, SA1100_GPIO_TO_IRQ (CONFIG_SA1100_USBCABLE_GPIO));	GPDR &= ~GPIO_GPIO (23);	set_GPIO_IRQ_edge (GPIO_GPIO (CONFIG_SA1100_USBCABLE_GPIO), GPIO_BOTH_EDGES);	return request_irq (SA1100_GPIO_TO_IRQ (CONFIG_SA1100_USBCABLE_GPIO), int_hndlr_cable,			    SA_INTERRUPT | SA_SAMPLE_RANDOM, "SA1100 Monitor", NULL);#else	return 0;#endif}/** * udc_request_udc_io - request UDC io region * * Return non-zero if not successful. */int udc_request_io (){	//sa1100_bi_init_dma ();        usbd_rcv_dma = usbd_tx_dma = -1;	if (sa1100_request_dma (&usbd_rcv_dma, "SA1100 USBD OUT - rcv dma", DMA_Ser0UDCRd)) {		dbg_init (2, "channel %d taken", usbd_rcv_dma);		return -EINVAL;	}	if (sa1100_request_dma (&usbd_tx_dma, "SA1100 USBD IN - tx dma", DMA_Ser0UDCWr)) {		dbg_init (2, "channel %d taken", usbd_tx_dma);		sa1100_free_dma (usbd_rcv_dma);		return -EINVAL;	}	return 0;}/** * udc_release_udc_irq - release UDC irq */void udc_release_udc_irq (){	free_irq (IRQ_Ser0UDC, NULL);}/** * udc_release_cable_irq - release Cable irq */void udc_release_cable_irq (){#ifdef CONFIG_SA1100_USBCABLE_GPIO	dbg_init (2, "freeing cable irq: %d", CONFIG_SA1100_USBCABLE_GPIO);

⌨️ 快捷键说明

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