LCOV - code coverage report
Current view: top level - drivers/video - hdmi.c (source / functions) Hit Total Coverage
Test: Real Lines: 0 462 0.0 %
Date: 2020-10-17 15:46:16 Functions: 0 40 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     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                 :            :         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                 :            :         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                 :            :  * Returns 0 on success or a negative error code on failure.
      58                 :            :  */
      59                 :          0 : int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
      60                 :            : {
      61                 :          0 :         memset(frame, 0, sizeof(*frame));
      62                 :            : 
      63                 :          0 :         frame->type = HDMI_INFOFRAME_TYPE_AVI;
      64                 :          0 :         frame->version = 2;
      65                 :          0 :         frame->length = HDMI_AVI_INFOFRAME_SIZE;
      66                 :            : 
      67                 :          0 :         return 0;
      68                 :            : }
      69                 :            : EXPORT_SYMBOL(hdmi_avi_infoframe_init);
      70                 :            : 
      71                 :            : static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame)
      72                 :            : {
      73                 :          0 :         if (frame->type != HDMI_INFOFRAME_TYPE_AVI ||
      74                 :          0 :             frame->version != 2 ||
      75                 :            :             frame->length != HDMI_AVI_INFOFRAME_SIZE)
      76                 :            :                 return -EINVAL;
      77                 :            : 
      78                 :          0 :         if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
      79                 :            :                 return -EINVAL;
      80                 :            : 
      81                 :            :         return 0;
      82                 :            : }
      83                 :            : 
      84                 :            : /**
      85                 :            :  * hdmi_avi_infoframe_check() - check a HDMI AVI infoframe
      86                 :            :  * @frame: HDMI AVI infoframe
      87                 :            :  *
      88                 :            :  * Validates that the infoframe is consistent and updates derived fields
      89                 :            :  * (eg. length) based on other fields.
      90                 :            :  *
      91                 :            :  * Returns 0 on success or a negative error code on failure.
      92                 :            :  */
      93                 :          0 : int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame)
      94                 :            : {
      95                 :          0 :         return hdmi_avi_infoframe_check_only(frame);
      96                 :            : }
      97                 :            : EXPORT_SYMBOL(hdmi_avi_infoframe_check);
      98                 :            : 
      99                 :            : /**
     100                 :            :  * hdmi_avi_infoframe_pack_only() - write HDMI AVI infoframe to binary buffer
     101                 :            :  * @frame: HDMI AVI infoframe
     102                 :            :  * @buffer: destination buffer
     103                 :            :  * @size: size of buffer
     104                 :            :  *
     105                 :            :  * Packs the information contained in the @frame structure into a binary
     106                 :            :  * representation that can be written into the corresponding controller
     107                 :            :  * registers. Also computes the checksum as required by section 5.3.5 of
     108                 :            :  * the HDMI 1.4 specification.
     109                 :            :  *
     110                 :            :  * Returns the number of bytes packed into the binary buffer or a negative
     111                 :            :  * error code on failure.
     112                 :            :  */
     113                 :          0 : ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
     114                 :            :                                      void *buffer, size_t size)
     115                 :            : {
     116                 :            :         u8 *ptr = buffer;
     117                 :            :         size_t length;
     118                 :            :         int ret;
     119                 :            : 
     120                 :            :         ret = hdmi_avi_infoframe_check_only(frame);
     121                 :          0 :         if (ret)
     122                 :            :                 return ret;
     123                 :            : 
     124                 :          0 :         length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
     125                 :            : 
     126                 :          0 :         if (size < length)
     127                 :            :                 return -ENOSPC;
     128                 :            : 
     129                 :          0 :         memset(buffer, 0, size);
     130                 :            : 
     131                 :          0 :         ptr[0] = frame->type;
     132                 :          0 :         ptr[1] = frame->version;
     133                 :          0 :         ptr[2] = frame->length;
     134                 :          0 :         ptr[3] = 0; /* checksum */
     135                 :            : 
     136                 :            :         /* start infoframe payload */
     137                 :            :         ptr += HDMI_INFOFRAME_HEADER_SIZE;
     138                 :            : 
     139                 :          0 :         ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
     140                 :            : 
     141                 :            :         /*
     142                 :            :          * Data byte 1, bit 4 has to be set if we provide the active format
     143                 :            :          * aspect ratio
     144                 :            :          */
     145                 :          0 :         if (frame->active_aspect & 0xf)
     146                 :          0 :                 ptr[0] |= BIT(4);
     147                 :            : 
     148                 :            :         /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */
     149                 :          0 :         if (frame->top_bar || frame->bottom_bar)
     150                 :          0 :                 ptr[0] |= BIT(3);
     151                 :            : 
     152                 :          0 :         if (frame->left_bar || frame->right_bar)
     153                 :          0 :                 ptr[0] |= BIT(2);
     154                 :            : 
     155                 :          0 :         ptr[1] = ((frame->colorimetry & 0x3) << 6) |
     156                 :          0 :                  ((frame->picture_aspect & 0x3) << 4) |
     157                 :          0 :                  (frame->active_aspect & 0xf);
     158                 :            : 
     159                 :          0 :         ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
     160                 :          0 :                  ((frame->quantization_range & 0x3) << 2) |
     161                 :          0 :                  (frame->nups & 0x3);
     162                 :            : 
     163                 :          0 :         if (frame->itc)
     164                 :          0 :                 ptr[2] |= BIT(7);
     165                 :            : 
     166                 :          0 :         ptr[3] = frame->video_code & 0x7f;
     167                 :            : 
     168                 :          0 :         ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
     169                 :          0 :                  ((frame->content_type & 0x3) << 4) |
     170                 :          0 :                  (frame->pixel_repeat & 0xf);
     171                 :            : 
     172                 :          0 :         ptr[5] = frame->top_bar & 0xff;
     173                 :          0 :         ptr[6] = (frame->top_bar >> 8) & 0xff;
     174                 :          0 :         ptr[7] = frame->bottom_bar & 0xff;
     175                 :          0 :         ptr[8] = (frame->bottom_bar >> 8) & 0xff;
     176                 :          0 :         ptr[9] = frame->left_bar & 0xff;
     177                 :          0 :         ptr[10] = (frame->left_bar >> 8) & 0xff;
     178                 :          0 :         ptr[11] = frame->right_bar & 0xff;
     179                 :          0 :         ptr[12] = (frame->right_bar >> 8) & 0xff;
     180                 :            : 
     181                 :            :         hdmi_infoframe_set_checksum(buffer, length);
     182                 :            : 
     183                 :          0 :         return length;
     184                 :            : }
     185                 :            : EXPORT_SYMBOL(hdmi_avi_infoframe_pack_only);
     186                 :            : 
     187                 :            : /**
     188                 :            :  * hdmi_avi_infoframe_pack() - check a HDMI AVI infoframe,
     189                 :            :  *                             and write it to binary buffer
     190                 :            :  * @frame: HDMI AVI infoframe
     191                 :            :  * @buffer: destination buffer
     192                 :            :  * @size: size of buffer
     193                 :            :  *
     194                 :            :  * Validates that the infoframe is consistent and updates derived fields
     195                 :            :  * (eg. length) based on other fields, after which it packs the information
     196                 :            :  * contained in the @frame structure into a binary representation that
     197                 :            :  * can be written into the corresponding controller registers. This function
     198                 :            :  * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
     199                 :            :  * specification.
     200                 :            :  *
     201                 :            :  * Returns the number of bytes packed into the binary buffer or a negative
     202                 :            :  * error code on failure.
     203                 :            :  */
     204                 :          0 : ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame,
     205                 :            :                                 void *buffer, size_t size)
     206                 :            : {
     207                 :            :         int ret;
     208                 :            : 
     209                 :            :         ret = hdmi_avi_infoframe_check(frame);
     210                 :          0 :         if (ret)
     211                 :            :                 return ret;
     212                 :            : 
     213                 :          0 :         return hdmi_avi_infoframe_pack_only(frame, buffer, size);
     214                 :            : }
     215                 :            : EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
     216                 :            : 
     217                 :            : /**
     218                 :            :  * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
     219                 :            :  * @frame: HDMI SPD infoframe
     220                 :            :  * @vendor: vendor string
     221                 :            :  * @product: product string
     222                 :            :  *
     223                 :            :  * Returns 0 on success or a negative error code on failure.
     224                 :            :  */
     225                 :          0 : int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
     226                 :            :                             const char *vendor, const char *product)
     227                 :            : {
     228                 :          0 :         memset(frame, 0, sizeof(*frame));
     229                 :            : 
     230                 :          0 :         frame->type = HDMI_INFOFRAME_TYPE_SPD;
     231                 :          0 :         frame->version = 1;
     232                 :          0 :         frame->length = HDMI_SPD_INFOFRAME_SIZE;
     233                 :            : 
     234                 :          0 :         strncpy(frame->vendor, vendor, sizeof(frame->vendor));
     235                 :          0 :         strncpy(frame->product, product, 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                 :            :         u8 *ptr = buffer;
     284                 :            :         size_t length;
     285                 :            :         int ret;
     286                 :            : 
     287                 :            :         ret = hdmi_spd_infoframe_check_only(frame);
     288                 :          0 :         if (ret)
     289                 :            :                 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                 :            :         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                 :            :         ret = hdmi_spd_infoframe_check(frame);
     340                 :          0 :         if (ret)
     341                 :            :                 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                 :            :         u8 *ptr = buffer;
     409                 :            :         size_t length;
     410                 :            :         int ret;
     411                 :            : 
     412                 :            :         ret = hdmi_audio_infoframe_check_only(frame);
     413                 :          0 :         if (ret)
     414                 :            :                 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                 :            :         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                 :            :         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                 :            :         ret = hdmi_audio_infoframe_check(frame);
     475                 :          0 :         if (ret)
     476                 :            :                 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 = 4;
     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                 :            :         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                 :            :                 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                 :            :         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                 :            :                 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                 :            :         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                 :            :         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                 :            :         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                 :            :         ret = hdmi_drm_infoframe_check(frame);
     790                 :          0 :         if (ret)
     791                 :            :                 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                 :            :         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                 :            :         ret = hdmi_vendor_any_infoframe_check_only(frame);
     826                 :          0 :         if (ret)
     827                 :            :                 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                 :            :                 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                 :            :                 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                 :          0 :                 break;
     963                 :            :         case HDMI_INFOFRAME_TYPE_AUDIO:
     964                 :          0 :                 length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size);
     965                 :          0 :                 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                 :            :                 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                 :            :         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                 :            :         const u8 *ptr = buffer;
    1556                 :            :         int ret;
    1557                 :            : 
    1558                 :          0 :         if (size < HDMI_INFOFRAME_SIZE(AVI))
    1559                 :            :                 return -EINVAL;
    1560                 :            : 
    1561                 :          0 :         if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
    1562                 :          0 :             ptr[1] != 2 ||
    1563                 :          0 :             ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
    1564                 :            :                 return -EINVAL;
    1565                 :            : 
    1566                 :          0 :         if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
    1567                 :            :                 return -EINVAL;
    1568                 :            : 
    1569                 :            :         ret = hdmi_avi_infoframe_init(frame);
    1570                 :            :         if (ret)
    1571                 :            :                 return ret;
    1572                 :            : 
    1573                 :            :         ptr += HDMI_INFOFRAME_HEADER_SIZE;
    1574                 :            : 
    1575                 :          0 :         frame->colorspace = (ptr[0] >> 5) & 0x3;
    1576                 :          0 :         if (ptr[0] & 0x10)
    1577                 :          0 :                 frame->active_aspect = ptr[1] & 0xf;
    1578                 :          0 :         if (ptr[0] & 0x8) {
    1579                 :          0 :                 frame->top_bar = (ptr[6] << 8) | ptr[5];
    1580                 :          0 :                 frame->bottom_bar = (ptr[8] << 8) | ptr[7];
    1581                 :            :         }
    1582                 :          0 :         if (ptr[0] & 0x4) {
    1583                 :          0 :                 frame->left_bar = (ptr[10] << 8) | ptr[9];
    1584                 :          0 :                 frame->right_bar = (ptr[12] << 8) | ptr[11];
    1585                 :            :         }
    1586                 :          0 :         frame->scan_mode = ptr[0] & 0x3;
    1587                 :            : 
    1588                 :          0 :         frame->colorimetry = (ptr[1] >> 6) & 0x3;
    1589                 :          0 :         frame->picture_aspect = (ptr[1] >> 4) & 0x3;
    1590                 :          0 :         frame->active_aspect = ptr[1] & 0xf;
    1591                 :            : 
    1592                 :          0 :         frame->itc = ptr[2] & 0x80 ? true : false;
    1593                 :          0 :         frame->extended_colorimetry = (ptr[2] >> 4) & 0x7;
    1594                 :          0 :         frame->quantization_range = (ptr[2] >> 2) & 0x3;
    1595                 :          0 :         frame->nups = ptr[2] & 0x3;
    1596                 :            : 
    1597                 :          0 :         frame->video_code = ptr[3] & 0x7f;
    1598                 :          0 :         frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3;
    1599                 :          0 :         frame->content_type = (ptr[4] >> 4) & 0x3;
    1600                 :            : 
    1601                 :          0 :         frame->pixel_repeat = ptr[4] & 0xf;
    1602                 :            : 
    1603                 :          0 :         return 0;
    1604                 :            : }
    1605                 :            : 
    1606                 :            : /**
    1607                 :            :  * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe
    1608                 :            :  * @frame: HDMI SPD infoframe
    1609                 :            :  * @buffer: source buffer
    1610                 :            :  * @size: size of buffer
    1611                 :            :  *
    1612                 :            :  * Unpacks the information contained in binary @buffer into a structured
    1613                 :            :  * @frame of the HDMI Source Product Description (SPD) information frame.
    1614                 :            :  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
    1615                 :            :  * specification.
    1616                 :            :  *
    1617                 :            :  * Returns 0 on success or a negative error code on failure.
    1618                 :            :  */
    1619                 :          0 : static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
    1620                 :            :                                      const void *buffer, size_t size)
    1621                 :            : {
    1622                 :            :         const u8 *ptr = buffer;
    1623                 :            :         int ret;
    1624                 :            : 
    1625                 :          0 :         if (size < HDMI_INFOFRAME_SIZE(SPD))
    1626                 :            :                 return -EINVAL;
    1627                 :            : 
    1628                 :          0 :         if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD ||
    1629                 :          0 :             ptr[1] != 1 ||
    1630                 :          0 :             ptr[2] != HDMI_SPD_INFOFRAME_SIZE) {
    1631                 :            :                 return -EINVAL;
    1632                 :            :         }
    1633                 :            : 
    1634                 :          0 :         if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0)
    1635                 :            :                 return -EINVAL;
    1636                 :            : 
    1637                 :          0 :         ptr += HDMI_INFOFRAME_HEADER_SIZE;
    1638                 :            : 
    1639                 :          0 :         ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8);
    1640                 :          0 :         if (ret)
    1641                 :            :                 return ret;
    1642                 :            : 
    1643                 :          0 :         frame->sdi = ptr[24];
    1644                 :            : 
    1645                 :          0 :         return 0;
    1646                 :            : }
    1647                 :            : 
    1648                 :            : /**
    1649                 :            :  * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe
    1650                 :            :  * @frame: HDMI Audio infoframe
    1651                 :            :  * @buffer: source buffer
    1652                 :            :  * @size: size of buffer
    1653                 :            :  *
    1654                 :            :  * Unpacks the information contained in binary @buffer into a structured
    1655                 :            :  * @frame of the HDMI Audio information frame.
    1656                 :            :  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
    1657                 :            :  * specification.
    1658                 :            :  *
    1659                 :            :  * Returns 0 on success or a negative error code on failure.
    1660                 :            :  */
    1661                 :          0 : static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
    1662                 :            :                                        const void *buffer, size_t size)
    1663                 :            : {
    1664                 :            :         const u8 *ptr = buffer;
    1665                 :            :         int ret;
    1666                 :            : 
    1667                 :          0 :         if (size < HDMI_INFOFRAME_SIZE(AUDIO))
    1668                 :            :                 return -EINVAL;
    1669                 :            : 
    1670                 :          0 :         if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO ||
    1671                 :          0 :             ptr[1] != 1 ||
    1672                 :          0 :             ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) {
    1673                 :            :                 return -EINVAL;
    1674                 :            :         }
    1675                 :            : 
    1676                 :          0 :         if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0)
    1677                 :            :                 return -EINVAL;
    1678                 :            : 
    1679                 :            :         ret = hdmi_audio_infoframe_init(frame);
    1680                 :            :         if (ret)
    1681                 :            :                 return ret;
    1682                 :            : 
    1683                 :            :         ptr += HDMI_INFOFRAME_HEADER_SIZE;
    1684                 :            : 
    1685                 :          0 :         frame->channels = ptr[0] & 0x7;
    1686                 :          0 :         frame->coding_type = (ptr[0] >> 4) & 0xf;
    1687                 :          0 :         frame->sample_size = ptr[1] & 0x3;
    1688                 :          0 :         frame->sample_frequency = (ptr[1] >> 2) & 0x7;
    1689                 :          0 :         frame->coding_type_ext = ptr[2] & 0x1f;
    1690                 :          0 :         frame->channel_allocation = ptr[3];
    1691                 :          0 :         frame->level_shift_value = (ptr[4] >> 3) & 0xf;
    1692                 :          0 :         frame->downmix_inhibit = ptr[4] & 0x80 ? true : false;
    1693                 :            : 
    1694                 :          0 :         return 0;
    1695                 :            : }
    1696                 :            : 
    1697                 :            : /**
    1698                 :            :  * hdmi_vendor_infoframe_unpack() - unpack binary buffer to a HDMI vendor infoframe
    1699                 :            :  * @frame: HDMI Vendor infoframe
    1700                 :            :  * @buffer: source buffer
    1701                 :            :  * @size: size of buffer
    1702                 :            :  *
    1703                 :            :  * Unpacks the information contained in binary @buffer into a structured
    1704                 :            :  * @frame of the HDMI Vendor information frame.
    1705                 :            :  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
    1706                 :            :  * specification.
    1707                 :            :  *
    1708                 :            :  * Returns 0 on success or a negative error code on failure.
    1709                 :            :  */
    1710                 :            : static int
    1711                 :          0 : hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
    1712                 :            :                                  const void *buffer, size_t size)
    1713                 :            : {
    1714                 :            :         const u8 *ptr = buffer;
    1715                 :            :         size_t length;
    1716                 :            :         int ret;
    1717                 :            :         u8 hdmi_video_format;
    1718                 :          0 :         struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
    1719                 :            : 
    1720                 :          0 :         if (size < HDMI_INFOFRAME_HEADER_SIZE)
    1721                 :            :                 return -EINVAL;
    1722                 :            : 
    1723                 :          0 :         if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR ||
    1724                 :          0 :             ptr[1] != 1 ||
    1725                 :          0 :             (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6))
    1726                 :            :                 return -EINVAL;
    1727                 :            : 
    1728                 :          0 :         length = ptr[2];
    1729                 :            : 
    1730                 :          0 :         if (size < HDMI_INFOFRAME_HEADER_SIZE + length)
    1731                 :            :                 return -EINVAL;
    1732                 :            : 
    1733                 :          0 :         if (hdmi_infoframe_checksum(buffer,
    1734                 :            :                                     HDMI_INFOFRAME_HEADER_SIZE + length) != 0)
    1735                 :            :                 return -EINVAL;
    1736                 :            : 
    1737                 :            :         ptr += HDMI_INFOFRAME_HEADER_SIZE;
    1738                 :            : 
    1739                 :            :         /* HDMI OUI */
    1740                 :          0 :         if ((ptr[0] != 0x03) ||
    1741                 :          0 :             (ptr[1] != 0x0c) ||
    1742                 :          0 :             (ptr[2] != 0x00))
    1743                 :            :                 return -EINVAL;
    1744                 :            : 
    1745                 :          0 :         hdmi_video_format = ptr[3] >> 5;
    1746                 :            : 
    1747                 :          0 :         if (hdmi_video_format > 0x2)
    1748                 :            :                 return -EINVAL;
    1749                 :            : 
    1750                 :            :         ret = hdmi_vendor_infoframe_init(hvf);
    1751                 :            :         if (ret)
    1752                 :            :                 return ret;
    1753                 :            : 
    1754                 :          0 :         hvf->length = length;
    1755                 :            : 
    1756                 :          0 :         if (hdmi_video_format == 0x2) {
    1757                 :          0 :                 if (length != 5 && length != 6)
    1758                 :            :                         return -EINVAL;
    1759                 :          0 :                 hvf->s3d_struct = ptr[4] >> 4;
    1760                 :          0 :                 if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) {
    1761                 :          0 :                         if (length != 6)
    1762                 :            :                                 return -EINVAL;
    1763                 :          0 :                         hvf->s3d_ext_data = ptr[5] >> 4;
    1764                 :            :                 }
    1765                 :          0 :         } else if (hdmi_video_format == 0x1) {
    1766                 :          0 :                 if (length != 5)
    1767                 :            :                         return -EINVAL;
    1768                 :          0 :                 hvf->vic = ptr[4];
    1769                 :            :         } else {
    1770                 :          0 :                 if (length != 4)
    1771                 :            :                         return -EINVAL;
    1772                 :            :         }
    1773                 :            : 
    1774                 :            :         return 0;
    1775                 :            : }
    1776                 :            : 
    1777                 :            : /**
    1778                 :            :  * hdmi_drm_infoframe_unpack() - unpack binary buffer to a HDMI DRM infoframe
    1779                 :            :  * @frame: HDMI DRM infoframe
    1780                 :            :  * @buffer: source buffer
    1781                 :            :  * @size: size of buffer
    1782                 :            :  *
    1783                 :            :  * Unpacks the information contained in binary @buffer into a structured
    1784                 :            :  * @frame of the HDMI Dynamic Range and Mastering (DRM) information frame.
    1785                 :            :  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
    1786                 :            :  * specification.
    1787                 :            :  *
    1788                 :            :  * Returns 0 on success or a negative error code on failure.
    1789                 :            :  */
    1790                 :          0 : static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
    1791                 :            :                                      const void *buffer, size_t size)
    1792                 :            : {
    1793                 :            :         const u8 *ptr = buffer;
    1794                 :            :         const u8 *temp;
    1795                 :            :         u8 x_lsb, x_msb;
    1796                 :            :         u8 y_lsb, y_msb;
    1797                 :            :         int ret;
    1798                 :            :         int i;
    1799                 :            : 
    1800                 :          0 :         if (size < HDMI_INFOFRAME_SIZE(DRM))
    1801                 :            :                 return -EINVAL;
    1802                 :            : 
    1803                 :          0 :         if (ptr[0] != HDMI_INFOFRAME_TYPE_DRM ||
    1804                 :          0 :             ptr[1] != 1 ||
    1805                 :          0 :             ptr[2] != HDMI_DRM_INFOFRAME_SIZE)
    1806                 :            :                 return -EINVAL;
    1807                 :            : 
    1808                 :          0 :         if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(DRM)) != 0)
    1809                 :            :                 return -EINVAL;
    1810                 :            : 
    1811                 :            :         ret = hdmi_drm_infoframe_init(frame);
    1812                 :            :         if (ret)
    1813                 :            :                 return ret;
    1814                 :            : 
    1815                 :            :         ptr += HDMI_INFOFRAME_HEADER_SIZE;
    1816                 :            : 
    1817                 :          0 :         frame->eotf = ptr[0] & 0x7;
    1818                 :          0 :         frame->metadata_type = ptr[1] & 0x7;
    1819                 :            : 
    1820                 :          0 :         temp = ptr + 2;
    1821                 :          0 :         for (i = 0; i < 3; i++) {
    1822                 :          0 :                 x_lsb = *temp++;
    1823                 :          0 :                 x_msb = *temp++;
    1824                 :          0 :                 frame->display_primaries[i].x =  (x_msb << 8) | x_lsb;
    1825                 :          0 :                 y_lsb = *temp++;
    1826                 :          0 :                 y_msb = *temp++;
    1827                 :          0 :                 frame->display_primaries[i].y = (y_msb << 8) | y_lsb;
    1828                 :            :         }
    1829                 :            : 
    1830                 :          0 :         frame->white_point.x = (ptr[15] << 8) | ptr[14];
    1831                 :          0 :         frame->white_point.y = (ptr[17] << 8) | ptr[16];
    1832                 :            : 
    1833                 :          0 :         frame->max_display_mastering_luminance = (ptr[19] << 8) | ptr[18];
    1834                 :          0 :         frame->min_display_mastering_luminance = (ptr[21] << 8) | ptr[20];
    1835                 :          0 :         frame->max_cll = (ptr[23] << 8) | ptr[22];
    1836                 :          0 :         frame->max_fall = (ptr[25] << 8) | ptr[24];
    1837                 :            : 
    1838                 :          0 :         return 0;
    1839                 :            : }
    1840                 :            : 
    1841                 :            : /**
    1842                 :            :  * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
    1843                 :            :  * @frame: HDMI infoframe
    1844                 :            :  * @buffer: source buffer
    1845                 :            :  * @size: size of buffer
    1846                 :            :  *
    1847                 :            :  * Unpacks the information contained in binary buffer @buffer into a structured
    1848                 :            :  * @frame of a HDMI infoframe.
    1849                 :            :  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
    1850                 :            :  * specification.
    1851                 :            :  *
    1852                 :            :  * Returns 0 on success or a negative error code on failure.
    1853                 :            :  */
    1854                 :          0 : int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
    1855                 :            :                           const void *buffer, size_t size)
    1856                 :            : {
    1857                 :            :         int ret;
    1858                 :            :         const u8 *ptr = buffer;
    1859                 :            : 
    1860                 :          0 :         if (size < HDMI_INFOFRAME_HEADER_SIZE)
    1861                 :            :                 return -EINVAL;
    1862                 :            : 
    1863                 :          0 :         switch (ptr[0]) {
    1864                 :            :         case HDMI_INFOFRAME_TYPE_AVI:
    1865                 :          0 :                 ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size);
    1866                 :          0 :                 break;
    1867                 :            :         case HDMI_INFOFRAME_TYPE_DRM:
    1868                 :          0 :                 ret = hdmi_drm_infoframe_unpack(&frame->drm, buffer, size);
    1869                 :          0 :                 break;
    1870                 :            :         case HDMI_INFOFRAME_TYPE_SPD:
    1871                 :          0 :                 ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size);
    1872                 :          0 :                 break;
    1873                 :            :         case HDMI_INFOFRAME_TYPE_AUDIO:
    1874                 :          0 :                 ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer, size);
    1875                 :          0 :                 break;
    1876                 :            :         case HDMI_INFOFRAME_TYPE_VENDOR:
    1877                 :          0 :                 ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size);
    1878                 :          0 :                 break;
    1879                 :            :         default:
    1880                 :            :                 ret = -EINVAL;
    1881                 :            :                 break;
    1882                 :            :         }
    1883                 :            : 
    1884                 :          0 :         return ret;
    1885                 :            : }
    1886                 :            : EXPORT_SYMBOL(hdmi_infoframe_unpack);
    

Generated by: LCOV version 1.14