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