public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Simon Ser <simon.ser@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Martin Peres <martin.peres@intel.com>
Subject: [igt-dev] [PATCH i-g-t 1/7] lib/igt_edid: add support for Short Audio Descriptors
Date: Fri, 26 Apr 2019 19:21:04 +0300	[thread overview]
Message-ID: <20190426162110.1768-2-simon.ser@intel.com> (raw)
In-Reply-To: <20190426162110.1768-1-simon.ser@intel.com>

Short Audio Descriptors (SADs) can be wrapped in an EDID extension to advertise
audio support.

The EDID structure is as follows:
- The 128-byte EDID block contains a field with the number of 128-byte
  extension blocks that follow.
- Each extension block has a tag which specifies its type. The tag we're
  interested in is CEA-861.
- The CEA block has a few flags, including one that indicates whether basic
  audio is supported. The CEA block contains several sub-blocks of variable
  size. There are two types of CEA sub-blocks:
  - Detailed Timing Descriptors (DTDs): additional video timings
  - Data Block Collection: these can detail video, audio, speaker placement and
    other pieces of information about the display.
  We're interested in audio blocks.
- Audio blocks contain one or more Short Audio Descriptors (SADs). A SAD is a
  3-byte record describing a supported format.
- SADs can describe support for the PCM format, including sampling rate,
  sample size and channels.

The igt_edid library intentionally exposes all of this complexity because it
would be nice to generate all kind of valid EDIDs and test the kernel handles
them correctly (e.g. multiple SADs in different CEA blocks, or any EDID we find
in the wild really).

Signed-off-by: Simon Ser <simon.ser@intel.com>
---
 lib/igt_edid.c | 71 +++++++++++++++++++++++++++++++++++++-----
 lib/igt_edid.h | 84 ++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 145 insertions(+), 10 deletions(-)

diff --git a/lib/igt_edid.c b/lib/igt_edid.c
index 9d604b13..d01defb0 100644
--- a/lib/igt_edid.c
+++ b/lib/igt_edid.c
@@ -252,19 +252,74 @@ void edid_init_with_mode(struct edid *edid, drmModeModeInfo *mode)
 				   EDID_DETAIL_MONITOR_NAME, "IGT");
 }
 
+static uint8_t compute_checksum(const uint8_t *buf, size_t size)
+{
+	size_t i;
+	uint8_t sum = 0;
+
+	assert(size > 0);
+	for (i = 0; i < size - 1; i++) {
+		sum += buf[i];
+	}
+
+	return 256 - sum;
+}
+
 /**
  * edid_update_checksum: compute and update the EDID checksum
  */
 void edid_update_checksum(struct edid *edid)
 {
-	size_t i;
-	const uint8_t *buf = (const uint8_t *) edid;
-	uint8_t sum = 0;
+	edid->checksum = compute_checksum((uint8_t *) edid,
+					  sizeof(struct edid));
+}
 
-	/* calculate checksum */
-	for (i = 0; i < sizeof(struct edid) - 1; i++) {
-		sum = sum + buf[i];
-	}
+/**
+ * cea_sad_init_pcm:
+ * @channels: the number of supported channels (max. 8)
+ * @sampling_rates: bitfield of enum cea_sad_sampling_rate
+ * @sample_sizes: bitfield of enum cea_sad_pcm_sample_size
+ *
+ * Initialize a Short Audio Descriptor to advertise PCM support.
+ */
+void cea_sad_init_pcm(struct cea_sad *sad, int channels,
+		      uint8_t sampling_rates, uint8_t sample_sizes)
+{
+	assert(channels <= 8);
+	sad->format_channels = CEA_SAD_FORMAT_PCM << 3 | (channels - 1);
+	sad->sampling_rates = sampling_rates;
+	sad->bitrate = sample_sizes;
+}
+
+/**
+ * edid_ext_set_cea_sad: set an extension block to be CEA SAD
+ */
+void edid_ext_set_cea_sad(struct edid_ext *ext, const struct cea_sad *sads,
+			  size_t sads_len)
+{
+	struct edid_cea *cea = &ext->data.cea;
+	struct edid_cea_data_block *data_block;
+	size_t sads_size, data_block_size;
 
-	edid->checksum = 256 - sum;
+	memset(ext, 0, sizeof(struct edid_ext));
+
+	sads_size = sizeof(struct cea_sad) * sads_len;
+	data_block_size = sizeof(struct edid_cea_data_block) + sads_size;
+
+	ext->tag = EDID_EXT_CEA;
+
+	cea->revision = 3;
+	cea->dtd_start = 4 + data_block_size;
+	cea->misc = 1 << 6; /* basic audio, no DTD */
+
+	assert(sads_size <= 0xFF);
+	data_block = (struct edid_cea_data_block *) cea->data;
+	data_block->type_len = EDID_CEA_DATA_AUDIO << 5 | sads_size;
+	memcpy(data_block->data.sads, sads, sads_size);
+}
+
+void edid_ext_update_cea_checksum(struct edid_ext *ext)
+{
+	ext->data.cea.checksum = compute_checksum((uint8_t *) ext,
+						  sizeof(struct edid_ext));
 }
diff --git a/lib/igt_edid.h b/lib/igt_edid.h
index d0963033..860ed929 100644
--- a/lib/igt_edid.h
+++ b/lib/igt_edid.h
@@ -148,6 +148,80 @@ struct detailed_timing {
 	} data;
 } __attribute__((packed));
 
+enum cea_sad_format {
+	CEA_SAD_FORMAT_PCM = 1,
+	CEA_SAD_FORMAT_AC3 = 2,
+	CEA_SAD_FORMAT_MPEG1 = 3, /* Layers 1 & 2 */
+	CEA_SAD_FORMAT_MP3 = 4,
+	CEA_SAD_FORMAT_MPEG2 = 5,
+	CEA_SAD_FORMAT_AAC = 6,
+	CEA_SAD_FORMAT_DTS = 7,
+	CEA_SAD_FORMAT_ATRAC = 8,
+	CEA_SAD_FORMAT_SACD = 9, /* One-bit audio */
+	CEA_SAD_FORMAT_DD_PLUS = 10,
+	CEA_SAD_FORMAT_DTS_HD = 11,
+	CEA_SAD_FORMAT_DOLBY = 12, /* MLP/Dolby TrueHD */
+	CEA_SAD_FORMAT_DST = 13,
+	CEA_SAD_FORMAT_WMA = 14, /* Microsoft WMA Pro */
+};
+
+enum cea_sad_sampling_rate {
+	CEA_SAD_SAMPLING_RATE_32KHZ = 1 << 0,
+	CEA_SAD_SAMPLING_RATE_44KHZ = 1 << 1,
+	CEA_SAD_SAMPLING_RATE_48KHZ = 1 << 2,
+	CEA_SAD_SAMPLING_RATE_88KHZ = 1 << 3,
+	CEA_SAD_SAMPLING_RATE_96KHZ = 1 << 4,
+	CEA_SAD_SAMPLING_RATE_176KHZ = 1 << 5,
+	CEA_SAD_SAMPLING_RATE_192KHZ = 1 << 6,
+};
+
+/* for PCM only */
+enum cea_sad_pcm_sample_size {
+	CEA_SAD_SAMPLE_SIZE_16 = 1 << 0,
+	CEA_SAD_SAMPLE_SIZE_20 = 1 << 1,
+	CEA_SAD_SAMPLE_SIZE_24 = 1 << 2,
+};
+
+/* Short Audio Descriptor */
+struct cea_sad {
+	uint8_t format_channels;
+	uint8_t sampling_rates;
+	uint8_t bitrate;
+} __attribute__((packed));
+
+enum edid_cea_data_type {
+	EDID_CEA_DATA_AUDIO = 1,
+	EDID_CEA_DATA_VIDEO = 2,
+	EDID_CEA_DATA_VENDOR_SPECIFIC = 3,
+	EDID_CEA_DATA_SPEAKER_ALLOC = 4,
+};
+
+struct edid_cea_data_block {
+	uint8_t type_len; /* type is from enum edid_cea_data_type */
+	union {
+		struct cea_sad sads[0];
+	} data;
+} __attribute__((packed));
+
+struct edid_cea {
+	uint8_t revision;
+	uint8_t dtd_start;
+	uint8_t misc;
+	char data[123]; /* DBC & DTD collection, padded with zeros */
+	uint8_t checksum;
+} __attribute__((packed));
+
+enum edid_ext_tag {
+	EDID_EXT_CEA = 0x02,
+};
+
+struct edid_ext {
+	uint8_t tag; /* enum edid_ext_tag */
+	union {
+		struct edid_cea cea;
+	} data;
+} __attribute__((packed));
+
 struct edid {
 	char header[8];
 	/* Vendor & product info */
@@ -183,9 +257,9 @@ struct edid {
 	/* Detailing timings 1-4 */
 	struct detailed_timing detailed_timings[DETAILED_TIMINGS_LEN];
 	/* Number of 128 byte ext. blocks */
-	uint8_t extensions;
-	/* Checksum */
+	uint8_t extensions_len;
 	uint8_t checksum;
+	struct edid_ext extensions[];
 } __attribute__((packed));
 
 void edid_init(struct edid *edid);
@@ -199,4 +273,10 @@ void detailed_timing_set_string(struct detailed_timing *dt,
 				enum detailed_non_pixel_type type,
 				const char *str);
 
+void cea_sad_init_pcm(struct cea_sad *sad, int channels,
+		      uint8_t sampling_rates, uint8_t sample_sizes);
+void edid_ext_set_cea_sad(struct edid_ext *ext, const struct cea_sad *sads,
+			  size_t sads_len);
+void edid_ext_update_cea_checksum(struct edid_ext *ext);
+
 #endif
-- 
2.21.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2019-04-26 16:21 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-26 16:21 [igt-dev] [PATCH i-g-t 0/7] tests/kms_chamelium: add hdmi-audio test Simon Ser
2019-04-26 16:21 ` Simon Ser [this message]
2019-04-26 16:21 ` [igt-dev] [PATCH i-g-t 2/7] lib/igt_edid: add support for Vendor Specific Data blocks Simon Ser
2019-04-26 16:21 ` [igt-dev] [PATCH i-g-t 3/7] tests/kms_chamelium: generate an EDID with audio support Simon Ser
2019-05-10 11:35   ` Arkadiusz Hiler
2019-04-26 16:21 ` [igt-dev] [PATCH i-g-t 4/7] test/kms_chamelium: disable >48KHz audio tests Simon Ser
2019-04-26 16:21 ` [igt-dev] [PATCH i-g-t 5/7] tests/kms_chamelium: enable audio test on HDMI ports Simon Ser
2019-05-10 11:38   ` Arkadiusz Hiler
2019-04-26 16:21 ` [igt-dev] [PATCH i-g-t 6/7] tests/kms_chamelium: don't abort audio test on first fail Simon Ser
2019-04-26 16:21 ` [igt-dev] [PATCH i-g-t 7/7] HAX: add dp-audio test to fast-feedback Simon Ser
2019-04-26 17:13 ` [igt-dev] ✗ Fi.CI.BAT: failure for tests/kms_chamelium: add hdmi-audio test Patchwork
2019-05-10 11:56   ` Arkadiusz Hiler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190426162110.1768-2-simon.ser@intel.com \
    --to=simon.ser@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=martin.peres@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox