diff mbox

[v5,4/9] video: Add generic HDMI infoframe helpers

Message ID 1361516611-2517-5-git-send-email-thierry.reding@avionic-design.de (mailing list archive)
State New, archived
Headers show

Commit Message

Thierry Reding Feb. 22, 2013, 7:03 a.m. UTC
Add generic helpers to pack HDMI infoframes into binary buffers.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
Changes in v2:
- add support for audio, vendor-specific and SPD infoframes
- add various validity checks on infoframes
- factor out checksum computation

Changes in v3:
- introduce HDMI_INFOFRAME_HEADER_SIZE
- fix SPD infoframe SDI field offset

Changes in v4:
- remove needless checks for input parameters
- use memcpy() instead of manual copy loop
- update SPD SPI enum to include HD-DVD and PMP as per CEA-861-E
- add audio coding type extension support
- match audio coding type names to those in CEA-861-E

 drivers/video/Kconfig  |   3 +
 drivers/video/Makefile |   1 +
 drivers/video/hdmi.c   | 308 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/hdmi.h   | 231 +++++++++++++++++++++++++++++++++++++
 4 files changed, 543 insertions(+)
 create mode 100644 drivers/video/hdmi.c
 create mode 100644 include/linux/hdmi.h

Comments

Ville Syrjälä Feb. 22, 2013, 4:01 p.m. UTC | #1
On Fri, Feb 22, 2013 at 08:03:26AM +0100, Thierry Reding wrote:
<snip>
> +enum hdmi_audio_coding_type {
> +	HDMI_AUDIO_CODING_TYPE_STREAM,
> +	HDMI_AUDIO_CODING_TYPE_PCM,
> +	HDMI_AUDIO_CODING_TYPE_AC3,
> +	HDMI_AUDIO_CODING_TYPE_MPEG1,
> +	HDMI_AUDIO_CODING_TYPE_MP3,
> +	HDMI_AUDIO_CODING_TYPE_MPEG2,
> +	HDMI_AUDIO_CODING_TYPE_AAC_LC,
> +	HDMI_AUDIO_CODING_TYPE_DTS,
> +	HDMI_AUDIO_CODING_TYPE_ATRAC,
> +	HDMI_AUDIO_CODING_TYPE_DSD,
> +	HDMI_AUDIO_CODING_TYPE_EAC3,
> +	HDMI_AUDIO_CODING_TYPE_DTS_HD,
> +	HDMI_AUDIO_CODING_TYPE_MLP,
> +	HDMI_AUDIO_CODING_TYPE_DST,
> +	HDMI_AUDIO_CODING_TYPE_WMA_PRO,

+ HDMI_AUDIO_CODING_TYPE_EXT or something like it?

> +};
> +
> +enum hdmi_audio_sample_size {
> +	HDMI_AUDIO_SAMPLE_SIZE_STREAM,
> +	HDMI_AUDIO_SAMPLE_SIZE_16,
> +	HDMI_AUDIO_SAMPLE_SIZE_20,
> +	HDMI_AUDIO_SAMPLE_SIZE_24,
> +};
> +
> +enum hdmi_audio_sample_frequency {
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_32000,
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_44100,
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_48000,
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_88200,
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_96000,
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_176400,
> +	HDMI_AUDIO_SAMPLE_FREQUENCY_192000,
> +};
> +
> +enum hdmi_audio_coding_type_ext {
> +	HDMI_AUDIO_CODING_TYPE_EXT_STREAM,

The spec is a bit confusing w.r.t. this value, but I think this is
correct. Any other value is illegal when CT!=15, and when CT==15,
CXT=0 means that look at CT (infinite loop anyone?), or stream header.
Since the infinite loop option doesn't make sense, looking at the
stream header is the only option. Although I think it would be
generally safer to avoid that specific combination. I'm sure some
"clever" guy would actually implement the infinite loop instead.

> +	HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC,
> +	HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2,
> +	HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND,
> +};
> +
Ville Syrjälä March 4, 2013, 2:49 p.m. UTC | #2
On Fri, Feb 22, 2013 at 08:03:26AM +0100, Thierry Reding wrote:
> Add generic helpers to pack HDMI infoframes into binary buffers.
> 
> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> ---
> Changes in v2:
> - add support for audio, vendor-specific and SPD infoframes
> - add various validity checks on infoframes
> - factor out checksum computation
> 
> Changes in v3:
> - introduce HDMI_INFOFRAME_HEADER_SIZE
> - fix SPD infoframe SDI field offset
> 
> Changes in v4:
> - remove needless checks for input parameters
> - use memcpy() instead of manual copy loop
> - update SPD SPI enum to include HD-DVD and PMP as per CEA-861-E
> - add audio coding type extension support
> - match audio coding type names to those in CEA-861-E
> 
>  drivers/video/Kconfig  |   3 +
>  drivers/video/Makefile |   1 +
>  drivers/video/hdmi.c   | 308 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/hdmi.h   | 231 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 543 insertions(+)
>  create mode 100644 drivers/video/hdmi.c
>  create mode 100644 include/linux/hdmi.h
> 
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 09f1a18..b11eeab 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -52,6 +52,9 @@ config OF_VIDEOMODE
>  	help
>  	  helper to get videomodes from the devicetree
>  
> +config HDMI
> +	bool
> +
>  menuconfig FB
>  	tristate "Support for frame buffer devices"
>  	---help---
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index f592f3b..0b50082 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -5,6 +5,7 @@
>  # Each configuration option enables a list of files.
>  
>  obj-$(CONFIG_VGASTATE)            += vgastate.o
> +obj-$(CONFIG_HDMI)                += hdmi.o
>  obj-y                             += fb_notify.o
>  obj-$(CONFIG_FB)                  += fb.o
>  fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> new file mode 100644
> index 0000000..ab23c9b
> --- /dev/null
> +++ b/drivers/video/hdmi.c
> @@ -0,0 +1,308 @@
> +/*
> + * Copyright (C) 2012 Avionic Design GmbH
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */

BTW was there any discussion about the license? drm is generally MIT.
Are people OK with depending on GPL code for infoframe support?
Thierry Reding March 4, 2013, 3:02 p.m. UTC | #3
On Mon, Mar 04, 2013 at 04:49:46PM +0200, Ville Syrjälä wrote:
> On Fri, Feb 22, 2013 at 08:03:26AM +0100, Thierry Reding wrote:
[...]
> > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > new file mode 100644
> > index 0000000..ab23c9b
> > --- /dev/null
> > +++ b/drivers/video/hdmi.c
> > @@ -0,0 +1,308 @@
> > +/*
> > + * Copyright (C) 2012 Avionic Design GmbH
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> 
> BTW was there any discussion about the license? drm is generally MIT.
> Are people OK with depending on GPL code for infoframe support?

I wasn't aware of that. I don't know how much of an issue it is really
since all symbols are exported non-GPL.

Thierry
Lucas Stach March 7, 2013, 1:32 p.m. UTC | #4
Am Montag, den 04.03.2013, 16:02 +0100 schrieb Thierry Reding:
> On Mon, Mar 04, 2013 at 04:49:46PM +0200, Ville Syrjälä wrote:
> > On Fri, Feb 22, 2013 at 08:03:26AM +0100, Thierry Reding wrote:
> [...]
> > > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > > new file mode 100644
> > > index 0000000..ab23c9b
> > > --- /dev/null
> > > +++ b/drivers/video/hdmi.c
> > > @@ -0,0 +1,308 @@
> > > +/*
> > > + * Copyright (C) 2012 Avionic Design GmbH
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License version 2 as
> > > + * published by the Free Software Foundation.
> > > + */
> > 
> > BTW was there any discussion about the license? drm is generally MIT.
> > Are people OK with depending on GPL code for infoframe support?
> 
> I wasn't aware of that. I don't know how much of an issue it is really
> since all symbols are exported non-GPL.
> 
> Thierry

It's not about the export of the symbols, but more about porting DRM to
other UNIXes like BSD. Using the GPL here makes life for the BSD guys a
lot harder and they are already struggling really hard to keep up with
the pace of Linux. So if you don't care too much it would be nice to use
MIT here.

Regards,
Lucas
Thierry Reding March 7, 2013, 1:44 p.m. UTC | #5
On Thu, Mar 07, 2013 at 02:32:51PM +0100, Lucas Stach wrote:
> Am Montag, den 04.03.2013, 16:02 +0100 schrieb Thierry Reding:
> > On Mon, Mar 04, 2013 at 04:49:46PM +0200, Ville Syrjälä wrote:
> > > On Fri, Feb 22, 2013 at 08:03:26AM +0100, Thierry Reding wrote:
> > [...]
> > > > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > > > new file mode 100644
> > > > index 0000000..ab23c9b
> > > > --- /dev/null
> > > > +++ b/drivers/video/hdmi.c
> > > > @@ -0,0 +1,308 @@
> > > > +/*
> > > > + * Copyright (C) 2012 Avionic Design GmbH
> > > > + *
> > > > + * This program is free software; you can redistribute it and/or modify
> > > > + * it under the terms of the GNU General Public License version 2 as
> > > > + * published by the Free Software Foundation.
> > > > + */
> > > 
> > > BTW was there any discussion about the license? drm is generally MIT.
> > > Are people OK with depending on GPL code for infoframe support?
> > 
> > I wasn't aware of that. I don't know how much of an issue it is really
> > since all symbols are exported non-GPL.
> > 
> > Thierry
> 
> It's not about the export of the symbols, but more about porting DRM to
> other UNIXes like BSD. Using the GPL here makes life for the BSD guys a
> lot harder and they are already struggling really hard to keep up with
> the pace of Linux. So if you don't care too much it would be nice to use
> MIT here.

Sure, I'll relicense it under MIT then.

Thierry
Ville Syrjälä April 8, 2013, 11:52 a.m. UTC | #6
On Thu, Mar 07, 2013 at 02:44:12PM +0100, Thierry Reding wrote:
> On Thu, Mar 07, 2013 at 02:32:51PM +0100, Lucas Stach wrote:
> > Am Montag, den 04.03.2013, 16:02 +0100 schrieb Thierry Reding:
> > > On Mon, Mar 04, 2013 at 04:49:46PM +0200, Ville Syrjälä wrote:
> > > > On Fri, Feb 22, 2013 at 08:03:26AM +0100, Thierry Reding wrote:
> > > [...]
> > > > > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > > > > new file mode 100644
> > > > > index 0000000..ab23c9b
> > > > > --- /dev/null
> > > > > +++ b/drivers/video/hdmi.c
> > > > > @@ -0,0 +1,308 @@
> > > > > +/*
> > > > > + * Copyright (C) 2012 Avionic Design GmbH
> > > > > + *
> > > > > + * This program is free software; you can redistribute it and/or modify
> > > > > + * it under the terms of the GNU General Public License version 2 as
> > > > > + * published by the Free Software Foundation.
> > > > > + */
> > > > 
> > > > BTW was there any discussion about the license? drm is generally MIT.
> > > > Are people OK with depending on GPL code for infoframe support?
> > > 
> > > I wasn't aware of that. I don't know how much of an issue it is really
> > > since all symbols are exported non-GPL.
> > > 
> > > Thierry
> > 
> > It's not about the export of the symbols, but more about porting DRM to
> > other UNIXes like BSD. Using the GPL here makes life for the BSD guys a
> > lot harder and they are already struggling really hard to keep up with
> > the pace of Linux. So if you don't care too much it would be nice to use
> > MIT here.
> 
> Sure, I'll relicense it under MIT then.

It seems these got merged as GPL. Do you want to provide a patch for
changing the license?
Thierry Reding April 8, 2013, 12:49 p.m. UTC | #7
On Mon, Apr 08, 2013 at 02:52:40PM +0300, Ville Syrjälä wrote:
> On Thu, Mar 07, 2013 at 02:44:12PM +0100, Thierry Reding wrote:
> > On Thu, Mar 07, 2013 at 02:32:51PM +0100, Lucas Stach wrote:
> > > Am Montag, den 04.03.2013, 16:02 +0100 schrieb Thierry Reding:
> > > > On Mon, Mar 04, 2013 at 04:49:46PM +0200, Ville Syrjälä wrote:
> > > > > On Fri, Feb 22, 2013 at 08:03:26AM +0100, Thierry Reding wrote:
> > > > [...]
> > > > > > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > > > > > new file mode 100644
> > > > > > index 0000000..ab23c9b
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/video/hdmi.c
> > > > > > @@ -0,0 +1,308 @@
> > > > > > +/*
> > > > > > + * Copyright (C) 2012 Avionic Design GmbH
> > > > > > + *
> > > > > > + * This program is free software; you can redistribute it and/or modify
> > > > > > + * it under the terms of the GNU General Public License version 2 as
> > > > > > + * published by the Free Software Foundation.
> > > > > > + */
> > > > > 
> > > > > BTW was there any discussion about the license? drm is generally MIT.
> > > > > Are people OK with depending on GPL code for infoframe support?
> > > > 
> > > > I wasn't aware of that. I don't know how much of an issue it is really
> > > > since all symbols are exported non-GPL.
> > > > 
> > > > Thierry
> > > 
> > > It's not about the export of the symbols, but more about porting DRM to
> > > other UNIXes like BSD. Using the GPL here makes life for the BSD guys a
> > > lot harder and they are already struggling really hard to keep up with
> > > the pace of Linux. So if you don't care too much it would be nice to use
> > > MIT here.
> > 
> > Sure, I'll relicense it under MIT then.
> 
> It seems these got merged as GPL. Do you want to provide a patch for
> changing the license?

Yes, I have the patch locally but had forgotten to send it out. Done
now. Thanks for reminding me.

Thierry
diff mbox

Patch

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 09f1a18..b11eeab 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -52,6 +52,9 @@  config OF_VIDEOMODE
 	help
 	  helper to get videomodes from the devicetree
 
+config HDMI
+	bool
+
 menuconfig FB
 	tristate "Support for frame buffer devices"
 	---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index f592f3b..0b50082 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -5,6 +5,7 @@ 
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_VGASTATE)            += vgastate.o
+obj-$(CONFIG_HDMI)                += hdmi.o
 obj-y                             += fb_notify.o
 obj-$(CONFIG_FB)                  += fb.o
 fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
new file mode 100644
index 0000000..ab23c9b
--- /dev/null
+++ b/drivers/video/hdmi.c
@@ -0,0 +1,308 @@ 
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/hdmi.h>
+#include <linux/string.h>
+
+static void hdmi_infoframe_checksum(void *buffer, size_t size)
+{
+	u8 *ptr = buffer;
+	u8 csum = 0;
+	size_t i;
+
+	/* compute checksum */
+	for (i = 0; i < size; i++)
+		csum += ptr[i];
+
+	ptr[3] = 256 - csum;
+}
+
+/**
+ * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
+ * @frame: HDMI AVI infoframe
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
+{
+	memset(frame, 0, sizeof(*frame));
+
+	frame->type = HDMI_INFOFRAME_TYPE_AVI;
+	frame->version = 2;
+	frame->length = 13;
+
+	return 0;
+}
+EXPORT_SYMBOL(hdmi_avi_infoframe_init);
+
+/**
+ * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
+ * @frame: HDMI AVI 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_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
+				size_t size)
+{
+	u8 *ptr = buffer;
+	size_t length;
+
+	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+	if (size < length)
+		return -ENOSPC;
+
+	memset(buffer, 0, length);
+
+	ptr[0] = frame->type;
+	ptr[1] = frame->version;
+	ptr[2] = frame->length;
+	ptr[3] = 0; /* checksum */
+
+	/* start infoframe payload */
+	ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+	ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
+
+	if (frame->active_info_valid)
+		ptr[0] |= BIT(4);
+
+	if (frame->horizontal_bar_valid)
+		ptr[0] |= BIT(3);
+
+	if (frame->vertical_bar_valid)
+		ptr[0] |= BIT(2);
+
+	ptr[1] = ((frame->colorimetry & 0x3) << 6) |
+		 ((frame->picture_aspect & 0x3) << 4) |
+		 (frame->active_aspect & 0xf);
+
+	ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
+		 ((frame->quantization_range & 0x3) << 2) |
+		 (frame->nups & 0x3);
+
+	if (frame->itc)
+		ptr[2] |= BIT(7);
+
+	ptr[3] = frame->video_code & 0x7f;
+
+	ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
+		 ((frame->content_type & 0x3) << 4) |
+		 (frame->pixel_repeat & 0xf);
+
+	ptr[5] = frame->top_bar & 0xff;
+	ptr[6] = (frame->top_bar >> 8) & 0xff;
+	ptr[7] = frame->bottom_bar & 0xff;
+	ptr[8] = (frame->bottom_bar >> 8) & 0xff;
+	ptr[9] = frame->left_bar & 0xff;
+	ptr[10] = (frame->left_bar >> 8) & 0xff;
+	ptr[11] = frame->right_bar & 0xff;
+	ptr[12] = (frame->right_bar >> 8) & 0xff;
+
+	hdmi_infoframe_checksum(buffer, length);
+
+	return length;
+}
+EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
+
+/**
+ * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
+ * @frame: HDMI SPD infoframe
+ * @vendor: vendor string
+ * @product: product string
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
+			    const char *vendor, const char *product)
+{
+	memset(frame, 0, sizeof(*frame));
+
+	frame->type = HDMI_INFOFRAME_TYPE_SPD;
+	frame->version = 1;
+	frame->length = 25;
+
+	strncpy(frame->vendor, vendor, sizeof(frame->vendor));
+	strncpy(frame->product, product, sizeof(frame->product));
+
+	return 0;
+}
+EXPORT_SYMBOL(hdmi_spd_infoframe_init);
+
+/**
+ * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
+ * @frame: HDMI SPD 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_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
+				size_t size)
+{
+	u8 *ptr = buffer;
+	size_t length;
+
+	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+	if (size < length)
+		return -ENOSPC;
+
+	memset(buffer, 0, length);
+
+	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->vendor, sizeof(frame->vendor));
+	memcpy(ptr + 8, frame->product, sizeof(frame->product));
+
+	ptr[24] = frame->sdi;
+
+	hdmi_infoframe_checksum(buffer, length);
+
+	return length;
+}
+EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
+
+/**
+ * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
+ * @frame: HDMI audio infoframe
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
+{
+	memset(frame, 0, sizeof(*frame));
+
+	frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
+	frame->version = 1;
+	frame->length = 10;
+
+	return 0;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_init);
+
+/**
+ * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
+ * @frame: HDMI audio 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_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
+				  void *buffer, size_t size)
+{
+	unsigned char channels;
+	u8 *ptr = buffer;
+	size_t length;
+
+	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+	if (size < length)
+		return -ENOSPC;
+
+	memset(buffer, 0, length);
+
+	if (frame->channels >= 2)
+		channels = frame->channels - 1;
+	else
+		channels = 0;
+
+	ptr[0] = frame->type;
+	ptr[1] = frame->version;
+	ptr[2] = frame->length;
+	ptr[3] = 0; /* checksum */
+
+	/* start infoframe payload */
+	ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+	ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+	ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
+		 (frame->sample_size & 0x3);
+	ptr[2] = frame->coding_type_ext & 0x1f;
+	ptr[3] = frame->channel_allocation;
+	ptr[4] = (frame->level_shift_value & 0xf) << 3;
+
+	if (frame->downmix_inhibit)
+		ptr[4] |= BIT(7);
+
+	hdmi_infoframe_checksum(buffer, length);
+
+	return length;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
+
+/**
+ * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary
+ *                                buffer
+ * @frame: HDMI vendor 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_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
+				   void *buffer, size_t size)
+{
+	u8 *ptr = buffer;
+	size_t length;
+
+	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+	if (size < length)
+		return -ENOSPC;
+
+	memset(buffer, 0, length);
+
+	ptr[0] = frame->type;
+	ptr[1] = frame->version;
+	ptr[2] = frame->length;
+	ptr[3] = 0; /* checksum */
+
+	memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length);
+
+	hdmi_infoframe_checksum(buffer, length);
+
+	return length;
+}
+EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
new file mode 100644
index 0000000..3b58944
--- /dev/null
+++ b/include/linux/hdmi.h
@@ -0,0 +1,231 @@ 
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_HDMI_H_
+#define __LINUX_HDMI_H_
+
+#include <linux/types.h>
+
+enum hdmi_infoframe_type {
+	HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
+	HDMI_INFOFRAME_TYPE_AVI = 0x82,
+	HDMI_INFOFRAME_TYPE_SPD = 0x83,
+	HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
+};
+
+#define HDMI_INFOFRAME_HEADER_SIZE  4
+#define HDMI_AVI_INFOFRAME_SIZE    13
+#define HDMI_SPD_INFOFRAME_SIZE    25
+#define HDMI_AUDIO_INFOFRAME_SIZE  10
+
+enum hdmi_colorspace {
+	HDMI_COLORSPACE_RGB,
+	HDMI_COLORSPACE_YUV422,
+	HDMI_COLORSPACE_YUV444,
+};
+
+enum hdmi_scan_mode {
+	HDMI_SCAN_MODE_NONE,
+	HDMI_SCAN_MODE_OVERSCAN,
+	HDMI_SCAN_MODE_UNDERSCAN,
+};
+
+enum hdmi_colorimetry {
+	HDMI_COLORIMETRY_NONE,
+	HDMI_COLORIMETRY_ITU_601,
+	HDMI_COLORIMETRY_ITU_709,
+	HDMI_COLORIMETRY_EXTENDED,
+};
+
+enum hdmi_picture_aspect {
+	HDMI_PICTURE_ASPECT_NONE,
+	HDMI_PICTURE_ASPECT_4_3,
+	HDMI_PICTURE_ASPECT_16_9,
+};
+
+enum hdmi_active_aspect {
+	HDMI_ACTIVE_ASPECT_16_9_TOP = 2,
+	HDMI_ACTIVE_ASPECT_14_9_TOP = 3,
+	HDMI_ACTIVE_ASPECT_16_9_CENTER = 4,
+	HDMI_ACTIVE_ASPECT_PICTURE = 8,
+	HDMI_ACTIVE_ASPECT_4_3 = 9,
+	HDMI_ACTIVE_ASPECT_16_9 = 10,
+	HDMI_ACTIVE_ASPECT_14_9 = 11,
+	HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13,
+	HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14,
+	HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15,
+};
+
+enum hdmi_extended_colorimetry {
+	HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
+	HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
+	HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
+	HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
+	HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB,
+};
+
+enum hdmi_quantization_range {
+	HDMI_QUANTIZATION_RANGE_DEFAULT,
+	HDMI_QUANTIZATION_RANGE_LIMITED,
+	HDMI_QUANTIZATION_RANGE_FULL,
+};
+
+/* non-uniform picture scaling */
+enum hdmi_nups {
+	HDMI_NUPS_UNKNOWN,
+	HDMI_NUPS_HORIZONTAL,
+	HDMI_NUPS_VERTICAL,
+	HDMI_NUPS_BOTH,
+};
+
+enum hdmi_ycc_quantization_range {
+	HDMI_YCC_QUANTIZATION_RANGE_LIMITED,
+	HDMI_YCC_QUANTIZATION_RANGE_FULL,
+};
+
+enum hdmi_content_type {
+	HDMI_CONTENT_TYPE_NONE,
+	HDMI_CONTENT_TYPE_PHOTO,
+	HDMI_CONTENT_TYPE_CINEMA,
+	HDMI_CONTENT_TYPE_GAME,
+};
+
+struct hdmi_avi_infoframe {
+	enum hdmi_infoframe_type type;
+	unsigned char version;
+	unsigned char length;
+	enum hdmi_colorspace colorspace;
+	bool active_info_valid;
+	bool horizontal_bar_valid;
+	bool vertical_bar_valid;
+	enum hdmi_scan_mode scan_mode;
+	enum hdmi_colorimetry colorimetry;
+	enum hdmi_picture_aspect picture_aspect;
+	enum hdmi_active_aspect active_aspect;
+	bool itc;
+	enum hdmi_extended_colorimetry extended_colorimetry;
+	enum hdmi_quantization_range quantization_range;
+	enum hdmi_nups nups;
+	unsigned char video_code;
+	enum hdmi_ycc_quantization_range ycc_quantization_range;
+	enum hdmi_content_type content_type;
+	unsigned char pixel_repeat;
+	unsigned short top_bar;
+	unsigned short bottom_bar;
+	unsigned short left_bar;
+	unsigned short right_bar;
+};
+
+int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
+ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
+				size_t size);
+
+enum hdmi_spd_sdi {
+	HDMI_SPD_SDI_UNKNOWN,
+	HDMI_SPD_SDI_DSTB,
+	HDMI_SPD_SDI_DVDP,
+	HDMI_SPD_SDI_DVHS,
+	HDMI_SPD_SDI_HDDVR,
+	HDMI_SPD_SDI_DVC,
+	HDMI_SPD_SDI_DSC,
+	HDMI_SPD_SDI_VCD,
+	HDMI_SPD_SDI_GAME,
+	HDMI_SPD_SDI_PC,
+	HDMI_SPD_SDI_BD,
+	HDMI_SPD_SDI_SACD,
+	HDMI_SPD_SDI_HDDVD,
+	HDMI_SPD_SDI_PMP,
+};
+
+struct hdmi_spd_infoframe {
+	enum hdmi_infoframe_type type;
+	unsigned char version;
+	unsigned char length;
+	char vendor[8];
+	char product[16];
+	enum hdmi_spd_sdi sdi;
+};
+
+int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
+			    const char *vendor, const char *product);
+ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
+				size_t size);
+
+enum hdmi_audio_coding_type {
+	HDMI_AUDIO_CODING_TYPE_STREAM,
+	HDMI_AUDIO_CODING_TYPE_PCM,
+	HDMI_AUDIO_CODING_TYPE_AC3,
+	HDMI_AUDIO_CODING_TYPE_MPEG1,
+	HDMI_AUDIO_CODING_TYPE_MP3,
+	HDMI_AUDIO_CODING_TYPE_MPEG2,
+	HDMI_AUDIO_CODING_TYPE_AAC_LC,
+	HDMI_AUDIO_CODING_TYPE_DTS,
+	HDMI_AUDIO_CODING_TYPE_ATRAC,
+	HDMI_AUDIO_CODING_TYPE_DSD,
+	HDMI_AUDIO_CODING_TYPE_EAC3,
+	HDMI_AUDIO_CODING_TYPE_DTS_HD,
+	HDMI_AUDIO_CODING_TYPE_MLP,
+	HDMI_AUDIO_CODING_TYPE_DST,
+	HDMI_AUDIO_CODING_TYPE_WMA_PRO,
+};
+
+enum hdmi_audio_sample_size {
+	HDMI_AUDIO_SAMPLE_SIZE_STREAM,
+	HDMI_AUDIO_SAMPLE_SIZE_16,
+	HDMI_AUDIO_SAMPLE_SIZE_20,
+	HDMI_AUDIO_SAMPLE_SIZE_24,
+};
+
+enum hdmi_audio_sample_frequency {
+	HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
+	HDMI_AUDIO_SAMPLE_FREQUENCY_32000,
+	HDMI_AUDIO_SAMPLE_FREQUENCY_44100,
+	HDMI_AUDIO_SAMPLE_FREQUENCY_48000,
+	HDMI_AUDIO_SAMPLE_FREQUENCY_88200,
+	HDMI_AUDIO_SAMPLE_FREQUENCY_96000,
+	HDMI_AUDIO_SAMPLE_FREQUENCY_176400,
+	HDMI_AUDIO_SAMPLE_FREQUENCY_192000,
+};
+
+enum hdmi_audio_coding_type_ext {
+	HDMI_AUDIO_CODING_TYPE_EXT_STREAM,
+	HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC,
+	HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2,
+	HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND,
+};
+
+struct hdmi_audio_infoframe {
+	enum hdmi_infoframe_type type;
+	unsigned char version;
+	unsigned char length;
+	unsigned char channels;
+	enum hdmi_audio_coding_type coding_type;
+	enum hdmi_audio_sample_size sample_size;
+	enum hdmi_audio_sample_frequency sample_frequency;
+	enum hdmi_audio_coding_type_ext coding_type_ext;
+	unsigned char channel_allocation;
+	unsigned char level_shift_value;
+	bool downmix_inhibit;
+
+};
+
+int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
+ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
+				  void *buffer, size_t size);
+
+struct hdmi_vendor_infoframe {
+	enum hdmi_infoframe_type type;
+	unsigned char version;
+	unsigned char length;
+	u8 data[27];
+};
+
+ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
+				   void *buffer, size_t size);
+
+#endif /* _DRM_HDMI_H */