The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/nvidia/drm2/hdmi.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e08d83a737884a481702db0472cd8b3d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.