This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

USB to Serial on OMAP L138 USB2.0

Other Parts Discussed in Thread: DA8XX, OMAPL138

Hi.

I have a USB to Serial converter connected to USB2.0 on OMAP L138 running Linux 3.3 from the PSP 3.22 package.

My first issue was getting the USB2.0 in Host mode such that it will register the connected devices. Although there is a large amount of information on this in forums, none of them led to solving my problem. I eventually discovered that the port is always in peripheral mode irrespective of the state of the ID pin. I eventually gave up trying to find an elegant solution and just forced the port into host-only mode by adding the line: 

cfgchip2 |= 0x2000;

in FILE: board-da850-evm.c; FUNCTION: da850_evm_usb_init() after all other alterations to the cfgchip2 variable was made.  

This worked for me and perhaps it will suffice for others as crude a solution it may be.

I am now facing a subsequent issue. Upon boot, Linux sees the USB devices but does not assign them to ttyUSB*. There are some forums on this issue, but once again they are not helping me solve the problem. lsusb shows the devices and mknod adds the devices to /dev/ttyUSB* but applying cat to them results in a no such device error. 

The device is hardwired in and can therefore not be plugged in and out nor can the power to it be recycled. I know the hardware is fine as it all worked on Linux 2.6.

Any help would be appreciated.

  • Hi Reino,

    I have done this experiment last year and had a detailed discussion on this forum( Refer the link below). Able to enable the corresponding drivers to support USB to serial converter in DaVinci PSP 3.22; able to configure the USB 2.0 port as Host interface and after connecting the USB to serial converter, able to open the serial port as ttyUSBx . I some how had those snapshots of result screen. Please have a look at it for your reference.

     

    Link : http://e2e.ti.com/support/embedded/linux/f/354/p/197489/1053895.aspx ( refer all the pages from 1 -3 )

    If this is the one you are trying to achieve, I will give you step by step procedure. Please do reply.

     

    Regards,

    Shankari

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------

  • Hi Shankari,

    Thanks for your response and attached link.

    I went through the whole thread again and although the problem is similar I am unable to find a solution from it.

    I have only one usb-to-serial converter attached (FT4232H from FTDI). The drivers included in my kernel is the generic serial driver and the FTDI single port serial driver. My problem is that the kernel does not detect that the device is a converter and therefore does not attach it to ttyUSB.

    I see in the thread that you were able to solve the problem without patching the kernel. I would like to prevent patching here as well, if possible.

    Regards,

    Reino

  • Hi,

    Due to the fact that the device is hardwired I cannot connect/disconnect it from the processor. I am attaching some information which might help.

    Uncompressing Linux... done, booting the kernel.
    Booting Linux on physical CPU 0
    Linux version 3.3.0 (user@PQD) (gcc version 4.5.3 20110311 (prerelease) (GCC) ) #3 PREEMPT Fri May 23 11:26:18 SAST 2014
    CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
    CPU: VIVT data cache, VIVT instruction cache
    Machine: DaVinci DA850/OMAP-L138/AM18x EVM
    Memory policy: ECC disabled, Data cache writeback
    BUG: mapping for 0x80000000 at 0xfffe0000 out of vmalloc space
    DaVinci da850/omap-l138/am18x variant 0x1
    Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 23296
    Kernel command line: mem=32M@0xc0000000 mem=60M@0xc4400000 console=ttyS2,115200n8 root=/dev/sda1 rw noinitrd rootwait ip=192.168.0.70:192.168.0.39:192.168.0.39:255.255.255.0::eth0:on
    PID hash table entries: 512 (order: -1, 2048 bytes)
    Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
    Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
    Memory: 32MB 60MB = 92MB total
    Memory: 88728k/88728k available, 5480k reserved, 0K highmem
    Virtual kernel memory layout:
        vector  : 0xffff0000 - 0xffff1000   (   4 kB)
        fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
        vmalloc : 0xc8800000 - 0xff000000   ( 872 MB)
        lowmem  : 0xc0000000 - 0xc8000000   ( 128 MB)
        modules : 0xbf000000 - 0xc0000000   (  16 MB)
          .text : 0xc0008000 - 0xc040c000   (4112 kB)
          .init : 0xc040c000 - 0xc0435000   ( 164 kB)
          .data : 0xc0436000 - 0xc045ffa0   ( 168 kB)
           .bss : 0xc045ffc4 - 0xc047d16c   ( 117 kB)
    SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
    NR_IRQS:245
    Console: colour dummy device 80x30
    Calibrating delay loop... 148.88 BogoMIPS (lpj=744448)
    pid_max: default: 32768 minimum: 301
    Mount-cache hash table entries: 512
    CPU: Testing write buffer coherency: ok
    Setting up static identity map for 0xc0319fb8 - 0xc031a010
    gpiochip_add: registered GPIOs 0 to 31 on device: DaVinci
    gpiochip_add: registered GPIOs 32 to 63 on device: DaVinci
    gpiochip_add: registered GPIOs 64 to 95 on device: DaVinci
    gpiochip_add: registered GPIOs 96 to 127 on device: DaVinci
    gpiochip_add: registered GPIOs 128 to 143 on device: DaVinci
    DaVinci: 144 gpio irqs
    print_constraints: dummy: 
    NET: Registered protocol family 16
    -----------> Registering USB2.0 with forced Host-mode
    bio: create slab <bio-0> at 0
    SCSI subsystem initialized
    usbcore: registered new interface driver usbfs
    usbcore: registered new interface driver hub
    usbcore: registered new device driver usb
    print_constraints: VDCDC1: 3200 <--> 3300 mV at 3300 mV 
    print_constraints: VDCDC2: 1750 <--> 3300 mV at 3300 mV 
    print_constraints: VDCDC3: 950 <--> 1350 mV at 1200 mV 
    print_constraints: LDO1: 1800 mV 
    print_constraints: LDO2: 1150 <--> 1300 mV at 1200 mV 
    i2c-gpio i2c-gpio.1: using pins 20 (SDA) and 21 (SCL)
    Switching to clocksource timer0_1
    musb-hdrc: version 6.0, ?dma?, otg (peripheral+host)
    musb-hdrc musb-hdrc: dma type: dma-cppi41
    MUSB255 controller's USBSS revision = 4ea11003
    Waiting for USB PHY clock good...
    musb-hdrc musb-hdrc: USB OTG mode controller at fee00000 using DMA, IRQ 58
    NET: Registered protocol family 2
    IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
    TCP established hash table entries: 4096 (order: 3, 32768 bytes)
    TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
    TCP: Hash tables configured (established 4096 bind 4096)
    TCP reno registered
    UDP hash table entries: 256 (order: 0, 4096 bytes)
    UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
    NET: Registered protocol family 1
    RPC: Registered named UNIX socket transport module.
    RPC: Registered udp transport module.
    RPC: Registered tcp transport module.
    RPC: Registered tcp NFSv4.1 backchannel transport module.
    EMAC: MII PHY configured, RMII PHY will not be functional
    JFFS2 version 2.2. (NAND) �© 2001-2006 Red Hat, Inc.
    msgmni has been set to 173
    io scheduler noop registered (default)
    da8xx_lcdc da8xx_lcdc.0: GLCD: Found Sharp_LK043T1DG01 panel
    Console: switching to colour frame buffer device 60x34
    Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
    serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a AR7
    serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a AR7
    serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a AR7
    console [ttyS2] enabled
    brd: module loaded
    ahci ahci: forcing PORTS_IMPL to 0x1
    ahci ahci: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl platform mode
    ahci ahci: flags: ncq sntf pm led clo only pmp pio slum part ccc 
    scsi0 : ahci_platform
    ata1: SATA max UDMA/133 mmio [mem 0x01e18000-0x01e19fff] port 0x100 irq 67
    spi_davinci spi_davinci.1: DMA: supported
    spi_davinci spi_davinci.1: DMA: RX channel: 18, TX channel: 19, event queue: 0
    spi_davinci spi_davinci.1: Controller at 0xfef0e000
    davinci_mdio davinci_mdio.0: davinci mdio revision 1.5
    davinci_mdio davinci_mdio.0: detected phy mask fffffffe
    davinci_mdio.0: probed
    davinci_mdio davinci_mdio.0: phy[0]: device davinci_mdio-0:00, driver SMSC LAN8710/LAN8720
    ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
    ohci ohci.0: DA8xx OHCI
    ohci ohci.0: new USB bus registered, assigned bus number 1
    Waiting for USB PHY clock good...
    ohci ohci.0: irq 59, io mem 0x01e25000
    usb usb1: New USB device found, idVendor=1d6b, idProduct=0001
    usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    usb usb1: Product: DA8xx OHCI
    usb usb1: Manufacturer: Linux 3.3.0 ohci_hcd
    usb usb1: SerialNumber: ohci.0
    hub 1-0:1.0: USB hub found
    hub 1-0:1.0: 1 port detected
    usbcore: registered new interface driver usbserial
    USB Serial support registered for generic
    usbcore: registered new interface driver usbserial_generic
    usbserial: USB Serial Driver core
    USB Serial support registered for FTDI USB Serial Device
    usbcore: registered new interface driver ftdi_sio
    ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver
    USB Serial support registered for pl2303
    usbcore: registered new interface driver pl2303
    pl2303: Prolific PL2303 USB to serial adaptor driver
     gadget: using random self ethernet address
     gadget: using random host ethernet address
    usb0: MAC 3e:f9:48:f1:30:73
    usb0: HOST MAC 1a:9c:1c:50:22:a2
     gadget: Ethernet Gadget, version: Memorial Day 2008
     gadget: g_ether ready
    musb-hdrc musb-hdrc: MUSB HDRC host driver
    musb-hdrc musb-hdrc: new USB bus registered, assigned bus number 2
    usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
    usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    usb usb2: Product: MUSB HDRC host driver
    usb usb2: Manufacturer: Linux 3.3.0 musb-hcd
    usb usb2: SerialNumber: musb-hdrc
    hub 2-0:1.0: USB hub found
    hub 2-0:1.0: 1 port detected
    input: TPS6507x Touchscreen as /devices/platform/i2c-gpio.1/i2c-1/1-0048/input/input0
    i2c /dev entries driver
    watchdog watchdog: heartbeat 60 sec
    cpuidle: using governor ladder
    cpuidle: using governor menu
    TCP cubic registered
    NET: Registered protocol family 17
    regulator_init_complete: LDO2: incomplete constraints, leaving on
    regulator_init_complete: LDO1: incomplete constraints, leaving on
    regulator_init_complete: VDCDC3: incomplete constraints, leaving on
    regulator_init_complete: VDCDC2: incomplete constraints, leaving on
    regulator_init_complete: VDCDC1: incomplete constraints, leaving on
    console [netcon0] enabled
    netconsole: network logging started
    davinci_emac davinci_emac.1: using random MAC addr: 3a:cf:88:bc:63:99
    davinci_mdio davinci_mdio.0: resetting idled controller
    net eth0: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=davinci_mdio-0:00, id=7c0f1)
    usb 2-1: new high-speed USB device number 2 using musb-hdrc
    usb 2-1: New USB device found, idVendor=0424, idProduct=2517
    usb 2-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
    hub 2-1:1.0: USB hub found
    hub 2-1:1.0: 7 ports detected
    usb 2-1.3: new full-speed USB device number 3 using musb-hdrc
    usb 2-1.3: New USB device found, idVendor=1546, idProduct=01a6
    usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    usb 2-1.3: Product: u-blox 6  -  GPS Receiver
    usb 2-1.3: Manufacturer: u-blox AG - www.u-blox.com
    PHY: davinci_mdio-0:00 - Link is Up - 100/Full
    IP-Config: Complete:
         device=eth0, addr=192.168.0.70, mask=255.255.255.0, gw=192.168.0.39,
         host=192.168.0.70, domain=, nis-domain=(none),
         bootserver=192.168.0.39, rootserver=192.168.0.39, rootpath=
    ata1: link is slow to respond, please be patient (ready=0)
    ata1: softreset failed (device not ready)
    ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
    ata1.00: ATA-8: TOSHIBA MQ01ABD100, AX001A, max UDMA/100
    ata1.00: 1953525168 sectors, multi 16: LBA48 NCQ (depth 31/32)
    ata1.00: configured for UDMA/100
    scsi 0:0:0:0: Direct-Access     ATA      TOSHIBA MQ01ABD1 AX00 PQ: 0 ANSI: 5
    sd 0:0:0:0: [sda] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
    sd 0:0:0:0: [sda] 4096-byte physical blocks
    sd 0:0:0:0: Attached scsi generic sg0 type 0
    sd 0:0:0:0: [sda] Write Protect is off
    sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
     sda: sda1 sda2
    sd 0:0:0:0: [sda] Attached SCSI disk
    EXT2-fs (sda1): warning: mounting unchecked fs, running e2fsck is recommended
    VFS: Mounted root (ext2 filesystem) on device 8:1.
    Freeing init memory: 164K
    INIT: version 2.86 booting
    Please wait: booting...
    Starting udev
    EXT2-fs (sda1): error: ext2_lookup: deleted inode referenced: 114725
    cmp: /etc/udev/saved.uname: Input/output error
    udevd (527): /proc/527/oom_adj is deprecated, please use /proc/527/oom_score_adj instead.
    EXT2-fs (sda2): warning: mounting unchecked fs, running e2fsck is recommended
    Remounting root file system...
    Caching udev devnodes
    Populating dev cacheEXT2-fs (sda1): error: ext2_lookup: deleted inode referenced: 114725
    mv: cannot stat '/etc/udev/saved.uname': Input/output error
    ALSA: Restoring mixer settings...
    Configuring network interfaces... /usr/sbin/alsactl: load_state:1625: No soundcards found...
    done.
    Setting up IP spoofing protection: rp_filter.
    hwclock: can't open '/dev/misc/rtc': No such file or directory
    Wed Jan  6 15:44:00 UTC 2021
    hwclock: can't open '/dev/misc/rtc': No such file or directory
    INIT: Entering runlevel: 5
    Starting system message bus: dbus.
    Starting Dropbear SSH server: dropbear.
    Starting telnet daemon.
    Starting network benchmark server: netserver.
    Starting Samba: smbd.
    Starting syslogd/klogd: done
    Starting thttpd.
    BusyBox v1.13.2 (2011-12-23 12:39:34 IST) multi-call binary
    
    Usage: mknod [OPTIONS] NAME TYPE MAJOR MINOR
    
    Create a special file (block, character, or pipe)
    
    Options:
            -m      Create the special file using the specified mode (default a=rw)
    TYPEs include:
            b:      Make a block device
            c or u: Make a character device
            p:      Make a named pipe (MAJOR and MINOR are ignored)
    
    
     _____                    _____           _         _   
    |  _  |___ ___ ___ ___   |  _  |___ ___  |_|___ ___| |_ 
    |     |  _| .'| . | . |  |   __|  _| . | | | -_|  _|  _|
    |__|__|_| |__,|_  |___|  |__|  |_| |___|_| |___|___|_|  
                  |___|                    |___|            
    
    Arago Project http://arago-project.org arago ttyS2
    
    Arago 2011.06 arago ttyS2

    root@arago:~# dmesg | grep USB
    -----------> Registering USB2.0 with forced Host-mode
    MUSB255 controller's USBSS revision = 4ea11003
    Waiting for USB PHY clock good...
    musb-hdrc musb-hdrc: USB OTG mode controller at fee00000 using DMA, IRQ 58
    ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
    ohci ohci.0: new USB bus registered, assigned bus number 1
    ohci ohci.0: starting USB controller
    Waiting for USB PHY clock good...
    usb usb1: New USB device found, idVendor=1d6b, idProduct=0001
    usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    hub 1-0:1.0: USB hub found
    USB Serial support registered for generic
    usbserial: USB Serial Driver core
    USB Serial support registered for FTDI USB Serial Device
    ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver
    USB Serial support registered for pl2303
    pl2303: Prolific PL2303 USB to serial adaptor driver
    musb-hdrc musb-hdrc: MUSB HDRC host driver
    musb-hdrc musb-hdrc: new USB bus registered, assigned bus number 2
    musb-hdrc musb-hdrc: supports USB remote wakeup
    usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
    usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    usb usb2: Product: MUSB HDRC host driver
    hub 2-0:1.0: USB hub found
    usb 2-1: new high-speed USB device number 2 using musb-hdrc
    usb 2-1: New USB device found, idVendor=0424, idProduct=2517
    usb 2-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
    hub 2-1:1.0: USB hub found
    usb 2-1.3: new full-speed USB device number 3 using musb-hdrc
    usb 2-1.3: New USB device found, idVendor=1546, idProduct=01a6
    usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0

    root@arago:~# ls /dev
    block               tty12               tty50
    bus                 tty13               tty51
    char                tty14               tty52
    console             tty15               tty53
    cpu_dma_latency     tty16               tty54
    disk                tty17               tty55
    fb                  tty18               tty56
    fb0                 tty19               tty57
    full                tty2                tty58
    i2c-1               tty20               tty59
    initctl             tty21               tty6
    input               tty22               tty60
    kmem                tty23               tty61
    kmsg                tty24               tty62
    log                 tty25               tty63
    mem                 tty26               tty7
    network_latency     tty27               tty8
    network_throughput  tty28               tty9
    null                tty29               ttyS0
    ptmx                tty3                ttyS1
    pts                 tty30               ttyS2
    ptyp0               tty31               ttyp0
    ptyp1               tty32               ttyp1
    ptyp2               tty33               ttyp2
    ptyp3               tty34               ttyp3
    ptyp4               tty35               ttyp4
    ptyp5               tty36               ttyp5
    ptyp6               tty37               ttyp6
    ptyp7               tty38               ttyp7
    ram0                tty39               ubi_ctrl
    random              tty4                udev_network_queue
    sda                 tty40               urandom
    sda1                tty41               vcs
    sda2                tty42               vcs1
    sg0                 tty43               vcs2
    shm                 tty44               vcsa
    spidev1.0           tty45               vcsa1
    tty                 tty46               vcsa2
    tty0                tty47               watchdog
    tty1                tty48               zero
    tty10               tty49
    tty11               tty5

    root@arago:~# lsusb
    Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 002 Device 002: ID 0424:2517 Standard Microsystems Corp. 
    Bus 002 Device 003: ID 1546:01a6 U-Blox AG 

    Regards,

    Reino

  • Hi Reino,

    I havenot looked into the attachment yet. Would you please upload your .config file too?

    Hope you enabled the driver for USB to serial converter while building kernel. I just wanted to ensure!!.

       [*] Device Drivers ---->

           [*] USB support ---->

                [*] USB Serial Converter support  --->

                         [*] USB FTDI Single Port Serial Driver

    Reino says said:
     My first issue was getting the USB2.0 in Host mode such that it will register the connected devices. Although there is a large amount of information on this in forums, none of them led to solving my problem. I eventually discovered that the port is always in peripheral mode irrespective of the state of the ID pin. I eventually gave up trying to find an elegant solution and just forced the port into host-only mode by adding the line:

    Please configure the USB 2.0 in Host mode like below while building the kernel.

    Device Drivers --->

        USB support --->
            <*> Support for Host-side USB
            --- Miscellaneous USB options
            [*] USB device class-devices
            --- USB Host Controller Drivers
            <*> Inventra Highspeed Dual Role Controller (TI, ADI, ...)
            --- Platform Glue Layer
            [*] DA8xx/OMAP-L1x
                 <*>     MUSB DMA mode (TI CPPI4.1)  --->
                 [ ]     Disable DMA (always use PIO)

    After configuring the USB 2.0 port as Host, first try connecting some peripheral devices like USB pen drive or USB card reader. So that you will make sure first, that the USB 2.0 is in Host mode.

    If these suggestions doesnot work out for you, then I will upload the .config file for da850 EVM, so that you can build teh kernel image and test it.

     

    Regards,

    Shankari

     

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------

  • Hi Shankari,

    I do not have access to the .config file right now, but if you have a look at Boot.txt it shows that the FTDI driver is definitely included in the kernel build. In connection with setting up the kernel for Host mode: I have tried what you suggested before as well as some variations, but none of them worked. The solution I could come up with was to change the source code as mentioned previously. 

    After this I confirmed that the USB 2.0 port is in Host mode. This is the only way the kernel would recognize devices attached to the USB 2.0 port. In line with your suggesting, when inserting and removing USB devices they are detected as expected. 

    Perhaps I could have a look at the .config file you are referring to? But from what I can see, the kernel seems to be fine? 

    Regards,

    Reino

  • Just some more information.

    I ran a little app after boot-up which makes the DSP disable-wait-enable the USB2.0 PHY to simulate disconnecting/reconnecting a device. The loading of devices were no different to boot-up.

    Has anyone successfully interfaced with an USB to serial converter using Linux 3.3 on a Logic PD Zoom SOM?

    I am starting to consider writing a driver to run on the DSP to handle the interfacing, but would really appreciate anymore insight into this problem before I shift my attention. 

    Regards,

    Reino

  • Hi Reino,

    In DaVinci-PSP-SDK-03.22.00.06, I tested again by configuring as below and able to interface the USB to serial converter.

    1. Enable the Gadget driver too in addtion to the Host mode.

    [*] USB Gadget support --->

    [*] USB peripheral controller ( Inventra HDRC...) -->

    [*] USB Gadget Drivers ( Ethernet Gadget with CDC Ethernet Support) --->

    You may ask why to enable the Gadget support. Here, in this version of DaVinci PSP, the USB 2.0 interface works as OTG ( both as Host and peripheral) . Once this configuration is done, able to detect as well list the "/devttyUSB0" terminal.

    I have uploaded the .config for your reference.

    With reference to the attached .config file, please modify your .config file and let me know the result.

     

    Regards,

    Shankari

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------   

  • Hi Shankari,

    Thank you for the file.

    I used your config file as is with the exception of adding the FTDI driver. The results were unfortunately the same.

    The Logic PD board has a Standard Microsystems USB hub connected to the OMAP. One of the ports of this hub is hardwired to the FTDI converter with another hub port connected to a USB plug. I have discovered that the kernel works when I plug a FTDI to USB converter into the USB plug. Even if it is plugged in before boot-up, that specific device is detected. Why would the FTDI converter which is hardwired directly to the Microsystems hub be different?

    Did you test the config file you sent me on a Logic PD board?

    Regards,

    Reino 

  • Hi Shankari,

    Another thing which might be applicable:

    Even when using the config script you provided, if I don't force the USB port into host as described in the beginning of this thread, no devices are detected. 

    Do you know whether the FTDI driver in the PSP 3.22 package supports the FT4232H device from FTDI?

    Regards,

    Reino

  • Hi Reino,

    Reino says said:
    Did you test the config file you sent me on a Logic PD board?

    Yes, I had tested the Kernel image built using the .config file uploaded here on OMAPL138 SDI EVM and able to get the /dev/ttyUSB0 when the USB to serial converter is inserted into USB 2.0 port.

    I have few questions here.

    1.You mentioned as a Logic PD board. So, it is a standard LOGIC PD EVM and not a custom board right?

    2.You mean to say that when a FTDI converter is connected directly to USB 2.0 interface, it is working for you and when it is hardwired, it is not working? or through hub it is not working?

    Reino says said:
    One of the ports of this hub is hardwired to the FTDI converter with another hub port connected to a USB plug

    Do you use an external hub? I do not understand what you mean by "FTDI converter with another hub port connected to a USB plug"

    Through hub you are connecting the FTDI converter into USB 2.0?

    If possible would you please upload the snapshot of your hardware set up?

    Would you please upload the board file?

    I have attached my boot logs.

    
    U-Boot 2009.11 (Jul 17 2012 - 16:59:18)
    
    I2C:   ready
    DRAM:  64 MB
    MMC:   davinci: 0
    In:    serial
    Out:   serial
    Err:   serial
    ARM Clock : 300000000 Hz
    DDR Clock : 150000000 Hz
    Net:   Ethernet PHY: GENERIC @ 0x00
    
    Hit any key to stop autoboot:  0
    Card did not respond to voltage select!
    8192 KiB W25Q64 at 0:0 is now current device
    Wrong Image Format for bootm command
    ERROR: can't get kernel image!
    U-Boot > tftpboot
    Using  device
    TFTP from server 10.100.1.72; our IP address is 10.100.1.155
    Filename 'uImage'.
    Load address: 0xc0700000
    Loading: #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             ######################################################
    done
    Bytes transferred = 2601960 (27b3e8 hex)
    U-Boot >
    bootm
    ## Booting kernel from Legacy Image at c0700000 ...
       Image Name:   Linux-3.3.0
       Image Type:   ARM Linux Kernel Image (uncompressed)
       Data Size:    2601896 Bytes =  2.5 MB
       Load Address: c0008000
       Entry Point:  c0008000
       Verifying Checksum ... OK
       Loading Kernel Image ... OK
    OK
    
    Starting kernel ...
    
    Uncompressing Linux... done, booting the kernel.
    Booting Linux on physical CPU 0
    Linux version 3.3.0 (root@INFCH05297) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #4 PREEMPT Tue May 27 14:54:01 IST 2014
    CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
    CPU: VIVT data cache, VIVT instruction cache
    Machine: DA850 SDI Development Board
    Memory policy: ECC disabled, Data cache writeback
    BUG: mapping for 0x80000000 at 0xfffe0000 out of vmalloc space
    DaVinci da850/omap-l138/am18x variant 0x1
    Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
    Kernel command line: console=ttyS2,115200n8 root=/dev/nfs nfsroot=10.100.1.72:/usr/local/filesystem_omapl138 ip=dhcp
    PID hash table entries: 256 (order: -2, 1024 bytes)
    Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
    Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
    Memory: 64MB = 64MB total
    Memory: 59424k/59424k available, 6112k reserved, 0K highmem
    Virtual kernel memory layout:
        vector  : 0xffff0000 - 0xffff1000   (   4 kB)
        fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
        vmalloc : 0xc4800000 - 0xff000000   ( 936 MB)
        lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
        modules : 0xbf000000 - 0xc0000000   (  16 MB)
          .text : 0xc0008000 - 0xc04d7000   (4924 kB)
          .init : 0xc04d7000 - 0xc0503000   ( 176 kB)
          .data : 0xc0504000 - 0xc0541100   ( 245 kB)
           .bss : 0xc0541124 - 0xc055f1ac   ( 121 kB)
    SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
    NR_IRQS:245
    Console: colour dummy device 80x30
    Calibrating delay loop... 148.88 BogoMIPS (lpj=744448)
    pid_max: default: 32768 minimum: 301
    Mount-cache hash table entries: 512
    CPU: Testing write buffer coherency: ok
    Setting up static identity map for 0xc03ab868 - 0xc03ab8c0
    gpiochip_add: registered GPIOs 0 to 31 on device: DaVinci
    gpiochip_add: registered GPIOs 32 to 63 on device: DaVinci
    gpiochip_add: registered GPIOs 64 to 95 on device: DaVinci
    gpiochip_add: registered GPIOs 96 to 127 on device: DaVinci
    gpiochip_add: registered GPIOs 128 to 143 on device: DaVinci
    DaVinci: 144 gpio irqs
    print_constraints: dummy:
    NET: Registered protocol family 16
    bio: create slab <bio-0> at 0
    SCSI subsystem initialized
    usbcore: registered new interface driver usbfs
    usbcore: registered new interface driver hub
    usbcore: registered new device driver usb
    print_constraints: VDCDC1: 3200 <--> 3300 mV at 3300 mV
    print_constraints: VDCDC2: 1750 <--> 3300 mV at 3300 mV
    print_constraints: VDCDC3: 950 <--> 1350 mV at 1200 mV
    print_constraints: LDO1: 1800 mV
    print_constraints: LDO2: 1150 <--> 1300 mV at 1200 mV
    pca953x 1-0020: failed reading register
    i2c-gpio i2c-gpio.1: using pins 20 (SDA) and 21 (SCL)
    Advanced Linux Sound Architecture Driver Version 1.0.24.
    Switching to clocksource timer0_1
    musb-hdrc: version 6.0, ?dma?, otg (peripheral+host)
    musb-hdrc musb-hdrc: dma type: dma-cppi41
    MUSB255 controller's USBSS revision = 4ea11003
    Waiting for USB PHY clock good...
    musb-hdrc musb-hdrc: USB OTG mode controller at fee00000 using DMA, IRQ 58
    NET: Registered protocol family 2
    IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
    TCP established hash table entries: 2048 (order: 2, 16384 bytes)
    TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
    TCP: Hash tables configured (established 2048 bind 2048)
    TCP reno registered
    UDP hash table entries: 256 (order: 0, 4096 bytes)
    UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
    NET: Registered protocol family 1
    RPC: Registered named UNIX socket transport module.
    RPC: Registered udp transport module.
    RPC: Registered tcp transport module.
    RPC: Registered tcp NFSv4.1 backchannel transport module.
    EMAC: RMII PHY configured, MII PHY will not be functional
    JFFS2 version 2.2. (NAND) � 2001-2006 Red Hat, Inc.
    msgmni has been set to 116
    io scheduler noop registered (default)
    da8xx_lcdc da8xx_lcdc.0: GLCD: Found Sharp_LK043T1DG01 panel
    Console: switching to colour frame buffer device 60x34
    Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
    serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a AR7
    serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a AR7
    serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a AR7
    console [ttyS2] enabled
    brd: module loaded
    ahci ahci: forcing PORTS_IMPL to 0x1
    ahci ahci: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl platform mode
    ahci ahci: flags: ncq sntf pm led clo only pmp pio slum part ccc
    scsi0 : ahci_platform
    ata1: SATA max UDMA/133 mmio [mem 0x01e18000-0x01e19fff] port 0x100 irq 67
    spi_davinci spi_davinci.1: DMA: supported
    spi_davinci spi_davinci.1: DMA: RX channel: 18, TX channel: 19, event queue: 0
    m25p80 spi1.0: found s25fl064k, expected m25p64
    m25p80 spi1.0: s25fl064k (8192 Kbytes)
    Creating 4 MTD partitions on "m25p80":
    0x000000000000-0x000000040000 : "U-Boot"
    0x000000040000-0x000000050000 : "U-Boot Environment"
    0x000000050000-0x0000007f0000 : "Linux"
    0x0000007f0000-0x000000800000 : "MAC Address"
    spi_davinci spi_davinci.1: Controller at 0xfef0e000
    davinci_mdio davinci_mdio.0: davinci mdio revision 1.5
    davinci_mdio davinci_mdio.0: detected phy mask fffffffe
    davinci_mdio.0: probed
    davinci_mdio davinci_mdio.0: phy[0]: device davinci_mdio-0:00, driver SMSC LAN8710/LAN8720
    ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
    ohci ohci.0: DA8xx OHCI
    ohci ohci.0: new USB bus registered, assigned bus number 1
    Waiting for USB PHY clock good...
    ohci ohci.0: irq 59, io mem 0x01e25000
    hub 1-0:1.0: USB hub found
    hub 1-0:1.0: 1 port detected
    Initializing USB Mass Storage driver...
    usbcore: registered new interface driver usb-storage
    USB Mass Storage support registered.
    usbcore: registered new interface driver usbserial
    usbserial: USB Serial Driver core
    USB Serial support registered for pl2303
    usbcore: registered new interface driver pl2303
    pl2303: Prolific PL2303 USB to serial adaptor driver
     gadget: using random self ethernet address
     gadget: using random host ethernet address
    usb0: MAC c2:ab:9b:15:02:65
    usb0: HOST MAC 7e:a2:22:27:19:28
     gadget: Ethernet Gadget, version: Memorial Day 2008
     gadget: g_ether ready
    musb-hdrc musb-hdrc: MUSB HDRC host driver
    musb-hdrc musb-hdrc: new USB bus registered, assigned bus number 2
    hub 2-0:1.0: USB hub found
    hub 2-0:1.0: 1 port detected
    input: TPS6507x Touchscreen as /devices/platform/i2c-gpio.1/i2c-1/1-0048/input/input0
    ata1: SATA link down (SStatus 0 SControl 300)
    omap_rtc omap_rtc: rtc core: registered omap_rtc as rtc0
    omap_rtc: RTC power up reset detected
    i2c /dev entries driver
    lirc_dev: IR Remote Control driver registered, major 253
    IR NEC protocol handler initialized
    IR RC5(x) protocol handler initialized
    IR RC6 protocol handler initialized
    IR JVC protocol handler initialized
    IR Sony protocol handler initialized
    IR RC5 (streamzap) protocol handler initialized
    IR SANYO protocol handler initialized
    IR MCE Keyboard/mouse protocol handler initialized
    IR LIRC bridge handler initialized
    Linux video capture interface: v2.00
    usbcore: registered new interface driver uvcvideo
    USB Video Class driver (1.1.1)
    watchdog watchdog: heartbeat 60 sec
    cpuidle: using governor ladder
    cpuidle: using governor menu
    davinci_mmc davinci_mmc.0: Using DMA, 4-bit mode
    usbcore: registered new interface driver usbhid
    usbhid: USB HID core driver
    usbcore: registered new interface driver snd-usb-audio
    ALSA device list:
      No soundcards found.
    TCP cubic registered
    NET: Registered protocol family 17
    regulator_init_complete: LDO2: incomplete constraints, leaving on
    regulator_init_complete: LDO1: incomplete constraints, leaving on
    regulator_init_complete: VDCDC3: incomplete constraints, leaving on
    regulator_init_complete: VDCDC2: incomplete constraints, leaving on
    regulator_init_complete: VDCDC1: incomplete constraints, leaving on
    console [netcon0] enabled
    netconsole: network logging started
    davinci_emac davinci_emac.1: using random MAC addr: 1e:fd:69:84:c7:97
    omap_rtc omap_rtc: setting system clock to 2000-01-01 00:00:00 UTC (946684800)
    davinci_mdio davinci_mdio.0: resetting idled controller
    net eth0: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=davinci_mdio-0:00, id=7c0f1)
    PHY: davinci_mdio-0:00 - Link is Up - 100/Full
    Sending DHCP requests ....., OK
    IP-Config: Got DHCP answer from 0.0.0.0, my address is 10.100.1.144
    IP-Config: Complete:
         device=eth0, addr=10.100.1.144, mask=255.255.255.0, gw=10.100.1.1,
         host=10.100.1.144, domain=chennaiodc.lntinfotech.com, nis-domain=(none),
         bootserver=0.0.0.0, rootserver=10.100.1.72, rootpath=
    VFS: Mounted root (nfs filesystem) on device 0:13.
    Freeing init memory: 176K
    INIT: version 2.86 booting
    Please wait: booting...
    Starting udev
    udevd (632): /proc/632/oom_adj is deprecated, please use /proc/632/oom_score_adj instead.
    Root filesystem already rw, not remounting
    Caching udev devnodes
    Populating dev cachemv: cannot rename '/tmp/devices': No such file or directory
    logger: mount: mount point /proc/bus/usb does not exist
    ALSA: Restoring mixer settings...
    NOT configuring network interfaces: / is an NFS mount
    NOT configuring network interfaces: / is an NFS mount
    /usr/sbin/alsactl: load_state:1625: No soundcards found...
    Tue Apr 10 18:57:00 BST 2012
    INIT: Entering runlevel: 5
    Starting system message bus: dbus.
    Starting Hardware abstraction layer hald
    Starting Dropbear SSH server: dropbear.
    Starting telnet daemon.
    Starting Vixie-cron.
    Starting network benchmark server: netserver.
    Starting syslogd/klogd: done
    Starting thttpd.
    Starting Lighttpd Web Server: lighttpd.
    2012-04-10 18:57:09: (log.c.166) server started
    ***************************************************************
    ***************************************************************
    NOTICE: This file system contains the followin GPLv3 packages:
            binutils-symlinks
            binutils
            gdbserver
    
    If you do not wish to distribute GPLv3 components please remove
    the above packages prior to distribution.  This can be done using
    the opkg remove command.  i.e.:
        opkg remove <package>
    Where <package> is the name printed in the list above
    
    NOTE: If the package is a dependency of another package you
          will be notified of the dependent packages.  You should
          use the --force-removal-of-dependent-packages option to
          also remove the dependent packages as well
    ***************************************************************
    ***************************************************************
    
     _____                    _____           _         _
    |  _  |___ ___ ___ ___   |  _  |___ ___  |_|___ ___| |_
    |     |  _| .'| . | . |  |   __|  _| . | | | -_|  _|  _|
    |__|__|_| |__,|_  |___|  |__|  |_| |___|_| |___|___|_|
                  |___|                    |___|
    
    Arago Project http://arago-project.org omapl138-lcdk ttyS2
    
    Arago 2011.09 omapl138-lcdk ttyS2
    
    omapl138-lcdk login: root
    root@omapl138-lcdk:~# usb 2-1: new full-speed USB device number 2 using musb-hdrc
    pl2303 2-1:1.0: pl2303 converter detected
    usb 2-1: pl2303 converter now attached to ttyUSB0
    Would you please compare your boot logs with it?

     

    Regards,

    Shankari

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------

  • Hi Shankari,

    Thank you for your patience.

    Unfortunately I will not be able to send you a picture of the board, but I have attached a schematic which is terrible but hopefully sufficient.

    The Logic PD SOM we use is standard, but it is mounted on a custom board, not the development kit board. On the SOM there is a USB hub from Standard Micro. This hub is connected to two things of importance. The first is the FTDI converter, the second is a physical USB female connector. The kernel can see the Standard Micro hub, but not the FTDI converter or any device connected to the serial side of the converter. The kernel does however recognize FTDI USB to serial converters that I plug into the USB "plug". 

    I have noticed that the FTDI driver in menuconfig is referred to as a Single port driver which sounds like it should not work for the FTDI converter (FT4232H) that I have hardwired in since that is a quad port converter. But the file ftdi_sio_ids.h in the kernel driver directory does list this device. This makes me believe that the driver will support the FT4232H. Is this perhaps incorrect?

    Regards,

    Reino

  • Hi Shankari,

    I have attached the requested file. My modification is on line 990.

    /*
     * TI DA850/OMAP-L138 EVM board
     *
     * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
     *
     * Derived from: arch/arm/mach-davinci/board-da830-evm.c
     * Original Copyrights follow:
     *
     * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
     * the terms of the GNU General Public License version 2. This program
     * is licensed "as is" without any warranty of any kind, whether express
     * or implied.
     */
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/clk.h>
    #include <linux/console.h>
    #include <linux/i2c.h>
    #include <linux/i2c/at24.h>
    #include <linux/i2c/pca953x.h>
    #include <linux/input.h>
    #include <linux/mfd/tps6507x.h>
    #include <linux/gpio.h>
    #include <linux/gpio_keys.h>
    #include <linux/platform_device.h>
    #include <linux/mtd/mtd.h>
    #include <linux/mtd/nand.h>
    #include <linux/mtd/partitions.h>
    #include <linux/mtd/physmap.h>
    #include <linux/regulator/machine.h>
    #include <linux/regulator/tps6507x.h>
    #include <linux/input/tps6507x-ts.h>
    #include <linux/spi/spi.h>
    #include <linux/spi/flash.h>
    #include <linux/delay.h>
    #include <linux/wl12xx.h>
    #include <linux/pwm_backlight.h>
    #include <linux/i2c-gpio.h>
    #include <linux/videodev2.h>
    #include <linux/module.h>
    
    #include <asm/mach-types.h>
    #include <asm/mach/arch.h>
    
    #include <mach/cp_intc.h>
    #include <mach/da8xx.h>
    #include <mach/nand.h>
    #include <mach/mux.h>
    #include <linux/mfd/davinci_aemif.h>
    #include <mach/spi.h>
    #include <mach/usb.h>
    #include <media/tvp514x.h>
    #include <media/davinci/vpif_types.h>
    
    #define DA850_EVM_PHY_ID		"davinci_mdio-0:00"
    #define DA850_LCD_PWR_PIN		GPIO_TO_PIN(2, 8)
    #define DA850_LCD_BL_PIN		GPIO_TO_PIN(2, 15)
    
    #define DA850_MMCSD_CD_PIN		GPIO_TO_PIN(4, 0)
    #define DA850_MMCSD_WP_PIN		GPIO_TO_PIN(4, 1)
    
    #define DA850_WLAN_EN			GPIO_TO_PIN(6, 9)
    #define DA850_WLAN_IRQ			GPIO_TO_PIN(6, 10)
    
    #define DA850_MII_MDIO_CLKEN_PIN	GPIO_TO_PIN(2, 6)
    
    #define DA850_SD_ENABLE_PIN		GPIO_TO_PIN(0, 11)
    
    #define DAVINCI_BACKLIGHT_MAX_BRIGHTNESS	250
    #define DAVINVI_BACKLIGHT_DEFAULT_BRIGHTNESS	250
    #define DAVINCI_PWM_PERIOD_NANO_SECONDS		10000000
    
    
    static struct platform_pwm_backlight_data da850evm_backlight_data = {
    	.max_brightness	= DAVINCI_BACKLIGHT_MAX_BRIGHTNESS,
    	.dft_brightness	= DAVINVI_BACKLIGHT_DEFAULT_BRIGHTNESS,
    	.pwm_period_ns	= DAVINCI_PWM_PERIOD_NANO_SECONDS,
    };
    
    static struct platform_device da850evm_backlight = {
    	.name		= "pwm-backlight",
    	.id		= -1,
    };
    
    static struct mtd_partition da850evm_spiflash_part[] = {
    	[0] = {
    		.name = "UBL",
    		.offset = 0,
    		.size = SZ_64K,
    		.mask_flags = MTD_WRITEABLE,
    	},
    	[1] = {
    		.name = "U-Boot",
    		.offset = MTDPART_OFS_APPEND,
    		.size = SZ_512K,
    		.mask_flags = MTD_WRITEABLE,
    	},
    	[2] = {
    		.name = "U-Boot-Env",
    		.offset = MTDPART_OFS_APPEND,
    		.size = SZ_64K,
    		.mask_flags = MTD_WRITEABLE,
    	},
    	[3] = {
    		.name = "Kernel",
    		.offset = MTDPART_OFS_APPEND,
    		.size = SZ_2M + SZ_512K,
    		.mask_flags = 0,
    	},
    	[4] = {
    		.name = "Filesystem",
    		.offset = MTDPART_OFS_APPEND,
    		.size = SZ_4M,
    		.mask_flags = 0,
    	},
    	[5] = {
    		.name = "MAC-Address",
    		.offset = SZ_8M - SZ_64K,
    		.size = SZ_64K,
    		.mask_flags = MTD_WRITEABLE,
    	},
    };
    
    static struct flash_platform_data da850evm_spiflash_data = {
    	.name		= "m25p80",
    	.parts		= da850evm_spiflash_part,
    	.nr_parts	= ARRAY_SIZE(da850evm_spiflash_part),
    	.type		= "m25p64",
    };
    
    static struct davinci_spi_config da850evm_spiflash_cfg = {
    	.io_type	= SPI_IO_TYPE_DMA,
    	.c2tdelay	= 8,
    	.t2cdelay	= 8,
    };
    
    static struct spi_board_info da850evm_spi_info[] = {
    	{
    		/*
    		.modalias		= "m25p80",
    		.platform_data		= &da850evm_spiflash_data,
    		.controller_data	= &da850evm_spiflash_cfg,
    		.mode			= SPI_MODE_0,
    		.max_speed_hz		= 30000000,
    		.bus_num		= 1,
    		.chip_select		= 0,
    		*/
    		.modalias			= "spidev",
    		.platform_data		= &da850evm_spiflash_data,
    		.controller_data	= &da850evm_spiflash_cfg,
    		.mode				= SPI_MODE_0,
    		.max_speed_hz		= 30000000,
    		.bus_num			= 1,
    		.chip_select		= 0,
    	},
    };
    
    #define TVP5147_CH0		"tvp514x-0"
    #define TVP5147_CH1		"tvp514x-1"
    
    #define VPIF_STATUS		0x002c
    #define VPIF_STATUS_CLR		0x0030
    
    #ifdef CONFIG_MTD
    static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
    {
    	char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
    	size_t retlen;
    
    	if (!strcmp(mtd->name, "MAC-Address")) {
    		mtd_read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
    		if (retlen == ETH_ALEN)
    			pr_info("Read MAC addr from SPI Flash: %pM\n",
    				mac_addr);
    	}
    }
    
    static struct mtd_notifier da850evm_spi_notifier = {
    	.add	= da850_evm_m25p80_notify_add,
    };
    
    static void da850_evm_setup_mac_addr(void)
    {
    	register_mtd_user(&da850evm_spi_notifier);
    }
    #else
    static void da850_evm_setup_mac_addr(void) { }
    #endif
    
    static struct mtd_partition da850_evm_norflash_partition[] = {
    	{
    		.name           = "bootloaders + env",
    		.offset         = 0,
    		.size           = SZ_512K,
    		.mask_flags     = MTD_WRITEABLE,
    	},
    	{
    		.name           = "kernel",
    		.offset         = MTDPART_OFS_APPEND,
    		.size           = SZ_4M,
    		.mask_flags     = 0,
    	},
    	{
    		.name           = "filesystem",
    		.offset         = MTDPART_OFS_APPEND,
    		.size           = MTDPART_SIZ_FULL,
    		.mask_flags     = 0,
    	},
    };
    
    static struct davinci_aemif_timing da850_evm_norflash_timing = {
    	.wsetup		= 10,
    	.wstrobe	= 60,
    	.whold		= 10,
    	.rsetup		= 10,
    	.rstrobe	= 110,
    	.rhold		= 10,
    	.ta		= 30,
    };
    
    static struct physmap_flash_data da850_evm_norflash_data = {
    	.width		= 2,
    	.parts		= da850_evm_norflash_partition,
    	.nr_parts	= ARRAY_SIZE(da850_evm_norflash_partition),
    	.timing		= &da850_evm_norflash_timing,
    };
    
    static struct resource da850_evm_norflash_resource[] = {
    	{
    		.start	= DA8XX_AEMIF_CS2_BASE,
    		.end	= DA8XX_AEMIF_CS2_BASE + SZ_32M - 1,
    		.flags	= IORESOURCE_MEM,
    	},
    };
    
    static struct davinci_pm_config da850_pm_pdata = {
    	.sleepcount = 128,
    };
    
    static struct platform_device da850_pm_device = {
    	.name           = "pm-davinci",
    	.dev = {
    		.platform_data	= &da850_pm_pdata,
    	},
    	.id             = -1,
    };
    
    /* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
     * (128K blocks). It may be used instead of the (default) SPI flash
     * to boot, using TI's tools to install the secondary boot loader
     * (UBL) and U-Boot.
     */
    static struct mtd_partition da850_evm_nandflash_partition[] = {
    	{
    		.name		= "u-boot env",
    		.offset		= 0,
    		.size		= SZ_128K,
    		.mask_flags	= MTD_WRITEABLE,
    	 },
    	{
    		.name		= "UBL",
    		.offset		= MTDPART_OFS_APPEND,
    		.size		= SZ_128K,
    		.mask_flags	= MTD_WRITEABLE,
    	},
    	{
    		.name		= "u-boot",
    		.offset		= MTDPART_OFS_APPEND,
    		.size		= 4 * SZ_128K,
    		.mask_flags	= MTD_WRITEABLE,
    	},
    	{
    		.name		= "kernel",
    		.offset		= MTDPART_OFS_APPEND,
    		.size		= SZ_4M,
    		.mask_flags	= 0,
    	},
    	{
    		.name		= "filesystem",
    		.offset		= MTDPART_OFS_APPEND,
    		.size		= MTDPART_SIZ_FULL,
    		.mask_flags	= 0,
    	},
    };
    
    static struct davinci_aemif_timing da850_evm_nandflash_timing = {
    	.wsetup		= 24,
    	.wstrobe	= 21,
    	.whold		= 14,
    	.rsetup		= 19,
    	.rstrobe	= 50,
    	.rhold		= 0,
    	.ta		= 20,
    };
    
    static struct davinci_nand_pdata da850_evm_nandflash_data = {
    	.parts		= da850_evm_nandflash_partition,
    	.nr_parts	= ARRAY_SIZE(da850_evm_nandflash_partition),
    	.ecc_mode	= NAND_ECC_HW,
    	.ecc_bits	= 4,
    	.bbt_options	= NAND_BBT_USE_FLASH,
    	.timing		= &da850_evm_nandflash_timing,
    };
    
    static struct resource da850_evm_nandflash_resource[] = {
    	{
    		.start	= DA8XX_AEMIF_CS3_BASE,
    		.end	= DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1,
    		.flags	= IORESOURCE_MEM,
    	},
    	{
    		.start	= DA8XX_AEMIF_CTL_BASE,
    		.end	= DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
    		.flags	= IORESOURCE_MEM,
    	},
    };
    
    static struct platform_device da850_evm_devices[] = {
    	{
    		.name		= "davinci_nand",
    		.id		= 1,
    		.dev		= {
    			.platform_data	= &da850_evm_nandflash_data,
    		},
    		.num_resources	= ARRAY_SIZE(da850_evm_nandflash_resource),
    		.resource	= da850_evm_nandflash_resource,
    	},
    #if !defined(CONFIG_MMC_DAVINCI) || \
        !defined(CONFIG_MMC_DAVINCI_MODULE)
    	{
    		.name		= "physmap-flash",
    		.id		= 0,
    		.dev		= {
    			.platform_data  = &da850_evm_norflash_data,
    		},
    		.num_resources	= 1,
    		.resource	= da850_evm_norflash_resource,
    
    	},
    #endif
    };
    static struct davinci_aemif_devices da850_emif_devices = {
    	.devices	= da850_evm_devices,
    	.num_devices	= ARRAY_SIZE(da850_evm_devices),
    };
    
    static struct platform_device davinci_emif_device = {
    	.name	= "davinci_aemif",
    	.id	= -1,
    	.dev	= {
    		.platform_data	= &da850_emif_devices,
    	},
    };
    
    #define DA8XX_AEMIF_CE2CFG_OFFSET	0x10
    #define DA8XX_AEMIF_ASIZE_16BIT		0x1
    
    static void __init da850_evm_init_nor(void)
    {
    	void __iomem *aemif_addr;
    
    	aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
    
    	/* Configure data bus width of CS2 to 16 bit */
    	writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
    		DA8XX_AEMIF_ASIZE_16BIT,
    		aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
    
    	iounmap(aemif_addr);
    }
    
    static const short da850_evm_nand_pins[] = {
    	DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
    	DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
    	DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4,
    	DA850_NEMA_WE, DA850_NEMA_OE,
    	-1
    };
    
    static const short da850_evm_nor_pins[] = {
    	DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2,
    	DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1,
    	DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5,
    	DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9,
    	DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13,
    	DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1,
    	DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5,
    	DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9,
    	DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
    	DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
    	DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
    	DA850_EMA_A_22, DA850_EMA_A_23,
    	-1
    };
    
    #if defined(CONFIG_MMC_DAVINCI) || \
        defined(CONFIG_MMC_DAVINCI_MODULE)
    #define HAS_MMC 1
    #else
    #define HAS_MMC 0
    #endif
    
    #if defined(CONFIG_SPI_DAVINCI)
    #define HAS_SPI 1
    #else
    #define HAS_SPI 0
    #endif
    
    #if defined(CONFIG_FB_DA8XX)
    #define HAS_LCD	1
    #else
    #define HAS_LCD	0
    #endif
    
    #if defined(CONFIG_SND_DA850_SOC_EVM) || \
    	defined(CONFIG_SND_DA850_SOC_EVM_MODULE)
    #define HAS_MCASP 1
    #else
    #define HAS_MCASP 0
    #endif
    
    #if defined(CONFIG_DAVINCI_EHRPWM) || defined(CONFIG_DAVINCI_EHRPWM_MODULE)
    #define HAS_EHRPWM 1
    #else
    #define HAS_EHRPWM 0
    #endif
    
    #if defined(CONFIG_ECAP_PWM) || \
    	defined(CONFIG_ECAP_PWM_MODULE)
    #define HAS_ECAP_PWM 1
    #else
    #define HAS_ECAP_PWM 0
    #endif
    
    #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
    #define HAS_BACKLIGHT 1
    #else
    #define HAS_BACKLIGHT 0
    #endif
    
    #if defined(CONFIG_ECAP_CAP) || defined(CONFIG_ECAP_CAP_MODULE)
    #define HAS_ECAP_CAP 1
    #else
    #define HAS_ECAP_CAP 0
    #endif
    
    /* have_imager() - Check if we have support for imager interface */
    static inline int have_imager(void)
    {
    #if defined(CONFIG_DA850_UI_CAMERA)
    	return 1;
    #else
    	return 0;
    #endif
    }
    
    static inline void da850_evm_setup_nor_nand(void)
    {
    	int ret = 0;
    
    	ret = davinci_cfg_reg_list(da850_evm_nand_pins);
    	if (ret)
    		pr_warning("da850_evm_init: nand mux setup failed: "
    				"%d\n", ret);
    
    	if (!HAS_MMC) {
    		ret = davinci_cfg_reg(DA850_GPIO0_11);
    		if (ret)
    			pr_warning("da850_evm_init:GPIO(0,11) mux setup "
    					"failed\n");
    
    		ret = gpio_request(DA850_SD_ENABLE_PIN, "mmc_sd_en");
    		if (ret)
    			pr_warning("Cannot open GPIO %d\n",
    					DA850_SD_ENABLE_PIN);
    
    		/* Driver GP0[11] low for NOR to work */
    		gpio_direction_output(DA850_SD_ENABLE_PIN, 0);
    
    		ret = davinci_cfg_reg_list(da850_evm_nor_pins);
    		if (ret)
    			pr_warning("da850_evm_init: nor mux setup failed: %d\n",
    				ret);
    
    		da850_evm_init_nor();
    	} else {
    		/*
    		 * On Logic PD Rev.3 EVMs GP0[11] pin needs to be configured
    		 * for MMC and NOR to work. When GP0[11] is low, the SD0
    		 * interface will not work, but NOR flash will. When GP0[11]
    		 * is high, SD0 will work but NOR flash will not. By default
    		 * we are assuming that GP0[11] pin is driven high, when UI
    		 * card is not connected. Hence we are not configuring the
    		 * GP0[11] pin when MMC/SD is enabled and UI card is not
    		 * connected. Not configuring the GPIO pin will enable the
    		 * bluetooth to work on AM18x as it requires the GP0[11]
    		 * pin for UART flow control.
    		 */
    		ret = davinci_cfg_reg(DA850_GPIO0_11);
    		if (ret)
    			pr_warning("da850_evm_init:GPIO(0,11) mux setup "
    					"failed\n");
    
    		ret = gpio_request(DA850_SD_ENABLE_PIN, "mmc_sd_en");
    		if (ret)
    			pr_warning("Cannot open GPIO %d\n",
    					DA850_SD_ENABLE_PIN);
    
    		/* Driver GP0[11] high for SD to work */
    		gpio_direction_output(DA850_SD_ENABLE_PIN, 1);
    	}
    
    	platform_device_register(&davinci_emif_device);
    }
    
    #ifdef CONFIG_DA850_UI_RMII
    static inline void da850_evm_setup_emac_rmii(int rmii_sel)
    {
    	struct davinci_soc_info *soc_info = &davinci_soc_info;
    
    	soc_info->emac_pdata->rmii_en = 1;
    	gpio_set_value_cansleep(rmii_sel, 0);
    }
    #else
    static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
    #endif
    
    
    #define DA850_KEYS_DEBOUNCE_MS	10
    /*
     * At 200ms polling interval it is possible to miss an
     * event by tapping very lightly on the push button but most
     * pushes do result in an event; longer intervals require the
     * user to hold the button whereas shorter intervals require
     * more CPU time for polling.
     */
    #define DA850_GPIO_KEYS_POLL_MS	200
    
    enum da850_evm_ui_exp_pins {
    	DA850_EVM_UI_EXP_SEL_C = 5,
    	DA850_EVM_UI_EXP_SEL_B,
    	DA850_EVM_UI_EXP_SEL_A,
    	DA850_EVM_UI_EXP_PB8,
    	DA850_EVM_UI_EXP_PB7,
    	DA850_EVM_UI_EXP_PB6,
    	DA850_EVM_UI_EXP_PB5,
    	DA850_EVM_UI_EXP_PB4,
    	DA850_EVM_UI_EXP_PB3,
    	DA850_EVM_UI_EXP_PB2,
    	DA850_EVM_UI_EXP_PB1,
    };
    
    static const char const *da850_evm_ui_exp[] = {
    	[DA850_EVM_UI_EXP_SEL_C]        = "sel_c",
    	[DA850_EVM_UI_EXP_SEL_B]        = "sel_b",
    	[DA850_EVM_UI_EXP_SEL_A]        = "sel_a",
    	[DA850_EVM_UI_EXP_PB8]          = "pb8",
    	[DA850_EVM_UI_EXP_PB7]          = "pb7",
    	[DA850_EVM_UI_EXP_PB6]          = "pb6",
    	[DA850_EVM_UI_EXP_PB5]          = "pb5",
    	[DA850_EVM_UI_EXP_PB4]          = "pb4",
    	[DA850_EVM_UI_EXP_PB3]          = "pb3",
    	[DA850_EVM_UI_EXP_PB2]          = "pb2",
    	[DA850_EVM_UI_EXP_PB1]          = "pb1",
    };
    
    #define DA850_N_UI_PB		8
    
    static struct gpio_keys_button da850_evm_ui_keys[] = {
    	[0 ... DA850_N_UI_PB - 1] = {
    		.type			= EV_KEY,
    		.active_low		= 1,
    		.wakeup			= 0,
    		.debounce_interval	= DA850_KEYS_DEBOUNCE_MS,
    		.code			= -1, /* assigned at runtime */
    		.gpio			= -1, /* assigned at runtime */
    		.desc			= NULL, /* assigned at runtime */
    	},
    };
    
    static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = {
    	.buttons = da850_evm_ui_keys,
    	.nbuttons = ARRAY_SIZE(da850_evm_ui_keys),
    	.poll_interval = DA850_GPIO_KEYS_POLL_MS,
    };
    
    static struct platform_device da850_evm_ui_keys_device = {
    	.name = "gpio-keys-polled",
    	.id = 0,
    	.dev = {
    		.platform_data = &da850_evm_ui_keys_pdata
    	},
    };
    
    static void da850_evm_ui_keys_init(unsigned gpio)
    {
    	int i;
    	struct gpio_keys_button *button;
    
    	for (i = 0; i < DA850_N_UI_PB; i++) {
    		button = &da850_evm_ui_keys[i];
    		button->code = KEY_F8 - i;
    		button->desc = (char *)
    				da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
    		button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
    	}
    }
    
    #ifdef CONFIG_DA850_UI_CLCD
    static inline void da850_evm_setup_char_lcd(int a, int b, int c)
    {
    	gpio_set_value_cansleep(a, 0);
    	gpio_set_value_cansleep(b, 0);
    	gpio_set_value_cansleep(c, 0);
    }
    #else
    static inline void da850_evm_setup_char_lcd(int a, int b, int c) { }
    #endif
    
    #ifdef CONFIG_DA850_UI_SD_VIDEO_PORT
    static inline void da850_evm_setup_video_port(int video_sel)
    {
    	gpio_set_value_cansleep(video_sel, 0);
    }
    #else
    static inline void da850_evm_setup_video_port(int video_sel) { }
    #endif
    
    #ifdef CONFIG_DA850_UI_CAMERA
    static inline void da850_evm_setup_camera(int camera_sel)
    {
    	gpio_set_value_cansleep(camera_sel, 0);
    }
    #else
    static inline void da850_evm_setup_camera(int camera_sel) { }
    #endif
    
    static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
    						unsigned ngpio, void *c)
    {
    	int sel_a, sel_b, sel_c, ret;
    
    	sel_a = gpio + DA850_EVM_UI_EXP_SEL_A;
    	sel_b = gpio + DA850_EVM_UI_EXP_SEL_B;
    	sel_c = gpio + DA850_EVM_UI_EXP_SEL_C;
    
    	ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]);
    	if (ret) {
    		pr_warning("Cannot open UI expander pin %d\n", sel_a);
    		goto exp_setup_sela_fail;
    	}
    
    	ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]);
    	if (ret) {
    		pr_warning("Cannot open UI expander pin %d\n", sel_b);
    		goto exp_setup_selb_fail;
    	}
    
    	ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]);
    	if (ret) {
    		pr_warning("Cannot open UI expander pin %d\n", sel_c);
    		goto exp_setup_selc_fail;
    	}
    
    	/* deselect all functionalities */
    	gpio_direction_output(sel_a, 1);
    	gpio_direction_output(sel_b, 1);
    	gpio_direction_output(sel_c, 1);
    
    	da850_evm_ui_keys_init(gpio);
    	ret = platform_device_register(&da850_evm_ui_keys_device);
    	if (ret) {
    		pr_warning("Could not register UI GPIO expander push-buttons");
    		goto exp_setup_keys_fail;
    	}
    
    	pr_info("DA850/OMAP-L138 EVM UI card detected\n");
    
    	da850_evm_setup_nor_nand();
    
    	da850_evm_setup_emac_rmii(sel_a);
    
    	da850_evm_setup_char_lcd(sel_a, sel_b, sel_c);
    
    	da850_evm_setup_video_port(sel_c);
    
    	da850_evm_setup_camera(sel_b);
    
    	return 0;
    
    exp_setup_keys_fail:
    	gpio_free(sel_c);
    exp_setup_selc_fail:
    	gpio_free(sel_b);
    exp_setup_selb_fail:
    	gpio_free(sel_a);
    exp_setup_sela_fail:
    	return ret;
    }
    
    static int da850_evm_ui_expander_teardown(struct i2c_client *client,
    					unsigned gpio, unsigned ngpio, void *c)
    {
    	platform_device_unregister(&da850_evm_ui_keys_device);
    
    	/* deselect all functionalities */
    	gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_C, 1);
    	gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_B, 1);
    	gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_A, 1);
    
    	gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
    	gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
    	gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
    
    	return 0;
    }
    
    /* assign the baseboard expander's GPIOs after the UI board's */
    #define DA850_UI_EXPANDER_N_GPIOS ARRAY_SIZE(da850_evm_ui_exp)
    #define DA850_BB_EXPANDER_GPIO_BASE (DAVINCI_N_GPIO + DA850_UI_EXPANDER_N_GPIOS)
    
    enum da850_evm_bb_exp_pins {
    	DA850_EVM_BB_EXP_DEEP_SLEEP_EN = 0,
    	DA850_EVM_BB_EXP_SW_RST,
    	DA850_EVM_BB_EXP_TP_23,
    	DA850_EVM_BB_EXP_TP_22,
    	DA850_EVM_BB_EXP_TP_21,
    	DA850_EVM_BB_EXP_USER_PB1,
    	DA850_EVM_BB_EXP_USER_LED2,
    	DA850_EVM_BB_EXP_USER_LED1,
    	DA850_EVM_BB_EXP_USER_SW1,
    	DA850_EVM_BB_EXP_USER_SW2,
    	DA850_EVM_BB_EXP_USER_SW3,
    	DA850_EVM_BB_EXP_USER_SW4,
    	DA850_EVM_BB_EXP_USER_SW5,
    	DA850_EVM_BB_EXP_USER_SW6,
    	DA850_EVM_BB_EXP_USER_SW7,
    	DA850_EVM_BB_EXP_USER_SW8
    };
    
    static const char const *da850_evm_bb_exp[] = {
    	[DA850_EVM_BB_EXP_DEEP_SLEEP_EN]	= "deep_sleep_en",
    	[DA850_EVM_BB_EXP_SW_RST]		= "sw_rst",
    	[DA850_EVM_BB_EXP_TP_23]		= "tp_23",
    	[DA850_EVM_BB_EXP_TP_22]		= "tp_22",
    	[DA850_EVM_BB_EXP_TP_21]		= "tp_21",
    	[DA850_EVM_BB_EXP_USER_PB1]		= "user_pb1",
    	[DA850_EVM_BB_EXP_USER_LED2]		= "user_led2",
    	[DA850_EVM_BB_EXP_USER_LED1]		= "user_led1",
    	[DA850_EVM_BB_EXP_USER_SW1]		= "user_sw1",
    	[DA850_EVM_BB_EXP_USER_SW2]		= "user_sw2",
    	[DA850_EVM_BB_EXP_USER_SW3]		= "user_sw3",
    	[DA850_EVM_BB_EXP_USER_SW4]		= "user_sw4",
    	[DA850_EVM_BB_EXP_USER_SW5]		= "user_sw5",
    	[DA850_EVM_BB_EXP_USER_SW6]		= "user_sw6",
    	[DA850_EVM_BB_EXP_USER_SW7]		= "user_sw7",
    	[DA850_EVM_BB_EXP_USER_SW8]		= "user_sw8",
    };
    
    #define DA850_N_BB_USER_SW	8
    
    static struct gpio_keys_button da850_evm_bb_keys[] = {
    	[0] = {
    		.type			= EV_KEY,
    		.active_low		= 1,
    		.wakeup			= 0,
    		.debounce_interval	= DA850_KEYS_DEBOUNCE_MS,
    		.code			= KEY_PROG1,
    		.desc			= NULL, /* assigned at runtime */
    		.gpio			= -1, /* assigned at runtime */
    	},
    	[1 ... DA850_N_BB_USER_SW] = {
    		.type			= EV_SW,
    		.active_low		= 1,
    		.wakeup			= 0,
    		.debounce_interval	= DA850_KEYS_DEBOUNCE_MS,
    		.code			= -1, /* assigned at runtime */
    		.desc			= NULL, /* assigned at runtime */
    		.gpio			= -1, /* assigned at runtime */
    	},
    };
    
    static struct gpio_keys_platform_data da850_evm_bb_keys_pdata = {
    	.buttons = da850_evm_bb_keys,
    	.nbuttons = ARRAY_SIZE(da850_evm_bb_keys),
    	.poll_interval = DA850_GPIO_KEYS_POLL_MS,
    };
    
    static struct platform_device da850_evm_bb_keys_device = {
    	.name = "gpio-keys-polled",
    	.id = 1,
    	.dev = {
    		.platform_data = &da850_evm_bb_keys_pdata
    	},
    };
    
    static void da850_evm_bb_keys_init(unsigned gpio)
    {
    	int i;
    	struct gpio_keys_button *button;
    
    	button = &da850_evm_bb_keys[0];
    	button->desc = (char *)
    		da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_PB1];
    	button->gpio = gpio + DA850_EVM_BB_EXP_USER_PB1;
    
    	for (i = 0; i < DA850_N_BB_USER_SW; i++) {
    		button = &da850_evm_bb_keys[i + 1];
    		button->code = SW_LID + i;
    		button->desc = (char *)
    				da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_SW1 + i];
    		button->gpio = gpio + DA850_EVM_BB_EXP_USER_SW1 + i;
    	}
    }
    
    #define DA850_N_BB_USER_LED	2
    
    static struct gpio_led da850_evm_bb_leds[] = {
    	[0 ... DA850_N_BB_USER_LED - 1] = {
    		.active_low = 1,
    		.gpio = -1, /* assigned at runtime */
    		.name = NULL, /* assigned at runtime */
    	},
    };
    
    static struct gpio_led_platform_data da850_evm_bb_leds_pdata = {
    	.leds = da850_evm_bb_leds,
    	.num_leds = ARRAY_SIZE(da850_evm_bb_leds),
    };
    
    static struct platform_device da850_evm_bb_leds_device = {
    	.name		= "leds-gpio",
    	.id		= -1,
    	.dev = {
    		.platform_data = &da850_evm_bb_leds_pdata
    	}
    };
    
    static void da850_evm_bb_leds_init(unsigned gpio)
    {
    	int i;
    	struct gpio_led *led;
    
    	for (i = 0; i < DA850_N_BB_USER_LED; i++) {
    		led = &da850_evm_bb_leds[i];
    
    		led->gpio = gpio + DA850_EVM_BB_EXP_USER_LED2 + i;
    		led->name =
    			da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_LED2 + i];
    	}
    }
    
    static int da850_evm_bb_expander_setup(struct i2c_client *client,
    						unsigned gpio, unsigned ngpio,
    						void *c)
    {
    	int ret;
    
    	/*
    	 * Register the switches and pushbutton on the baseboard as a gpio-keys
    	 * device.
    	 */
    	da850_evm_bb_keys_init(gpio);
    	ret = platform_device_register(&da850_evm_bb_keys_device);
    	if (ret) {
    		pr_warning("Could not register baseboard GPIO expander keys");
    		goto io_exp_setup_sw_fail;
    	}
    
    	da850_evm_bb_leds_init(gpio);
    	ret = platform_device_register(&da850_evm_bb_leds_device);
    	if (ret) {
    		pr_warning("Could not register baseboard GPIO expander LEDS");
    		goto io_exp_setup_leds_fail;
    	}
    
    	return 0;
    
    io_exp_setup_leds_fail:
    	platform_device_unregister(&da850_evm_bb_keys_device);
    io_exp_setup_sw_fail:
    	return ret;
    }
    
    static int da850_evm_bb_expander_teardown(struct i2c_client *client,
    					unsigned gpio, unsigned ngpio, void *c)
    {
    	platform_device_unregister(&da850_evm_bb_leds_device);
    	platform_device_unregister(&da850_evm_bb_keys_device);
    
    	return 0;
    }
    
    static struct pca953x_platform_data da850_evm_ui_expander_info = {
    	.gpio_base	= DAVINCI_N_GPIO,
    	.setup		= da850_evm_ui_expander_setup,
    	.teardown	= da850_evm_ui_expander_teardown,
    	.names		= da850_evm_ui_exp,
    };
    
    static struct pca953x_platform_data da850_evm_bb_expander_info = {
    	.gpio_base	= DA850_BB_EXPANDER_GPIO_BASE,
    	.setup		= da850_evm_bb_expander_setup,
    	.teardown	= da850_evm_bb_expander_teardown,
    	.names		= da850_evm_bb_exp,
    };
    
    static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
    	{
    		I2C_BOARD_INFO("tlv320aic3x", 0x18),
    	},
    	{
    		I2C_BOARD_INFO("tca6416", 0x20),
    		.platform_data = &da850_evm_ui_expander_info,
    	},
    	{
    		I2C_BOARD_INFO("tca6416", 0x21),
    		.platform_data = &da850_evm_bb_expander_info,
    	},
    	{
    		I2C_BOARD_INFO("cdce913", 0x65),
    	},
    	{
    		I2C_BOARD_INFO("PCA9543A", 0x73),
    	},
    };
    
    /*
     * USB1 VBUS is controlled by GPIO2[4], over-current is reported on GPIO6[13].
     */
    #define ON_BD_USB_DRV	GPIO_TO_PIN(2, 4)
    #define ON_BD_USB_OVC	GPIO_TO_PIN(6, 13)
    
    static const short da850_evm_usb11_pins[] = {
    	DA850_GPIO2_4, DA850_GPIO6_13,
    	-1
    };
    
    static irqreturn_t da850_evm_usb_ocic_irq(int, void *);
    
    static struct da8xx_ohci_root_hub da850_evm_usb11_pdata = {
    	.type			= GPIO_BASED,
    	.method	= {
    		.gpio_method = {
    			.power_control_pin	= ON_BD_USB_DRV,
    			.over_current_indicator = ON_BD_USB_OVC,
    		},
    	},
    	.board_ocic_handler	= da850_evm_usb_ocic_irq,
    };
    
    static irqreturn_t da850_evm_usb_ocic_irq(int irq, void *handler)
    {
    	if (handler != NULL)
    		((da8xx_ocic_handler_t)handler)(&da850_evm_usb11_pdata, 1);
    	return IRQ_HANDLED;
    }
    
    static __init void da850_evm_usb_init(void)
    {
    	u32 cfgchip2;
    	int ret;
    
    	/*
    	 * Set up USB clock/mode in the CFGCHIP2 register.
    	 * FYI:  CFGCHIP2 is 0x0000ef00 initially.
    	 */
    	cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
    
    	/* USB2.0 PHY reference clock is 24 MHz */
    	cfgchip2 &= ~CFGCHIP2_REFFREQ;
    	cfgchip2 |=  CFGCHIP2_REFFREQ_24MHZ;
    
    	/*
    	 * Select internal reference clock for USB 2.0 PHY
    	 * and use it as a clock source for USB 1.1 PHY
    	 * (this is the default setting anyway).
    	 */
    	cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
    	cfgchip2 |=  CFGCHIP2_USB2PHYCLKMUX;
    	/*
    	 * We have to override VBUS/ID signals when MUSB is configured into the
    	 * host-only mode -- ID pin will float if no cable is connected, so the
    	 * controller won't be able to drive VBUS thinking that it's a B-device.
    	 * Otherwise, we want to use the OTG mode and enable VBUS comparators.
    	 */
    	cfgchip2 &= ~CFGCHIP2_OTGMODE;
    	cfgchip2 |=  CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
    	
    	/* PQD Addition: ******************************************************************************************/ cfgchip2 |= 0x00002000;
    	/* PQD Addition: ******************************************************************************************/ pr_warning("-> Registering USB2.0 in forced Host mode (0x%X)\n", cfgchip2);
    
    	__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
    
    	/*
    	 * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A),
    	 * with the power on to power good time of 3 ms.
    	 */
    	 																				
    	ret = da8xx_register_usb20(1000, 3);
    	if (ret)
    		pr_warning("%s: USB 2.0 registration failed: %d\n",
    			   __func__, ret);
    
    	/* initilaize usb module */
    	da8xx_board_usb_init(da850_evm_usb11_pins, &da850_evm_usb11_pdata);
    }
    
    static struct davinci_uart_config da850_evm_uart_config __initdata = {
    	.enabled_uarts = 0x7,
    };
    
    /* davinci da850 evm audio machine driver */
    static u8 da850_iis_serializer_direction[] = {
    	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
    	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
    	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	TX_MODE,
    	RX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
    };
    
    static struct snd_platform_data da850_evm_snd_data = {
    	.tx_dma_offset	= 0x2000,
    	.rx_dma_offset	= 0x2000,
    	.op_mode	= DAVINCI_MCASP_IIS_MODE,
    	.num_serializer	= ARRAY_SIZE(da850_iis_serializer_direction),
    	.tdm_slots	= 2,
    	.serial_dir	= da850_iis_serializer_direction,
    	.asp_chan_q	= EVENTQ_0,
    	.version	= MCASP_VERSION_2,
    	.txnumevt	= 1,
    	.rxnumevt	= 1,
    };
    
    static const short da850_evm_mcasp_pins[] __initconst = {
    	DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
    	DA850_ACLKR, DA850_AFSR, DA850_AMUTE,
    	DA850_AXR_11, DA850_AXR_12,
    	-1
    };
    
    static int da850_evm_mmc_get_ro(int index)
    {
    	return gpio_get_value(DA850_MMCSD_WP_PIN);
    }
    
    static int da850_evm_mmc_get_cd(int index)
    {
    	return !gpio_get_value(DA850_MMCSD_CD_PIN);
    }
    
    static struct davinci_mmc_config da850_mmc_config = {
    	.get_ro		= da850_evm_mmc_get_ro,
    	.get_cd		= da850_evm_mmc_get_cd,
    	.wires		= 4,
    	.max_freq	= 50000000,
    	.caps		= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
    	.version	= MMC_CTLR_VERSION_2,
    };
    
    static const short da850_evm_mmcsd0_pins[] __initconst = {
    	DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
    	DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
    	DA850_GPIO4_0, DA850_GPIO4_1,
    	-1
    };
    
    static void da850_panel_power_ctrl(int val)
    {
    	/* lcd power */
    	gpio_set_value_cansleep(DA850_LCD_PWR_PIN, val);
    
    	mdelay(200);
    
    	/* lcd backlight */
    	gpio_set_value_cansleep(DA850_LCD_BL_PIN, val);
    }
    
    static int da850_lcd_hw_init(void)
    {
    	int status;
    
    	status = gpio_request(DA850_LCD_BL_PIN, "lcd bl\n");
    	if (status < 0)
    		return status;
    
    	status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr\n");
    	if (status < 0) {
    		gpio_free(DA850_LCD_BL_PIN);
    		return status;
    	}
    
    	gpio_direction_output(DA850_LCD_BL_PIN, 0);
    	gpio_direction_output(DA850_LCD_PWR_PIN, 0);
    
    	return 0;
    }
    
    /* TPS65070 voltage regulator support */
    
    /* 3.3V */
    static struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
    	{
    		.supply = "usb0_vdda33",
    	},
    	{
    		.supply = "usb1_vdda33",
    	},
    };
    
    /* 3.3V or 1.8V */
    static struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
    	{
    		.supply = "dvdd3318_a",
    	},
    	{
    		.supply = "dvdd3318_b",
    	},
    	{
    		.supply = "dvdd3318_c",
    	},
    };
    
    /* 1.2V */
    static struct regulator_consumer_supply tps65070_dcdc3_consumers[] = {
    	{
    		.supply = "cvdd",
    	},
    };
    
    /* 1.8V LDO */
    static struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
    	{
    		.supply = "sata_vddr",
    	},
    	{
    		.supply = "usb0_vdda18",
    	},
    	{
    		.supply = "usb1_vdda18",
    	},
    	{
    		.supply = "ddr_dvdd18",
    	},
    };
    
    /* 1.2V LDO */
    static struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
    	{
    		.supply = "sata_vdd",
    	},
    	{
    		.supply = "pll0_vdda",
    	},
    	{
    		.supply = "pll1_vdda",
    	},
    	{
    		.supply = "usbs_cvdd",
    	},
    	{
    		.supply = "vddarnwa1",
    	},
    };
    
    /* We take advantage of the fact that both defdcdc{2,3} are tied high */
    static struct tps6507x_reg_platform_data tps6507x_platform_data = {
    	.defdcdc_default = true,
    };
    
    static struct regulator_init_data tps65070_regulator_data[] = {
    	/* dcdc1 */
    	{
    		.constraints = {
    			.min_uV = 3150000,
    			.max_uV = 3450000,
    			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
    				REGULATOR_CHANGE_STATUS),
    			.boot_on = 1,
    		},
    		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc1_consumers),
    		.consumer_supplies = tps65070_dcdc1_consumers,
    	},
    
    	/* dcdc2 */
    	{
    		.constraints = {
    			.min_uV = 1710000,
    			.max_uV = 3450000,
    			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
    				REGULATOR_CHANGE_STATUS),
    			.boot_on = 1,
    		},
    		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers),
    		.consumer_supplies = tps65070_dcdc2_consumers,
    		.driver_data = &tps6507x_platform_data,
    	},
    
    	/* dcdc3 */
    	{
    		.constraints = {
    			.min_uV = 950000,
    			.max_uV = 1350000,
    			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
    				REGULATOR_CHANGE_STATUS),
    			.boot_on = 1,
    		},
    		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers),
    		.consumer_supplies = tps65070_dcdc3_consumers,
    		.driver_data = &tps6507x_platform_data,
    	},
    
    	/* ldo1 */
    	{
    		.constraints = {
    			.min_uV = 1710000,
    			.max_uV = 1890000,
    			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
    				REGULATOR_CHANGE_STATUS),
    			.boot_on = 1,
    		},
    		.num_consumer_supplies = ARRAY_SIZE(tps65070_ldo1_consumers),
    		.consumer_supplies = tps65070_ldo1_consumers,
    	},
    
    	/* ldo2 */
    	{
    		.constraints = {
    			.min_uV = 1140000,
    			.max_uV = 1320000,
    			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
    				REGULATOR_CHANGE_STATUS),
    			.boot_on = 1,
    		},
    		.num_consumer_supplies = ARRAY_SIZE(tps65070_ldo2_consumers),
    		.consumer_supplies = tps65070_ldo2_consumers,
    	},
    };
    
    static struct touchscreen_init_data tps6507x_touchscreen_data = {
    	.poll_period =  30,	/* ms between touch samples */
    	.min_pressure = 0x30,	/* minimum pressure to trigger touch */
    	.vref = 0,		/* turn off vref when not using A/D */
    	.vendor = 0,		/* /sys/class/input/input?/id/vendor */
    	.product = 65070,	/* /sys/class/input/input?/id/product */
    	.version = 0x100,	/* /sys/class/input/input?/id/version */
    };
    
    static struct tps6507x_board tps_board = {
    	.tps6507x_pmic_init_data = &tps65070_regulator_data[0],
    	.tps6507x_ts_init_data = &tps6507x_touchscreen_data,
    };
    
    static struct i2c_board_info __initdata da850_evm_tps65070_info[] = {
    	{
    		I2C_BOARD_INFO("tps6507x", 0x48),
    		.platform_data = &tps_board,
    	},
    };
    
    static int __init pmic_tps65070_init(void)
    {
    	return i2c_register_board_info(1, da850_evm_tps65070_info,
    					ARRAY_SIZE(da850_evm_tps65070_info));
    }
    
    static const short da850_evm_lcdc_pins[] = {
    	DA850_GPIO2_8, DA850_GPIO2_15,
    	-1
    };
    
    static struct i2c_client *pca9543a;
    
    static int pca9543a_probe(struct i2c_client *client,
    		const struct i2c_device_id *id)
    {
    	pr_info("pca9543a_probe");
    	pca9543a = client;
    	return 0;
    }
    
    static int pca9543a_remove(struct i2c_client *client)
    {
    	pca9543a = NULL;
    	return 0;
    }
    
    static const struct i2c_device_id pca9543a_ids[] = {
    	{ "PCA9543A", 0, },
    	{ /* end of list */ },
    };
    
    /* This is for i2c driver for the MT9T031 header i2c switch */
    static struct i2c_driver pca9543a_driver = {
    	.driver.name	= "PCA9543A",
    	.id_table	= pca9543a_ids,
    	.probe		= pca9543a_probe,
    	.remove		= pca9543a_remove,
    };
    
    /**
     * da850_enable_pca9543a() - Enable/Disable I2C switch PCA9543A for sensor
     * @en: enable/disable flag
     */
    static int da850_enable_pca9543a(int en)
    {
    	static char val = 1;
    	int status;
    	struct i2c_msg msg = {
    			.flags = 0,
    			.len = 1,
    			.buf = &val,
    		};
    
    	pr_info("da850evm_enable_pca9543a\n");
    	if (!en)
    		val = 0;
    
    	if (!pca9543a)
    		return -ENXIO;
    
    	msg.addr = pca9543a->addr;
    	/* turn i2c switch, pca9543a, on/off */
    	status = i2c_transfer(pca9543a->adapter, &msg, 1);
    	pr_info("da850evm_enable_pca9543a, status = %d\n", status);
    	return status;
    }
    
    static const short da850_evm_mii_pins[] = {
    	DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
    	DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
    	DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
    	DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
    	DA850_MDIO_D,
    	-1
    };
    
    static const short da850_evm_rmii_pins[] = {
    	DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
    	DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
    	DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
    	DA850_MDIO_D,
    	-1
    };
    
    static int __init da850_evm_config_emac(void)
    {
    	void __iomem *cfg_chip3_base;
    	int ret;
    	u32 val;
    	struct davinci_soc_info *soc_info = &davinci_soc_info;
    	u8 rmii_en = soc_info->emac_pdata->rmii_en;
    
    	if (!machine_is_davinci_da850_evm())
    		return 0;
    
    	cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
    
    	val = __raw_readl(cfg_chip3_base);
    
    	if (rmii_en) {
    		val |= BIT(8);
    		ret = davinci_cfg_reg_list(da850_evm_rmii_pins);
    		pr_info("EMAC: RMII PHY configured, MII PHY will not be"
    							" functional\n");
    	} else {
    		val &= ~BIT(8);
    		ret = davinci_cfg_reg_list(da850_evm_mii_pins);
    		pr_info("EMAC: MII PHY configured, RMII PHY will not be"
    							" functional\n");
    	}
    
    	if (ret)
    		pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n",
    				ret);
    
    	/* configure the CFGCHIP3 register for RMII or MII */
    	__raw_writel(val, cfg_chip3_base);
    
    	ret = davinci_cfg_reg(DA850_GPIO2_6);
    	if (ret)
    		pr_warning("da850_evm_init:GPIO(2,6) mux setup "
    							"failed\n");
    
    	ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en");
    	if (ret) {
    		pr_warning("Cannot open GPIO %d\n",
    					DA850_MII_MDIO_CLKEN_PIN);
    		return ret;
    	}
    
    	/* Enable/Disable MII MDIO clock */
    	gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en);
    
    	soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID;
    
    	ret = da8xx_register_emac();
    	if (ret)
    		pr_warning("da850_evm_init: emac registration failed: %d\n",
    				ret);
    
    	return 0;
    }
    device_initcall(da850_evm_config_emac);
    
    static const struct vpif_input da850_ch2_inputs[] = {
    		{
    		.input = {
    			.index = 0,
    			.name = "Camera",
    			.type = V4L2_INPUT_TYPE_CAMERA,
    			.std = V4L2_STD_BAYER_ALL
    		},
    		.subdev_name = "mt9t031",
    	},
    };
    
    /*
     * The following EDMA channels/slots are not being used by drivers (for
     * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence
     * they are being reserved for codecs on the DSP side.
     */
    static const s16 da850_dma0_rsv_chans[][2] = {
    	/* (offset, number) */
    	{ 8,  6},
    	{24,  4},
    	{30,  2},
    	{-1, -1}
    };
    
    static const s16 da850_dma0_rsv_slots[][2] = {
    	/* (offset, number) */
    	{ 8,  6},
    	{24,  4},
    	{30, 50},
    	{-1, -1}
    };
    
    static const s16 da850_dma1_rsv_chans[][2] = {
    	/* (offset, number) */
    	{ 0, 28},
    	{30,  2},
    	{-1, -1}
    };
    
    static const s16 da850_dma1_rsv_slots[][2] = {
    	/* (offset, number) */
    	{ 0, 28},
    	{30, 90},
    	{-1, -1}
    };
    
    static struct edma_rsv_info da850_edma_cc0_rsv = {
    	.rsv_chans	= da850_dma0_rsv_chans,
    	.rsv_slots	= da850_dma0_rsv_slots,
    };
    
    static struct edma_rsv_info da850_edma_cc1_rsv = {
    	.rsv_chans	= da850_dma1_rsv_chans,
    	.rsv_slots	= da850_dma1_rsv_slots,
    };
    
    static struct edma_rsv_info *da850_edma_rsv[2] = {
    	&da850_edma_cc0_rsv,
    	&da850_edma_cc1_rsv,
    };
    
    #ifdef CONFIG_CPU_FREQ
    static __init int da850_evm_init_cpufreq(void)
    {
    	switch (system_rev & 0xF) {
    	case 3:
    		da850_max_speed = 456000;
    		break;
    	case 2:
    		da850_max_speed = 408000;
    		break;
    	case 1:
    		da850_max_speed = 372000;
    		break;
    	}
    
    	return da850_register_cpufreq("pll0_sysclk3");
    }
    #else
    static __init int da850_evm_init_cpufreq(void) { return 0; }
    #endif
    
    #if defined(CONFIG_DAVINCI_UART1_AFE)
    #define HAS_UART1_AFE 1
    #else
    #define HAS_UART1_AFE 0
    #endif
    
    /* Retaining these APIs, since the VPIF drivers do not check NULL handlers */
    static int da850_set_vpif_clock(int mux_mode, int hd)
    {
    	return 0;
    }
    
    static int da850_setup_vpif_input_channel_mode(int mux_mode)
    {
    	return 0;
    }
    
    int da850_vpif_setup_input_path(int ch, const char *name)
    {
    	int ret = 1;
    
    	 if (!strcmp(name, "mt9t031") && have_imager())
    		ret = da850_enable_pca9543a(1);
    
    	return ret;
    }
    
    static int da850_vpif_intr_status(void __iomem *vpif_base, int channel)
    {
    	int status = 0;
    	int mask;
    
    	if (channel < 0 || channel > 3)
    		return 0;
    
    	mask = 1 << channel;
    	status = __raw_readl((vpif_base + VPIF_STATUS)) & mask;
    	__raw_writel(status, (vpif_base + VPIF_STATUS_CLR));
    
    	return status;
    }
    
    #if defined(CONFIG_DA850_UI_SD_VIDEO_PORT)
    /* VPIF capture configuration */
    static struct tvp514x_platform_data tvp5146_pdata = {
    	.clk_polarity = 0,
    	.hs_polarity = 1,
    	.vs_polarity = 1
    };
    #endif
    
    #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
    
    static struct vpif_subdev_info da850_vpif_capture_sdev_info[] = {
    #if defined(CONFIG_DA850_UI_CAMERA)
    	{
    		.name	= "mt9t031",
    		.board_info = {
    			I2C_BOARD_INFO("mt9t031", 0x5d),
    			.platform_data = (void *)1,
    		},
    		.vpif_if = {
    			.if_type = VPIF_IF_RAW_BAYER,
    			.hd_pol = 0,
    			.vd_pol = 0,
    			.fid_pol = 0,
    		},
    	},
    #elif defined(CONFIG_DA850_UI_SD_VIDEO_PORT)
    	{
    		.name	= TVP5147_CH0,
    		.board_info = {
    			I2C_BOARD_INFO("tvp5146", 0x5d),
    			.platform_data = &tvp5146_pdata,
    		},
    		.input = INPUT_CVBS_VI2B,
    		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
    		.can_route = 1,
    		.vpif_if = {
    			.if_type = VPIF_IF_BT656,
    			.hd_pol = 1,
    			.vd_pol = 1,
    			.fid_pol = 0,
    		},
    	},
    	{
    		.name	= TVP5147_CH1,
    		.board_info = {
    			I2C_BOARD_INFO("tvp5146", 0x5c),
    			.platform_data = &tvp5146_pdata,
    		},
    		.input = INPUT_SVIDEO_VI2C_VI1C,
    		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
    		.can_route = 1,
    		.vpif_if = {
    			.if_type = VPIF_IF_BT656,
    			.hd_pol = 1,
    			.vd_pol = 1,
    			.fid_pol = 0,
    		},
    	},
    #endif
    };
    
    static const struct vpif_input da850_ch0_inputs[] = {
    	{
    		.input = {
    			.index = 0,
    			.name = "Composite",
    			.type = V4L2_INPUT_TYPE_CAMERA,
    			.std = TVP514X_STD_ALL,
    		},
    		.subdev_name = TVP5147_CH0,
    	},
    };
    
    static const struct vpif_input da850_ch1_inputs[] = {
    	{
    		.input = {
    			.index = 0,
    			.name = "S-Video",
    			.type = V4L2_INPUT_TYPE_CAMERA,
    			.std = TVP514X_STD_ALL,
    		},
    		.subdev_name = TVP5147_CH1,
    	},
    };
    
    static struct vpif_capture_config da850_vpif_capture_config = {
    	.setup_input_channel_mode = da850_setup_vpif_input_channel_mode,
    	.setup_input_path = da850_vpif_setup_input_path,
    	.intr_status = da850_vpif_intr_status,
    	.subdev_info = da850_vpif_capture_sdev_info,
    	.subdev_count = ARRAY_SIZE(da850_vpif_capture_sdev_info),
    #if defined(CONFIG_DA850_UI_SD_VIDEO_PORT)
    	.chan_config[0] = {
    		.inputs = da850_ch0_inputs,
    		.input_count = ARRAY_SIZE(da850_ch0_inputs),
    	},
    	.chan_config[1] = {
    		.inputs = da850_ch1_inputs,
    		.input_count = ARRAY_SIZE(da850_ch1_inputs),
    	},
    #elif defined(CONFIG_DA850_UI_CAMERA)
    	.chan_config[0] = {
    		.inputs = da850_ch2_inputs,
    		.input_count = ARRAY_SIZE(da850_ch2_inputs),
    	},
    #endif
    	.card_name      = "DA850/OMAP-L138 Video Capture",
    };
    
    /* VPIF display configuration */
    static struct vpif_subdev_info da850_vpif_subdev[] = {
    	{
    		.name	= "adv7343",
    		.board_info = {
    			I2C_BOARD_INFO("adv7343", 0x2a),
    		},
    	},
    };
    
    static const char *vpif_output[] = {
    	"Composite",
    	"Component",
    	"S-Video",
    };
    
    static struct vpif_display_config da850_vpif_display_config = {
    	.set_clock	= da850_set_vpif_clock,
    	.intr_status	= da850_vpif_intr_status,
    	.subdevinfo	= da850_vpif_subdev,
    	.subdev_count	= ARRAY_SIZE(da850_vpif_subdev),
    	.output		= vpif_output,
    	.output_count	= ARRAY_SIZE(vpif_output),
    	.card_name	= "DA850/OMAP-L138 Video Display",
    };
    
    #if defined(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) ||\
    		defined(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY_MODULE)
    #define HAS_VPIF_DISPLAY 1
    #else
    #define HAS_VPIF_DISPLAY 0
    #endif
    
    #if defined(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) ||\
    		defined(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE_MODULE)
    #define HAS_VPIF_CAPTURE 1
    #else
    #define HAS_VPIF_CAPTURE 0
    #endif
    
    #ifdef CONFIG_DA850_WL12XX
    
    static void wl12xx_set_power(int index, bool power_on)
    {
    	static bool power_state;
    
    	pr_debug("Powering %s wl12xx", power_on ? "on" : "off");
    
    	if (power_on == power_state)
    		return;
    	power_state = power_on;
    
    	if (power_on) {
    		/* Power up sequence required for wl127x devices */
    		gpio_set_value_cansleep(DA850_WLAN_EN, 1);
    		usleep_range(15000, 15000);
    		gpio_set_value_cansleep(DA850_WLAN_EN, 0);
    		usleep_range(1000, 1000);
    		gpio_set_value_cansleep(DA850_WLAN_EN, 1);
    		msleep(70);
    	} else {
    		gpio_set_value_cansleep(DA850_WLAN_EN, 0);
    	}
    }
    
    static struct davinci_mmc_config da850_wl12xx_mmc_config = {
    	.set_power	= wl12xx_set_power,
    	.wires		= 4,
    	.max_freq	= 25000000,
    	.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE |
    			  MMC_CAP_POWER_OFF_CARD,
    	.version	= MMC_CTLR_VERSION_2,
    };
    
    static const short da850_wl12xx_pins[] __initconst = {
    	DA850_MMCSD1_DAT_0, DA850_MMCSD1_DAT_1, DA850_MMCSD1_DAT_2,
    	DA850_MMCSD1_DAT_3, DA850_MMCSD1_CLK, DA850_MMCSD1_CMD,
    	DA850_GPIO6_9, DA850_GPIO6_10,
    	-1
    };
    
    static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
    	.irq			= -1,
    	.board_ref_clock	= WL12XX_REFCLOCK_38,
    	.platform_quirks	= WL12XX_PLATFORM_QUIRK_EDGE_IRQ,
    };
    
    static __init int da850_wl12xx_init(void)
    {
    	int ret;
    
    	ret = davinci_cfg_reg_list(da850_wl12xx_pins);
    	if (ret) {
    		pr_err("wl12xx/mmc mux setup failed: %d\n", ret);
    		goto exit;
    	}
    
    	ret = da850_register_mmcsd1(&da850_wl12xx_mmc_config);
    	if (ret) {
    		pr_err("wl12xx/mmc registration failed: %d\n", ret);
    		goto exit;
    	}
    
    	ret = gpio_request_one(DA850_WLAN_EN, GPIOF_OUT_INIT_LOW, "wl12xx_en");
    	if (ret) {
    		pr_err("Could not request wl12xx enable gpio: %d\n", ret);
    		goto exit;
    	}
    
    	ret = gpio_request_one(DA850_WLAN_IRQ, GPIOF_IN, "wl12xx_irq");
    	if (ret) {
    		pr_err("Could not request wl12xx irq gpio: %d\n", ret);
    		goto free_wlan_en;
    	}
    
    	da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
    
    	ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
    	if (ret) {
    		pr_err("Could not set wl12xx data: %d\n", ret);
    		goto free_wlan_irq;
    	}
    
    	return 0;
    
    free_wlan_irq:
    	gpio_free(DA850_WLAN_IRQ);
    
    free_wlan_en:
    	gpio_free(DA850_WLAN_EN);
    
    exit:
    	return ret;
    }
    
    #else /* CONFIG_DA850_WL12XX */
    
    static __init int da850_wl12xx_init(void)
    {
    	return 0;
    }
    
    #endif /* CONFIG_DA850_WL12XX */
    
    static struct i2c_gpio_platform_data da850_gpio_i2c_pdata = {
    	.sda_pin	= GPIO_TO_PIN(1, 4),
    	.scl_pin	= GPIO_TO_PIN(1, 5),
    	.udelay		= 2,			/* 250 KHz */
    };
    
    static struct platform_device da850_gpio_i2c = {
    	.name		= "i2c-gpio",
    	.id		= 1,
    	.dev		= {
    		.platform_data	= &da850_gpio_i2c_pdata,
    	},
    };
    
    static __init int da850_set_emif_clk_rate(void)
    {
    	struct clk *emif_clk;
    
    	emif_clk = clk_get(NULL, "pll0_sysclk3");
    	if (WARN(IS_ERR(emif_clk), "Unable to get emif clock\n"))
    		return PTR_ERR(emif_clk);
    
    	return clk_set_rate(emif_clk, CONFIG_DA850_FIX_PLL0_SYSCLK3RATE);
    }
    
    struct uio_pruss_pdata da8xx_pruss_uio_pdata = {
    	.pintc_base	= 0x4000,
    };
    
    #define DA850EVM_SATA_REFCLKPN_RATE	(100 * 1000 * 1000)
    
    static __init void da850_evm_init(void)
    {
    	int ret;
    	char mask = 0;
    	struct davinci_soc_info *soc_info = &davinci_soc_info;
    
    	u8 rmii_en = soc_info->emac_pdata->rmii_en;
    
    	ret = pmic_tps65070_init();
    	if (ret)
    		pr_warning("da850_evm_init: TPS65070 PMIC init failed: %d\n",
    				ret);
    
    	/*
    	 * Though bootloader takes care to set emif clock at allowed
    	 * possible rate. Kernel needs to reconfigure this rate to
    	 * support platforms requiring fixed emif clock rate.
    	 */
    	ret = da850_set_emif_clk_rate();
    	if (ret)
    		pr_warning("da850_evm_init: Failed to set rate of pll0_sysclk3/emif clock: %d\n",
    				ret);
    
    	ret = da850_register_edma(da850_edma_rsv);
    	if (ret)
    		pr_warning("da850_evm_init: edma registration failed: %d\n",
    				ret);
    
    	ret = davinci_cfg_reg_list(da850_i2c0_pins);
    	if (ret)
    		pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
    				ret);
    
    	platform_device_register(&da850_gpio_i2c);
    
    	ret = da8xx_register_watchdog();
    	if (ret)
    		pr_warning("da830_evm_init: watchdog registration failed: %d\n",
    				ret);
    
    	/* Support for UART 1 */
    	ret = davinci_cfg_reg_list(da850_uart1_pins);
    	if (ret)
    		pr_warning("da850_evm_init: UART 1 mux setup failed:"
    						" %d\n", ret);
    
    	if (HAS_MMC) {
    		ret = davinci_cfg_reg_list(da850_evm_mmcsd0_pins);
    		if (ret)
    			pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
    					" %d\n", ret);
    
    		ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n");
    		if (ret)
    			pr_warning("da850_evm_init: can not open GPIO %d\n",
    					DA850_MMCSD_CD_PIN);
    		gpio_direction_input(DA850_MMCSD_CD_PIN);
    
    		ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n");
    		if (ret)
    			pr_warning("da850_evm_init: can not open GPIO %d\n",
    					DA850_MMCSD_WP_PIN);
    		gpio_direction_input(DA850_MMCSD_WP_PIN);
    
    		ret = da8xx_register_mmcsd0(&da850_mmc_config);
    		if (ret)
    			pr_warning("da850_evm_init: mmcsd0 registration failed:"
    					" %d\n", ret);
    
    		ret = da850_wl12xx_init();
    		if (ret)
    			pr_warning("da850_evm_init: wl12xx initialization"
    				   " failed: %d\n", ret);
    	}
    
    	davinci_serial_init(&da850_evm_uart_config);
    
    	if (have_imager())
    		i2c_add_driver(&pca9543a_driver);
    
    	i2c_register_board_info(1, da850_evm_i2c_devices,
    			ARRAY_SIZE(da850_evm_i2c_devices));
    
    	/*
    	 * shut down uart 0 and 1; they are not used on the board and
    	 * accessing them causes endless "too much work in irq53" messages
    	 * with arago fs
    	 */
    	__raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30);
    
    	if (HAS_MCASP) {
    		if (HAS_UART1_AFE)
    			pr_warning("WARNING: both McASP and UART1_AFE are "
    				"enabled, but they share pins.\n"
    					"\tDisable one of them.\n");
    
    		ret = davinci_cfg_reg_list(da850_evm_mcasp_pins);
    		if (ret)
    			pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
    					ret);
    
    		da8xx_register_mcasp(0, &da850_evm_snd_data);
    	}
    
    	ret = da8xx_register_pruss_uio(&da8xx_pruss_uio_pdata);
    	if (ret)
    		pr_warning("%s: pruss_uio initialization failed: %d\n",
    				__func__, ret);	
    
    	ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
    	if (ret)
    		pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
    				ret);
    
    	/* Handle board specific muxing for LCD here */
    	ret = davinci_cfg_reg_list(da850_evm_lcdc_pins);
    	if (ret)
    		pr_warning("da850_evm_init: evm specific lcd mux setup "
    				"failed: %d\n",	ret);
    
    	ret = da850_lcd_hw_init();
    	if (ret)
    		pr_warning("da850_evm_init: lcd initialization failed: %d\n",
    				ret);
    
    	sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
    	ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
    	if (ret)
    		pr_warning("da850_evm_init: lcdc registration failed: %d\n",
    				ret);
    
    	ret = da8xx_register_rtc();
    	if (ret)
    		pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
    
    	ret = da850_evm_init_cpufreq();
    	if (ret)
    		pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
    				ret);
    
    	ret = da8xx_register_cpuidle();
    	if (ret)
    		pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
    				ret);
    
    	ret = da850_register_pm(&da850_pm_device);
    	if (ret)
    		pr_warning("da850_evm_init: suspend registration failed: %d\n",
    				ret);
    
    	if (HAS_VPIF_DISPLAY || HAS_VPIF_CAPTURE) {
    		ret = da850_register_vpif();
    		if (ret)
    			pr_warning("da850_evm_init: VPIF setup failed: %d\n",
    				   ret);
    	}
    
    	if (HAS_VPIF_CAPTURE) {
    		ret = davinci_cfg_reg_list(da850_vpif_capture_pins);
    		if (ret)
    			pr_warning("da850_evm_init: VPIF capture mux failed:"
    					"%d\n", ret);
    
    		ret = da850_register_vpif_capture(&da850_vpif_capture_config);
    		if (ret)
    			pr_warning("da850_evm_init: VPIF capture setup failed:"
    					"%d\n", ret);
    	}
    
    	if (HAS_VPIF_DISPLAY) {
    		ret = davinci_cfg_reg_list(da850_vpif_display_pins);
    		if (ret)
    			pr_warning("da850_evm_init : VPIF capture mux failed :"
    					"%d\n", ret);
    
    		ret = da850_register_vpif_display(&da850_vpif_display_config);
    		if (ret)
    			pr_warning("da850_evm_init: VPIF display setup failed:"
    					"%d\n", ret);
    	}
    
    	ret = da8xx_register_spi(1, da850evm_spi_info,
    				 ARRAY_SIZE(da850evm_spi_info));
    	if (ret)
    		pr_warning("da850_evm_init: spi 1 registration failed: %d\n",
    				ret);
    
    	ret = da850_register_sata(DA850EVM_SATA_REFCLKPN_RATE);
    	if (ret)
    		pr_warning("da850_evm_init: sata registration failed: %d\n",
    				ret);
    
    	da850_evm_setup_mac_addr();
    
    	da850_evm_usb_init();
    
    	if (HAS_EHRPWM) {
    		if (rmii_en) {
    			ret = davinci_cfg_reg_list(da850_ehrpwm0_pins);
    			if (ret)
    				pr_warning("da850_evm_init:"
    				" ehrpwm0 mux setup failed: %d\n", ret);
    			else
    				mask = BIT(0) | BIT(1);
    		} else {
    			pr_warning("da850_evm_init:"
    			" eHRPWM module 0 cannot be used"
    			" since it is being used by MII interface\n");
    			mask = 0;
    		}
    
    		if (!HAS_LCD) {
    			ret = davinci_cfg_reg_list(da850_ehrpwm1_pins);
    			if (ret)
    				pr_warning("da850_evm_init:"
    				" eHRPWM module1 output A mux"
    				" setup failed %d\n", ret);
    			else
    				mask = mask | BIT(2);
    		} else {
    			pr_warning("da850_evm_init:"
    				" eHRPWM module1 outputA cannot be"
    				" used since it is being used by LCD\n");
    		}
    
    		if (!HAS_SPI) {
    			ret = davinci_cfg_reg(DA850_EHRPWM1_B);
    			if (ret)
    				pr_warning("da850_evm_init:"
    					" eHRPWM module1 outputB mux"
    					" setup failed %d\n", ret);
    		else
    			mask =  mask  | BIT(3);
    		} else {
    			pr_warning("da850_evm_init:"
    				" eHRPWM module1 outputB cannot be"
    				" used since it is being used by spi1\n");
    		}
    
    		da850_register_ehrpwm(mask);
    	}
    
    	if (HAS_ECAP_PWM) {
    		ret = davinci_cfg_reg(DA850_ECAP2_APWM2);
    		if (ret)
    			pr_warning("da850_evm_init:ecap mux failed:"
    					" %d\n", ret);
    		ret = da850_register_ecap(2);
    		if (ret)
    			pr_warning("da850_evm_init:"
    				" eCAP registration failed: %d\n", ret);
    	}
    
    	if (HAS_BACKLIGHT) {
    		ret = da850_register_backlight(&da850evm_backlight,
    				&da850evm_backlight_data);
    		if (ret)
    			pr_warning("da850_evm_init:"
    				" backlight device registration"
    				" failed: %d\n", ret);
    	}
    
    	if (HAS_ECAP_CAP) {
    		if (HAS_MCASP)
    			pr_warning("da850_evm_init:"
    				"ecap module 1 cannot be used "
    				"since it shares pins with McASP\n");
    		else {
    			ret = davinci_cfg_reg(DA850_ECAP1_APWM1);
    			if (ret)
    				pr_warning("da850_evm_init:ecap mux failed:%d\n"
    						, ret);
    			else {
    				ret = da850_register_ecap_cap(1);
    				if (ret)
    					pr_warning("da850_evm_init"
    					"eCAP registration failed: %d\n", ret);
    			}
    		}
    	}
    }
    
    #ifdef CONFIG_SERIAL_8250_CONSOLE
    static int __init da850_evm_console_init(void)
    {
    	if (!machine_is_davinci_da850_evm())
    		return 0;
    
    	return add_preferred_console("ttyS", 2, "115200");
    }
    console_initcall(da850_evm_console_init);
    #endif
    
    static void __init da850_evm_map_io(void)
    {
    	da850_init();
    }
    
    MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
    	.atag_offset	= 0x100,
    	.map_io		= da850_evm_map_io,
    	.init_irq	= cp_intc_init,
    	.timer		= &davinci_timer,
    	.init_machine	= da850_evm_init,
    	.dma_zone_size	= SZ_128M,
    	.restart	= da8xx_restart,
    MACHINE_END
    

    Regards,

    Reino

  • Hi Reino,

    Thanks for sharing the layout. This is sufficient to get a clear picture about the connection.

    Reino says said:
    The kernel does however recognize FTDI USB to serial converters that I plug into the USB "plug".

    From this statement, we can conclude the following few things.

    1. In your set up, the required FTDI driver is enabled properly in kernel and it is able to detect the USB to serial converter connected into the one of the Hub ports ( i.e., here, "USB plug"). so, there is no question about the driver support for FT4232H.

    2. And you must be able to open the ttyUSBx when the USB to serial converter is connected into the "USB plug" right? Did you verify this?

    3. We have to check, why the hardwired FTDI serial to USB converter is not getting detected.

    If the kernel is able to detect the converter plugged into the USB plug, then it should also detect the hardwired converter too. It could be hardware/interface problem too. I do not see any software problem here. 

    --------------

    I compared your boot.txt and my boot logs ( attached in my previous post)

    In your boot logs, all the neccessary drivers like MUSB, FTDI are shown up and as per the product ID and Vendor ID, the following are the devices detected.

    1. usb usb1: New USB device found, idVendor=1d6b, idProduct=0001  -- Root Hub 1.1

    2. usb usb2: New USB device found, idVendor=1d6b, idProduct=0002 -- Root Hub 2.0

    3. usb 2-1: New USB device found, idVendor=0424, idProduct=2517 -- Hub of Standard Microsystems Corp. ( Is it a 2.0 compatible one? Because the idproduct=2514 is the 2.0 and not sure about idproduct 2517)  Check whether any problem in the hub too.

    4. usb 2-1.3: New USB device found, idVendor=1546, idProduct=01a6  -- U-Blox AG

    -----

    In my boot logs, you will be able to see the following when the converter is inserted into the USB 2.0

    omapl138-lcdk login: root

    root@omapl138-lcdk:~# usb 2-1: new full-speed USB device number 2 using musb-hdrc

    pl2303 2-1:1.0: pl2303 converter detected

    usb 2-1: pl2303 converter now attached to ttyUSB0

    In addition, I have connected the USB hub 2.0 into the USB 2.0 port of OMAPl138 SDI EVM and inserted two USB to serial converters into the hub.  I have attached the snapshot below in which the converters are attached to ttyUSB0 and ttyUSB1. This test will confirm that the OMAPl138 SOM doesnot have any problem in detecting multiple USB devices!!.

     

     

    Regards,

    Shankari

     

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------

  • Hi Shankari,

    Thank you for another detailed response.

    In connection with the Standard Micro Hub, 2.0 compatibility has been confirmed.

    The hardware has also been confirmed to work, so it must be a software issue.

    The FTDI device that was detected through the USB plug was not a FT4232H device. It was a single port device. I have therefore not been able to confirm that the driver is compatible with the FT4232H.

    I have found the following post: http://e2e.ti.com/support/embedded/linux/f/354/p/67093/1203698.aspx#1203698

    In that thread, George seems to have had the same problem, I am not sure if he managed to solve it. Filosofi however got it to work. He included a line in his config file:

    CONFIG_USB_SERIAL_FTDI=y

    which is different to the prescribed:

    CONFIG_USB_SERIAL_FTDI_SIO=y.

    I originally thought it was a typo, but tried it anyway. The kernel compiles, but it still does not work. Just to re-ask Filosofi's question, surely there is no operation/functional difference between compiling the driver into the kernel versus dynamically loading the driver as a module?

    This does seem to be a problem that has occurred before and it would be nice if we could get the solution on a forum where others could see it.

    Regards,

    Reino 

  • Hi Reino,

    Apparently, I do not have the particular FT4232H converter to test. Without the converter not sure how to reproduce the problem.

    And more over, as the converter is hardwired, the converter should get properly detected and should have shown up early in the Boot logs. If you do not get a connect event occured, then it seems to be hardware issue.

    In you boot logs, I do not see the vendor id for FT4232H device; which means the that USB device is not detected. what type of device ( i.e., whether a pen drive or card reader or converter) is the second stage where in it look for appropriate driver. Thus, the FT4232H driver is questionable only after proper detection of the device as a USB.

    In dmesg of your boot logs, you should atleast first get "0403" as vendor ID.

     

    Regards,

    Shankari

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------