Re: [PATCH 07/18] video/hdmi: Handle the NTSC VBI infoframe
On Fri, Sep 21, 2018 at 10:30:16AM +0200, Hans Verkuil wrote: > On 09/20/18 20:51, Ville Syrjala wrote: > > From: Ville Syrjälä > > > > Add the code to deal with the NTSC VBI infoframe. > > > > I decided against parsing the PES_data_field and just leave > > it as an opaque blob, just dumping it out as hex in the log. > > > > Blindly typed from the spec, and totally untested. > > Do we have any driver that uses this? I would prefer to wait until someone > actually need this. No users that I know of. So totally fine with me to leave it out. > > Regards, > > Hans > > > > > Cc: Thierry Reding > > Cc: Hans Verkuil > > Cc: linux-me...@vger.kernel.org > > Signed-off-by: Ville Syrjälä > > --- > > drivers/video/hdmi.c | 208 > > +++ > > include/linux/hdmi.h | 18 + > > 2 files changed, 226 insertions(+) > > > > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c > > index 3d24c7746c51..3c320d69fa0a 100644 > > --- a/drivers/video/hdmi.c > > +++ b/drivers/video/hdmi.c > > @@ -831,6 +831,139 @@ ssize_t hdmi_mpeg_source_infoframe_pack(struct > > hdmi_mpeg_source_infoframe *frame > > } > > EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack); > > > > +/** > > + * hdmi_ntsc_vbi_infoframe_init() - initialize an HDMI NTSC VBI infoframe > > + * @frame: HDMI NTSC VBI infoframe > > + * @pes_data_field: ANSI/SCTE 127 PES_data_field > > + * @length: ANSI/SCTE 127 PES_data_field length > > + * > > + * Returns 0 on success or a negative error code on failure. > > + */ > > +int hdmi_ntsc_vbi_infoframe_init(struct hdmi_ntsc_vbi_infoframe *frame, > > +const void *pes_data_field, > > +size_t length) > > +{ > > + if (length < 1 || length > 27) > > + return -EINVAL; > > + > > + memset(frame, 0, sizeof(*frame)); > > + > > + frame->type = HDMI_INFOFRAME_TYPE_NTSC_VBI; > > + frame->version = 1; > > + frame->length = length; > > + > > + memcpy(frame->pes_data_field, pes_data_field, length); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_init); > > + > > +static int hdmi_ntsc_vbi_infoframe_check_only(const struct > > hdmi_ntsc_vbi_infoframe *frame) > > +{ > > + if (frame->type != HDMI_INFOFRAME_TYPE_NTSC_VBI || > > + frame->version != 1 || > > + frame->length < 1 || frame->length > 27) > > + return -EINVAL; > > + > > + if (frame->pes_data_field[0] != 0x99) > > + return -EINVAL; > > + > > + return 0; > > +} > > + > > +/** > > + * hdmi_ntsc_vbi_infoframe_check() - Check and check a HDMI NTSC VBI > > infoframe > > + * @frame: HDMI NTSC VBI infoframe > > + * > > + * Validates that the infoframe is consistent and updates derived fields > > + * (eg. length) based on other fields. > > + * > > + * Returns 0 on success or a negative error code on failure. > > + */ > > +int hdmi_ntsc_vbi_infoframe_check(struct hdmi_ntsc_vbi_infoframe *frame) > > +{ > > + return hdmi_ntsc_vbi_infoframe_check_only(frame); > > +} > > +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_check); > > + > > +/** > > + * hdmi_ntsc_vbi_infoframe_pack_only() - write HDMI NTSC VBI infoframe to > > binary buffer > > + * @frame: HDMI NTSC VBI 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_ntsc_vbi_infoframe_pack_only(const struct > > hdmi_ntsc_vbi_infoframe *frame, > > + void *buffer, size_t size) > > +{ > > + u8 *ptr = buffer; > > + size_t length; > > + int ret; > > + > > + ret = hdmi_ntsc_vbi_infoframe_check_only(frame); > > + if (ret) > > + return ret; > > + > > + 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 */ > > + > > + /* start infoframe payload */ > > + ptr += HDMI_INFOFRAME_HEADER_SIZE; > > + > > + memcpy(ptr, frame->pes_data_field, frame->length); > > + > > + hdmi_infoframe_set_checksum(buffer, length); > > + > > + return length; > > +} > > +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_pack_only); > > + > > +/** > > + * hdmi_ntsc_vbi_infoframe_pack() - Check and check a HDMI NTSC VBI > > infoframe, > > + * and write it to binary buffer > > + * @frame: HDMI NTSC VBI infoframe > > + * @buffer: destination buffer > > + * @size: size of buffer > > + * > > + * Validates that the
Re: [PATCH 07/18] video/hdmi: Handle the NTSC VBI infoframe
On 09/20/18 20:51, Ville Syrjala wrote: > From: Ville Syrjälä > > Add the code to deal with the NTSC VBI infoframe. > > I decided against parsing the PES_data_field and just leave > it as an opaque blob, just dumping it out as hex in the log. > > Blindly typed from the spec, and totally untested. Do we have any driver that uses this? I would prefer to wait until someone actually need this. Regards, Hans > > Cc: Thierry Reding > Cc: Hans Verkuil > Cc: linux-me...@vger.kernel.org > Signed-off-by: Ville Syrjälä > --- > drivers/video/hdmi.c | 208 > +++ > include/linux/hdmi.h | 18 + > 2 files changed, 226 insertions(+) > > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c > index 3d24c7746c51..3c320d69fa0a 100644 > --- a/drivers/video/hdmi.c > +++ b/drivers/video/hdmi.c > @@ -831,6 +831,139 @@ ssize_t hdmi_mpeg_source_infoframe_pack(struct > hdmi_mpeg_source_infoframe *frame > } > EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack); > > +/** > + * hdmi_ntsc_vbi_infoframe_init() - initialize an HDMI NTSC VBI infoframe > + * @frame: HDMI NTSC VBI infoframe > + * @pes_data_field: ANSI/SCTE 127 PES_data_field > + * @length: ANSI/SCTE 127 PES_data_field length > + * > + * Returns 0 on success or a negative error code on failure. > + */ > +int hdmi_ntsc_vbi_infoframe_init(struct hdmi_ntsc_vbi_infoframe *frame, > + const void *pes_data_field, > + size_t length) > +{ > + if (length < 1 || length > 27) > + return -EINVAL; > + > + memset(frame, 0, sizeof(*frame)); > + > + frame->type = HDMI_INFOFRAME_TYPE_NTSC_VBI; > + frame->version = 1; > + frame->length = length; > + > + memcpy(frame->pes_data_field, pes_data_field, length); > + > + return 0; > +} > +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_init); > + > +static int hdmi_ntsc_vbi_infoframe_check_only(const struct > hdmi_ntsc_vbi_infoframe *frame) > +{ > + if (frame->type != HDMI_INFOFRAME_TYPE_NTSC_VBI || > + frame->version != 1 || > + frame->length < 1 || frame->length > 27) > + return -EINVAL; > + > + if (frame->pes_data_field[0] != 0x99) > + return -EINVAL; > + > + return 0; > +} > + > +/** > + * hdmi_ntsc_vbi_infoframe_check() - Check and check a HDMI NTSC VBI > infoframe > + * @frame: HDMI NTSC VBI infoframe > + * > + * Validates that the infoframe is consistent and updates derived fields > + * (eg. length) based on other fields. > + * > + * Returns 0 on success or a negative error code on failure. > + */ > +int hdmi_ntsc_vbi_infoframe_check(struct hdmi_ntsc_vbi_infoframe *frame) > +{ > + return hdmi_ntsc_vbi_infoframe_check_only(frame); > +} > +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_check); > + > +/** > + * hdmi_ntsc_vbi_infoframe_pack_only() - write HDMI NTSC VBI infoframe to > binary buffer > + * @frame: HDMI NTSC VBI 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_ntsc_vbi_infoframe_pack_only(const struct > hdmi_ntsc_vbi_infoframe *frame, > + void *buffer, size_t size) > +{ > + u8 *ptr = buffer; > + size_t length; > + int ret; > + > + ret = hdmi_ntsc_vbi_infoframe_check_only(frame); > + if (ret) > + return ret; > + > + 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 */ > + > + /* start infoframe payload */ > + ptr += HDMI_INFOFRAME_HEADER_SIZE; > + > + memcpy(ptr, frame->pes_data_field, frame->length); > + > + hdmi_infoframe_set_checksum(buffer, length); > + > + return length; > +} > +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_pack_only); > + > +/** > + * hdmi_ntsc_vbi_infoframe_pack() - Check and check a HDMI NTSC VBI > infoframe, > + * and write it to binary buffer > + * @frame: HDMI NTSC VBI infoframe > + * @buffer: destination buffer > + * @size: size of buffer > + * > + * Validates that the infoframe is consistent and updates derived fields > + * (eg. length) based on other fields, after which 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.
[PATCH 07/18] video/hdmi: Handle the NTSC VBI infoframe
From: Ville Syrjälä Add the code to deal with the NTSC VBI infoframe. I decided against parsing the PES_data_field and just leave it as an opaque blob, just dumping it out as hex in the log. Blindly typed from the spec, and totally untested. Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-me...@vger.kernel.org Signed-off-by: Ville Syrjälä --- drivers/video/hdmi.c | 208 +++ include/linux/hdmi.h | 18 + 2 files changed, 226 insertions(+) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 3d24c7746c51..3c320d69fa0a 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -831,6 +831,139 @@ ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame } EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack); +/** + * hdmi_ntsc_vbi_infoframe_init() - initialize an HDMI NTSC VBI infoframe + * @frame: HDMI NTSC VBI infoframe + * @pes_data_field: ANSI/SCTE 127 PES_data_field + * @length: ANSI/SCTE 127 PES_data_field length + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_ntsc_vbi_infoframe_init(struct hdmi_ntsc_vbi_infoframe *frame, +const void *pes_data_field, +size_t length) +{ + if (length < 1 || length > 27) + return -EINVAL; + + memset(frame, 0, sizeof(*frame)); + + frame->type = HDMI_INFOFRAME_TYPE_NTSC_VBI; + frame->version = 1; + frame->length = length; + + memcpy(frame->pes_data_field, pes_data_field, length); + + return 0; +} +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_init); + +static int hdmi_ntsc_vbi_infoframe_check_only(const struct hdmi_ntsc_vbi_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_NTSC_VBI || + frame->version != 1 || + frame->length < 1 || frame->length > 27) + return -EINVAL; + + if (frame->pes_data_field[0] != 0x99) + return -EINVAL; + + return 0; +} + +/** + * hdmi_ntsc_vbi_infoframe_check() - Check and check a HDMI NTSC VBI infoframe + * @frame: HDMI NTSC VBI infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_ntsc_vbi_infoframe_check(struct hdmi_ntsc_vbi_infoframe *frame) +{ + return hdmi_ntsc_vbi_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_check); + +/** + * hdmi_ntsc_vbi_infoframe_pack_only() - write HDMI NTSC VBI infoframe to binary buffer + * @frame: HDMI NTSC VBI 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_ntsc_vbi_infoframe_pack_only(const struct hdmi_ntsc_vbi_infoframe *frame, + void *buffer, size_t size) +{ + u8 *ptr = buffer; + size_t length; + int ret; + + ret = hdmi_ntsc_vbi_infoframe_check_only(frame); + if (ret) + return ret; + + 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 */ + + /* start infoframe payload */ + ptr += HDMI_INFOFRAME_HEADER_SIZE; + + memcpy(ptr, frame->pes_data_field, frame->length); + + hdmi_infoframe_set_checksum(buffer, length); + + return length; +} +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_pack_only); + +/** + * hdmi_ntsc_vbi_infoframe_pack() - Check and check a HDMI NTSC VBI infoframe, + * and write it to binary buffer + * @frame: HDMI NTSC VBI infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which 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_ntsc_vbi_infoframe_pack(struct hdmi_ntsc_vbi_infoframe *frame, +void *buffer, size_t size) +{ + int ret; + + ret = hdmi_ntsc_vbi_infoframe_check(frame); + if (ret) + return ret; + +