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

📄 3332 驱动源码.c

📁 SL811HS控制器驱动基于三星4510b的处理器
💻 C
📖 第 1 页 / 共 3 页
字号:

/*****************************************************************
 *
 * Function Name: getPortStatusAndChange
 *
 * This function gets the ports status from SL811 and format it 
 * to a USB request format
 *
 * Input:  hci = data structure for the host controller
 *
 * Return value  : port status and change
 *                
 *****************************************************************/
static __u32 getPortStatusAndChange (hci_t * hci)
{
	hcipriv_t *hp = &hci->hp;
	__u32 portstatus;

	DBGFUNC ("enter getPorStatusAndChange\n");

	portstatus = hp->RHportStatus->portChange << 16 | hp->RHportStatus->portStatus;

	return (portstatus);
}

/*****************************************************************
 *
 * Function Name: setPortChange
 *
 * This function set the bit position of portChange.
 *
 * Input:  hci = data structure for the host controller
 *         bitPos = the bit position
 *
 * Return value  : none 
 *                
 *****************************************************************/
static void setPortChange (hci_t * hci, __u16 bitPos)
{
	hcipriv_t *hp = &hci->hp;

	switch (bitPos) {
	case PORT_CONNECT_STAT:
		hp->RHportStatus->portChange |= bitPos;
		break;

	case PORT_ENABLE_STAT:
		hp->RHportStatus->portChange |= bitPos;
		break;

	case PORT_RESET_STAT:
		hp->RHportStatus->portChange |= bitPos;
		break;

	case PORT_POWER_STAT:
		hp->RHportStatus->portChange |= bitPos;
		break;

	case PORT_SUSPEND_STAT:
		hp->RHportStatus->portChange |= bitPos;
		break;

	case PORT_OVER_CURRENT_STAT:
		hp->RHportStatus->portChange |= bitPos;
		break;
	}
}

/*****************************************************************
 *
 * Function Name: clrPortChange
 *
 * This function clear the bit position of portChange.
 *
 * Input:  hci = data structure for the host controller
 *         bitPos = the bit position
 *
 * Return value  : none 
 *                
 *****************************************************************/
static void clrPortChange (hci_t * hci, __u16 bitPos)
{
	hcipriv_t *hp = &hci->hp;
	switch (bitPos) {
	case PORT_CONNECT_CHANGE:
		hp->RHportStatus->portChange &= ~bitPos;
		break;

	case PORT_ENABLE_CHANGE:
		hp->RHportStatus->portChange &= ~bitPos;
		break;

	case PORT_RESET_CHANGE:
		hp->RHportStatus->portChange &= ~bitPos;
		break;

	case PORT_SUSPEND_CHANGE:
		hp->RHportStatus->portChange &= ~bitPos;
		break;

	case PORT_OVER_CURRENT_CHANGE:
		hp->RHportStatus->portChange &= ~bitPos;
		break;
	}
}

/*****************************************************************
 *
 * Function Name: clrPortStatus
 *
 * This function clear the bit position of portStatus.
 *
 * Input:  hci = data structure for the host controller
 *         bitPos = the bit position
 *
 * Return value  : none 
 *                
 *****************************************************************/
static void clrPortStatus (hci_t * hci, __u16 bitPos)
{
	hcipriv_t *hp = &hci->hp;
	switch (bitPos) {
	case PORT_ENABLE_STAT:
		hp->RHportStatus->portStatus &= ~bitPos;
		break;

	case PORT_RESET_STAT:
		hp->RHportStatus->portStatus &= ~bitPos;
		break;

	case PORT_POWER_STAT:
		hp->RHportStatus->portStatus &= ~bitPos;
		break;

	case PORT_SUSPEND_STAT:
		hp->RHportStatus->portStatus &= ~bitPos;
		break;
	}
}

/*****************************************************************
 *
 * Function Name: setPortStatus
 *
 * This function set the bit position of portStatus.
 *
 * Input:  hci = data structure for the host controller
 *         bitPos = the bit position
 *
 * Return value  : none 
 *                
 *****************************************************************/
static void setPortStatus (hci_t * hci, __u16 bitPos)
{
	hcipriv_t *hp = &hci->hp;
	switch (bitPos) {
	case PORT_ENABLE_STAT:
		hp->RHportStatus->portStatus |= bitPos;
		break;

	case PORT_RESET_STAT:
		hp->RHportStatus->portStatus |= bitPos;
		break;

	case PORT_POWER_STAT:
		hp->RHportStatus->portStatus |= bitPos;
		break;

	case PORT_SUSPEND_STAT:
		hp->RHportStatus->portStatus |= bitPos;
		break;
	}
}

/*****************************************************************
 *
 * Function Name: hc_start
 *
 * This function starts the root hub functionality. 
 *
 * Input:  hci = data structure for the host controller
 *
 * Return value  : 0 
 *                
 *****************************************************************/
static int hc_start (hci_t * hci)
{
	DBGFUNC ("Enter hc_start\n");

	rh_connect_rh (hci);

	return 0;
}

/*****************************************************************
 *
 * Function Name: hc_alloc_hci
 *
 * This function allocates all data structure and store in the 
 * private data structure. 
 *
 * Input:  hci = data structure for the host controller
 *
 * Return value  : 0 
 *                
 *****************************************************************/
static hci_t *__devinit hc_alloc_hci (void)
{
	hci_t *hci;
	hcipriv_t *hp;
	portstat_t *ps;
	struct usb_bus *bus;

	DBGFUNC ("Enter hc_alloc_hci\n");
	hci = (hci_t *) kmalloc (sizeof (hci_t), GFP_KERNEL);
	if (!hci)
		return NULL;

	memset (hci, 0, sizeof (hci_t));

	hp = &hci->hp;

	hp->irq = -1;
	hp->hcport = -1;

	/* setup root hub port status */

	ps = (portstat_t *) kmalloc (sizeof (portstat_t), GFP_KERNEL);

	if (!ps)
		return NULL;
	ps->portStatus = PORT_STAT_DEFAULT;
	ps->portChange = PORT_CHANGE_DEFAULT;
	hp->RHportStatus = ps;

	hci->nakCnt = 0;
	hci->last_packet_nak = 0;

	hci->a_td_array.len = 0;
	hci->i_td_array[0].len = 0;
	hci->i_td_array[1].len = 0;
	hci->td_array = &hci->a_td_array;
	hci->active_urbs = 0;
	hci->active_trans = 0;
	INIT_LIST_HEAD (&hci->hci_hcd_list);
	list_add (&hci->hci_hcd_list, &hci_hcd_list);
	init_waitqueue_head (&hci->waitq);

	INIT_LIST_HEAD (&hci->ctrl_list);
	INIT_LIST_HEAD (&hci->bulk_list);
	INIT_LIST_HEAD (&hci->iso_list);
	INIT_LIST_HEAD (&hci->intr_list);
	INIT_LIST_HEAD (&hci->del_list);

	bus = usb_alloc_bus (&hci_device_operations);
	if (!bus) {
		kfree (hci);
		kfree (ps);
		return NULL;
	}

	hci->bus = bus;
	bus->bus_name = "sl811";
	bus->hcpriv = (void *) hci;

	return hci;
}

/*****************************************************************
 *
 * Function Name: hc_release_hci
 *
 * This function De-allocate all resources  
 *
 * Input:  hci = data structure for the host controller
 *
 * Return value  : 0 
 *                
 *****************************************************************/
static void hc_release_hci (hci_t * hci)
{
	hcipriv_t *hp = &hci->hp;

	DBGFUNC ("Enter hc_release_hci\n");

	/* disconnect all devices */
	if (hci->bus->root_hub)
		usb_disconnect (&hci->bus->root_hub);

	hc_reset (hci);

	if (hp->tl)
		kfree (hp->tl);

	if (hp->hcport > 0) {
		release_region (hp->hcport, 2);
		hp->hcport = 0;
	}

	if (hp->irq >= 0) {
		free_irq (hp->irq, hci);
		hp->irq = -1;
	}

	usb_deregister_bus (hci->bus);
	usb_free_bus (hci->bus);

	list_del (&hci->hci_hcd_list);
	INIT_LIST_HEAD (&hci->hci_hcd_list);

	kfree (hci);
}
#ifndef CONFIG_COLDFIRE
/*****************************************************************
 *
 * Function Name: init_irq
 *
 * This function is board specific.  It sets up the interrupt to 
 * be an edge trigger and trigger on the rising edge  
 *
 * Input: none 
 *
 * Return value  : none 
 *                
 *****************************************************************/
void init_irq (void)
{
	//GPDR &= ~(1 << 13);
	//set_GPIO_IRQ_edge (1 << 13, GPIO_RISING_EDGE);
	int i;
	i=0;
	i++;
}
#endif
/*****************************************************************
 *
 * Function Name: hc_found_hci
 *
 * This function request IO memory regions, request IRQ, and
 * allocate all other resources. 
 *
 * Input: addr = first IO address
 *        addr2 = second IO address
 *        irq = interrupt number 
 *
 * Return: 0 = success or error condition 
 *                
 *****************************************************************/
static int __devinit hc_found_hci (int addr, int addr2, int irq)
{
	hci_t *hci;
	hcipriv_t *hp;

	DBGFUNC ("Enter hc_found_hci\n");
	hci = hc_alloc_hci ();
	if (!hci) {
		return -ENOMEM;
	}
#ifndef CONFIG_COLDFIRE
	/*
	 * This is arm specific!
	 */
	init_irq ();
	hp = &hci->hp;
#endif
	if (!request_region (addr, 256, "SL811 USB HOST")) {
		DBGERR ("request address %d failed", addr);
		hc_release_hci (hci);
		return -EBUSY;
	}
	hp->hcport = addr;
	if (!hp->hcport) {
		DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport);
	}

	if (!request_region (addr2, 256, "SL811 USB HOST")) {
		DBGERR ("request address %d failed", addr2);
		hc_release_hci (hci);
		return -EBUSY;
	}
	hp->hcport2 = addr2;
	if (!hp->hcport2) {
		DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport2);
	}

	if (hc_alloc_trans_buffer (hci)) {
		hc_release_hci (hci);
		return -ENOMEM;
	}

	usb_register_bus (hci->bus);

	if (request_irq (irq, hc_interrupt, 0, "SL811", hci) != 0) {
		DBGERR ("request interrupt %d failed", irq);
		hc_release_hci (hci);
		return -EBUSY;
	}
	hp->irq = irq;

	printk (KERN_INFO __FILE__ ": USB SL811 at %x, addr2 = %x, IRQ %d\n",
		addr, addr2, irq);
	hc_reset (hci);

	if (hc_start (hci) < 0) {
		DBGERR ("can't start usb-%x", addr);
		hc_release_hci (hci);
		return -EBUSY;
	}

	return 0;
}

/*****************************************************************
 *
 * Function Name: hci_hcd_init
 *
 * This is an init function, and it is the first function being called
 *
 * Input: none 
 *
 * Return: 0 = success or error condition 
 *                
 *****************************************************************/
static int __init hci_hcd_init (void)
{
	int ret;
#ifdef CONFIG_USB_SL811HC_AUTO
    int index;

    DBGFUNC ("Enter hci_hcd_init with auto probe!\n");

    for( index = 0, ret = -1; sl811hc_portlist[index], ret; index++ ) 
      ret = hc_found_hci ( sl811hc_portlist[index], sl811hc_datalist[index], sl811hc_irqlist[index] );
#else
	DBGFUNC ("Enter hci_hcd_init\n");
	ret = hc_found_hci (base_addr, data_reg_addr, irq);
#endif
	return ret;
}

/*****************************************************************
 *
 * Function Name: hci_hcd_cleanup
 *
 * This is a cleanup function, and it is called when module is 
 * unloaded. 
 *
 * Input: none 
 *
 * Return: none 
 *                
 *****************************************************************/
static void __exit hci_hcd_cleanup (void)
{
	struct list_head *hci_l;
	hci_t *hci;

	DBGFUNC ("Enter hci_hcd_cleanup\n");
	for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;) {
		hci = list_entry (hci_l, hci_t, hci_hcd_list);
		hci_l = hci_l->next;
		hc_release_hci (hci);
	}
}

module_init (hci_hcd_init);
module_exit (hci_hcd_cleanup);

MODULE_AUTHOR ("Pei Liu <pbl@cypress.com>");
MODULE_DESCRIPTION ("USB SL811HS Host Controller Driver");

⌨️ 快捷键说明

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