📄 ev44b0_usb.c
字号:
/*------------------------------------------------------------------------ . ev44b0_usb.c . . This is a USB driver for Philips's PDIUSBD12 single-chip USB device. . . (C) Copyright 2003 . MICETEK International Inc., Shanghai China . Qin Wei <king@micetek.com.cn> . . . 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 . . . author: . Qin Wei ( king@micetek.com.cn ) . History: . 01/14/03 Qin Wei ----------------------------------------------------------------------------*/#include <linux/module.h>#include <linux/types.h>#include <linux/wait.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/poll.h>#include <linux/miscdevice.h>#include <linux/init.h>#include <linux/compiler.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/uaccess.h>#include <asm/irq.h>#include <asm/hardware.h>#include "ev44b0_usb.h"#define EV44B0II_USB_MODULE_NAME "usb"#define USB_BULK_MAJOR 0x55static const char usb_driver_version[] = "EV44B0II USB driver v1.0 (2003-01-09) Qinwei, MICETEK Shanghai";#define CONFIG_USBD12_BASE 0x4000000#define verbose 0#define Usb_Base_Address CONFIG_USBD12_BASEstatic char *usb_bulk_id = "ev44b0ii usb"; static volatile char USB_CONNECT_FLAG = 0;#define MAXUSBBUFFERLEN 1024static unsigned char gbuffer[MAXUSBBUFFERLEN];static unsigned char controlbuffer0[64];struct ev44b0ii_usb_priv gusb;//****************************************************************************//// This structure defines the setup packet received from the host via the// control out endpoint. This sturcture is padded at the end to the maximum// control endpoint transfer size.////****************************************************************************typedef struct{ unsigned char bmRequestType; unsigned char bRequest; unsigned short wValue; unsigned short wIndex; unsigned short wLength;} ControlTransfer;//****************************************************************************//// The following structure contains the persistent state of the USB interface.////****************************************************************************static struct{ // The currently selected USB configuration. unsigned long ulConfiguration; // The buffer of data that is being sent to the control endpoint. const unsigned char *pucControlIn; // The number of bytes to be sent to the control endpoint. unsigned long ulControlInCount; // The buffer of data that is being received from the control endpoint. ControlTransfer sControlOut; // The buffer of data that is being sent to the bulk endpoint. const unsigned char *pucBulkIn; // The number of bytes to be sent to the bulk endpoint. unsigned long ulBulkInCount; // The buffer of data that is being received from the bulk endpoint. unsigned char *pucBulkOut; // The number of bytes still to be read from the bulk endpoint. unsigned long ulBulkOutCount; const unsigned char *pucACKIn; unsigned long ulACKInCount; unsigned char *pucCommandOut; unsigned long ulCommandOutCount;} sUSB;//****************************************************************************//// This is the configuration descriptor for the digital audio player. See the// USB specification for the definition of this descriptor.////****************************************************************************static const unsigned char ucDeviceDescriptor[] ={ 0x12, // bLength 0x01, // bDescriptorType 0x00, 0x01, // bcdUSB 0x00, // bDeviceClass 0x00, // bDeviceSubClass 0x00, // bDeviceProtocol 0x10, // bMaxPacketSize0 0x5e, 0x04, // idVendor 0x0a, 0x93, // idProduct 0x00, 0x01, // bcdDevice 0x01, // iManufacturer 0x02, // iProduct 0x00, // iSerial Number 0x01 // bNumConfigurations};//****************************************************************************//// This is the configuration descriptor for the digital audio player. See the// USB specification for the definition of this descriptor.////****************************************************************************static const unsigned char ucConfigurationDescriptor[] ={ // // The configuration descriptor structure. // 0x09, // bLength 0x02, // bDescriptorType 0x20, // wTotalLength 0x00, // bCorrection 0x01, // bNumInterfaces 0x01, // bConfigurationValue 0x00, // iConfiguration 0x40, // bmAttributes 0x00, // MaxPower // // The interface descriptor structure. // 0x09, // bLength 0x04, // bDescriptorType 0x00, // bInterfaceNumber 0x00, // bAlternateSetting 0x02, // bNumEndpoints 0x00, // bInterfaceClass 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol 0x00, // iInterface // // The endpoint descriptor structure. // 0x07, // bLength 0x05, // bDescriptorType 0x82, // bEndpointAddress 0x02, // bmAttributes 0x40, 0x00, // wMaxPacketSize 0x00, // bInterval // // The endpoint descriptor structure. // 0x07, // bLength 0x05, // bDescriptorType 0x02, // bEndpointAddress 0x02, // bmAttributes 0x40, 0x00, // wMaxPacketSize 0x00 // bInterval};//****************************************************************************//// String descriptor 0 for the digital audio player. This defines the// languages supported by the string descriptors. See the USB specification// for the definition of this descriptor.////****************************************************************************static const unsigned char ucString0[] ={ 0x04, // bLength 0x03, // bDescriptorType 0x09, 0x04 // wLANGID[0] -> US English};//****************************************************************************//// String descriptor 1 for the digital audio player. This defines the// manufacturer of the player. See the USB specification for the definition// of this descriptor.////****************************************************************************static const unsigned char ucString1[] ={ 0x1e, // bLength 0x03, // bDescriptorType 'M', 0x00, // wString[] 'i', 0x00, 'c', 0x00, 'e', 0x00, 't', 0x00, 'e', 0x00, 'k', 0x00, ' ', 0x00, 'I', 0x00, 'N', 0x00, 'C', 0x00, '.', 0x00, ',', 0x00, ' ', 0x00};//****************************************************************************//// String descriptor 1 for the digital audio player. This defines the product// description of the player. See the USB specification for the definition of// this descriptor.////****************************************************************************static const unsigned char ucString2[] ={ 0x52, // bLength 0x03, // bDescriptorType 'M', 0x00, // wString[] 'i', 0x00, 'c', 0x00, 'e', 0x00, 't', 0x00, 'e', 0x00, 'k', 0x00, ' ', 0x00, 'E', 0x00, 'v', 0x00, '4', 0x00, '4', 0x00, 'b', 0x00, '0', 0x00, '-', 0x00, 'i', 0x00, 'i', 0x00, ' ', 0x00, 'e', 0x00, 'v', 0x00, 'a', 0x00, 'l', 0x00, 'u', 0x00, 'a', 0x00, 't', 0x00, 'i', 0x00, 'o', 0x00, 'n', 0x00, ' ', 0x00, 'b', 0x00, 'o', 0x00, 'a', 0x00, 'r', 0x00, 'd', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00};//****************************************************************************//// An array of pointers to the USB standard device request handler Functions.////****************************************************************************void (* const USBStandardDeviceRequest[])(void) ={ USBGetStatus, USBClearFeature, USBReserved, USBSetFeature, USBReserved, USBSetAddress, USBGetDescriptor, USBReserved, USBGetConfiguration, USBSetConfiguration, USBGetInterface, USBSetInterface, USBReserved};#define USB_STRUCT_INITED 0x55AAA55Astatic void usb_wait_ms(unsigned int ms){ if (!in_interrupt()) { current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(1 + ms * HZ / 1000); } else { current->state = TASK_INTERRUPTIBLE; schedule_timeout(1 + ms * HZ / 1000); current->state = TASK_RUNNING; }}static unsigned char USBInitStruct(void){ if (sUSB.ulConfiguration == USB_STRUCT_INITED) return 0; memset(&sUSB, 0 , sizeof(sUSB)); sUSB.ulConfiguration = USB_STRUCT_INITED; sUSB.pucControlIn = controlbuffer0; sUSB.ulControlInCount = 0;// sUSB.pucBulkIn = usbbuffer2; /* The buffer that we send to host.*/ sUSB.ulBulkInCount = 0; sUSB.pucBulkOut = gbuffer; /* The buffer that host send to us.*/ sUSB.ulBulkOutCount = MAXUSBBUFFERLEN; sUSB.pucACKIn = controlbuffer0; sUSB.ulACKInCount = 0; sUSB.pucCommandOut = controlbuffer0; sUSB.ulCommandOutCount = 0; return 0;}//****************************************************************************//// USBReadData will read a value from the data register of the PDIUSBD12.////****************************************************************************static unsigned char USBReadData(void){ volatile unsigned char * dataregister = (unsigned char *)(unsigned char *)(Usb_Base_Address + Usb_Data_Address); int delay; unsigned char datavalue; // // Read the value from the data register. // datavalue = * dataregister; // // Delay a bit to comply with the timing specification of the PDIUSBD12. // for(delay = 0; delay < 24; delay++) { } // // Return the value read. // return(datavalue);}//****************************************************************************//// USBReadEndpoint reads data from the specified endpoint.////****************************************************************************static unsigned long USBReadEndpoint(unsigned long ulEndpoint, unsigned char **ppucData, unsigned long *pulLength){ unsigned long ulIdx, ulLength; unsigned char *buffer = *ppucData; // // Select the appropriate endpoint. // USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + ulEndpoint); // // Is there buffer space to fill with this data or should we throw the // data away? // if(*pulLength) { // // Send the read buffer command. // USBWriteCommand(USB_COMMAND_READ_BUFFER); // // Throw away the reserved byte from the beginning of the buffer. // USBReadData(); // // Read the length of the data buffer. // ulLength = USBReadData(); // // Read the data into the receive buffer. // for(ulIdx = 0; (ulIdx < ulLength) && (ulIdx < *pulLength); ulIdx++) { *(*ppucData)++ = USBReadData(); } // // Decrement the count of bytes to read. // *pulLength -= ulIdx; if (ulEndpoint == USB_ENDPOINT_BULK_OUT) { gusb.head += ulIdx; gusb.total += ulIdx; } if (verbose) { printk("Get %ld data from USB chip.\n",ulLength); { u8 i; for (i = 0; i< ulLength; i++) { printk("%02x ", buffer[i]); } } printk("\n"); } } else /* haven't space to store the data, so drop it.*/ { if (ulEndpoint == USB_ENDPOINT_BULK_OUT) { // // Send the read buffer command. // USBWriteCommand(USB_COMMAND_READ_BUFFER); // // Throw away the reserved byte from the beginning of the buffer. // USBReadData(); // // Read the length of the data buffer. // ulLength = USBReadData(); gusb.dropped += ulLength; } } // // Send the clear buffer command so that the endpoint can receive another // packet. // USBWriteCommand(USB_COMMAND_CLEAR_BUFFER); // // Return the size of the packet received. // return(ulLength);}//****************************************************************************//// USBWriteCommand will write the specified value to the command register of// the PDIUSBD12.////****************************************************************************static void USBWriteCommand(unsigned char commandvalue){ volatile unsigned char *commandregister = (unsigned char *)(Usb_Base_Address + Usb_Command_Address); volatile int delay; /* * Write the value to the command register. */ *commandregister = commandvalue; /* * Delay a bit to comply with the timing specification of the PDIUSBD12. */ for(delay = 0; delay < 24; delay++) { }}//****************************************************************************//// USBWriteData will write the specified value to the data register of the// PDIUSBD12.////****************************************************************************static void USBWriteData(unsigned char datavalue){ volatile unsigned char *dataregister = (unsigned char *)(Usb_Base_Address + Usb_Data_Address); volatile int delay; // // Write the value to the data register. // *dataregister = datavalue; // // Delay a bit to comply with the timing specification of the PDIUSBD12. // for(delay = 0; delay < 24; delay++) { }}//****************************************************************************//// USBWriteEndpoint writes data to the specified endpoint.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -