-------------------------------------------------------------------------------
Howto for Linux device driver for the AMD5536 USB Device Controller (UDC)
for gadget driver stack
-------------------------------------------------------------------------------

Author: Thomas Dahlmann

INTRODUCTION:

The AMD5536 UDC is part of x86 southbridge AMD5536 and MIPS CPU Au1200.
It is a DMA capable usb device controller. The usb port is shared
between host and UDC. The on-chip OTG controller is used to switch the
usb port between host, UDC and neutral. So amd5536otg driver is needed
to get the UDC operating.

-------------------------------------------------------------------------------
WHAT YOU NEED:
-------------------------------------------------------------------------------

copy/replace following files to /usr/src/linux/drivers/usb/gadget
        amd5536udc.c
        amd5536udc.h
        amd5536otg-fsm.c
        amd5536otg.h
        amd5536uoc.c
        amd5536uoc.h
        ether.c
        file_storage.c
        zero.c
        gadget_chips.h
        Makefile
        Kconfig 

-------------------------------------------------------------------------------
HOW TO INSTALL IT:
-------------------------------------------------------------------------------

change to directory /usr/src/linux

configure gadget as module:
        "make menuconfig"
        under "Code maturity level options" choose "Prompt for development ..."
        goto "Device Drivers"
        goto "USB support" -> "USB Gadget support"
        choose "Support for USB Gadgets" as module
        under choice "USB Peripheral Controller" choose "AMD5536-UDC"
        under "USB Gadget Drivers"
        choose "Gadget Zero" as module or
        choose "Ethernet Gagdet" as module or
        choose "File-backed Storage Gadget" as module
        choose "AMD5536 USB portmux control (On-The-Go support)"
        under choice "OTG port functionality" choose "Gadget only"
        exit and save config

compile and install modules:
        "make modules modules_install"

-------------------------------------------------------------------------------
HOW TO USE IT:
-------------------------------------------------------------------------------

*** How to load FILE-BACKED STORAGE gadget driver - mass storage ***
enable USB mass storage support for linux host:
        change to directory /usr/src/linux
        "make menuconfig"
        under "File systems" choose "DOS/FAT/NT filesystems"
        choose "MSDOS fs support"
        under "Device Drivers" under "SCSI device support"
                choose "SCSI device support"
                choose "SCSI generic support"
        under "Device Drivers" under "USB support" in section 
                "USB Device Class drivers" choose
                "USB Mass Storage support"
        compile new kernel
create disk file:
        "dd bs=1M count=128 if=/dev/zero of=/tmp/disk"
        => creates a 128Mbyte image file /tmp/disk
load modules:
        "modprobe amd5536udc"  
        "modprobe g_file_storage file=/tmp/disk"
        "modprobe amd5536otg"
create a primary FAT16 disk partition via linux host site:
        "fdisk /dev/sda", make FAT16 prim. partition
        => "n", "p", "1", "<RETURN>", "<RETURN>", "t", "6", "w",
        "mkdosfs /dev/sda1"
        "sync"
create primary disk partition via Windows XP host site:
        right click on "My Computer"
        choose "Manage" => "Disk Management"
        choose usb disk and follow instructions of partition menu
mount usb mass storage device on linux host:
        make directory "/mnt/gadget/"
        "mount -t msdos /dev/sda1 /mnt/gadget"

***  How to access files of disk image on UDC side ***
When files were copied from host to UDC mass storage device then files
are inside the monolitic disk image (see above) on UDC side. This
disk image can be mounted via the loopback device driver to a 
directory on UDC side to access these files.
Steps on UDC side:
        enable kernel support for loopback device
        change to directory /usr/src/linux
        "make menuconfig"
        under "Block devices" choose "Loopback device support"
                and recompile the kernel
        determine offset inside disk image:
        "fdisk -l -u disk_image", output is like:
>> You must set cylinders.
>> You can do this from the extra functions menu.
>>
>> Disk /tmp/disk128: 5 heads, 52 sectors, 0 cylinders
>> Units = sectors of 1 * 512 bytes
>>
>>         Device Boot    Start       End    Blocks   Id  System
>> /tmp/disk128p1            52    262079    131014    6  FAT16

        get offset my multiplying start value by sector size:
        52 * 512 = 26624
        mount disk image:
        "mount -o loop,offset=26624 -t msdos disk_image /mnt"


*** How to load ZERO gadget driver - simple BULK loop back ***
load modules:
UDC driver:
        (a) Slave/Fifo mode:       "modprobe amd5536udc use_dma=0"
        (b) DMA Buffer Fill mode:  "modprobe amd5536udc use_dma=1" 
        default:
        (c) DMA PPBNDU mode:       "modprobe amd5536udc"  
        (d) DMA PPBDU mode:        "modprobe amd5536udc use_dma=1 use_dma_ppb=1 use_dma_ppb_du=1"  
        (e) fullspeed mode:        "modprobe amd5536udc use_fullspeed=1", can be combined
                                    with all dma modes  
        (f) special higspeed
            tx buffer size:        "modprobe amd5536udc hs_tx_buf=<buf_size in dwords>"
                                   example: "modprobe amd5536udc use_dma=1 hs_tx_buf=128"
                                            => buffer size = 512 bytes (=bulk max packet)
Gadget Zero driver:
        (a) Bulk loop:             "modprobe g_zero"
        (b) Int loop:              "modprobe g_zero use_interrupt_traffic=1"
        (c) Source/Sink            "modprobe g_zero loopdefault=0"
                                   OUT data must all be zero's
        (d) Source/Sink count      "modprobe g_zero loopdefault=0 pattern=1"
                                   each OUT packet must count modulo63 (0,1,..,62,0,1,..) 
OTG driver:                        "modprobe amd5536otg"
example:
        "modprobe amd5536udc"
        "modprobe g_zero"
        "modprobe amd5536otg"
        => loads driver for DMA PPBNDU mode and Bulk loop  


*** How to use ETHERNET gadget driver (CDC protocol) ***
                   with Linux Host
UDC side bringup: 
        load gadget modules
        "modprobe amd5536udc"  
        "modprobe g_ether"
        "modprobe amd5536otg"
        "ifconfig usb0 192.168.0.2"  
Host side bringup: 
        install support for CDC Ethernet:
        change to directory /usr/src/linux
        "make menuconfig"
        under "Device Drivers" under "USB support" under
        "USB Network adapters" choose
        "Multi-purpose USB Networking Framework"
        choose "CDC Ethernet support"
        compile mew kernel
        "modprobe CDCEther"
        "ifconfig eth1 192.168.0.1"
        note: assuming there is one network card assigned to eth0,
                otherwise kernel messages of CDC Ethernet module show
                which interface (ethX) is used 
Use network connection: 
        after bringup of host and UDC side it behaves like a normal
                ethernet connection between host and UDC
        test the connection:
        host side: "ping -I eth1 192.168.0.2"
        UDC side : "ping -I usb0 192.168.0.1"
        note: the "-I" option assures that the USB cable is used, the
                option can be omitted when the routing table is setup to avoid
                using other network interfaces as eth0

