xref: /linux/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmi.c (revision 3d0fe49454652117522f60bfbefb978ba0e5300b)
1 // SPDX-License-Identifier: MIT
2 #include "hdmi.h"
3 
4 void pack_hdmi_infoframe(struct packed_hdmi_infoframe *packed_frame,
5 			 u8 *raw_frame, ssize_t len)
6 {
7 	u32 header = 0;
8 	u32 subpack0_low = 0;
9 	u32 subpack0_high = 0;
10 	u32 subpack1_low = 0;
11 	u32 subpack1_high = 0;
12 
13 	switch (len) {
14 		/*
15 		 * "When in doubt, use brute force."
16 		 *     -- Ken Thompson.
17 		 */
18 	default:
19 		/*
20 		 * We presume that no valid frame is longer than 17
21 		 * octets, including header...  And truncate to that
22 		 * if it's longer.
23 		 */
24 	case 17:
25 		subpack1_high = (raw_frame[16] << 16);
26 		fallthrough;
27 	case 16:
28 		subpack1_high |= (raw_frame[15] << 8);
29 		fallthrough;
30 	case 15:
31 		subpack1_high |= raw_frame[14];
32 		fallthrough;
33 	case 14:
34 		subpack1_low = (raw_frame[13] << 24);
35 		fallthrough;
36 	case 13:
37 		subpack1_low |= (raw_frame[12] << 16);
38 		fallthrough;
39 	case 12:
40 		subpack1_low |= (raw_frame[11] << 8);
41 		fallthrough;
42 	case 11:
43 		subpack1_low |= raw_frame[10];
44 		fallthrough;
45 	case 10:
46 		subpack0_high = (raw_frame[9] << 16);
47 		fallthrough;
48 	case 9:
49 		subpack0_high |= (raw_frame[8] << 8);
50 		fallthrough;
51 	case 8:
52 		subpack0_high |= raw_frame[7];
53 		fallthrough;
54 	case 7:
55 		subpack0_low = (raw_frame[6] << 24);
56 		fallthrough;
57 	case 6:
58 		subpack0_low |= (raw_frame[5] << 16);
59 		fallthrough;
60 	case 5:
61 		subpack0_low |= (raw_frame[4] << 8);
62 		fallthrough;
63 	case 4:
64 		subpack0_low |= raw_frame[3];
65 		fallthrough;
66 	case 3:
67 		header = (raw_frame[2] << 16);
68 		fallthrough;
69 	case 2:
70 		header |= (raw_frame[1] << 8);
71 		fallthrough;
72 	case 1:
73 		header |= raw_frame[0];
74 		fallthrough;
75 	case 0:
76 		break;
77 	}
78 
79 	packed_frame->header = header;
80 	packed_frame->subpack0_low = subpack0_low;
81 	packed_frame->subpack0_high = subpack0_high;
82 	packed_frame->subpack1_low = subpack1_low;
83 	packed_frame->subpack1_high = subpack1_high;
84 }
85