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

Generated by: LCOV version 1.14