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

📄 hc_isp116x.c

📁 嵌入式USB主控制器ISP1161的驱动编程
💻 C
📖 第 1 页 / 共 4 页
字号:
{	hcipriv_t * hp = &hci->hp;  	__u32 mask;  	unsigned int fminterval;  	fminterval = 0x2edf;	fminterval |= ((((fminterval - 210) * 6) / 7) << 16);	WRITE_REG32 (hci, fminterval, HcFmInterval);	WRITE_REG32 (hci, 0x628, HcLSThreshold); 	/* start controller operations */ 	hp->hc_control = OHCI_USB_OPER; 	WRITE_REG32 (hci, hp->hc_control, HcControl);	/* Choose the interrupts we care about now, others later on demand */	mask = OHCI_INTR_MIE |//	OHCI_INTR_ATD |	OHCI_INTR_SO ;//	OHCI_INTR_SF;	WRITE_REG32 (hci, mask, HcInterruptEnable);	WRITE_REG32 (hci, mask, HcInterruptStatus);	mask = SOFITLInt | ATLInt | OPR_Reg;#ifdef HC_SWITCH_INT	mask = 0;#endif	WRITE_REG16 (hci, mask, HcuPInterrupt);	WRITE_REG16 (hci, mask, HcuPInterruptEnable);#ifdef	OHCI_USE_NPS	WRITE_REG32 (hci,(READ_REG32 (hci, HcRhDescriptorA) | RH_A_NPS) & ~RH_A_PSM,		HcRhDescriptorA);	WRITE_REG32 (hci, RH_HS_LPSC, HcRhStatus);#endif	/* OHCI_USE_NPS */	// POTPGT delay is bits 24-31, in 2 ms units.	mdelay ((READ_REG32 (hci, HcRhDescriptorA) >> 23) & 0x1fe);	rh_connect_rh (hci);	return 0;}/*-------------------------------------------------------------------------*//* allocate HCI */static hci_t * __devinit hc_alloc_hci (void){	hci_t * hci;	hcipriv_t * hp;	struct usb_bus * bus;	hci = (hci_t *) kmalloc (sizeof (hci_t), GFP_ATOMIC);	if (!hci)		return NULL;	memset (hci, 0, sizeof (hci_t));	hp = &hci->hp;	hp->irq = -1;	hp->data_port = -1;	hp->cmd_port = -1;	hp->wu_port = -1; 	hci->a_td_array.len = 0; 	hci->i_td_array[0].len = 0; 	hci->i_td_array[1].len = 0; 	hci->td_array = &hci->a_td_array; 	hci->active_urbs = 0;	hci->bh_in_progress = 0;	hci->iso_buffer_index = 0;	INIT_LIST_HEAD (&hci->hci_hcd_list);	list_add (&hci->hci_hcd_list, &hci_hcd_list);	init_waitqueue_head (&hci->waitq);	INIT_LIST_HEAD (&hci->ctrl_list);	INIT_LIST_HEAD (&hci->bulk_list);	INIT_LIST_HEAD (&hci->iso_list);	INIT_LIST_HEAD (&hci->intr_list);	INIT_LIST_HEAD (&hci->del_list);	INIT_LIST_HEAD (&hci->itl_list);	bus = usb_alloc_bus (&hci_device_operations);	if (!bus) {		kfree (hci);		return NULL;	}	hci->bus = bus;	bus->bus_name = "isp116x";	bus->hcpriv = (void *) hci;	hci->bottomHalf.func = hc_interrupt_bh;	hci->bottomHalf.data = (unsigned long)hci;	hci->ChipReset.func = hc_renew_chip;	hci->ChipReset.data = (unsigned long)hci;	return hci;}/*-------------------------------------------------------------------------*//* De-allocate all resources.. */static void hc_release_hci (hci_t * hci){	hcipriv_t * hp = &hci->hp;	dbg ("USB HC release hci %d", hci->regs);	/* disconnect all devices */	if (hci->bus->root_hub)		usb_disconnect (&hci->bus->root_hub);	if (hp->data_port != -1) {		WRITE_REG16 (hci, 0, HcHardwareConfiguration);		WRITE_REG16 (hci, 0, HcDMAConfiguration);		WRITE_REG16 (hci, 0, HcuPInterruptEnable);	}//	if (!hci->disabled)		hc_reset (hci);	if (hp->tl)		kfree (hp->tl);	if (hp->data_port != -1) {		release_region (hp->data_port, 2);		hp->data_port = -1;	}	if (hp->cmd_port != -1) {		release_region (hp->cmd_port, 2);		hp->cmd_port = -1;	}	if (hp->wu_port != -1) {		release_region (hp->wu_port, 2);		hp->wu_port = -1;	}	if (hp->irq >= 0) {		free_irq (hp->irq, hci);		hp->irq = -1;	}	usb_deregister_bus (hci->bus);	usb_free_bus (hci->bus);	list_del (&hci->hci_hcd_list);	INIT_LIST_HEAD (&hci->hci_hcd_list);	kfree (hci);}/*-------------------------------------------------------------------------*//* Increment the module usage count, start the control thread and * return success. */static int __devinit hc_found_hci (int data_port, int cmd_port, int wu_addr, int irq, int dma){	hci_t * hci;	hcipriv_t * hp;	hci = hc_alloc_hci ();	if (!hci) {		return -ENOMEM;	}	hp = &hci->hp;	if (!request_region (data_port, 2, "ISP116x USB HOST")) {		err ("request address %d-%d failed", data_port, data_port+4);		hc_release_hci (hci);		return -EBUSY;	}	hp->data_port = data_port;	if (!request_region (cmd_port, 2, "ISP116x USB HOST")) {		err ("request address %d-%d failed", data_port, data_port+4);		hc_release_hci (hci);		return -EBUSY;	}	hp->cmd_port = cmd_port;	if ( wu_addr != -1 ) {		if (!request_region (wu_addr, 2, "ISP116x USB HOST")) {			err ("request address %d-%d failed", wu_addr, wu_addr+2);			hc_release_hci (hci);			return -EBUSY;		}	}	hp->wu_port = wu_addr;	if ((READ_REG16(hci, HcChipID) & 0xff00) != 0x6100) {             printk("ISP116x Not Found. HcChipID = 0x%x\n",READ_REG16(hci, HcChipID));             hc_release_hci (hci);		return -ENODEV;	}	if (hc_reset (hci) < 0) {		hc_release_hci (hci);		return -ENODEV;	}	if (hc_alloc_trans_buffer (hci)) {		hc_release_hci (hci);		return -ENOMEM;	}	printk(KERN_INFO __FILE__ ": USB ISP116x at %x/%x,%x IRQ %d Rev. %x ChipID: %x\n",		data_port, cmd_port, wu_addr, irq, READ_REG32(hci, HcRevision), READ_REG16(hci, HcChipID));	/* FIXME this is a second HC reset; why?? *///	WRITE_REG32 (hci, hp->hc_control = OHCI_USB_RESET, HcControl);	wait_ms (1000);	usb_register_bus (hci->bus);	if (request_irq (irq, hc_interrupt, SA_SHIRQ,			"ISP116x", hci) != 0) {		err ("request interrupt %d failed", irq);		hc_release_hci (hci);		return -EBUSY;	}	hp->irq = irq;	if (hc_start (hci) < 0) {		err ("can't start usb-%x", data_port);		hc_release_hci (hci);		return -EBUSY;	}	SITSANG_BIPR_RW = SITSANG_BIPR_USB_HC_IRQ;        SITSANG_BIMR_RW |= SITSANG_BIMR_USB_HC_IRQ;	return 0;}/*-------------------------------------------------------------------------*/static int __init hci_hcd_init (void){	int ret;#ifdef CONFIG_ARCH_SITSANG        unsigned int irq_gpio_pin = 0;        irq_gpio_pin = IRQ_TO_GPIO_2_80(SITSANG_USB_HC_IRQ);        GPDR(irq_gpio_pin) &= ~GPIO_bit(irq_gpio_pin);        set_GPIO_IRQ_edge(irq_gpio_pin, GPIO_RISING_EDGE);        SITSANG_PCR_RW |= SITSANG_PCR_USB_HOST_ON | SITSANG_PCR_PER_ON;        SITSANG_BCR_RW |= SITSANG_BCR_BUS_OPEN | SITSANG_BCR_USB_NDP;        SITSANG_BCR_RW |= SITSANG_BCR_USB_HC_RESET;        mdelay(500);        /*Reset the CHIP*/        SITSANG_BCR_RW &= ~(SITSANG_BCR_USB_HC_RESET);        mdelay(500);        MSC2 &= 0xffff0000;        MSC2 |= 0x00009489;#endif	ret = hc_found_hci (data_port, cmd_port, wu_port, irq, 0);	/* init these data */	for (Buffer_History_p=0; Buffer_History_p<10; Buffer_History_p++) {		Buffer_History[Buffer_History_p] = 0;	}	Buffer_History_p = 0;	create_proc_read_entry ("isp_info", 0, NULL, hc_isp_proc_info, NULL);	create_proc_read_entry ("isp_reset", 0, NULL, hc_isp_proc_reset, NULL);	return ret;}/*-------------------------------------------------------------------------*/static void __exit hci_hcd_cleanup (void){	struct list_head *  hci_l;	cleanup = 1;	hci_t * hci;	for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;) {		hci = list_entry (hci_l, hci_t, hci_hcd_list);		hci_l = hci_l->next;		hc_release_hci(hci);      	}	remove_proc_entry("isp_info", NULL);#ifdef CONFIG_ARCH_SITSANG        SITSANG_BIMR_RW &= ~SITSANG_BIMR_USB_HC_IRQ;        SITSANG_PCR_RW &= ~SITSANG_PCR_USB_HOST_ON;#endif}int hc_isp_proc_info (char *buf, char **start, off_t offset, int count, int *eof, void *data){	int i, j, len = 0;	int usec_interval = 0;	struct timeval timeVal;	do_gettimeofday (&timeVal);	j = Buffer_History_p;	for (i=0; i<10; i++) {		len += sprintf (buf+len,"in hc_interrupt HcBufferStatus: 0x%x	\n", Buffer_History[j]);		j = (j+1)%10;	}	len += sprintf (buf+len,"some flags about Buffer: \n");	len += sprintf (buf+len,"\tATL_quirk_flag : %d \n", ATL_quirk_flag);	len += sprintf (buf+len,"\tITL0_die_flag  : %d \n", ITL0_die_flag);	len += sprintf (buf+len,"\tITL1_die_flag  : %d \n", ITL1_die_flag);	len += sprintf (buf+len,"\n");	len += sprintf (buf+len,"go to force_return count : %d \n", force_return_count);	len += sprintf (buf+len,"kernel panic count : %d \n", kernel_panic_count);	len += sprintf (buf+len,"itl_list_map error : %d %d %d %d %d \n", itl_list_error[0], itl_list_error[1],	\				 itl_list_error[2], itl_list_error[3], itl_list_error[4]);	if (last_proc_time_sec==-1) {		len += sprintf (buf+len,"now we will start to calculate bandwidth!!\n");		last_proc_time_sec = timeVal.tv_sec;		last_proc_time_usec = timeVal.tv_usec;		proc_itl_stream = 0;	} else {		usec_interval = (timeVal.tv_sec-last_proc_time_sec)*1000000 + (timeVal.tv_usec-last_proc_time_usec);		len += sprintf (buf+len,"USB ITL BandWidth : %dbyte/sec\n", (proc_itl_stream*1000000)/usec_interval);		len += sprintf (buf+len,"test interval     : %dsec\n", usec_interval/1000000);			last_proc_time_sec = timeVal.tv_sec;		last_proc_time_usec = timeVal.tv_usec;		proc_itl_stream = 0;	}			return len;}int hc_isp_proc_reset (char *buf, char **start, off_t offset, int count, int *eof, void *data){	int len = 0;	len += sprintf (buf+len,"%d", chip_reset);	return len;}void hc_renew_chip (unsigned long __hci){	hci_t* hci = (hci_t *)__hci;	hcipriv_t * hp = &hci->hp;	unsigned int fminterval;	int mask;	if (hc_reset (hci) < 0) {		hc_release_hci (hci);		printk (KERN_EMERG "Error in hc_reset, check code!!\n");		return;	}	WRITE_REG16 (hci, hp->itl_buffer_len, HcITLBufferLength);	WRITE_REG16 (hci, hp->atl_buffer_len, HcATLBufferLength);	/* Enable IRQ's */	WRITE_REG16 (hci,		     InterruptPinEnable | HC_HARDWARE_CONFIG,		     HcHardwareConfiguration);	WRITE_REG16 (hci, 0, HcDMAConfiguration);	wait_ms (1000);	if (hc_start (hci) < 0) {		err ("can't start usb-%x", data_port);		hc_release_hci (hci);		return;	}  	fminterval = 0x2edf;	fminterval |= ((((fminterval - 210) * 6) / 7) << 16);	WRITE_REG32 (hci, fminterval, HcFmInterval);	WRITE_REG32 (hci, 0x628, HcLSThreshold); 	/* start controller operations */ 	hp->hc_control = OHCI_USB_OPER; 	WRITE_REG32 (hci, hp->hc_control, HcControl);	/* Choose the interrupts we care about now, others later on demand */	mask = OHCI_INTR_MIE |//	OHCI_INTR_ATD |	OHCI_INTR_SO ;//	OHCI_INTR_SF;	WRITE_REG32 (hci, mask, HcInterruptEnable);	WRITE_REG32 (hci, mask, HcInterruptStatus);	mask = SOFITLInt | ATLInt | OPR_Reg;	WRITE_REG16 (hci, mask, HcuPInterrupt);	WRITE_REG16 (hci, mask, HcuPInterruptEnable);#ifdef	OHCI_USE_NPS	WRITE_REG32 (hci,(READ_REG32 (hci, HcRhDescriptorA) | RH_A_NPS) & ~RH_A_PSM,		HcRhDescriptorA);	WRITE_REG32 (hci, RH_HS_LPSC, HcRhStatus);#endif	/* OHCI_USE_NPS */	// POTPGT delay is bits 24-31, in 2 ms units.	mdelay ((READ_REG32 (hci, HcRhDescriptorA) >> 23) & 0x1fe);	printk (KERN_EMERG "Succeed in renew chip!!\n");	return;}		module_init (hci_hcd_init);module_exit (hci_hcd_cleanup);MODULE_AUTHOR ("Roman Weissgaerber <weissg@vienna.at>");MODULE_DESCRIPTION ("USB ISP116x Host Controller Driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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