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

📄 hc_sl811.c

📁 软件中包含了Cypress的SL811 USB接口芯片的固件程序以及如何51单片机进行操作的例子
💻 C
📖 第 1 页 / 共 3 页
字号:
 * 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);
	return NULL;
    }

    hci->bus = bus;
    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);
}

/*****************************************************************
 *
 * 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);
}

/*****************************************************************
 *
 * 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;
    }

    init_irq();
    hp = &hci->hp;
	
    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;

    DBGFUNC ("Enter hci_hcd_init\n");
    ret = hc_found_hci (base_addr, data_reg_addr, irq);   

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