hdmi.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255
  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. #include <linux/bitops.h>
  24. #include <linux/bug.h>
  25. #include <linux/errno.h>
  26. #include <linux/export.h>
  27. #include <linux/hdmi.h>
  28. #include <linux/string.h>
  29. #include <linux/device.h>
  30. #define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__)
  31. static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
  32. {
  33. u8 csum = 0;
  34. size_t i;
  35. /* compute checksum */
  36. for (i = 0; i < size; i++)
  37. csum += ptr[i];
  38. return 256 - csum;
  39. }
  40. static void hdmi_infoframe_set_checksum(void *buffer, size_t size)
  41. {
  42. u8 *ptr = buffer;
  43. ptr[3] = hdmi_infoframe_checksum(buffer, size);
  44. }
  45. /**
  46. * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
  47. * @frame: HDMI AVI infoframe
  48. *
  49. * Returns 0 on success or a negative error code on failure.
  50. */
  51. int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
  52. {
  53. memset(frame, 0, sizeof(*frame));
  54. frame->type = HDMI_INFOFRAME_TYPE_AVI;
  55. frame->version = 2;
  56. frame->length = HDMI_AVI_INFOFRAME_SIZE;
  57. return 0;
  58. }
  59. EXPORT_SYMBOL(hdmi_avi_infoframe_init);
  60. /**
  61. * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
  62. * @frame: HDMI AVI infoframe
  63. * @buffer: destination buffer
  64. * @size: size of buffer
  65. *
  66. * Packs the information contained in the @frame structure into a binary
  67. * representation that can be written into the corresponding controller
  68. * registers. Also computes the checksum as required by section 5.3.5 of
  69. * the HDMI 1.4 specification.
  70. *
  71. * Returns the number of bytes packed into the binary buffer or a negative
  72. * error code on failure.
  73. */
  74. ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
  75. size_t size)
  76. {
  77. u8 *ptr = buffer;
  78. size_t length;
  79. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  80. if (size < length)
  81. return -ENOSPC;
  82. memset(buffer, 0, size);
  83. ptr[0] = frame->type;
  84. ptr[1] = frame->version;
  85. ptr[2] = frame->length;
  86. ptr[3] = 0; /* checksum */
  87. /* start infoframe payload */
  88. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  89. ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
  90. /*
  91. * Data byte 1, bit 4 has to be set if we provide the active format
  92. * aspect ratio
  93. */
  94. if (frame->active_aspect & 0xf)
  95. ptr[0] |= BIT(4);
  96. /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */
  97. if (frame->top_bar || frame->bottom_bar)
  98. ptr[0] |= BIT(3);
  99. if (frame->left_bar || frame->right_bar)
  100. ptr[0] |= BIT(2);
  101. ptr[1] = ((frame->colorimetry & 0x3) << 6) |
  102. ((frame->picture_aspect & 0x3) << 4) |
  103. (frame->active_aspect & 0xf);
  104. ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
  105. ((frame->quantization_range & 0x3) << 2) |
  106. (frame->nups & 0x3);
  107. if (frame->itc)
  108. ptr[2] |= BIT(7);
  109. ptr[3] = frame->video_code & 0x7f;
  110. ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
  111. ((frame->content_type & 0x3) << 4) |
  112. (frame->pixel_repeat & 0xf);
  113. ptr[5] = frame->top_bar & 0xff;
  114. ptr[6] = (frame->top_bar >> 8) & 0xff;
  115. ptr[7] = frame->bottom_bar & 0xff;
  116. ptr[8] = (frame->bottom_bar >> 8) & 0xff;
  117. ptr[9] = frame->left_bar & 0xff;
  118. ptr[10] = (frame->left_bar >> 8) & 0xff;
  119. ptr[11] = frame->right_bar & 0xff;
  120. ptr[12] = (frame->right_bar >> 8) & 0xff;
  121. hdmi_infoframe_set_checksum(buffer, length);
  122. return length;
  123. }
  124. EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
  125. /**
  126. * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
  127. * @frame: HDMI SPD infoframe
  128. * @vendor: vendor string
  129. * @product: product string
  130. *
  131. * Returns 0 on success or a negative error code on failure.
  132. */
  133. int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
  134. const char *vendor, const char *product)
  135. {
  136. memset(frame, 0, sizeof(*frame));
  137. frame->type = HDMI_INFOFRAME_TYPE_SPD;
  138. frame->version = 1;
  139. frame->length = HDMI_SPD_INFOFRAME_SIZE;
  140. strncpy(frame->vendor, vendor, sizeof(frame->vendor));
  141. strncpy(frame->product, product, sizeof(frame->product));
  142. return 0;
  143. }
  144. EXPORT_SYMBOL(hdmi_spd_infoframe_init);
  145. /**
  146. * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
  147. * @frame: HDMI SPD infoframe
  148. * @buffer: destination buffer
  149. * @size: size of buffer
  150. *
  151. * Packs the information contained in the @frame structure into a binary
  152. * representation that can be written into the corresponding controller
  153. * registers. Also computes the checksum as required by section 5.3.5 of
  154. * the HDMI 1.4 specification.
  155. *
  156. * Returns the number of bytes packed into the binary buffer or a negative
  157. * error code on failure.
  158. */
  159. ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
  160. size_t size)
  161. {
  162. u8 *ptr = buffer;
  163. size_t length;
  164. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  165. if (size < length)
  166. return -ENOSPC;
  167. memset(buffer, 0, size);
  168. ptr[0] = frame->type;
  169. ptr[1] = frame->version;
  170. ptr[2] = frame->length;
  171. ptr[3] = 0; /* checksum */
  172. /* start infoframe payload */
  173. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  174. memcpy(ptr, frame->vendor, sizeof(frame->vendor));
  175. memcpy(ptr + 8, frame->product, sizeof(frame->product));
  176. ptr[24] = frame->sdi;
  177. hdmi_infoframe_set_checksum(buffer, length);
  178. return length;
  179. }
  180. EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
  181. /**
  182. * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
  183. * @frame: HDMI audio infoframe
  184. *
  185. * Returns 0 on success or a negative error code on failure.
  186. */
  187. int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
  188. {
  189. memset(frame, 0, sizeof(*frame));
  190. frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
  191. frame->version = 1;
  192. frame->length = HDMI_AUDIO_INFOFRAME_SIZE;
  193. return 0;
  194. }
  195. EXPORT_SYMBOL(hdmi_audio_infoframe_init);
  196. /**
  197. * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
  198. * @frame: HDMI audio infoframe
  199. * @buffer: destination buffer
  200. * @size: size of buffer
  201. *
  202. * Packs the information contained in the @frame structure into a binary
  203. * representation that can be written into the corresponding controller
  204. * registers. Also computes the checksum as required by section 5.3.5 of
  205. * the HDMI 1.4 specification.
  206. *
  207. * Returns the number of bytes packed into the binary buffer or a negative
  208. * error code on failure.
  209. */
  210. ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
  211. void *buffer, size_t size)
  212. {
  213. unsigned char channels;
  214. u8 *ptr = buffer;
  215. size_t length;
  216. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  217. if (size < length)
  218. return -ENOSPC;
  219. memset(buffer, 0, size);
  220. if (frame->channels >= 2)
  221. channels = frame->channels - 1;
  222. else
  223. channels = 0;
  224. ptr[0] = frame->type;
  225. ptr[1] = frame->version;
  226. ptr[2] = frame->length;
  227. ptr[3] = 0; /* checksum */
  228. /* start infoframe payload */
  229. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  230. ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
  231. ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
  232. (frame->sample_size & 0x3);
  233. ptr[2] = frame->coding_type_ext & 0x1f;
  234. ptr[3] = frame->channel_allocation;
  235. ptr[4] = (frame->level_shift_value & 0xf) << 3;
  236. if (frame->downmix_inhibit)
  237. ptr[4] |= BIT(7);
  238. hdmi_infoframe_set_checksum(buffer, length);
  239. return length;
  240. }
  241. EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
  242. /**
  243. * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  244. * @frame: HDMI vendor infoframe
  245. *
  246. * Returns 0 on success or a negative error code on failure.
  247. */
  248. int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
  249. {
  250. memset(frame, 0, sizeof(*frame));
  251. frame->type = HDMI_INFOFRAME_TYPE_VENDOR;
  252. frame->version = 1;
  253. frame->oui = HDMI_IEEE_OUI;
  254. /*
  255. * 0 is a valid value for s3d_struct, so we use a special "not set"
  256. * value
  257. */
  258. frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
  259. return 0;
  260. }
  261. EXPORT_SYMBOL(hdmi_vendor_infoframe_init);
  262. static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *frame)
  263. {
  264. /* for side by side (half) we also need to provide 3D_Ext_Data */
  265. if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
  266. return 6;
  267. else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
  268. return 5;
  269. else
  270. return 4;
  271. }
  272. /**
  273. * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer
  274. * @frame: HDMI infoframe
  275. * @buffer: destination buffer
  276. * @size: size of buffer
  277. *
  278. * Packs the information contained in the @frame structure into a binary
  279. * representation that can be written into the corresponding controller
  280. * registers. Also computes the checksum as required by section 5.3.5 of
  281. * the HDMI 1.4 specification.
  282. *
  283. * Returns the number of bytes packed into the binary buffer or a negative
  284. * error code on failure.
  285. */
  286. ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
  287. void *buffer, size_t size)
  288. {
  289. u8 *ptr = buffer;
  290. size_t length;
  291. /* only one of those can be supplied */
  292. if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
  293. return -EINVAL;
  294. frame->length = hdmi_vendor_infoframe_length(frame);
  295. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  296. if (size < length)
  297. return -ENOSPC;
  298. memset(buffer, 0, size);
  299. ptr[0] = frame->type;
  300. ptr[1] = frame->version;
  301. ptr[2] = frame->length;
  302. ptr[3] = 0; /* checksum */
  303. /* HDMI OUI */
  304. ptr[4] = 0x03;
  305. ptr[5] = 0x0c;
  306. ptr[6] = 0x00;
  307. if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
  308. ptr[7] = 0x2 << 5; /* video format */
  309. ptr[8] = (frame->s3d_struct & 0xf) << 4;
  310. if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
  311. ptr[9] = (frame->s3d_ext_data & 0xf) << 4;
  312. } else if (frame->vic) {
  313. ptr[7] = 0x1 << 5; /* video format */
  314. ptr[8] = frame->vic;
  315. } else {
  316. ptr[7] = 0x0 << 5; /* video format */
  317. }
  318. hdmi_infoframe_set_checksum(buffer, length);
  319. return length;
  320. }
  321. EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
  322. /*
  323. * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer
  324. */
  325. static ssize_t
  326. hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
  327. void *buffer, size_t size)
  328. {
  329. /* we only know about HDMI vendor infoframes */
  330. if (frame->any.oui != HDMI_IEEE_OUI)
  331. return -EINVAL;
  332. return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size);
  333. }
  334. /**
  335. * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer
  336. * @frame: HDMI infoframe
  337. * @buffer: destination buffer
  338. * @size: size of buffer
  339. *
  340. * Packs the information contained in the @frame structure into a binary
  341. * representation that can be written into the corresponding controller
  342. * registers. Also computes the checksum as required by section 5.3.5 of
  343. * the HDMI 1.4 specification.
  344. *
  345. * Returns the number of bytes packed into the binary buffer or a negative
  346. * error code on failure.
  347. */
  348. ssize_t
  349. hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size)
  350. {
  351. ssize_t length;
  352. switch (frame->any.type) {
  353. case HDMI_INFOFRAME_TYPE_AVI:
  354. length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size);
  355. break;
  356. case HDMI_INFOFRAME_TYPE_SPD:
  357. length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size);
  358. break;
  359. case HDMI_INFOFRAME_TYPE_AUDIO:
  360. length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size);
  361. break;
  362. case HDMI_INFOFRAME_TYPE_VENDOR:
  363. length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
  364. buffer, size);
  365. break;
  366. default:
  367. WARN(1, "Bad infoframe type %d\n", frame->any.type);
  368. length = -EINVAL;
  369. }
  370. return length;
  371. }
  372. EXPORT_SYMBOL(hdmi_infoframe_pack);
  373. static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
  374. {
  375. if (type < 0x80 || type > 0x9f)
  376. return "Invalid";
  377. switch (type) {
  378. case HDMI_INFOFRAME_TYPE_VENDOR:
  379. return "Vendor";
  380. case HDMI_INFOFRAME_TYPE_AVI:
  381. return "Auxiliary Video Information (AVI)";
  382. case HDMI_INFOFRAME_TYPE_SPD:
  383. return "Source Product Description (SPD)";
  384. case HDMI_INFOFRAME_TYPE_AUDIO:
  385. return "Audio";
  386. }
  387. return "Reserved";
  388. }
  389. static void hdmi_infoframe_log_header(const char *level,
  390. struct device *dev,
  391. struct hdmi_any_infoframe *frame)
  392. {
  393. hdmi_log("HDMI infoframe: %s, version %u, length %u\n",
  394. hdmi_infoframe_type_get_name(frame->type),
  395. frame->version, frame->length);
  396. }
  397. static const char *hdmi_colorspace_get_name(enum hdmi_colorspace colorspace)
  398. {
  399. switch (colorspace) {
  400. case HDMI_COLORSPACE_RGB:
  401. return "RGB";
  402. case HDMI_COLORSPACE_YUV422:
  403. return "YCbCr 4:2:2";
  404. case HDMI_COLORSPACE_YUV444:
  405. return "YCbCr 4:4:4";
  406. case HDMI_COLORSPACE_YUV420:
  407. return "YCbCr 4:2:0";
  408. case HDMI_COLORSPACE_RESERVED4:
  409. return "Reserved (4)";
  410. case HDMI_COLORSPACE_RESERVED5:
  411. return "Reserved (5)";
  412. case HDMI_COLORSPACE_RESERVED6:
  413. return "Reserved (6)";
  414. case HDMI_COLORSPACE_IDO_DEFINED:
  415. return "IDO Defined";
  416. }
  417. return "Invalid";
  418. }
  419. static const char *hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode)
  420. {
  421. switch (scan_mode) {
  422. case HDMI_SCAN_MODE_NONE:
  423. return "No Data";
  424. case HDMI_SCAN_MODE_OVERSCAN:
  425. return "Overscan";
  426. case HDMI_SCAN_MODE_UNDERSCAN:
  427. return "Underscan";
  428. case HDMI_SCAN_MODE_RESERVED:
  429. return "Reserved";
  430. }
  431. return "Invalid";
  432. }
  433. static const char *hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry)
  434. {
  435. switch (colorimetry) {
  436. case HDMI_COLORIMETRY_NONE:
  437. return "No Data";
  438. case HDMI_COLORIMETRY_ITU_601:
  439. return "ITU601";
  440. case HDMI_COLORIMETRY_ITU_709:
  441. return "ITU709";
  442. case HDMI_COLORIMETRY_EXTENDED:
  443. return "Extended";
  444. }
  445. return "Invalid";
  446. }
  447. static const char *
  448. hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect)
  449. {
  450. switch (picture_aspect) {
  451. case HDMI_PICTURE_ASPECT_NONE:
  452. return "No Data";
  453. case HDMI_PICTURE_ASPECT_4_3:
  454. return "4:3";
  455. case HDMI_PICTURE_ASPECT_16_9:
  456. return "16:9";
  457. case HDMI_PICTURE_ASPECT_RESERVED:
  458. return "Reserved";
  459. }
  460. return "Invalid";
  461. }
  462. static const char *
  463. hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect)
  464. {
  465. if (active_aspect < 0 || active_aspect > 0xf)
  466. return "Invalid";
  467. switch (active_aspect) {
  468. case HDMI_ACTIVE_ASPECT_16_9_TOP:
  469. return "16:9 Top";
  470. case HDMI_ACTIVE_ASPECT_14_9_TOP:
  471. return "14:9 Top";
  472. case HDMI_ACTIVE_ASPECT_16_9_CENTER:
  473. return "16:9 Center";
  474. case HDMI_ACTIVE_ASPECT_PICTURE:
  475. return "Same as Picture";
  476. case HDMI_ACTIVE_ASPECT_4_3:
  477. return "4:3";
  478. case HDMI_ACTIVE_ASPECT_16_9:
  479. return "16:9";
  480. case HDMI_ACTIVE_ASPECT_14_9:
  481. return "14:9";
  482. case HDMI_ACTIVE_ASPECT_4_3_SP_14_9:
  483. return "4:3 SP 14:9";
  484. case HDMI_ACTIVE_ASPECT_16_9_SP_14_9:
  485. return "16:9 SP 14:9";
  486. case HDMI_ACTIVE_ASPECT_16_9_SP_4_3:
  487. return "16:9 SP 4:3";
  488. }
  489. return "Reserved";
  490. }
  491. static const char *
  492. hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col)
  493. {
  494. switch (ext_col) {
  495. case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601:
  496. return "xvYCC 601";
  497. case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709:
  498. return "xvYCC 709";
  499. case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
  500. return "sYCC 601";
  501. case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601:
  502. return "Adobe YCC 601";
  503. case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB:
  504. return "Adobe RGB";
  505. case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
  506. return "BT.2020 Constant Luminance";
  507. case HDMI_EXTENDED_COLORIMETRY_BT2020:
  508. return "BT.2020";
  509. case HDMI_EXTENDED_COLORIMETRY_RESERVED:
  510. return "Reserved";
  511. }
  512. return "Invalid";
  513. }
  514. static const char *
  515. hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange)
  516. {
  517. switch (qrange) {
  518. case HDMI_QUANTIZATION_RANGE_DEFAULT:
  519. return "Default";
  520. case HDMI_QUANTIZATION_RANGE_LIMITED:
  521. return "Limited";
  522. case HDMI_QUANTIZATION_RANGE_FULL:
  523. return "Full";
  524. case HDMI_QUANTIZATION_RANGE_RESERVED:
  525. return "Reserved";
  526. }
  527. return "Invalid";
  528. }
  529. static const char *hdmi_nups_get_name(enum hdmi_nups nups)
  530. {
  531. switch (nups) {
  532. case HDMI_NUPS_UNKNOWN:
  533. return "Unknown Non-uniform Scaling";
  534. case HDMI_NUPS_HORIZONTAL:
  535. return "Horizontally Scaled";
  536. case HDMI_NUPS_VERTICAL:
  537. return "Vertically Scaled";
  538. case HDMI_NUPS_BOTH:
  539. return "Horizontally and Vertically Scaled";
  540. }
  541. return "Invalid";
  542. }
  543. static const char *
  544. hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange)
  545. {
  546. switch (qrange) {
  547. case HDMI_YCC_QUANTIZATION_RANGE_LIMITED:
  548. return "Limited";
  549. case HDMI_YCC_QUANTIZATION_RANGE_FULL:
  550. return "Full";
  551. }
  552. return "Invalid";
  553. }
  554. static const char *
  555. hdmi_content_type_get_name(enum hdmi_content_type content_type)
  556. {
  557. switch (content_type) {
  558. case HDMI_CONTENT_TYPE_GRAPHICS:
  559. return "Graphics";
  560. case HDMI_CONTENT_TYPE_PHOTO:
  561. return "Photo";
  562. case HDMI_CONTENT_TYPE_CINEMA:
  563. return "Cinema";
  564. case HDMI_CONTENT_TYPE_GAME:
  565. return "Game";
  566. }
  567. return "Invalid";
  568. }
  569. /**
  570. * hdmi_avi_infoframe_log() - log info of HDMI AVI infoframe
  571. * @level: logging level
  572. * @dev: device
  573. * @frame: HDMI AVI infoframe
  574. */
  575. static void hdmi_avi_infoframe_log(const char *level,
  576. struct device *dev,
  577. struct hdmi_avi_infoframe *frame)
  578. {
  579. hdmi_infoframe_log_header(level, dev,
  580. (struct hdmi_any_infoframe *)frame);
  581. hdmi_log(" colorspace: %s\n",
  582. hdmi_colorspace_get_name(frame->colorspace));
  583. hdmi_log(" scan mode: %s\n",
  584. hdmi_scan_mode_get_name(frame->scan_mode));
  585. hdmi_log(" colorimetry: %s\n",
  586. hdmi_colorimetry_get_name(frame->colorimetry));
  587. hdmi_log(" picture aspect: %s\n",
  588. hdmi_picture_aspect_get_name(frame->picture_aspect));
  589. hdmi_log(" active aspect: %s\n",
  590. hdmi_active_aspect_get_name(frame->active_aspect));
  591. hdmi_log(" itc: %s\n", frame->itc ? "IT Content" : "No Data");
  592. hdmi_log(" extended colorimetry: %s\n",
  593. hdmi_extended_colorimetry_get_name(frame->extended_colorimetry));
  594. hdmi_log(" quantization range: %s\n",
  595. hdmi_quantization_range_get_name(frame->quantization_range));
  596. hdmi_log(" nups: %s\n", hdmi_nups_get_name(frame->nups));
  597. hdmi_log(" video code: %u\n", frame->video_code);
  598. hdmi_log(" ycc quantization range: %s\n",
  599. hdmi_ycc_quantization_range_get_name(frame->ycc_quantization_range));
  600. hdmi_log(" hdmi content type: %s\n",
  601. hdmi_content_type_get_name(frame->content_type));
  602. hdmi_log(" pixel repeat: %u\n", frame->pixel_repeat);
  603. hdmi_log(" bar top %u, bottom %u, left %u, right %u\n",
  604. frame->top_bar, frame->bottom_bar,
  605. frame->left_bar, frame->right_bar);
  606. }
  607. static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi)
  608. {
  609. if (sdi < 0 || sdi > 0xff)
  610. return "Invalid";
  611. switch (sdi) {
  612. case HDMI_SPD_SDI_UNKNOWN:
  613. return "Unknown";
  614. case HDMI_SPD_SDI_DSTB:
  615. return "Digital STB";
  616. case HDMI_SPD_SDI_DVDP:
  617. return "DVD Player";
  618. case HDMI_SPD_SDI_DVHS:
  619. return "D-VHS";
  620. case HDMI_SPD_SDI_HDDVR:
  621. return "HDD Videorecorder";
  622. case HDMI_SPD_SDI_DVC:
  623. return "DVC";
  624. case HDMI_SPD_SDI_DSC:
  625. return "DSC";
  626. case HDMI_SPD_SDI_VCD:
  627. return "Video CD";
  628. case HDMI_SPD_SDI_GAME:
  629. return "Game";
  630. case HDMI_SPD_SDI_PC:
  631. return "PC General";
  632. case HDMI_SPD_SDI_BD:
  633. return "Blu-Ray Disc (BD)";
  634. case HDMI_SPD_SDI_SACD:
  635. return "Super Audio CD";
  636. case HDMI_SPD_SDI_HDDVD:
  637. return "HD DVD";
  638. case HDMI_SPD_SDI_PMP:
  639. return "PMP";
  640. }
  641. return "Reserved";
  642. }
  643. /**
  644. * hdmi_spd_infoframe_log() - log info of HDMI SPD infoframe
  645. * @level: logging level
  646. * @dev: device
  647. * @frame: HDMI SPD infoframe
  648. */
  649. static void hdmi_spd_infoframe_log(const char *level,
  650. struct device *dev,
  651. struct hdmi_spd_infoframe *frame)
  652. {
  653. u8 buf[17];
  654. hdmi_infoframe_log_header(level, dev,
  655. (struct hdmi_any_infoframe *)frame);
  656. memset(buf, 0, sizeof(buf));
  657. strncpy(buf, frame->vendor, 8);
  658. hdmi_log(" vendor: %s\n", buf);
  659. strncpy(buf, frame->product, 16);
  660. hdmi_log(" product: %s\n", buf);
  661. hdmi_log(" source device information: %s (0x%x)\n",
  662. hdmi_spd_sdi_get_name(frame->sdi), frame->sdi);
  663. }
  664. static const char *
  665. hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type)
  666. {
  667. switch (coding_type) {
  668. case HDMI_AUDIO_CODING_TYPE_STREAM:
  669. return "Refer to Stream Header";
  670. case HDMI_AUDIO_CODING_TYPE_PCM:
  671. return "PCM";
  672. case HDMI_AUDIO_CODING_TYPE_AC3:
  673. return "AC-3";
  674. case HDMI_AUDIO_CODING_TYPE_MPEG1:
  675. return "MPEG1";
  676. case HDMI_AUDIO_CODING_TYPE_MP3:
  677. return "MP3";
  678. case HDMI_AUDIO_CODING_TYPE_MPEG2:
  679. return "MPEG2";
  680. case HDMI_AUDIO_CODING_TYPE_AAC_LC:
  681. return "AAC";
  682. case HDMI_AUDIO_CODING_TYPE_DTS:
  683. return "DTS";
  684. case HDMI_AUDIO_CODING_TYPE_ATRAC:
  685. return "ATRAC";
  686. case HDMI_AUDIO_CODING_TYPE_DSD:
  687. return "One Bit Audio";
  688. case HDMI_AUDIO_CODING_TYPE_EAC3:
  689. return "Dolby Digital +";
  690. case HDMI_AUDIO_CODING_TYPE_DTS_HD:
  691. return "DTS-HD";
  692. case HDMI_AUDIO_CODING_TYPE_MLP:
  693. return "MAT (MLP)";
  694. case HDMI_AUDIO_CODING_TYPE_DST:
  695. return "DST";
  696. case HDMI_AUDIO_CODING_TYPE_WMA_PRO:
  697. return "WMA PRO";
  698. case HDMI_AUDIO_CODING_TYPE_CXT:
  699. return "Refer to CXT";
  700. }
  701. return "Invalid";
  702. }
  703. static const char *
  704. hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size)
  705. {
  706. switch (sample_size) {
  707. case HDMI_AUDIO_SAMPLE_SIZE_STREAM:
  708. return "Refer to Stream Header";
  709. case HDMI_AUDIO_SAMPLE_SIZE_16:
  710. return "16 bit";
  711. case HDMI_AUDIO_SAMPLE_SIZE_20:
  712. return "20 bit";
  713. case HDMI_AUDIO_SAMPLE_SIZE_24:
  714. return "24 bit";
  715. }
  716. return "Invalid";
  717. }
  718. static const char *
  719. hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq)
  720. {
  721. switch (freq) {
  722. case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM:
  723. return "Refer to Stream Header";
  724. case HDMI_AUDIO_SAMPLE_FREQUENCY_32000:
  725. return "32 kHz";
  726. case HDMI_AUDIO_SAMPLE_FREQUENCY_44100:
  727. return "44.1 kHz (CD)";
  728. case HDMI_AUDIO_SAMPLE_FREQUENCY_48000:
  729. return "48 kHz";
  730. case HDMI_AUDIO_SAMPLE_FREQUENCY_88200:
  731. return "88.2 kHz";
  732. case HDMI_AUDIO_SAMPLE_FREQUENCY_96000:
  733. return "96 kHz";
  734. case HDMI_AUDIO_SAMPLE_FREQUENCY_176400:
  735. return "176.4 kHz";
  736. case HDMI_AUDIO_SAMPLE_FREQUENCY_192000:
  737. return "192 kHz";
  738. }
  739. return "Invalid";
  740. }
  741. static const char *
  742. hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx)
  743. {
  744. if (ctx < 0 || ctx > 0x1f)
  745. return "Invalid";
  746. switch (ctx) {
  747. case HDMI_AUDIO_CODING_TYPE_EXT_CT:
  748. return "Refer to CT";
  749. case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC:
  750. return "HE AAC";
  751. case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2:
  752. return "HE AAC v2";
  753. case HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND:
  754. return "MPEG SURROUND";
  755. case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC:
  756. return "MPEG-4 HE AAC";
  757. case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2:
  758. return "MPEG-4 HE AAC v2";
  759. case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC:
  760. return "MPEG-4 AAC LC";
  761. case HDMI_AUDIO_CODING_TYPE_EXT_DRA:
  762. return "DRA";
  763. case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND:
  764. return "MPEG-4 HE AAC + MPEG Surround";
  765. case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND:
  766. return "MPEG-4 AAC LC + MPEG Surround";
  767. }
  768. return "Reserved";
  769. }
  770. /**
  771. * hdmi_audio_infoframe_log() - log info of HDMI AUDIO infoframe
  772. * @level: logging level
  773. * @dev: device
  774. * @frame: HDMI AUDIO infoframe
  775. */
  776. static void hdmi_audio_infoframe_log(const char *level,
  777. struct device *dev,
  778. struct hdmi_audio_infoframe *frame)
  779. {
  780. hdmi_infoframe_log_header(level, dev,
  781. (struct hdmi_any_infoframe *)frame);
  782. if (frame->channels)
  783. hdmi_log(" channels: %u\n", frame->channels - 1);
  784. else
  785. hdmi_log(" channels: Refer to stream header\n");
  786. hdmi_log(" coding type: %s\n",
  787. hdmi_audio_coding_type_get_name(frame->coding_type));
  788. hdmi_log(" sample size: %s\n",
  789. hdmi_audio_sample_size_get_name(frame->sample_size));
  790. hdmi_log(" sample frequency: %s\n",
  791. hdmi_audio_sample_frequency_get_name(frame->sample_frequency));
  792. hdmi_log(" coding type ext: %s\n",
  793. hdmi_audio_coding_type_ext_get_name(frame->coding_type_ext));
  794. hdmi_log(" channel allocation: 0x%x\n",
  795. frame->channel_allocation);
  796. hdmi_log(" level shift value: %u dB\n",
  797. frame->level_shift_value);
  798. hdmi_log(" downmix inhibit: %s\n",
  799. frame->downmix_inhibit ? "Yes" : "No");
  800. }
  801. static const char *
  802. hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct)
  803. {
  804. if (s3d_struct < 0 || s3d_struct > 0xf)
  805. return "Invalid";
  806. switch (s3d_struct) {
  807. case HDMI_3D_STRUCTURE_FRAME_PACKING:
  808. return "Frame Packing";
  809. case HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE:
  810. return "Field Alternative";
  811. case HDMI_3D_STRUCTURE_LINE_ALTERNATIVE:
  812. return "Line Alternative";
  813. case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL:
  814. return "Side-by-side (Full)";
  815. case HDMI_3D_STRUCTURE_L_DEPTH:
  816. return "L + Depth";
  817. case HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH:
  818. return "L + Depth + Graphics + Graphics-depth";
  819. case HDMI_3D_STRUCTURE_TOP_AND_BOTTOM:
  820. return "Top-and-Bottom";
  821. case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF:
  822. return "Side-by-side (Half)";
  823. default:
  824. break;
  825. }
  826. return "Reserved";
  827. }
  828. /**
  829. * hdmi_vendor_infoframe_log() - log info of HDMI VENDOR infoframe
  830. * @level: logging level
  831. * @dev: device
  832. * @frame: HDMI VENDOR infoframe
  833. */
  834. static void
  835. hdmi_vendor_any_infoframe_log(const char *level,
  836. struct device *dev,
  837. union hdmi_vendor_any_infoframe *frame)
  838. {
  839. struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
  840. hdmi_infoframe_log_header(level, dev,
  841. (struct hdmi_any_infoframe *)frame);
  842. if (frame->any.oui != HDMI_IEEE_OUI) {
  843. hdmi_log(" not a HDMI vendor infoframe\n");
  844. return;
  845. }
  846. if (hvf->vic == 0 && hvf->s3d_struct == HDMI_3D_STRUCTURE_INVALID) {
  847. hdmi_log(" empty frame\n");
  848. return;
  849. }
  850. if (hvf->vic)
  851. hdmi_log(" HDMI VIC: %u\n", hvf->vic);
  852. if (hvf->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
  853. hdmi_log(" 3D structure: %s\n",
  854. hdmi_3d_structure_get_name(hvf->s3d_struct));
  855. if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
  856. hdmi_log(" 3D extension data: %d\n",
  857. hvf->s3d_ext_data);
  858. }
  859. }
  860. /**
  861. * hdmi_infoframe_log() - log info of HDMI infoframe
  862. * @level: logging level
  863. * @dev: device
  864. * @frame: HDMI infoframe
  865. */
  866. void hdmi_infoframe_log(const char *level,
  867. struct device *dev,
  868. union hdmi_infoframe *frame)
  869. {
  870. switch (frame->any.type) {
  871. case HDMI_INFOFRAME_TYPE_AVI:
  872. hdmi_avi_infoframe_log(level, dev, &frame->avi);
  873. break;
  874. case HDMI_INFOFRAME_TYPE_SPD:
  875. hdmi_spd_infoframe_log(level, dev, &frame->spd);
  876. break;
  877. case HDMI_INFOFRAME_TYPE_AUDIO:
  878. hdmi_audio_infoframe_log(level, dev, &frame->audio);
  879. break;
  880. case HDMI_INFOFRAME_TYPE_VENDOR:
  881. hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
  882. break;
  883. }
  884. }
  885. EXPORT_SYMBOL(hdmi_infoframe_log);
  886. /**
  887. * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe
  888. * @buffer: source buffer
  889. * @frame: HDMI AVI infoframe
  890. *
  891. * Unpacks the information contained in binary @buffer into a structured
  892. * @frame of the HDMI Auxiliary Video (AVI) information frame.
  893. * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
  894. * specification.
  895. *
  896. * Returns 0 on success or a negative error code on failure.
  897. */
  898. static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
  899. void *buffer)
  900. {
  901. u8 *ptr = buffer;
  902. int ret;
  903. if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
  904. ptr[1] != 2 ||
  905. ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
  906. return -EINVAL;
  907. if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
  908. return -EINVAL;
  909. ret = hdmi_avi_infoframe_init(frame);
  910. if (ret)
  911. return ret;
  912. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  913. frame->colorspace = (ptr[0] >> 5) & 0x3;
  914. if (ptr[0] & 0x10)
  915. frame->active_aspect = ptr[1] & 0xf;
  916. if (ptr[0] & 0x8) {
  917. frame->top_bar = (ptr[5] << 8) + ptr[6];
  918. frame->bottom_bar = (ptr[7] << 8) + ptr[8];
  919. }
  920. if (ptr[0] & 0x4) {
  921. frame->left_bar = (ptr[9] << 8) + ptr[10];
  922. frame->right_bar = (ptr[11] << 8) + ptr[12];
  923. }
  924. frame->scan_mode = ptr[0] & 0x3;
  925. frame->colorimetry = (ptr[1] >> 6) & 0x3;
  926. frame->picture_aspect = (ptr[1] >> 4) & 0x3;
  927. frame->active_aspect = ptr[1] & 0xf;
  928. frame->itc = ptr[2] & 0x80 ? true : false;
  929. frame->extended_colorimetry = (ptr[2] >> 4) & 0x7;
  930. frame->quantization_range = (ptr[2] >> 2) & 0x3;
  931. frame->nups = ptr[2] & 0x3;
  932. frame->video_code = ptr[3] & 0x7f;
  933. frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3;
  934. frame->content_type = (ptr[4] >> 4) & 0x3;
  935. frame->pixel_repeat = ptr[4] & 0xf;
  936. return 0;
  937. }
  938. /**
  939. * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe
  940. * @buffer: source buffer
  941. * @frame: HDMI SPD infoframe
  942. *
  943. * Unpacks the information contained in binary @buffer into a structured
  944. * @frame of the HDMI Source Product Description (SPD) information frame.
  945. * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
  946. * specification.
  947. *
  948. * Returns 0 on success or a negative error code on failure.
  949. */
  950. static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
  951. void *buffer)
  952. {
  953. u8 *ptr = buffer;
  954. int ret;
  955. if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD ||
  956. ptr[1] != 1 ||
  957. ptr[2] != HDMI_SPD_INFOFRAME_SIZE) {
  958. return -EINVAL;
  959. }
  960. if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0)
  961. return -EINVAL;
  962. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  963. ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8);
  964. if (ret)
  965. return ret;
  966. frame->sdi = ptr[24];
  967. return 0;
  968. }
  969. /**
  970. * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe
  971. * @buffer: source buffer
  972. * @frame: HDMI Audio infoframe
  973. *
  974. * Unpacks the information contained in binary @buffer into a structured
  975. * @frame of the HDMI Audio information frame.
  976. * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
  977. * specification.
  978. *
  979. * Returns 0 on success or a negative error code on failure.
  980. */
  981. static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
  982. void *buffer)
  983. {
  984. u8 *ptr = buffer;
  985. int ret;
  986. if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO ||
  987. ptr[1] != 1 ||
  988. ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) {
  989. return -EINVAL;
  990. }
  991. if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0)
  992. return -EINVAL;
  993. ret = hdmi_audio_infoframe_init(frame);
  994. if (ret)
  995. return ret;
  996. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  997. frame->channels = ptr[0] & 0x7;
  998. frame->coding_type = (ptr[0] >> 4) & 0xf;
  999. frame->sample_size = ptr[1] & 0x3;
  1000. frame->sample_frequency = (ptr[1] >> 2) & 0x7;
  1001. frame->coding_type_ext = ptr[2] & 0x1f;
  1002. frame->channel_allocation = ptr[3];
  1003. frame->level_shift_value = (ptr[4] >> 3) & 0xf;
  1004. frame->downmix_inhibit = ptr[4] & 0x80 ? true : false;
  1005. return 0;
  1006. }
  1007. /**
  1008. * hdmi_vendor_infoframe_unpack() - unpack binary buffer to a HDMI vendor infoframe
  1009. * @buffer: source buffer
  1010. * @frame: HDMI Vendor infoframe
  1011. *
  1012. * Unpacks the information contained in binary @buffer into a structured
  1013. * @frame of the HDMI Vendor information frame.
  1014. * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
  1015. * specification.
  1016. *
  1017. * Returns 0 on success or a negative error code on failure.
  1018. */
  1019. static int
  1020. hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  1021. void *buffer)
  1022. {
  1023. u8 *ptr = buffer;
  1024. size_t length;
  1025. int ret;
  1026. u8 hdmi_video_format;
  1027. struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
  1028. if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR ||
  1029. ptr[1] != 1 ||
  1030. (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6))
  1031. return -EINVAL;
  1032. length = ptr[2];
  1033. if (hdmi_infoframe_checksum(buffer,
  1034. HDMI_INFOFRAME_HEADER_SIZE + length) != 0)
  1035. return -EINVAL;
  1036. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  1037. /* HDMI OUI */
  1038. if ((ptr[0] != 0x03) ||
  1039. (ptr[1] != 0x0c) ||
  1040. (ptr[2] != 0x00))
  1041. return -EINVAL;
  1042. hdmi_video_format = ptr[3] >> 5;
  1043. if (hdmi_video_format > 0x2)
  1044. return -EINVAL;
  1045. ret = hdmi_vendor_infoframe_init(hvf);
  1046. if (ret)
  1047. return ret;
  1048. hvf->length = length;
  1049. if (hdmi_video_format == 0x2) {
  1050. if (length != 5 && length != 6)
  1051. return -EINVAL;
  1052. hvf->s3d_struct = ptr[4] >> 4;
  1053. if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) {
  1054. if (length != 6)
  1055. return -EINVAL;
  1056. hvf->s3d_ext_data = ptr[5] >> 4;
  1057. }
  1058. } else if (hdmi_video_format == 0x1) {
  1059. if (length != 5)
  1060. return -EINVAL;
  1061. hvf->vic = ptr[4];
  1062. } else {
  1063. if (length != 4)
  1064. return -EINVAL;
  1065. }
  1066. return 0;
  1067. }
  1068. /**
  1069. * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
  1070. * @buffer: source buffer
  1071. * @frame: HDMI infoframe
  1072. *
  1073. * Unpacks the information contained in binary buffer @buffer into a structured
  1074. * @frame of a HDMI infoframe.
  1075. * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
  1076. * specification.
  1077. *
  1078. * Returns 0 on success or a negative error code on failure.
  1079. */
  1080. int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer)
  1081. {
  1082. int ret;
  1083. u8 *ptr = buffer;
  1084. switch (ptr[0]) {
  1085. case HDMI_INFOFRAME_TYPE_AVI:
  1086. ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer);
  1087. break;
  1088. case HDMI_INFOFRAME_TYPE_SPD:
  1089. ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer);
  1090. break;
  1091. case HDMI_INFOFRAME_TYPE_AUDIO:
  1092. ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer);
  1093. break;
  1094. case HDMI_INFOFRAME_TYPE_VENDOR:
  1095. ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer);
  1096. break;
  1097. default:
  1098. ret = -EINVAL;
  1099. break;
  1100. }
  1101. return ret;
  1102. }
  1103. EXPORT_SYMBOL(hdmi_infoframe_unpack);