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

📄 usb_otg.c

📁 linux下的usb开发
💻 C
字号:
/******************************************************* * Philips OTG (On The Go) Driver for USB. * * (c) 2002 Koninklijke Philips Electronics N.V., All rights reserved *  * This  source code and any compilation or derivative thereof is the * proprietary information of Koninklijke Philips Electronics N.V. * and is confidential in nature. * Under no circumstances is this software to be exposed to or placed * under an Open Source License of any type without the expressed * written permission of Koninklijke Philips Electronics N.V. * * File Name:	usb_otg.c * * History:	 * *	Version	Date		Author		Comments * ------------------------------------------------- * 	1.0		09/23/02	SYARRA		Initial Creation * *******************************************************/ #include <linux/config.h>#define MODULE#include <linux/module.h>#include <linux/pci.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/devfs_fs_kernel.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/timer.h>#include <linux/list.h>#include <linux/interrupt.h>  /* for in_interrupt() */#undef DEBUG#include <linux/usb.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/unaligned.h>#include <asm/uaccess.h>#include "linux/usb.h"#include "pdc_intf.h"#include "usb_phci.h"#include "usb_otg.h"/* Internal functional declerations */int	usb_otgdev_open( struct inode *inode, struct file *fp);int	usb_otgdev_close( struct inode *inode, struct file *fp);int usb_otgdev_fasync( int	fd, struct file *fp, int mode);int	usb_otgdev_ioctl(struct inode *inode, struct file *fp, 					unsigned int	cmd, unsigned long arg);//void usb_otgdev_async_notif(usb_otgdev_t	*otgdev);usb_otgdev_t		*usb_otgdev;phci_otg_data_t		hc_otg_data;pdc_otg_data_t		dc_otg_data;/*-------------------------------------------------------------------------* * OTG FSM related functions * ------------------------------------------------------------------------*//*-------------------------------------------------------------------------* * process Device Controller Notification on behalf of OTG FSM * ------------------------------------------------------------------------*/void	otgfsm_pdc_notif(void *priv, unsigned long notif, unsigned long data) {	usb_otgdev_t	*dev = (usb_otgdev_t*)priv;	otg_tcb_t		*tcb = &(dev->fsm_data.tcb);	func_debug(("otgfsm_pdc_notif(priv=%p,notif=%d,data=%x)\n",priv,notif,data))	switch(notif) {		case PDC_SUSPEND:			if(tcb->id == 0) {				tcb->b_bus_suspend = 1;			} else if(tcb->id == 1){				tcb->a_bus_suspend = 1;			}		break;		case PDC_RESET:			tcb->b_hnp_en = 0;			tcb->a_hnp_support = 0;			tcb->a_alt_hnp_support = 0;		case PDC_RESUME:			if(tcb->id == 0) {				tcb->b_bus_suspend = 0;			} else if(tcb->id == 1){				tcb->a_bus_suspend = 0;			}		break;		case PDC_SET_HNP:			if(data == USB_OTG_FS_HNP_ENABLE) {				tcb->b_hnp_en = 1;			} else if ( data == USB_OTG_FS_HNP_SUPPORT) {				tcb->a_hnp_support = 1;			} else if ( data == USB_OTG_FS_ALT_HNP_SUPPORT) {				tcb->a_alt_hnp_support = 1;			}		break;	}	otgfsm_run(&(dev->fsm_data));}/*-------------------------------------------------------------------------* * process USB core Notification on behalf of OTG FSM * ------------------------------------------------------------------------*/void	otgfsm_usb_notif(void *priv) {	__u32			data;	func_debug(("otgfsm_usb_notif(priv=%p)\n",priv))	usb_otgdev_t	*dev = (usb_otgdev_t*)priv;	otg_tcb_t		*tcb = &(dev->fsm_data.tcb);	phci_otg_port_control(dev->fsm_data.hcd_priv, OTG_PORT_GET_ENUM, &data);	if(tcb->id == 0) {		/* A device, results of HNP protocol */		tcb->a_set_b_hnp_en = (data & USB_OTG_HNP_ENABLED) ? 1 : 0;		tcb->b_hnp_support = (data & USB_OTG_HNP_ENABLED) ? 1 : 0;		tcb->b_srp_support = (data & USB_OTG_HNP_ENABLED) ? 1 : 0;		if(tcb->a_set_b_hnp_en == 1) {			/* If HNP is enabled on B device, allow it to become Host 			 * when necessary */			tcb->AllowStateChange = 1;		}	}	if(tcb->bus_req == 1) {		/* There is a request for the Device to get enumerated		 * Now copy the results to the status */		if((data & USB_OTG_DEV_ENUMERATED)) {			dev->status.status_code = OTG_STATUS_ENUM_SUCCESS;		} else {			printk("Enumeration failed\n");			dev->status.status_code = OTG_STATUS_ENUM_FAILED;		}		usb_otgdev_async_notif(dev);	}	otgfsm_run(&(dev->fsm_data));}/*-------------------------------------------------------------------------* * process Host Controller ISR on behalf of OTG FSM * ------------------------------------------------------------------------*/void usb_otg_isr(struct isp1362_dev *dev, void *isr_data) {	otg_fsm_t	*fsm_data = &(((usb_otgdev_t*)isr_data)->fsm_data);	func_debug(("usb_otg_isr(dev=%p,isr_data=%p)\n",dev,isr_data))		fsm_data->regs.int_port.data = dev->int_reg;		otgfsm_run(fsm_data);}/*-------------------------------------------------------------------------* * OTG virtual device file related functions * ------------------------------------------------------------------------*//* Device file operations */static struct file_operations usb_otgdev_fops = {	owner:		THIS_MODULE,	read:		NULL,	write:		NULL,	poll:		NULL,	ioctl:		usb_otgdev_ioctl,	open:		usb_otgdev_open,	release:	usb_otgdev_close,	fasync:		usb_otgdev_fasync,};int	usb_otgdev_open( struct inode *inode, struct file *fp) {		func_debug(("usb_otgdev_open(inode=%p,fp=%p)\n",inode,fp))	fp->private_data = usb_otgdev;		/* set the OTG controller data in file */	MOD_INC_USE_COUNT;					/* Increment the module count */	return 0;}int	usb_otgdev_close( struct inode *inode, struct file *fp) {	func_debug(("usb_otgdev_close(inode=%p,fp=%p)\n",inode,fp))		MOD_DEC_USE_COUNT;					/* Decrement module count */	usb_otgdev_fasync(-1,fp, 0);		/* cancel asynchronous notification to application */	return 0;}int usb_otgdev_fasync( int	fd, struct file *fp, int mode) {	usb_otgdev_t	*otgdev = (usb_otgdev_t*)fp->private_data;	func_debug(("usb_otgdev_fasync(fd=%d,fp=%p,mode=%d)\n",fd,fp,mode))	return fasync_helper(fd, fp, mode, &otgdev->fasync_q);}int	usb_otgdev_ioctl(struct inode *inode, struct file *fp, 					unsigned int	cmd, unsigned long arg) {	func_debug(("usb_otgdev_ioctl(inode=%p,fp=%p,cmd=%d,arg=%x)\n",inode,fp,cmd,arg))	usb_otgdev_t	*otgdev = (usb_otgdev_t*)fp->private_data;	int				ret = 0;	switch(cmd) {		case OTG_IOC_GET_STATE:									/* Get OTG sw FSM State */			/* Copy the status information from driver to user space */			otgdev->status.id = otgdev->fsm_data.tcb.id;			otgdev->status.state = otgdev->fsm_data.tcb.app_state;			if(otgdev->status.status_code == OTG_STATUS_NONE) {				otgdev->status.status_code = otgdev->fsm_data.tcb.err_code;			}			copy_to_user((usb_otg_info_t *)arg, &otgdev->status, sizeof(usb_otg_info_t));		break;		case OTG_IOC_SET_STATE:						/* Set OTG sw FSM State */			copy_from_user(&otgdev->status, (usb_otg_info_t *)arg, sizeof(usb_otg_info_t));			otgdev->status.status_code = OTG_STATUS_NONE;			otgfsm_set_state(&(otgdev->fsm_data), otgdev->status.state); //			otgfsm_run(&(otgdev->fsm_data));		break;	}	return ret;}/*------------------------------------------------------------------------- *  * -----------------------------------------------------------------------*/void usb_otgdev_async_notif(usb_otgdev_t	*otgdev){	func_debug(("usb_otgdev_async_notif(otgdev=%p)\n",otgdev))		if(otgdev->fasync_q) {		kill_fasync( &otgdev->fasync_q, SIGIO, POLL_IN);	}}static int usb_otg_probe (struct isp1362_dev	*dev);static void usb_otg_remove (struct isp1362_dev	*dev);struct isp1362_driver	usb_otg_driver = {	name:		"usb-otg",	index:		ISP1362_OTG,	probe:		usb_otg_probe,	remove:		usb_otg_remove,};/*------------------------------------------------------------------------- * OTG module init function * -----------------------------------------------------------------------*/static int usb_otg_probe (struct isp1362_dev	*dev) {	int	result = 0;	func_debug(("usb_otg_probe(dev=%p)\n",dev))		result = isp1362_check_io_region(dev);	if(result < 0) {		detail_debug(("%s: IO resources are busy\n",usb_otg_driver.name))		return result;	}	isp1362_request_io_region(dev);		usb_otgdev = kmalloc(sizeof(usb_otgdev_t), GFP_KERNEL);		if(usb_otgdev) {		memset(usb_otgdev, 0, sizeof(usb_otgdev_t));		dev->driver_data = usb_otgdev;		usb_otgdev->fsm_data.dev = dev;		/* Initialize the OTG FSM state to invalid state */		otgfsm_init(&(usb_otgdev->fsm_data));		hc_otg_data.priv_data = (void*)usb_otgdev;		hc_otg_data.otg_notif = otgfsm_usb_notif;		dc_otg_data.priv_data = (void*)usb_otgdev;		dc_otg_data.otg_notif = otgfsm_pdc_notif;		result = pdc_otg_register(&dc_otg_data);		result = phci_register_otg(&hc_otg_data);		if(result == 0) {			usb_otgdev->fsm_data.hcd_priv = hc_otg_data.hc_priv_data;			usb_otgdev->fsm_data.usb_otg_data = usb_otgdev;			otgfsm_status_probe(&(usb_otgdev->fsm_data));			/* Register the OTG driver to device file system so appliation 	 		* can access this driver */			result = devfs_register_chrdev(USB_OTG_MAJOR,										USB_OTG_MODULE_NAME,										&usb_otgdev_fops);			if(result == 0) {				result=isp1362_request_irq(usb_otg_isr,dev,usb_otgdev);				if(result == 0) {					info(DRIVER_DESC " Ver" USB_OTG_VERSION " Initialization Successful\n");					return result;				}				devfs_unregister_chrdev(USB_OTG_MAJOR,USB_OTG_MODULE_NAME);			}			pdc_otg_unregister(&dc_otg_data);			dc_otg_data.priv_data = NULL;			hc_otg_data.priv_data = NULL;			kfree(usb_otgdev);		}		usb_otgdev->fsm_data.dev = NULL;	}	result = -ENOMEM;	isp1362_release_io_region(dev);	dev->driver_data = NULL;	info(DRIVER_DESC " Ver" USB_OTG_VERSION " Initialization Falied\n");	return result;} /* End of usb_otg_probe *//*------------------------------------------------------------------------- * OTG module clean up function * -----------------------------------------------------------------------*/static void usb_otg_remove (struct isp1362_dev	*dev) {	func_debug(("usb_otg_remove(dev=%p)\n",dev))	otgfsm_deinit(&(usb_otgdev->fsm_data));	isp1362_free_irq(dev, dev->driver_data);	/* De register from the device file system */	devfs_unregister_chrdev(USB_OTG_MAJOR,USB_OTG_MODULE_NAME);	phci_unregister_otg(&hc_otg_data);	hc_otg_data.priv_data = NULL;	pdc_otg_unregister(&dc_otg_data);	dc_otg_data.priv_data = NULL;	kfree(dev->driver_data);	dev->driver_data = NULL;	isp1362_release_io_region(dev);} /* End of usb_otg_remove */static int __init usb_otg_module_init (void) {	func_debug(("usb_otg_module_init(void)\n"))	return isp1362_register_driver(&usb_otg_driver);}static void __exit usb_otg_module_cleanup (void) {	func_debug(("usb_otg_module_cleanup(void)\n"))	return isp1362_unregister_driver(&usb_otg_driver);}module_init (usb_otg_module_init);module_exit (usb_otg_module_cleanup);MODULE_AUTHOR (DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);

⌨️ 快捷键说明

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