📄 usbinit.c
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright (C) 2002 Motorola Semiconductors HK Ltd * */#include <linux/kernel.h>#include <linux/module.h>#include <linux/compatmac.h>#include <linux/hdreg.h>#include <linux/vmalloc.h>#include <linux/fs.h>#include <linux/module.h>#include <linux/blkpg.h>#include "prototype.h"#include "define.h"#include "mx1.h"void _iUsbDelay(U32 count);void _iUsbLoadEPconfig(void);void _iUsbReset(void);U8 _gUsbMode; // operation mode of driverU8 _gUsbDrvStatus[2]; // Drive statusU32 gEPconfigData[55] = { // EP0 0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x00000000, // EP1 0x00000014, // EP#:1, CF#: 1, IF#:0 0x00000014, // BULK, IN 0x00000020, // MAX PS: 32 0x000000C0, // 0xC0, except for EP0 0x00000001, // FIFO#: 1 // EP2 0x00000024, // EP#:2, CF#: 1, IF#:0 0x00000010, // BULK, OUT 0x00000020, // MAX PS: 32 0x000000C0, // 0xC0, except for EP0 0x00000002, // FIFO#: 2 // EP3 0x00000034, // EP#:3, CF#: 1, IF#:0 0x0000001C, // INTR, IN 0x00000010, // MAX PS: 16 0x000000C0, // 0xC0, except for EP0 0x00000003, // FIFO#: 3 // EP4 0x00000044, // EP#:4, CF#: 1, IF#:0 0x00000018, // INTR, OIUT 0x00000010, // MAX PS: 16 0x000000C0, // 0xC0, except for EP0 0x00000004, // FIFO#: 4 // EP5 0x00000054, // EP#:5, CF#: 1, IF#:0 0x0000001C, // INTR, IN 0x00000010, // MAX PS: 16 0x000000C0, // 0xC0, except for EP0 0x00000005, // FIFO#: 5 // EP6 0x00000018, // EP#:1, CF#: 2, IF#:0 0x00000014, // BULK, IN 0x00000020, // MAX PS: 32 0x000000C0, // 0xC0, except for EP0 0x00000001, // FIFO#: 1 // EP7 0x00000028, // EP#:2, CF#: 2, IF#:0 0x00000010, // BULK, OUT 0x00000020, // MAX PS: 32 0x000000C0, // 0xC0, except for EP0 0x00000002, // FIFO#: 2 // EP8 0x00000038, // EP#:3, CF#: 2, IF#:0 0x0000001C, // INTR, IN 0x00000010, // MAX PS: 16 0x000000C0, // 0xC0, except for EP0 0x00000003, // FIFO#: 3 // EP9 0x00000048, // EP#:4, CF#: 2, IF#:0 0x00000018, // INTR, OIUT 0x00000010, // MAX PS: 16 0x000000C0, // 0xC0, except for EP0 0x00000004, // FIFO#: 4 // EP10 0x00000058, // EP#:5, CF#: 2, IF#:0 0x0000001C, // INTR, IN 0x00000010, // MAX PS: 16 0x000000C0, // 0xC0, except for EP0 0x00000005, // FIFO#: 5 };void _iUsbDelay(U32 count){ U32 i; i = 0; while (i<count) { i++; }}void _iUsbReset(){ U8 i; /* reset and enable USB device module */ //_reg_USBD_ENABLE = 0x00000000; /* disable module */// PLAM -- for rev2 (changed from using direct assignment and for new endian bit) _reg_USBD_ENABLE &= ~0x40000000; /* disable module */// end PLAM _iUsbDelay(10); //_reg_USBD_ENABLE = 0x80000000; /* enable and reset module */// PLAM -- for rev2 (changed from using direct assignment and for new endian bit) _reg_USBD_ENABLE &= ~0x00000001; /* select 32-bit mode FIFO */ _reg_USBD_ENABLE &= ~0x10000000; /* Set big endian */ _reg_USBD_ENABLE |= 0x40000000; /* enable module */// end PLAM /* remark: resetting the module will enable module automatically */ while (!(_reg_USBD_ENABLE & 0x40000000)); // wait until it is enabled // fill endpoint configuration buffer for (i=0; i<55; i++) { _reg_USBD_EPBUF = gEPconfigData[i]; while (_reg_USBD_CFGBSY & 0x40000000); // wait until busy bit is cleared } // mask interrupts _reg_USBD_INTR_STAT = 0x800000FF; // clear general interrupts _reg_USBD_INTR_MASK = 0x800000FF; // mask all general interrupts//DPRINTK("intr stat: 0x%08x\n",_reg_USBD_INTR_STAT); _reg_USBD_EP0_INTR_STAT = 0x000001FF; // clear EP interrupts _reg_USBD_EP0_INTR_MASK = 0x000001FF; // mask all EP interrupts _reg_USBD_EP1_INTR_STAT = 0x000001FF; // clear EP interrupts _reg_USBD_EP1_INTR_MASK = 0x000001FF; // mask all EP interrupts _reg_USBD_EP2_INTR_STAT = 0x000001FF; // clear EP interrupts _reg_USBD_EP2_INTR_MASK = 0x000001FF; // mask all EP interrupts _reg_USBD_EP3_INTR_STAT = 0x000001FF; // clear EP interrupts _reg_USBD_EP3_INTR_MASK = 0x000001FF; // mask all EP interrupts _reg_USBD_EP4_INTR_STAT = 0x000001FF; // clear EP interrupts _reg_USBD_EP4_INTR_MASK = 0x000001FF; // mask all EP interrupts _reg_USBD_EP5_INTR_STAT = 0x000001FF; // clear EP interrupts _reg_USBD_EP5_INTR_MASK = 0x000001FF; // mask all EP interrupts // configure USB_EPn_STAT registers and flush FIFOs _reg_USBD_EP0_STAT = 0x00000002; _reg_USBD_EP1_STAT = 0x000000D2; // IN, MAX PS 32, BULK _reg_USBD_EP2_STAT = 0x00000052; // OUT, MAX pS 32, BULK _reg_USBD_EP3_STAT = 0x000000BA; // IN, MAX PS 16, INTR _reg_USBD_EP4_STAT = 0x0000003A; // OUT, MAX PS 16, INTR _reg_USBD_EP5_STAT = 0x000000BA; // IN, MAX PS 16, INTR // configure USB_EPn_FCTRL registers _reg_USBD_EP0_FCTRL = 0x0F000000; _reg_USBD_EP1_FCTRL = 0x0B000000; _reg_USBD_EP2_FCTRL = 0x0F000000; _reg_USBD_EP3_FCTRL = 0x0B000000; _reg_USBD_EP4_FCTRL = 0x0F000000; _reg_USBD_EP5_FCTRL = 0x0B000000; // configure USB_EPn_FALRM registers _reg_USBD_EP0_FALRM = 0x00000000; _reg_USBD_EP1_FALRM = 0x00000020; _reg_USBD_EP2_FALRM = 0x00000020; _reg_USBD_EP3_FALRM = 0x00000010; _reg_USBD_EP4_FALRM = 0x00000010; _reg_USBD_EP5_FALRM = 0x00000010; while (_reg_USBD_INTR_STAT & RST_START_MASK); // wait until reset signaling finished _reg_USBD_CTRL = 0x0000001A; // enable module//DPRINTK("intr stat: 0x%08x\n",_reg_USBD_INTR_STAT);}int init_module(void){ printk("USB driver version 0.2.0\n"); // set clock for 48 MHz USB clock //_reg_CCM_CSCR = 0x47008403;// PLAM -- for rev2 (changed from using direct assignment and for new endian bit) _reg_CCM_CSCR &= ~USB_DIV_MASK; _reg_CCM_CSCR |= 0x04000000; // set USB DIV to divide-by-2// end PLAM // config port for USBD _reg_PTB_GIUS &= 0x000FFFFF; // set PB31-28 to UART2 and PB27-20 to USBD _reg_PTB_GPR &= 0x000FFFFF; // select primary peripheral // enable USB device interrupt// _reg_IMR &= (~USBD_INTR_MASK); /* initialize variables */ _gUsbDrvStatus[0] = USB_DRV_READY;// _gUsbDrvStatus[0] = USB_DRV_NOT_READY; _gUsbDrvStatus[1] = USB_DRV_NOT_READY; /* register interrupt handler */// _HalAttachIsr(USB_INTR_SOURCE, (P_VOID)_UsbIntrHandler); _iUsbReset(); if (request_irq(USB_INTR_SOURCE0, ep0_interrupt, SA_INTERRUPT, "USB EP0", 0) < 0) printk("Intr request for source %d failed !\n", USB_INTR_SOURCE0); if (request_irq(USB_INTR_SOURCE1, ep1_interrupt, SA_INTERRUPT, "USB EP1", 0) < 0) printk("Intr request for source %d failed !\n", USB_INTR_SOURCE1); if (request_irq(USB_INTR_SOURCE2, ep2_interrupt, SA_INTERRUPT, "USB EP2", 0) < 0) printk("Intr request for source %d failed !\n", USB_INTR_SOURCE2); if (request_irq(USB_INTR_SOURCE3, usb_interrupt, SA_INTERRUPT, "USB EP3", 0) < 0) printk("Intr request for source %d failed !\n", USB_INTR_SOURCE3); if (request_irq(USB_INTR_SOURCE4, usb_interrupt, SA_INTERRUPT, "USB EP4", 0) < 0) printk("Intr request for source %d failed !\n", USB_INTR_SOURCE4); if (request_irq(USB_INTR_SOURCE5, usb_interrupt, SA_INTERRUPT, "USB EP5", 0) < 0) printk("Intr request for source %d failed !\n", USB_INTR_SOURCE5); if (request_irq(USB_INTR_SOURCE6, usb_interrupt, SA_INTERRUPT, "USB", 0) < 0) printk("Intr request for source %d failed !\n", USB_INTR_SOURCE6); _reg_USBD_EP0_INTR_MASK &= ~(DEVREQ_MASK); // enable DEVREQ for EP0// _reg_USBD_EP0_INTR_MASK = 0x1FD; // enable DEVREQ for EP0 _reg_USBD_EP2_INTR_MASK &= ~(EOT_MASK); // enable EOT for EP2 return 0;}void cleanup_module(void){ printk("Cleanup USB driver.\n"); free_irq(USB_INTR_SOURCE0, 0); free_irq(USB_INTR_SOURCE1, 0); free_irq(USB_INTR_SOURCE2, 0); free_irq(USB_INTR_SOURCE3, 0); free_irq(USB_INTR_SOURCE4, 0); free_irq(USB_INTR_SOURCE5, 0); free_irq(USB_INTR_SOURCE6, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -