Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

TI811X PSP Adding External Decoders to V4L2 Capture Driver

From Texas Instruments Wiki
Jump to: navigation, search
TIBanner.png
TI811X PSP Adding External Decoders to V4L2 Capture Driver
Linux PSP

Introduction

Linux HDVPSS software stack contains drivers for controlling the video display, video capture graphics paths of the HDVPSS.Video display and capture paths are exposed using the V4L2 user interface of Linux. Graphics path of the HDVPSS is controlled using the frame buffer (fbdev) interface of Linux. HDVPSS hardware supports number of different analog and digital video encoders and decoders. All of these encoders can be used to drive the external encoders which can convert output of HDVPSS encoder to any of the standard video protocols like HDMI, DVI, and VGA etc. All of the decoders can be used to convert the incoming videos in different protocols like HDMI, DVI VGA etc to the standard BT656, BT1120, BT601 interface which HDVPSS understands.

All the external decoders are supported with V4L2 capture driver using standard V4L2 sub-device model. Decoders that are required to be interfaced to the V4L2 capture driver needs to adhere V4L2 sub-device architecture. More about V4L2 sub-device architecture is available at $Kernel_source/Documentation/video4linux/v4l2-framework.txt

V4L2 master driver requires information on how the decoder driver is interfaced to V4L2 master driver that is HDVPSS capture in addition to the sub-device ioctls. This information is passed to V4L2 capture driver through platform data. Following part of the document explains how to add/delete external decoders.

Design

All the external decoders are controlled through standard V4L2 driver model architecture. All the decoders need to be implemented as V4L2 sub-device architecture. All the standard APIs that need to be supported by decoder based on decoder features are listed in V4L2 API specification. Link to V4L2 API specification is given in references section of this documentation.

Steps for Adding new Decoders

  • All the files related to new external decoders should be added in following kernel directory
$kernel_source/drivers/media/video/<external_decoder_directory_file>
  • MakeFiles and Kconfig files needs to be modified accordingly. Please refer to following kernel documentation on makefiles and Kconfig under following kernel directory.
$kernel_source/Documentation/kbuild/
  • TVP7002 decoder is added as the sub-device model in Linux Driver stack. Please refer following files for TVP7002 decoder implementation.
$kernel_source/drivers/media/video/tvp7002.c
$kernel_source/drivers/media/video/tvp7002_reg.h
$kernel_source/drivers/media/video/tvp7002_reg.h
$kernel_source/media/video/Makefile
$kernel_source/drivers/media/video/Kconfig
  • TVP7002 specifications could be found at tvp7002
  • Data about the external decoders like what inputs they support, how they are interfaced to VPSS VIP port, what is the I2C address etc, needs to be passed to V4L2 capture driver. This data is board dependent and needs to be filled based on decoder and how decoder is connected to VIP port.
  • ti81xxvin_config data structure needs to be field and passed it as platform data to the HDVPSS V4L2 capture driver. It includes many sub-structures and enums all those will be explained in sub-sequent sections in code.

Structures

All the structures that needs to be instantiate and filled in according to the external decoder and connectivity between decoder and VIP are explained below.

/* Structure to configure V4L2 capture driver based on external decoders preset on board. */
struct ti81xxvin_config {
 
        /* Configuration for each instance of VIP */
        struct ti81xxvin_inst_config inst_config[TI81XXVIN_NUM_INSTANCES];
 
        /* Information for all sub-devices (external decoders) connected to VIP port */
        struct ti81xxvin_subdev_info *subdev_info;
 
        /* Number of sub-devices (external decoders) present on board */
        int subdev_count;
 
        /* Daughter Card name */
        const char *card_name;
};
  • Below structure is for configuring instance of the HDVPSS capture driver based on decoders connected and what they support. This structure is used by master driver to select particular decoder based on the input selected. Like if two decoders are connected to same VIP port, than based on input selected, master driver will configured any one of the decoder. Even same decoder can support mutiple inputs like TVP5147 supports composite as well as s-video inputs.
/* V4L2 master driver instance configuration based on decoder connected to specific master driver*/
struct ti81xxvin_inst_config {
 
        /* Different inputs possible on this instance like DVI, HDMI,
         * Component etc. This is addition of all the different inputs
         * supported bu all the decoders connected to this V4L2 master driver instance.
         */
        const struct ti81xxvin_input *inputs;
 
        /* Number of inputs possible on this V4L2 master driver instance.*/
        int input_count;
};
  • Structure for each of the inputs possible on an instance.
struct ti81xxvin_input {
 
        /* V4L2 input structure to be filled for each supported inputs
         * This is a standard V4L2 structure. Please refer to V4L2 specifications
         * for details.
         */
        struct v4l2_input input;
 
        /* Sub-device name  */
        const char *subdev_name;
 
        /* Different DV presets this input supports
         * This is a standard V4L2 structure. Please refer to V4L2 specifications
         * for details.
         */
        const struct v4l2_dv_preset *dv_presets;
 
        /* Number of presets supported by this input */
        int num_dv_presets;
};
  • Structure for sub-device information. This structure gives information on various sub-devices present on boards.
struct ti81xxvin_subdev_info {
 
        /* Name of the sub-device This name can be anything based on subdevice*/
        const char *name;
 
       /* Sub-device board info like how sub-device is connected on board.
        * What is its i2c address, sub-device name etc. This should match
        * sub-device  name given in the sub-device driver under driver/media/video folder.
        * Based on name only sub-device will be searched.
        */
        struct i2c_board_info board_info;
 
        /* HDVPSS video input port configuration based on how sub-device is interfaced to
         * the HDVPSS VIP Port
         */
        struct Vps_VipPortConfig vip_port_cfg;
 
        /* VIP config. This is used to clip the blanking/active data based on sub-device interfaced */
        struct Vps_VipConfig vip_cfg;
 
        /* How is video captured, like Embedded Sync, discrete sync,
         * single channel etc For details see #Vps_CaptVideoCaptureMode
         */
        u32 video_capture_mode;
 
        /* How is decoder interfaced, 8bit, 16bit, 24 bit etc.
         * For details see #Vps_CaptVideoIfMode
         */
        u32 video_if_mode;
 
        /* Input source color data format, valid values are given below \n
         *   FVID2_DF_YUV422P, ( 'P' is not relavent for input data format) \n
         *   FVID2_DF_YUV444P, ( 'P' is not relavent for input data format) \n
         *   FVID2_DF_RGB24_888.
         */
        u32 input_data_format;
 
        /* This function is used to select this decoder. Number of
         * decoders are muxed on board to same VIP port. This
         * function connects, this decoder to VIP using this function pointer
         * This is an optional field since this is required if multiple decoders are connected
         * to same VIP port and if they are required to be selected.
         */
        int (*ti81xxvin_select_decoder) (int decoder_id);
 
        /* There are filters on board which needs to be configured
         * based on dv_preset. This function allows to configure
         * those filter if they are present. This is an optional field.
         */
        int (*ti81xxvin_set_mode) (enum fvid2_standard standard);
 
        /* ID of the decoder to be passed to select this decoder
         * This is required only if ''ti81xxvin_select_decoder'' is defined.
         */
        int decoder_id;
  • Structure to configure VIP port based on how decoder is interfaced to VIP.
struct Vps_VipPortConfig {
 
        /*  It describes channels numbers from extract control code and Vertical
         *  Ancillary Data. This is normally used in embedded sync where sync signals
         *  are embedded in data.  For valid values see #Vps_VipCtrlChanSel
         */
        u32 ctrlChanSel;
 
        /* It gives the information in 8b interface mode from where to extract
         * Vertical Ancillary data. For valid values see #Vps_VipAncChSel8b
         */
        u32 ancChSel8b;
 
        /* At what polarity of pixel clock should VIP sample data.
         * For valid values see #Vps_VipPixClkEdgePol
         */
        u32 pixClkEdgePol;
 
        /* FALSE: Keep FID as found, TRUE: Invert Value of FID */
        u32 invertFidPol;
 
        /* Configuration parameter specific to Embedded Sync mode */
        struct Vps_VipEmbConfig       embConfig;
 
        /* Configuration parameter specific to Discrete Sync mode */
        struct Vps_VipDiscreteConfig  disConfig;
 
};
  • Structure to configure VIP for clipping of blanking and/or active data.
struct Vps_VipConfig {
 
        /* FALSE: Do not clip active Data TRUE : Clip active Data */
        u32 clipActive;
 
        /* FALSE: Do not clip blanking Data TRUE : Clip blanking Data */
        u32 clipBlank;
 
};
  • Structure to configure VIP in embedded sync mode.
struct Vps_VipEmbConfig {
 
        /* TRUE: Error Correction enable, FALSE: disabled
         * It should be TRUE for most of the decoders
         */
        u32 errCorrEnable;
 
        /* This needs to be set to VPS_VIP_SRC_NUM_POS_DONT_CARE */
        u32 srcNumPos;
 
        /* This needs to be set to ''0''
        u32 isMaxChan3Bits;
 
};
  • Structure to configure VIP in discrete sync mode.
struct Vps_VipDiscreteConfig {
 
        /* Post count value when using vsync skew in FID determination */
        u32 fidSkewPostCnt;
 
        /* Pre count value when using vsync skew in FID determination */
        u32 fidSkewPreCnt;
 
        /* For valid values see #Vps_VipLineCaptureStyle */
        u32 lineCaptureStyle;
 
        /* How to detect fid, For valid values see #Vps_VipFidDetectMode */
        u32 fidDetectMode;
 
        /* Polarity of the Active Video signal, For valid values see #Vps_VipPolarity */
        u32 actvidPol;
 
        /* Polarity of Vsync signal, For valid values see #Vps_VipPolarity */
        u32 vsyncPol;
 
        /* Polarity of hsync signal, For valid values see #Vps_VipPolarity */
        u32 hsyncPol;
 
};

Enums

All the enums used in above structure are explained below.

  • Enum to configure capture mode
/**
 * \brief Video capture operation mode
*/
enum Vps_CaptVideoCaptureMode {
 
        /* Single Channel non multiplexed mode */
        VPS_CAPT_VIDEO_CAPTURE_MODE_SINGLE_CH_NON_MUX_EMBEDDED_SYNC = 0,
 
        /* Multi-channel line-multiplexed mode. This is not supported by V4L2 capture driver */
        VPS_CAPT_VIDEO_CAPTURE_MODE_MULTI_CH_LINE_MUX_EMBEDDED_SYNC,
 
        /* Multi-channel pixel muxed. This is not supported by V4L2 capture driver */
        VPS_CAPT_VIDEO_CAPTURE_MODE_MULTI_CH_PIXEL_MUX_EMBEDDED_SYNC,
 
        /* Single Channel non multiplexed discrete sync mode with HSYNC and VBLK as control signals. */
        VPS_CAPT_VIDEO_CAPTURE_MODE_SINGLE_CH_NON_MUX_DISCRETE_SYNC_HSYNC_VBLK,
 
        /* Single Channel non multiplexed discrete sync mode with HSYNC and VSYNC as control signals. */
        VPS_CAPT_VIDEO_CAPTURE_MODE_SINGLE_CH_NON_MUX_DISCRETE_SYNC_HSYNC_VSYNC,
 
        /* Single Channel non multiplexed discrete sync mode with ACTVID and VBLK as control signals. */
        VPS_CAPT_VIDEO_CAPTURE_MODE_SINGLE_CH_NON_MUX_DISCRETE_SYNC_ACTVID_VBLK,
 
        /* Single Channel non multiplexed discrete sync mode with ACTVID and VBLK as control signals. */
        VPS_CAPT_VIDEO_CAPTURE_MODE_SINGLE_CH_NON_MUX_DISCRETE_SYNC_ACTVID_VSYNC,
 
        /* Multi-channel line-multiplexed mode - split line mode This is not supported by V4L2 capture driver*/
        VPS_CAPT_VIDEO_CAPTURE_MODE_MULTI_CH_LINE_MUX_SPLIT_LINE_EMBEDDED_SYNC,
 
        /* Maximum modes */
        VPS_CAPT_VIDEO_CAPTURE_MODE_MAX
 
};
  • Enum to configure how decoder is interfaced to VIP
/**
 * \brief Video interface mode
*/
enum Vps_CaptVideoIfMode {
 
        /*8bit interface Mostly used for YUV422 SD capture*/
        VPS_CAPT_VIDEO_IF_MODE_8BIT = 0,
 
        /*16bit interface  Mostly used for YUV422 HD capture */
        VPS_CAPT_VIDEO_IF_MODE_16BIT,
 
        /*24bit interface mostly used for RGB */
        VPS_CAPT_VIDEO_IF_MODE_24BIT,
 
        /* Maximum modes */
        VPS_CAPT_VIDEO_IF_MODE_MAX
 
};
  • Enum for control channel selection
/**
 *  \brief Enum for Control Channel Selection
 *  It describes channels numbers from extract control code and Vertical
 *  Ancillary Data
 */
enum Vps_VipCtrlChanSel {
 
        /* Use data[7:0] to extract control codes and Vertical Ancillary Data */
        VPS_VIP_CTRL_CHAN_SEL_7_0 = 0,
 
        /* Use data[15:8] to extract control codes and Vertical Ancillary Data */
        VPS_VIP_CTRL_CHAN_SEL_15_8,
 
        /* Use data[23:16] to extract control codes and Vertical Ancillary Data */
        VPS_VIP_CTRL_CHAN_SEL_23_16,
 
        /* Value is dont care */
        VPS_VIP_CTRL_CHAN_DONT_CARE = -1
 
};
  • Enum for extracting vertical ancillary data in 8 bit interface mode
/**
 *  \brief It gives the imformation in 8b interface mode from where to extract
 *  Vertical Ancillary data
 */
enum Vps_VipAncChSel8b {
 
        /* Extract 8b Mode Vertical Ancillary Data from Luma Sites */
        VPS_VIP_ANC_CH_SEL_8B_LUMA_SIDE = 0,
 
        /* Extract 8b Mode Vertical Ancillary Data from Chroma Sites */
        VPS_VIP_ANC_CH_SEL_8B_CHROMA_SIDE,
 
        /* Value is dont care */
        VPS_VIP_ANC_CH_SEL_DONT_CARE = -1
 
};
  • Polarity of pixel clock on which VIP will do sampling.
/**
 *  \brief Pixel clock edge polarity
 */
enum Vps_VipPixClkEdgePol {
 
        /* Rising Edge is active PIXCLK edge */
        VPS_VIP_PIX_CLK_EDGE_POL_RISING = 0,
 
        /* Falling Edge is active PIXCLK edge */
        VPS_VIP_PIX_CLK_EDGE_POL_FALLING,
 
        /* Value is dont care */
        VPS_VIP_PIX_CLK_EDGE_POL_DONT_CARE = -1
 
};
  • Vip line capture style enum
/**
 *  \brief It is used only for Discrete Sync
 */
enum Vps_VipLineCaptureStyle {
        /* Use HSYNC style linecapture */
        VPS_VIP_LINE_CAPTURE_STYLE_HSYNC = 0,
 
        /* Use ACTVID style line capture */
        VPS_VIP_LINE_CAPTURE_STYLE_ACTVID,
 
        /* Value is dont care */
        VPS_VIP_LINE_CAPTURE_STYLE_DONT_CARE = -1
 
 
};
  • Enum on how to detect FID
/**
 *  \brief It is only used for Discrete Sync
 */
enum Vps_VipFidDetectMode {
 
        /* Take FID from pin */
        VPS_VIP_FID_DETECT_MODE_PIN = 0,
 
        /* FID is determined by VSYNC skew */
        VPS_VIP_FID_DETECT_MODE_VSYNC,
 
        /* Value is dont care */
        VPS_VIP_FID_DETECT_MODE_DONT_CARE = -1
 
 
};
  • Enum for various control signals polarity
/**
 *  \brief VIP Polarity
 */
enum Vps_VipPolarity {
 
         /* low Polarity */
        VPS_VIP_POLARITY_LOW = 0,
 
        /* high Polarity */
        VPS_VIP_POLARITY_HIGH,
 
        /* Value is dont care */
        VPS_VIP_POLARITY_DONT_CARE = -1
 
 
};

Example

Please refer to $kernel_source/arch/arm/mach-omap2/ti81xx_fb.c to see how above data structures are populated for TVP7002 decoder. Schematics of the board can be found at schematics to see how TVP7002 is interfaced to VIP port.

Technical Support and Product Updates =

For further information or to report any problems, contact http://community.ti.com or http://support.ti.com.

OMAP Linux Mailing List: http://vger.kernel.org/vger-lists.html#linux-omap