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

📄 dwc_otg_driver.c

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ========================================================================== * * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless * otherwise expressly agreed to in writing between Synopsys and you. * * The Software IS NOT an item of Licensed Software or Licensed Product under * any End User Software License Agreement or Agreement for Licensed Product * with Synopsys or any supplement thereto. You are permitted to use and * redistribute this Software in source and binary forms, with or without * modification, provided that redistributions of source code must retain this * notice. You may not view, use, disclose, copy or distribute this file or * any information contained herein except pursuant to this license grant from * Synopsys. If you do not agree with this notice, including the disclaimer * below, then you are not authorized to use the Software. * * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * ========================================================================== *//** @file * The dwc_otg_driver module provides the initialization and cleanup entry * points for the DWC_otg driver. This module will be dynamically installed * after Linux is booted using the insmod command. When the module is * installed, the dwc_otg_driver_init function is called. When the module is * removed (using rmmod), the dwc_otg_driver_cleanup function is called. * * This module also defines a data structure for the dwc_otg_driver, which is * used in conjunction with the standard ARM lm_device structure. These * structures allow the OTG driver to comply with the standard Linux driver * model in which devices and drivers are registered with a bus driver. This * has the benefit that Linux can expose attributes of the driver and device * in its special sysfs file system. Users can then read or write files in * this file system to perform diagnostics on the driver components or the * device. */#include <linux/kernel.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/device.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/stat.h>		/* permission constants */#include <linux/version.h>#include <linux/platform_device.h>#include <linux/clk.h>#include <linux/proc_fs.h>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)# include <linux/irq.h>#endif#include <asm/io.h>#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)# include <asm/irq.h>#endif#include <asm/sizes.h>#include <asm/arch/regs-s3c6400-clock.h>#include "dwc_otg_plat.h"#include "dwc_otg_attr.h"#include "dwc_otg_driver.h"#include "dwc_otg_cil.h"#include "dwc_otg_pcd.h"#include "dwc_otg_hcd.h"#define DWC_DRIVER_VERSION	"2.70a 22-AUG-2007"#define DWC_DRIVER_DESC		"HS OTG USB Controller driver"static const char dwc_driver_name[] = "dwc_otg";/*-------------------------------------------------------------------------*//* Encapsulate the module parameter settings */static dwc_otg_core_params_t dwc_otg_module_params = {	.opt = -1,	.otg_cap = -1,	.dma_enable = -1,	.dma_desc_enable = -1,	.dma_burst_size = -1,	.speed = -1,	.host_support_fs_ls_low_power = -1,	.host_ls_low_power_phy_clk = -1,	.enable_dynamic_fifo = -1,	.data_fifo_size = -1,	.dev_rx_fifo_size = -1,	.dev_nperio_tx_fifo_size = -1,	.dev_perio_tx_fifo_size = {	/* dev_perio_tx_fifo_size_1 */				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1,				   -1},	/* 15 */	.host_rx_fifo_size = -1,	.host_nperio_tx_fifo_size = -1,	.host_perio_tx_fifo_size = -1,	.max_transfer_size = -1,	.max_packet_count = -1,	.host_channels = -1,	.dev_endpoints = -1,	.phy_type = -1,	.phy_utmi_width = -1,	.phy_ulpi_ddr = -1,	.phy_ulpi_ext_vbus = -1,	.i2c_enable = -1,	.ulpi_fs_ls = -1,	.ts_dline = -1,	.en_multiple_tx_fifo = -1,	.dev_tx_fifo_size = {	/* dev_tx_fifo_size */			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1,			     -1},	/* 15 */	.thr_ctl = -1,	.tx_thr_length = -1,	.rx_thr_length = -1,};#if 0/** * This function shows the Driver Version. */static ssize_t version_show(struct device_driver *dev, char *buf){	return snprintf(buf, sizeof(DWC_DRIVER_VERSION) + 2, "%s\n", DWC_DRIVER_VERSION);}static DRIVER_ATTR(version, S_IRUGO, version_show, NULL);#endif/** * Global Debug Level Mask. */uint32_t g_dbg_lvl = 0;		/* OFF */#if 0/** * This function shows the driver Debug Level. */static ssize_t dbg_level_show(struct device_driver *_drv, char *_buf){	return sprintf(_buf, "0x%0x\n", g_dbg_lvl);}/** * This function stores the driver Debug Level. */static ssize_t dbg_level_store(struct device_driver *_drv, const char *_buf, size_t _count){	g_dbg_lvl = simple_strtoul(_buf, NULL, 16);	return _count;}static DRIVER_ATTR(debuglevel, S_IRUGO | S_IWUSR, dbg_level_show, dbg_level_store);#endif/** * This function is called during module intialization to verify that * the module parameters are in a valid state. */static int check_parameters(dwc_otg_core_if_t * core_if){	int i;	int retval = 0;/* Checks if the parameter is outside of its valid range of values */#define DWC_OTG_PARAM_TEST(_param_,_low_,_high_) \		((dwc_otg_module_params._param_ < (_low_)) || \		(dwc_otg_module_params._param_ > (_high_)))/* If the parameter has been set by the user, check that the parameter value is * within the value range of values.  If not, report a module error. */#define DWC_OTG_PARAM_ERR(_param_,_low_,_high_,_string_) \		do { \			if (dwc_otg_module_params._param_ != -1) { \				if (DWC_OTG_PARAM_TEST(_param_,(_low_),(_high_))) { \					DWC_ERROR("`%d' invalid for parameter `%s'\n", \						dwc_otg_module_params._param_, _string_); \					dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \					retval ++; \				} \			} \		} while (0)	DWC_OTG_PARAM_ERR(opt, 0, 1, "opt");	DWC_OTG_PARAM_ERR(otg_cap, 0, 2, "otg_cap");	DWC_OTG_PARAM_ERR(dma_enable, 0, 1, "dma_enable");	DWC_OTG_PARAM_ERR(dma_desc_enable, 0, 1, "dma_desc_enable");	DWC_OTG_PARAM_ERR(speed, 0, 1, "speed");	DWC_OTG_PARAM_ERR(host_support_fs_ls_low_power, 0, 1, "host_support_fs_ls_low_power");	DWC_OTG_PARAM_ERR(host_ls_low_power_phy_clk, 0, 1, "host_ls_low_power_phy_clk");	DWC_OTG_PARAM_ERR(enable_dynamic_fifo, 0, 1, "enable_dynamic_fifo");	DWC_OTG_PARAM_ERR(data_fifo_size, 32, 32768, "data_fifo_size");	DWC_OTG_PARAM_ERR(dev_rx_fifo_size, 16, 32768, "dev_rx_fifo_size");	DWC_OTG_PARAM_ERR(dev_nperio_tx_fifo_size, 16, 32768, "dev_nperio_tx_fifo_size");	DWC_OTG_PARAM_ERR(host_rx_fifo_size, 16, 32768, "host_rx_fifo_size");	DWC_OTG_PARAM_ERR(host_nperio_tx_fifo_size, 16, 32768, "host_nperio_tx_fifo_size");	DWC_OTG_PARAM_ERR(host_perio_tx_fifo_size, 16, 32768, "host_perio_tx_fifo_size");	DWC_OTG_PARAM_ERR(max_transfer_size, 2047, 524288, "max_transfer_size");	DWC_OTG_PARAM_ERR(max_packet_count, 15, 511, "max_packet_count");	DWC_OTG_PARAM_ERR(host_channels, 1, 16, "host_channels");	DWC_OTG_PARAM_ERR(dev_endpoints, 1, 15, "dev_endpoints");	DWC_OTG_PARAM_ERR(phy_type, 0, 2, "phy_type");	DWC_OTG_PARAM_ERR(phy_ulpi_ddr, 0, 1, "phy_ulpi_ddr");	DWC_OTG_PARAM_ERR(phy_ulpi_ext_vbus, 0, 1, "phy_ulpi_ext_vbus");	DWC_OTG_PARAM_ERR(i2c_enable, 0, 1, "i2c_enable");	DWC_OTG_PARAM_ERR(ulpi_fs_ls, 0, 1, "ulpi_fs_ls");	DWC_OTG_PARAM_ERR(ts_dline, 0, 1, "ts_dline");	if (dwc_otg_module_params.dma_burst_size != -1) {		if (DWC_OTG_PARAM_TEST(dma_burst_size, 1, 1) &&		    DWC_OTG_PARAM_TEST(dma_burst_size, 4, 4) &&		    DWC_OTG_PARAM_TEST(dma_burst_size, 8, 8) &&		    DWC_OTG_PARAM_TEST(dma_burst_size, 16, 16) &&		    DWC_OTG_PARAM_TEST(dma_burst_size, 32, 32) &&		    DWC_OTG_PARAM_TEST(dma_burst_size, 64, 64) &&		    DWC_OTG_PARAM_TEST(dma_burst_size, 128, 128) &&		    DWC_OTG_PARAM_TEST(dma_burst_size, 256, 256)) {			DWC_ERROR("`%d' invalid for parameter `dma_burst_size'\n",				  dwc_otg_module_params.dma_burst_size);			dwc_otg_module_params.dma_burst_size = 32;			retval++;		}	}	if (dwc_otg_module_params.phy_utmi_width != -1) {		if (DWC_OTG_PARAM_TEST(phy_utmi_width, 8, 8) &&		    DWC_OTG_PARAM_TEST(phy_utmi_width, 16, 16)) {			DWC_ERROR("`%d' invalid for parameter `phy_utmi_width'\n",				  dwc_otg_module_params.phy_utmi_width);			dwc_otg_module_params.phy_utmi_width = 16;			retval++;		}	}	for (i = 0; i < 15; i++) {		/** @todo should be like above */		//DWC_OTG_PARAM_ERR(dev_perio_tx_fifo_size[i],4,768,"dev_perio_tx_fifo_size");		if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -1) {			if (DWC_OTG_PARAM_TEST(dev_perio_tx_fifo_size[i], 4, 768)) {				DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",					  dwc_otg_module_params.dev_perio_tx_fifo_size[i],					  "dev_perio_tx_fifo_size", i);				dwc_otg_module_params.dev_perio_tx_fifo_size[i] =					dwc_param_dev_perio_tx_fifo_size_default;				retval++;			}		}	}	DWC_OTG_PARAM_ERR(en_multiple_tx_fifo, 0, 1, "en_multiple_tx_fifo");	for (i = 0; i < 15; i++) {		/** @todo should be like above */		//DWC_OTG_PARAM_ERR(dev_tx_fifo_size[i],4,768,"dev_tx_fifo_size");		if (dwc_otg_module_params.dev_tx_fifo_size[i] != -1) {			if (DWC_OTG_PARAM_TEST(dev_tx_fifo_size[i], 4, 768)) {				DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",					  dwc_otg_module_params.dev_tx_fifo_size[i],					  "dev_tx_fifo_size", i);				dwc_otg_module_params.dev_tx_fifo_size[i] =					dwc_param_dev_tx_fifo_size_default;				retval++;			}		}	}	DWC_OTG_PARAM_ERR(thr_ctl, 0, 7, "thr_ctl");	DWC_OTG_PARAM_ERR(tx_thr_length, 8, 128, "tx_thr_length");	DWC_OTG_PARAM_ERR(rx_thr_length, 8, 128, "rx_thr_length");	/* At this point, all module parameters that have been set by the user	 * are valid, and those that have not are left unset.  Now set their	 * default values and/or check the parameters against the hardware	 * configurations of the OTG core. *//* This sets the parameter to the default value if it has not been set by the * user */#define DWC_OTG_PARAM_SET_DEFAULT(_param_) \	({ \		int changed = 1; \		if (dwc_otg_module_params._param_ == -1) { \			changed = 0; \			dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \		} \		changed; \	})/* This checks the macro agains the hardware configuration to see if it is * valid.  It is possible that the default value could be invalid.	In this * case, it will report a module error if the user touched the parameter. * Otherwise it will adjust the value without any error. */#define DWC_OTG_PARAM_CHECK_VALID(_param_,_str_,_is_valid_,_set_valid_) \	({ \			int changed = DWC_OTG_PARAM_SET_DEFAULT(_param_); \		int error = 0; \		if (!(_is_valid_)) { \			if (changed) { \				DWC_ERROR("`%d' invalid for parameter `%s'.	 Check HW configuration.\n", dwc_otg_module_params._param_,_str_); \				error = 1; \			} \			dwc_otg_module_params._param_ = (_set_valid_); \		} \		error; \	})	/* OTG Cap */	retval += DWC_OTG_PARAM_CHECK_VALID(otg_cap, "otg_cap", ( {								 int valid;								 valid = 1;

⌨️ 快捷键说明

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