uboot/arch/powerpc/cpu/ppc4xx/usbdev.c
<<
>>
Prefs
   1/*USB 1.1,2.0 device*/
   2
   3#include <common.h>
   4#include <asm/processor.h>
   5
   6#if (defined(CONFIG_440EP) || defined(CONFIG_440EPX)) && defined(CONFIG_CMD_USB)
   7
   8#include <usb.h>
   9#include <asm/ppc4xx-uic.h>
  10#include "usbdev.h"
  11
  12#define USB_DT_DEVICE        0x01
  13#define USB_DT_CONFIG        0x02
  14#define USB_DT_STRING        0x03
  15#define USB_DT_INTERFACE     0x04
  16#define USB_DT_ENDPOINT      0x05
  17
  18int set_value = -1;
  19
  20void process_endpoints(unsigned short usb2d0_intrin)
  21{
  22        /*will hold the packet received */
  23        struct usb_device_descriptor usb_device_packet;
  24        struct usb_configuration_descriptor usb_config_packet;
  25        struct usb_string_descriptor usb_string_packet;
  26        struct devrequest setup_packet;
  27        unsigned int *setup_packet_pt;
  28        unsigned char *packet_pt = NULL;
  29        int temp, temp1;
  30
  31        int i;
  32
  33        /*printf("{USB device} - endpoint 0x%X \n", usb2d0_intrin); */
  34
  35        /*set usb address, seems to not work unless it is done in the next
  36           interrupt, so that is why it is done this way */
  37        if (set_value != -1)
  38                *(unsigned char *)USB2D0_FADDR_8 = (unsigned char)set_value;
  39
  40        /*endpoint 1 */
  41        if (usb2d0_intrin & 0x01) {
  42                setup_packet_pt = (unsigned int *)&setup_packet;
  43
  44                /*copy packet */
  45                setup_packet_pt[0] = *(unsigned int *)USB2D0_FIFO_0;
  46                setup_packet_pt[1] = *(unsigned int *)USB2D0_FIFO_0;
  47                temp = *(unsigned int *)USB2D0_FIFO_0;
  48                temp1 = *(unsigned int *)USB2D0_FIFO_0;
  49
  50                /*do some swapping */
  51                setup_packet.value = swap_16(setup_packet.value);
  52                setup_packet.index = swap_16(setup_packet.index);
  53                setup_packet.length = swap_16(setup_packet.length);
  54
  55                /*clear rx packet */
  56                *(unsigned short *)USB2D0_INCSR0_8 = 0x48;
  57
  58                /*printf("0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", setup_packet.requesttype,
  59                   setup_packet.request, setup_packet.value,
  60                   setup_packet.index, setup_packet.length, temp, temp1 ); */
  61
  62                switch (setup_packet.request) {
  63                case USB_REQ_GET_DESCRIPTOR:
  64
  65                        switch (setup_packet.value >> 8) {
  66                        case USB_DT_DEVICE:
  67                                /*create packet */
  68                                usb_device_packet.bLength = 18;
  69                                usb_device_packet.bDescriptorType =
  70                                    USB_DT_DEVICE;
  71#ifdef USB_2_0_DEVICE
  72                                usb_device_packet.bcdUSB = swap_16(0x200);
  73#else
  74                                usb_device_packet.bcdUSB = swap_16(0x110);
  75#endif
  76                                usb_device_packet.bDeviceClass = 0xff;
  77                                usb_device_packet.bDeviceSubClass = 0;
  78                                usb_device_packet.bDeviceProtocol = 0;
  79                                usb_device_packet.bMaxPacketSize0 = 32;
  80                                usb_device_packet.idVendor = swap_16(1);
  81                                usb_device_packet.idProduct = swap_16(2);
  82                                usb_device_packet.bcdDevice = swap_16(0x300);
  83                                usb_device_packet.iManufacturer = 1;
  84                                usb_device_packet.iProduct = 1;
  85                                usb_device_packet.iSerialNumber = 1;
  86                                usb_device_packet.bNumConfigurations = 1;
  87
  88                                /*put packet in fifo */
  89                                packet_pt = (unsigned char *)&usb_device_packet;
  90                                break;
  91
  92                        case USB_DT_CONFIG:
  93                                /*create packet */
  94                                usb_config_packet.bLength = 9;
  95                                usb_config_packet.bDescriptorType =
  96                                    USB_DT_CONFIG;
  97                                usb_config_packet.wTotalLength = swap_16(25);
  98                                usb_config_packet.bNumInterfaces = 1;
  99                                usb_config_packet.bConfigurationValue = 1;
 100                                usb_config_packet.iConfiguration = 0;
 101                                usb_config_packet.bmAttributes = 0x40;
 102                                usb_config_packet.bMaxPower = 0;
 103
 104                                /*put packet in fifo */
 105                                packet_pt = (unsigned char *)&usb_config_packet;
 106                                break;
 107
 108                        case USB_DT_STRING:
 109                                /*create packet */
 110                                usb_string_packet.bLength = 2;
 111                                usb_string_packet.bDescriptorType =
 112                                    USB_DT_STRING;
 113                                usb_string_packet.wData[0] = 0x0094;
 114
 115                                /*put packet in fifo */
 116                                packet_pt = (unsigned char *)&usb_string_packet;
 117                                break;
 118                        }
 119
 120                        /*put packet in fifo */
 121                        for (i = 0; i < (setup_packet.length); i++) {
 122                                *(unsigned char *)USB2D0_FIFO_0 = packet_pt[i];
 123                        }
 124
 125                        /*give tx command */
 126                        *(unsigned short *)USB2D0_INCSR0_8 = 0x0a;
 127
 128                        break;
 129
 130                case USB_REQ_SET_ADDRESS:
 131
 132                        /*copy usb address */
 133                        set_value = setup_packet.value;
 134
 135                        break;
 136                }
 137
 138        }
 139}
 140
 141void process_other(unsigned char usb2d0_intrusb)
 142{
 143
 144        /*check for sof */
 145        if (usb2d0_intrusb & 0x08) {
 146                /*printf("{USB device} - sof detected\n"); */
 147        }
 148
 149        /*check for reset */
 150        if (usb2d0_intrusb & 0x04) {
 151                /*printf("{USB device} - reset detected\n"); */
 152
 153                /*copy usb address of zero, need to do this when usb reset */
 154                set_value = 0;
 155        }
 156
 157        if (usb2d0_intrusb & 0x02) {
 158                /*printf("{USB device} - resume detected\n"); */
 159        }
 160
 161        if (usb2d0_intrusb & 0x01) {
 162                /*printf("{USB device} - suspend detected\n"); */
 163        }
 164}
 165
 166int usbInt(void)
 167{
 168        /*Must read these 2 registers and use values to clear interrupts.  If you
 169           do not read them then the interrupt will not be cleared.  If you do not
 170           use the variable the optimizer will not do a read. */
 171        volatile unsigned short usb2d0_intrin =
 172            *(unsigned short *)USB2D0_INTRIN_16;
 173        volatile unsigned char usb2d0_intrusb =
 174            *(unsigned char *)USB2D0_INTRUSB_8;
 175
 176        /*check if there was an endpoint interrupt */
 177        if (usb2d0_intrin != 0) {
 178                process_endpoints(usb2d0_intrin);
 179        }
 180
 181        /*check for other interrupts */
 182        if (usb2d0_intrusb != 0) {
 183                process_other(usb2d0_intrusb);
 184        }
 185
 186        return 0;
 187}
 188
 189#if defined(CONFIG_440EPX)
 190void usb_dev_init()
 191{
 192        printf("USB 2.0 Device init\n");
 193
 194        /*usb dev init */
 195        *(unsigned char *)USB2D0_POWER_8 = 0xa1;        /* 2.0 */
 196
 197        /*enable interrupts */
 198        *(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f;
 199
 200        irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,
 201                            NULL);
 202}
 203#else
 204void usb_dev_init()
 205{
 206#ifdef USB_2_0_DEVICE
 207        printf("USB 2.0 Device init\n");
 208        /*select 2.0 device */
 209        mtsdr(SDR0_USB0, 0x0);  /* 2.0 */
 210
 211        /*usb dev init */
 212        *(unsigned char *)USB2D0_POWER_8 = 0xa1;        /* 2.0 */
 213#else
 214        printf("USB 1.1 Device init\n");
 215        /*select 1.1 device */
 216        mtsdr(SDR0_USB0, 0x2);  /* 1.1 */
 217
 218        /*usb dev init */
 219        *(unsigned char *)USB2D0_POWER_8 = 0xc0;        /* 1.1 */
 220#endif
 221
 222        /*enable interrupts */
 223        *(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f;
 224
 225        irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,
 226                            NULL);
 227}
 228#endif
 229
 230#endif /* CONFIG_440EP || CONFIG_440EPX */
 231