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

📄 dm_usb_isp1362.c

📁 blackfin 的 usb devise 的代码 很基础
💻 C
📖 第 1 页 / 共 4 页
字号:
	.release = single_release,};/* expect just one isp1362 per system */static const char proc_filename[] = "driver/isp1362";static void create_debug_file(struct isp1362 *isp1362){	struct proc_dir_entry *pde;	pde = create_proc_entry(proc_filename, 0, NULL);	if (pde == NULL)		return;	pde->proc_fops = &proc_ops;	pde->data = isp1362;	isp1362->pde = pde;}static void remove_debug_file(struct isp1362 *isp1362){	if (isp1362->pde)		remove_proc_entry(proc_filename, NULL);}#endif/*-----------------------------------------------------------------*//*  Software reset - can be called from any contect.*/static int isp1362_sw_reset(struct isp1362 *isp1362){	int retries = 15;	unsigned long flags;	int ret = 0;	spin_lock_irqsave(&isp1362->lock, flags);	isp1362_write_reg16(isp1362, HCSWRES, HCSWRES_MAGIC);	isp1362_write_reg32(isp1362, HCCMDSTAT, HCCMDSTAT_HCR);	while (--retries) {		/* It usually resets within 1 ms */		mdelay(1);		if (!(isp1362_read_reg32(isp1362, HCCMDSTAT) & HCCMDSTAT_HCR))			break;	}	if (!retries) {		ERR("Software reset timeout\n");		ret = -ETIME;	}	spin_unlock_irqrestore(&isp1362->lock, flags);	return ret;}static int isp1362_reset(struct usb_hcd *hcd){	struct isp1362 *isp1362 = hcd_to_isp1362(hcd);	unsigned long t;	u16 clkrdy = 0;	int ret = 0, timeout = 15 /* ms */ ;	ret = isp1362_sw_reset(isp1362);	if (ret)		return ret;	t = jiffies + msecs_to_jiffies(timeout);	while (time_before_eq(jiffies, t)) {		msleep(4);		spin_lock_irq(&isp1362->lock);		clkrdy = isp1362_read_reg16(isp1362, HCuPINT) & HCuPINT_CLKRDY;		spin_unlock_irq(&isp1362->lock);		if (clkrdy)			break;	}	if (!clkrdy) {		ERR("Clock not ready after 20ms\n");		/* After sw_reset the clock won't report to be ready, if		   H_WAKEUP pin is high. */		ERR("Please make sure that the H_WAKEUP pin is pulled low!\n");		ret = -ENODEV;	}	return ret;}static void isp1362_stop(struct usb_hcd *hcd){	struct isp1362 *isp1362 = hcd_to_isp1362(hcd);	unsigned long flags;	u32 val;	spin_lock_irqsave(&isp1362->lock, flags);	isp1362_write_reg16(isp1362, HCuPINTENB, 0);	/* Switch off ports' power, some devices don't come up	   after next 'insmod' without this */	val = isp1362_read_reg32(isp1362, HCRHDESCA);	val &= ~(RH_A_NPS | RH_A_PSM);	isp1362_write_reg32(isp1362, HCRHDESCA, val);	isp1362_write_reg32(isp1362, HCRHSTATUS, RH_HS_LPS);	spin_unlock_irqrestore(&isp1362->lock, flags);	isp1362_sw_reset(isp1362);}/*  Configure the chip. The chip must be successfully reset by now.*/static int isp1362_start(struct usb_hcd *hcd){	struct isp1362 *isp1362 = hcd_to_isp1362(hcd);	struct isp1362_platform_data *board = isp1362->board;	u32 val;	unsigned long flags;	spin_lock_irqsave(&isp1362->lock, flags);	/* clear interrupt status and disable all interrupt sources */	isp1362_write_reg16(isp1362, HCuPINT, 0xff);	isp1362_write_reg16(isp1362, HCuPINTENB, 0);	val = isp1362_read_reg16(isp1362, HCCHIPID);	if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {		ERR("Invalid chip ID %04x\n", val);		spin_unlock_irqrestore(&isp1362->lock, flags);		return -ENODEV;	}	/* To be removed in future */	hcd->uses_new_polling = 1;	isp1362_write_reg16(isp1362, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);	isp1362_write_reg16(isp1362, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);	/* ----- HW conf */	val = HCHWCFG_INT_ENABLE | HCHWCFG_DBWIDTH(1);	if (board->sel15Kres)		val |= HCHWCFG_15KRSEL;	/* Remote wakeup won't work without working clock */	if (board->remote_wakeup_enable)		val |= HCHWCFG_CLKNOTSTOP;	if (board->oc_enable)		val |= HCHWCFG_ANALOG_OC;	if (board->int_act_high)		val |= HCHWCFG_INT_POL;	if (board->int_edge_triggered)		val |= HCHWCFG_INT_TRIGGER;	isp1362_write_reg16(isp1362, HCHWCFG, val);	/* ----- Root hub conf */	val = (25 << 24) & RH_A_POTPGT;	/* AN10003_1.pdf recommends RH_A_NPS (no power switching) to	   be always set. Yet, instead, we request individual port	   power switching. */	val |= RH_A_PSM;	/* Report overcurrent per port */	val |= RH_A_OCPM;	isp1362_write_reg32(isp1362, HCRHDESCA, val);	isp1362->rhdesca = isp1362_read_reg32(isp1362, HCRHDESCA);	val = RH_B_PPCM;	isp1362_write_reg32(isp1362, HCRHDESCB, val);	isp1362->rhdescb = isp1362_read_reg32(isp1362, HCRHDESCB);	val = 0;	if (board->remote_wakeup_enable) {		hcd->can_wakeup = 1;		val |= RH_HS_DRWE;	}	isp1362_write_reg32(isp1362, HCRHSTATUS, val);	isp1362->rhstatus = isp1362_read_reg32(isp1362, HCRHSTATUS);	isp1362_write_reg32(isp1362, HCFMINTVL, 0x27782edf);	hcd->state = HC_STATE_RUNNING;	/* Set up interrupts */	isp1362->intenb = HCINT_MIE | HCINT_RHSC | HCINT_UE;	if (board->remote_wakeup_enable)		isp1362->intenb |= HCINT_RD;	isp1362->irqenb = HCuPINT_ATL | HCuPINT_OPR;	/* | HCuPINT_SUSP; */	isp1362_write_reg32(isp1362, HCINTENB, isp1362->intenb);	isp1362_write_reg16(isp1362, HCuPINTENB, isp1362->irqenb);	/* Go operational */	val = HCCONTROL_USB_OPER;	if (board->remote_wakeup_enable)		val |= HCCONTROL_RWE;	isp1362_write_reg32(isp1362, HCCONTROL, val);	/* Disable ports to avoid race in device enumeration */	isp1362_write_reg32(isp1362, HCRHPORT1, RH_PS_CCS);	isp1362_write_reg32(isp1362, HCRHPORT2, RH_PS_CCS);	isp1362_show_regs(isp1362);	spin_unlock_irqrestore(&isp1362->lock, flags);	return 0;}/*-----------------------------------------------------------------*/static struct hc_driver isp1362_hc_driver = {	.description = hcd_name,	.product_desc = "ISP116x Host Controller",	.hcd_priv_size = sizeof(struct isp1362),	.irq = isp1362_irq,	.flags = HCD_USB11,	.reset = isp1362_reset,	.start = isp1362_start,	.stop = isp1362_stop,	.urb_enqueue = isp1362_urb_enqueue,	.urb_dequeue = isp1362_urb_dequeue,	.endpoint_disable = isp1362_endpoint_disable,	.get_frame_number = isp1362_get_frame,	.hub_status_data = isp1362_hub_status_data,	.hub_control = isp1362_hub_control,	.hub_suspend = isp1362_hub_suspend,	.hub_resume = isp1362_hub_resume,};/*----------------------------------------------------------------*/static int __init_or_module isp1362_remove(struct device *dev){	struct usb_hcd *hcd = dev_get_drvdata(dev);	struct isp1362 *isp1362;	struct platform_device *pdev;	struct resource *res;	if (!hcd)		return 0;	isp1362 = hcd_to_isp1362(hcd);	pdev = container_of(dev, struct platform_device, dev);	remove_debug_file(isp1362);	usb_remove_hcd(hcd);	iounmap(isp1362->data_reg);	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);	release_mem_region(res->start, 2);	iounmap(isp1362->addr_reg);	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	release_mem_region(res->start, 2);	usb_put_hcd(hcd);	return 0;}#define resource_len(r) (((r)->end - (r)->start) + 1)/*********************************************************************************** 名称 :isp1362_probe* 功能 :检测设备* 入口参数 :无* 出口参数 :无***********************************************************************************/static int __init isp1362_probe(struct device *dev){	struct usb_hcd *hcd;	struct isp1362 *isp1362;	struct platform_device *pdev;	struct resource *addr, *data;	void __iomem *addr_reg;	void __iomem *data_reg;	int irq;	int ret = 0;	pdev = container_of(dev, struct platform_device, dev);	if (pdev->num_resources < 3) {		ret = -ENODEV;		goto err1;	}	data = platform_get_resource(pdev, IORESOURCE_MEM, 0);	addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);	irq = platform_get_irq(pdev, 0);	if (!addr || !data || irq < 0) {		ret = -ENODEV;		goto err1;	}	if (dev->dma_mask) {		DBG("DMA not supported\n");		ret = -EINVAL;		goto err1;	}	if (!request_mem_region(addr->start, 2, hcd_name)) {		ret = -EBUSY;		goto err1;	}	addr_reg = ioremap(addr->start, resource_len(addr));	if (addr_reg == NULL) {		ret = -ENOMEM;		goto err2;	}	if (!request_mem_region(data->start, 2, hcd_name)) {		ret = -EBUSY;		goto err3;	}	data_reg = ioremap(data->start, resource_len(data));	if (data_reg == NULL) {		ret = -ENOMEM;		goto err4;	}	/* allocate and initialize hcd */	hcd = usb_create_hcd(&isp1362_hc_driver, dev, dev->bus_id);	if (!hcd) {		ret = -ENOMEM;		goto err5;	}	/* this rsrc_start is bogus */	hcd->rsrc_start = addr->start;	isp1362 = hcd_to_isp1362(hcd);	isp1362->data_reg = data_reg;	isp1362->addr_reg = addr_reg;	spin_lock_init(&isp1362->lock);	INIT_LIST_HEAD(&isp1362->async);///	INIT_WORK(&isp1362->rh_resume, isp1362_rh_resume, hcd);	isp1362->board = dev->platform_data;	if (!isp1362->board) {		ERR("Platform data structure not initialized\n");		ret = -ENODEV;		goto err6;	}	if (isp1362_check_platform_delay(isp1362)) {		ERR("USE_PLATFORM_DELAY defined, but delay function not "		    "implemented.\n");		ERR("See comments in drivers/usb/host/isp1362-hcd.c\n");		ret = -ENODEV;		goto err6;	}	ret = usb_add_hcd(hcd, irq, SA_INTERRUPT);	if (ret != 0)		goto err6;	create_debug_file(isp1362);	return 0;      err6:	usb_put_hcd(hcd);      err5:	iounmap(data_reg);      err4:	release_mem_region(data->start, 2);      err3:	iounmap(addr_reg);      err2:	release_mem_region(addr->start, 2);      err1:	ERR("init error, %d\n", ret);	return ret;}#ifdef	CONFIG_PM/*********************************************************************************** 名称 :isp1362_suspend* 功能 :挂起设备* 入口参数 :无* 出口参数 :无***********************************************************************************/static int isp1362_suspend(struct device *dev, pm_message_t state, u32 phase){	int ret = 0;	struct usb_hcd *hcd = dev_get_drvdata(dev);	VDBG("%s: state %x, phase %x\n", __func__, state, phase);	if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN)		return 0;	ret = usb_suspend_device(hcd->self.root_hub, state);	if (!ret) {		dev->power.power_state = state;		INFO("%s suspended\n", hcd_name);	} else		ERR("%s suspend failed\n", hcd_name);	return ret;}/*********************************************************************************** 名称 :isp1362_resume* 功能 :重新连接设备* 入口参数 :无* 出口参数 :无***********************************************************************************/static int isp1362_resume(struct device *dev, u32 phase){	int ret = 0;	struct usb_hcd *hcd = dev_get_drvdata(dev);	VDBG("%s:  state %x, phase %x\n", __func__, dev->power.power_state,	     phase);	if (phase != RESUME_POWER_ON)		return 0;	ret = usb_resume_device(hcd->self.root_hub);	if (!ret) {		dev->power.power_state = PMSG_ON;		VDBG("%s resumed\n", (char *)hcd_name);	}	return ret;}#else#define	isp1362_suspend    NULL#define	isp1362_resume     NULL#endifstatic struct device_driver isp1362_driver = {	.name = (char *)hcd_name,	.bus = &platform_bus_type,	.probe = isp1362_probe,	.remove = isp1362_remove,	.suspend = isp1362_suspend,	.resume = isp1362_resume,};/*-----------------------------------------------------------------*//*********************************************************************************** 名称 :isp1362_init* 功能 :ISP1362初始化* 入口参数 :无* 出口参数 :无***********************************************************************************/static int __init isp1362_init(void){	if (usb_disabled())		return -ENODEV;	INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION);	return driver_register(&isp1362_driver);}module_init(isp1362_init);/*********************************************************************************** 名称 :isp1362_cleanup* 功能 :清除ISP1362* 入口参数 :无* 出口参数 :无***********************************************************************************/static void __exit isp1362_cleanup(void){	driver_unregister(&isp1362_driver);}module_exit(isp1362_cleanup);#endif//motor

⌨️ 快捷键说明

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