hdmi.h revision 1.2.6.3 1 1.2.6.2 tls /* $NetBSD: hdmi.h,v 1.2.6.3 2017/12/03 11:37:59 jdolecek Exp $ */
2 1.2.6.2 tls
3 1.2.6.2 tls /*-
4 1.2.6.2 tls * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 1.2.6.2 tls * All rights reserved.
6 1.2.6.2 tls *
7 1.2.6.2 tls * This code is derived from software contributed to The NetBSD Foundation
8 1.2.6.2 tls * by Taylor R. Campbell.
9 1.2.6.2 tls *
10 1.2.6.2 tls * Redistribution and use in source and binary forms, with or without
11 1.2.6.2 tls * modification, are permitted provided that the following conditions
12 1.2.6.2 tls * are met:
13 1.2.6.2 tls * 1. Redistributions of source code must retain the above copyright
14 1.2.6.2 tls * notice, this list of conditions and the following disclaimer.
15 1.2.6.2 tls * 2. Redistributions in binary form must reproduce the above copyright
16 1.2.6.2 tls * notice, this list of conditions and the following disclaimer in the
17 1.2.6.2 tls * documentation and/or other materials provided with the distribution.
18 1.2.6.2 tls *
19 1.2.6.2 tls * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.2.6.2 tls * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.2.6.2 tls * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.2.6.2 tls * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.2.6.2 tls * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.2.6.2 tls * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.2.6.2 tls * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.2.6.2 tls * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.2.6.2 tls * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.2.6.2 tls * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.2.6.2 tls * POSSIBILITY OF SUCH DAMAGE.
30 1.2.6.2 tls */
31 1.2.6.2 tls
32 1.2.6.2 tls #ifndef _LINUX_HDMI_H_
33 1.2.6.2 tls #define _LINUX_HDMI_H_
34 1.2.6.2 tls
35 1.2.6.2 tls #include <sys/types.h>
36 1.2.6.2 tls #include <sys/param.h>
37 1.2.6.2 tls #include <sys/errno.h>
38 1.2.6.2 tls #include <sys/systm.h>
39 1.2.6.2 tls
40 1.2.6.2 tls enum hdmi_3d_structure {
41 1.2.6.2 tls HDMI_3D_STRUCTURE_INVALID = -1,
42 1.2.6.2 tls HDMI_3D_STRUCTURE_FRAME_PACKING = 0,
43 1.2.6.2 tls HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE = 1,
44 1.2.6.2 tls HDMI_3D_STRUCTURE_LINE_ALTERNATIVE = 2,
45 1.2.6.2 tls HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL = 3,
46 1.2.6.2 tls HDMI_3D_STRUCTURE_L_DEPTH = 4,
47 1.2.6.2 tls HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH = 5,
48 1.2.6.2 tls HDMI_3D_STRUCTURE_TOP_AND_BOTTOM = 6,
49 1.2.6.2 tls HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8,
50 1.2.6.2 tls };
51 1.2.6.2 tls
52 1.2.6.2 tls enum hdmi_active_aspect {
53 1.2.6.2 tls HDMI_ACTIVE_ASPECT_16_9_TOP = 2,
54 1.2.6.2 tls HDMI_ACTIVE_ASPECT_14_9_TOP = 3,
55 1.2.6.2 tls HDMI_ACTIVE_ASPECT_16_9_CENTER = 4,
56 1.2.6.2 tls HDMI_ACTIVE_ASPECT_PICTURE = 8,
57 1.2.6.2 tls HDMI_ACTIVE_ASPECT_4_3 = 9,
58 1.2.6.2 tls HDMI_ACTIVE_ASPECT_16_9 = 10,
59 1.2.6.2 tls HDMI_ACTIVE_ASPECT_14_9 = 11,
60 1.2.6.2 tls HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13,
61 1.2.6.2 tls HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14,
62 1.2.6.2 tls HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15,
63 1.2.6.2 tls };
64 1.2.6.2 tls
65 1.2.6.2 tls enum hdmi_audio_coding_type {
66 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_STREAM = 0,
67 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_PCM = 1,
68 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_AC3 = 2,
69 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_MPEG1 = 3,
70 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_MP3 = 4,
71 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_MPEG2 = 5,
72 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_AAC_LC = 6,
73 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_DTS = 7,
74 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_ATRAC = 8,
75 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_DSD = 9,
76 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_EAC3 = 10,
77 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_DTS_HD = 11,
78 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_MLP = 12,
79 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_DST = 13,
80 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_WMA_PRO = 14,
81 1.2.6.2 tls };
82 1.2.6.2 tls
83 1.2.6.2 tls enum hdmi_audio_coding_type_ext {
84 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_EXT_STREAM = 0,
85 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC = 1,
86 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2 = 2,
87 1.2.6.2 tls HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND = 3,
88 1.2.6.2 tls };
89 1.2.6.2 tls
90 1.2.6.2 tls enum hdmi_audio_sample_frequency {
91 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM = 0,
92 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_32000 = 1,
93 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_44100 = 2,
94 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_48000 = 3,
95 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_88200 = 4,
96 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_96000 = 5,
97 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_176400 = 6,
98 1.2.6.2 tls HDMI_AUDIO_SAMPLE_FREQUENCY_192000 = 7,
99 1.2.6.2 tls };
100 1.2.6.2 tls
101 1.2.6.2 tls enum hdmi_audio_sample_size {
102 1.2.6.2 tls HDMI_AUDIO_SAMPLE_SIZE_STREAM = 0,
103 1.2.6.2 tls HDMI_AUDIO_SAMPLE_SIZE_16 = 1,
104 1.2.6.2 tls HDMI_AUDIO_SAMPLE_SIZE_20 = 2,
105 1.2.6.2 tls HDMI_AUDIO_SAMPLE_SIZE_24 = 3,
106 1.2.6.2 tls };
107 1.2.6.2 tls
108 1.2.6.2 tls enum hdmi_colorimetry {
109 1.2.6.2 tls HDMI_COLORIMETRY_NONE = 0,
110 1.2.6.2 tls HDMI_COLORIMETRY_ITU_601 = 1,
111 1.2.6.2 tls HDMI_COLORIMETRY_ITU_709 = 2,
112 1.2.6.2 tls HDMI_COLORIMETRY_EXTENDED = 3,
113 1.2.6.2 tls };
114 1.2.6.2 tls
115 1.2.6.2 tls enum hdmi_colorspace {
116 1.2.6.2 tls HDMI_COLORSPACE_RGB = 0,
117 1.2.6.2 tls HDMI_COLORSPACE_YUV422 = 1,
118 1.2.6.2 tls HDMI_COLORSPACE_YUV444 = 2,
119 1.2.6.2 tls };
120 1.2.6.2 tls
121 1.2.6.2 tls enum hdmi_content_type {
122 1.2.6.2 tls HDMI_CONTENT_TYPE_NONE = 0,
123 1.2.6.2 tls HDMI_CONTENT_TYPE_PHOTO = 1,
124 1.2.6.2 tls HDMI_CONTENT_TYPE_CINEMA = 2,
125 1.2.6.2 tls HDMI_CONTENT_TYPE_GAME = 3,
126 1.2.6.2 tls };
127 1.2.6.2 tls
128 1.2.6.2 tls enum hdmi_extended_colorimetry {
129 1.2.6.2 tls HDMI_EXTENDED_COLORIMETRY_XV_YCC_601 = 0,
130 1.2.6.2 tls HDMI_EXTENDED_COLORIMETRY_XV_YCC_709 = 1,
131 1.2.6.2 tls HDMI_EXTENDED_COLORIMETRY_S_YCC_601 = 2,
132 1.2.6.2 tls HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601 = 3,
133 1.2.6.2 tls HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB = 4,
134 1.2.6.2 tls };
135 1.2.6.2 tls
136 1.2.6.2 tls enum hdmi_nups {
137 1.2.6.2 tls HDMI_NUPS_UNKNOWN = 0,
138 1.2.6.2 tls HDMI_NUPS_HORIZONTAL = 1,
139 1.2.6.2 tls HDMI_NUPS_VERTICAL = 2,
140 1.2.6.2 tls HDMI_NUPS_BOTH = 3,
141 1.2.6.2 tls };
142 1.2.6.2 tls
143 1.2.6.2 tls enum hdmi_picture_aspect {
144 1.2.6.2 tls HDMI_PICTURE_ASPECT_NONE = 0,
145 1.2.6.2 tls HDMI_PICTURE_ASPECT_4_3 = 1,
146 1.2.6.2 tls HDMI_PICTURE_ASPECT_16_9 = 2,
147 1.2.6.2 tls };
148 1.2.6.2 tls
149 1.2.6.2 tls enum hdmi_quantization_range {
150 1.2.6.2 tls HDMI_QUANTIZATION_RANGE_DEFAULT = 0,
151 1.2.6.2 tls HDMI_QUANTIZATION_RANGE_LIMITED = 1,
152 1.2.6.2 tls HDMI_QUANTIZATION_RANGE_FULL = 2,
153 1.2.6.2 tls };
154 1.2.6.2 tls
155 1.2.6.2 tls enum hdmi_scan_mode {
156 1.2.6.2 tls HDMI_SCAN_MODE_NONE = 0,
157 1.2.6.2 tls HDMI_SCAN_MODE_OVERSCAN = 1,
158 1.2.6.2 tls HDMI_SCAN_MODE_UNDERSCAN = 2,
159 1.2.6.2 tls };
160 1.2.6.2 tls
161 1.2.6.2 tls enum hdmi_ycc_quantization_range {
162 1.2.6.2 tls HDMI_YCC_QUANTIZATION_RANGE_LIMITED = 0,
163 1.2.6.2 tls HDMI_YCC_QUANTIZATION_RANGE_FULL = 1,
164 1.2.6.2 tls };
165 1.2.6.2 tls
166 1.2.6.2 tls enum hdmi_infoframe_type {
167 1.2.6.2 tls HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
168 1.2.6.2 tls HDMI_INFOFRAME_TYPE_AVI = 0x82,
169 1.2.6.2 tls HDMI_INFOFRAME_TYPE_SPD = 0x83,
170 1.2.6.2 tls HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
171 1.2.6.2 tls };
172 1.2.6.2 tls
173 1.2.6.2 tls #define HDMI_INFOFRAME_SIZE(TYPE) \
174 1.2.6.2 tls (HDMI_INFOFRAME_HEADER_SIZE + HDMI_##TYPE##_INFOFRAME_SIZE)
175 1.2.6.2 tls
176 1.2.6.2 tls #define HDMI_INFOFRAME_HEADER_SIZE 4
177 1.2.6.2 tls struct hdmi_infoframe_header {
178 1.2.6.2 tls enum hdmi_infoframe_type type;
179 1.2.6.2 tls uint8_t version;
180 1.2.6.2 tls uint8_t length;
181 1.2.6.2 tls /* checksum */
182 1.2.6.2 tls };
183 1.2.6.2 tls
184 1.2.6.2 tls static inline void
185 1.2.6.2 tls hdmi_infoframe_header_init(struct hdmi_infoframe_header *header,
186 1.2.6.2 tls enum hdmi_infoframe_type type, uint8_t vers, uint8_t length)
187 1.2.6.2 tls {
188 1.2.6.2 tls
189 1.2.6.2 tls header->type = type;
190 1.2.6.2 tls header->version = vers;
191 1.2.6.2 tls header->length = length;
192 1.2.6.2 tls }
193 1.2.6.2 tls
194 1.2.6.2 tls static inline int
195 1.2.6.2 tls hdmi_infoframe_header_pack(const struct hdmi_infoframe_header *header,
196 1.2.6.2 tls uint8_t length, void *buf, size_t size)
197 1.2.6.2 tls {
198 1.2.6.2 tls uint8_t *const p = buf;
199 1.2.6.2 tls
200 1.2.6.3 jdolecek if (length < HDMI_INFOFRAME_HEADER_SIZE)
201 1.2.6.3 jdolecek return -ENOSPC;
202 1.2.6.3 jdolecek if (size < length)
203 1.2.6.2 tls return -ENOSPC;
204 1.2.6.2 tls
205 1.2.6.2 tls p[0] = header->type;
206 1.2.6.2 tls p[1] = header->version;
207 1.2.6.3 jdolecek p[2] = (length - HDMI_INFOFRAME_HEADER_SIZE);
208 1.2.6.2 tls p[3] = 0; /* checksum */
209 1.2.6.2 tls
210 1.2.6.2 tls return HDMI_INFOFRAME_HEADER_SIZE;
211 1.2.6.2 tls }
212 1.2.6.2 tls
213 1.2.6.2 tls static inline void
214 1.2.6.2 tls hdmi_infoframe_checksum(void *buf, size_t length)
215 1.2.6.2 tls {
216 1.2.6.2 tls uint8_t *p = buf;
217 1.2.6.2 tls uint8_t checksum = 0;
218 1.2.6.2 tls
219 1.2.6.2 tls while (length--)
220 1.2.6.3 jdolecek checksum += *p++;
221 1.2.6.2 tls
222 1.2.6.2 tls p = buf;
223 1.2.6.2 tls p[3] = (256 - checksum);
224 1.2.6.2 tls }
225 1.2.6.2 tls
226 1.2.6.2 tls #define HDMI_AUDIO_INFOFRAME_SIZE 10
227 1.2.6.2 tls struct hdmi_audio_infoframe {
228 1.2.6.2 tls struct hdmi_infoframe_header header;
229 1.2.6.2 tls uint8_t channels;
230 1.2.6.2 tls enum hdmi_audio_coding_type coding_type;
231 1.2.6.2 tls enum hdmi_audio_sample_size sample_size;
232 1.2.6.2 tls enum hdmi_audio_sample_frequency sample_frequency;
233 1.2.6.2 tls enum hdmi_audio_coding_type_ext coding_type_ext;
234 1.2.6.2 tls uint8_t channel_allocation;
235 1.2.6.2 tls uint8_t level_shift_value;
236 1.2.6.2 tls bool downmix_inhibit;
237 1.2.6.2 tls };
238 1.2.6.2 tls
239 1.2.6.2 tls static inline int
240 1.2.6.2 tls hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
241 1.2.6.2 tls {
242 1.2.6.2 tls static const struct hdmi_audio_infoframe zero_frame;
243 1.2.6.2 tls
244 1.2.6.2 tls *frame = zero_frame;
245 1.2.6.2 tls
246 1.2.6.2 tls hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_AUDIO,
247 1.2.6.2 tls 1, HDMI_AUDIO_INFOFRAME_SIZE);
248 1.2.6.2 tls
249 1.2.6.2 tls return 0;
250 1.2.6.2 tls }
251 1.2.6.2 tls
252 1.2.6.2 tls static inline ssize_t
253 1.2.6.2 tls hdmi_audio_infoframe_pack(const struct hdmi_audio_infoframe *frame, void *buf,
254 1.2.6.2 tls size_t size)
255 1.2.6.2 tls {
256 1.2.6.2 tls const size_t length = HDMI_INFOFRAME_HEADER_SIZE +
257 1.2.6.2 tls HDMI_AUDIO_INFOFRAME_SIZE;
258 1.2.6.2 tls uint8_t channels = 0;
259 1.2.6.2 tls uint8_t *p = buf;
260 1.2.6.2 tls int ret;
261 1.2.6.2 tls
262 1.2.6.2 tls KASSERT(frame->header.length == HDMI_AUDIO_INFOFRAME_SIZE);
263 1.2.6.2 tls
264 1.2.6.2 tls ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
265 1.2.6.2 tls if (ret < 0)
266 1.2.6.2 tls return ret;
267 1.2.6.3 jdolecek KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
268 1.2.6.2 tls p += HDMI_INFOFRAME_HEADER_SIZE;
269 1.2.6.2 tls size -= HDMI_INFOFRAME_HEADER_SIZE;
270 1.2.6.2 tls
271 1.2.6.2 tls if (frame->channels >= 2)
272 1.2.6.2 tls channels = frame->channels - 1;
273 1.2.6.2 tls
274 1.2.6.2 tls p[0] = __SHIFTIN(frame->coding_type, __BITS(7,4));
275 1.2.6.2 tls p[0] |= __SHIFTIN(channels, __BITS(2,0));
276 1.2.6.2 tls
277 1.2.6.2 tls p[1] = __SHIFTIN(frame->sample_frequency, __BITS(4,2));
278 1.2.6.2 tls p[1] |= __SHIFTIN(frame->sample_size, __BITS(1,0));
279 1.2.6.2 tls
280 1.2.6.2 tls p[2] = __SHIFTIN(frame->coding_type_ext, __BITS(5,0));
281 1.2.6.2 tls
282 1.2.6.2 tls p[3] = __SHIFTIN(frame->level_shift_value, __BITS(6, 3));
283 1.2.6.2 tls
284 1.2.6.2 tls p[4] = __SHIFTIN(frame->downmix_inhibit? 1 : 0, __BIT(7));
285 1.2.6.2 tls
286 1.2.6.3 jdolecek /* PB6 to PB10 are reserved */
287 1.2.6.3 jdolecek p[5] = 0;
288 1.2.6.3 jdolecek p[6] = 0;
289 1.2.6.3 jdolecek p[7] = 0;
290 1.2.6.3 jdolecek p[8] = 0;
291 1.2.6.3 jdolecek p[9] = 0;
292 1.2.6.3 jdolecek
293 1.2.6.2 tls CTASSERT(HDMI_AUDIO_INFOFRAME_SIZE == 10);
294 1.2.6.2 tls
295 1.2.6.2 tls hdmi_infoframe_checksum(buf, length);
296 1.2.6.2 tls
297 1.2.6.2 tls return length;
298 1.2.6.2 tls }
299 1.2.6.2 tls
300 1.2.6.2 tls #define HDMI_AVI_INFOFRAME_SIZE 13
301 1.2.6.2 tls struct hdmi_avi_infoframe {
302 1.2.6.2 tls struct hdmi_infoframe_header header;
303 1.2.6.2 tls enum hdmi_colorspace colorspace;
304 1.2.6.2 tls enum hdmi_scan_mode scan_mode;
305 1.2.6.2 tls enum hdmi_colorimetry colorimetry;
306 1.2.6.2 tls enum hdmi_picture_aspect picture_aspect;
307 1.2.6.2 tls enum hdmi_active_aspect active_aspect;
308 1.2.6.2 tls bool itc;
309 1.2.6.2 tls enum hdmi_extended_colorimetry extended_colorimetry;
310 1.2.6.2 tls enum hdmi_quantization_range quantization_range;
311 1.2.6.2 tls enum hdmi_nups nups;
312 1.2.6.2 tls uint8_t video_code;
313 1.2.6.2 tls enum hdmi_ycc_quantization_range ycc_quantization_range;
314 1.2.6.2 tls enum hdmi_content_type content_type;
315 1.2.6.2 tls uint8_t pixel_repeat;
316 1.2.6.2 tls uint16_t top_bar;
317 1.2.6.2 tls uint16_t bottom_bar;
318 1.2.6.2 tls uint16_t left_bar;
319 1.2.6.2 tls uint16_t right_bar;
320 1.2.6.2 tls };
321 1.2.6.2 tls
322 1.2.6.2 tls static inline int
323 1.2.6.2 tls hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
324 1.2.6.2 tls {
325 1.2.6.2 tls static const struct hdmi_avi_infoframe zero_frame;
326 1.2.6.2 tls
327 1.2.6.2 tls *frame = zero_frame;
328 1.2.6.2 tls
329 1.2.6.2 tls hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_AVI, 2,
330 1.2.6.2 tls HDMI_AVI_INFOFRAME_SIZE);
331 1.2.6.2 tls
332 1.2.6.2 tls return 0;
333 1.2.6.2 tls }
334 1.2.6.2 tls
335 1.2.6.2 tls static inline ssize_t
336 1.2.6.2 tls hdmi_avi_infoframe_pack(const struct hdmi_avi_infoframe *frame, void *buf,
337 1.2.6.2 tls size_t size)
338 1.2.6.2 tls {
339 1.2.6.2 tls const size_t length = HDMI_INFOFRAME_HEADER_SIZE +
340 1.2.6.2 tls HDMI_AVI_INFOFRAME_SIZE;
341 1.2.6.2 tls uint8_t *p = buf;
342 1.2.6.2 tls int ret;
343 1.2.6.2 tls
344 1.2.6.2 tls KASSERT(frame->header.length == HDMI_AVI_INFOFRAME_SIZE);
345 1.2.6.2 tls
346 1.2.6.2 tls ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
347 1.2.6.2 tls if (ret < 0)
348 1.2.6.2 tls return ret;
349 1.2.6.3 jdolecek KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
350 1.2.6.2 tls p += HDMI_INFOFRAME_HEADER_SIZE;
351 1.2.6.2 tls size -= HDMI_INFOFRAME_HEADER_SIZE;
352 1.2.6.2 tls
353 1.2.6.2 tls p[0] = __SHIFTIN(frame->colorspace, __BITS(6,5));
354 1.2.6.2 tls p[0] |= __SHIFTIN(frame->active_aspect & 0xf? 1 : 0, __BIT(4));
355 1.2.6.2 tls p[0] |= __SHIFTIN(frame->top_bar || frame->bottom_bar, __BIT(3));
356 1.2.6.2 tls p[0] |= __SHIFTIN(frame->left_bar || frame->right_bar, __BIT(2));
357 1.2.6.2 tls p[0] |= __SHIFTIN(frame->scan_mode, __BITS(1,0));
358 1.2.6.2 tls
359 1.2.6.2 tls p[1] = __SHIFTIN(frame->colorimetry, __BITS(7,6));
360 1.2.6.2 tls p[1] |= __SHIFTIN(frame->picture_aspect, __BITS(5,4));
361 1.2.6.2 tls p[1] |= __SHIFTIN(frame->active_aspect, __BITS(3,0));
362 1.2.6.2 tls
363 1.2.6.2 tls p[2] = __SHIFTIN(frame->itc? 1 : 0, __BIT(7));
364 1.2.6.2 tls p[2] |= __SHIFTIN(frame->extended_colorimetry, __BITS(6,4));
365 1.2.6.2 tls p[2] |= __SHIFTIN(frame->quantization_range, __BITS(3,2));
366 1.2.6.2 tls p[2] |= __SHIFTIN(frame->nups, __BITS(1,0));
367 1.2.6.2 tls
368 1.2.6.2 tls p[3] = frame->video_code;
369 1.2.6.2 tls
370 1.2.6.2 tls p[4] = __SHIFTIN(frame->ycc_quantization_range, __BITS(7,6));
371 1.2.6.2 tls p[4] |= __SHIFTIN(frame->content_type, __BITS(5,4));
372 1.2.6.2 tls p[4] |= __SHIFTIN(frame->pixel_repeat, __BITS(3,0));
373 1.2.6.2 tls
374 1.2.6.2 tls le16enc(&p[5], frame->top_bar);
375 1.2.6.2 tls le16enc(&p[7], frame->bottom_bar);
376 1.2.6.2 tls le16enc(&p[9], frame->left_bar);
377 1.2.6.2 tls le16enc(&p[11], frame->right_bar);
378 1.2.6.2 tls CTASSERT(HDMI_AVI_INFOFRAME_SIZE == 13);
379 1.2.6.2 tls
380 1.2.6.2 tls hdmi_infoframe_checksum(buf, length);
381 1.2.6.2 tls
382 1.2.6.2 tls return length;
383 1.2.6.2 tls }
384 1.2.6.2 tls
385 1.2.6.2 tls #define HDMI_SPD_INFOFRAME_SIZE 25
386 1.2.6.2 tls struct hdmi_spd_infoframe {
387 1.2.6.2 tls struct hdmi_infoframe_header header;
388 1.2.6.2 tls char vendor[8];
389 1.2.6.2 tls char product[16];
390 1.2.6.2 tls enum hdmi_spd_sdi {
391 1.2.6.2 tls HDMI_SPD_SDI_UNKNOWN = 0,
392 1.2.6.2 tls HDMI_SPD_SDI_DSTB = 1,
393 1.2.6.2 tls HDMI_SPD_SDI_DVDP = 2,
394 1.2.6.2 tls HDMI_SPD_SDI_DVHS = 3,
395 1.2.6.2 tls HDMI_SPD_SDI_HDDVR = 4,
396 1.2.6.2 tls HDMI_SPD_SDI_DVC = 5,
397 1.2.6.2 tls HDMI_SPD_SDI_DSC = 6,
398 1.2.6.2 tls HDMI_SPD_SDI_VCD = 7,
399 1.2.6.2 tls HDMI_SPD_SDI_GAME = 8,
400 1.2.6.2 tls HDMI_SPD_SDI_PC = 9,
401 1.2.6.2 tls HDMI_SPD_SDI_BD = 10,
402 1.2.6.2 tls HDMI_SPD_SDI_SACD = 11,
403 1.2.6.2 tls HDMI_SPD_SDI_HDDVD = 12,
404 1.2.6.2 tls HDMI_SPD_SDI_PMP = 13,
405 1.2.6.2 tls } sdi;
406 1.2.6.2 tls };
407 1.2.6.2 tls
408 1.2.6.2 tls static inline int
409 1.2.6.2 tls hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, const char *vendor,
410 1.2.6.2 tls const char *product)
411 1.2.6.2 tls {
412 1.2.6.2 tls static const struct hdmi_spd_infoframe zero_frame;
413 1.2.6.2 tls
414 1.2.6.2 tls *frame = zero_frame;
415 1.2.6.2 tls
416 1.2.6.2 tls hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_SPD,
417 1.2.6.2 tls 1, HDMI_SPD_INFOFRAME_SIZE);
418 1.2.6.2 tls
419 1.2.6.2 tls (void)strlcpy(frame->vendor, vendor, sizeof(frame->vendor));
420 1.2.6.2 tls (void)strlcpy(frame->product, product, sizeof(frame->product));
421 1.2.6.2 tls
422 1.2.6.2 tls return 0;
423 1.2.6.2 tls }
424 1.2.6.2 tls
425 1.2.6.2 tls static inline ssize_t
426 1.2.6.2 tls hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buf,
427 1.2.6.2 tls size_t size)
428 1.2.6.2 tls {
429 1.2.6.2 tls const size_t length = HDMI_INFOFRAME_HEADER_SIZE +
430 1.2.6.2 tls HDMI_SPD_INFOFRAME_SIZE;
431 1.2.6.2 tls uint8_t *p = buf;
432 1.2.6.2 tls int ret;
433 1.2.6.2 tls
434 1.2.6.2 tls KASSERT(frame->header.length == HDMI_SPD_INFOFRAME_SIZE);
435 1.2.6.2 tls
436 1.2.6.2 tls ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
437 1.2.6.2 tls if (ret < 0)
438 1.2.6.2 tls return ret;
439 1.2.6.3 jdolecek KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
440 1.2.6.2 tls p += HDMI_INFOFRAME_HEADER_SIZE;
441 1.2.6.2 tls size -= HDMI_INFOFRAME_HEADER_SIZE;
442 1.2.6.2 tls
443 1.2.6.2 tls (void)memcpy(&p[0], frame->vendor, 8);
444 1.2.6.2 tls (void)memcpy(&p[8], frame->product, 16);
445 1.2.6.2 tls p[24] = frame->sdi;
446 1.2.6.2 tls
447 1.2.6.2 tls hdmi_infoframe_checksum(buf, length);
448 1.2.6.2 tls
449 1.2.6.2 tls return length;
450 1.2.6.2 tls }
451 1.2.6.2 tls
452 1.2.6.2 tls #define HDMI_IEEE_OUI 0x000c03
453 1.2.6.2 tls
454 1.2.6.2 tls struct hdmi_vendor_infoframe {
455 1.2.6.2 tls struct hdmi_infoframe_header header;
456 1.2.6.2 tls uint32_t oui;
457 1.2.6.2 tls uint8_t vic;
458 1.2.6.2 tls enum hdmi_3d_structure s3d_struct;
459 1.2.6.2 tls unsigned s3d_ext_data;
460 1.2.6.2 tls };
461 1.2.6.2 tls
462 1.2.6.2 tls union hdmi_vendor_any_infoframe {
463 1.2.6.2 tls struct {
464 1.2.6.2 tls struct hdmi_infoframe_header header;
465 1.2.6.2 tls uint32_t oui;
466 1.2.6.2 tls } any;
467 1.2.6.2 tls struct hdmi_vendor_infoframe hdmi;
468 1.2.6.2 tls };
469 1.2.6.2 tls
470 1.2.6.2 tls static inline int
471 1.2.6.2 tls hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
472 1.2.6.2 tls {
473 1.2.6.2 tls static const struct hdmi_vendor_infoframe zero_frame;
474 1.2.6.2 tls
475 1.2.6.2 tls *frame = zero_frame;
476 1.2.6.2 tls
477 1.2.6.2 tls hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_VENDOR,
478 1.2.6.2 tls 1, 0 /* depends on s3d_struct */);
479 1.2.6.2 tls
480 1.2.6.2 tls frame->oui = HDMI_IEEE_OUI;
481 1.2.6.2 tls frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
482 1.2.6.2 tls
483 1.2.6.2 tls return 0;
484 1.2.6.2 tls }
485 1.2.6.2 tls
486 1.2.6.2 tls static inline int
487 1.2.6.2 tls hdmi_vendor_infoframe_pack(const struct hdmi_vendor_infoframe *frame,
488 1.2.6.2 tls void *buf, size_t size)
489 1.2.6.2 tls {
490 1.2.6.2 tls uint8_t *p = buf;
491 1.2.6.2 tls size_t length;
492 1.2.6.2 tls int ret;
493 1.2.6.2 tls
494 1.2.6.2 tls /* Exactly one must be supplied. */
495 1.2.6.2 tls if ((frame->vic == 0) ==
496 1.2.6.2 tls (frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID))
497 1.2.6.2 tls return -EINVAL;
498 1.2.6.2 tls
499 1.2.6.2 tls length = HDMI_INFOFRAME_HEADER_SIZE + 6;
500 1.2.6.2 tls if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
501 1.2.6.2 tls length += 1;
502 1.2.6.2 tls
503 1.2.6.2 tls ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
504 1.2.6.2 tls if (ret < 0)
505 1.2.6.2 tls return ret;
506 1.2.6.3 jdolecek KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
507 1.2.6.2 tls p += HDMI_INFOFRAME_HEADER_SIZE;
508 1.2.6.2 tls size -= HDMI_INFOFRAME_HEADER_SIZE;
509 1.2.6.2 tls
510 1.2.6.2 tls p[0] = 0x03;
511 1.2.6.2 tls p[1] = 0x0c;
512 1.2.6.2 tls p[2] = 0x00;
513 1.2.6.2 tls
514 1.2.6.2 tls if (frame->vic == 0) {
515 1.2.6.2 tls p[3] = __SHIFTIN(0x2, __BITS(6,5));
516 1.2.6.2 tls p[4] = __SHIFTIN(frame->s3d_struct, __BITS(7,4));
517 1.2.6.2 tls if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
518 1.2.6.2 tls p[9] = __SHIFTIN(frame->s3d_ext_data, __BITS(7,4));
519 1.2.6.2 tls } else {
520 1.2.6.2 tls p[3] = __SHIFTIN(0x1, __BITS(6,5));
521 1.2.6.2 tls p[4] = frame->vic;
522 1.2.6.2 tls }
523 1.2.6.2 tls
524 1.2.6.2 tls hdmi_infoframe_checksum(buf, length);
525 1.2.6.2 tls
526 1.2.6.2 tls return length;
527 1.2.6.2 tls }
528 1.2.6.2 tls
529 1.2.6.2 tls union hdmi_infoframe {
530 1.2.6.2 tls struct hdmi_infoframe_header any;
531 1.2.6.2 tls struct hdmi_avi_infoframe avi;
532 1.2.6.2 tls struct hdmi_spd_infoframe spd;
533 1.2.6.2 tls union hdmi_vendor_any_infoframe vendor;
534 1.2.6.2 tls };
535 1.2.6.2 tls
536 1.2.6.2 tls static inline ssize_t
537 1.2.6.2 tls hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buf, size_t size)
538 1.2.6.2 tls {
539 1.2.6.2 tls
540 1.2.6.2 tls switch (frame->any.type) {
541 1.2.6.2 tls case HDMI_INFOFRAME_TYPE_AVI:
542 1.2.6.2 tls return hdmi_avi_infoframe_pack(&frame->avi, buf, size);
543 1.2.6.2 tls case HDMI_INFOFRAME_TYPE_SPD:
544 1.2.6.2 tls return hdmi_spd_infoframe_pack(&frame->spd, buf, size);
545 1.2.6.2 tls case HDMI_INFOFRAME_TYPE_VENDOR:
546 1.2.6.2 tls return hdmi_vendor_infoframe_pack(&frame->vendor.hdmi, buf,
547 1.2.6.2 tls size);
548 1.2.6.2 tls default:
549 1.2.6.2 tls return -EINVAL;
550 1.2.6.2 tls }
551 1.2.6.2 tls }
552 1.2.6.2 tls
553 1.2.6.2 tls #endif /* _LINUX_HDMI_H_ */
554