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

📄 dwc_otg_driver.c

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * Remove the device attributes	 * by scsuh	 *///	dwc_otg_attr_remove(dev);	/*	 * Return the memory.	 */	if (otg_dev->base != NULL) {		iounmap(otg_dev->base);	}	kfree(otg_dev);	/*	 * Clear the drvdata pointer.	 */	platform_set_drvdata(dev, 0);	return 0;}static struct clk	*otg_clock = NULL;static dwc_otg_core_if_t *core_if_global;/** * This function is called when an lm_device is bound to a * dwc_otg_driver. It creates the driver components required to * control the device (CIL, HCD, and PCD) and it initializes the * device. The driver components are stored in a dwc_otg_device * structure. A reference to the dwc_otg_device is saved in the * lm_device. This allows the driver to access the dwc_otg_device * structure on subsequent calls to driver methods for this device. * * @param[in] _lmdev  lm_device definition */static int dwc_otg_driver_probe (struct platform_device *pdev){	int retval = 0;	dwc_otg_device_t *dwc_otg_device;	uint reg;	dbg_otg("%s\n", __FUNCTION__);	dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);	if (dwc_otg_device == 0) {		dev_err(&pdev->dev, "kmalloc of dwc_otg_device failed\n");		retval = -ENOMEM;		goto fail;	}	memset(dwc_otg_device, 0, sizeof(*dwc_otg_device));	dwc_otg_device->reg_offset = 0xFFFFFFFF;	/*	 * enable hclk using clk_enable()	 * by scsuh.	 * special modification for S3C64xx	 */	otg_clock = clk_get(&pdev->dev, "otg");	if (otg_clock == NULL) {		printk(KERN_INFO "failed to find otg clock source\n");		return -ENOENT;	}	clk_enable(otg_clock);	/*	 * very important init code for S3C64xx	 * by scsuh.	 * special modification for S3C64xx	 */	{		uint temp;		temp = __raw_readl(S3C_OTHERS);		temp |= (1<<16);   // USB_SIG_MASK		__raw_writel(temp, S3C_OTHERS);		/* 1. Initializes OTG Phy. */		__raw_writel(0x0, S3C_USBOTG_PHYPWR);		__raw_writel(0x20, S3C_USBOTG_PHYCLK);		__raw_writel(0x1, S3C_USBOTG_RSTCON);		udelay(50);		__raw_writel(0x0, S3C_USBOTG_RSTCON);		udelay(50);	}	/*	 * Map the DWC_otg Core memory into virtual address space.	 * in S3C64xx we already have virtual address for OTG.	 * modified by scsuh.	 */#if 0	dwc_otg_device->base = ioremap(XXXX, SZ_256K);	if (dwc_otg_device->base == NULL) {		dev_err(&pdev->dev, "ioremap() failed\n");		retval = -ENOMEM;		goto fail;	}#else	dwc_otg_device->base = S3C24XX_VA_OTG;#endif	dbg_otg("base=0x%08x\n", (unsigned) dwc_otg_device->base);	/*	 * Attempt to ensure this device is really a DWC_otg Controller.	 * Read and verify the SNPSID register contents. The value should be	 * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX".	 */	reg = dwc_read_reg32((uint32_t *) ((uint8_t *) dwc_otg_device->base + 0x40));	if ((reg & 0xFFFFF000) != 0x4F542000) {		printk("Bad value for SNPSID: 0x%08x\n", reg);		retval = -EINVAL;		goto fail;	}	/*	 * Initialize driver data to point to the global DWC_otg	 * Device structure.	 */	platform_set_drvdata(pdev, dwc_otg_device);	printk("dwc_otg_device=0x%p\n", dwc_otg_device);	dwc_otg_device->core_if = dwc_otg_cil_init(dwc_otg_device->base, &dwc_otg_module_params);	if (dwc_otg_device->core_if == 0) {		printk("CIL initialization failed!\n");		retval = -ENOMEM;		goto fail;	}	core_if_global = dwc_otg_device->core_if;	/*	 * Validate parameter values.	 */	if (check_parameters(dwc_otg_device->core_if) != 0) {		retval = -EINVAL;		goto fail;	}	/*	 * Create Device Attributes in sysfs	 * rem by scsuh.	 *///	dwc_otg_attr_create(pdev);	/*	 * Disable the global interrupt until all the interrupt	 * handlers are installed.	 */	dwc_otg_disable_global_interrupts(dwc_otg_device->core_if);	/*	 * Install the interrupt handler for the common interrupts before	 * enabling common interrupts in core_init below.	 */	dbg_otg("registering (common) handler for irq%d\n", IRQ_OTG);	retval = request_irq(IRQ_OTG, dwc_otg_common_irq, SA_SHIRQ, "dwc_otg", dwc_otg_device);	if (retval != 0) {		printk("request of irq%d failed\n", IRQ_OTG);		retval = -EBUSY;		goto fail;	} else {		dwc_otg_device->common_irq_installed = 1;	}	/*	 * Initialize the DWC_otg core.	 */	dwc_otg_core_init(dwc_otg_device->core_if);#ifndef DWC_HOST_ONLY	/*	 * Initialize the PCD	 */	retval = dwc_otg_pcd_init(pdev);	if (retval != 0) {		printk("dwc_otg_pcd_init failed\n");		dwc_otg_device->pcd = NULL;		goto fail;	}#endif#ifndef DWC_DEVICE_ONLY	/*	 * Initialize the HCD	 */	retval = dwc_otg_hcd_init(pdev);	if (retval != 0) {		printk("dwc_otg_hcd_init failed\n");		dwc_otg_device->hcd = NULL;		goto fail;	}#endif	/*	 * Enable the global interrupt after all the interrupt	 * handlers are installed.	 */#if 0	dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);#else	reg = readl(S3C_UDC_OTG_GAHBCFG);	writel(reg | 1, S3C_UDC_OTG_GAHBCFG);#endif	return 0;fail:	dwc_otg_driver_remove(pdev);	return retval;}/** * This structure defines the methods to be called by a bus driver * during the lifecycle of a device on that bus. Both drivers and * devices are registered with a bus driver. The bus driver matches * devices to drivers based on information in the device and driver * structures. * * The probe function is called when the bus driver matches a device * to this driver. The remove function is called when a device is * unregistered with the bus driver. */static struct platform_driver dwc_otg_driver = {	.probe = dwc_otg_driver_probe,	.remove = dwc_otg_driver_remove,	.driver = {		.name = "s3c2410-usbgadget",		.owner = THIS_MODULE,	},};/** * This function is called when the dwc_otg_driver is installed with the * insmod command. It registers the dwc_otg_driver structure with the * appropriate bus driver. This will cause the dwc_otg_driver_probe function * to be called. In addition, the bus driver will automatically expose * attributes defined for the device and driver in the special sysfs file * system. * * @return */static int __init dwc_otg_driver_init(void){	int retval = 0;	printk(KERN_INFO "%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION);	printk(KERN_INFO "Working version %s\n", "No 007 - 10/24/2007");	retval = platform_driver_register(&dwc_otg_driver);	if (retval < 0) {		printk(KERN_ERR "%s retval=%d\n", __func__, retval);	}//	driver_create_file(&dwc_otg_driver.drv, &driver_attr_version);//	driver_create_file(&dwc_otg_driver.drv, &driver_attr_debuglevel);	return retval;}module_init(dwc_otg_driver_init);/** * This function is called when the driver is removed from the kernel * with the rmmod command. The driver unregisters itself with its bus * driver. * */static void __exit dwc_otg_driver_cleanup(void){	printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n");//	driver_remove_file(&dwc_otg_driver.drv, &driver_attr_debuglevel);//	driver_remove_file(&dwc_otg_driver.drv, &driver_attr_version);	platform_driver_unregister(&dwc_otg_driver);	printk(KERN_INFO "%s module removed\n", dwc_driver_name);}module_exit(dwc_otg_driver_cleanup);MODULE_DESCRIPTION(DWC_DRIVER_DESC);MODULE_AUTHOR("Synopsys Inc.");MODULE_LICENSE("GPL");module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444);MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None");module_param_named(opt, dwc_otg_module_params.opt, int, 0444);MODULE_PARM_DESC(opt, "OPT Mode");module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444);MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled");module_param_named(dma_desc_enable, dwc_otg_module_params.dma_desc_enable, int, 0444);MODULE_PARM_DESC(dma_desc_enable, "DMA Desc Mode 0=Address DMA 1=DMA Descriptor enabled");module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int, 0444);MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256");module_param_named(speed, dwc_otg_module_params.speed, int, 0444);MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");module_param_named(host_support_fs_ls_low_power, dwc_otg_module_params.host_support_fs_ls_low_power,		   int, 0444);MODULE_PARM_DESC(host_support_fs_ls_low_power,		 "Support Low Power w/FS or LS 0=Support 1=Don't Support");module_param_named(host_ls_low_power_phy_clk, dwc_otg_module_params.host_ls_low_power_phy_clk, int,		   0444);MODULE_PARM_DESC(host_ls_low_power_phy_clk, "Low Speed Low Power Clock 0=48Mhz 1=6Mhz");module_param_named(enable_dynamic_fifo, dwc_otg_module_params.enable_dynamic_fifo, int, 0444);MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing");module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int, 0444);MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768");module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size, int, 0444);MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");module_param_named(dev_nperio_tx_fifo_size, dwc_otg_module_params.dev_nperio_tx_fifo_size, int,		   0444);MODULE_PARM_DESC(dev_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");module_param_named(dev_perio_tx_fifo_size_1, dwc_otg_module_params.dev_perio_tx_fifo_size[0], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_1, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_2, dwc_otg_module_params.dev_perio_tx_fifo_size[1], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_2, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_3, dwc_otg_module_params.dev_perio_tx_fifo_size[2], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_3, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_4, dwc_otg_module_params.dev_perio_tx_fifo_size[3], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_4, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_5, dwc_otg_module_params.dev_perio_tx_fifo_size[4], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_5, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_6, dwc_otg_module_params.dev_perio_tx_fifo_size[5], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_6, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_7, dwc_otg_module_params.dev_perio_tx_fifo_size[6], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_7, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_8, dwc_otg_module_params.dev_perio_tx_fifo_size[7], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_8, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_9, dwc_otg_module_params.dev_perio_tx_fifo_size[8], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_9, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_10, dwc_otg_module_params.dev_perio_tx_fifo_size[9], int,		   0444);MODULE_PARM_DESC(dev_perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO 4-768");module_param_named(dev_perio_tx_fifo_size_11, dwc_otg_module_params.dev_perio_tx_fifo_size[10], int,		   0444);

⌨️ 快捷键说明

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