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.

Regarding Video Capture in DM81xx

Other Parts Discussed in Thread: TVP7002, PCF8575, THS7375, THS7360

Greetings:

1.       V4L2 Capture: http://processors.wiki.ti.com/index.php/DM81xx_AM38xx_Video_Capture_Driver_User_Guide#Sample_Applications

In the above wiki link, it seems that v4l2 capture ( name: ti81xxin.ko) has been available, although the sample application given is still using TVP decoder.

--Is this video capture the general digital video capture driver?

In other meanings, as long as we feed DM814x/DM816x Soc with standard video streams like RGB888/YUV422, the Soc can recognize and accept them for our future video processing, regardless where our video stream come from either HDMI or DVI.          

========

Our current solution is using the capture-encode omx example to do the video capture and using  TI81xx-gstreamer to implement network protocols.

  I am wondering is there any compatible issues between omx lib and TI81xx-gstreamer lib?

 

Cheers,

 

Jun

  • Hi,

    Capture driver is based on V4L2 Framework of Linux. For supporting any capture master driver there needs to be slave driver  like TVP7002 or sil1161 or anything. You can very well modify the V4L2 capture driver to user your own slave driver or not to use at all.  V4L2 framework works on notion of master driver and slave driver. Master driver is the one which does DMA of the received data to memory. While slave driver is the one which provides requried data to master driver like TVP7002, TVP1161. Master drivers are configurable to use any of the decoders through board file.  You can look at $Kernel_source\arch\arm\mach-omap2\baord-ti8148evm.c or $Kernel_source\arch\arm\mach-omap2\baord-ti8168evm.c

     

    Regards,

    Hardik Shah

  • Hi Hardik

     

    Thanks for your reply very much.

    I got most of your reply but still confused by "Master drivers are configurable to use any of the decoders through board file"

    After took look into the board-ti8168evm.c, I still do not know where should I modify the C codes to let Master drivers configured to the decoder we will going to use, like HDMI rx Sil9135 or any other decoders which can output standard YUV video streams.

    I would appreciate if you can give us more detail.

     

    Thanks in advance,

     

    Jun

     

    =================================================

    board-ti8168evm.c

    ========================

    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/platform_device.h>
    #include <linux/i2c/at24.h>
    #include <linux/device.h>
    #include <linux/mtd/mtd.h>
    #include <linux/mtd/partitions.h>
    #include <linux/device.h>
    #include <linux/mtd/nand.h>
    #include <linux/spi/spi.h>
    #include <linux/spi/flash.h>
    #include <linux/mtd/physmap.h>
    #include <linux/phy.h>
    #include <linux/gpio.h>
    #include <linux/regulator/machine.h>
    #include <linux/regulator/gpio-regulator.h>

    #include <mach/hardware.h>
    #include <asm/mach-types.h>
    #include <asm/mach/arch.h>
    #include <asm/mach/map.h>

    #include <plat/mcspi.h>
    #include <plat/irqs.h>
    #include <plat/board.h>
    #include <plat/common.h>
    #include <plat/asp.h>
    #include <plat/usb.h>
    #include <plat/mmc.h>
    #include <plat/gpmc.h>
    #include <plat/nand.h>
    #include <plat/hdmi_lib.h>

    #include "control.h"


    #include "clock.h"
    #include "mux.h"
    #include "hsmmc.h"
    #include "board-flash.h"
    #include <mach/board-ti816x.h>

    static struct omap2_hsmmc_info mmc[] = {
        {
            .mmc        = 1,
            .caps           = MMC_CAP_4_BIT_DATA,
            .gpio_cd    = -EINVAL,/* Dedicated pins for CD and WP */
            .gpio_wp    = -EINVAL,
            .ocr_mask    = MMC_VDD_33_34,
        },
        {}    /* Terminator */
    };

    static struct mtd_partition ti816x_evm_norflash_partitions[] = {
        /* bootloader (U-Boot, etc) in first 5 sectors */
        {
            .name        = "bootloader",
            .offset        = 0,
            .size        = 2 * SZ_128K,
            .mask_flags    = MTD_WRITEABLE, /* force read-only */
        },
        /* bootloader params in the next 1 sectors */
        {
            .name        = "env",
            .offset        = MTDPART_OFS_APPEND,
            .size        = SZ_128K,
            .mask_flags    = 0,
        },
        /* kernel */
        {
            .name        = "kernel",
            .offset        = MTDPART_OFS_APPEND,
            .size        = 2 * SZ_2M,
            .mask_flags    = 0
        },
        /* file system */
        {
            .name        = "filesystem",
            .offset        = MTDPART_OFS_APPEND,
            .size        = 25 * SZ_2M,
            .mask_flags    = 0
        },
        /* reserved */
        {
            .name        = "reserved",
            .offset        = MTDPART_OFS_APPEND,
            .size        = MTDPART_SIZ_FULL,
            .mask_flags    = 0
        }
    };


    /* Maximum ports supported by the PCF8575 */
    #define VPS_PCF8575_MAX_PORTS           (2u)

    /* Macros for accessing for ports */
    #define VPS_PCF8575_PORT0               (0u)
    #define VPS_PCF8575_PORT1               (1u)

    /* Macros for PCF8575 Pins */
    #define VPS_PCF8575_PIN0                (0x1)
    #define VPS_PCF8575_PIN1                (0x2)
    #define VPS_PCF8575_PIN2                (0x4)
    #define VPS_PCF8575_PIN3                (0x8)
    #define VPS_PCF8575_PIN4                (0x10)
    #define VPS_PCF8575_PIN5                (0x20)
    #define VPS_PCF8575_PIN6                (0x40)
    #define VPS_PCF8575_PIN7                (0x80)

    #define VPS_PCF8575_PIN10               (0x1)
    #define VPS_PCF8575_PIN11               (0x2)

    #define VPS_THS7375_MASK                (VPS_PCF8575_PIN10 | VPS_PCF8575_PIN11)

    #define VPS_THS7360_SD_MASK             (VPS_PCF8575_PIN2 | VPS_PCF8575_PIN5)

    #define VPS_THS7360_SF_MASK             (VPS_PCF8575_PIN0 |                    \
                         VPS_PCF8575_PIN1 |                    \
                         VPS_PCF8575_PIN3 |                    \
                         VPS_PCF8575_PIN4)

    #define NAND_BLOCK_SIZE                    SZ_128K

    /* Macro for GPIO voltage regulator */
    #define VR_GPIO_INSTANCE    0

    static struct mtd_partition ti816x_nand_partitions[] = {
    /* All the partition sizes are listed in terms of NAND block size */
        {
            .name           = "U-Boot",
            .offset         = 0,    /* Offset = 0x0 */
            .size           = 19 * NAND_BLOCK_SIZE,
            .mask_flags     = MTD_WRITEABLE,        /* force read-only */
        },
        {
            .name           = "U-Boot Env",
            .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x260000 */
            .size           = 1 * NAND_BLOCK_SIZE,
        },
        {
            .name           = "Kernel",
            .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x280000 */
            .size           = 34 * NAND_BLOCK_SIZE,
        },
        {
            .name           = "File System",
            .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x6C0000 */
            .size           = 1601 * NAND_BLOCK_SIZE,
        },
        {
            .name           = "Reserved",
            .offset         = MTDPART_OFS_APPEND,   /* Offset = 0xCEE0000 */
            .size           = MTDPART_SIZ_FULL,
        },
    };

    static struct at24_platform_data eeprom_info = {
        .byte_len       = (256*1024) / 8,
        .page_size      = 64,
        .flags          = AT24_FLAG_ADDR16,
    };

    #ifdef CONFIG_REGULATOR_GPIO
    static struct regulator_consumer_supply ti816x_gpio_dcdc_supply[] = {
        {
            .supply = "vdd_avs",
        },
    };

    static struct regulator_init_data gpio_pmic_init_data = {
        .constraints = {
            .min_uV        = 800000,
            .max_uV        = 1025000,
            .valid_ops_mask    = (REGULATOR_CHANGE_VOLTAGE |
                REGULATOR_CHANGE_STATUS),
        },
        .num_consumer_supplies    = ARRAY_SIZE(ti816x_gpio_dcdc_supply),
        .consumer_supplies    = ti816x_gpio_dcdc_supply,
    };

    /* Supported voltage values for regulators */
    static struct gpio_vr_data ti816x_vsel_table[] = {
        {0x0, 800000}, {0x8, 815000}, {0x4, 830000}, {0xC, 845000},
        {0x2, 860000}, {0xA, 875000}, {0x6, 890000}, {0xE, 905000},
        {0x1, 920000}, {0x9, 935000}, {0x5, 950000}, {0xD, 965000},
        {0x3, 980000}, {0xB, 995000}, {0x7, 1010000}, {0xF, 1025000},
    };

    static struct gpio vcore_gpios[] = {
        { (VR_GPIO_INSTANCE * 32) + 0, GPIOF_IN, "vgpio 0"},
        { (VR_GPIO_INSTANCE * 32) + 1, GPIOF_IN, "vgpio 1"},
        { (VR_GPIO_INSTANCE * 32) + 2, GPIOF_IN, "vgpio 2"},
        { (VR_GPIO_INSTANCE * 32) + 3, GPIOF_IN, "vgpio 3"},
    };

    /* GPIO regulator platform data */
    static struct gpio_reg_platform_data gpio_vr_init_data = {
        .name            = "VFB",
        .pmic_init_data        = &gpio_pmic_init_data,
        .gpio_vsel_table    = ti816x_vsel_table,
        .num_voltages        = ARRAY_SIZE(ti816x_vsel_table),
        .gpios            = vcore_gpios,
        .gpio_single_bank    = true,
        .gpio_arr_mask        = 0xF,
        .num_gpio_pins        = ARRAY_SIZE(vcore_gpios),
        .pmic_vout        = 600000,
    };

    /* VCORE for SR regulator init */
    static struct platform_device ti816x_gpio_vr_device = {
        .name        = "gpio_vr",
        .id        = -1,
        .dev = {
            .platform_data = &gpio_vr_init_data,
        },
    };

    static void __init ti816x_gpio_vr_init(void)
    {
        if (platform_device_register(&ti816x_gpio_vr_device))
            printk(KERN_ERR "failed to register ti816x_gpio_vr device\n");
        else
            printk(KERN_INFO "registered ti816x_gpio_vr device\n");
    }
    #else
    static inline void ti816x_gpio_vr_init(void) {}
    #endif

    static struct i2c_board_info __initdata ti816x_i2c_boardinfo0[] = {
        {
            I2C_BOARD_INFO("eeprom", 0x50),
            .platform_data    = &eeprom_info,
        },
        {
            I2C_BOARD_INFO("cpld", 0x23),
        },
        {
            I2C_BOARD_INFO("tlv320aic3x", 0x18),
        },
        {
            I2C_BOARD_INFO("IO Expander", 0x20),
        },

    };

    static struct i2c_board_info __initdata ti816x_i2c_boardinfo1[] = {
        {
            I2C_BOARD_INFO("pcf8575_1", 0x20),
        },
        {
            I2C_BOARD_INFO("sii9022a", 0x39),
        }
    };

    static struct i2c_client *pcf8575_1_client;
    static unsigned char pcf8575_port[2] = {0, 0};

    int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)
    {
        struct i2c_msg msg = {
                .addr = pcf8575_1_client->addr,
                .flags = 0,
                .len = 2,
            };

        pcf8575_port[1] &= ~VPS_THS7375_MASK;
        pcf8575_port[1] |= (ctrl & VPS_THS7375_MASK);
        msg.buf = pcf8575_port;

        return i2c_transfer(pcf8575_1_client->adapter, &msg, 1);
    }
    EXPORT_SYMBOL(pcf8575_ths7375_enable);

    int pcf8575_ths7360_sd_enable(enum ti816x_ths_filter_ctrl ctrl)
    {
        struct i2c_msg msg = {
            .addr = pcf8575_1_client->addr,
            .flags = 0,
            .len = 2,
        };

        pcf8575_port[0] &= ~VPS_THS7360_SD_MASK;
        switch (ctrl)    {
        case TI816X_THSFILTER_ENABLE_MODULE:
            pcf8575_port[0] &= ~(VPS_THS7360_SD_MASK);
            break;
        case TI816X_THSFILTER_BYPASS_MODULE:
            pcf8575_port[0] |= VPS_PCF8575_PIN2;
            break;
        case TI816X_THSFILTER_DISABLE_MODULE:
            pcf8575_port[0] |= VPS_THS7360_SD_MASK;
            break;
        default:
            return -EINVAL;
        }

        msg.buf = pcf8575_port;

        return i2c_transfer(pcf8575_1_client->adapter, &msg, 1);
    }
    EXPORT_SYMBOL(pcf8575_ths7360_sd_enable);

    int pcf8575_ths7360_hd_enable(enum ti816x_ths7360_sf_ctrl ctrl)
    {
        struct i2c_msg msg = {
            .addr = pcf8575_1_client->addr,
            .flags = 0,
            .len = 2,
        };

        pcf8575_port[0] &= ~VPS_THS7360_SF_MASK;

        switch (ctrl) {
        case TI816X_THS7360_DISABLE_SF:
            pcf8575_port[0] |= VPS_PCF8575_PIN4;
            break;
        case TI816X_THS7360_BYPASS_SF:
            pcf8575_port[0] |= VPS_PCF8575_PIN3;
            break;
        case TI816X_THS7360_SF_SD_MODE:
            pcf8575_port[0] &= ~(VPS_THS7360_SF_MASK);
            break;
        case TI816X_THS7360_SF_ED_MODE:
            pcf8575_port[0] |= VPS_PCF8575_PIN0;
            break;
        case TI816X_THS7360_SF_HD_MODE:
            pcf8575_port[0] |= VPS_PCF8575_PIN1;
            break;
        case TI816X_THS7360_SF_TRUE_HD_MODE:
            pcf8575_port[0] |= VPS_PCF8575_PIN0|VPS_PCF8575_PIN1;
            break;
        default:
                return -EINVAL;
        }

        msg.buf = pcf8575_port;

        return i2c_transfer(pcf8575_1_client->adapter, &msg, 1);
    }
    EXPORT_SYMBOL(pcf8575_ths7360_hd_enable);

    static int pcf8575_video_probe(struct i2c_client *client,
                    const struct i2c_device_id *id)
    {
        pcf8575_1_client = client;
        return 0;
    }

    static int __devexit pcf8575_video_remove(struct i2c_client *client)
    {
        pcf8575_1_client = NULL;
        return 0;
    }

    static const struct i2c_device_id pcf8575_video_id[] = {
        { "pcf8575_1", 0 },
        { }
    };

    static struct i2c_driver pcf8575_driver = {
        .driver = {
            .name   = "pcf8575_1",
        },
        .probe          = pcf8575_video_probe,
        .remove         = pcf8575_video_remove,
        .id_table       = pcf8575_video_id,
    };

    int ti816x_pcf8575_init(void)
    {
        i2c_add_driver(&pcf8575_driver);
        return 0;
    }
    EXPORT_SYMBOL(ti816x_pcf8575_init);

    int ti816x_pcf8575_exit(void)
    {
        i2c_del_driver(&pcf8575_driver);
        return 0;
    }
    EXPORT_SYMBOL(ti816x_pcf8575_exit);
    /* FIX ME: Check on the Bit Value */

    #define TI816X_EVM_CIR_UART BIT(5)

    static struct i2c_client *cpld_reg0_client;

    /* CPLD Register 0 Client: used for I/O Control */
    static int cpld_reg0_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
    {
        u8 data;
        struct i2c_msg msg[2] = {
            {
                .addr = client->addr,
                .flags = I2C_M_RD,
                .len = 1,
                .buf = &data,
            },
            {
                .addr = client->addr,
                .flags = 0,
                .len = 1,
                .buf = &data,
            },
        };

        cpld_reg0_client = client;

        /* Clear UART CIR to enable cir operation. */
            i2c_transfer(client->adapter, msg, 1);
            data &= ~(TI816X_EVM_CIR_UART);
            i2c_transfer(client->adapter, msg + 1, 1);
        return 0;
    }

    static const struct i2c_device_id cpld_reg_ids[] = {
            { "cpld_reg0", 0, },
            { },
    };

    static struct i2c_driver ti816xevm_cpld_driver = {
        .driver.name    = "cpld_reg0",
        .id_table       = cpld_reg_ids,
        .probe          = cpld_reg0_probe,
    };

    static int __init ti816x_evm_i2c_init(void)
    {
        omap_register_i2c_bus(1, 100, ti816x_i2c_boardinfo0,
            ARRAY_SIZE(ti816x_i2c_boardinfo0));
        omap_register_i2c_bus(2, 100, ti816x_i2c_boardinfo1,
            ARRAY_SIZE(ti816x_i2c_boardinfo1));
        return 0;
    }

    /* SPI fLash information */
    struct mtd_partition ti816x_spi_partitions[] = {
        /* All the partition sizes are listed in terms of NAND block size */
        {
            .name        = "U-Boot",
            .offset        = 0,    /* Offset = 0x0 */
            .size        = 64 * SZ_4K,
            .mask_flags    = MTD_WRITEABLE,    /* force read-only */
        },
        {
            .name        = "U-Boot Env",
            .offset        = MTDPART_OFS_APPEND,    /* Offset = 0x40000 */
            .size        = 2 * SZ_4K,
        },
        {
            .name        = "Kernel",
            .offset        = MTDPART_OFS_APPEND,    /* Offset = 0x42000 */
            .size        = 640 * SZ_4K,
        },
        {
            .name        = "File System",
            .offset        = MTDPART_OFS_APPEND,    /* Offset = 0x2C2000 */
            .size        = MTDPART_SIZ_FULL,    /* size = 1.24 MiB */
        }
    };

    const struct flash_platform_data ti816x_spi_flash = {
        .type        = "w25x32",
        .name        = "spi_flash",
        .parts        = ti816x_spi_partitions,
        .nr_parts    = ARRAY_SIZE(ti816x_spi_partitions),
    };

    struct spi_board_info __initdata ti816x_spi_slave_info[] = {
        {
            .modalias    = "m25p80",
            .platform_data    = &ti816x_spi_flash,
            .irq        = -1,
            .max_speed_hz    = 75000000,
            .bus_num    = 1,
            .chip_select    = 0,
        },
    };

    static void __init ti816x_spi_init(void)
    {
        spi_register_board_info(ti816x_spi_slave_info,
                    ARRAY_SIZE(ti816x_spi_slave_info));
    }


    static void __init ti8168_evm_init_irq(void)
    {
        omap2_init_common_infrastructure();
        omap2_init_common_devices(NULL, NULL);
        omap_init_irq();
        gpmc_init();
    }

    static u8 ti8168_iis_serializer_direction[] = {
        TX_MODE,    RX_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,    INACTIVE_MODE,    INACTIVE_MODE,
    };

    static struct snd_platform_data ti8168_evm_snd_data = {
        .tx_dma_offset    = 0x46800000,
        .rx_dma_offset    = 0x46800000,
        .op_mode    = DAVINCI_MCASP_IIS_MODE,
        .num_serializer = ARRAY_SIZE(ti8168_iis_serializer_direction),
        .tdm_slots    = 2,
        .serial_dir    = ti8168_iis_serializer_direction,
        .asp_chan_q    = EVENTQ_2,
        .version    = MCASP_VERSION_2,
        .txnumevt    = 1,
        .rxnumevt    = 1,
    };

    static struct omap_musb_board_data musb_board_data = {
        .interface_type        = MUSB_INTERFACE_ULPI,
    #ifdef CONFIG_USB_MUSB_OTG
        .mode           = MUSB_OTG,
    #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
        .mode           = MUSB_HOST,
    #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
        .mode           = MUSB_PERIPHERAL,
    #endif
        .power        = 500,
        .instances    = 1,
    };

    #ifdef CONFIG_OMAP_MUX
    static struct omap_board_mux board_mux[] __initdata = {

        /* PIN mux for non-muxed NOR */
        TI816X_MUX(TIM7_OUT, OMAP_MUX_MODE1),    /* gpmc_a12 */
        TI816X_MUX(UART1_CTSN, OMAP_MUX_MODE1),    /* gpmc_a13 */
        TI816X_MUX(UART1_RTSN, OMAP_MUX_MODE1),    /* gpmc_a14 */
        TI816X_MUX(UART2_RTSN, OMAP_MUX_MODE1),    /* gpmc_a15 */
        /* REVISIT: why 2 lines configured as gpmc_a15 */
        TI816X_MUX(SC1_RST, OMAP_MUX_MODE1),    /* gpmc_a15 */
        TI816X_MUX(UART2_CTSN, OMAP_MUX_MODE1),    /* gpmc_a16 */
        TI816X_MUX(UART0_RIN, OMAP_MUX_MODE1),    /* gpmc_a17 */
        TI816X_MUX(UART0_DCDN, OMAP_MUX_MODE1),    /* gpmc_a18 */
        TI816X_MUX(UART0_DSRN, OMAP_MUX_MODE1),    /* gpmc_a19 */
        TI816X_MUX(UART0_DTRN, OMAP_MUX_MODE1),    /* gpmc_a20 */
        TI816X_MUX(SPI_SCS3, OMAP_MUX_MODE1),    /* gpmc_a21 */
        TI816X_MUX(SPI_SCS2, OMAP_MUX_MODE1),    /* gpmc_a22 */
        TI816X_MUX(GP0_IO6, OMAP_MUX_MODE2),    /* gpmc_a23 */
        TI816X_MUX(TIM6_OUT, OMAP_MUX_MODE1),    /* gpmc-a24 */
        TI816X_MUX(SC0_DATA, OMAP_MUX_MODE1),    /* gpmc_a25 */
        /* for controlling high address */
        TI816X_MUX(GPMC_A27, OMAP_MUX_MODE1),    /* gpio-20 */
        { .reg_offset = OMAP_MUX_TERMINATOR },
    };
    #else
    #define board_mux    NULL
    #endif

    int __init ti_ahci_register(u8 num_inst);
    static struct platform_device vpss_device = {
        .name = "vpss",
        .id = -1,
        .dev = {
            .platform_data = NULL,
        },
    };

    static void __init ti816x_vpss_init(void)
    {
        if (platform_device_register(&vpss_device))
            printk(KERN_ERR "failed to register ti816x_vpss device\n");
        else
            printk(KERN_INFO "registered ti816x_vpss device\n");
        /*FIXME add platform data here*/
    }

    static struct platform_device ti816x_hdmi_plat_device = {
        .name = "TI81XX_HDMI",
        .id = -1,
        .num_resources = 0,
        .dev = {
            /*.release = ti81xx_hdmi_platform_release,*/
            .platform_data = NULL,
        }
    };

    #ifdef CONFIG_SND_SOC_TI81XX_HDMI
    static struct snd_hdmi_platform_data ti8168_snd_hdmi_pdata = {
        .dma_addr = TI81xx_HDMI_WP + HDMI_WP_AUDIO_DATA,
        .channel = 53,
        .data_type = 4,
        .acnt = 4,
        .fifo_level = 0x20,
    };

    static struct platform_device ti8168_hdmi_audio_device = {
        .name    = "hdmi-dai",
        .id    = -1,
            .dev = {
            .platform_data = &ti8168_snd_hdmi_pdata,
            }
    };

    static struct platform_device ti8168_hdmi_codec_device = {
        .name    = "hdmi-dummy-codec",
        .id    = -1,
    };

    static struct platform_device *ti8168_devices[] __initdata = {
        &ti8168_hdmi_audio_device,
        &ti8168_hdmi_codec_device,
    };
    #endif

    static void __init ti816x_hdmi_init(void)
    {

        if (platform_device_register(&ti816x_hdmi_plat_device))
            printk(KERN_ERR "Could not register TI816x onchip-HDMI device\n");
        else
            printk(KERN_INFO "registered TI816x on-chip HDMI device\n");
        /*FIXME add platform data here*/
    }


    static void __init ti8168_evm_init(void)
    {
        int bw; /* bus-width */

        ti81xx_mux_init(board_mux);
        omap_serial_init();
        ti816x_evm_i2c_init();
        i2c_add_driver(&ti816xevm_cpld_driver);
        ti81xx_register_mcasp(0, &ti8168_evm_snd_data);
        ti816x_spi_init();
        /* initialize usb */
        usb_musb_init(&musb_board_data);

        /* nand initialisation */
        if (cpu_is_ti81xx()) {
            u32 *control_status = TI81XX_CTRL_REGADDR(0x40);
            if (*control_status & (1<<16))
                bw = 0;    /*8-bit nand if BTMODE BW pin on board is ON*/
            else
                bw = 2;    /*16-bit nand if BTMODE BW pin on board is OFF*/

            board_nand_init(ti816x_nand_partitions,
                ARRAY_SIZE(ti816x_nand_partitions), 0, bw);
        } else
            board_nand_init(ti816x_nand_partitions,
            ARRAY_SIZE(ti816x_nand_partitions), 0, NAND_BUSWIDTH_16);

        omap2_hsmmc_init(mmc);
        board_nor_init(ti816x_evm_norflash_partitions,
            ARRAY_SIZE(ti816x_evm_norflash_partitions), 0);
        ti816x_vpss_init();
        ti816x_gpio_vr_init();
        ti816x_hdmi_init();
    #ifdef CONFIG_SND_SOC_TI81XX_HDMI
        platform_add_devices(ti8168_devices, ARRAY_SIZE(ti8168_devices));
    #endif
        regulator_has_full_constraints();
        regulator_use_dummy_regulator();
    }

    static int __init ti8168_evm_gpio_setup(void)
    {
        /* GPIO-20 should be low for NOR access beyond 4KiB */
        gpio_request(20, "nor");
        gpio_direction_output(20, 0x0);
        return 0;
    }
    /* GPIO setup should be as subsys_initcall() as gpio driver
     * is registered in arch_initcall()
     */
    subsys_initcall(ti8168_evm_gpio_setup);

    static void __init ti8168_evm_map_io(void)
    {
        omap2_set_globals_ti816x();
        ti81xx_map_common_io();
    }

    MACHINE_START(TI8168EVM, "ti8168evm")
        /* Maintainer: Texas Instruments */
        .boot_params    = 0x80000100,
        .map_io        = ti8168_evm_map_io,
        .reserve         = ti81xx_reserve,
        .init_irq    = ti8168_evm_init_irq,
        .init_machine    = ti8168_evm_init,
        .timer        = &omap_timer,
    MACHINE_END

  • Jun,

    Please refer to the arch/arm/march-omap2/ti81xx_fb.c to understand how tvp7002 was connected to the V4L2 capture driver.

    Regards,

    yihe

  • Hi yihe

    I would highly appreciate if you can give me more hint about how TVP7002 was connected to the v4l2 capture driver.

    After reading the ti81xx_fb.c and other files included by this one, I still cannot  have a clear idea.

    Please correct if i am wrong, I thought TIxx_fb is more for video display not video capture.

    Could you please give me some details about how a video decoder connected to v4l2 driver, and how can I change the video decoder.

     

    Thanks in advance,

     

    Jun

  • Hi,

    Can you please go through V4L2 sub-device architecture.  Link for same is at http://lwn.net/Articles/313784/

    This sub-device architecture is mainly for encoder/decoder devices which can be used across different master drivers. Like same TVP7002 driver can be used with Davinci and DM816x. So sub-device drivers are independent of the master drivers. Master driver needs to instantiate sub-devices drivers based on the SoCs and board. In DM816x case we are instantiating TVP7002 sub-device driver in following way.

    static struct ti81xxvin_subdev_info hdvpss_capture_sdev_info[] = {

            {
                    .name   = TVP7002_INST0,
                    .board_info = {
                            /* TODO Find the correct address
                                    of the TVP7002 connected */
                            I2C_BOARD_INFO("tvp7002", 0x5d),
                            .platform_data = &tvp7002_pdata,

                    },
                    .vip_port_cfg = {
                            .ctrlChanSel = VPS_VIP_CTRL_CHAN_SEL_15_8,
                            .ancChSel8b = VPS_VIP_ANC_CH_SEL_DONT_CARE,
                            .pixClkEdgePol = VPS_VIP_PIX_CLK_EDGE_POL_RISING,
                            .invertFidPol = 0,
                            .embConfig = {
                                    .errCorrEnable = 1,
                                    .srcNumPos = VPS_VIP_SRC_NUM_POS_DONT_CARE,
                                    .isMaxChan3Bits = 0,
                            },
                            .disConfig = {
                                    .fidSkewPostCnt = 0,
                                    .fidSkewPreCnt = 0,
                                    .lineCaptureStyle =
                                            VPS_VIP_LINE_CAPTURE_STYLE_DONT_CARE,
                                    .fidDetectMode =
                                            VPS_VIP_FID_DETECT_MODE_DONT_CARE,
                                    .actvidPol = VPS_VIP_POLARITY_DONT_CARE,
                                    .vsyncPol =  VPS_VIP_POLARITY_DONT_CARE,
                                    .hsyncPol = VPS_VIP_POLARITY_DONT_CARE,
                            }
                    },
                    .video_capture_mode =
                            VPS_CAPT_VIDEO_CAPTURE_MODE_SINGLE_CH_NON_MUX_EMBEDDED_SYNC,
                    .video_if_mode = VPS_CAPT_VIDEO_IF_MODE_16BIT,
                    .input_data_format = FVID2_DF_YUV422P,
            },

    Bold line in above structure instantiate sub-device. while all other configuration depends on how your decoder is interfaced to master driver like, embedded syncs, discrete syncs etc. For supporting your decoder you need to create sub-device driver for your decoder and instantiate in same way.

     

    Regards,

    Hardik Shah

  • Hello.

    What about EZSDK 5.04? I cant find any files named "ti81xx_fb", only "ti81xxfb", but still i dont see any signs of tvp connection...