Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/compat/linuxkpi/common/src/linux_hdmi.c
39586 views
1
/*
2
* Copyright (C) 2012 Avionic Design GmbH
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sub license,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the
12
* next paragraph) shall be included in all copies or substantial portions
13
* of the Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
* DEALINGS IN THE SOFTWARE.
22
*/
23
24
#ifdef __linux__
25
#include <drm/display/drm_dp.h>
26
#endif
27
#include <linux/bitops.h>
28
#include <linux/bug.h>
29
#include <linux/errno.h>
30
#include <linux/export.h>
31
#include <linux/hdmi.h>
32
#include <linux/string.h>
33
#include <linux/device.h>
34
35
#define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__)
36
37
static u8 hdmi_infoframe_checksum(const u8 *ptr, size_t size)
38
{
39
u8 csum = 0;
40
size_t i;
41
42
/* compute checksum */
43
for (i = 0; i < size; i++)
44
csum += ptr[i];
45
46
return 256 - csum;
47
}
48
49
static void hdmi_infoframe_set_checksum(void *buffer, size_t size)
50
{
51
u8 *ptr = buffer;
52
53
ptr[3] = hdmi_infoframe_checksum(buffer, size);
54
}
55
56
/**
57
* hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
58
* @frame: HDMI AVI infoframe
59
*/
60
void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
61
{
62
memset(frame, 0, sizeof(*frame));
63
64
frame->type = HDMI_INFOFRAME_TYPE_AVI;
65
frame->version = 2;
66
frame->length = HDMI_AVI_INFOFRAME_SIZE;
67
}
68
EXPORT_SYMBOL(hdmi_avi_infoframe_init);
69
70
static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame)
71
{
72
if (frame->type != HDMI_INFOFRAME_TYPE_AVI ||
73
frame->version != 2 ||
74
frame->length != HDMI_AVI_INFOFRAME_SIZE)
75
return -EINVAL;
76
77
if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
78
return -EINVAL;
79
80
return 0;
81
}
82
83
/**
84
* hdmi_avi_infoframe_check() - check a HDMI AVI infoframe
85
* @frame: HDMI AVI infoframe
86
*
87
* Validates that the infoframe is consistent and updates derived fields
88
* (eg. length) based on other fields.
89
*
90
* Returns 0 on success or a negative error code on failure.
91
*/
92
int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame)
93
{
94
return hdmi_avi_infoframe_check_only(frame);
95
}
96
EXPORT_SYMBOL(hdmi_avi_infoframe_check);
97
98
/**
99
* hdmi_avi_infoframe_pack_only() - write HDMI AVI infoframe to binary buffer
100
* @frame: HDMI AVI infoframe
101
* @buffer: destination buffer
102
* @size: size of buffer
103
*
104
* Packs the information contained in the @frame structure into a binary
105
* representation that can be written into the corresponding controller
106
* registers. Also computes the checksum as required by section 5.3.5 of
107
* the HDMI 1.4 specification.
108
*
109
* Returns the number of bytes packed into the binary buffer or a negative
110
* error code on failure.
111
*/
112
ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
113
void *buffer, size_t size)
114
{
115
u8 *ptr = buffer;
116
size_t length;
117
int ret;
118
119
ret = hdmi_avi_infoframe_check_only(frame);
120
if (ret)
121
return ret;
122
123
length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
124
125
if (size < length)
126
return -ENOSPC;
127
128
memset(buffer, 0, size);
129
130
ptr[0] = frame->type;
131
ptr[1] = frame->version;
132
ptr[2] = frame->length;
133
ptr[3] = 0; /* checksum */
134
135
/* start infoframe payload */
136
ptr += HDMI_INFOFRAME_HEADER_SIZE;
137
138
ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
139
140
/*
141
* Data byte 1, bit 4 has to be set if we provide the active format
142
* aspect ratio
143
*/
144
if (frame->active_aspect & 0xf)
145
ptr[0] |= BIT(4);
146
147
/* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */
148
if (frame->top_bar || frame->bottom_bar)
149
ptr[0] |= BIT(3);
150
151
if (frame->left_bar || frame->right_bar)
152
ptr[0] |= BIT(2);
153
154
ptr[1] = ((frame->colorimetry & 0x3) << 6) |
155
((frame->picture_aspect & 0x3) << 4) |
156
(frame->active_aspect & 0xf);
157
158
ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
159
((frame->quantization_range & 0x3) << 2) |
160
(frame->nups & 0x3);
161
162
if (frame->itc)
163
ptr[2] |= BIT(7);
164
165
ptr[3] = frame->video_code & 0x7f;
166
167
ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
168
((frame->content_type & 0x3) << 4) |
169
(frame->pixel_repeat & 0xf);
170
171
ptr[5] = frame->top_bar & 0xff;
172
ptr[6] = (frame->top_bar >> 8) & 0xff;
173
ptr[7] = frame->bottom_bar & 0xff;
174
ptr[8] = (frame->bottom_bar >> 8) & 0xff;
175
ptr[9] = frame->left_bar & 0xff;
176
ptr[10] = (frame->left_bar >> 8) & 0xff;
177
ptr[11] = frame->right_bar & 0xff;
178
ptr[12] = (frame->right_bar >> 8) & 0xff;
179
180
hdmi_infoframe_set_checksum(buffer, length);
181
182
return length;
183
}
184
EXPORT_SYMBOL(hdmi_avi_infoframe_pack_only);
185
186
/**
187
* hdmi_avi_infoframe_pack() - check a HDMI AVI infoframe,
188
* and write it to binary buffer
189
* @frame: HDMI AVI infoframe
190
* @buffer: destination buffer
191
* @size: size of buffer
192
*
193
* Validates that the infoframe is consistent and updates derived fields
194
* (eg. length) based on other fields, after which it packs the information
195
* contained in the @frame structure into a binary representation that
196
* can be written into the corresponding controller registers. This function
197
* also computes the checksum as required by section 5.3.5 of the HDMI 1.4
198
* specification.
199
*
200
* Returns the number of bytes packed into the binary buffer or a negative
201
* error code on failure.
202
*/
203
ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame,
204
void *buffer, size_t size)
205
{
206
int ret;
207
208
ret = hdmi_avi_infoframe_check(frame);
209
if (ret)
210
return ret;
211
212
return hdmi_avi_infoframe_pack_only(frame, buffer, size);
213
}
214
EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
215
216
/**
217
* hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
218
* @frame: HDMI SPD infoframe
219
* @vendor: vendor string
220
* @product: product string
221
*
222
* Returns 0 on success or a negative error code on failure.
223
*/
224
int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
225
const char *vendor, const char *product)
226
{
227
size_t len;
228
229
memset(frame, 0, sizeof(*frame));
230
231
frame->type = HDMI_INFOFRAME_TYPE_SPD;
232
frame->version = 1;
233
frame->length = HDMI_SPD_INFOFRAME_SIZE;
234
235
len = strlen(vendor);
236
memcpy(frame->vendor, vendor, min(len, sizeof(frame->vendor)));
237
len = strlen(product);
238
memcpy(frame->product, product, min(len, sizeof(frame->product)));
239
240
return 0;
241
}
242
EXPORT_SYMBOL(hdmi_spd_infoframe_init);
243
244
static int hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe *frame)
245
{
246
if (frame->type != HDMI_INFOFRAME_TYPE_SPD ||
247
frame->version != 1 ||
248
frame->length != HDMI_SPD_INFOFRAME_SIZE)
249
return -EINVAL;
250
251
return 0;
252
}
253
254
/**
255
* hdmi_spd_infoframe_check() - check a HDMI SPD infoframe
256
* @frame: HDMI SPD infoframe
257
*
258
* Validates that the infoframe is consistent and updates derived fields
259
* (eg. length) based on other fields.
260
*
261
* Returns 0 on success or a negative error code on failure.
262
*/
263
int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame)
264
{
265
return hdmi_spd_infoframe_check_only(frame);
266
}
267
EXPORT_SYMBOL(hdmi_spd_infoframe_check);
268
269
/**
270
* hdmi_spd_infoframe_pack_only() - write HDMI SPD infoframe to binary buffer
271
* @frame: HDMI SPD infoframe
272
* @buffer: destination buffer
273
* @size: size of buffer
274
*
275
* Packs the information contained in the @frame structure into a binary
276
* representation that can be written into the corresponding controller
277
* registers. Also computes the checksum as required by section 5.3.5 of
278
* the HDMI 1.4 specification.
279
*
280
* Returns the number of bytes packed into the binary buffer or a negative
281
* error code on failure.
282
*/
283
ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame,
284
void *buffer, size_t size)
285
{
286
u8 *ptr = buffer;
287
size_t length;
288
int ret;
289
290
ret = hdmi_spd_infoframe_check_only(frame);
291
if (ret)
292
return ret;
293
294
length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
295
296
if (size < length)
297
return -ENOSPC;
298
299
memset(buffer, 0, size);
300
301
ptr[0] = frame->type;
302
ptr[1] = frame->version;
303
ptr[2] = frame->length;
304
ptr[3] = 0; /* checksum */
305
306
/* start infoframe payload */
307
ptr += HDMI_INFOFRAME_HEADER_SIZE;
308
309
memcpy(ptr, frame->vendor, sizeof(frame->vendor));
310
memcpy(ptr + 8, frame->product, sizeof(frame->product));
311
312
ptr[24] = frame->sdi;
313
314
hdmi_infoframe_set_checksum(buffer, length);
315
316
return length;
317
}
318
EXPORT_SYMBOL(hdmi_spd_infoframe_pack_only);
319
320
/**
321
* hdmi_spd_infoframe_pack() - check a HDMI SPD infoframe,
322
* and write it to binary buffer
323
* @frame: HDMI SPD infoframe
324
* @buffer: destination buffer
325
* @size: size of buffer
326
*
327
* Validates that the infoframe is consistent and updates derived fields
328
* (eg. length) based on other fields, after which it packs the information
329
* contained in the @frame structure into a binary representation that
330
* can be written into the corresponding controller registers. This function
331
* also computes the checksum as required by section 5.3.5 of the HDMI 1.4
332
* specification.
333
*
334
* Returns the number of bytes packed into the binary buffer or a negative
335
* error code on failure.
336
*/
337
ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame,
338
void *buffer, size_t size)
339
{
340
int ret;
341
342
ret = hdmi_spd_infoframe_check(frame);
343
if (ret)
344
return ret;
345
346
return hdmi_spd_infoframe_pack_only(frame, buffer, size);
347
}
348
EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
349
350
/**
351
* hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
352
* @frame: HDMI audio infoframe
353
*
354
* Returns 0 on success or a negative error code on failure.
355
*/
356
int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
357
{
358
memset(frame, 0, sizeof(*frame));
359
360
frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
361
frame->version = 1;
362
frame->length = HDMI_AUDIO_INFOFRAME_SIZE;
363
364
return 0;
365
}
366
EXPORT_SYMBOL(hdmi_audio_infoframe_init);
367
368
static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *frame)
369
{
370
if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO ||
371
frame->version != 1 ||
372
frame->length != HDMI_AUDIO_INFOFRAME_SIZE)
373
return -EINVAL;
374
375
return 0;
376
}
377
378
/**
379
* hdmi_audio_infoframe_check() - check a HDMI audio infoframe
380
* @frame: HDMI audio infoframe
381
*
382
* Validates that the infoframe is consistent and updates derived fields
383
* (eg. length) based on other fields.
384
*
385
* Returns 0 on success or a negative error code on failure.
386
*/
387
int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
388
{
389
return hdmi_audio_infoframe_check_only(frame);
390
}
391
EXPORT_SYMBOL(hdmi_audio_infoframe_check);
392
393
static void
394
hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
395
u8 *buffer)
396
{
397
u8 channels;
398
399
if (frame->channels >= 2)
400
channels = frame->channels - 1;
401
else
402
channels = 0;
403
404
buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
405
buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
406
(frame->sample_size & 0x3);
407
buffer[2] = frame->coding_type_ext & 0x1f;
408
buffer[3] = frame->channel_allocation;
409
buffer[4] = (frame->level_shift_value & 0xf) << 3;
410
411
if (frame->downmix_inhibit)
412
buffer[4] |= BIT(7);
413
}
414
415
/**
416
* hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer
417
* @frame: HDMI audio infoframe
418
* @buffer: destination buffer
419
* @size: size of buffer
420
*
421
* Packs the information contained in the @frame structure into a binary
422
* representation that can be written into the corresponding controller
423
* registers. Also computes the checksum as required by section 5.3.5 of
424
* the HDMI 1.4 specification.
425
*
426
* Returns the number of bytes packed into the binary buffer or a negative
427
* error code on failure.
428
*/
429
ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
430
void *buffer, size_t size)
431
{
432
u8 *ptr = buffer;
433
size_t length;
434
int ret;
435
436
ret = hdmi_audio_infoframe_check_only(frame);
437
if (ret)
438
return ret;
439
440
length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
441
442
if (size < length)
443
return -ENOSPC;
444
445
memset(buffer, 0, size);
446
447
ptr[0] = frame->type;
448
ptr[1] = frame->version;
449
ptr[2] = frame->length;
450
ptr[3] = 0; /* checksum */
451
452
hdmi_audio_infoframe_pack_payload(frame,
453
ptr + HDMI_INFOFRAME_HEADER_SIZE);
454
455
hdmi_infoframe_set_checksum(buffer, length);
456
457
return length;
458
}
459
EXPORT_SYMBOL(hdmi_audio_infoframe_pack_only);
460
461
/**
462
* hdmi_audio_infoframe_pack() - check a HDMI Audio infoframe,
463
* and write it to binary buffer
464
* @frame: HDMI Audio infoframe
465
* @buffer: destination buffer
466
* @size: size of buffer
467
*
468
* Validates that the infoframe is consistent and updates derived fields
469
* (eg. length) based on other fields, after which it packs the information
470
* contained in the @frame structure into a binary representation that
471
* can be written into the corresponding controller registers. This function
472
* also computes the checksum as required by section 5.3.5 of the HDMI 1.4
473
* specification.
474
*
475
* Returns the number of bytes packed into the binary buffer or a negative
476
* error code on failure.
477
*/
478
ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
479
void *buffer, size_t size)
480
{
481
int ret;
482
483
ret = hdmi_audio_infoframe_check(frame);
484
if (ret)
485
return ret;
486
487
return hdmi_audio_infoframe_pack_only(frame, buffer, size);
488
}
489
EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
490
491
#ifdef __linux__
492
/**
493
* hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for DisplayPort
494
*
495
* @frame: HDMI Audio infoframe
496
* @sdp: Secondary data packet for DisplayPort.
497
* @dp_version: DisplayPort version to be encoded in the header
498
*
499
* Packs a HDMI Audio Infoframe to be sent over DisplayPort. This function
500
* fills the secondary data packet to be used for DisplayPort.
501
*
502
* Return: Number of total written bytes or a negative errno on failure.
503
*/
504
ssize_t
505
hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
506
struct dp_sdp *sdp, u8 dp_version)
507
{
508
int ret;
509
510
ret = hdmi_audio_infoframe_check(frame);
511
if (ret)
512
return ret;
513
514
memset(sdp->db, 0, sizeof(sdp->db));
515
516
/* Secondary-data packet header */
517
sdp->sdp_header.HB0 = 0;
518
sdp->sdp_header.HB1 = frame->type;
519
sdp->sdp_header.HB2 = DP_SDP_AUDIO_INFOFRAME_HB2;
520
sdp->sdp_header.HB3 = (dp_version & 0x3f) << 2;
521
522
hdmi_audio_infoframe_pack_payload(frame, sdp->db);
523
524
/* Return size = frame length + four HB for sdp_header */
525
return frame->length + 4;
526
}
527
EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
528
#endif
529
530
/**
531
* hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
532
* @frame: HDMI vendor infoframe
533
*
534
* Returns 0 on success or a negative error code on failure.
535
*/
536
int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
537
{
538
memset(frame, 0, sizeof(*frame));
539
540
frame->type = HDMI_INFOFRAME_TYPE_VENDOR;
541
frame->version = 1;
542
543
frame->oui = HDMI_IEEE_OUI;
544
545
/*
546
* 0 is a valid value for s3d_struct, so we use a special "not set"
547
* value
548
*/
549
frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
550
frame->length = HDMI_VENDOR_INFOFRAME_SIZE;
551
552
return 0;
553
}
554
EXPORT_SYMBOL(hdmi_vendor_infoframe_init);
555
556
static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *frame)
557
{
558
/* for side by side (half) we also need to provide 3D_Ext_Data */
559
if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
560
return 6;
561
else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
562
return 5;
563
else
564
return 4;
565
}
566
567
static int hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe *frame)
568
{
569
if (frame->type != HDMI_INFOFRAME_TYPE_VENDOR ||
570
frame->version != 1 ||
571
frame->oui != HDMI_IEEE_OUI)
572
return -EINVAL;
573
574
/* only one of those can be supplied */
575
if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
576
return -EINVAL;
577
578
if (frame->length != hdmi_vendor_infoframe_length(frame))
579
return -EINVAL;
580
581
return 0;
582
}
583
584
/**
585
* hdmi_vendor_infoframe_check() - check a HDMI vendor infoframe
586
* @frame: HDMI infoframe
587
*
588
* Validates that the infoframe is consistent and updates derived fields
589
* (eg. length) based on other fields.
590
*
591
* Returns 0 on success or a negative error code on failure.
592
*/
593
int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame)
594
{
595
frame->length = hdmi_vendor_infoframe_length(frame);
596
597
return hdmi_vendor_infoframe_check_only(frame);
598
}
599
EXPORT_SYMBOL(hdmi_vendor_infoframe_check);
600
601
/**
602
* hdmi_vendor_infoframe_pack_only() - write a HDMI vendor infoframe to binary buffer
603
* @frame: HDMI infoframe
604
* @buffer: destination buffer
605
* @size: size of buffer
606
*
607
* Packs the information contained in the @frame structure into a binary
608
* representation that can be written into the corresponding controller
609
* registers. Also computes the checksum as required by section 5.3.5 of
610
* the HDMI 1.4 specification.
611
*
612
* Returns the number of bytes packed into the binary buffer or a negative
613
* error code on failure.
614
*/
615
ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame,
616
void *buffer, size_t size)
617
{
618
u8 *ptr = buffer;
619
size_t length;
620
int ret;
621
622
ret = hdmi_vendor_infoframe_check_only(frame);
623
if (ret)
624
return ret;
625
626
length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
627
628
if (size < length)
629
return -ENOSPC;
630
631
memset(buffer, 0, size);
632
633
ptr[0] = frame->type;
634
ptr[1] = frame->version;
635
ptr[2] = frame->length;
636
ptr[3] = 0; /* checksum */
637
638
/* HDMI OUI */
639
ptr[4] = 0x03;
640
ptr[5] = 0x0c;
641
ptr[6] = 0x00;
642
643
if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
644
ptr[7] = 0x2 << 5; /* video format */
645
ptr[8] = (frame->s3d_struct & 0xf) << 4;
646
if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
647
ptr[9] = (frame->s3d_ext_data & 0xf) << 4;
648
} else if (frame->vic) {
649
ptr[7] = 0x1 << 5; /* video format */
650
ptr[8] = frame->vic;
651
} else {
652
ptr[7] = 0x0 << 5; /* video format */
653
}
654
655
hdmi_infoframe_set_checksum(buffer, length);
656
657
return length;
658
}
659
EXPORT_SYMBOL(hdmi_vendor_infoframe_pack_only);
660
661
/**
662
* hdmi_vendor_infoframe_pack() - check a HDMI Vendor infoframe,
663
* and write it to binary buffer
664
* @frame: HDMI Vendor infoframe
665
* @buffer: destination buffer
666
* @size: size of buffer
667
*
668
* Validates that the infoframe is consistent and updates derived fields
669
* (eg. length) based on other fields, after which it packs the information
670
* contained in the @frame structure into a binary representation that
671
* can be written into the corresponding controller registers. This function
672
* also computes the checksum as required by section 5.3.5 of the HDMI 1.4
673
* specification.
674
*
675
* Returns the number of bytes packed into the binary buffer or a negative
676
* error code on failure.
677
*/
678
ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
679
void *buffer, size_t size)
680
{
681
int ret;
682
683
ret = hdmi_vendor_infoframe_check(frame);
684
if (ret)
685
return ret;
686
687
return hdmi_vendor_infoframe_pack_only(frame, buffer, size);
688
}
689
EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
690
691
static int
692
hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *frame)
693
{
694
if (frame->any.type != HDMI_INFOFRAME_TYPE_VENDOR ||
695
frame->any.version != 1)
696
return -EINVAL;
697
698
return 0;
699
}
700
701
/**
702
* hdmi_drm_infoframe_init() - initialize an HDMI Dynaminc Range and
703
* mastering infoframe
704
* @frame: HDMI DRM infoframe
705
*
706
* Returns 0 on success or a negative error code on failure.
707
*/
708
int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame)
709
{
710
memset(frame, 0, sizeof(*frame));
711
712
frame->type = HDMI_INFOFRAME_TYPE_DRM;
713
frame->version = 1;
714
frame->length = HDMI_DRM_INFOFRAME_SIZE;
715
716
return 0;
717
}
718
EXPORT_SYMBOL(hdmi_drm_infoframe_init);
719
720
static int hdmi_drm_infoframe_check_only(const struct hdmi_drm_infoframe *frame)
721
{
722
if (frame->type != HDMI_INFOFRAME_TYPE_DRM ||
723
frame->version != 1)
724
return -EINVAL;
725
726
if (frame->length != HDMI_DRM_INFOFRAME_SIZE)
727
return -EINVAL;
728
729
return 0;
730
}
731
732
/**
733
* hdmi_drm_infoframe_check() - check a HDMI DRM infoframe
734
* @frame: HDMI DRM infoframe
735
*
736
* Validates that the infoframe is consistent.
737
* Returns 0 on success or a negative error code on failure.
738
*/
739
int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame)
740
{
741
return hdmi_drm_infoframe_check_only(frame);
742
}
743
EXPORT_SYMBOL(hdmi_drm_infoframe_check);
744
745
/**
746
* hdmi_drm_infoframe_pack_only() - write HDMI DRM infoframe to binary buffer
747
* @frame: HDMI DRM infoframe
748
* @buffer: destination buffer
749
* @size: size of buffer
750
*
751
* Packs the information contained in the @frame structure into a binary
752
* representation that can be written into the corresponding controller
753
* registers. Also computes the checksum as required by section 5.3.5 of
754
* the HDMI 1.4 specification.
755
*
756
* Returns the number of bytes packed into the binary buffer or a negative
757
* error code on failure.
758
*/
759
ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame,
760
void *buffer, size_t size)
761
{
762
u8 *ptr = buffer;
763
size_t length;
764
int i;
765
766
length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
767
768
if (size < length)
769
return -ENOSPC;
770
771
memset(buffer, 0, size);
772
773
ptr[0] = frame->type;
774
ptr[1] = frame->version;
775
ptr[2] = frame->length;
776
ptr[3] = 0; /* checksum */
777
778
/* start infoframe payload */
779
ptr += HDMI_INFOFRAME_HEADER_SIZE;
780
781
*ptr++ = frame->eotf;
782
*ptr++ = frame->metadata_type;
783
784
for (i = 0; i < 3; i++) {
785
*ptr++ = frame->display_primaries[i].x;
786
*ptr++ = frame->display_primaries[i].x >> 8;
787
*ptr++ = frame->display_primaries[i].y;
788
*ptr++ = frame->display_primaries[i].y >> 8;
789
}
790
791
*ptr++ = frame->white_point.x;
792
*ptr++ = frame->white_point.x >> 8;
793
794
*ptr++ = frame->white_point.y;
795
*ptr++ = frame->white_point.y >> 8;
796
797
*ptr++ = frame->max_display_mastering_luminance;
798
*ptr++ = frame->max_display_mastering_luminance >> 8;
799
800
*ptr++ = frame->min_display_mastering_luminance;
801
*ptr++ = frame->min_display_mastering_luminance >> 8;
802
803
*ptr++ = frame->max_cll;
804
*ptr++ = frame->max_cll >> 8;
805
806
*ptr++ = frame->max_fall;
807
*ptr++ = frame->max_fall >> 8;
808
809
hdmi_infoframe_set_checksum(buffer, length);
810
811
return length;
812
}
813
EXPORT_SYMBOL(hdmi_drm_infoframe_pack_only);
814
815
/**
816
* hdmi_drm_infoframe_pack() - check a HDMI DRM infoframe,
817
* and write it to binary buffer
818
* @frame: HDMI DRM infoframe
819
* @buffer: destination buffer
820
* @size: size of buffer
821
*
822
* Validates that the infoframe is consistent and updates derived fields
823
* (eg. length) based on other fields, after which it packs the information
824
* contained in the @frame structure into a binary representation that
825
* can be written into the corresponding controller registers. This function
826
* also computes the checksum as required by section 5.3.5 of the HDMI 1.4
827
* specification.
828
*
829
* Returns the number of bytes packed into the binary buffer or a negative
830
* error code on failure.
831
*/
832
ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame,
833
void *buffer, size_t size)
834
{
835
int ret;
836
837
ret = hdmi_drm_infoframe_check(frame);
838
if (ret)
839
return ret;
840
841
return hdmi_drm_infoframe_pack_only(frame, buffer, size);
842
}
843
EXPORT_SYMBOL(hdmi_drm_infoframe_pack);
844
845
/*
846
* hdmi_vendor_any_infoframe_check() - check a vendor infoframe
847
*/
848
static int
849
hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe *frame)
850
{
851
int ret;
852
853
ret = hdmi_vendor_any_infoframe_check_only(frame);
854
if (ret)
855
return ret;
856
857
/* we only know about HDMI vendor infoframes */
858
if (frame->any.oui != HDMI_IEEE_OUI)
859
return -EINVAL;
860
861
return hdmi_vendor_infoframe_check(&frame->hdmi);
862
}
863
864
/*
865
* hdmi_vendor_any_infoframe_pack_only() - write a vendor infoframe to binary buffer
866
*/
867
static ssize_t
868
hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe *frame,
869
void *buffer, size_t size)
870
{
871
int ret;
872
873
ret = hdmi_vendor_any_infoframe_check_only(frame);
874
if (ret)
875
return ret;
876
877
/* we only know about HDMI vendor infoframes */
878
if (frame->any.oui != HDMI_IEEE_OUI)
879
return -EINVAL;
880
881
return hdmi_vendor_infoframe_pack_only(&frame->hdmi, buffer, size);
882
}
883
884
/*
885
* hdmi_vendor_any_infoframe_pack() - check a vendor infoframe,
886
* and write it to binary buffer
887
*/
888
static ssize_t
889
hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
890
void *buffer, size_t size)
891
{
892
int ret;
893
894
ret = hdmi_vendor_any_infoframe_check(frame);
895
if (ret)
896
return ret;
897
898
return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size);
899
}
900
901
/**
902
* hdmi_infoframe_check() - check a HDMI infoframe
903
* @frame: HDMI infoframe
904
*
905
* Validates that the infoframe is consistent and updates derived fields
906
* (eg. length) based on other fields.
907
*
908
* Returns 0 on success or a negative error code on failure.
909
*/
910
int
911
hdmi_infoframe_check(union hdmi_infoframe *frame)
912
{
913
switch (frame->any.type) {
914
case HDMI_INFOFRAME_TYPE_AVI:
915
return hdmi_avi_infoframe_check(&frame->avi);
916
case HDMI_INFOFRAME_TYPE_SPD:
917
return hdmi_spd_infoframe_check(&frame->spd);
918
case HDMI_INFOFRAME_TYPE_AUDIO:
919
return hdmi_audio_infoframe_check(&frame->audio);
920
case HDMI_INFOFRAME_TYPE_VENDOR:
921
return hdmi_vendor_any_infoframe_check(&frame->vendor);
922
default:
923
WARN(1, "Bad infoframe type %d\n", frame->any.type);
924
return -EINVAL;
925
}
926
}
927
EXPORT_SYMBOL(hdmi_infoframe_check);
928
929
/**
930
* hdmi_infoframe_pack_only() - write a HDMI infoframe to binary buffer
931
* @frame: HDMI infoframe
932
* @buffer: destination buffer
933
* @size: size of buffer
934
*
935
* Packs the information contained in the @frame structure into a binary
936
* representation that can be written into the corresponding controller
937
* registers. Also computes the checksum as required by section 5.3.5 of
938
* the HDMI 1.4 specification.
939
*
940
* Returns the number of bytes packed into the binary buffer or a negative
941
* error code on failure.
942
*/
943
ssize_t
944
hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size)
945
{
946
ssize_t length;
947
948
switch (frame->any.type) {
949
case HDMI_INFOFRAME_TYPE_AVI:
950
length = hdmi_avi_infoframe_pack_only(&frame->avi,
951
buffer, size);
952
break;
953
case HDMI_INFOFRAME_TYPE_DRM:
954
length = hdmi_drm_infoframe_pack_only(&frame->drm,
955
buffer, size);
956
break;
957
case HDMI_INFOFRAME_TYPE_SPD:
958
length = hdmi_spd_infoframe_pack_only(&frame->spd,
959
buffer, size);
960
break;
961
case HDMI_INFOFRAME_TYPE_AUDIO:
962
length = hdmi_audio_infoframe_pack_only(&frame->audio,
963
buffer, size);
964
break;
965
case HDMI_INFOFRAME_TYPE_VENDOR:
966
length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor,
967
buffer, size);
968
break;
969
default:
970
WARN(1, "Bad infoframe type %d\n", frame->any.type);
971
length = -EINVAL;
972
}
973
974
return length;
975
}
976
EXPORT_SYMBOL(hdmi_infoframe_pack_only);
977
978
/**
979
* hdmi_infoframe_pack() - check a HDMI infoframe,
980
* and write it to binary buffer
981
* @frame: HDMI infoframe
982
* @buffer: destination buffer
983
* @size: size of buffer
984
*
985
* Validates that the infoframe is consistent and updates derived fields
986
* (eg. length) based on other fields, after which it packs the information
987
* contained in the @frame structure into a binary representation that
988
* can be written into the corresponding controller registers. This function
989
* also computes the checksum as required by section 5.3.5 of the HDMI 1.4
990
* specification.
991
*
992
* Returns the number of bytes packed into the binary buffer or a negative
993
* error code on failure.
994
*/
995
ssize_t
996
hdmi_infoframe_pack(union hdmi_infoframe *frame,
997
void *buffer, size_t size)
998
{
999
ssize_t length;
1000
1001
switch (frame->any.type) {
1002
case HDMI_INFOFRAME_TYPE_AVI:
1003
length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size);
1004
break;
1005
case HDMI_INFOFRAME_TYPE_DRM:
1006
length = hdmi_drm_infoframe_pack(&frame->drm, buffer, size);
1007
break;
1008
case HDMI_INFOFRAME_TYPE_SPD:
1009
length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size);
1010
break;
1011
case HDMI_INFOFRAME_TYPE_AUDIO:
1012
length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size);
1013
break;
1014
case HDMI_INFOFRAME_TYPE_VENDOR:
1015
length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
1016
buffer, size);
1017
break;
1018
default:
1019
WARN(1, "Bad infoframe type %d\n", frame->any.type);
1020
length = -EINVAL;
1021
}
1022
1023
return length;
1024
}
1025
EXPORT_SYMBOL(hdmi_infoframe_pack);
1026
1027
static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
1028
{
1029
if (type < 0x80 || type > 0x9f)
1030
return "Invalid";
1031
switch (type) {
1032
case HDMI_INFOFRAME_TYPE_VENDOR:
1033
return "Vendor";
1034
case HDMI_INFOFRAME_TYPE_AVI:
1035
return "Auxiliary Video Information (AVI)";
1036
case HDMI_INFOFRAME_TYPE_SPD:
1037
return "Source Product Description (SPD)";
1038
case HDMI_INFOFRAME_TYPE_AUDIO:
1039
return "Audio";
1040
case HDMI_INFOFRAME_TYPE_DRM:
1041
return "Dynamic Range and Mastering";
1042
}
1043
return "Reserved";
1044
}
1045
1046
static void hdmi_infoframe_log_header(const char *level,
1047
struct device *dev,
1048
const struct hdmi_any_infoframe *frame)
1049
{
1050
hdmi_log("HDMI infoframe: %s, version %u, length %u\n",
1051
hdmi_infoframe_type_get_name(frame->type),
1052
frame->version, frame->length);
1053
}
1054
1055
static const char *hdmi_colorspace_get_name(enum hdmi_colorspace colorspace)
1056
{
1057
switch (colorspace) {
1058
case HDMI_COLORSPACE_RGB:
1059
return "RGB";
1060
case HDMI_COLORSPACE_YUV422:
1061
return "YCbCr 4:2:2";
1062
case HDMI_COLORSPACE_YUV444:
1063
return "YCbCr 4:4:4";
1064
case HDMI_COLORSPACE_YUV420:
1065
return "YCbCr 4:2:0";
1066
case HDMI_COLORSPACE_RESERVED4:
1067
return "Reserved (4)";
1068
case HDMI_COLORSPACE_RESERVED5:
1069
return "Reserved (5)";
1070
case HDMI_COLORSPACE_RESERVED6:
1071
return "Reserved (6)";
1072
case HDMI_COLORSPACE_IDO_DEFINED:
1073
return "IDO Defined";
1074
}
1075
return "Invalid";
1076
}
1077
1078
static const char *hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode)
1079
{
1080
switch (scan_mode) {
1081
case HDMI_SCAN_MODE_NONE:
1082
return "No Data";
1083
case HDMI_SCAN_MODE_OVERSCAN:
1084
return "Overscan";
1085
case HDMI_SCAN_MODE_UNDERSCAN:
1086
return "Underscan";
1087
case HDMI_SCAN_MODE_RESERVED:
1088
return "Reserved";
1089
}
1090
return "Invalid";
1091
}
1092
1093
static const char *hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry)
1094
{
1095
switch (colorimetry) {
1096
case HDMI_COLORIMETRY_NONE:
1097
return "No Data";
1098
case HDMI_COLORIMETRY_ITU_601:
1099
return "ITU601";
1100
case HDMI_COLORIMETRY_ITU_709:
1101
return "ITU709";
1102
case HDMI_COLORIMETRY_EXTENDED:
1103
return "Extended";
1104
}
1105
return "Invalid";
1106
}
1107
1108
static const char *
1109
hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect)
1110
{
1111
switch (picture_aspect) {
1112
case HDMI_PICTURE_ASPECT_NONE:
1113
return "No Data";
1114
case HDMI_PICTURE_ASPECT_4_3:
1115
return "4:3";
1116
case HDMI_PICTURE_ASPECT_16_9:
1117
return "16:9";
1118
case HDMI_PICTURE_ASPECT_64_27:
1119
return "64:27";
1120
case HDMI_PICTURE_ASPECT_256_135:
1121
return "256:135";
1122
case HDMI_PICTURE_ASPECT_RESERVED:
1123
return "Reserved";
1124
}
1125
return "Invalid";
1126
}
1127
1128
static const char *
1129
hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect)
1130
{
1131
if (active_aspect < 0 || active_aspect > 0xf)
1132
return "Invalid";
1133
1134
switch (active_aspect) {
1135
case HDMI_ACTIVE_ASPECT_16_9_TOP:
1136
return "16:9 Top";
1137
case HDMI_ACTIVE_ASPECT_14_9_TOP:
1138
return "14:9 Top";
1139
case HDMI_ACTIVE_ASPECT_16_9_CENTER:
1140
return "16:9 Center";
1141
case HDMI_ACTIVE_ASPECT_PICTURE:
1142
return "Same as Picture";
1143
case HDMI_ACTIVE_ASPECT_4_3:
1144
return "4:3";
1145
case HDMI_ACTIVE_ASPECT_16_9:
1146
return "16:9";
1147
case HDMI_ACTIVE_ASPECT_14_9:
1148
return "14:9";
1149
case HDMI_ACTIVE_ASPECT_4_3_SP_14_9:
1150
return "4:3 SP 14:9";
1151
case HDMI_ACTIVE_ASPECT_16_9_SP_14_9:
1152
return "16:9 SP 14:9";
1153
case HDMI_ACTIVE_ASPECT_16_9_SP_4_3:
1154
return "16:9 SP 4:3";
1155
}
1156
return "Reserved";
1157
}
1158
1159
static const char *
1160
hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col)
1161
{
1162
switch (ext_col) {
1163
case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601:
1164
return "xvYCC 601";
1165
case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709:
1166
return "xvYCC 709";
1167
case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
1168
return "sYCC 601";
1169
case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
1170
return "opYCC 601";
1171
case HDMI_EXTENDED_COLORIMETRY_OPRGB:
1172
return "opRGB";
1173
case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
1174
return "BT.2020 Constant Luminance";
1175
case HDMI_EXTENDED_COLORIMETRY_BT2020:
1176
return "BT.2020";
1177
case HDMI_EXTENDED_COLORIMETRY_RESERVED:
1178
return "Reserved";
1179
}
1180
return "Invalid";
1181
}
1182
1183
static const char *
1184
hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange)
1185
{
1186
switch (qrange) {
1187
case HDMI_QUANTIZATION_RANGE_DEFAULT:
1188
return "Default";
1189
case HDMI_QUANTIZATION_RANGE_LIMITED:
1190
return "Limited";
1191
case HDMI_QUANTIZATION_RANGE_FULL:
1192
return "Full";
1193
case HDMI_QUANTIZATION_RANGE_RESERVED:
1194
return "Reserved";
1195
}
1196
return "Invalid";
1197
}
1198
1199
static const char *hdmi_nups_get_name(enum hdmi_nups nups)
1200
{
1201
switch (nups) {
1202
case HDMI_NUPS_UNKNOWN:
1203
return "Unknown Non-uniform Scaling";
1204
case HDMI_NUPS_HORIZONTAL:
1205
return "Horizontally Scaled";
1206
case HDMI_NUPS_VERTICAL:
1207
return "Vertically Scaled";
1208
case HDMI_NUPS_BOTH:
1209
return "Horizontally and Vertically Scaled";
1210
}
1211
return "Invalid";
1212
}
1213
1214
static const char *
1215
hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange)
1216
{
1217
switch (qrange) {
1218
case HDMI_YCC_QUANTIZATION_RANGE_LIMITED:
1219
return "Limited";
1220
case HDMI_YCC_QUANTIZATION_RANGE_FULL:
1221
return "Full";
1222
}
1223
return "Invalid";
1224
}
1225
1226
static const char *
1227
hdmi_content_type_get_name(enum hdmi_content_type content_type)
1228
{
1229
switch (content_type) {
1230
case HDMI_CONTENT_TYPE_GRAPHICS:
1231
return "Graphics";
1232
case HDMI_CONTENT_TYPE_PHOTO:
1233
return "Photo";
1234
case HDMI_CONTENT_TYPE_CINEMA:
1235
return "Cinema";
1236
case HDMI_CONTENT_TYPE_GAME:
1237
return "Game";
1238
}
1239
return "Invalid";
1240
}
1241
1242
static void hdmi_avi_infoframe_log(const char *level,
1243
struct device *dev,
1244
const struct hdmi_avi_infoframe *frame)
1245
{
1246
hdmi_infoframe_log_header(level, dev,
1247
(const struct hdmi_any_infoframe *)frame);
1248
1249
hdmi_log(" colorspace: %s\n",
1250
hdmi_colorspace_get_name(frame->colorspace));
1251
hdmi_log(" scan mode: %s\n",
1252
hdmi_scan_mode_get_name(frame->scan_mode));
1253
hdmi_log(" colorimetry: %s\n",
1254
hdmi_colorimetry_get_name(frame->colorimetry));
1255
hdmi_log(" picture aspect: %s\n",
1256
hdmi_picture_aspect_get_name(frame->picture_aspect));
1257
hdmi_log(" active aspect: %s\n",
1258
hdmi_active_aspect_get_name(frame->active_aspect));
1259
hdmi_log(" itc: %s\n", frame->itc ? "IT Content" : "No Data");
1260
hdmi_log(" extended colorimetry: %s\n",
1261
hdmi_extended_colorimetry_get_name(frame->extended_colorimetry));
1262
hdmi_log(" quantization range: %s\n",
1263
hdmi_quantization_range_get_name(frame->quantization_range));
1264
hdmi_log(" nups: %s\n", hdmi_nups_get_name(frame->nups));
1265
hdmi_log(" video code: %u\n", frame->video_code);
1266
hdmi_log(" ycc quantization range: %s\n",
1267
hdmi_ycc_quantization_range_get_name(frame->ycc_quantization_range));
1268
hdmi_log(" hdmi content type: %s\n",
1269
hdmi_content_type_get_name(frame->content_type));
1270
hdmi_log(" pixel repeat: %u\n", frame->pixel_repeat);
1271
hdmi_log(" bar top %u, bottom %u, left %u, right %u\n",
1272
frame->top_bar, frame->bottom_bar,
1273
frame->left_bar, frame->right_bar);
1274
}
1275
1276
static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi)
1277
{
1278
if (sdi < 0 || sdi > 0xff)
1279
return "Invalid";
1280
switch (sdi) {
1281
case HDMI_SPD_SDI_UNKNOWN:
1282
return "Unknown";
1283
case HDMI_SPD_SDI_DSTB:
1284
return "Digital STB";
1285
case HDMI_SPD_SDI_DVDP:
1286
return "DVD Player";
1287
case HDMI_SPD_SDI_DVHS:
1288
return "D-VHS";
1289
case HDMI_SPD_SDI_HDDVR:
1290
return "HDD Videorecorder";
1291
case HDMI_SPD_SDI_DVC:
1292
return "DVC";
1293
case HDMI_SPD_SDI_DSC:
1294
return "DSC";
1295
case HDMI_SPD_SDI_VCD:
1296
return "Video CD";
1297
case HDMI_SPD_SDI_GAME:
1298
return "Game";
1299
case HDMI_SPD_SDI_PC:
1300
return "PC General";
1301
case HDMI_SPD_SDI_BD:
1302
return "Blu-Ray Disc (BD)";
1303
case HDMI_SPD_SDI_SACD:
1304
return "Super Audio CD";
1305
case HDMI_SPD_SDI_HDDVD:
1306
return "HD DVD";
1307
case HDMI_SPD_SDI_PMP:
1308
return "PMP";
1309
}
1310
return "Reserved";
1311
}
1312
1313
static void hdmi_spd_infoframe_log(const char *level,
1314
struct device *dev,
1315
const struct hdmi_spd_infoframe *frame)
1316
{
1317
u8 buf[17];
1318
1319
hdmi_infoframe_log_header(level, dev,
1320
(const struct hdmi_any_infoframe *)frame);
1321
1322
memset(buf, 0, sizeof(buf));
1323
1324
strncpy(buf, frame->vendor, 8);
1325
hdmi_log(" vendor: %s\n", buf);
1326
strncpy(buf, frame->product, 16);
1327
hdmi_log(" product: %s\n", buf);
1328
hdmi_log(" source device information: %s (0x%x)\n",
1329
hdmi_spd_sdi_get_name(frame->sdi), frame->sdi);
1330
}
1331
1332
static const char *
1333
hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type)
1334
{
1335
switch (coding_type) {
1336
case HDMI_AUDIO_CODING_TYPE_STREAM:
1337
return "Refer to Stream Header";
1338
case HDMI_AUDIO_CODING_TYPE_PCM:
1339
return "PCM";
1340
case HDMI_AUDIO_CODING_TYPE_AC3:
1341
return "AC-3";
1342
case HDMI_AUDIO_CODING_TYPE_MPEG1:
1343
return "MPEG1";
1344
case HDMI_AUDIO_CODING_TYPE_MP3:
1345
return "MP3";
1346
case HDMI_AUDIO_CODING_TYPE_MPEG2:
1347
return "MPEG2";
1348
case HDMI_AUDIO_CODING_TYPE_AAC_LC:
1349
return "AAC";
1350
case HDMI_AUDIO_CODING_TYPE_DTS:
1351
return "DTS";
1352
case HDMI_AUDIO_CODING_TYPE_ATRAC:
1353
return "ATRAC";
1354
case HDMI_AUDIO_CODING_TYPE_DSD:
1355
return "One Bit Audio";
1356
case HDMI_AUDIO_CODING_TYPE_EAC3:
1357
return "Dolby Digital +";
1358
case HDMI_AUDIO_CODING_TYPE_DTS_HD:
1359
return "DTS-HD";
1360
case HDMI_AUDIO_CODING_TYPE_MLP:
1361
return "MAT (MLP)";
1362
case HDMI_AUDIO_CODING_TYPE_DST:
1363
return "DST";
1364
case HDMI_AUDIO_CODING_TYPE_WMA_PRO:
1365
return "WMA PRO";
1366
case HDMI_AUDIO_CODING_TYPE_CXT:
1367
return "Refer to CXT";
1368
}
1369
return "Invalid";
1370
}
1371
1372
static const char *
1373
hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size)
1374
{
1375
switch (sample_size) {
1376
case HDMI_AUDIO_SAMPLE_SIZE_STREAM:
1377
return "Refer to Stream Header";
1378
case HDMI_AUDIO_SAMPLE_SIZE_16:
1379
return "16 bit";
1380
case HDMI_AUDIO_SAMPLE_SIZE_20:
1381
return "20 bit";
1382
case HDMI_AUDIO_SAMPLE_SIZE_24:
1383
return "24 bit";
1384
}
1385
return "Invalid";
1386
}
1387
1388
static const char *
1389
hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq)
1390
{
1391
switch (freq) {
1392
case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM:
1393
return "Refer to Stream Header";
1394
case HDMI_AUDIO_SAMPLE_FREQUENCY_32000:
1395
return "32 kHz";
1396
case HDMI_AUDIO_SAMPLE_FREQUENCY_44100:
1397
return "44.1 kHz (CD)";
1398
case HDMI_AUDIO_SAMPLE_FREQUENCY_48000:
1399
return "48 kHz";
1400
case HDMI_AUDIO_SAMPLE_FREQUENCY_88200:
1401
return "88.2 kHz";
1402
case HDMI_AUDIO_SAMPLE_FREQUENCY_96000:
1403
return "96 kHz";
1404
case HDMI_AUDIO_SAMPLE_FREQUENCY_176400:
1405
return "176.4 kHz";
1406
case HDMI_AUDIO_SAMPLE_FREQUENCY_192000:
1407
return "192 kHz";
1408
}
1409
return "Invalid";
1410
}
1411
1412
static const char *
1413
hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx)
1414
{
1415
if (ctx < 0 || ctx > 0x1f)
1416
return "Invalid";
1417
1418
switch (ctx) {
1419
case HDMI_AUDIO_CODING_TYPE_EXT_CT:
1420
return "Refer to CT";
1421
case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC:
1422
return "HE AAC";
1423
case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2:
1424
return "HE AAC v2";
1425
case HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND:
1426
return "MPEG SURROUND";
1427
case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC:
1428
return "MPEG-4 HE AAC";
1429
case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2:
1430
return "MPEG-4 HE AAC v2";
1431
case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC:
1432
return "MPEG-4 AAC LC";
1433
case HDMI_AUDIO_CODING_TYPE_EXT_DRA:
1434
return "DRA";
1435
case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND:
1436
return "MPEG-4 HE AAC + MPEG Surround";
1437
case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND:
1438
return "MPEG-4 AAC LC + MPEG Surround";
1439
}
1440
return "Reserved";
1441
}
1442
1443
static void hdmi_audio_infoframe_log(const char *level,
1444
struct device *dev,
1445
const struct hdmi_audio_infoframe *frame)
1446
{
1447
hdmi_infoframe_log_header(level, dev,
1448
(const struct hdmi_any_infoframe *)frame);
1449
1450
if (frame->channels)
1451
hdmi_log(" channels: %u\n", frame->channels - 1);
1452
else
1453
hdmi_log(" channels: Refer to stream header\n");
1454
hdmi_log(" coding type: %s\n",
1455
hdmi_audio_coding_type_get_name(frame->coding_type));
1456
hdmi_log(" sample size: %s\n",
1457
hdmi_audio_sample_size_get_name(frame->sample_size));
1458
hdmi_log(" sample frequency: %s\n",
1459
hdmi_audio_sample_frequency_get_name(frame->sample_frequency));
1460
hdmi_log(" coding type ext: %s\n",
1461
hdmi_audio_coding_type_ext_get_name(frame->coding_type_ext));
1462
hdmi_log(" channel allocation: 0x%x\n",
1463
frame->channel_allocation);
1464
hdmi_log(" level shift value: %u dB\n",
1465
frame->level_shift_value);
1466
hdmi_log(" downmix inhibit: %s\n",
1467
frame->downmix_inhibit ? "Yes" : "No");
1468
}
1469
1470
static void hdmi_drm_infoframe_log(const char *level,
1471
struct device *dev,
1472
const struct hdmi_drm_infoframe *frame)
1473
{
1474
int i;
1475
1476
hdmi_infoframe_log_header(level, dev,
1477
(struct hdmi_any_infoframe *)frame);
1478
hdmi_log("length: %d\n", frame->length);
1479
hdmi_log("metadata type: %d\n", frame->metadata_type);
1480
hdmi_log("eotf: %d\n", frame->eotf);
1481
for (i = 0; i < 3; i++) {
1482
hdmi_log("x[%d]: %d\n", i, frame->display_primaries[i].x);
1483
hdmi_log("y[%d]: %d\n", i, frame->display_primaries[i].y);
1484
}
1485
1486
hdmi_log("white point x: %d\n", frame->white_point.x);
1487
hdmi_log("white point y: %d\n", frame->white_point.y);
1488
1489
hdmi_log("max_display_mastering_luminance: %d\n",
1490
frame->max_display_mastering_luminance);
1491
hdmi_log("min_display_mastering_luminance: %d\n",
1492
frame->min_display_mastering_luminance);
1493
1494
hdmi_log("max_cll: %d\n", frame->max_cll);
1495
hdmi_log("max_fall: %d\n", frame->max_fall);
1496
}
1497
1498
static const char *
1499
hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct)
1500
{
1501
if (s3d_struct < 0 || s3d_struct > 0xf)
1502
return "Invalid";
1503
1504
switch (s3d_struct) {
1505
case HDMI_3D_STRUCTURE_FRAME_PACKING:
1506
return "Frame Packing";
1507
case HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE:
1508
return "Field Alternative";
1509
case HDMI_3D_STRUCTURE_LINE_ALTERNATIVE:
1510
return "Line Alternative";
1511
case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL:
1512
return "Side-by-side (Full)";
1513
case HDMI_3D_STRUCTURE_L_DEPTH:
1514
return "L + Depth";
1515
case HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH:
1516
return "L + Depth + Graphics + Graphics-depth";
1517
case HDMI_3D_STRUCTURE_TOP_AND_BOTTOM:
1518
return "Top-and-Bottom";
1519
case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF:
1520
return "Side-by-side (Half)";
1521
default:
1522
break;
1523
}
1524
return "Reserved";
1525
}
1526
1527
static void
1528
hdmi_vendor_any_infoframe_log(const char *level,
1529
struct device *dev,
1530
const union hdmi_vendor_any_infoframe *frame)
1531
{
1532
const struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
1533
1534
hdmi_infoframe_log_header(level, dev,
1535
(const struct hdmi_any_infoframe *)frame);
1536
1537
if (frame->any.oui != HDMI_IEEE_OUI) {
1538
hdmi_log(" not a HDMI vendor infoframe\n");
1539
return;
1540
}
1541
if (hvf->vic == 0 && hvf->s3d_struct == HDMI_3D_STRUCTURE_INVALID) {
1542
hdmi_log(" empty frame\n");
1543
return;
1544
}
1545
1546
if (hvf->vic)
1547
hdmi_log(" HDMI VIC: %u\n", hvf->vic);
1548
if (hvf->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
1549
hdmi_log(" 3D structure: %s\n",
1550
hdmi_3d_structure_get_name(hvf->s3d_struct));
1551
if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
1552
hdmi_log(" 3D extension data: %d\n",
1553
hvf->s3d_ext_data);
1554
}
1555
}
1556
1557
/**
1558
* hdmi_infoframe_log() - log info of HDMI infoframe
1559
* @level: logging level
1560
* @dev: device
1561
* @frame: HDMI infoframe
1562
*/
1563
void hdmi_infoframe_log(const char *level,
1564
struct device *dev,
1565
const union hdmi_infoframe *frame)
1566
{
1567
switch (frame->any.type) {
1568
case HDMI_INFOFRAME_TYPE_AVI:
1569
hdmi_avi_infoframe_log(level, dev, &frame->avi);
1570
break;
1571
case HDMI_INFOFRAME_TYPE_SPD:
1572
hdmi_spd_infoframe_log(level, dev, &frame->spd);
1573
break;
1574
case HDMI_INFOFRAME_TYPE_AUDIO:
1575
hdmi_audio_infoframe_log(level, dev, &frame->audio);
1576
break;
1577
case HDMI_INFOFRAME_TYPE_VENDOR:
1578
hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
1579
break;
1580
case HDMI_INFOFRAME_TYPE_DRM:
1581
hdmi_drm_infoframe_log(level, dev, &frame->drm);
1582
break;
1583
}
1584
}
1585
EXPORT_SYMBOL(hdmi_infoframe_log);
1586
1587
/**
1588
* hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe
1589
* @frame: HDMI AVI infoframe
1590
* @buffer: source buffer
1591
* @size: size of buffer
1592
*
1593
* Unpacks the information contained in binary @buffer into a structured
1594
* @frame of the HDMI Auxiliary Video (AVI) information frame.
1595
* Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1596
* specification.
1597
*
1598
* Returns 0 on success or a negative error code on failure.
1599
*/
1600
static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
1601
const void *buffer, size_t size)
1602
{
1603
const u8 *ptr = buffer;
1604
1605
if (size < HDMI_INFOFRAME_SIZE(AVI))
1606
return -EINVAL;
1607
1608
if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
1609
ptr[1] != 2 ||
1610
ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
1611
return -EINVAL;
1612
1613
if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
1614
return -EINVAL;
1615
1616
hdmi_avi_infoframe_init(frame);
1617
1618
ptr += HDMI_INFOFRAME_HEADER_SIZE;
1619
1620
frame->colorspace = (ptr[0] >> 5) & 0x3;
1621
if (ptr[0] & 0x10)
1622
frame->active_aspect = ptr[1] & 0xf;
1623
if (ptr[0] & 0x8) {
1624
frame->top_bar = (ptr[6] << 8) | ptr[5];
1625
frame->bottom_bar = (ptr[8] << 8) | ptr[7];
1626
}
1627
if (ptr[0] & 0x4) {
1628
frame->left_bar = (ptr[10] << 8) | ptr[9];
1629
frame->right_bar = (ptr[12] << 8) | ptr[11];
1630
}
1631
frame->scan_mode = ptr[0] & 0x3;
1632
1633
frame->colorimetry = (ptr[1] >> 6) & 0x3;
1634
frame->picture_aspect = (ptr[1] >> 4) & 0x3;
1635
frame->active_aspect = ptr[1] & 0xf;
1636
1637
frame->itc = ptr[2] & 0x80 ? true : false;
1638
frame->extended_colorimetry = (ptr[2] >> 4) & 0x7;
1639
frame->quantization_range = (ptr[2] >> 2) & 0x3;
1640
frame->nups = ptr[2] & 0x3;
1641
1642
frame->video_code = ptr[3] & 0x7f;
1643
frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3;
1644
frame->content_type = (ptr[4] >> 4) & 0x3;
1645
1646
frame->pixel_repeat = ptr[4] & 0xf;
1647
1648
return 0;
1649
}
1650
1651
/**
1652
* hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe
1653
* @frame: HDMI SPD infoframe
1654
* @buffer: source buffer
1655
* @size: size of buffer
1656
*
1657
* Unpacks the information contained in binary @buffer into a structured
1658
* @frame of the HDMI Source Product Description (SPD) information frame.
1659
* Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1660
* specification.
1661
*
1662
* Returns 0 on success or a negative error code on failure.
1663
*/
1664
static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
1665
const void *buffer, size_t size)
1666
{
1667
const u8 *ptr = buffer;
1668
int ret;
1669
1670
if (size < HDMI_INFOFRAME_SIZE(SPD))
1671
return -EINVAL;
1672
1673
if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD ||
1674
ptr[1] != 1 ||
1675
ptr[2] != HDMI_SPD_INFOFRAME_SIZE) {
1676
return -EINVAL;
1677
}
1678
1679
if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0)
1680
return -EINVAL;
1681
1682
ptr += HDMI_INFOFRAME_HEADER_SIZE;
1683
1684
ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8);
1685
if (ret)
1686
return ret;
1687
1688
frame->sdi = ptr[24];
1689
1690
return 0;
1691
}
1692
1693
/**
1694
* hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe
1695
* @frame: HDMI Audio infoframe
1696
* @buffer: source buffer
1697
* @size: size of buffer
1698
*
1699
* Unpacks the information contained in binary @buffer into a structured
1700
* @frame of the HDMI Audio information frame.
1701
* Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1702
* specification.
1703
*
1704
* Returns 0 on success or a negative error code on failure.
1705
*/
1706
static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
1707
const void *buffer, size_t size)
1708
{
1709
const u8 *ptr = buffer;
1710
int ret;
1711
1712
if (size < HDMI_INFOFRAME_SIZE(AUDIO))
1713
return -EINVAL;
1714
1715
if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO ||
1716
ptr[1] != 1 ||
1717
ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) {
1718
return -EINVAL;
1719
}
1720
1721
if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0)
1722
return -EINVAL;
1723
1724
ret = hdmi_audio_infoframe_init(frame);
1725
if (ret)
1726
return ret;
1727
1728
ptr += HDMI_INFOFRAME_HEADER_SIZE;
1729
1730
frame->channels = ptr[0] & 0x7;
1731
frame->coding_type = (ptr[0] >> 4) & 0xf;
1732
frame->sample_size = ptr[1] & 0x3;
1733
frame->sample_frequency = (ptr[1] >> 2) & 0x7;
1734
frame->coding_type_ext = ptr[2] & 0x1f;
1735
frame->channel_allocation = ptr[3];
1736
frame->level_shift_value = (ptr[4] >> 3) & 0xf;
1737
frame->downmix_inhibit = ptr[4] & 0x80 ? true : false;
1738
1739
return 0;
1740
}
1741
1742
/**
1743
* hdmi_vendor_any_infoframe_unpack() - unpack binary buffer to a HDMI
1744
* vendor infoframe
1745
* @frame: HDMI Vendor infoframe
1746
* @buffer: source buffer
1747
* @size: size of buffer
1748
*
1749
* Unpacks the information contained in binary @buffer into a structured
1750
* @frame of the HDMI Vendor information frame.
1751
* Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1752
* specification.
1753
*
1754
* Returns 0 on success or a negative error code on failure.
1755
*/
1756
static int
1757
hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
1758
const void *buffer, size_t size)
1759
{
1760
const u8 *ptr = buffer;
1761
size_t length;
1762
int ret;
1763
u8 hdmi_video_format;
1764
struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
1765
1766
if (size < HDMI_INFOFRAME_HEADER_SIZE)
1767
return -EINVAL;
1768
1769
if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR ||
1770
ptr[1] != 1 ||
1771
(ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6))
1772
return -EINVAL;
1773
1774
length = ptr[2];
1775
1776
if (size < HDMI_INFOFRAME_HEADER_SIZE + length)
1777
return -EINVAL;
1778
1779
if (hdmi_infoframe_checksum(buffer,
1780
HDMI_INFOFRAME_HEADER_SIZE + length) != 0)
1781
return -EINVAL;
1782
1783
ptr += HDMI_INFOFRAME_HEADER_SIZE;
1784
1785
/* HDMI OUI */
1786
if ((ptr[0] != 0x03) ||
1787
(ptr[1] != 0x0c) ||
1788
(ptr[2] != 0x00))
1789
return -EINVAL;
1790
1791
hdmi_video_format = ptr[3] >> 5;
1792
1793
if (hdmi_video_format > 0x2)
1794
return -EINVAL;
1795
1796
ret = hdmi_vendor_infoframe_init(hvf);
1797
if (ret)
1798
return ret;
1799
1800
hvf->length = length;
1801
1802
if (hdmi_video_format == 0x2) {
1803
if (length != 5 && length != 6)
1804
return -EINVAL;
1805
hvf->s3d_struct = ptr[4] >> 4;
1806
if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) {
1807
if (length != 6)
1808
return -EINVAL;
1809
hvf->s3d_ext_data = ptr[5] >> 4;
1810
}
1811
} else if (hdmi_video_format == 0x1) {
1812
if (length != 5)
1813
return -EINVAL;
1814
hvf->vic = ptr[4];
1815
} else {
1816
if (length != 4)
1817
return -EINVAL;
1818
}
1819
1820
return 0;
1821
}
1822
1823
/**
1824
* hdmi_drm_infoframe_unpack_only() - unpack binary buffer of CTA-861-G DRM
1825
* infoframe DataBytes to a HDMI DRM
1826
* infoframe
1827
* @frame: HDMI DRM infoframe
1828
* @buffer: source buffer
1829
* @size: size of buffer
1830
*
1831
* Unpacks CTA-861-G DRM infoframe DataBytes contained in the binary @buffer
1832
* into a structured @frame of the HDMI Dynamic Range and Mastering (DRM)
1833
* infoframe.
1834
*
1835
* Returns 0 on success or a negative error code on failure.
1836
*/
1837
int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame,
1838
const void *buffer, size_t size)
1839
{
1840
const u8 *ptr = buffer;
1841
const u8 *temp;
1842
u8 x_lsb, x_msb;
1843
u8 y_lsb, y_msb;
1844
int ret;
1845
int i;
1846
1847
if (size < HDMI_DRM_INFOFRAME_SIZE)
1848
return -EINVAL;
1849
1850
ret = hdmi_drm_infoframe_init(frame);
1851
if (ret)
1852
return ret;
1853
1854
frame->eotf = ptr[0] & 0x7;
1855
frame->metadata_type = ptr[1] & 0x7;
1856
1857
temp = ptr + 2;
1858
for (i = 0; i < 3; i++) {
1859
x_lsb = *temp++;
1860
x_msb = *temp++;
1861
frame->display_primaries[i].x = (x_msb << 8) | x_lsb;
1862
y_lsb = *temp++;
1863
y_msb = *temp++;
1864
frame->display_primaries[i].y = (y_msb << 8) | y_lsb;
1865
}
1866
1867
frame->white_point.x = (ptr[15] << 8) | ptr[14];
1868
frame->white_point.y = (ptr[17] << 8) | ptr[16];
1869
1870
frame->max_display_mastering_luminance = (ptr[19] << 8) | ptr[18];
1871
frame->min_display_mastering_luminance = (ptr[21] << 8) | ptr[20];
1872
frame->max_cll = (ptr[23] << 8) | ptr[22];
1873
frame->max_fall = (ptr[25] << 8) | ptr[24];
1874
1875
return 0;
1876
}
1877
EXPORT_SYMBOL(hdmi_drm_infoframe_unpack_only);
1878
1879
/**
1880
* hdmi_drm_infoframe_unpack() - unpack binary buffer to a HDMI DRM infoframe
1881
* @frame: HDMI DRM infoframe
1882
* @buffer: source buffer
1883
* @size: size of buffer
1884
*
1885
* Unpacks the CTA-861-G DRM infoframe contained in the binary @buffer into
1886
* a structured @frame of the HDMI Dynamic Range and Mastering (DRM)
1887
* infoframe. It also verifies the checksum as required by section 5.3.5 of
1888
* the HDMI 1.4 specification.
1889
*
1890
* Returns 0 on success or a negative error code on failure.
1891
*/
1892
static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
1893
const void *buffer, size_t size)
1894
{
1895
const u8 *ptr = buffer;
1896
int ret;
1897
1898
if (size < HDMI_INFOFRAME_SIZE(DRM))
1899
return -EINVAL;
1900
1901
if (ptr[0] != HDMI_INFOFRAME_TYPE_DRM ||
1902
ptr[1] != 1 ||
1903
ptr[2] != HDMI_DRM_INFOFRAME_SIZE)
1904
return -EINVAL;
1905
1906
if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(DRM)) != 0)
1907
return -EINVAL;
1908
1909
ret = hdmi_drm_infoframe_unpack_only(frame, ptr + HDMI_INFOFRAME_HEADER_SIZE,
1910
size - HDMI_INFOFRAME_HEADER_SIZE);
1911
return ret;
1912
}
1913
1914
/**
1915
* hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
1916
* @frame: HDMI infoframe
1917
* @buffer: source buffer
1918
* @size: size of buffer
1919
*
1920
* Unpacks the information contained in binary buffer @buffer into a structured
1921
* @frame of a HDMI infoframe.
1922
* Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1923
* specification.
1924
*
1925
* Returns 0 on success or a negative error code on failure.
1926
*/
1927
int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
1928
const void *buffer, size_t size)
1929
{
1930
int ret;
1931
const u8 *ptr = buffer;
1932
1933
if (size < HDMI_INFOFRAME_HEADER_SIZE)
1934
return -EINVAL;
1935
1936
switch (ptr[0]) {
1937
case HDMI_INFOFRAME_TYPE_AVI:
1938
ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size);
1939
break;
1940
case HDMI_INFOFRAME_TYPE_DRM:
1941
ret = hdmi_drm_infoframe_unpack(&frame->drm, buffer, size);
1942
break;
1943
case HDMI_INFOFRAME_TYPE_SPD:
1944
ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size);
1945
break;
1946
case HDMI_INFOFRAME_TYPE_AUDIO:
1947
ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer, size);
1948
break;
1949
case HDMI_INFOFRAME_TYPE_VENDOR:
1950
ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size);
1951
break;
1952
default:
1953
ret = -EINVAL;
1954
break;
1955
}
1956
1957
return ret;
1958
}
1959
EXPORT_SYMBOL(hdmi_infoframe_unpack);
1960
1961