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

📄 usb_otg.c

📁 philips公司ISP1362 USB OTG控制芯片的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************
 * 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
 *	1.10	04/10/03	SYARRA		OTG1.0A changes
 *	1.21	08/04/03	SYARRA		OPT1.2 compliance
 *******************************************************/
 
#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;

/*-------------------------------------------------------------------------*
 * USB CORE stuff (related to OTG)
 * These functions execute under the context of HUB enumeration
 * OTG1.0A changes:	moved some stuff from usbcore to here. Added unsupported device
 * 					support
 * ------------------------------------------------------------------------*/


static	int	usb_otg_new_device(void	*priv, struct usb_device *dev);

struct usb_device_id	otg_target_peripheral[] = isp1362_targeted_peripheral;


int	usb_otg_is_targeted_peripheral(struct usb_device *dev) {

	int	matched = 0;

	if(dev->descriptor.idVendor == USB_OTG_UNSUP_VEND_ID) return matched;

#if 0
	for(i = 0; i<count; i++) {

		switch(otg_target_peripheral[i].match_flags) {

			case USB_DEVICE_ID_MATCH_DEVICE:

				if((dev->descriptor.idVendor == otg_target_peripheral[i].idVendor) && 
				   (dev->descriptor.idProduct == otg_target_peripheral[i].idProduct)) {
						matched = 1;
				}

				break;
		}

	}
#else
	matched = 1;
#endif

	return matched;
}

int	usb_otg_new_device(void *priv, struct usb_device *dev) {

	char	*buffer = dev->rawdescriptors[0];
	struct 	usb_descriptor_header *header;
	struct 	usb_otg_descriptor *otg_desc;
	int		size;
	usb_otgdev_t	*otg_dev = (usb_otgdev_t*)priv;
	otg_tcb_t		*tcb = &(otg_dev->fsm_data.tcb);

	int		result = 0, supported = 0;
	__u8	feature;

	supported = usb_otg_is_targeted_peripheral(dev);

	if(!supported) {
		isp1362_kernel_user_mesg("Connected device is not supported");
	}
	/* Set OTG enable for the root hub port OTG devices */
	if((dev->parent) && (dev->parent == dev->bus->root_hub)) {

		/* If OTG capable, OTG descriptor is present in all configurations
		 * So let us dig first configuration */
		if(buffer && (tcb->id == 0)) {

			/* This has already been parsed by the get_configuration fn */
			size = dev->config[0].wTotalLength;

			while (size >= sizeof(struct usb_descriptor_header)) {
				header = (struct usb_descriptor_header *)buffer;

				/* Check for OTG descriptor presence */
				if (header->bDescriptorType == USB_DT_OTG) {

					otg_desc = (struct usb_otg_descriptor *)buffer;	

					if(otg_desc->bLength == USB_DT_OTG_SIZE) {
						/* Copy OTG attributes */

						tcb->b_hnp_support = (otg_desc->bmAttributes & USB_OTG_HNP_SUPPORT) ? 1 : 0;
						tcb->b_srp_support = (otg_desc->bmAttributes & USB_OTG_SRP_SUPPORT) ? 1 : 0;

						if(tcb->b_hnp_support == 1) {
							/* OTG feature is available on other port, this is normal USB port */
							if(dev->parent->children[OTG_HC_PORT_NO] == dev) {
								/* This port supports OTG */
								feature = USB_OTG_FS_HNP_ENABLE;
								result = otg_hub_set_otg_feature(dev, feature);
								if(result >= 0) {
									tcb->a_set_b_hnp_en = 1;
									tcb->AllowStateChange = 1;
								} else {
									isp1362_kernel_user_mesg("Connected device is not supported");
									tcb->a_set_b_hnp_en = 0;
									tcb->AllowStateChange = 0;
									result = -1;
								}
							} else {
								/* OTG support is on the other port */
								feature =  USB_OTG_FS_ALT_HNP_SUPPORT; 
								otg_hub_set_otg_feature(dev, feature);
						 	}
						}
					} else {
						/* Problem in OTG descriptor */
						/* Fail enumeration */
						result =  -1;
					}
					break;
				}
	
				buffer += header->bLength;
				size -= header->bLength;
			}
			/* If there is no bus request on the OTG port, this must be due to an SRP, so no need to 
			 * enumerate further. So fail the enumeration */
			if((dev->parent->children[OTG_HC_PORT_NO] == dev) && (tcb->bus_req == 0)) {

				if(header->bDescriptorType != USB_DT_OTG) {
					/* B device is SRP capable but doesn't give any OTG descriptor ??? Inform the User */
					isp1362_kernel_user_mesg("Connected device is not supported");
				}
				result = -1;
			}
		}
	}

	/* If not a supported device & not a root hub  fail it */
	if((dev->parent) && (!supported))	return -1;

	return result;
}


/*-------------------------------------------------------------------------*
 * 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_BUSTATUS:

			/*Just update the variables of suspend */
			/* If you run the FSM it might cause looping
			 * otg->dev->otg->dev........ */
			if(tcb->id == 0) {
				tcb->b_bus_suspend = 1;
			} else if(tcb->id == 1){
				tcb->a_bus_suspend = 1;
			}
			return;
			break;

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

	if(tcb->bus_req == 1) {
		/* There is a request for the Device to get enumerated

⌨️ 快捷键说明

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