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

📄 hc_isp116x.c

📁 tango针对嵌入式USB主控制器ISP1161的驱动编程
💻 C
📖 第 1 页 / 共 2 页
字号:
		hci->td_array = &hci->i_td_array [iso_buffer_index];              sh_scan_iso_urb_list (hci, &hci->iso_list, hci->frame_number);              if (hp->tlp >0) {			hp->units_left = hp->itl_buffer_len;			WRITE_REG16 (hci, hp->tlp, HcTransferCounter);			WRITE_REGn16 (hci, HcITLBufferPort, hp->tlp, hp->tl);//                    WRITE_REG16 (hci, 8, HcTransferCounter);//			WRITE_REGn16 (hci, HcITLBufferPort, 8, hp->tl);		}#endif	}        if (ints_uP & ATLInt) {		if ((bstat & ATLBufferFull) && (bstat & ATLBufferDone)) {			if (hp->atl_len > 0) {				WRITE_REG16 (hci, hp->atl_len, HcTransferCounter);				READ_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);				hp->tlp = 0;				hci->td_array = &hci->a_td_array;				sh_done_list (hci);			}			hp->tlp = 0;		}	}	if (!hci->td_array->len)		sh_del_list (hci);	hci->td_array = &hci->a_td_array;	bstat = READ_REG16 (hci, HcBufferStatus);	if (hci->td_array->len == 0 && !(bstat & ATLBufferFull)) {		hp->units_left = hp->atl_buffer_len;		hp->tlp = 0;		sh_schedule_trans (hci);		hc_mark_last_trans (hci);		hp->atl_len = hp->tlp;		if (hp->atl_len > 0) {			WRITE_REG16 (hci, hp->atl_len, HcTransferCounter);			WRITE_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);		}	}}/*-------------------------------------------------------------------------* * HC functions *-------------------------------------------------------------------------*//* reset the HC and BUS */static int hc_reset (hci_t * hci){	int timeout = 30;	/* Disable HC interrupts */	WRITE_REG16 (hci, 0,HcuPInterruptEnable);	WRITE_REG16 (hci,InterruptPinEnable | DataBusWidth16 | DownstreamPort15KRSel, HcHardwareConfiguration);	WRITE_REG16 (hci,InterruptOutputPolarity  | DataBusWidth16 | DownstreamPort15KRSel, HcHardwareConfiguration);	dbg ("USB HC reset_hc usb-: ctrl = 0x%x ;",		READ_REG32 (hci, HcControl));  	/* Reset USB (needed by some controllers) *///	WRITE_REG32 (hci, 0, HcControl);//	WRITE_REG0 (hci, HcSoftwareReset);       WRITE_REG16 (hci, 0xf6, HcSoftwareReset);	/* HC Reset requires max 10 us delay */	WRITE_REG32 (hci, OHCI_HCR, HcCommandStatus);	while ((READ_REG32 (hci, HcCommandStatus) & OHCI_HCR) != 0) {		if (--timeout == 0) {			printk ("USB HC reset timed out!\n");			return -1;		}		udelay (10);	}	return 0;}/*-------------------------------------------------------------------------*//* Start an host controller, set the BUS operational * enable interrupts * connect the virtual root hub */static int hc_alloc_trans_buffer (hci_t * hci){	hcipriv_t * hp = &hci->hp;	int maxlen;	hp->itl0_len = 0;	hp->itl1_len = 0;	hp->atl_len = 0;	hp->itl_buffer_len = 1024;	hp->atl_buffer_len = 4096 - 2 * hp->itl_buffer_len; /* 2048 */	WRITE_REG16 (hci, hp->itl_buffer_len, HcITLBufferLength);	WRITE_REG16 (hci, hp->atl_buffer_len, HcATLBufferLength);	WRITE_REG16 (hci, 0, HcDMAConfiguration);	maxlen = (hp->itl_buffer_len > hp->atl_buffer_len) ? hp->itl_buffer_len : hp->atl_buffer_len;	hp->tl = kmalloc (maxlen, GFP_KERNEL);	if (!hp->tl)		return -ENOMEM;	memset (hp->tl, 0, maxlen);	return 0;}static int hc_start (hci_t * hci){	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);//	WRITE_REG16 (hci,InterruptPinEnable | DataBusWidth16 , HcHardwareConfiguration);#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);//	WRITE_REG16 (hci,InterruptPinEnable | DataBusWidth16 | DownstreamPort15KRSel, HcHardwareConfiguration);//	WRITE_REG16 (hci,InterruptPinEnable | DataBusWidth16 , HcHardwareConfiguration);	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_KERNEL);	if (!hci)		return NULL;	memset (hci, 0, sizeof (hci_t));	hp = &hci->hp;	hp->irq = -1;	hp->hcport = -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;	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);	bus = usb_alloc_bus (&hci_device_operations);	if (!bus) {		kfree (hci);		return NULL;	}	hci->bus = bus;	bus->hcpriv = (void *) 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->hcport > 0) {		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->hcport > 0) {		release_region (hp->hcport, 2);		hp->hcport = 0;	}	if (hp->hcport2 > 0) {		release_region (hp->hcport2, 2);		hp->hcport2 = 0;	}//	if (hp->wuport > 0) {//		release_region (hp->wuport, 2);//		hp->wuport = 0;//	}	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 addr, int addr2, int wuaddr, int irq, int dma){	hci_t * hci;	hcipriv_t * hp;	hci = hc_alloc_hci ();	if (!hci) {		return -ENOMEM;	}	hp = &hci->hp;	if (!request_region (addr, 2, "ISP116x USB HOST")) {		err ("request address %d-%d failed", addr, addr+4);		hc_release_hci (hci);		return -EBUSY;	}	hp->hcport = addr;	if (!request_region (addr2, 2, "ISP116x USB HOST")) {		err ("request address %d-%d failed", addr, addr+4);		hc_release_hci (hci);		return -EBUSY;	}	hp->hcport2 = addr2;	if ((READ_REG16(hci, HcChipID) & 0xff00) != 0x6100) {             printk("ISP1161 Not Found HcChipID =%x\n",READ_REG16(hci, HcChipID));             hc_release_hci (hci);		return -ENODEV;	}//	if (!request_region (wuaddr, 2, "ISP116x USB HOST")) {//		err ("request address %d-%d failed", wuaddr, wuaddr+2);//		hc_release_hci (hci);//		return -EBUSY;//	}//	hp->wuport = wuaddr;	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",		addr, addr2, wuaddr, 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, 0,			"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", addr);		hc_release_hci (hci);		return -EBUSY;	}	return 0;}/*-------------------------------------------------------------------------*/static int __init hci_hcd_init (void){	int ret;	ret = hc_found_hci (hcport, hcport2, wuport, irq, 0);	return ret;}/*-------------------------------------------------------------------------*/static void __exit hci_hcd_cleanup (void){	struct list_head *  hci_l;	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);      }}module_init (hci_hcd_init);module_exit (hci_hcd_cleanup);MODULE_AUTHOR ("Roman Weissgaerber <weissg@vienna.at>");MODULE_DESCRIPTION ("USB ISP116x Host Controller Driver");

⌨️ 快捷键说明

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