hdmi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  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. static void hdmi_infoframe_checksum(void *buffer, size_t size)
  30. {
  31. u8 *ptr = buffer;
  32. u8 csum = 0;
  33. size_t i;
  34. /* compute checksum */
  35. for (i = 0; i < size; i++)
  36. csum += ptr[i];
  37. ptr[3] = 256 - csum;
  38. }
  39. /**
  40. * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
  41. * @frame: HDMI AVI infoframe
  42. *
  43. * Returns 0 on success or a negative error code on failure.
  44. */
  45. int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
  46. {
  47. memset(frame, 0, sizeof(*frame));
  48. frame->type = HDMI_INFOFRAME_TYPE_AVI;
  49. frame->version = 2;
  50. frame->length = HDMI_AVI_INFOFRAME_SIZE;
  51. return 0;
  52. }
  53. EXPORT_SYMBOL(hdmi_avi_infoframe_init);
  54. /**
  55. * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
  56. * @frame: HDMI AVI infoframe
  57. * @buffer: destination buffer
  58. * @size: size of buffer
  59. *
  60. * Packs the information contained in the @frame structure into a binary
  61. * representation that can be written into the corresponding controller
  62. * registers. Also computes the checksum as required by section 5.3.5 of
  63. * the HDMI 1.4 specification.
  64. *
  65. * Returns the number of bytes packed into the binary buffer or a negative
  66. * error code on failure.
  67. */
  68. ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
  69. size_t size)
  70. {
  71. u8 *ptr = buffer;
  72. size_t length;
  73. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  74. if (size < length)
  75. return -ENOSPC;
  76. memset(buffer, 0, size);
  77. ptr[0] = frame->type;
  78. ptr[1] = frame->version;
  79. ptr[2] = frame->length;
  80. ptr[3] = 0; /* checksum */
  81. /* start infoframe payload */
  82. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  83. ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
  84. /*
  85. * Data byte 1, bit 4 has to be set if we provide the active format
  86. * aspect ratio
  87. */
  88. if (frame->active_aspect & 0xf)
  89. ptr[0] |= BIT(4);
  90. /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */
  91. if (frame->top_bar || frame->bottom_bar)
  92. ptr[0] |= BIT(3);
  93. if (frame->left_bar || frame->right_bar)
  94. ptr[0] |= BIT(2);
  95. ptr[1] = ((frame->colorimetry & 0x3) << 6) |
  96. ((frame->picture_aspect & 0x3) << 4) |
  97. (frame->active_aspect & 0xf);
  98. ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
  99. ((frame->quantization_range & 0x3) << 2) |
  100. (frame->nups & 0x3);
  101. if (frame->itc)
  102. ptr[2] |= BIT(7);
  103. ptr[3] = frame->video_code & 0x7f;
  104. ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
  105. ((frame->content_type & 0x3) << 4) |
  106. (frame->pixel_repeat & 0xf);
  107. ptr[5] = frame->top_bar & 0xff;
  108. ptr[6] = (frame->top_bar >> 8) & 0xff;
  109. ptr[7] = frame->bottom_bar & 0xff;
  110. ptr[8] = (frame->bottom_bar >> 8) & 0xff;
  111. ptr[9] = frame->left_bar & 0xff;
  112. ptr[10] = (frame->left_bar >> 8) & 0xff;
  113. ptr[11] = frame->right_bar & 0xff;
  114. ptr[12] = (frame->right_bar >> 8) & 0xff;
  115. hdmi_infoframe_checksum(buffer, length);
  116. return length;
  117. }
  118. EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
  119. /**
  120. * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
  121. * @frame: HDMI SPD infoframe
  122. * @vendor: vendor string
  123. * @product: product string
  124. *
  125. * Returns 0 on success or a negative error code on failure.
  126. */
  127. int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
  128. const char *vendor, const char *product)
  129. {
  130. memset(frame, 0, sizeof(*frame));
  131. frame->type = HDMI_INFOFRAME_TYPE_SPD;
  132. frame->version = 1;
  133. frame->length = HDMI_SPD_INFOFRAME_SIZE;
  134. strncpy(frame->vendor, vendor, sizeof(frame->vendor));
  135. strncpy(frame->product, product, sizeof(frame->product));
  136. return 0;
  137. }
  138. EXPORT_SYMBOL(hdmi_spd_infoframe_init);
  139. /**
  140. * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
  141. * @frame: HDMI SPD infoframe
  142. * @buffer: destination buffer
  143. * @size: size of buffer
  144. *
  145. * Packs the information contained in the @frame structure into a binary
  146. * representation that can be written into the corresponding controller
  147. * registers. Also computes the checksum as required by section 5.3.5 of
  148. * the HDMI 1.4 specification.
  149. *
  150. * Returns the number of bytes packed into the binary buffer or a negative
  151. * error code on failure.
  152. */
  153. ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
  154. size_t size)
  155. {
  156. u8 *ptr = buffer;
  157. size_t length;
  158. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  159. if (size < length)
  160. return -ENOSPC;
  161. memset(buffer, 0, size);
  162. ptr[0] = frame->type;
  163. ptr[1] = frame->version;
  164. ptr[2] = frame->length;
  165. ptr[3] = 0; /* checksum */
  166. /* start infoframe payload */
  167. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  168. memcpy(ptr, frame->vendor, sizeof(frame->vendor));
  169. memcpy(ptr + 8, frame->product, sizeof(frame->product));
  170. ptr[24] = frame->sdi;
  171. hdmi_infoframe_checksum(buffer, length);
  172. return length;
  173. }
  174. EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
  175. /**
  176. * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
  177. * @frame: HDMI audio infoframe
  178. *
  179. * Returns 0 on success or a negative error code on failure.
  180. */
  181. int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
  182. {
  183. memset(frame, 0, sizeof(*frame));
  184. frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
  185. frame->version = 1;
  186. frame->length = HDMI_AUDIO_INFOFRAME_SIZE;
  187. return 0;
  188. }
  189. EXPORT_SYMBOL(hdmi_audio_infoframe_init);
  190. /**
  191. * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
  192. * @frame: HDMI audio infoframe
  193. * @buffer: destination buffer
  194. * @size: size of buffer
  195. *
  196. * Packs the information contained in the @frame structure into a binary
  197. * representation that can be written into the corresponding controller
  198. * registers. Also computes the checksum as required by section 5.3.5 of
  199. * the HDMI 1.4 specification.
  200. *
  201. * Returns the number of bytes packed into the binary buffer or a negative
  202. * error code on failure.
  203. */
  204. ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
  205. void *buffer, size_t size)
  206. {
  207. unsigned char channels;
  208. u8 *ptr = buffer;
  209. size_t length;
  210. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  211. if (size < length)
  212. return -ENOSPC;
  213. memset(buffer, 0, size);
  214. if (frame->channels >= 2)
  215. channels = frame->channels - 1;
  216. else
  217. channels = 0;
  218. ptr[0] = frame->type;
  219. ptr[1] = frame->version;
  220. ptr[2] = frame->length;
  221. ptr[3] = 0; /* checksum */
  222. /* start infoframe payload */
  223. ptr += HDMI_INFOFRAME_HEADER_SIZE;
  224. ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
  225. ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
  226. (frame->sample_size & 0x3);
  227. ptr[2] = frame->coding_type_ext & 0x1f;
  228. ptr[3] = frame->channel_allocation;
  229. ptr[4] = (frame->level_shift_value & 0xf) << 3;
  230. if (frame->downmix_inhibit)
  231. ptr[4] |= BIT(7);
  232. hdmi_infoframe_checksum(buffer, length);
  233. return length;
  234. }
  235. EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
  236. /**
  237. * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  238. * @frame: HDMI vendor infoframe
  239. *
  240. * Returns 0 on success or a negative error code on failure.
  241. */
  242. int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
  243. {
  244. memset(frame, 0, sizeof(*frame));
  245. frame->type = HDMI_INFOFRAME_TYPE_VENDOR;
  246. frame->version = 1;
  247. frame->oui = HDMI_IEEE_OUI;
  248. /*
  249. * 0 is a valid value for s3d_struct, so we use a special "not set"
  250. * value
  251. */
  252. frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
  253. return 0;
  254. }
  255. EXPORT_SYMBOL(hdmi_vendor_infoframe_init);
  256. /**
  257. * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer
  258. * @frame: HDMI infoframe
  259. * @buffer: destination buffer
  260. * @size: size of buffer
  261. *
  262. * Packs the information contained in the @frame structure into a binary
  263. * representation that can be written into the corresponding controller
  264. * registers. Also computes the checksum as required by section 5.3.5 of
  265. * the HDMI 1.4 specification.
  266. *
  267. * Returns the number of bytes packed into the binary buffer or a negative
  268. * error code on failure.
  269. */
  270. ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
  271. void *buffer, size_t size)
  272. {
  273. u8 *ptr = buffer;
  274. size_t length;
  275. /* empty info frame */
  276. if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID)
  277. return -EINVAL;
  278. /* only one of those can be supplied */
  279. if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
  280. return -EINVAL;
  281. /* for side by side (half) we also need to provide 3D_Ext_Data */
  282. if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
  283. frame->length = 6;
  284. else
  285. frame->length = 5;
  286. length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
  287. if (size < length)
  288. return -ENOSPC;
  289. memset(buffer, 0, size);
  290. ptr[0] = frame->type;
  291. ptr[1] = frame->version;
  292. ptr[2] = frame->length;
  293. ptr[3] = 0; /* checksum */
  294. /* HDMI OUI */
  295. ptr[4] = 0x03;
  296. ptr[5] = 0x0c;
  297. ptr[6] = 0x00;
  298. if (frame->vic) {
  299. ptr[7] = 0x1 << 5; /* video format */
  300. ptr[8] = frame->vic;
  301. } else {
  302. ptr[7] = 0x2 << 5; /* video format */
  303. ptr[8] = (frame->s3d_struct & 0xf) << 4;
  304. if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
  305. ptr[9] = (frame->s3d_ext_data & 0xf) << 4;
  306. }
  307. hdmi_infoframe_checksum(buffer, length);
  308. return length;
  309. }
  310. EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
  311. /*
  312. * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer
  313. */
  314. static ssize_t
  315. hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
  316. void *buffer, size_t size)
  317. {
  318. /* we only know about HDMI vendor infoframes */
  319. if (frame->any.oui != HDMI_IEEE_OUI)
  320. return -EINVAL;
  321. return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size);
  322. }
  323. /**
  324. * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer
  325. * @frame: HDMI infoframe
  326. * @buffer: destination buffer
  327. * @size: size of buffer
  328. *
  329. * Packs the information contained in the @frame structure into a binary
  330. * representation that can be written into the corresponding controller
  331. * registers. Also computes the checksum as required by section 5.3.5 of
  332. * the HDMI 1.4 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
  338. hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size)
  339. {
  340. ssize_t length;
  341. switch (frame->any.type) {
  342. case HDMI_INFOFRAME_TYPE_AVI:
  343. length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size);
  344. break;
  345. case HDMI_INFOFRAME_TYPE_SPD:
  346. length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size);
  347. break;
  348. case HDMI_INFOFRAME_TYPE_AUDIO:
  349. length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size);
  350. break;
  351. case HDMI_INFOFRAME_TYPE_VENDOR:
  352. length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
  353. buffer, size);
  354. break;
  355. default:
  356. WARN(1, "Bad infoframe type %d\n", frame->any.type);
  357. length = -EINVAL;
  358. }
  359. return length;
  360. }
  361. EXPORT_SYMBOL(hdmi_infoframe_pack);