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

📄 usb_otg.c

📁 philips公司ISP1362 USB OTG控制芯片的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * Now copy the results to the status */
		if(*result == 0) {
			dev->status.status_code = OTG_STATUS_ENUM_SUCCESS;
		} else {
			dev->status.status_code = OTG_STATUS_ENUM_FAILED;
			tcb->AllowStateChange = 1;
			tcb->bus_req = 0;
		}
		usb_otgdev_async_notif(dev);
	} else if(tcb->id == 1) {

		/* Bus request was cancelled, but we are
		 * waiting to finish HNP sequnce */
//		if(tcb->b_host_pending == 1) 
			tcb->AllowStateChange = 1;
	}

	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;
			otgdev->status.state = otgdev->fsm_data.tcb.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_enum_result = otgfsm_usb_notif;
		hc_otg_data.otg_new_device = usb_otg_new_device;

		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) {
					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;

	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) 
{
	int	result;

	func_debug(("usb_otg_module_init(void)\n"))

	result =  isp1362_register_driver(&usb_otg_driver);

	if(result == 0) {
		isp1362_printk(KERN_INFO __FILE__ ": %s Initialization Success \n",usb_otg_driver.name);
	} else {
		isp1362_printk(KERN_INFO __FILE__ ": %s Iinitialization Failed (error = %d)\n",usb_otg_driver.name,result);
	}

	return  result;
}

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 + -