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.

OMAP-L138LCDK VPIF memory issue

Other Parts Discussed in Thread: OMAP-L138

I'm trying to get the composite input of the LCDK board working. Firstly, I follow this post http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/339153.aspx. I have used the config file given in the bottom of that post (0763.board-omapl138-lcdk.c, 0028.dot_config_lcdk.txt). According to that post, these config files are for the DaVinci-PSP-SDK-03.22.00.06. However I have succesfully used it for the MCSDK. Now I have /dev/video0 and /dev/video1 show up and my boot log is identical to what given in the last comment in that post.

I've tested with loopback application given in this link (http://processors.wiki.ti.com/index.php/Demonstration_of_VPIF_raw_capture_using_MT9T031_sensor_on_AM18X/DA850/OMAP-L138_running_Linux#Setup) and this is what I have thus far 

I have add the following code into /driver/video/davincifb.c  to make the code compile

/* see : http://gumstix.8.x6.nabble.com/IO-ADDRESS-definition-missing-in-ti-codec-engine-build-td666095.html */
#define IO_OFFSET               0x01000000      /* Virtual IO = 0xfefb0000 */
#define IO_ADDRESS(x)           ((x) - IO_OFFSET)


and I comment out line 301 of file /driver/media/video/videobuf-core.c

//BUG_ON(V4L2_FIELD_ANY == field);

Thanks you

Nuntipat

  • Hi Nuntipat,

    Could you attach your complete linux bootup log.

    Have you tried to change bootargs for VPIF ?

    u-boot> setenv bootargs console=ttyS2,115200n8 noinitrd rw ip=<ipaddr> root=/dev/nfs nfsroot=<nfs path>, nolock mem=60M
    vpif_display.ch2_bufsize=2622464 vpif_display.cont_bufsize=20979712 vpif_capture.ch0_bufsize=2622464 
    vpif_capture.cont_bufoffset=6291456 vpif_capture.cont_bufsize=20979712

  • I have tried it but the problem persist. I will try it again tomorrow and share with you how it is going and also a complete boot log.

    By the way, what is the correct IO_ADRESS macro? Without this the compiler says it is undefined.

    Thank you

  • Here is my complete boot log

    Booting Linux on physical CPU 0
    Linux version 3.3.0 (visionear@Visionear-PC) (gcc version 4.5.3 20110311 (prerelease) (GCC) ) #11 PREEMPT Wed Nov 26 09:04:06 ICT 2014
    CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
    CPU: VIVT data cache, VIVT instruction cache
    Machine: AM18x/OMAP-L138 lcdk 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
    On node 0 totalpages: 15360
    free_area_init_node: node 0, pgdat c05128ec, node_mem_map c0530000
      DMA zone: 120 pages used for memmap
      DMA zone: 0 pages reserved
      DMA zone: 15240 pages, LIFO batch:3
    pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
    pcpu-alloc: [0] 0 
    Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 15240
    Kernel command line: console=ttyS2,115200n8 rw noinitrd root=/dev/nfs nfsroot=192.168.1.1:/home/visionear/ti/mcsdk_1_01_00_02/targetNFS,nolock ip=192.168.1.2 mem=60M vpif_display.ch2_bufsize=2622464 vpif_display.cont_bufsize=20979712 vpif_capture.ch0_bufsize=2622464 vpif_capture.cont_bufoffset=6291456 vpif_capture.cont_bufsize=20979712
    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: 60MB = 60MB total
    Memory: 55552k/55552k available, 5888k reserved, 0K highmem
    Virtual kernel memory layout:
        vector  : 0xffff0000 - 0xffff1000   (   4 kB)
        fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
        vmalloc : 0xc4000000 - 0xff000000   ( 944 MB)
        lowmem  : 0xc0000000 - 0xc3c00000   (  60 MB)
        modules : 0xbf000000 - 0xc0000000   (  16 MB)
          .text : 0xc0008000 - 0xc04ac000   (4752 kB)
          .init : 0xc04ac000 - 0xc04d7000   ( 172 kB)
          .data : 0xc04d8000 - 0xc0513400   ( 237 kB)
           .bss : 0xc0513424 - 0xc052f00c   ( 111 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... 227.32 BogoMIPS (lpj=1136640)
    pid_max: default: 32768 minimum: 301
    Mount-cache hash table entries: 512
    CPU: Testing write buffer coherency: ok
    Setting up static identity map for 0xc03893d0 - 0xc0389428
    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
    EMAC: MII PHY configured
    da850_evm_init VPIF : vpif capture mux success: 0
    da850_evm_init VPIF : VPIF registration success: 0
    bio: create slab <bio-0> at 0
    SCSI subsystem initialized
    libata version 3.00 loaded.
    usbcore: registered new interface driver usbfs
    usbcore: registered new interface driver hub
    usbcore: registered new device driver usb
    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: ConfigData=0x06 (UTMI-8, dyn FIFOs, SoftConn)
    musb-hdrc: MHDRC RTL version 1.800 
    musb-hdrc: setup fifo_mode 2
    musb-hdrc: 7/9 max ep, 2624/4096 memory
    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.
    JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
    msgmni has been set to 108
    io scheduler noop registered (default)
    da8xx_lcdc da8xx_lcdc.0: GLCD: Found VGA_Monitor panel
    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
    NAND device: Manufacturer ID: 0x2c, Chip ID: 0xcc (Micron NAND 512MiB 3,3V 16-bit)
    Bad block table found at page 262080, version 0x01
    Bad block table found at page 262016, version 0x01
    Creating 4 MTD partitions on "davinci_nand.1":
    0x000000000000-0x000000020000 : "u-boot env"
    0x000000020000-0x0000000a0000 : "u-boot"
    0x0000000a0000-0x0000002a0000 : "kernel"
    0x0000002a0000-0x000020000000 : "filesystem"
    davinci_nand davinci_nand.1: controller rev. 2.5
    davinci_mdio davinci_mdio.0: davinci mdio revision 1.5
    davinci_mdio davinci_mdio.0: detected phy mask ffffff7f
    davinci_mdio.0: probed
    davinci_mdio davinci_mdio.0: phy[7]: device davinci_mdio-0:07, 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.
    input: gpio-keys-polled as /devices/platform/gpio-keys-polled.0/input/input0
    omap_rtc omap_rtc: rtc core: registered omap_rtc as rtc0
    omap_rtc: RTC power up reset detected
    omap_rtc: already running
    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
    tvp514x 1-005d: tvp514x 1-005d decoder driver registered !!
    vpif_capture vpif_capture: registered sub device tvp514x-0
    ata1: SATA link down (SStatus 0 SControl 300)
    tvp514x 1-005c: Write: retry ... 0
    tvp514x 1-005c: Write: retry ... 1
    tvp514x 1-005c: Write: retry ... 2
    tvp514x 1-005c: Write: retry ... 3
    tvp514x 1-005c: Write: retry ... 4
    tvp514x 1-005c: Write: retry ... 5
    tvp514x 1-005c: tvp514x 1-005c decoder driver registered !!
    vpif_capture vpif_capture: registered sub device tvp514x-1
    vpif_capture vpif_capture: VPIF capture driver initialized
    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
    soc-audio soc-audio.0: ASoC: Failed to create card debugfs directory
    _regulator_get: 1-0018 supply IOVDD not found, using dummy regulator
    _regulator_get: 1-0018 supply DVDD not found, using dummy regulator
    _regulator_get: 1-0018 supply AVDD not found, using dummy regulator
    _regulator_get: 1-0018 supply DRVDD not found, using dummy regulator
    asoc: tlv320aic3x-hifi <-> davinci-mcasp.0 mapping ok
    ALSA device list:
      #0: DA850/OMAP-L138 EVM
    TCP cubic registered
    NET: Registered protocol family 17
    console [netcon0] enabled
    netconsole: network logging started
    davinci_emac davinci_emac.1: using random MAC addr: 8a:3b:09:6c:e6:72
    omap_rtc omap_rtc: setting system clock to 2013-11-06 04:40:36 UTC (1383712836)
    davinci_mdio davinci_mdio.0: resetting idled controller
    net eth0: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=davinci_mdio-0:07, id=7c0f1)
    PHY: davinci_mdio-0:07 - Link is Up - 100/Full
    IP-Config: Guessing netmask 255.255.255.0
    IP-Config: Complete:
         device=eth0, addr=192.168.1.2, mask=255.255.255.0, gw=255.255.255.255,
         host=192.168.1.2, domain=, nis-domain=(none),
         bootserver=255.255.255.255, rootserver=192.168.1.1, rootpath=
    VFS: Mounted root (nfs filesystem) on device 0:13.
    Freeing init memory: 172K
    NET: Registered protocol family 10
    eth0: no IPv6 routers present
    
    .

    I have edit the IO_ADRESS macro to the one from hardware.h

    #define IO_PHYS				0x01c00000UL
    #define IO_OFFSET			0xfd000000 /* Virtual IO = 0xfec00000 */
    #define IO_SIZE				0x00400000
    #define IO_VIRT				(IO_PHYS + IO_OFFSET)
    #define io_v2p(va)			((va) - IO_OFFSET)
    #define __IO_ADDRESS(x)			((x) + IO_OFFSET)
    #define IO_ADDRESS(pa)			IOMEM(__IO_ADDRESS(pa))
    
    #ifdef __ASSEMBLER__
    #define IOMEM(x)                	x
    #else
    #define IOMEM(x)                	((void __force __iomem *)(x))
    #endif

    To clarify what I get now. Firstly the code always failed at line 271 in file vpif_mmap_loopback.c. If I comment out this block, I end up segmentation fault like in the picture below.

    
    
    ret = ioctl(*capture_fd, VIDIOC_S_FMT, fmt);
    	if (ret < 0) {
    		perror("VIDIOC_S_FMT failed\n");
    		return -1;
    	}

    Secondly, If I don't comment out line 301 of file /driver/media/video/videobuf-core.c, this is what I get.

    Thanks you for your help

  • Anyone has faced these problems? Any help would be really appreciate.

    Thank you

    Palm

  • Hi Palm,

    Actually you don't want to change anything on the latest SDK.

    I presume that you are using the latest TI SDK MCSDK1.00.02.

    Able to get video streaming through mplayer ?

    I've tested with loopback application given in this link (http://processors.wiki.ti.com/index.php/Demonstration_of_VPIF_raw_capture_using_MT9T031_sensor_on_AM18X/DA850/OMAP-L138_running_Linux#Setup) and this is what I have thus far

    FYI, The above code works well on LogicPD EVM and not tested with LCDK boards.

    You can use "mplayer" tool get video streaming.

    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/328619/1146743.aspx#1146743

    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/328715/1146751.aspx#1146751

  • The code work for the USB webcam but not trough composite input. I try with USB webcam with success but with the composite camera this is what I get.

  • Could you attach your board file here or send to me (x0213399@ti.com)

  • Here is my board file

    /*
     * TI's OMAP-L138 LCDK Development Board
     *
     * Initial code: Syed Mohammed Khasim
     *
     * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com
     *
     * 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/console.h>
    #include <linux/gpio.h>
    #include <linux/i2c.h>
    #include <linux/i2c-gpio.h>
    #include <linux/leds.h>
    #include <linux/gpio_keys.h>
    #include <linux/input.h>
    #include <linux/platform_device.h>
    #include <linux/mtd/mtd.h>
    #include <linux/mtd/nand.h>
    #include <linux/mtd/partitions.h>
    #include <linux/mfd/davinci_aemif.h>
    
    #include <asm/mach-types.h>
    #include <asm/mach/arch.h>
    
    #include <mach/cp_intc.h>
    #include <mach/da8xx.h>
    #include <mach/mux.h>
    #include <mach/nand.h>
    
    /* Titus Hack */
    
    #include <media/davinci/vpif_types.h>
    #include <media/tvp514x.h>
    
    #define LCDKBOARD_PHY_ID		"davinci_mdio-0:07"
    #define DA850_LCDK_MMCSD_CD_PIN		GPIO_TO_PIN(4, 0)
    
    #define DA850_USB1_VBUS_PIN		GPIO_TO_PIN(2, 4)
    #define DA850_USB1_OC_PIN		GPIO_TO_PIN(6, 13)
    
    #define LCDKBOARD_SATA_REFCLKPN_RATE   (100 * 1000 * 1000)
    
    #define DA850_LCDK_USER_LED0		GPIO_TO_PIN(6, 12)
    #define DA850_LCDK_USER_LED1		GPIO_TO_PIN(6, 13)
    #define DA850_LCDK_USER_LED2		GPIO_TO_PIN(2, 12)
    #define DA850_LCDK_USER_LED3		GPIO_TO_PIN(0, 9)
    
    #define	DA850_LCDK_USER_KEY0            GPIO_TO_PIN(2, 4)
    #define	DA850_LCDK_USER_KEY1            GPIO_TO_PIN(2, 5)
    
    #if defined(CONFIG_USB_OHCI_HCD)
    #define HAS_OHCI               1
    #else
    #define HAS_OHCI               0
    #endif
    
    #define        DA850_LCDK_KEYS_DEBOUNCE_MS     10
    #define        DA850_LCDK_GPIO_KEYS_POLL_MS    200
    
    #define DA850_LCD_PWR_PIN              GPIO_TO_PIN(2, 8)
    #define DA850_LCD_BL_PIN               GPIO_TO_PIN(2, 15)
    
    /* Titus Hack */
    
    #if defined(CONFIG_DA850_UI_RMII) && (HAS_EMAC)
    #define HAS_RMII 1
    #else
    #define HAS_RMII 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
    
    #define TVP5147_CH0		"tvp514x-0"
    #define TVP5147_CH1		"tvp514x-1"
    
    #define VPIF_STATUS	(0x002C)
    #define VPIF_STATUS_CLR	(0x0030)
    
    
    
    #if defined(CONFIG_MTD_NAND_DAVINCI) || \
    	defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
    struct mtd_partition omapl138_lcdk_nandflash_partition[] = {
    	{
    		.name           = "u-boot env",
    		.offset         = 0,
    		.size           = SZ_128K,
    		.mask_flags     = MTD_WRITEABLE,
    	},
    	{
    		.name           = "u-boot",
    		.offset         = MTDPART_OFS_APPEND,
    		.size           = SZ_512K,
    		.mask_flags     = MTD_WRITEABLE,
    	},
    	{
    		.name           = "kernel",
    		.offset         = MTDPART_OFS_APPEND,
    		.size           = SZ_2M,
    		.mask_flags     = 0,
    	},
    	{
    		.name           = "filesystem",
    		.offset         = MTDPART_OFS_APPEND,
    		.size           = MTDPART_SIZ_FULL,
    		.mask_flags     = 0,
    	},
    };
    
    static struct davinci_nand_pdata omapl138_lcdk_nandflash_data = {
    	.parts          = omapl138_lcdk_nandflash_partition,
    	.nr_parts       = ARRAY_SIZE(omapl138_lcdk_nandflash_partition),
    	.ecc_mode       = NAND_ECC_HW,
    	.options        = NAND_BUSWIDTH_16,
    	.ecc_bits       = 1, /* 4 bit mode is not
    			      * supported with 16 bit NAND */
    	.bbt_options    = NAND_BBT_USE_FLASH,
    };
    
    static const short omapl138_lcdk_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_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_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4,
    	DA850_NEMA_WE, DA850_NEMA_OE,
    	-1
    };
    
    static struct resource omapl138_lcdk_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 omapl138_lcdk_nandflash_device = {
    	.name           = "davinci_nand",
    	.id             = 1,
    	.dev            = {
    		.platform_data  = &omapl138_lcdk_nandflash_data,
    	},
    	.resource       = omapl138_lcdk_nandflash_resource,
    	.num_resources  = ARRAY_SIZE(omapl138_lcdk_nandflash_resource),
    };
    
    static __init void omapl138_lcdk_nand_init(void)
    {
    	int ret;
    
    	ret = davinci_cfg_reg_list(omapl138_lcdk_nand_pins);
    	if (ret) {
    		pr_warn("da850_lcdk_init:"
    				"nand mux setup failed: %d\n", ret);
    		return;
    	}
    	platform_device_register(&omapl138_lcdk_nandflash_device);
    }
    #else
    static void omapl138_lcdk_nand_init(void) { }
    #endif
    
    
    static short omapl138_lcdk_mii_pins[] __initdata = {
    	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 __init void omapl138_lcdk_config_emac(void)
    {
    	void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
    	int ret;
    	u32 val;
    	struct davinci_soc_info *soc_info = &davinci_soc_info;
    
    	val = __raw_readl(cfgchip3);
    	val &= ~BIT(8);
    	ret = davinci_cfg_reg_list(omapl138_lcdk_mii_pins);
    	if (ret) {
    		pr_warning("%s: cpgmac/mii mux setup failed: %d\n",
    			__func__, ret);
    		return;
    	}
    
    	/* configure the CFGCHIP3 register for MII */
    	__raw_writel(val, cfgchip3);
    	pr_info("EMAC: MII PHY configured\n");
    
    	soc_info->emac_pdata->phy_id = LCDKBOARD_PHY_ID;
    
    	ret = da8xx_register_emac();
    	if (ret)
    		pr_warning("%s: emac registration failed: %d\n",
    			__func__, ret);
    }
    
    /*
     * The following EDMA channels/slots are not being used by drivers (for
     * example: Timer, GPIO, UART events etc) on da850/omap-l138 LCDK 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,
    };
    
    static const short lcdk_mmcsd0_pins[] = {
    	DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
    	DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
    	DA850_GPIO3_12, DA850_GPIO3_13,
    	-1
    };
    
    static int da850_lcdk_mmc_get_ro(int index)
    {
    	return 0;
    }
    
    static int da850_lcdk_mmc_get_cd(int index)
    {
    	return !gpio_get_value(DA850_LCDK_MMCSD_CD_PIN);
    }
    
    static struct davinci_mmc_config da850_mmc_config = {
    	.get_ro		= da850_lcdk_mmc_get_ro,
    	.get_cd		= da850_lcdk_mmc_get_cd,
    	.wires		= 4,
    	.max_freq	= 50000000,
    	.caps		= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
    	.version	= MMC_CTLR_VERSION_2,
    };
    
    static __init void omapl138_lcdk_mmc_init(void)
    {
    	int ret;
    
    	ret = davinci_cfg_reg_list(lcdk_mmcsd0_pins);
    	if (ret) {
    		pr_warning("%s: MMC/SD0 mux setup failed: %d\n",
    			__func__, ret);
    		return;
    	}
    
    	ret = gpio_request_one(DA850_LCDK_MMCSD_CD_PIN,
    			GPIOF_DIR_IN, "MMC CD");
    	if (ret < 0) {
    		pr_warning("%s: can not open GPIO %d\n",
    			__func__, DA850_LCDK_MMCSD_CD_PIN);
    		return;
    	}
    
    	ret = da8xx_register_mmcsd0(&da850_mmc_config);
    	if (ret) {
    		pr_warning("%s: MMC/SD0 registration failed: %d\n",
    			__func__, ret);
    		goto mmc_setup_mmcsd_fail;
    	}
    
    	return;
    
    mmc_setup_mmcsd_fail:
    	gpio_free(DA850_LCDK_MMCSD_CD_PIN);
    }
    
    static irqreturn_t omapl138_lcdk_usb_ocic_irq(int irq, void *dev_id);
    
    static const short da850_lcdk_usb11_pins[] = {
    	DA850_GPIO2_4, DA850_GPIO6_13,
    	-1
    };
    
    static struct da8xx_ohci_root_hub omapl138_lcdk_usb11_pdata = {
    	.type	= GPIO_BASED,
    	.method	= {
    		.gpio_method = {
    			.power_control_pin	= DA850_USB1_VBUS_PIN,
    			.over_current_indicator = DA850_USB1_OC_PIN,
    		},
    	},
    	.board_ocic_handler	= omapl138_lcdk_usb_ocic_irq,
    };
    
    static irqreturn_t omapl138_lcdk_usb_ocic_irq(int irq, void *handler)
    {
    	if (handler != NULL)
    		((da8xx_ocic_handler_t)handler)(&omapl138_lcdk_usb11_pdata, 1);
    	return IRQ_HANDLED;
    }
    
    /* VGA */
    static const short omapl138_lcdk_lcdc_pins[] = {
    	DA850_GPIO2_8, DA850_GPIO2_15,
    	-1
    };
    
    /* Backlight and power is for use with LCD expansion header only */
    static void da850_panel_power_ctrl(int val)
    {
    	/* lcd backlight */
    	gpio_set_value(DA850_LCD_BL_PIN, val);
    	/* lcd power */
    	gpio_set_value(DA850_LCD_PWR_PIN, val);
    }
    
    static int da850_lcd_hw_init(void)
    {
    	void __iomem *cfg_mstpri1_base;
    	void __iomem *cfg_mstpri2_base;
    	void __iomem *emifb;
    	void __iomem *myptr;
    	int status;
    	u32 val;
    
    	/*
    	 * Default master priorities in reg 0 are all lower by default than LCD
    	 * which is set below to 0. Hence don't need to change here.
    	 */
    
    	/* set EDMA30TC0 and TC1 to lower than LCDC (4 < 0) */
    	cfg_mstpri1_base = DA8XX_SYSCFG0_VIRT(DA8XX_MSTPRI1_REG);
    	val = __raw_readl(cfg_mstpri1_base);
    	val &= 0xFFFF00FF;
    	val |= 4 << 8;             /* 0-high, 7-low priority*/
    	val |= 4 << 12;            /* 0-high, 7-low priority*/
    	__raw_writel(val, cfg_mstpri1_base);
    
    	/*
    	 * Reconfigure the LCDC priority to the highest to ensure that
    	 * the throughput/latency requirements for the LCDC are met.
    	 */
    	cfg_mstpri2_base = DA8XX_SYSCFG0_VIRT(DA8XX_MSTPRI2_REG);
    
    	val = __raw_readl(cfg_mstpri2_base);
    	val &= 0x0fffffff;
    	__raw_writel(val, cfg_mstpri2_base);
    
    	/* set BPRIO */
    #define DA8XX_EMIF30_CONTROL_BASE               0xB0000000
    #define DA8XX_EMIF30_BPRIO_OFFSET               0x20
    #define DA8XX_EMIFB_VIRT(x)     (emifb + (x))
    	emifb = ioremap(DA8XX_EMIF30_CONTROL_BASE, SZ_4K);
    	myptr = DA8XX_EMIFB_VIRT(0x20);
    	__raw_writel(0x20, myptr);
    
    	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);
    
    	/* Switch off panel power and backlight */
    	da850_panel_power_ctrl(0);
    
    	/* Switch on panel power and backlight */
    	da850_panel_power_ctrl(1);
    
    	return 0;
    }
    
    static void omapl138_lcdk_display_init(void)
    {
    	int ret;
    
    	ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
    	if (ret)
    		pr_warn("omapl138_lcdk_init: lcdcntl mux setup failed:%d\n",
    				ret);
    
    	ret = davinci_cfg_reg_list(omapl138_lcdk_lcdc_pins);
    	if (ret)
    		pr_warn("omapl138_lcdk_init: evm specific lcd mux setup "
    				"failed: %d\n", ret);
    
    	da850_lcd_hw_init();
    
    	ret = da8xx_register_lcdc(&vga_monitor_pdata);
    	if (ret)
    		pr_warn("omapl138_lcdk_init: lcdc registration failed: %d\n",
    				ret);
    }
    
    static __init void omapl138_lcdk_usb_init(void)
    {
    	u32 cfgchip2;
    	int ret;
    
    	/* Setup the Ref. clock frequency for the LCDK at 24 MHz. */
    
    	cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
    	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;
    
    	/*
    	 * 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_warn("%s: USB 2.0 registration failed: %d\n",
    				__func__, ret);
    
    	__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
    
    	if (HAS_OHCI)
    		da8xx_board_usb_init(da850_lcdk_usb11_pins,
    				     &omapl138_lcdk_usb11_pdata);
    
    	return;
    }
    
    static struct davinci_uart_config omapl138_lcdk_uart_config __initdata = {
    	.enabled_uarts = 0x7,
    };
    
    /* I2C */
    static struct i2c_board_info __initdata omapl138_lcdk_i2c_devices[] = {
    	{
    		I2C_BOARD_INFO("tlv320aic3x", 0x18),
    	},
    };
    
    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 void omapl138_lcdk_i2c_init(void)
    {
    	int ret;
    	ret = davinci_cfg_reg_list(da850_i2c0_pins);
    	if (ret)
    		pr_warn("omapl138_lcdk_init: i2c0 mux setup failed: %d\n",
    				ret);
    
    	platform_device_register(&da850_gpio_i2c);
    
    	if (ret)
    		pr_warn("omapl138_lcdk_init: i2c0 registration failed: %d\n",
    				ret);
    	i2c_register_board_info(1, omapl138_lcdk_i2c_devices,
    			ARRAY_SIZE(omapl138_lcdk_i2c_devices));
    }
    
    /* Set up OMAP-L138 LCDK low-level McASP 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,  INACTIVE_MODE,
    	INACTIVE_MODE,  TX_MODE,        RX_MODE,        INACTIVE_MODE,
    };
    
    static struct snd_platform_data omapl138_lcdk_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 omapl138_lcdk_mcasp_pins[] __initconst = {
    	DA850_AHCLKX,   DA850_ACLKX,    DA850_AFSX,
    	DA850_AHCLKR,   DA850_ACLKR,    DA850_AFSR,     DA850_AMUTE,
    	DA850_AXR_13,   DA850_AXR_14,
    	-1
    };
    
    static void omapl138_lcdk_sound_init(void)
    {
    	int ret;
    	ret = davinci_cfg_reg_list(omapl138_lcdk_mcasp_pins);
    	if (ret)
    		pr_warn("omapl138_lcdk_init: mcasp mux setup failed: %d\n",
    				ret);
    
    	da8xx_register_mcasp(0, &omapl138_lcdk_snd_data);
    }
    
    static const short omapl138_lcdk_led_pin_mux[] __initconst = {
    	DA850_GPIO6_12,
    #if !HAS_OHCI
    	DA850_GPIO6_13,
    #endif
    	DA850_GPIO2_12,
    	DA850_GPIO0_9,
    	-1
    };
    
    static struct gpio_led gpio_leds[] = {
    	{
    		.active_low = 1,
    		.gpio = DA850_LCDK_USER_LED0,
    		.name = "user_led0",
    	},
    #if !HAS_OHCI
    	{
    		.active_low = 1,
    		.gpio   = DA850_LCDK_USER_LED1,
    		.name   = "user_led1",
    	},
    #endif
    	{
    		.active_low = 1,
    		.gpio = DA850_LCDK_USER_LED2,
    		.name = "user_led2",
    	},
    	{
    		.active_low = 1,
    		.gpio   = DA850_LCDK_USER_LED3,
    		.name   = "user_led3",
    	},
    };
    
    static struct gpio_led_platform_data gpio_led_info = {
    	.leds           = gpio_leds,
    	.num_leds       = ARRAY_SIZE(gpio_leds),
    };
    
    static struct platform_device leds_gpio = {
    	.name   = "leds-gpio",
    	.id     = -1,
    	.dev    = {
    		.platform_data  = &gpio_led_info,
    	},
    };
    
    static  __init void omapl138_lcdk_led_init(void)
    {
    	int err;
    
    	davinci_cfg_reg_list(omapl138_lcdk_led_pin_mux);
    	err = platform_device_register(&leds_gpio);
    	if (err)
    		pr_err("failed to register leds_gpio device\n");
    	return;
    };
    
    static const short omapl138_lcdk_keys_pin_mux[] __initconst = {
    #if !HAS_OHCI
    	DA850_GPIO2_4,
    #endif
    	DA850_GPIO2_5,
    	-1
    };
    
    static struct gpio_keys_button omapl138_lcdk_evm_keys[] = {
    #if !HAS_OHCI
    	{
    		.type                   = EV_KEY,
    		.active_low             = 1,
    		.wakeup                 = 0,
    		.debounce_interval      = DA850_LCDK_KEYS_DEBOUNCE_MS,
    		.code                   = KEY_F8,
    		.gpio                   = DA850_LCDK_USER_KEY0,
    		.desc                   = "pb1",
    	},
    #endif
    	{
    		.type                   = EV_KEY,
    		.active_low             = 1,
    		.wakeup                 = 0,
    		.debounce_interval      = DA850_LCDK_KEYS_DEBOUNCE_MS,
    		.code                   = KEY_F7,
    		.gpio                   = DA850_LCDK_USER_KEY1,
    		.desc                   = "pb2",
    	},
    };
    
    static struct gpio_keys_platform_data omapl138_lcdk_evm_keys_pdata = {
    	.buttons = omapl138_lcdk_evm_keys,
    	.nbuttons = ARRAY_SIZE(omapl138_lcdk_evm_keys),
    	.poll_interval = DA850_LCDK_GPIO_KEYS_POLL_MS,
    };
    
    static struct platform_device omapl138_lcdk_evm_keys_device = {
    	.name = "gpio-keys-polled",
    	.id = 0,
    	.dev = {
    		.platform_data = &omapl138_lcdk_evm_keys_pdata
    	},
    };
    
    static  __init void omapl138_lcdk_keys_init(void)
    {
    	int err;
    
    	davinci_cfg_reg_list(omapl138_lcdk_keys_pin_mux);
    	err = platform_device_register(&omapl138_lcdk_evm_keys_device);
    	if (err)
    		pr_err("failed to register omapl138_lcdk_evm_keys_device\n");
    	return;
    };
    
    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,
    };
    
    /* Titus Hack */
    
    static int da850_setup_vpif_input_channel_mode(int mux_mode)
    {
    	return 0;
    }
    
    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;
    }
    
    /* VPIF capture configuration */
    static struct tvp514x_platform_data tvp5146_pdata = {
    	.clk_polarity = 0,
    	.hs_polarity = 1,
    	.vs_polarity = 1
    };
    
    #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
    
    static struct vpif_subdev_info da850_vpif_capture_sdev_info[] = {
    	{
    		.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,
    		},
    	},
    };
    
    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,
    	.intr_status = da850_vpif_intr_status,
    	.subdev_info = da850_vpif_capture_sdev_info,
    	.subdev_count = ARRAY_SIZE(da850_vpif_capture_sdev_info),
    	.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),
    	},
    	.card_name      = "DA850/OMAP-L138 Video Capture",
    };
    
    
    
    
    static __init void omapl138_lcdk_init(void)
    {
    	int ret;
    
    	davinci_serial_init(&omapl138_lcdk_uart_config);
    
    	/*
    	 * shut down uart 0 and 1; they are not used on this board and
    	 * accessing them causes endless "too much work in irq53" messages
    	 * with arago fs
    	 */
    	__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30);
    	__raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30);
    
    	omapl138_lcdk_config_emac();
    
    	ret = da850_register_edma(da850_edma_rsv);
    	if (ret)
    		pr_warning("%s: EDMA registration failed: %d\n",
    			__func__, ret);
    
    	omapl138_lcdk_mmc_init();
    
    	omapl138_lcdk_usb_init();
    
    	ret = da8xx_register_watchdog();
    	if (ret)
    		pr_warning("omapl138_lcdk_init: "
    			"watchdog registration failed: %d\n",
    			ret);
    
    	ret = da8xx_register_rtc();
    	if (ret)
    		pr_warning("omapl138_lcdk_init: rtc setup failed: %d\n", ret);
    
    	omapl138_lcdk_i2c_init();
    	omapl138_lcdk_sound_init();
    
    	ret = da850_register_sata(LCDKBOARD_SATA_REFCLKPN_RATE);
    	if (ret)
    		pr_warning("omapl138_lcdk_init: sata 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);
    
    	omapl138_lcdk_led_init();
    	omapl138_lcdk_keys_init();
    	omapl138_lcdk_nand_init();
    	omapl138_lcdk_display_init();
    
    /* Titus Hack */
    
    	if (!HAS_RMII && HAS_VPIF_CAPTURE) {
    		ret = davinci_cfg_reg_list(da850_vpif_capture_pins);
    		if (ret)
    			pr_warning("da850_evm_init VPIF : vpif capture mux failed: "
    					"%d\n",	ret);
    		else
    			pr_warning("da850_evm_init VPIF : vpif capture mux success: "
    					"%d\n",	ret);
    
    
    		ret = da850_register_vpif_capture(&da850_vpif_capture_config);
    		if (ret)
    			pr_warning("da850_evm_init VPIF : VPIF registration failed: "
    					"%d\n",	ret);
    		else
    			pr_warning("da850_evm_init VPIF : VPIF registration success: "
    					"%d\n",	ret);
    
    	}
    
    }
    
    #ifdef CONFIG_SERIAL_8250_CONSOLE
    static int __init omapl138_lcdk_console_init(void)
    {
    	if (!machine_is_omapl138_lcdkboard())
    		return 0;
    
    	return add_preferred_console("ttyS", 2, "115200");
    }
    console_initcall(omapl138_lcdk_console_init);
    #endif
    
    static void __init omapl138_lcdk_map_io(void)
    {
    	da850_init();
    }
    
    MACHINE_START(OMAPL138_LCDKBOARD, "AM18x/OMAP-L138 lcdk board")
    	.atag_offset	= 0x100,
    	.map_io		= omapl138_lcdk_map_io,
    	.init_irq	= cp_intc_init,
    	.timer		= &davinci_timer,
    	.init_machine	= omapl138_lcdk_init,
    	.dma_zone_size	= SZ_128M,
    	.restart	= da8xx_restart,
    MACHINE_END
    


    Thank you

    Palm

  • Normally this is the boot command I use when using SysLink.

    setenv bootargs 'console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait ip=off mem=32M@0xc0000000 mem=64M@0xc4000000'

    When using VPIF I use this one

    setenv bootargs console=ttyS2,115200n8 rw noinitrd root=/dev/nfs nfsroot=192.168.1.1:/home/visionear/ti/mcsdk_1_01_00_02/targetNFS,nolock ip=192.168.1.2 mem=60M vpif_display.ch2_bufsize=2622464 vpif_display.cont_bufsize=20979712 vpif_capture.ch0_bufsize=2622464 vpif_capture.cont_bufoffset=6291456 vpif_capture.cont_bufsize=20979712

    If I use both SysLink and the VPIF. How can I merge the two boot arguments? Is "mem=60M" mean allocate 60 Mb for the ARM side running linux? How the memory "vpif_capture.ch0_bufsize" is allocated? Is it include in that 60Mb or it uses free space left?


    Sorry for causing you lots of trouble. Thank you for your help.

    Palm

  • Any update from TI support team? Now I'm trying to get the composite camera to work with mplayer. However my final goal is to make it works with the c code I found. Will the code given above work or I need to look at mplayer source code to edit my code. Any help would be really appreciate.

    Thank you

    Palm

  • Hi Palm,

    If I use both SysLink and the VPIF. How can I merge the two boot arguments? Is "mem=60M" mean allocate 60 Mb for the ARM side running linux? How the memory "vpif_capture.ch0_bufsize" is allocated? Is it include in that 60Mb or it uses free space left?

    For a while, avoid syslink and use VPIF alone with mentioned boot args.

    setenv bootargs console=ttyS2,115200n8 noinitrd rw ip=<ipaddr> root=/dev/nfs nfsroot=<nfs path>, nolock mem=60M vpif_display.ch2_bufsize=2622464 vpif_display.cont_bufsize=20979712 vpif_capture.ch0_bufsize=2622464 vpif_capture.cont_bufoffset=6291456 vpif_capture.cont_bufsize=20979712

    Have you modified the vpif_mmap_loopback.c file to mention video source & capture device with correct resolution  (BUFFER_HEIGHT & BUFFER_PITCH) ?

    What is your LCD resolution ?

  • Hi Titus S.

    Here the issue I currently faced.

    1. MPlayer is working with the USB webcam but not my composite camera

    2. vpif_mmap_loopback.c is not working for both USB webcam and the composite camera.

    It gives following error when using with composite camera.

    /*
     * vpif_mmap_loopback.c
     *
     * This is the sample to show DavinciHD capture and display functionality using
     * memory mapped buffers. It accepts channel number and standard to capture
     * as input; For channel0 it assumes input is composite and for channel1
     * it assumes input as s-video.It captures frames from the capture device,
     * copies them from capture buffer to the display buffer and displays them.
     * Flow: Capture -> Display
     *
     * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 
     * 
     * 
     *  Redistribution and use in source and binary forms, with or without 
     *  modification, are permitted provided that the following conditions 
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright 
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the 
     *    documentation and/or other materials provided with the   
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
    */
     /******************************************************************************
      Header File Inclusion
     ******************************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <errno.h>
    /* Palm's fixed */
    //#include <linux/videodev.h>
    #include <linux/videodev2.h>
    /******************************************************************************
     Macros
     MAX_BUFFER     : Changing the following will result different number of 
    		  instances of buf_info structure.
     BUFFER_HEIGHT	: This indicates maximum height of the image which is 
     		  captured or displayed.
     BUFFER_PITCH	: This indicates maximum widht of the image which is 
     		  captured or displayed.
     CAPTURE_DEVICE : This indicates device to be used for capture
     DISPLAY_DEVICE : This indicates device to be used for display
     MAXLOOPCOUNT	: This indicates number of frames to be captured and displayed
     ******************************************************************************/
    #define MAX_BUFFER	3
    #define CAPTURE_DEVICE0	"/dev/video0"
    #define CAPTURE_DEVICE1	"/dev/video1"
    #define DISPLAY_DEVICE	"/dev/fb0"
    #define BUFFER_PITCH	720
    #define BUFFER_HEIGHT	576
    #define MAXLOOPCOUNT	500
    #define CAPTURE_INPUT0 "Composite"
    #define CAPTURE_INPUT1 "S-Video"
    #define CLEAR(x)	memset (&(x), 0, sizeof (x))
    #define ALIGN(x, y)     (((x + (y-1))/y)*y)
    
    /******************************************************************************
     Declaration
     	Following structure is used to store information of the buffers which 
    	are mmapped.
     ******************************************************************************/
    struct buf_info {
    	int index;
    	unsigned int length;
    	char *start;
    };
    
    /******************************************************************************
     Globals
    	Following variables stores file descriptors returned when opening 
    	capture and display device.
    	capture_buff_info and display_buff_info stores mmaped buffer 
    	information of capture and display respectively.
    	capture_numbuffers, display_numbuffers is used to store number of 
    	buffers actually allocated by the driver.
    	outputidx is used to store index of the output to be selected in 
    	display depending on the input detecting on the capture.
    	capture_std used to store detected standard.
     ******************************************************************************/
    static struct buf_info capture_buff_info[MAX_BUFFER];
    static struct buf_info display_buff_info[MAX_BUFFER];
    /******************************************************************************
                            Function Definitions
     ******************************************************************************/
    static int initCapture(int *capture_fd, int *numbuffers, struct v4l2_format *fmt);
    static int startCapture(int *);
    static void *getCaptureBuffer(int *);
    static int stopCapture(int *);
    static int releaseCapture(int *, int);
    static int putCaptureBuffer(int *capture_fd, int numbuffers, void *addr);
    static int initDisplay(int *display_fd, int *numbuffers,struct v4l2_format *fmt);
    static int releaseDisplay(int *, int);
    static int startDisplay(int *);
    static int stopDisplay(int *);
    static void *getDisplayBuffer(int *);
    static int putDisplayBuffer(int *display_fd, int numbuffers, void *addr);
    
    v4l2_std_id input_std_id = V4L2_STD_PAL;
    char *input_device;
    char *input_name;
    
    /* print frame number */
    int print_fn = 1;
    /* stress test */
    int stress_test = 0;
    /* enable/disable display */
    int display_enable = 1;
    /* save catptured frame */
    int save_frame = 0;
    
    FILE *file_fp = NULL;
    
    #define BYTESPERLINE 720
    
    int sizeimage = BYTESPERLINE*576*2;
    int kernel_buf_size = ALIGN(BUFFER_PITCH * BUFFER_HEIGHT * 2, 4096);
    
    int app_main();
    
    /*=====================initCapture========================*/
    /* This function initializes capture device. It detects   *
     * first input connected on the channel-0 and detects the *
     * standard on that input. It, then, allocates buffers in *
     * the driver's memory space and mmaps them in the        *
     * application space.					  */
    static int initCapture(int *capture_fd, int *numbuffers, struct v4l2_format *fmt)
    {
    	int mode = O_RDWR, ret, i;
    	struct v4l2_requestbuffers reqbuf;
    	struct v4l2_buffer buf;
    	struct v4l2_input input;
    	int input_idx;
    	struct v4l2_standard standard;
    	v4l2_std_id std;
    	int found = 0;
    
    	/* Open the channel-0 capture device */
    	*capture_fd = open((const char *)input_device, mode);
    	if (*capture_fd <= 0) {
    		printf("Cannot open = %s device\n", input_device);
    		return -1;
    	}
    
    
    	/* Enumerate inputs to get the name of the input chosen by user*/
    	input.index = 0;
    	while(1) {
    		ret = ioctl(*capture_fd, VIDIOC_ENUMINPUT, &input);
    		if (ret < 0) {
    			perror("VIDIOC_ENUMINPUT\n");
    			return -1;
    		}
    		if (!strcmp(input.name, input_name)) {
    			found = 1;
    			break;
    		}
    	}
    
    	if (!found) {
    		printf("Input %s not found\n", input_name);
    		return -1;
    	}
    
    	/* Set input
    	 * VIDIOC_G_INPUT ioctl detects the inputs connected. It returns
    	 * error if no inputs are connected. Otherwise it returns index of 
    	 * the input connected. */
    	ret = ioctl(*capture_fd, VIDIOC_S_INPUT, &input.index);
    	if (ret < 0) {
    		perror("VIDIOC_S_INPUT\n");
    		return -1;
    	}
    
    	/* check if input is selected correctly */
    	ret = ioctl(*capture_fd, VIDIOC_G_INPUT, &input_idx);
    	if (ret < 0) {
    		perror("VIDIOC_G_INPUT\n");
    		return -1;
    	}
    
    	if (input_idx != input.index) {
    		printf("Couldn't set input correctly\n");
    		return -1;
    	}
    	/* Set the user selected standard */
    
    	found = 0;
    	/* Enumerate standard to get the name of the standard detected */
    	standard.index = 0;
    	do {
    		ret = ioctl(*capture_fd, VIDIOC_ENUMSTD, &standard);
    		if (ret < 0) {
    			perror("VIDIOC_ENUM_STD failed\n");
    			return -1;
    		}
    		printf("standard.name = %s\n", standard.name);
    		if (standard.id & input_std_id) {
    			printf("Found standard support in the driver\n");
    			found = 1;
    			break;
    		}
    		standard.index++;
    	} while (1);
    
    	if (!found) {
    		printf("Driver doesn't support the standard\n");
    		return -1;
    	} 
    
    	ret == ioctl(*capture_fd, VIDIOC_S_STD, &input_std_id);
    	if (ret < 0) {
    		perror("VIDIOC_S_STD failed\n");
    		return -1;
    	}
    
    	/* Detect the standard in the input detected */
    	ret = ioctl(*capture_fd, VIDIOC_QUERYSTD, &std);
    
    	if (ret < 0) {
    		perror("VIDIOC_QUERYSTD\n");
    		return -1;
    	}
    
    	if (std & V4L2_STD_NTSC)
    		printf("Input video standard is NTSC.\n");
    	else if (std & V4L2_STD_PAL)
    		printf("Input video standard is PAL.\n");
    	else if (std & V4L2_STD_PAL_M)
    		printf("Input video standard is PAL-M.\n");
    	else if (std & V4L2_STD_PAL_N)
    		printf("Input video standard is PAL-N.\n");
    	else if (std & V4L2_STD_SECAM)
    		printf("Input video standard is SECAM.\n");
    	else if (std & V4L2_STD_PAL_60)
    		printf("Input video standard to PAL60.\n");
    	else 
    		return -1;
    
    	/* Set format */
    	CLEAR(*fmt);
    	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	fmt->fmt.pix.bytesperline = BYTESPERLINE;
    	fmt->fmt.pix.sizeimage = sizeimage;
    	fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
    	fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
    
    	ret = ioctl(*capture_fd, VIDIOC_S_FMT, fmt);
    	if (ret < 0) {
    		perror("VIDIOC_S_FMT failed\n");
    		return -1;
    	}
    
    	CLEAR(*fmt);
    	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	ret = ioctl(*capture_fd, VIDIOC_G_FMT, fmt);
    	if (ret < 0) {
    		perror("VIDIOC_G_FMT failed\n");
    		return -1;
    	}
    
    	/* Buffer allocation 
    	 * Buffer can be allocated either from capture driver or
    	 * user pointer can be used 
    	 */
    	/* Request for 3 input buffers. As far as Physically contiguous 
    	 * memory is available, driver can allocate as many buffers as 
    	 * possible. If memory is not available, it returns number of 
    	 * buffers it has allocated in count member of reqbuf.
    	 * HERE count = number of buffer to be allocated.
    	 * type = type of device for which buffers are to be allocated. 
    	 * memory = type of the buffers requested i.e. driver allocated or 
    	 * user pointer */
    	reqbuf.count = *numbuffers;
    	reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	reqbuf.memory = V4L2_MEMORY_MMAP;
    
    	ret = ioctl(*capture_fd, VIDIOC_REQBUFS, &reqbuf);
    	if (ret < 0) {
    		perror("cannot allocate memory\n");
    		return -1;
    	}
    
    	/* Store the number of buffers actually allocated */
    	*numbuffers = reqbuf.count;
    
    	/* It is better to zero all the members of buffer structure */
    	memset(&buf, 0, sizeof(buf));
    
    	/* Mmap the buffers
    	 * To access driver allocated buffer in application space, they have
    	 * to be mmapped in the application space using mmap system call */
    	for (i = 0; i < reqbuf.count; i++) {
    		/* Query physical address of the buffers */
    		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    		buf.index = i;
    		buf.memory = V4L2_MEMORY_MMAP;
    		ret = ioctl(*capture_fd, VIDIOC_QUERYBUF, &buf);
    		if (ret < 0) {
    			perror("VIDIOC_QUERYCAP\n");
    			return -1;
    		}
    
    		/* Mmap the buffers in application space */
    		capture_buff_info[i].length = buf.length;
    		capture_buff_info[i].index = i;
    		capture_buff_info[i].start =
    		    mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
    			 MAP_SHARED, *capture_fd, buf.m.offset);
    
    		if (capture_buff_info[i].start == MAP_FAILED) {
    			printf("Cannot mmap = %d buffer\n", i);
    			return -1;
    		}
    		printf("capture_buff_info[%d].length = %d\n", i, capture_buff_info[i].length); 
    		printf("capture_buff_info[%d].index = %d\n", i, capture_buff_info[i].index); 
    		printf("capture_buff_info[%d].start = %p\n", i, capture_buff_info[i].start); 
    		/* It is better to zero buffers */
    		memset(capture_buff_info[i].start, 0x80,
    		       capture_buff_info[i].length);
    	}
    
    	/* Enqueue buffers
    	 * Before starting streaming, all the buffers needs to be en-queued 
    	 * in the driver incoming queue. These buffers will be used by the 
    	 * drive for storing captured frames. */
    	/* Enqueue buffers */
    	for (i = 0; i < reqbuf.count; i++) {
    		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    		buf.index = i;
    		buf.memory = V4L2_MEMORY_MMAP;
    		ret = ioctl(*capture_fd, VIDIOC_QBUF, &buf);
    		if (ret < 0) {
    			perror("VIDIOC_QBUF\n");
    			return -1;
    		}
    	}
    
    	return 0;
    }
    
    /*=====================startCapture========================*/
    /* This function starts streaming on the capture device	   */
    static int startCapture(int *capture_fd)
    {
    	int a = V4L2_BUF_TYPE_VIDEO_CAPTURE, ret;
    	/* Here type of device to be streamed on is required to be passed */
    	ret = ioctl(*capture_fd, VIDIOC_STREAMON, &a);
    	if (ret < 0) {
    		perror("VIDIOC_STREAMON\n");
    		return -1;
    	}
    	return 0;
    }
    
    /*=====================getCaptureBuffer====================*/
    /* This function de-queues captured buffer from the 	   *
     * capture device's outgoing queue. 			   */
    static void *getCaptureBuffer(int *capture_fd)
    {
    	int ret;
    	struct v4l2_buffer buf;
    	/* It is better to zero members of v4l2_buffer structure */
    	memset(&buf, 0, sizeof(buf));
    	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	buf.memory = V4L2_MEMORY_MMAP;
    	/* Dequeue buffer
    	 * VIDIOC_DQBUF ioctl de-queues a captured buffer from driver.
    	 * This call can be blocking or non blocking. For blocking call, it
    	 * blocks untill a capture frame is available. For non-blocking call,
    	 * it returns instantaneously with success or error depending on 
    	 * captured buffer is available or not. */
    	ret = ioctl(*capture_fd, VIDIOC_DQBUF, &buf);
    	if (ret < 0) {
    		perror("VIDIOC_DQBUF\n");
    		return NULL;
    	}
    	return capture_buff_info[buf.index].start;
    }
    
    /*=====================stopCapture========================*/
    /* This function stops streaming on the capture device	  */
    static int stopCapture(int *capture_fd)
    {
    	int ret, a = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	/* Here type of device to be streamed off is required to be passed */
    	ret = ioctl(*capture_fd, VIDIOC_STREAMOFF, &a);
    	if (ret < 0) {
    		perror("VIDIOC_STREAMOFF\n");
    		return -1;
    	}
    	return 0;
    }
    
    /*=====================releaseCapture========================*/
    /* This function un-maps all the mmapped buffers of capture  *
     * and closes the capture file handle			     */
    static int releaseCapture(int *capture_fd, int numbuffers)
    {
    	int i;
    	/* Un-map the buffers */
    	for (i = 0; i < numbuffers; i++) {
    		munmap(capture_buff_info[i].start, capture_buff_info[i].length);
    		capture_buff_info[i].start = NULL;
    	}
    	/* Close the file handle */
    	close(*capture_fd);
    	*capture_fd = 0;
    	return 0;
    }
    
    /*=====================putCaptureBuffer====================*/
    /* This function en-queues empty buffer into the 	   *
     * capture device's incoming queue. 			   */
    static int putCaptureBuffer(int *capture_fd, int numbuffers, void *addr)
    {
    	struct v4l2_buffer buf;
    	int i, index = 0;
    	int ret;
    	if (addr == NULL)
    		return -1;
    
    	/* It is better to zero members of v4l2_buffer structure */
    	memset(&buf, 0, sizeof(buf));
    
    	/* Find index of the buffer whose address is passed as the argument */
    	for (i = 0; i < numbuffers; i++) {
    		if (addr == capture_buff_info[i].start) {
    			index = capture_buff_info[i].index;
    			break;
    		}
    	}
    
    	if (i == numbuffers)
    		return -1;
    
    	/* Enqueue the buffer */
    	buf.m.offset = (unsigned long)addr;
    
    	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	buf.memory = V4L2_MEMORY_MMAP;
    	buf.index = index;
    	ret = ioctl(*capture_fd, VIDIOC_QBUF, &buf);
    
    	if (ret < 0) {
    		perror("VIDIOC_QBUF\n");
    		return ret;
    	}
    
    	return 0;
    }
    
    /*=====================initDisplay========================*/
    /* This function initializes display device. It sets      *
     * output and standard on channel-2. These output and     *
     * standard are same as those detected in capture device. *
     * It, then, allocates buffers in the driver's memory     *
     * space and mmaps them in the application space	  */
    static int initDisplay(int *display_fd, int *numbuffers, struct v4l2_format *fmt)
    {
    	int mode = O_RDWR;
    	struct v4l2_buffer buf;
    	int ret, i = 0;
    	struct v4l2_requestbuffers reqbuf;
    	struct v4l2_output output;
    	int temp_output;
    	struct v4l2_standard standard;
    	v4l2_std_id std_id;
    	int found = 0;
    
    	/* Open the channel-2 display device */
    	*display_fd = open((const char *)DISPLAY_DEVICE, mode);
    	if (*display_fd <= 0) {
    		printf("Cannot open %s\n", DISPLAY_DEVICE);
    		return -1;
    	}
    
    	/* Enumerate outputs */
    	output.type = V4L2_OUTPUT_TYPE_ANALOG;
    	output.index = 0;
      	while ((ret = ioctl(*display_fd, VIDIOC_ENUMOUTPUT, &output) == 0)) { 
    		printf("output.name = %s\n", output.name);
    		if (!strcmp(output.name, input_name)) {
    			found = 1;
    			break;
    		}
    		output.index++;
      	}
    
    	if (!found) {
    		printf("Unable to find output name matching input name\n", input_name);
    		return -1;
    	}
    
    	/* Set output */
    	ret = ioctl(*display_fd, VIDIOC_S_OUTPUT, &output.index);
    	if (ret < 0) {
    		perror("VIDIOC_S_OUTPUT failed\n");
    		return -1;
    	}
    	
    	ret = ioctl(*display_fd, VIDIOC_G_OUTPUT, &temp_output);
    	if (ret < 0) {
    		perror("VIDIOC_S_OUTPUT failed\n");
    		return -1;
    	}
    
    	if (temp_output != output.index) {
    		printf("Couldn't set output index %d at display\n", output.index);
    		return -1;
    	}
    
    	/* Set standard */
    	found = 0;
    	/* Enumerate standard to get the name of the standard detected */
    	standard.index = 0;
    	do {
    		ret = ioctl(*display_fd, VIDIOC_ENUMSTD, &standard);
    		if (ret < 0) {
    			perror("VIDIOC_ENUM_STD failed\n");
    			return -1;
    		}
    		
    		
    		if (standard.id & input_std_id) {
    			printf("Found standard support in the driver\n");
    			found = 1;
    			break;
    		}
    		standard.index++;
    	} while (1);
    
    	ret == ioctl(*display_fd, VIDIOC_S_STD, &input_std_id);
    	if (ret < 0) {
    		perror("VIDIOC_S_STD failed\n");
    		return -1;
    	}
    
    	printf("Set output standard to match with input capture standard\n");
    
    	printf("Setting display format\n");
    
    	/* Set format */
    	CLEAR(*fmt);
    	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    	fmt->fmt.pix.bytesperline = BYTESPERLINE;
    	fmt->fmt.pix.sizeimage = sizeimage;
    	fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_NV16;
    	fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
    
    	ret = ioctl(*display_fd, VIDIOC_S_FMT, fmt);
    	if (ret < 0) {
    		perror("VIDIOC_S_FMT failed\n");
    		return -1;
    	}
    
    	CLEAR(*fmt);
    	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    	ret = ioctl(*display_fd, VIDIOC_G_FMT, fmt);
    	if (ret < 0) {
    		perror("VIDIOC_G_FMT\n");
    		return -1;
    	}
    
    	/* Buffer allocation 
    	 * Buffer can be allocated either from display driver or
    	 * user pointer can be used 
    	 */
    	/* Request for 3 buffers. As far as Physically contiguous 
    	 * memory is available, driver can allocate as many buffers as 
    	 * possible. If memory is not available, it returns number of 
    	 * buffers it has allocated in count member of reqbuf.
    	 * HERE count = number of buffer to be allocated.
    	 * type = type of device for which buffers are to be allocated. 
    	 * memory = type of the buffers requested i.e. driver allocated or 
    	 * user pointer */
    	reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    	reqbuf.count = *numbuffers;
    	reqbuf.memory = V4L2_MEMORY_MMAP;
    
    	ret = ioctl(*display_fd, VIDIOC_REQBUFS, &reqbuf);
    	if (ret < 0) {
    		perror("cannot allocate memory\n");
    		return -1;
    	}
    	/* Store the numbfer of buffers allocated */
    	*numbuffers = reqbuf.count;
    
    	/* It is better to zero all the members of buffer structure */
    	memset(&buf, 0, sizeof(buf));
    
    	/* Mmap the buffers
    	 * To access driver allocated buffer in application space, they have
    	 * to be mmapped in the application space using mmap system call */
    	for (i = 0; i < reqbuf.count; i++) {
    		/* Query physical address of the buffers */
    		buf.index = i;
    		buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    		buf.memory = V4L2_MEMORY_MMAP;
    		ret = ioctl(*display_fd, VIDIOC_QUERYBUF, &buf);
    		if (ret < 0) {
    			perror("VIDIOC_QUERYCAP\n");
    			return -1;
    		}
    
    		/* Mmap the buffers in application space */
    		display_buff_info[i].length = buf.length;
    		display_buff_info[i].index = i;
    		display_buff_info[i].start =
    		    mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
    			 MAP_SHARED, *display_fd, buf.m.offset);
    
    		if ((unsigned int)display_buff_info[i].start == MAP_SHARED) {
    			printf("Cannot mmap = %d buffer\n", i);
    			return -1;
    
    		}
    		/* It is better to zero buffers */
    		memset(display_buff_info[i].start, 0x80,
    		       display_buff_info[i].length);
    
    		printf("display_buff_info[%d].length = %d\n", i, display_buff_info[i].length); 
    		printf("display_buff_info[%d].index = %d\n", i, display_buff_info[i].index); 
    		printf("display_buff_info[%d].start = %p\n", i, display_buff_info[i].start); 
    	}
    
    	/* Enqueue buffers
    	 * Before starting streaming, all the buffers needs to be en-queued 
    	 * in the driver incoming queue. */
    	/* Enqueue buffers */
    	for (i = 0; i < reqbuf.count; i++) {
    		buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    		buf.memory = V4L2_MEMORY_MMAP;
    		buf.index = i;
    		ret = ioctl(*display_fd, VIDIOC_QBUF, &buf);
    		if (ret < 0) {
    			perror("VIDIOC_QBUF\n");
    			return -1;
    		}
    	}
    
    	return 0;
    }
    
    /*=====================releaseDisplay========================*/
    /* This function un-maps all the mmapped buffers of display  *
     * and closes the display file handle			     */
    static int releaseDisplay(int *display_fd, int numbuffers)
    {
    	int i;
    	/* Un-map buffers */
    	for (i = 0; i < numbuffers; i++) {
    		munmap(display_buff_info[i].start, display_buff_info[i].length);
    		display_buff_info[i].start = NULL;
    	}
    	/* Close the file handle */
    	close(*display_fd);
    	*display_fd = 0;
    	return 0;
    }
    
    /*=====================startDisplay========================*/
    /* This function starts streaming on the display device	   */
    static int startDisplay(int *display_fd)
    {
    	int a = V4L2_BUF_TYPE_VIDEO_OUTPUT, ret;
    	/* Here type of device to be streamed on is required to be passed */
    	ret = ioctl(*display_fd, VIDIOC_STREAMON, &a);
    	if (ret < 0) {
    		perror("VIDIOC_STREAMON\n");
    		return -1;
    	}
    	return 0;
    }
    
    /*=====================stopDisplay========================*/
    /* This function stops streaming on the display device	  */
    static int stopDisplay(int *display_fd)
    {
    	int ret, a = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    	/* Here type of device to be streamed off is required to be passed */
    	ret = ioctl(*display_fd, VIDIOC_STREAMOFF, &a);
    	if (ret < 0) {
    		perror("VIDIOC_STREAMOFF\n");
    		return -1;
    	}
    	return 0;
    }
    
    /*=====================getDisplayBuffer====================*/
    /* This function de-queues displayed empty buffer from the *
     * display device's outgoing queue. 			   */
    static void *getDisplayBuffer(int *display_fd)
    {
    	int ret;
    	struct v4l2_buffer buf;
    	/* It is better to zero members of v4l2_buffer structure */
    	memset(&buf, 0, sizeof(buf));
    	/* Dequeue buffer
    	 * VIDIOC_DQBUF ioctl de-queues a displayed empty buffer from driver.
    	 * This call can be blocking or non blocking. For blocking call, it
    	 * blocks untill an empty buffer is available. For non-blocking call,
    	 * it returns instantaneously with success or error depending on 
    	 * empty buffer is available or not. */
    	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    	ret = ioctl(*display_fd, VIDIOC_DQBUF, &buf);
    	if (ret < 0) {
    		perror("VIDIOC_DQBUF\n");
    		return NULL;
    	}
    	return display_buff_info[buf.index].start;
    }
    
    /*=====================putDisplayBuffer====================*/
    /* This function en-queues a buffer, which contains frame  *
     * to be displayed, into the display device's incoming     *
     * queue.						   */
    static int putDisplayBuffer(int *display_fd, int numbuffers, void *addr)
    {
    	struct v4l2_buffer buf;
    	int i, index = 0;
    	int ret;
    	if (addr == NULL)
    		return -1;
    
    	/* It is better to zero members of v4l2_buffer structure */
    	memset(&buf, 0, sizeof(buf));
    
    	/* Find index of the buffer whose address is passed as the argument */
    	for (i = 0; i < numbuffers; i++) {
    		if (addr == display_buff_info[i].start) {
    			index = display_buff_info[i].index;
    			break;
    		}
    	}
    
    	if (i == numbuffers)
    		return -1;
    
    	/* Enqueue the buffer */
    	buf.m.offset = (unsigned long)addr;
    	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    	buf.memory = V4L2_MEMORY_MMAP;
    	buf.index = index;
    	ret = ioctl(*display_fd, VIDIOC_QBUF, &buf);
    	if (ret < 0) {
    		perror("VIDIOC_QBUF\n");
    	}
    	return ret;
    }
    
    /*=====================app_main===========================*/
    int app_main()
    {
    	int i = 0;
    	void *capturebuffer0;
    	void *displaybuffer;
    	int counter = 0;
    	int ret = 0;
    	struct v4l2_format capture_fmt;
    	struct v4l2_format display_fmt;
    	int capture_chroma_offset, display_chroma_offset;
    	int capture_size;
    	int capture_fd, display_fd;
    	char outputname[15];
    	char stdname[15];
    	int capture_numbuffers = MAX_BUFFER, display_numbuffers = MAX_BUFFER;
    
    	for (i = 0; i < MAX_BUFFER; i++) {
    		capture_buff_info[i].start = NULL;
    		display_buff_info[i].start = NULL;
    	}
    
    	/* STEP1:
    	 * Initialization section
    	 * Initialize capture and display devices. 
    	 * Here one capture channel is opened 
    	 * Display channel is opened with the same standard that is detected at
    	 * capture channel. same output name as input
    	 * */
    
    	/* open capture channel 0 */
    	ret = initCapture(&capture_fd, &capture_numbuffers, &capture_fmt);
    	if (ret < 0) {
    		printf("Error in opening capture device for channel 0\n");
    		return ret;
    	}
    
    	printf(" Capture initialized\n");
    
    	/* open display channel */
    	if (display_enable) {
    		ret = initDisplay(&display_fd, &display_numbuffers, &display_fmt);
    		if (ret < 0) {
    			printf("Error in opening display device\n");
    			return ret;
    		}
    		printf(" Display initialized\n");
    		/* run section
    		 * STEP2:
    		 * Here display and capture channels are started for streaming. After 
    		 * this capture device will start capture frames into enqueued 
    		 * buffers and display device will start displaying buffers from 
    		 * the qneueued buffers */
    
    		/* start display */
    		ret = startDisplay(&display_fd);
    		if (ret < 0) {
    			printf("Error in starting display\n");
    			return ret;
    		}
    		printf(" display started \n");
    	}
    	/* start capturing for channel 0 */
    	ret = startCapture(&capture_fd);
    	if (ret < 0) {
    		printf("Error in starting capturing for channel 0\n");
    		return ret;
    	}
    
    	printf(" capture started \n");
    
    	/* calculate the offset from where chroma data will be stored for 
    	 * both capture and display */
    	capture_chroma_offset = kernel_buf_size/2;
    	//display_chroma_offset = display_fmt.fmt.pix.sizeimage / 2;
    	display_chroma_offset = kernel_buf_size/2;
    	capture_size = capture_fmt.fmt.pix.width * capture_fmt.fmt.pix.height;
    
    	/* One buffer is dequeued from display and capture channels.
    	 * Capture buffer will be copied to display buffer.
    	 * All two buffers are put back to respective channels.
    	 * This sequence is repeated in loop.
    	 * After completion of this loop, channels are stopped.
    	 * */
    	printf("Going into loopback\n");
    
    #if 0
    	sleep(10);
    #else
    	while (1) {
    		/* get capturing buffer for channel 0 */
    		capturebuffer0 = getCaptureBuffer(&capture_fd);
    		if (NULL == capturebuffer0) {
    			printf("Error in get capture buffer for channel 0\n");
    			return ret;
    		}
    
    		/* get display buffer */
    		if (display_enable) {
    			displaybuffer = getDisplayBuffer(&display_fd);
    			if (NULL == displaybuffer) {
    				printf("Error in get display buffer\n");
    				return ret;
    			}
    
    			/* Copy Luma data from capture buffer to display buffer */
    			memcpy(displaybuffer, capturebuffer0, capture_size);
    			/* Copy chroma data from capture buffer to display buffer
    			 * from the appropriate offsets in capture buffer and 
    			 * display buffer */
    			memcpy(displaybuffer + display_chroma_offset,
    				capturebuffer0 + capture_chroma_offset,
    				capture_size);
    
    			/* put output buffer into display queue */
    			ret = putDisplayBuffer(&display_fd, display_numbuffers,
    					       displaybuffer);
    			if (ret < 0) {
    				printf("Error in put display buffer\n");
    				return ret;
    			}
    		}
    		if (save_frame && counter == 100) {
    			fwrite(capturebuffer0, 1, capture_size,
    				file_fp);
    			fwrite(capturebuffer0 + capture_chroma_offset,
    				1, capture_size,
    				file_fp); 
    			fclose(file_fp);
    		}
    
    		/* put buffers in capture channels */
    		ret = putCaptureBuffer(&capture_fd, capture_numbuffers,
    				       capturebuffer0);
    		if (ret < 0) {
    			printf("Error in put capture buffer for channel 0\n");
    			return ret;
    		}
    		counter++;
    
    
    		if (print_fn)
    			printf("time:%lu    frame:%u\n", (unsigned long)time(NULL), counter);
    
    		if (stress_test && counter >= MAXLOOPCOUNT)
    			break;
    	}
    #endif
    
    	printf("After sleep, stop capture/display\n");
    	/* stop display */
    	if (display_enable) {
    		ret = stopDisplay(&display_fd);
    		if (ret < 0) {
    			printf("Error in stopping display\n");
    			return ret;
    		}
    	}
    	/* stop capturing for channel 0 */
    	ret = stopCapture(&capture_fd);
    	if (ret < 0) {
    		printf("Error in stopping capturing for channel 0\n");
    		return ret;
    	}
    
    	/* close capture channel 0 */
    	ret = releaseCapture(&capture_fd, capture_numbuffers);
    	if (ret < 0) {
    		printf("Error in closing capture device\n");
    		return ret;
    	}
    	/* Free section
    	 * Here channels for capture and display are close.
    	 * */
    	/* open display channel */
    	if (display_enable) {
    		ret = releaseDisplay(&display_fd, display_numbuffers);
    		if (ret < 0) {
    			printf("Error in closing display device\n");
    			return ret;
    		}
    	}
    	return ret;
    }
    
    void menu()
    {
    	printf("vpif_mmap_loopback -c <channel> -s <stress test> -p <print frame");
    	printf(" number, -m <ntsc or pal>\n");
    }
    
    /******************************************************************************
      			Program Main
    *******************************************************************************/
    int main(int argc, char *argv[])
    {
    	int ret = 0, d, index;
    	char shortoptions[] = "s:c:p:m:d:w:";
    	/* 0 or 1 */
    	static int channel_no;
    	/* 0 - NTSC, 1 - PAL */
    	static int input_std = V4L2_STD_NTSC;
    	
    	
    
    	input_device = CAPTURE_DEVICE0;
    	input_name = CAPTURE_INPUT0;
    
    	for (;;) {
    		d = getopt_long(argc, argv, shortoptions, (void *)NULL, &index);
    		if (-1 == d)
    			break;
    		switch (d) {
    		case 'm':
    		case 'M':
    			input_std = atoi(optarg);
    			if (input_std) {
    				input_std_id = V4L2_STD_PAL;
    				sizeimage = BYTESPERLINE*576*2;
    			}
    			break;
    		case 's':
    		case 'S':
    			stress_test = atoi(optarg);
    			break;
    		case 'p':
    		case 'P':
    			print_fn = atoi(optarg);
    			break;
    		case 'c':
    		case 'C':
    			channel_no = atoi(optarg);
    			if (channel_no == 1) {
    				input_device = CAPTURE_DEVICE1;
    				input_name = CAPTURE_INPUT1;
    			}
    			break;
    		case 'd':
    		case 'D':
    			display_enable =  atoi(optarg);
    			break;
    		case 'w':
    		case 'W':
    			save_frame = atoi(optarg);
    			break;
    		default:
    			menu();
    			exit(1);
    		}
    	}
    	if (save_frame) {
    		file_fp = fopen("./capt_frame.yuv", "wb");
    		if (file_fp == NULL) {
    			printf("Unable to open ./capt_frame.yuv\n");
    			exit(1);
    		}
    	}
    
    	app_main();
    	return 0;
    }
    

    and it freeze(cursor blink without any output on the console and vga display) when using with USBwebcam. (I have already edit the code by set the resolution to 640x480 which is supported on my webcam)

    3. camera_test.c doesn't work with both input either but it gives different error message compare with vpif_mmap_loopback.c. (code from http://elinux.org/Testing_Video_Input_of_Hawkboard)

    USBwebcam

    I have to make change to the following line to make it runs

    if (ioctl(cinfo->fd, VIDIOC_S_STD, &std_id) == -1) {
        printf("Unable to set video standard\n");
        //err = EINVAL;
        //goto cleanup_devnode;
    }

    /*
     * Author: Yusuf Caglar Akyuz, Bilkon, Inc. <caglar@bilkon-kontrol.com.tr>
     *
     * Copyright (C) 2010 Bilkon Bilgisayar Kontrollu Cihazlar Ltd. Sti.
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License.
    
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    #include <asm/errno.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #include <sys/ioctl.h>
    #include <asm/types.h>
    
    #include "camera.h"
    
    /**
     * This function detects if camera is plugged or not.
     *
     * Note: This feature is currently broken in Hawkboard,
     * probably in all DaVincis.
     */
    static int detect_camera(int fd)
    {
    	int input;
        if (ioctl(fd, VIDIOC_G_INPUT, &input) == -1) {
        	printf("Failed GET_INPUT. No inputs connected?\n");
        	return -ENODEV;
        }
    
    	return 0;
    }
    
    /**
     * Allocates capture buffers from the kernel driver. Since
     * kernel drivers are contiguous, it is safe to pass these buffers
     * to DSP side.
     *
     * Return 0 on success.
     */
    static int alloc_buffers(unsigned int buf_cnt, enum v4l2_buf_type type,
                              struct capture_info *info)
    {
        struct v4l2_requestbuffers  req;
        struct v4l2_format          fmt;
    
        fmt.type = type;
        int fd = info->fd;
        unsigned int i;
    
        if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) {
            return -EINVAL;
        }
    
        req.count  = buf_cnt;
        req.type   = type;
        req.memory = V4L2_MEMORY_MMAP;
    
        /* Allocate buffers in the capture device driver */
        if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
            return -ENOMEM;
        }
    
        if (req.count < buf_cnt || !req.count) {
            return -ENOMEM;
        }
    
        for (i = 0; i < buf_cnt; i++) {
            info->v4l2buf[i].type   = type;
            info->v4l2buf[i].memory = V4L2_MEMORY_MMAP;
            info->v4l2buf[i].index  = i;
    
            if (ioctl(fd, VIDIOC_QUERYBUF, &info->v4l2buf[i]) == -1) {
                return -ENOMEM;
            }
    
            /* Map the driver buffer to user space */
            info->userptr[i] = mmap(NULL,
                           info->v4l2buf[i].length,
                           PROT_READ | PROT_WRITE,
                           MAP_SHARED,
                           fd,
                           info->v4l2buf[i].m.offset);
    
            if (info->userptr[i] == MAP_FAILED) {
                return -ENOMEM;
            }
    
            /* Queue buffer in device driver */
            if (ioctl(fd, VIDIOC_QBUF, &info->v4l2buf[i]) == -1) {
                return -ENOMEM;
            }
        }
    
        return 0;
    }
    
    /**
     * Stop capturing from the camera.
     *
     * Returns 0 on success.
     */
    int close_camera(struct capture_info *cinfo)
    {
    	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	int i;
    
    	/* Stop the video streaming */
        if (ioctl(cinfo->fd, VIDIOC_STREAMOFF, &type) == -1) {
            printf("VIDIOC_STREAMOFF failed on device\n");
        }
    
        for (i = 0; i < 3; i++)
        	munmap(cinfo->userptr[i], cinfo->v4l2buf[i].length);
    
    	close(cinfo->fd);
    	cinfo->fd = -1;
    	return 0;
    }
    
    /**
     * Adjusts Linux kernel camera driver for capturing.
     *
     * Camera is adjusted for 640x480 resolution and cropping is not
     * supported.
     *
     * Returns 0 on success.
     */
    int init_camera(struct capture_info *cinfo)
    {
    	v4l2_std_id 				std_id = V4L2_STD_625_50; // Edit here V4L2_STD_625_50
        struct v4l2_capability      cap;
        struct v4l2_format          fmt;
        struct v4l2_input          	input;
        enum v4l2_buf_type          type;
        int width = 640, height = 480;
    	int err = 0;
    
        /* Open video capture device */
        cinfo->fd = open(cinfo->device_name, O_RDWR, 0);
        if (cinfo->fd == -1) {
        	printf("Cannot open capture device %s\n", cinfo->device_name);
            return -ENODEV;
        }
        /* See if an input is connected */
        if (detect_camera(cinfo->fd) != 0) {
        	printf("Cannot detect camera on the capture input\n");
            err = ENODEV;
            goto cleanup_devnode;
        }
        err = 0;
        if (ioctl(cinfo->fd, VIDIOC_S_INPUT, &err) == -1) {
        	printf("Failed set video input\n");
            err = ENODEV;
            goto cleanup_devnode;
        }
        input.index = 0;
        if (ioctl(cinfo->fd, VIDIOC_ENUMINPUT, &input) == -1) {
        	printf("Unable to enumerate input\n");
        }
        if (ioctl(cinfo->fd, VIDIOC_S_STD, &std_id) == -1) {
        	printf("Unable to set video standard\n");
        	//err = EINVAL;
            //goto cleanup_devnode;
        }
        /* Query for capture device capabilities */
        if (ioctl(cinfo->fd, VIDIOC_QUERYCAP, &cap) == -1) {
        	printf("Unable to query device for capture capabilities\n");
        	err = errno;
            goto cleanup_devnode;
        }
        if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        	printf("Device does not support capturing\n");
            err = EINVAL;
            goto cleanup_devnode;
        }
        if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
            printf("Device does not support streaming\n");
            err = EINVAL;
            goto cleanup_devnode;
        }
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(cinfo->fd, VIDIOC_G_FMT, &fmt) == -1) {
            printf("Unable to get VIDIOC_G_FMT\n");
            err = EINVAL;
            goto cleanup_devnode;
        }
    
        fmt.fmt.pix.width        = width;
        fmt.fmt.pix.height       = height;
        fmt.fmt.pix.bytesperline = width * 2;
        fmt.fmt.pix.pixelformat  = V4L2_PIX_FMT_MJPEG;	// edit here
        fmt.fmt.pix.field        = V4L2_FIELD_INTERLACED;
    
        if (ioctl(cinfo->fd, VIDIOC_S_FMT, &fmt) == -1) {
            printf("Unable to set VIDIOC_S_FMT\n");
            err = EINVAL;
            goto cleanup_devnode;
        }
    
        if (alloc_buffers(1, V4L2_BUF_TYPE_VIDEO_CAPTURE, cinfo) < 0) {
            printf("Unable to allocate capture driver buffers\n");
            err = ENOMEM;
            goto cleanup_devnode;
        }
    return 0;
        /* Start the video streaming */
        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
        if (ioctl(cinfo->fd, VIDIOC_STREAMON, &type) == -1) {
            printf("VIDIOC_STREAMON failed on device\n");
            err = EPERM;
            goto cleanup_devnode;
        }
    
        return 0;
    
    cleanup_devnode:
    	close(cinfo->fd);
    	return -err;
    }
    
    /**
     * Receives a frame from the camera driver using V4L2 API.
     */
    int get_camera_frame(struct capture_info *cinfo)
    {
        struct v4l2_buffer v4l2buf;
    
        v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        v4l2buf.memory = V4L2_MEMORY_MMAP;
    
        /* Get a frame buffer with captured data */
        if (ioctl(cinfo->fd, VIDIOC_DQBUF, &v4l2buf) < 0) {
            printf("VIDIOC_DQBUF failed\n");
            return -EIO;
        }
    
        return v4l2buf.index;
    }
    
    /**
     * Gives previously received camera buffer back to V4L2 kernel driver.
     */
    int put_camera_frame(struct capture_info *cinfo, int buf_no)
    {
        cinfo->v4l2buf[buf_no].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
        /* Issue captured frame buffer back to device driver */
        if (ioctl(cinfo->fd, VIDIOC_QBUF, &cinfo->v4l2buf[buf_no]) == -1) {
            printf("VIDIOC_QBUF failed (%s)\n", strerror(errno));
            return -EIO;
        }
    
        return 0;
    }
    
    


    FYI, my vga lcd screen resolution is 1080p (I don't think it causes any problem)

    Thanks you very much for your help

    Palm

  • Hi Palm,

    You can try to use "facedetect" demo which loopback the composite input to VGA output.

    I have tried already this facdetect demo run on my LCDK board with DVD player composite input & composite surveillance camera and able to run successfully but not with LCD (only VGA).

    Need to change "static void SetUpLCD(void)" function for LCD (width, height & PCLK etc.,)

    ti/c6sdk_02_00_00_00/demos/facedetect/src/facedetect_lcdk.c.

    http://processors.wiki.ti.com/index.php/BIOS_C6SDK_2.0_User_Guide#Facedetect

    http://processors.wiki.ti.com/index.php/BIOS_C6SDK_2.0_Getting_Started_Guide

    I don't have a LCD for LCDK board.

  • I don't have the LCD screen either. The display I use to test is my 1080p vga display. I will try the code and get back with you soon.

    Thank you for your help

    Palm

  • This code is for the C6748 lcdk and run without any operating system. How can I run it on the ARM side of my OMAP-L138 lcdk board? I don't think it is possible.


    By the way, do you have any idea on what is actually the problem with my code and configuration? I have tried to capture and write all the detail regarding my problem. If there is anything you would like to know, I could upload more file and do more testing.

    Palm