linux/drivers/video/hdmi.c
<<
>>
Prefs
   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
  34static u8 hdmi_infoframe_checksum(const u8 *ptr, size_t size)
  35{
  36        u8 csum = 0;
  37        size_t i;
  38
  39        /* compute checksum */
  40        for (i = 0; i < size; i++)
  41                csum += ptr[i];
  42
  43        return 256 - csum;
  44}
  45
  46static void hdmi_infoframe_set_checksum(void *buffer, size_t size)
  47{
  48        u8 *ptr = buffer;
  49
  50        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 */
  59int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
  60{
  61        memset(frame, 0, sizeof(*frame));
  62
  63        frame->type = HDMI_INFOFRAME_TYPE_AVI;
  64        frame->version = 2;
  65        frame->length = HDMI_AVI_INFOFRAME_SIZE;
  66
  67        return 0;
  68}
  69EXPORT_SYMBOL(hdmi_avi_infoframe_init);
  70
  71static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame)
  72{
  73        if (frame->type != HDMI_INFOFRAME_TYPE_AVI ||
  74            frame->version != 2 ||
  75            frame->length != HDMI_AVI_INFOFRAME_SIZE)
  76                return -EINVAL;
  77
  78        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 */
  93int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame)
  94{
  95        return hdmi_avi_infoframe_check_only(frame);
  96}
  97EXPORT_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 */
 113ssize_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        if (ret)
 122                return ret;
 123
 124        length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
 125
 126        if (size < length)
 127                return -ENOSPC;
 128
 129        memset(buffer, 0, size);
 130
 131        ptr[0] = frame->type;
 132        ptr[1] = frame->version;
 133        ptr[2] = frame->length;
 134        ptr[3] = 0; /* checksum */
 135
 136        /* start infoframe payload */
 137        ptr += HDMI_INFOFRAME_HEADER_SIZE;
 138
 139        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        if (frame->active_aspect & 0xf)
 146                ptr[0] |= BIT(4);
 147
 148        /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */
 149        if (frame->top_bar || frame->bottom_bar)
 150                ptr[0] |= BIT(3);
 151
 152        if (frame->left_bar || frame->right_bar)
 153                ptr[0] |= BIT(2);
 154
 155        ptr[1] = ((frame->colorimetry & 0x3) << 6) |
 156                 ((frame->picture_aspect & 0x3) << 4) |
 157                 (frame->active_aspect & 0xf);
 158
 159        ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
 160                 ((frame->quantization_range & 0x3) << 2) |
 161                 (frame->nups & 0x3);
 162
 163        if (frame->itc)
 164                ptr[2] |= BIT(7);
 165
 166        ptr[3] = frame->video_code & 0x7f;
 167
 168        ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
 169                 ((frame->content_type & 0x3) << 4) |
 170                 (frame->pixel_repeat & 0xf);
 171
 172        ptr[5] = frame->top_bar & 0xff;
 173        ptr[6] = (frame->top_bar >> 8) & 0xff;
 174        ptr[7] = frame->bottom_bar & 0xff;
 175        ptr[8] = (frame->bottom_bar >> 8) & 0xff;
 176        ptr[9] = frame->left_bar & 0xff;
 177        ptr[10] = (frame->left_bar >> 8) & 0xff;
 178        ptr[11] = frame->right_bar & 0xff;
 179        ptr[12] = (frame->right_bar >> 8) & 0xff;
 180
 181        hdmi_infoframe_set_checksum(buffer, length);
 182
 183        return length;
 184}
 185EXPORT_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 */
 204ssize_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        if (ret)
 211                return ret;
 212
 213        return hdmi_avi_infoframe_pack_only(frame, buffer, size);
 214}
 215EXPORT_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 */
 225int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
 226                            const char *vendor, const char *product)
 227{
 228        memset(frame, 0, sizeof(*frame));
 229
 230        frame->type = HDMI_INFOFRAME_TYPE_SPD;
 231        frame->version = 1;
 232        frame->length = HDMI_SPD_INFOFRAME_SIZE;
 233
 234        strncpy(frame->vendor, vendor, sizeof(frame->vendor));
 235        strncpy(frame->product, product, sizeof(frame->product));
 236
 237        return 0;
 238}
 239EXPORT_SYMBOL(hdmi_spd_infoframe_init);
 240
 241static int hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe *frame)
 242{
 243        if (frame->type != HDMI_INFOFRAME_TYPE_SPD ||
 244            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 */
 260int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame)
 261{
 262        return hdmi_spd_infoframe_check_only(frame);
 263}
 264EXPORT_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 */
 280ssize_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        if (ret)
 289                return ret;
 290
 291        length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
 292
 293        if (size < length)
 294                return -ENOSPC;
 295
 296        memset(buffer, 0, size);
 297
 298        ptr[0] = frame->type;
 299        ptr[1] = frame->version;
 300        ptr[2] = frame->length;
 301        ptr[3] = 0; /* checksum */
 302
 303        /* start infoframe payload */
 304        ptr += HDMI_INFOFRAME_HEADER_SIZE;
 305
 306        memcpy(ptr, frame->vendor, sizeof(frame->vendor));
 307        memcpy(ptr + 8, frame->product, sizeof(frame->product));
 308
 309        ptr[24] = frame->sdi;
 310
 311        hdmi_infoframe_set_checksum(buffer, length);
 312
 313        return length;
 314}
 315EXPORT_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 */
 334ssize_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        if (ret)
 341                return ret;
 342
 343        return hdmi_spd_infoframe_pack_only(frame, buffer, size);
 344}
 345EXPORT_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 */
 353int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
 354{
 355        memset(frame, 0, sizeof(*frame));
 356
 357        frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
 358        frame->version = 1;
 359        frame->length = HDMI_AUDIO_INFOFRAME_SIZE;
 360
 361        return 0;
 362}
 363EXPORT_SYMBOL(hdmi_audio_infoframe_init);
 364
 365static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *frame)
 366{
 367        if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO ||
 368            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 */
 384int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
 385{
 386        return hdmi_audio_infoframe_check_only(frame);
 387}
 388EXPORT_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 */
 404ssize_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        if (ret)
 414                return ret;
 415
 416        length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
 417
 418        if (size < length)
 419                return -ENOSPC;
 420
 421        memset(buffer, 0, size);
 422
 423        if (frame->channels >= 2)
 424                channels = frame->channels - 1;
 425        else
 426                channels = 0;
 427
 428        ptr[0] = frame->type;
 429        ptr[1] = frame->version;
 430        ptr[2] = frame->length;
 431        ptr[3] = 0; /* checksum */
 432
 433        /* start infoframe payload */
 434        ptr += HDMI_INFOFRAME_HEADER_SIZE;
 435
 436        ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
 437        ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
 438                 (frame->sample_size & 0x3);
 439        ptr[2] = frame->coding_type_ext & 0x1f;
 440        ptr[3] = frame->channel_allocation;
 441        ptr[4] = (frame->level_shift_value & 0xf) << 3;
 442
 443        if (frame->downmix_inhibit)
 444                ptr[4] |= BIT(7);
 445
 446        hdmi_infoframe_set_checksum(buffer, length);
 447
 448        return length;
 449}
 450EXPORT_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 */
 469ssize_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        if (ret)
 476                return ret;
 477
 478        return hdmi_audio_infoframe_pack_only(frame, buffer, size);
 479}
 480EXPORT_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 */
 488int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
 489{
 490        memset(frame, 0, sizeof(*frame));
 491
 492        frame->type = HDMI_INFOFRAME_TYPE_VENDOR;
 493        frame->version = 1;
 494
 495        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        frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
 502        frame->length = 4;
 503
 504        return 0;
 505}
 506EXPORT_SYMBOL(hdmi_vendor_infoframe_init);
 507
 508static 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        if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
 512                return 6;
 513        else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
 514                return 5;
 515        else
 516                return 4;
 517}
 518
 519static int hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe *frame)
 520{
 521        if (frame->type != HDMI_INFOFRAME_TYPE_VENDOR ||
 522            frame->version != 1 ||
 523            frame->oui != HDMI_IEEE_OUI)
 524                return -EINVAL;
 525
 526        /* only one of those can be supplied */
 527        if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
 528                return -EINVAL;
 529
 530        if (frame->length != hdmi_vendor_infoframe_length(frame))
 531                return -EINVAL;
 532
 533        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 */
 545int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame)
 546{
 547        frame->length = hdmi_vendor_infoframe_length(frame);
 548
 549        return hdmi_vendor_infoframe_check_only(frame);
 550}
 551EXPORT_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 */
 567ssize_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        ret = hdmi_vendor_infoframe_check_only(frame);
 575        if (ret)
 576                return ret;
 577
 578        length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
 579
 580        if (size < length)
 581                return -ENOSPC;
 582
 583        memset(buffer, 0, size);
 584
 585        ptr[0] = frame->type;
 586        ptr[1] = frame->version;
 587        ptr[2] = frame->length;
 588        ptr[3] = 0; /* checksum */
 589
 590        /* HDMI OUI */
 591        ptr[4] = 0x03;
 592        ptr[5] = 0x0c;
 593        ptr[6] = 0x00;
 594
 595        if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
 596                ptr[7] = 0x2 << 5;      /* video format */
 597                ptr[8] = (frame->s3d_struct & 0xf) << 4;
 598                if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
 599                        ptr[9] = (frame->s3d_ext_data & 0xf) << 4;
 600        } else if (frame->vic) {
 601                ptr[7] = 0x1 << 5;      /* video format */
 602                ptr[8] = frame->vic;
 603        } else {
 604                ptr[7] = 0x0 << 5;      /* video format */
 605        }
 606
 607        hdmi_infoframe_set_checksum(buffer, length);
 608
 609        return length;
 610}
 611EXPORT_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 */
 630ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
 631                                   void *buffer, size_t size)
 632{
 633        int ret;
 634
 635        ret = hdmi_vendor_infoframe_check(frame);
 636        if (ret)
 637                return ret;
 638
 639        return hdmi_vendor_infoframe_pack_only(frame, buffer, size);
 640}
 641EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
 642
 643static int
 644hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *frame)
 645{
 646        if (frame->any.type != HDMI_INFOFRAME_TYPE_VENDOR ||
 647            frame->any.version != 1)
 648                return -EINVAL;
 649
 650        return 0;
 651}
 652
 653/*
 654 * hdmi_vendor_any_infoframe_check() - check a vendor infoframe
 655 */
 656static int
 657hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe *frame)
 658{
 659        int ret;
 660
 661        ret = hdmi_vendor_any_infoframe_check_only(frame);
 662        if (ret)
 663                return ret;
 664
 665        /* we only know about HDMI vendor infoframes */
 666        if (frame->any.oui != HDMI_IEEE_OUI)
 667                return -EINVAL;
 668
 669        return hdmi_vendor_infoframe_check(&frame->hdmi);
 670}
 671
 672/*
 673 * hdmi_vendor_any_infoframe_pack_only() - write a vendor infoframe to binary buffer
 674 */
 675static ssize_t
 676hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe *frame,
 677                                    void *buffer, size_t size)
 678{
 679        int ret;
 680
 681        ret = hdmi_vendor_any_infoframe_check_only(frame);
 682        if (ret)
 683                return ret;
 684
 685        /* we only know about HDMI vendor infoframes */
 686        if (frame->any.oui != HDMI_IEEE_OUI)
 687                return -EINVAL;
 688
 689        return hdmi_vendor_infoframe_pack_only(&frame->hdmi, buffer, size);
 690}
 691
 692/*
 693 * hdmi_vendor_any_infoframe_pack() - check a vendor infoframe,
 694 *                                    and write it to binary buffer
 695 */
 696static ssize_t
 697hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
 698                               void *buffer, size_t size)
 699{
 700        int ret;
 701
 702        ret = hdmi_vendor_any_infoframe_check(frame);
 703        if (ret)
 704                return ret;
 705
 706        return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size);
 707}
 708
 709/**
 710 * hdmi_infoframe_check() - check a HDMI infoframe
 711 * @frame: HDMI infoframe
 712 *
 713 * Validates that the infoframe is consistent and updates derived fields
 714 * (eg. length) based on other fields.
 715 *
 716 * Returns 0 on success or a negative error code on failure.
 717 */
 718int
 719hdmi_infoframe_check(union hdmi_infoframe *frame)
 720{
 721        switch (frame->any.type) {
 722        case HDMI_INFOFRAME_TYPE_AVI:
 723                return hdmi_avi_infoframe_check(&frame->avi);
 724        case HDMI_INFOFRAME_TYPE_SPD:
 725                return hdmi_spd_infoframe_check(&frame->spd);
 726        case HDMI_INFOFRAME_TYPE_AUDIO:
 727                return hdmi_audio_infoframe_check(&frame->audio);
 728        case HDMI_INFOFRAME_TYPE_VENDOR:
 729                return hdmi_vendor_any_infoframe_check(&frame->vendor);
 730        default:
 731                WARN(1, "Bad infoframe type %d\n", frame->any.type);
 732                return -EINVAL;
 733        }
 734}
 735EXPORT_SYMBOL(hdmi_infoframe_check);
 736
 737/**
 738 * hdmi_infoframe_pack_only() - write a HDMI infoframe to binary buffer
 739 * @frame: HDMI infoframe
 740 * @buffer: destination buffer
 741 * @size: size of buffer
 742 *
 743 * Packs the information contained in the @frame structure into a binary
 744 * representation that can be written into the corresponding controller
 745 * registers. Also computes the checksum as required by section 5.3.5 of
 746 * the HDMI 1.4 specification.
 747 *
 748 * Returns the number of bytes packed into the binary buffer or a negative
 749 * error code on failure.
 750 */
 751ssize_t
 752hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size)
 753{
 754        ssize_t length;
 755
 756        switch (frame->any.type) {
 757        case HDMI_INFOFRAME_TYPE_AVI:
 758                length = hdmi_avi_infoframe_pack_only(&frame->avi,
 759                                                      buffer, size);
 760                break;
 761        case HDMI_INFOFRAME_TYPE_SPD:
 762                length = hdmi_spd_infoframe_pack_only(&frame->spd,
 763                                                      buffer, size);
 764                break;
 765        case HDMI_INFOFRAME_TYPE_AUDIO:
 766                length = hdmi_audio_infoframe_pack_only(&frame->audio,
 767                                                        buffer, size);
 768                break;
 769        case HDMI_INFOFRAME_TYPE_VENDOR:
 770                length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor,
 771                                                             buffer, size);
 772                break;
 773        default:
 774                WARN(1, "Bad infoframe type %d\n", frame->any.type);
 775                length = -EINVAL;
 776        }
 777
 778        return length;
 779}
 780EXPORT_SYMBOL(hdmi_infoframe_pack_only);
 781
 782/**
 783 * hdmi_infoframe_pack() - check a HDMI infoframe,
 784 *                         and write it to binary buffer
 785 * @frame: HDMI infoframe
 786 * @buffer: destination buffer
 787 * @size: size of buffer
 788 *
 789 * Validates that the infoframe is consistent and updates derived fields
 790 * (eg. length) based on other fields, after which it packs the information
 791 * contained in the @frame structure into a binary representation that
 792 * can be written into the corresponding controller registers. This function
 793 * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
 794 * specification.
 795 *
 796 * Returns the number of bytes packed into the binary buffer or a negative
 797 * error code on failure.
 798 */
 799ssize_t
 800hdmi_infoframe_pack(union hdmi_infoframe *frame,
 801                    void *buffer, size_t size)
 802{
 803        ssize_t length;
 804
 805        switch (frame->any.type) {
 806        case HDMI_INFOFRAME_TYPE_AVI:
 807                length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size);
 808                break;
 809        case HDMI_INFOFRAME_TYPE_SPD:
 810                length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size);
 811                break;
 812        case HDMI_INFOFRAME_TYPE_AUDIO:
 813                length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size);
 814                break;
 815        case HDMI_INFOFRAME_TYPE_VENDOR:
 816                length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
 817                                                        buffer, size);
 818                break;
 819        default:
 820                WARN(1, "Bad infoframe type %d\n", frame->any.type);
 821                length = -EINVAL;
 822        }
 823
 824        return length;
 825}
 826EXPORT_SYMBOL(hdmi_infoframe_pack);
 827
 828static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
 829{
 830        if (type < 0x80 || type > 0x9f)
 831                return "Invalid";
 832        switch (type) {
 833        case HDMI_INFOFRAME_TYPE_VENDOR:
 834                return "Vendor";
 835        case HDMI_INFOFRAME_TYPE_AVI:
 836                return "Auxiliary Video Information (AVI)";
 837        case HDMI_INFOFRAME_TYPE_SPD:
 838                return "Source Product Description (SPD)";
 839        case HDMI_INFOFRAME_TYPE_AUDIO:
 840                return "Audio";
 841        }
 842        return "Reserved";
 843}
 844
 845static void hdmi_infoframe_log_header(const char *level,
 846                                      struct device *dev,
 847                                      const struct hdmi_any_infoframe *frame)
 848{
 849        hdmi_log("HDMI infoframe: %s, version %u, length %u\n",
 850                hdmi_infoframe_type_get_name(frame->type),
 851                frame->version, frame->length);
 852}
 853
 854static const char *hdmi_colorspace_get_name(enum hdmi_colorspace colorspace)
 855{
 856        switch (colorspace) {
 857        case HDMI_COLORSPACE_RGB:
 858                return "RGB";
 859        case HDMI_COLORSPACE_YUV422:
 860                return "YCbCr 4:2:2";
 861        case HDMI_COLORSPACE_YUV444:
 862                return "YCbCr 4:4:4";
 863        case HDMI_COLORSPACE_YUV420:
 864                return "YCbCr 4:2:0";
 865        case HDMI_COLORSPACE_RESERVED4:
 866                return "Reserved (4)";
 867        case HDMI_COLORSPACE_RESERVED5:
 868                return "Reserved (5)";
 869        case HDMI_COLORSPACE_RESERVED6:
 870                return "Reserved (6)";
 871        case HDMI_COLORSPACE_IDO_DEFINED:
 872                return "IDO Defined";
 873        }
 874        return "Invalid";
 875}
 876
 877static const char *hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode)
 878{
 879        switch (scan_mode) {
 880        case HDMI_SCAN_MODE_NONE:
 881                return "No Data";
 882        case HDMI_SCAN_MODE_OVERSCAN:
 883                return "Overscan";
 884        case HDMI_SCAN_MODE_UNDERSCAN:
 885                return "Underscan";
 886        case HDMI_SCAN_MODE_RESERVED:
 887                return "Reserved";
 888        }
 889        return "Invalid";
 890}
 891
 892static const char *hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry)
 893{
 894        switch (colorimetry) {
 895        case HDMI_COLORIMETRY_NONE:
 896                return "No Data";
 897        case HDMI_COLORIMETRY_ITU_601:
 898                return "ITU601";
 899        case HDMI_COLORIMETRY_ITU_709:
 900                return "ITU709";
 901        case HDMI_COLORIMETRY_EXTENDED:
 902                return "Extended";
 903        }
 904        return "Invalid";
 905}
 906
 907static const char *
 908hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect)
 909{
 910        switch (picture_aspect) {
 911        case HDMI_PICTURE_ASPECT_NONE:
 912                return "No Data";
 913        case HDMI_PICTURE_ASPECT_4_3:
 914                return "4:3";
 915        case HDMI_PICTURE_ASPECT_16_9:
 916                return "16:9";
 917        case HDMI_PICTURE_ASPECT_64_27:
 918                return "64:27";
 919        case HDMI_PICTURE_ASPECT_256_135:
 920                return "256:135";
 921        case HDMI_PICTURE_ASPECT_RESERVED:
 922                return "Reserved";
 923        }
 924        return "Invalid";
 925}
 926
 927static const char *
 928hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect)
 929{
 930        if (active_aspect < 0 || active_aspect > 0xf)
 931                return "Invalid";
 932
 933        switch (active_aspect) {
 934        case HDMI_ACTIVE_ASPECT_16_9_TOP:
 935                return "16:9 Top";
 936        case HDMI_ACTIVE_ASPECT_14_9_TOP:
 937                return "14:9 Top";
 938        case HDMI_ACTIVE_ASPECT_16_9_CENTER:
 939                return "16:9 Center";
 940        case HDMI_ACTIVE_ASPECT_PICTURE:
 941                return "Same as Picture";
 942        case HDMI_ACTIVE_ASPECT_4_3:
 943                return "4:3";
 944        case HDMI_ACTIVE_ASPECT_16_9:
 945                return "16:9";
 946        case HDMI_ACTIVE_ASPECT_14_9:
 947                return "14:9";
 948        case HDMI_ACTIVE_ASPECT_4_3_SP_14_9:
 949                return "4:3 SP 14:9";
 950        case HDMI_ACTIVE_ASPECT_16_9_SP_14_9:
 951                return "16:9 SP 14:9";
 952        case HDMI_ACTIVE_ASPECT_16_9_SP_4_3:
 953                return "16:9 SP 4:3";
 954        }
 955        return "Reserved";
 956}
 957
 958static const char *
 959hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col)
 960{
 961        switch (ext_col) {
 962        case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601:
 963                return "xvYCC 601";
 964        case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709:
 965                return "xvYCC 709";
 966        case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
 967                return "sYCC 601";
 968        case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
 969                return "opYCC 601";
 970        case HDMI_EXTENDED_COLORIMETRY_OPRGB:
 971                return "opRGB";
 972        case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
 973                return "BT.2020 Constant Luminance";
 974        case HDMI_EXTENDED_COLORIMETRY_BT2020:
 975                return "BT.2020";
 976        case HDMI_EXTENDED_COLORIMETRY_RESERVED:
 977                return "Reserved";
 978        }
 979        return "Invalid";
 980}
 981
 982static const char *
 983hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange)
 984{
 985        switch (qrange) {
 986        case HDMI_QUANTIZATION_RANGE_DEFAULT:
 987                return "Default";
 988        case HDMI_QUANTIZATION_RANGE_LIMITED:
 989                return "Limited";
 990        case HDMI_QUANTIZATION_RANGE_FULL:
 991                return "Full";
 992        case HDMI_QUANTIZATION_RANGE_RESERVED:
 993                return "Reserved";
 994        }
 995        return "Invalid";
 996}
 997
 998static const char *hdmi_nups_get_name(enum hdmi_nups nups)
 999{
1000        switch (nups) {
1001        case HDMI_NUPS_UNKNOWN:
1002                return "Unknown Non-uniform Scaling";
1003        case HDMI_NUPS_HORIZONTAL:
1004                return "Horizontally Scaled";
1005        case HDMI_NUPS_VERTICAL:
1006                return "Vertically Scaled";
1007        case HDMI_NUPS_BOTH:
1008                return "Horizontally and Vertically Scaled";
1009        }
1010        return "Invalid";
1011}
1012
1013static const char *
1014hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange)
1015{
1016        switch (qrange) {
1017        case HDMI_YCC_QUANTIZATION_RANGE_LIMITED:
1018                return "Limited";
1019        case HDMI_YCC_QUANTIZATION_RANGE_FULL:
1020                return "Full";
1021        }
1022        return "Invalid";
1023}
1024
1025static const char *
1026hdmi_content_type_get_name(enum hdmi_content_type content_type)
1027{
1028        switch (content_type) {
1029        case HDMI_CONTENT_TYPE_GRAPHICS:
1030                return "Graphics";
1031        case HDMI_CONTENT_TYPE_PHOTO:
1032                return "Photo";
1033        case HDMI_CONTENT_TYPE_CINEMA:
1034                return "Cinema";
1035        case HDMI_CONTENT_TYPE_GAME:
1036                return "Game";
1037        }
1038        return "Invalid";
1039}
1040
1041/**
1042 * hdmi_avi_infoframe_log() - log info of HDMI AVI infoframe
1043 * @level: logging level
1044 * @dev: device
1045 * @frame: HDMI AVI infoframe
1046 */
1047static void hdmi_avi_infoframe_log(const char *level,
1048                                   struct device *dev,
1049                                   const struct hdmi_avi_infoframe *frame)
1050{
1051        hdmi_infoframe_log_header(level, dev,
1052                                  (const struct hdmi_any_infoframe *)frame);
1053
1054        hdmi_log("    colorspace: %s\n",
1055                        hdmi_colorspace_get_name(frame->colorspace));
1056        hdmi_log("    scan mode: %s\n",
1057                        hdmi_scan_mode_get_name(frame->scan_mode));
1058        hdmi_log("    colorimetry: %s\n",
1059                        hdmi_colorimetry_get_name(frame->colorimetry));
1060        hdmi_log("    picture aspect: %s\n",
1061                        hdmi_picture_aspect_get_name(frame->picture_aspect));
1062        hdmi_log("    active aspect: %s\n",
1063                        hdmi_active_aspect_get_name(frame->active_aspect));
1064        hdmi_log("    itc: %s\n", frame->itc ? "IT Content" : "No Data");
1065        hdmi_log("    extended colorimetry: %s\n",
1066                        hdmi_extended_colorimetry_get_name(frame->extended_colorimetry));
1067        hdmi_log("    quantization range: %s\n",
1068                        hdmi_quantization_range_get_name(frame->quantization_range));
1069        hdmi_log("    nups: %s\n", hdmi_nups_get_name(frame->nups));
1070        hdmi_log("    video code: %u\n", frame->video_code);
1071        hdmi_log("    ycc quantization range: %s\n",
1072                        hdmi_ycc_quantization_range_get_name(frame->ycc_quantization_range));
1073        hdmi_log("    hdmi content type: %s\n",
1074                        hdmi_content_type_get_name(frame->content_type));
1075        hdmi_log("    pixel repeat: %u\n", frame->pixel_repeat);
1076        hdmi_log("    bar top %u, bottom %u, left %u, right %u\n",
1077                        frame->top_bar, frame->bottom_bar,
1078                        frame->left_bar, frame->right_bar);
1079}
1080
1081static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi)
1082{
1083        if (sdi < 0 || sdi > 0xff)
1084                return "Invalid";
1085        switch (sdi) {
1086        case HDMI_SPD_SDI_UNKNOWN:
1087                return "Unknown";
1088        case HDMI_SPD_SDI_DSTB:
1089                return "Digital STB";
1090        case HDMI_SPD_SDI_DVDP:
1091                return "DVD Player";
1092        case HDMI_SPD_SDI_DVHS:
1093                return "D-VHS";
1094        case HDMI_SPD_SDI_HDDVR:
1095                return "HDD Videorecorder";
1096        case HDMI_SPD_SDI_DVC:
1097                return "DVC";
1098        case HDMI_SPD_SDI_DSC:
1099                return "DSC";
1100        case HDMI_SPD_SDI_VCD:
1101                return "Video CD";
1102        case HDMI_SPD_SDI_GAME:
1103                return "Game";
1104        case HDMI_SPD_SDI_PC:
1105                return "PC General";
1106        case HDMI_SPD_SDI_BD:
1107                return "Blu-Ray Disc (BD)";
1108        case HDMI_SPD_SDI_SACD:
1109                return "Super Audio CD";
1110        case HDMI_SPD_SDI_HDDVD:
1111                return "HD DVD";
1112        case HDMI_SPD_SDI_PMP:
1113                return "PMP";
1114        }
1115        return "Reserved";
1116}
1117
1118/**
1119 * hdmi_spd_infoframe_log() - log info of HDMI SPD infoframe
1120 * @level: logging level
1121 * @dev: device
1122 * @frame: HDMI SPD infoframe
1123 */
1124static void hdmi_spd_infoframe_log(const char *level,
1125                                   struct device *dev,
1126                                   const struct hdmi_spd_infoframe *frame)
1127{
1128        u8 buf[17];
1129
1130        hdmi_infoframe_log_header(level, dev,
1131                                  (const struct hdmi_any_infoframe *)frame);
1132
1133        memset(buf, 0, sizeof(buf));
1134
1135        strncpy(buf, frame->vendor, 8);
1136        hdmi_log("    vendor: %s\n", buf);
1137        strncpy(buf, frame->product, 16);
1138        hdmi_log("    product: %s\n", buf);
1139        hdmi_log("    source device information: %s (0x%x)\n",
1140                hdmi_spd_sdi_get_name(frame->sdi), frame->sdi);
1141}
1142
1143static const char *
1144hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type)
1145{
1146        switch (coding_type) {
1147        case HDMI_AUDIO_CODING_TYPE_STREAM:
1148                return "Refer to Stream Header";
1149        case HDMI_AUDIO_CODING_TYPE_PCM:
1150                return "PCM";
1151        case HDMI_AUDIO_CODING_TYPE_AC3:
1152                return "AC-3";
1153        case HDMI_AUDIO_CODING_TYPE_MPEG1:
1154                return "MPEG1";
1155        case HDMI_AUDIO_CODING_TYPE_MP3:
1156                return "MP3";
1157        case HDMI_AUDIO_CODING_TYPE_MPEG2:
1158                return "MPEG2";
1159        case HDMI_AUDIO_CODING_TYPE_AAC_LC:
1160                return "AAC";
1161        case HDMI_AUDIO_CODING_TYPE_DTS:
1162                return "DTS";
1163        case HDMI_AUDIO_CODING_TYPE_ATRAC:
1164                return "ATRAC";
1165        case HDMI_AUDIO_CODING_TYPE_DSD:
1166                return "One Bit Audio";
1167        case HDMI_AUDIO_CODING_TYPE_EAC3:
1168                return "Dolby Digital +";
1169        case HDMI_AUDIO_CODING_TYPE_DTS_HD:
1170                return "DTS-HD";
1171        case HDMI_AUDIO_CODING_TYPE_MLP:
1172                return "MAT (MLP)";
1173        case HDMI_AUDIO_CODING_TYPE_DST:
1174                return "DST";
1175        case HDMI_AUDIO_CODING_TYPE_WMA_PRO:
1176                return "WMA PRO";
1177        case HDMI_AUDIO_CODING_TYPE_CXT:
1178                return "Refer to CXT";
1179        }
1180        return "Invalid";
1181}
1182
1183static const char *
1184hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size)
1185{
1186        switch (sample_size) {
1187        case HDMI_AUDIO_SAMPLE_SIZE_STREAM:
1188                return "Refer to Stream Header";
1189        case HDMI_AUDIO_SAMPLE_SIZE_16:
1190                return "16 bit";
1191        case HDMI_AUDIO_SAMPLE_SIZE_20:
1192                return "20 bit";
1193        case HDMI_AUDIO_SAMPLE_SIZE_24:
1194                return "24 bit";
1195        }
1196        return "Invalid";
1197}
1198
1199static const char *
1200hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq)
1201{
1202        switch (freq) {
1203        case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM:
1204                return "Refer to Stream Header";
1205        case HDMI_AUDIO_SAMPLE_FREQUENCY_32000:
1206                return "32 kHz";
1207        case HDMI_AUDIO_SAMPLE_FREQUENCY_44100:
1208                return "44.1 kHz (CD)";
1209        case HDMI_AUDIO_SAMPLE_FREQUENCY_48000:
1210                return "48 kHz";
1211        case HDMI_AUDIO_SAMPLE_FREQUENCY_88200:
1212                return "88.2 kHz";
1213        case HDMI_AUDIO_SAMPLE_FREQUENCY_96000:
1214                return "96 kHz";
1215        case HDMI_AUDIO_SAMPLE_FREQUENCY_176400:
1216                return "176.4 kHz";
1217        case HDMI_AUDIO_SAMPLE_FREQUENCY_192000:
1218                return "192 kHz";
1219        }
1220        return "Invalid";
1221}
1222
1223static const char *
1224hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx)
1225{
1226        if (ctx < 0 || ctx > 0x1f)
1227                return "Invalid";
1228
1229        switch (ctx) {
1230        case HDMI_AUDIO_CODING_TYPE_EXT_CT:
1231                return "Refer to CT";
1232        case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC:
1233                return "HE AAC";
1234        case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2:
1235                return "HE AAC v2";
1236        case HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND:
1237                return "MPEG SURROUND";
1238        case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC:
1239                return "MPEG-4 HE AAC";
1240        case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2:
1241                return "MPEG-4 HE AAC v2";
1242        case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC:
1243                return "MPEG-4 AAC LC";
1244        case HDMI_AUDIO_CODING_TYPE_EXT_DRA:
1245                return "DRA";
1246        case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND:
1247                return "MPEG-4 HE AAC + MPEG Surround";
1248        case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND:
1249                return "MPEG-4 AAC LC + MPEG Surround";
1250        }
1251        return "Reserved";
1252}
1253
1254/**
1255 * hdmi_audio_infoframe_log() - log info of HDMI AUDIO infoframe
1256 * @level: logging level
1257 * @dev: device
1258 * @frame: HDMI AUDIO infoframe
1259 */
1260static void hdmi_audio_infoframe_log(const char *level,
1261                                     struct device *dev,
1262                                     const struct hdmi_audio_infoframe *frame)
1263{
1264        hdmi_infoframe_log_header(level, dev,
1265                                  (const struct hdmi_any_infoframe *)frame);
1266
1267        if (frame->channels)
1268                hdmi_log("    channels: %u\n", frame->channels - 1);
1269        else
1270                hdmi_log("    channels: Refer to stream header\n");
1271        hdmi_log("    coding type: %s\n",
1272                        hdmi_audio_coding_type_get_name(frame->coding_type));
1273        hdmi_log("    sample size: %s\n",
1274                        hdmi_audio_sample_size_get_name(frame->sample_size));
1275        hdmi_log("    sample frequency: %s\n",
1276                        hdmi_audio_sample_frequency_get_name(frame->sample_frequency));
1277        hdmi_log("    coding type ext: %s\n",
1278                        hdmi_audio_coding_type_ext_get_name(frame->coding_type_ext));
1279        hdmi_log("    channel allocation: 0x%x\n",
1280                        frame->channel_allocation);
1281        hdmi_log("    level shift value: %u dB\n",
1282                        frame->level_shift_value);
1283        hdmi_log("    downmix inhibit: %s\n",
1284                        frame->downmix_inhibit ? "Yes" : "No");
1285}
1286
1287static const char *
1288hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct)
1289{
1290        if (s3d_struct < 0 || s3d_struct > 0xf)
1291                return "Invalid";
1292
1293        switch (s3d_struct) {
1294        case HDMI_3D_STRUCTURE_FRAME_PACKING:
1295                return "Frame Packing";
1296        case HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE:
1297                return "Field Alternative";
1298        case HDMI_3D_STRUCTURE_LINE_ALTERNATIVE:
1299                return "Line Alternative";
1300        case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL:
1301                return "Side-by-side (Full)";
1302        case HDMI_3D_STRUCTURE_L_DEPTH:
1303                return "L + Depth";
1304        case HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH:
1305                return "L + Depth + Graphics + Graphics-depth";
1306        case HDMI_3D_STRUCTURE_TOP_AND_BOTTOM:
1307                return "Top-and-Bottom";
1308        case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF:
1309                return "Side-by-side (Half)";
1310        default:
1311                break;
1312        }
1313        return "Reserved";
1314}
1315
1316/**
1317 * hdmi_vendor_infoframe_log() - log info of HDMI VENDOR infoframe
1318 * @level: logging level
1319 * @dev: device
1320 * @frame: HDMI VENDOR infoframe
1321 */
1322static void
1323hdmi_vendor_any_infoframe_log(const char *level,
1324                              struct device *dev,
1325                              const union hdmi_vendor_any_infoframe *frame)
1326{
1327        const struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
1328
1329        hdmi_infoframe_log_header(level, dev,
1330                                  (const struct hdmi_any_infoframe *)frame);
1331
1332        if (frame->any.oui != HDMI_IEEE_OUI) {
1333                hdmi_log("    not a HDMI vendor infoframe\n");
1334                return;
1335        }
1336        if (hvf->vic == 0 && hvf->s3d_struct == HDMI_3D_STRUCTURE_INVALID) {
1337                hdmi_log("    empty frame\n");
1338                return;
1339        }
1340
1341        if (hvf->vic)
1342                hdmi_log("    HDMI VIC: %u\n", hvf->vic);
1343        if (hvf->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
1344                hdmi_log("    3D structure: %s\n",
1345                                hdmi_3d_structure_get_name(hvf->s3d_struct));
1346                if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
1347                        hdmi_log("    3D extension data: %d\n",
1348                                        hvf->s3d_ext_data);
1349        }
1350}
1351
1352/**
1353 * hdmi_infoframe_log() - log info of HDMI infoframe
1354 * @level: logging level
1355 * @dev: device
1356 * @frame: HDMI infoframe
1357 */
1358void hdmi_infoframe_log(const char *level,
1359                        struct device *dev,
1360                        const union hdmi_infoframe *frame)
1361{
1362        switch (frame->any.type) {
1363        case HDMI_INFOFRAME_TYPE_AVI:
1364                hdmi_avi_infoframe_log(level, dev, &frame->avi);
1365                break;
1366        case HDMI_INFOFRAME_TYPE_SPD:
1367                hdmi_spd_infoframe_log(level, dev, &frame->spd);
1368                break;
1369        case HDMI_INFOFRAME_TYPE_AUDIO:
1370                hdmi_audio_infoframe_log(level, dev, &frame->audio);
1371                break;
1372        case HDMI_INFOFRAME_TYPE_VENDOR:
1373                hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
1374                break;
1375        }
1376}
1377EXPORT_SYMBOL(hdmi_infoframe_log);
1378
1379/**
1380 * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe
1381 * @frame: HDMI AVI infoframe
1382 * @buffer: source buffer
1383 * @size: size of buffer
1384 *
1385 * Unpacks the information contained in binary @buffer into a structured
1386 * @frame of the HDMI Auxiliary Video (AVI) information frame.
1387 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1388 * specification.
1389 *
1390 * Returns 0 on success or a negative error code on failure.
1391 */
1392static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
1393                                     const void *buffer, size_t size)
1394{
1395        const u8 *ptr = buffer;
1396        int ret;
1397
1398        if (size < HDMI_INFOFRAME_SIZE(AVI))
1399                return -EINVAL;
1400
1401        if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
1402            ptr[1] != 2 ||
1403            ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
1404                return -EINVAL;
1405
1406        if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
1407                return -EINVAL;
1408
1409        ret = hdmi_avi_infoframe_init(frame);
1410        if (ret)
1411                return ret;
1412
1413        ptr += HDMI_INFOFRAME_HEADER_SIZE;
1414
1415        frame->colorspace = (ptr[0] >> 5) & 0x3;
1416        if (ptr[0] & 0x10)
1417                frame->active_aspect = ptr[1] & 0xf;
1418        if (ptr[0] & 0x8) {
1419                frame->top_bar = (ptr[5] << 8) + ptr[6];
1420                frame->bottom_bar = (ptr[7] << 8) + ptr[8];
1421        }
1422        if (ptr[0] & 0x4) {
1423                frame->left_bar = (ptr[9] << 8) + ptr[10];
1424                frame->right_bar = (ptr[11] << 8) + ptr[12];
1425        }
1426        frame->scan_mode = ptr[0] & 0x3;
1427
1428        frame->colorimetry = (ptr[1] >> 6) & 0x3;
1429        frame->picture_aspect = (ptr[1] >> 4) & 0x3;
1430        frame->active_aspect = ptr[1] & 0xf;
1431
1432        frame->itc = ptr[2] & 0x80 ? true : false;
1433        frame->extended_colorimetry = (ptr[2] >> 4) & 0x7;
1434        frame->quantization_range = (ptr[2] >> 2) & 0x3;
1435        frame->nups = ptr[2] & 0x3;
1436
1437        frame->video_code = ptr[3] & 0x7f;
1438        frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3;
1439        frame->content_type = (ptr[4] >> 4) & 0x3;
1440
1441        frame->pixel_repeat = ptr[4] & 0xf;
1442
1443        return 0;
1444}
1445
1446/**
1447 * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe
1448 * @frame: HDMI SPD infoframe
1449 * @buffer: source buffer
1450 * @size: size of buffer
1451 *
1452 * Unpacks the information contained in binary @buffer into a structured
1453 * @frame of the HDMI Source Product Description (SPD) information frame.
1454 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1455 * specification.
1456 *
1457 * Returns 0 on success or a negative error code on failure.
1458 */
1459static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
1460                                     const void *buffer, size_t size)
1461{
1462        const u8 *ptr = buffer;
1463        int ret;
1464
1465        if (size < HDMI_INFOFRAME_SIZE(SPD))
1466                return -EINVAL;
1467
1468        if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD ||
1469            ptr[1] != 1 ||
1470            ptr[2] != HDMI_SPD_INFOFRAME_SIZE) {
1471                return -EINVAL;
1472        }
1473
1474        if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0)
1475                return -EINVAL;
1476
1477        ptr += HDMI_INFOFRAME_HEADER_SIZE;
1478
1479        ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8);
1480        if (ret)
1481                return ret;
1482
1483        frame->sdi = ptr[24];
1484
1485        return 0;
1486}
1487
1488/**
1489 * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe
1490 * @frame: HDMI Audio infoframe
1491 * @buffer: source buffer
1492 * @size: size of buffer
1493 *
1494 * Unpacks the information contained in binary @buffer into a structured
1495 * @frame of the HDMI Audio information frame.
1496 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1497 * specification.
1498 *
1499 * Returns 0 on success or a negative error code on failure.
1500 */
1501static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
1502                                       const void *buffer, size_t size)
1503{
1504        const u8 *ptr = buffer;
1505        int ret;
1506
1507        if (size < HDMI_INFOFRAME_SIZE(AUDIO))
1508                return -EINVAL;
1509
1510        if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO ||
1511            ptr[1] != 1 ||
1512            ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) {
1513                return -EINVAL;
1514        }
1515
1516        if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0)
1517                return -EINVAL;
1518
1519        ret = hdmi_audio_infoframe_init(frame);
1520        if (ret)
1521                return ret;
1522
1523        ptr += HDMI_INFOFRAME_HEADER_SIZE;
1524
1525        frame->channels = ptr[0] & 0x7;
1526        frame->coding_type = (ptr[0] >> 4) & 0xf;
1527        frame->sample_size = ptr[1] & 0x3;
1528        frame->sample_frequency = (ptr[1] >> 2) & 0x7;
1529        frame->coding_type_ext = ptr[2] & 0x1f;
1530        frame->channel_allocation = ptr[3];
1531        frame->level_shift_value = (ptr[4] >> 3) & 0xf;
1532        frame->downmix_inhibit = ptr[4] & 0x80 ? true : false;
1533
1534        return 0;
1535}
1536
1537/**
1538 * hdmi_vendor_infoframe_unpack() - unpack binary buffer to a HDMI vendor infoframe
1539 * @frame: HDMI Vendor infoframe
1540 * @buffer: source buffer
1541 * @size: size of buffer
1542 *
1543 * Unpacks the information contained in binary @buffer into a structured
1544 * @frame of the HDMI Vendor information frame.
1545 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1546 * specification.
1547 *
1548 * Returns 0 on success or a negative error code on failure.
1549 */
1550static int
1551hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
1552                                 const void *buffer, size_t size)
1553{
1554        const u8 *ptr = buffer;
1555        size_t length;
1556        int ret;
1557        u8 hdmi_video_format;
1558        struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
1559
1560        if (size < HDMI_INFOFRAME_HEADER_SIZE)
1561                return -EINVAL;
1562
1563        if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR ||
1564            ptr[1] != 1 ||
1565            (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6))
1566                return -EINVAL;
1567
1568        length = ptr[2];
1569
1570        if (size < HDMI_INFOFRAME_HEADER_SIZE + length)
1571                return -EINVAL;
1572
1573        if (hdmi_infoframe_checksum(buffer,
1574                                    HDMI_INFOFRAME_HEADER_SIZE + length) != 0)
1575                return -EINVAL;
1576
1577        ptr += HDMI_INFOFRAME_HEADER_SIZE;
1578
1579        /* HDMI OUI */
1580        if ((ptr[0] != 0x03) ||
1581            (ptr[1] != 0x0c) ||
1582            (ptr[2] != 0x00))
1583                return -EINVAL;
1584
1585        hdmi_video_format = ptr[3] >> 5;
1586
1587        if (hdmi_video_format > 0x2)
1588                return -EINVAL;
1589
1590        ret = hdmi_vendor_infoframe_init(hvf);
1591        if (ret)
1592                return ret;
1593
1594        hvf->length = length;
1595
1596        if (hdmi_video_format == 0x2) {
1597                if (length != 5 && length != 6)
1598                        return -EINVAL;
1599                hvf->s3d_struct = ptr[4] >> 4;
1600                if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) {
1601                        if (length != 6)
1602                                return -EINVAL;
1603                        hvf->s3d_ext_data = ptr[5] >> 4;
1604                }
1605        } else if (hdmi_video_format == 0x1) {
1606                if (length != 5)
1607                        return -EINVAL;
1608                hvf->vic = ptr[4];
1609        } else {
1610                if (length != 4)
1611                        return -EINVAL;
1612        }
1613
1614        return 0;
1615}
1616
1617/**
1618 * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
1619 * @frame: HDMI infoframe
1620 * @buffer: source buffer
1621 * @size: size of buffer
1622 *
1623 * Unpacks the information contained in binary buffer @buffer into a structured
1624 * @frame of a HDMI infoframe.
1625 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1626 * specification.
1627 *
1628 * Returns 0 on success or a negative error code on failure.
1629 */
1630int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
1631                          const void *buffer, size_t size)
1632{
1633        int ret;
1634        const u8 *ptr = buffer;
1635
1636        if (size < HDMI_INFOFRAME_HEADER_SIZE)
1637                return -EINVAL;
1638
1639        switch (ptr[0]) {
1640        case HDMI_INFOFRAME_TYPE_AVI:
1641                ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size);
1642                break;
1643        case HDMI_INFOFRAME_TYPE_SPD:
1644                ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size);
1645                break;
1646        case HDMI_INFOFRAME_TYPE_AUDIO:
1647                ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer, size);
1648                break;
1649        case HDMI_INFOFRAME_TYPE_VENDOR:
1650                ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size);
1651                break;
1652        default:
1653                ret = -EINVAL;
1654                break;
1655        }
1656
1657        return ret;
1658}
1659EXPORT_SYMBOL(hdmi_infoframe_unpack);
1660