On Wed, Aug 14, 2013 at 06:19:10PM +0100, Damien Lespiau wrote:
> Provide the same programming model than the other infoframe types.
> 
> The generic _pack() function can't handle those yet as we need to move
> the vendor OUI in the generic hdmi_vendor_infoframe structure to know
> which kind of vendor infoframe we are dealing with.
> 
> v2: Fix the value of Side-by-side (half), hmdi typo, pack 3D_Ext_Data
>     (Ville Syrjälä)
> 
> Signed-off-by: Damien Lespiau <damien.lesp...@intel.com>
> ---
>  drivers/video/hdmi.c | 88 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/hdmi.h | 26 ++++++++++++++++
>  2 files changed, 114 insertions(+)
> 
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> index ac84215..59c4748 100644
> --- a/drivers/video/hdmi.c
> +++ b/drivers/video/hdmi.c
> @@ -286,6 +286,94 @@ ssize_t hdmi_audio_infoframe_pack(struct 
> hdmi_audio_infoframe *frame,
>  EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
>  
>  /**
> + * hdmi_hdmi_infoframe_init() - initialize an HDMI vendor infoframe
> + * @frame: HDMI vendor infoframe
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame)
> +{
> +     memset(frame, 0, sizeof(*frame));
> +
> +     frame->type = HDMI_INFOFRAME_TYPE_VENDOR;
> +     frame->version = 1;
> +
> +     /* 0 is a valid value for s3d_struct, so we use a special "not set"
> +      * value */
> +     frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
> +
> +     return 0;
> +}
> +EXPORT_SYMBOL(hdmi_hdmi_infoframe_init);
> +
> +/**
> + * hdmi_hdmi_infoframe_pack() - write a HDMI vendor infoframe to binary 
> buffer
> + * @frame: HDMI infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Packs the information contained in the @frame structure into a binary
> + * representation that can be written into the corresponding controller
> + * registers. Also computes the checksum as required by section 5.3.5 of
> + * the HDMI 1.4 specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame,
> +                              void *buffer, size_t size)
> +{
> +     u8 *ptr = buffer;
> +     size_t length;
> +
> +     /* empty info frame */
> +     if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID)
> +             return -EINVAL;
> +
> +     /* only one of those can be supplied */
> +     if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
> +             return -EINVAL;
> +
> +     /* for side by side (half) we also need to provide 3D_Ext_Data */
> +     if (frame->s3d_struct == HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)

Could be >= for a bit of future proofing since the spec says we should
send 3d_ext_data even for the reserved > 8 values.

> +             frame->length = 6;
> +     else
> +             frame->length = 5;
> +
> +     length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
> +
> +     if (size < length)
> +             return -ENOSPC;
> +
> +     memset(buffer, 0, size);
> +
> +     ptr[0] = frame->type;
> +     ptr[1] = frame->version;
> +     ptr[2] = frame->length;
> +     ptr[3] = 0; /* checksum */
> +
> +     /* HDMI OUI */
> +     ptr[4] = 0x03;
> +     ptr[5] = 0x0c;
> +     ptr[6] = 0x00;
> +
> +     if (frame->vic) {
> +             ptr[7] = 0x1 << 5;      /* video format */
> +             ptr[8] = frame->vic;
> +     } else {
> +             ptr[7] = 0x2 << 5;      /* video format */
> +             ptr[8] = (frame->s3d_struct & 0xf) << 4;
> +             if (frame->s3d_struct == HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)

Could be >= here too.

But whether or not you make those changes:
Reviewed-by: Ville Syrjälä <ville.syrj...@linux.intel.com>

> +                     ptr[9] = (frame->s3d_ext_data & 0xf) << 4;
> +     }
> +
> +     hdmi_infoframe_checksum(buffer, length);
> +
> +     return length;
> +}
> +EXPORT_SYMBOL(hdmi_hdmi_infoframe_pack);
> +
> +/**
>   * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary
>   *                                buffer
>   * @frame: HDMI vendor infoframe
> diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> index b98340b..e733252 100644
> --- a/include/linux/hdmi.h
> +++ b/include/linux/hdmi.h
> @@ -234,11 +234,37 @@ struct hdmi_vendor_infoframe {
>  ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
>                                  void *buffer, size_t size);
>  
> +enum hdmi_3d_structure {
> +     HDMI_3D_STRUCTURE_INVALID = -1,
> +     HDMI_3D_STRUCTURE_FRAME_PACKING = 0,
> +     HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE,
> +     HDMI_3D_STRUCTURE_LINE_ALTERNATIVE,
> +     HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL,
> +     HDMI_3D_STRUCTURE_L_DEPTH,
> +     HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH,
> +     HDMI_3D_STRUCTURE_TOP_AND_BOTTOM,
> +     HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8,
> +};
> +
> +struct hdmi_hdmi_infoframe {
> +     enum hdmi_infoframe_type type;
> +     unsigned char version;
> +     unsigned char length;
> +     u8 vic;
> +     enum hdmi_3d_structure s3d_struct;
> +     unsigned int s3d_ext_data;
> +};
> +
> +int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame);
> +ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame,
> +                              void *buffer, size_t size);
> +
>  union hdmi_infoframe {
>       struct hdmi_any_infoframe any;
>       struct hdmi_avi_infoframe avi;
>       struct hdmi_spd_infoframe spd;
>       struct hdmi_vendor_infoframe vendor;
> +     struct hdmi_hdmi_infoframe hdmi;
>       struct hdmi_audio_infoframe audio;
>  };
>  
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to