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

📄 hc_isp116x.c

📁 isp1161a USB主控制芯片驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
        InterruptPinEnable | HCR_VALUE,        HcHardwareConfiguration);        WRITE_REG16 (hci, 0, HcDMAConfiguration);    maxlen = (hp->itl_buffer_len > hp->atl_buffer_len) ? hp->itl_buffer_len : hp->atl_buffer_len;    hp->tl = kmalloc (maxlen, GFP_KERNEL);        if (!hp->tl)        return -ENOMEM;    memset (hp->tl, 0, maxlen);    dbg("hc_alloc_trans_buffer done");    return 0;}    static int hc_start (hci_t * hci){    hcipriv_t * hp = &hci->hp;       __u32 mask;      unsigned int fminterval;    dbg("hc_start\n");      fminterval = 0x2edf;    fminterval |= ((((fminterval - 210) * 6) / 7) << 16);     WRITE_REG32 (hci, fminterval, HcFmInterval);        WRITE_REG32 (hci, 0x628, HcLSThreshold);     /* start controller operations */     hp->hc_control = OHCI_USB_OPER;     WRITE_REG32 (hci, hp->hc_control, HcControl);    /* Choose the interrupts we care about now, others later on demand */    mask = OHCI_INTR_MIE | //    OHCI_INTR_ATD | //    OHCI_INTR_SF |     OHCI_INTR_SO;//    mask = OHCI_INTR_MIE | OHCI_INTR_SF;    WRITE_REG32 (hci, mask, HcInterruptStatus);    WRITE_REG32 (hci, mask, HcInterruptEnable);    mask = SOFITLInt | ATLInt | OPR_Reg;  //commented by xiongly for debug    //mask = ATLInt | OPR_Reg;#ifdef HC_SWITCH_INT    mask = 0;#endif    WRITE_REG16 (hci, mask, HcuPInterrupt);     WRITE_REG16 (hci, mask, HcuPInterruptEnable);#ifdef    OHCI_USE_NPS    WRITE_REG32 ((READ_REG32 (hci, HcRhDescriptorA) | RH_A_NPS) & ~RH_A_PSM,        HcRhDescriptorA);    WRITE_REG32 (hci, RH_HS_LPSC, HcRhStatus);#endif    /* OHCI_USE_NPS */    // POTPGT delay is bits 24-31, in 2 ms units.    mdelay ((READ_REG32 (hci, HcRhDescriptorA) >> 23) & 0x1fe);    dump_regs(hci);     return rh_connect_rh (hci);}/*-------------------------------------------------------------------------*//* allocate HCI */static hci_t * __devinit hc_alloc_hci (void){    hci_t * hci;    hcipriv_t * hp;         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->data_port = -1;    hp->cmd_port = -1;    hp->wu_port = -1;     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;     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) {        DBGFUNC ("knackered\n");        kfree (hci);        return NULL;    }    hci->bus = bus;    bus->bus_name = "isp116x";    bus->hcpriv = (void *) hci;    return hci;} /*-------------------------------------------------------------------------*//* De-allocate all resources.. */static void hc_release_hci (hci_t * hci){        hcipriv_t * hp = &hci->hp;     DBGFUNC("USB HC release hci %p", hci);    if (hp->irq >= 0) {        free_irq (hp->irq, hci);        hp->irq = -1;    }    /* disconnect all devices */        if (hci->bus->root_hub)        usb_disconnect (&hci->bus->root_hub);    if (hp->data_port > 0) {        WRITE_REG16 (hci, 0, HcHardwareConfiguration);        WRITE_REG16 (hci, 0, HcDMAConfiguration);        WRITE_REG16 (hci, 0, HcuPInterruptEnable);    }//    if (!hci->disabled)        hc_reset (hci);        if (hp->tl)        kfree (hp->tl);    /* TODO: We should probably unmap the ports at this point */            if(hci->bus->controller)        usb_deregister_bus (hci->bus);    /*usb_put_bus (hci->bus); it was moved by usb developers*/    list_del (&hci->hci_hcd_list);    INIT_LIST_HEAD (&hci->hci_hcd_list);           kfree (hci);}/*-------------------------------------------------------------------------*//*static __inline__ void wait_ms(unsigned int ms){        if(!in_interrupt()) {                current->state = TASK_UNINTERRUPTIBLE;                schedule_timeout(1 + ms * HZ / 1000);        }        else                mdelay(ms);}*/static void isp116x_set_cpu_int(void){  void * addr;  u32 value;  /* set irq select and enable */  addr = ioremap(0xFFFFF000,0x40);  value = inl(addr+0x00C);  value &= ~(((u32)1)<<irq);      	/*bit3=0*/  outl(value, addr+0x00C);  		/*select as irq*/  printk(KERN_ALERT"    int select reg=0x%.8x\n", (u32)inl(addr+0x00C));  printk(KERN_ALERT"    int enable reg=0x%.8x\n", (u32)inl(addr+0x010));  outl(((u32)1)<<irq, addr+0x014); 	/*disable int 3*/  printk(KERN_ALERT"    int enable reg=0x%.8x\n", (u32)inl(addr+0x010));  iounmap(addr);  /* set int configuration */  addr = ioremap(0xFFFE2000,0x100);  value = inl(addr+0x00);  value |= (((u32)1)<<9);  outl(value, addr+0x00);		/* enable RCPC write */  value = inl(addr+0x80);  value &= ~(((u32)0x3)<<(irq*2));#if 1  value |= 0x00 <<(irq*2);		/* low level */#else  value |= 0x01 <<(irq*2);		/* high level */#endif  outl(value, addr+0x80);  value = inl(addr+0x80);  printk(KERN_ALERT"    int config reg=0x%.8x\n", value);  outl(((u32)1)<<irq, addr+0x84);	/* clear int */  value = inl(addr+0x00);  value &= ~(((u32)1)<<9);  outl(value, addr+0x00);		/* disable RCPC write */  iounmap(addr);}/* hc_found_hci * * Check for the existance of the USB HC at the address's specified * and then if its there allocate its private data, iIncrement the * module usage count, start the control thread and return success. */ static int __devinit hc_found_hci (int data_addr, int cmd_addr, int wuaddr, int irq, int dma){    hci_t * hci;    hcipriv_t * hp;        hci = hc_alloc_hci ();    if (!hci) {        return -ENOMEM;    }    hp = &hci->hp;#if 0    /* Request io access to the correct ports */    hp->data_port = (unsigned long) ioremap_nocache(data_addr, 4);    hp->cmd_port = (unsigned long) ioremap_nocache(cmd_addr, 4);    hp->wu_port = (unsigned long) ioremap_nocache(wuaddr, 4);#else    hp->data_port = (unsigned long) data_addr;    hp->cmd_port = (unsigned long) cmd_addr;    hp->wu_port = (unsigned long) wuaddr;#endif    /*     * See if we can read the ChipID and prove the chip is there     */    if ((READ_REG16(hci, HcChipID) & 0xff00) != 0x6100) {        printk("Can't read chip\n");        hc_release_hci (hci);        return -ENODEV;    }    /*     * Display the essential details about the chip wot we have     * found, including some debug information for now     */    printk(KERN_ALERT ": USB ISP116x at %lx/%lx,%lx IRQ %d Rev. %x ChipID: %x\n",        hp->data_port, hp->cmd_port, hp->wu_port, irq, READ_REG32(hci, HcRevision), READ_REG16(hci, HcChipID));    printk(KERN_ALERT ": HcControl=0x%x, HcCommandStatus=0x%x\n",        READ_REG32(hci, HcControl),        READ_REG32(hci, HcCommandStatus) );    printk(KERN_ALERT ": HcInterruptEnable=0x%x HcInterruptDisable=0x%x HcuPinterruptEnable=0x%x\n",        READ_REG32(hci, HcInterruptEnable),        READ_REG32(hci, HcInterruptDisable),        READ_REG16(hci, HcuPInterruptEnable));    printk(KERN_ALERT ": HcHardwareConfiguration=0x%x\n",        READ_REG16(hci, HcHardwareConfiguration));    isp116x_set_cpu_int();    dc_set_reg();     /*     * Disable All Interrupts     */    WRITE_REG16(hci, HCR_VALUE|InterruptPinEnable, HcHardwareConfiguration);    WRITE_REG32(hci, 0xffffffff, HcInterruptDisable);    WRITE_REG16(hci, 0x0, HcuPInterruptEnable);    WRITE_REG16(hci, 0xffff, HcuPInterrupt);        /* clear any pending */    WRITE_REG16(hci, HCR_VALUE, HcHardwareConfiguration);       if (hc_reset (hci) < 0) {        hc_release_hci (hci);        return -ENODEV;    }    if (hc_alloc_trans_buffer (hci)) {        hc_release_hci (hci);        return -ENOMEM;    }    dbg("doing final reset");    /* FIXME this is a second HC reset; why?? */    //WRITE_REG32 (hci, hp->hc_control = OHCI_USB_RESET, HcControl);    //wait_ms (1000);    hci->bus->controller = &isp116x_device->dev;    usb_register_bus (hci->bus);    if (hc_start (hci) < 0) {        err ("can't start usb-%x", data_addr);        hc_release_hci (hci);        return -EBUSY;    }    /*     * Install the irq handler first - as I was seeing     * un-acknowledged interrupts occur during setup     */    if (request_irq (irq, isp116x_interrupt, 0,            "ISP116x", hci) != 0) {        err ("request interrupt %d failed", irq);        hc_release_hci (hci);        return -EBUSY;    }    hp->irq = irq;    return 0;}/*-------------------------------------------------------------------------*/static int __init hci_hcd_init (void) {    int ret;    DBGFUNC("hci_hcd_init entered\n");    /* create spinlock for reg accesses */    spin_lock_init(&isp116x_spinlock);    isp116x_device = platform_device_register_simple("isp116x", -1, NULL, 0);    if (IS_ERR(isp116x_device))        return PTR_ERR(isp116x_device);        ret = hc_found_hci (hc_data_port, hc_cmd_port, hc_wu_port, irq, 0);       DBGFUNC("hci_hcd_init result=%d\n",ret);    if(ret) {        platform_device_unregister(isp116x_device);    }    return ret;}/*-------------------------------------------------------------------------*/static void __exit hci_hcd_cleanup (void) {    struct list_head *  hci_l;    hci_t * hci;    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);    }        platform_device_unregister(isp116x_device);}module_init (hci_hcd_init);module_exit (hci_hcd_cleanup);MODULE_AUTHOR ("Roman Weissgaerber <weissg@vienna.at>");MODULE_DESCRIPTION ("USB ISP116x Host Controller Driver");MODULE_LICENSE ("GPL");

⌨️ 快捷键说明

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