LCOV - code coverage report
Current view: top level - drivers/video - hdmi.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 530 0.0 %
Date: 2023-04-06 08:38:28 Functions: 0 43 0.0 %

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

Generated by: LCOV version 1.14