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

📄 usb-ohci-omap1510.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************	linux/drivers/usb/usb-ohci-omap1510.c	USB OHCI Support for OMAP1510/1610	Author: MontaVista Software, Inc. <source@mvista.com>	Copyright (c) 2003 MontaVista Software, Inc.	The outline of this code was taken from Brad Parkers <brad@heeltoe.com>	original OHCI driver modifications, and reworked into a cleaner form	by Russell King <rmk@arm.linux.org.uk>.	This program is free software; you can redistribute it and/or	modify it under the terms of the GNU General Public License	as published by the Free Software Foundation; either version 2	of the License, or (at your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*******************************************************************************/#include <linux/module.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/ioport.h>#include <linux/interrupt.h>#include <linux/slab.h>#include <linux/pci.h>		/* for pci_pool_* prototypes */#include <linux/usb.h>#include <asm/hardware.h>#include <asm/irq.h>#include <asm/io.h>#include "usb-ohci.h"#ifdef CONFIG_OMAP_H2#include <linux/i2c.h>#define ISP1301_I2C_ADDR 0x2D#define ISP1301_I2C_MODE_CONTROL_1 0x4#define ISP1301_I2C_MODE_CONTROL_2 0x12#define ISP1301_I2C_OTG_CONTROL_1 0x6#define ISP1301_I2C_OTG_CONTROL_2 0x10#define ISP1301_I2C_INTERRUPT_SOURCE 0x8#define ISP1301_I2C_INTERRUPT_LATCH 0xA#define ISP1301_I2C_INTERRUPT_FALLING 0xC#define ISP1301_I2C_INTERRUPT_RISING 0xE#define ISP1301_I2C_REG_CLEAR_ADDR 1#endif#define OMAP1510_LB_OFFSET (0x30000000UL)#ifdef CONFIG_ARCH_OMAP1610#define OMAP1610_SET_FUNC_MUX_CTRL(mode,reg,bit) outl((inl(reg)&~(0x7<<bit))|(mode<<bit),reg)#define OMAP1610_CONFIRM_MUX_SETUP() outl(0xeaef,COMP_MODE_CTRL_0)#define open_drain(bit,reg) outl(inl(reg)|(1<<bit),reg)#endifextern int __devinit hc_add_ohci(struct pci_dev *dev, int irq, void *membase,				 unsigned long flags, ohci_t ** ohci,				 const char *name, const char *slot_name);extern void hc_remove_ohci(ohci_t * ohci);static ohci_t *omap1510_ohci;/* bogus pci_dev structure */static struct pci_dev bogus_pcidev;static int __devinit omap1510_ohci_configure(void);static void omap1510_ohci_release(void);#ifdef CONFIG_OMAP_H2static struct file *i2c_file;static struct i2c_client *omap_i2c_client;static int initstate_i2c;static int initstate_region;static inti2c_configure(void){	char filename[20];	int tmp;	if (initstate_i2c)		return 0;	/*find the I2C driver we need */	for (tmp = 0; tmp < I2C_ADAP_MAX; tmp++) {#ifdef CONFIG_DEVFS_FS		sprintf(filename, "/dev/i2c/%d", tmp);#else		sprintf(filename, "/dev/i2c-%d", tmp);#endif		if (!IS_ERR(i2c_file = filp_open(filename, O_RDWR, 0))) {			/*found some driver */			omap_i2c_client =			    (struct i2c_client *) i2c_file->private_data;			if (strlen(omap_i2c_client->adapter->name) >= 12) {				if (!memcmp				    (omap_i2c_client->adapter->name,				     "OMAP1610 I2C", 12))					break;	/*we found our driver! */			}			filp_close(i2c_file, NULL);		}	}	if (tmp == I2C_ADAP_MAX) {	/*no matching I2C driver found */		err("cannot find OMAP1610 I2C driver");		return -ENODEV;	}	initstate_i2c = 1;	return 0;}static voidi2c_close(void){	if (initstate_i2c)		filp_close(i2c_file, NULL);	initstate_i2c = 0;}#if 0static inti2c_read(u8 subaddr){	u8 buf = 0;	if (!i2c_configure()) {		omap_i2c_client->addr = ISP1301_I2C_ADDR;		i2c_master_send(omap_i2c_client, &subaddr, 1);		i2c_master_recv(omap_i2c_client, &buf, 1);	}	return buf;}#endifstatic inti2c_write(u8 buf, u8 subaddr){	char tmpbuf[2];	if (!i2c_configure()) {		omap_i2c_client->addr = ISP1301_I2C_ADDR;		tmpbuf[0] = subaddr;	/*register number */		tmpbuf[1] = buf;	/*register data */		i2c_master_send(omap_i2c_client, &tmpbuf[0], 2);	}	return 0;}static voidisp1301_configure(void){	i2c_write(6, ISP1301_I2C_MODE_CONTROL_1);	i2c_write(~6, ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR);	i2c_write(4, ISP1301_I2C_MODE_CONTROL_2);	i2c_write(~4, ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR);	i2c_write(0xC, ISP1301_I2C_OTG_CONTROL_1);	i2c_write(~0xC, ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR);	i2c_write(0xFF,		  ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR);	i2c_write(0xFF,		  ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR);	i2c_write(0xFF,		  ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR);}#endif#if	defined(CONFIG_OMAP_INNOVATOR)	/* MVL-CEE */#include <linux/device.h>static int omap1510_ohci_suspend(struct device *dev, u32 state, u32 level);static int omap1510_ohci_resume(struct device *dev, u32 level);static int omap1510_ohci_scale(struct bus_op_point *op, u32 level);static int omap1510_ohci_pid;static DECLARE_COMPLETION(kusbdpmd);static int omap1510_usbpmd_req;static wait_queue_head_t kusbdpmd_wait;static struct device_driver omap1510_ohci_driver_ldm = {	.name = "omap1510/1610-ohci",	.devclass = NULL,	.probe = NULL,	.suspend = omap1510_ohci_suspend,	.resume = omap1510_ohci_resume,	.scale = omap1510_ohci_scale,	.remove = NULL,	.constraints = NULL,};static struct device omap1510_ohci_device_ldm = {	.name = "OMAP1510/1610 OHCI",	.bus_id = "OHCI",	.driver = NULL,	.power_state = DPM_POWER_ON,};static intomap1510_ohci_thread(void){	int ret;	struct task_struct *tsk = current;	/*	 * We don't want /any/ signals, not even SIGKILL	 */	sigfillset(&tsk->blocked);	sigemptyset(&tsk->pending.signal);	recalc_sigpending(tsk);	daemonize();	reparent_to_init();	strcpy(tsk->comm, "kusbdpmd");	tsk->tty = NULL;	while (1) {		int req;		do {			req = xchg(&omap1510_usbpmd_req, 0);			if (req == 0) {				sigemptyset(&tsk->pending.signal);				interruptible_sleep_on(&kusbdpmd_wait);			}		} while (req == 0);		if (req == SIGTERM) {			break;		} else if (req == SIGHUP) {			ret = omap1510_ohci_configure();			complete(&kusbdpmd);		} else {			printk(KERN_DEBUG "%s: Unknown Request: %d\n",			       __FUNCTION__, req);		}	}	complete_and_exit(&kusbdpmd, 0);}static voidomap1510_ohci_ldm_driver_register(void){	extern void mpu_public_driver_register(struct device_driver *driver);	mpu_public_driver_register(&omap1510_ohci_driver_ldm);}static voidomap1510_ohci_ldm_device_register(void){	extern void mpu_public_device_register(struct device *device);	mpu_public_device_register(&omap1510_ohci_device_ldm);}static voidomap1510_ohci_ldm_driver_unregister(void){	extern void mpu_public_driver_unregister(struct device_driver *driver);	mpu_public_driver_unregister(&omap1510_ohci_driver_ldm);}static voidomap1510_ohci_ldm_device_unregister(void){	extern void mpu_public_device_unregister(struct device *device);	mpu_public_device_unregister(&omap1510_ohci_device_ldm);}static intomap1510_ohci_scale(struct bus_op_point *op, u32 level){	/* REVISIT */	return 0;}static intomap1510_ohci_suspend(struct device *dev, u32 state, u32 level){	switch (level) {	case SUSPEND_POWER_DOWN:		omap1510_ohci_release();		break;	}	return 0;}static intomap1510_ohci_resume(struct device *dev, u32 level){	int ret = 0;	switch (level) {	case RESUME_POWER_ON:			/* Wake up thread for reinit. */		init_completion(&kusbdpmd);		omap1510_usbpmd_req = SIGHUP;		wake_up(&kusbdpmd_wait);		break;	}	return ret;}#endif				/* MVL-CEE */static int __devinitomap1510_ohci_configure(void){#ifndef CONFIG_ARCH_OMAP1610	/* TO DO:  make a proper header file for all of these registers. */#ifdef CONFIG_OMAP_INNOVATOR	volatile unsigned char *fpga_usb_host_ctrl =	    (unsigned char *) 0xe800020c;#endif	volatile unsigned short *apll_ctrl_reg = (unsigned short *) 0xfffe084c;	volatile unsigned short *dpll_ctrl_reg = (unsigned short *) 0xfffe083c;	volatile unsigned short *soft_req_reg = (unsigned short *) 0xfffe0834;	volatile unsigned short *clock_ctrl_reg = (unsigned short *) 0xfffe0830;	volatile unsigned long *mod_conf_ctrl_0 = (unsigned long *) 0xfffe1080;	volatile unsigned long *lb_clock_div = (unsigned long *) 0xfffec10c;	volatile unsigned short *lb_mmu_cntl_reg =	    (unsigned short *) 0xfffec208;	volatile unsigned short *lb_mmu_lock_reg =	    (unsigned short *) 0xfffec224;	volatile unsigned short *lb_mmu_ld_tlb_reg =	    (unsigned short *) 0xfffec228;	volatile unsigned short *lb_mmu_cam_h_reg =	    (unsigned short *) 0xfffec22c;	volatile unsigned short *lb_mmu_cam_l_reg =	    (unsigned short *) 0xfffec230;	volatile unsigned short *lb_mmu_ram_h_reg =	    (unsigned short *) 0xfffec234;	volatile unsigned short *lb_mmu_ram_l_reg =

⌨️ 快捷键说明

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