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.lespiau@xxxxxxxxx> > --- > 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.syrjala@xxxxxxxxxxxxxxx> > + 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-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx