diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 11:45:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 11:45:40 -0500 |
commit | 3e63430a5cc26bc90a6e33ab33f901196b7b63ac (patch) | |
tree | bdc92e6cbaccc26f88d4c71fddbe54a86e5e707d /drivers/video | |
parent | 6fc26fc5783add961533c819995bd97db05990f0 (diff) | |
parent | 4bad5d2d25099a42e146d7b18d2b98950ed287f5 (diff) |
Merge tag 'media/v3.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- Some documentation updates and a few new pixel formats
- Stop btcx-risc abuse by cx88 and move it to bt8xx driver
- New platform driver: am437x
- New webcam driver: toptek
- New remote controller hardware protocols added to img-ir driver
- Removal of a few very old drivers that relies on old kABIs and are
for very hard to find hardware: parallel port webcam drivers
(bw-qcam, c-cam, pms and w9966), tlg2300, Video In/Out for SGI (vino)
- Removal of the USB Telegent driver (tlg2300). The company that
developed this driver has long gone and the hardware is hard to find.
As it relies on a legacy set of kABI symbols and nobody seems to care
about it, remove it.
- several improvements at rtl2832 driver
- conversion on cx28521 and au0828 to use videobuf2 (VB2)
- several improvements, fixups and board additions
* tag 'media/v3.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (321 commits)
[media] dvb_net: Convert local hex dump to print_hex_dump_debug
[media] dvb_net: Use standard debugging facilities
[media] dvb_net: Use vsprintf %pM extension to print Ethernet addresses
[media] staging: lirc_serial: adjust boolean assignments
[media] stb0899: use sign_extend32() for sign extension
[media] si2168: add support for 1.7MHz bandwidth
[media] si2168: return error if set_frontend is called with invalid parameters
[media] lirc_dev: avoid potential null-dereference
[media] mn88472: simplify bandwidth registers setting code
[media] dvb: tc90522: re-add symbol-rate report
[media] lmedm04: add read snr, signal strength and ber call backs
[media] lmedm04: Create frontend call back for read status
[media] lmedm04: create frontend callbacks for signal/snr/ber/ucblocks
[media] lmedm04: Fix usb_submit_urb BOGUS urb xfer, pipe 1 != type 3 in interrupt urb
[media] lmedm04: Increase Interupt due time to 200 msec
[media] cx88-dvb: whitespace cleanup
[media] rtl28xxu: properly initialize pdata
[media] rtl2832: declare functions as static
[media] rtl2830: declare functions as static
[media] rtl2832_sdr: add kernel-doc comments for platform_data
...
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/hdmi.c | 822 |
1 files changed, 815 insertions, 7 deletions
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 9e758a8f890d..162689227a23 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c | |||
@@ -27,10 +27,12 @@ | |||
27 | #include <linux/export.h> | 27 | #include <linux/export.h> |
28 | #include <linux/hdmi.h> | 28 | #include <linux/hdmi.h> |
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/device.h> | ||
30 | 31 | ||
31 | static void hdmi_infoframe_checksum(void *buffer, size_t size) | 32 | #define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__) |
33 | |||
34 | static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size) | ||
32 | { | 35 | { |
33 | u8 *ptr = buffer; | ||
34 | u8 csum = 0; | 36 | u8 csum = 0; |
35 | size_t i; | 37 | size_t i; |
36 | 38 | ||
@@ -38,7 +40,14 @@ static void hdmi_infoframe_checksum(void *buffer, size_t size) | |||
38 | for (i = 0; i < size; i++) | 40 | for (i = 0; i < size; i++) |
39 | csum += ptr[i]; | 41 | csum += ptr[i]; |
40 | 42 | ||
41 | ptr[3] = 256 - csum; | 43 | return 256 - csum; |
44 | } | ||
45 | |||
46 | static void hdmi_infoframe_set_checksum(void *buffer, size_t size) | ||
47 | { | ||
48 | u8 *ptr = buffer; | ||
49 | |||
50 | ptr[3] = hdmi_infoframe_checksum(buffer, size); | ||
42 | } | 51 | } |
43 | 52 | ||
44 | /** | 53 | /** |
@@ -136,7 +145,7 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, | |||
136 | ptr[11] = frame->right_bar & 0xff; | 145 | ptr[11] = frame->right_bar & 0xff; |
137 | ptr[12] = (frame->right_bar >> 8) & 0xff; | 146 | ptr[12] = (frame->right_bar >> 8) & 0xff; |
138 | 147 | ||
139 | hdmi_infoframe_checksum(buffer, length); | 148 | hdmi_infoframe_set_checksum(buffer, length); |
140 | 149 | ||
141 | return length; | 150 | return length; |
142 | } | 151 | } |
@@ -206,7 +215,7 @@ ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, | |||
206 | 215 | ||
207 | ptr[24] = frame->sdi; | 216 | ptr[24] = frame->sdi; |
208 | 217 | ||
209 | hdmi_infoframe_checksum(buffer, length); | 218 | hdmi_infoframe_set_checksum(buffer, length); |
210 | 219 | ||
211 | return length; | 220 | return length; |
212 | } | 221 | } |
@@ -281,7 +290,7 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, | |||
281 | if (frame->downmix_inhibit) | 290 | if (frame->downmix_inhibit) |
282 | ptr[4] |= BIT(7); | 291 | ptr[4] |= BIT(7); |
283 | 292 | ||
284 | hdmi_infoframe_checksum(buffer, length); | 293 | hdmi_infoframe_set_checksum(buffer, length); |
285 | 294 | ||
286 | return length; | 295 | return length; |
287 | } | 296 | } |
@@ -373,7 +382,7 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, | |||
373 | ptr[9] = (frame->s3d_ext_data & 0xf) << 4; | 382 | ptr[9] = (frame->s3d_ext_data & 0xf) << 4; |
374 | } | 383 | } |
375 | 384 | ||
376 | hdmi_infoframe_checksum(buffer, length); | 385 | hdmi_infoframe_set_checksum(buffer, length); |
377 | 386 | ||
378 | return length; | 387 | return length; |
379 | } | 388 | } |
@@ -434,3 +443,802 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) | |||
434 | return length; | 443 | return length; |
435 | } | 444 | } |
436 | EXPORT_SYMBOL(hdmi_infoframe_pack); | 445 | EXPORT_SYMBOL(hdmi_infoframe_pack); |
446 | |||
447 | static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type) | ||
448 | { | ||
449 | if (type < 0x80 || type > 0x9f) | ||
450 | return "Invalid"; | ||
451 | switch (type) { | ||
452 | case HDMI_INFOFRAME_TYPE_VENDOR: | ||
453 | return "Vendor"; | ||
454 | case HDMI_INFOFRAME_TYPE_AVI: | ||
455 | return "Auxiliary Video Information (AVI)"; | ||
456 | case HDMI_INFOFRAME_TYPE_SPD: | ||
457 | return "Source Product Description (SPD)"; | ||
458 | case HDMI_INFOFRAME_TYPE_AUDIO: | ||
459 | return "Audio"; | ||
460 | } | ||
461 | return "Reserved"; | ||
462 | } | ||
463 | |||
464 | static void hdmi_infoframe_log_header(const char *level, | ||
465 | struct device *dev, | ||
466 | struct hdmi_any_infoframe *frame) | ||
467 | { | ||
468 | hdmi_log("HDMI infoframe: %s, version %u, length %u\n", | ||
469 | hdmi_infoframe_type_get_name(frame->type), | ||
470 | frame->version, frame->length); | ||
471 | } | ||
472 | |||
473 | static const char *hdmi_colorspace_get_name(enum hdmi_colorspace colorspace) | ||
474 | { | ||
475 | switch (colorspace) { | ||
476 | case HDMI_COLORSPACE_RGB: | ||
477 | return "RGB"; | ||
478 | case HDMI_COLORSPACE_YUV422: | ||
479 | return "YCbCr 4:2:2"; | ||
480 | case HDMI_COLORSPACE_YUV444: | ||
481 | return "YCbCr 4:4:4"; | ||
482 | case HDMI_COLORSPACE_YUV420: | ||
483 | return "YCbCr 4:2:0"; | ||
484 | case HDMI_COLORSPACE_RESERVED4: | ||
485 | return "Reserved (4)"; | ||
486 | case HDMI_COLORSPACE_RESERVED5: | ||
487 | return "Reserved (5)"; | ||
488 | case HDMI_COLORSPACE_RESERVED6: | ||
489 | return "Reserved (6)"; | ||
490 | case HDMI_COLORSPACE_IDO_DEFINED: | ||
491 | return "IDO Defined"; | ||
492 | } | ||
493 | return "Invalid"; | ||
494 | } | ||
495 | |||
496 | static const char *hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode) | ||
497 | { | ||
498 | switch (scan_mode) { | ||
499 | case HDMI_SCAN_MODE_NONE: | ||
500 | return "No Data"; | ||
501 | case HDMI_SCAN_MODE_OVERSCAN: | ||
502 | return "Overscan"; | ||
503 | case HDMI_SCAN_MODE_UNDERSCAN: | ||
504 | return "Underscan"; | ||
505 | case HDMI_SCAN_MODE_RESERVED: | ||
506 | return "Reserved"; | ||
507 | } | ||
508 | return "Invalid"; | ||
509 | } | ||
510 | |||
511 | static const char *hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry) | ||
512 | { | ||
513 | switch (colorimetry) { | ||
514 | case HDMI_COLORIMETRY_NONE: | ||
515 | return "No Data"; | ||
516 | case HDMI_COLORIMETRY_ITU_601: | ||
517 | return "ITU601"; | ||
518 | case HDMI_COLORIMETRY_ITU_709: | ||
519 | return "ITU709"; | ||
520 | case HDMI_COLORIMETRY_EXTENDED: | ||
521 | return "Extended"; | ||
522 | } | ||
523 | return "Invalid"; | ||
524 | } | ||
525 | |||
526 | static const char * | ||
527 | hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect) | ||
528 | { | ||
529 | switch (picture_aspect) { | ||
530 | case HDMI_PICTURE_ASPECT_NONE: | ||
531 | return "No Data"; | ||
532 | case HDMI_PICTURE_ASPECT_4_3: | ||
533 | return "4:3"; | ||
534 | case HDMI_PICTURE_ASPECT_16_9: | ||
535 | return "16:9"; | ||
536 | case HDMI_PICTURE_ASPECT_RESERVED: | ||
537 | return "Reserved"; | ||
538 | } | ||
539 | return "Invalid"; | ||
540 | } | ||
541 | |||
542 | static const char * | ||
543 | hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect) | ||
544 | { | ||
545 | if (active_aspect < 0 || active_aspect > 0xf) | ||
546 | return "Invalid"; | ||
547 | |||
548 | switch (active_aspect) { | ||
549 | case HDMI_ACTIVE_ASPECT_16_9_TOP: | ||
550 | return "16:9 Top"; | ||
551 | case HDMI_ACTIVE_ASPECT_14_9_TOP: | ||
552 | return "14:9 Top"; | ||
553 | case HDMI_ACTIVE_ASPECT_16_9_CENTER: | ||
554 | return "16:9 Center"; | ||
555 | case HDMI_ACTIVE_ASPECT_PICTURE: | ||
556 | return "Same as Picture"; | ||
557 | case HDMI_ACTIVE_ASPECT_4_3: | ||
558 | return "4:3"; | ||
559 | case HDMI_ACTIVE_ASPECT_16_9: | ||
560 | return "16:9"; | ||
561 | case HDMI_ACTIVE_ASPECT_14_9: | ||
562 | return "14:9"; | ||
563 | case HDMI_ACTIVE_ASPECT_4_3_SP_14_9: | ||
564 | return "4:3 SP 14:9"; | ||
565 | case HDMI_ACTIVE_ASPECT_16_9_SP_14_9: | ||
566 | return "16:9 SP 14:9"; | ||
567 | case HDMI_ACTIVE_ASPECT_16_9_SP_4_3: | ||
568 | return "16:9 SP 4:3"; | ||
569 | } | ||
570 | return "Reserved"; | ||
571 | } | ||
572 | |||
573 | static const char * | ||
574 | hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col) | ||
575 | { | ||
576 | switch (ext_col) { | ||
577 | case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601: | ||
578 | return "xvYCC 601"; | ||
579 | case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709: | ||
580 | return "xvYCC 709"; | ||
581 | case HDMI_EXTENDED_COLORIMETRY_S_YCC_601: | ||
582 | return "sYCC 601"; | ||
583 | case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601: | ||
584 | return "Adobe YCC 601"; | ||
585 | case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB: | ||
586 | return "Adobe RGB"; | ||
587 | case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM: | ||
588 | return "BT.2020 Constant Luminance"; | ||
589 | case HDMI_EXTENDED_COLORIMETRY_BT2020: | ||
590 | return "BT.2020"; | ||
591 | case HDMI_EXTENDED_COLORIMETRY_RESERVED: | ||
592 | return "Reserved"; | ||
593 | } | ||
594 | return "Invalid"; | ||
595 | } | ||
596 | |||
597 | static const char * | ||
598 | hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange) | ||
599 | { | ||
600 | switch (qrange) { | ||
601 | case HDMI_QUANTIZATION_RANGE_DEFAULT: | ||
602 | return "Default"; | ||
603 | case HDMI_QUANTIZATION_RANGE_LIMITED: | ||
604 | return "Limited"; | ||
605 | case HDMI_QUANTIZATION_RANGE_FULL: | ||
606 | return "Full"; | ||
607 | case HDMI_QUANTIZATION_RANGE_RESERVED: | ||
608 | return "Reserved"; | ||
609 | } | ||
610 | return "Invalid"; | ||
611 | } | ||
612 | |||
613 | static const char *hdmi_nups_get_name(enum hdmi_nups nups) | ||
614 | { | ||
615 | switch (nups) { | ||
616 | case HDMI_NUPS_UNKNOWN: | ||
617 | return "Unknown Non-uniform Scaling"; | ||
618 | case HDMI_NUPS_HORIZONTAL: | ||
619 | return "Horizontally Scaled"; | ||
620 | case HDMI_NUPS_VERTICAL: | ||
621 | return "Vertically Scaled"; | ||
622 | case HDMI_NUPS_BOTH: | ||
623 | return "Horizontally and Vertically Scaled"; | ||
624 | } | ||
625 | return "Invalid"; | ||
626 | } | ||
627 | |||
628 | static const char * | ||
629 | hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange) | ||
630 | { | ||
631 | switch (qrange) { | ||
632 | case HDMI_YCC_QUANTIZATION_RANGE_LIMITED: | ||
633 | return "Limited"; | ||
634 | case HDMI_YCC_QUANTIZATION_RANGE_FULL: | ||
635 | return "Full"; | ||
636 | } | ||
637 | return "Invalid"; | ||
638 | } | ||
639 | |||
640 | static const char * | ||
641 | hdmi_content_type_get_name(enum hdmi_content_type content_type) | ||
642 | { | ||
643 | switch (content_type) { | ||
644 | case HDMI_CONTENT_TYPE_GRAPHICS: | ||
645 | return "Graphics"; | ||
646 | case HDMI_CONTENT_TYPE_PHOTO: | ||
647 | return "Photo"; | ||
648 | case HDMI_CONTENT_TYPE_CINEMA: | ||
649 | return "Cinema"; | ||
650 | case HDMI_CONTENT_TYPE_GAME: | ||
651 | return "Game"; | ||
652 | } | ||
653 | return "Invalid"; | ||
654 | } | ||
655 | |||
656 | /** | ||
657 | * hdmi_avi_infoframe_log() - log info of HDMI AVI infoframe | ||
658 | * @level: logging level | ||
659 | * @dev: device | ||
660 | * @frame: HDMI AVI infoframe | ||
661 | */ | ||
662 | static void hdmi_avi_infoframe_log(const char *level, | ||
663 | struct device *dev, | ||
664 | struct hdmi_avi_infoframe *frame) | ||
665 | { | ||
666 | hdmi_infoframe_log_header(level, dev, | ||
667 | (struct hdmi_any_infoframe *)frame); | ||
668 | |||
669 | hdmi_log(" colorspace: %s\n", | ||
670 | hdmi_colorspace_get_name(frame->colorspace)); | ||
671 | hdmi_log(" scan mode: %s\n", | ||
672 | hdmi_scan_mode_get_name(frame->scan_mode)); | ||
673 | hdmi_log(" colorimetry: %s\n", | ||
674 | hdmi_colorimetry_get_name(frame->colorimetry)); | ||
675 | hdmi_log(" picture aspect: %s\n", | ||
676 | hdmi_picture_aspect_get_name(frame->picture_aspect)); | ||
677 | hdmi_log(" active aspect: %s\n", | ||
678 | hdmi_active_aspect_get_name(frame->active_aspect)); | ||
679 | hdmi_log(" itc: %s\n", frame->itc ? "IT Content" : "No Data"); | ||
680 | hdmi_log(" extended colorimetry: %s\n", | ||
681 | hdmi_extended_colorimetry_get_name(frame->extended_colorimetry)); | ||
682 | hdmi_log(" quantization range: %s\n", | ||
683 | hdmi_quantization_range_get_name(frame->quantization_range)); | ||
684 | hdmi_log(" nups: %s\n", hdmi_nups_get_name(frame->nups)); | ||
685 | hdmi_log(" video code: %u\n", frame->video_code); | ||
686 | hdmi_log(" ycc quantization range: %s\n", | ||
687 | hdmi_ycc_quantization_range_get_name(frame->ycc_quantization_range)); | ||
688 | hdmi_log(" hdmi content type: %s\n", | ||
689 | hdmi_content_type_get_name(frame->content_type)); | ||
690 | hdmi_log(" pixel repeat: %u\n", frame->pixel_repeat); | ||
691 | hdmi_log(" bar top %u, bottom %u, left %u, right %u\n", | ||
692 | frame->top_bar, frame->bottom_bar, | ||
693 | frame->left_bar, frame->right_bar); | ||
694 | } | ||
695 | |||
696 | static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi) | ||
697 | { | ||
698 | if (sdi < 0 || sdi > 0xff) | ||
699 | return "Invalid"; | ||
700 | switch (sdi) { | ||
701 | case HDMI_SPD_SDI_UNKNOWN: | ||
702 | return "Unknown"; | ||
703 | case HDMI_SPD_SDI_DSTB: | ||
704 | return "Digital STB"; | ||
705 | case HDMI_SPD_SDI_DVDP: | ||
706 | return "DVD Player"; | ||
707 | case HDMI_SPD_SDI_DVHS: | ||
708 | return "D-VHS"; | ||
709 | case HDMI_SPD_SDI_HDDVR: | ||
710 | return "HDD Videorecorder"; | ||
711 | case HDMI_SPD_SDI_DVC: | ||
712 | return "DVC"; | ||
713 | case HDMI_SPD_SDI_DSC: | ||
714 | return "DSC"; | ||
715 | case HDMI_SPD_SDI_VCD: | ||
716 | return "Video CD"; | ||
717 | case HDMI_SPD_SDI_GAME: | ||
718 | return "Game"; | ||
719 | case HDMI_SPD_SDI_PC: | ||
720 | return "PC General"; | ||
721 | case HDMI_SPD_SDI_BD: | ||
722 | return "Blu-Ray Disc (BD)"; | ||
723 | case HDMI_SPD_SDI_SACD: | ||
724 | return "Super Audio CD"; | ||
725 | case HDMI_SPD_SDI_HDDVD: | ||
726 | return "HD DVD"; | ||
727 | case HDMI_SPD_SDI_PMP: | ||
728 | return "PMP"; | ||
729 | } | ||
730 | return "Reserved"; | ||
731 | } | ||
732 | |||
733 | /** | ||
734 | * hdmi_spd_infoframe_log() - log info of HDMI SPD infoframe | ||
735 | * @level: logging level | ||
736 | * @dev: device | ||
737 | * @frame: HDMI SPD infoframe | ||
738 | */ | ||
739 | static void hdmi_spd_infoframe_log(const char *level, | ||
740 | struct device *dev, | ||
741 | struct hdmi_spd_infoframe *frame) | ||
742 | { | ||
743 | u8 buf[17]; | ||
744 | |||
745 | hdmi_infoframe_log_header(level, dev, | ||
746 | (struct hdmi_any_infoframe *)frame); | ||
747 | |||
748 | memset(buf, 0, sizeof(buf)); | ||
749 | |||
750 | strncpy(buf, frame->vendor, 8); | ||
751 | hdmi_log(" vendor: %s\n", buf); | ||
752 | strncpy(buf, frame->product, 16); | ||
753 | hdmi_log(" product: %s\n", buf); | ||
754 | hdmi_log(" source device information: %s (0x%x)\n", | ||
755 | hdmi_spd_sdi_get_name(frame->sdi), frame->sdi); | ||
756 | } | ||
757 | |||
758 | static const char * | ||
759 | hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type) | ||
760 | { | ||
761 | switch (coding_type) { | ||
762 | case HDMI_AUDIO_CODING_TYPE_STREAM: | ||
763 | return "Refer to Stream Header"; | ||
764 | case HDMI_AUDIO_CODING_TYPE_PCM: | ||
765 | return "PCM"; | ||
766 | case HDMI_AUDIO_CODING_TYPE_AC3: | ||
767 | return "AC-3"; | ||
768 | case HDMI_AUDIO_CODING_TYPE_MPEG1: | ||
769 | return "MPEG1"; | ||
770 | case HDMI_AUDIO_CODING_TYPE_MP3: | ||
771 | return "MP3"; | ||
772 | case HDMI_AUDIO_CODING_TYPE_MPEG2: | ||
773 | return "MPEG2"; | ||
774 | case HDMI_AUDIO_CODING_TYPE_AAC_LC: | ||
775 | return "AAC"; | ||
776 | case HDMI_AUDIO_CODING_TYPE_DTS: | ||
777 | return "DTS"; | ||
778 | case HDMI_AUDIO_CODING_TYPE_ATRAC: | ||
779 | return "ATRAC"; | ||
780 | case HDMI_AUDIO_CODING_TYPE_DSD: | ||
781 | return "One Bit Audio"; | ||
782 | case HDMI_AUDIO_CODING_TYPE_EAC3: | ||
783 | return "Dolby Digital +"; | ||
784 | case HDMI_AUDIO_CODING_TYPE_DTS_HD: | ||
785 | return "DTS-HD"; | ||
786 | case HDMI_AUDIO_CODING_TYPE_MLP: | ||
787 | return "MAT (MLP)"; | ||
788 | case HDMI_AUDIO_CODING_TYPE_DST: | ||
789 | return "DST"; | ||
790 | case HDMI_AUDIO_CODING_TYPE_WMA_PRO: | ||
791 | return "WMA PRO"; | ||
792 | case HDMI_AUDIO_CODING_TYPE_CXT: | ||
793 | return "Refer to CXT"; | ||
794 | } | ||
795 | return "Invalid"; | ||
796 | } | ||
797 | |||
798 | static const char * | ||
799 | hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size) | ||
800 | { | ||
801 | switch (sample_size) { | ||
802 | case HDMI_AUDIO_SAMPLE_SIZE_STREAM: | ||
803 | return "Refer to Stream Header"; | ||
804 | case HDMI_AUDIO_SAMPLE_SIZE_16: | ||
805 | return "16 bit"; | ||
806 | case HDMI_AUDIO_SAMPLE_SIZE_20: | ||
807 | return "20 bit"; | ||
808 | case HDMI_AUDIO_SAMPLE_SIZE_24: | ||
809 | return "24 bit"; | ||
810 | } | ||
811 | return "Invalid"; | ||
812 | } | ||
813 | |||
814 | static const char * | ||
815 | hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq) | ||
816 | { | ||
817 | switch (freq) { | ||
818 | case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM: | ||
819 | return "Refer to Stream Header"; | ||
820 | case HDMI_AUDIO_SAMPLE_FREQUENCY_32000: | ||
821 | return "32 kHz"; | ||
822 | case HDMI_AUDIO_SAMPLE_FREQUENCY_44100: | ||
823 | return "44.1 kHz (CD)"; | ||
824 | case HDMI_AUDIO_SAMPLE_FREQUENCY_48000: | ||
825 | return "48 kHz"; | ||
826 | case HDMI_AUDIO_SAMPLE_FREQUENCY_88200: | ||
827 | return "88.2 kHz"; | ||
828 | case HDMI_AUDIO_SAMPLE_FREQUENCY_96000: | ||
829 | return "96 kHz"; | ||
830 | case HDMI_AUDIO_SAMPLE_FREQUENCY_176400: | ||
831 | return "176.4 kHz"; | ||
832 | case HDMI_AUDIO_SAMPLE_FREQUENCY_192000: | ||
833 | return "192 kHz"; | ||
834 | } | ||
835 | return "Invalid"; | ||
836 | } | ||
837 | |||
838 | static const char * | ||
839 | hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx) | ||
840 | { | ||
841 | if (ctx < 0 || ctx > 0x1f) | ||
842 | return "Invalid"; | ||
843 | |||
844 | switch (ctx) { | ||
845 | case HDMI_AUDIO_CODING_TYPE_EXT_CT: | ||
846 | return "Refer to CT"; | ||
847 | case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC: | ||
848 | return "HE AAC"; | ||
849 | case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2: | ||
850 | return "HE AAC v2"; | ||
851 | case HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND: | ||
852 | return "MPEG SURROUND"; | ||
853 | case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC: | ||
854 | return "MPEG-4 HE AAC"; | ||
855 | case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2: | ||
856 | return "MPEG-4 HE AAC v2"; | ||
857 | case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC: | ||
858 | return "MPEG-4 AAC LC"; | ||
859 | case HDMI_AUDIO_CODING_TYPE_EXT_DRA: | ||
860 | return "DRA"; | ||
861 | case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND: | ||
862 | return "MPEG-4 HE AAC + MPEG Surround"; | ||
863 | case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND: | ||
864 | return "MPEG-4 AAC LC + MPEG Surround"; | ||
865 | } | ||
866 | return "Reserved"; | ||
867 | } | ||
868 | |||
869 | /** | ||
870 | * hdmi_audio_infoframe_log() - log info of HDMI AUDIO infoframe | ||
871 | * @level: logging level | ||
872 | * @dev: device | ||
873 | * @frame: HDMI AUDIO infoframe | ||
874 | */ | ||
875 | static void hdmi_audio_infoframe_log(const char *level, | ||
876 | struct device *dev, | ||
877 | struct hdmi_audio_infoframe *frame) | ||
878 | { | ||
879 | hdmi_infoframe_log_header(level, dev, | ||
880 | (struct hdmi_any_infoframe *)frame); | ||
881 | |||
882 | if (frame->channels) | ||
883 | hdmi_log(" channels: %u\n", frame->channels - 1); | ||
884 | else | ||
885 | hdmi_log(" channels: Refer to stream header\n"); | ||
886 | hdmi_log(" coding type: %s\n", | ||
887 | hdmi_audio_coding_type_get_name(frame->coding_type)); | ||
888 | hdmi_log(" sample size: %s\n", | ||
889 | hdmi_audio_sample_size_get_name(frame->sample_size)); | ||
890 | hdmi_log(" sample frequency: %s\n", | ||
891 | hdmi_audio_sample_frequency_get_name(frame->sample_frequency)); | ||
892 | hdmi_log(" coding type ext: %s\n", | ||
893 | hdmi_audio_coding_type_ext_get_name(frame->coding_type_ext)); | ||
894 | hdmi_log(" channel allocation: 0x%x\n", | ||
895 | frame->channel_allocation); | ||
896 | hdmi_log(" level shift value: %u dB\n", | ||
897 | frame->level_shift_value); | ||
898 | hdmi_log(" downmix inhibit: %s\n", | ||
899 | frame->downmix_inhibit ? "Yes" : "No"); | ||
900 | } | ||
901 | |||
902 | static const char * | ||
903 | hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct) | ||
904 | { | ||
905 | if (s3d_struct < 0 || s3d_struct > 0xf) | ||
906 | return "Invalid"; | ||
907 | |||
908 | switch (s3d_struct) { | ||
909 | case HDMI_3D_STRUCTURE_FRAME_PACKING: | ||
910 | return "Frame Packing"; | ||
911 | case HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE: | ||
912 | return "Field Alternative"; | ||
913 | case HDMI_3D_STRUCTURE_LINE_ALTERNATIVE: | ||
914 | return "Line Alternative"; | ||
915 | case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL: | ||
916 | return "Side-by-side (Full)"; | ||
917 | case HDMI_3D_STRUCTURE_L_DEPTH: | ||
918 | return "L + Depth"; | ||
919 | case HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH: | ||
920 | return "L + Depth + Graphics + Graphics-depth"; | ||
921 | case HDMI_3D_STRUCTURE_TOP_AND_BOTTOM: | ||
922 | return "Top-and-Bottom"; | ||
923 | case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF: | ||
924 | return "Side-by-side (Half)"; | ||
925 | default: | ||
926 | break; | ||
927 | } | ||
928 | return "Reserved"; | ||
929 | } | ||
930 | |||
931 | /** | ||
932 | * hdmi_vendor_infoframe_log() - log info of HDMI VENDOR infoframe | ||
933 | * @level: logging level | ||
934 | * @dev: device | ||
935 | * @frame: HDMI VENDOR infoframe | ||
936 | */ | ||
937 | static void | ||
938 | hdmi_vendor_any_infoframe_log(const char *level, | ||
939 | struct device *dev, | ||
940 | union hdmi_vendor_any_infoframe *frame) | ||
941 | { | ||
942 | struct hdmi_vendor_infoframe *hvf = &frame->hdmi; | ||
943 | |||
944 | hdmi_infoframe_log_header(level, dev, | ||
945 | (struct hdmi_any_infoframe *)frame); | ||
946 | |||
947 | if (frame->any.oui != HDMI_IEEE_OUI) { | ||
948 | hdmi_log(" not a HDMI vendor infoframe\n"); | ||
949 | return; | ||
950 | } | ||
951 | if (hvf->vic == 0 && hvf->s3d_struct == HDMI_3D_STRUCTURE_INVALID) { | ||
952 | hdmi_log(" empty frame\n"); | ||
953 | return; | ||
954 | } | ||
955 | |||
956 | if (hvf->vic) | ||
957 | hdmi_log(" HDMI VIC: %u\n", hvf->vic); | ||
958 | if (hvf->s3d_struct != HDMI_3D_STRUCTURE_INVALID) { | ||
959 | hdmi_log(" 3D structure: %s\n", | ||
960 | hdmi_3d_structure_get_name(hvf->s3d_struct)); | ||
961 | if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) | ||
962 | hdmi_log(" 3D extension data: %d\n", | ||
963 | hvf->s3d_ext_data); | ||
964 | } | ||
965 | } | ||
966 | |||
967 | /** | ||
968 | * hdmi_infoframe_log() - log info of HDMI infoframe | ||
969 | * @level: logging level | ||
970 | * @dev: device | ||
971 | * @frame: HDMI infoframe | ||
972 | */ | ||
973 | void hdmi_infoframe_log(const char *level, | ||
974 | struct device *dev, | ||
975 | union hdmi_infoframe *frame) | ||
976 | { | ||
977 | switch (frame->any.type) { | ||
978 | case HDMI_INFOFRAME_TYPE_AVI: | ||
979 | hdmi_avi_infoframe_log(level, dev, &frame->avi); | ||
980 | break; | ||
981 | case HDMI_INFOFRAME_TYPE_SPD: | ||
982 | hdmi_spd_infoframe_log(level, dev, &frame->spd); | ||
983 | break; | ||
984 | case HDMI_INFOFRAME_TYPE_AUDIO: | ||
985 | hdmi_audio_infoframe_log(level, dev, &frame->audio); | ||
986 | break; | ||
987 | case HDMI_INFOFRAME_TYPE_VENDOR: | ||
988 | hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor); | ||
989 | break; | ||
990 | } | ||
991 | } | ||
992 | EXPORT_SYMBOL(hdmi_infoframe_log); | ||
993 | |||
994 | /** | ||
995 | * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe | ||
996 | * @buffer: source buffer | ||
997 | * @frame: HDMI AVI infoframe | ||
998 | * | ||
999 | * Unpacks the information contained in binary @buffer into a structured | ||
1000 | * @frame of the HDMI Auxiliary Video (AVI) information frame. | ||
1001 | * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 | ||
1002 | * specification. | ||
1003 | * | ||
1004 | * Returns 0 on success or a negative error code on failure. | ||
1005 | */ | ||
1006 | static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, | ||
1007 | void *buffer) | ||
1008 | { | ||
1009 | u8 *ptr = buffer; | ||
1010 | int ret; | ||
1011 | |||
1012 | if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI || | ||
1013 | ptr[1] != 2 || | ||
1014 | ptr[2] != HDMI_AVI_INFOFRAME_SIZE) | ||
1015 | return -EINVAL; | ||
1016 | |||
1017 | if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0) | ||
1018 | return -EINVAL; | ||
1019 | |||
1020 | ret = hdmi_avi_infoframe_init(frame); | ||
1021 | if (ret) | ||
1022 | return ret; | ||
1023 | |||
1024 | ptr += HDMI_INFOFRAME_HEADER_SIZE; | ||
1025 | |||
1026 | frame->colorspace = (ptr[0] >> 5) & 0x3; | ||
1027 | if (ptr[0] & 0x10) | ||
1028 | frame->active_aspect = ptr[1] & 0xf; | ||
1029 | if (ptr[0] & 0x8) { | ||
1030 | frame->top_bar = (ptr[5] << 8) + ptr[6]; | ||
1031 | frame->bottom_bar = (ptr[7] << 8) + ptr[8]; | ||
1032 | } | ||
1033 | if (ptr[0] & 0x4) { | ||
1034 | frame->left_bar = (ptr[9] << 8) + ptr[10]; | ||
1035 | frame->right_bar = (ptr[11] << 8) + ptr[12]; | ||
1036 | } | ||
1037 | frame->scan_mode = ptr[0] & 0x3; | ||
1038 | |||
1039 | frame->colorimetry = (ptr[1] >> 6) & 0x3; | ||
1040 | frame->picture_aspect = (ptr[1] >> 4) & 0x3; | ||
1041 | frame->active_aspect = ptr[1] & 0xf; | ||
1042 | |||
1043 | frame->itc = ptr[2] & 0x80 ? true : false; | ||
1044 | frame->extended_colorimetry = (ptr[2] >> 4) & 0x7; | ||
1045 | frame->quantization_range = (ptr[2] >> 2) & 0x3; | ||
1046 | frame->nups = ptr[2] & 0x3; | ||
1047 | |||
1048 | frame->video_code = ptr[3] & 0x7f; | ||
1049 | frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3; | ||
1050 | frame->content_type = (ptr[4] >> 4) & 0x3; | ||
1051 | |||
1052 | frame->pixel_repeat = ptr[4] & 0xf; | ||
1053 | |||
1054 | return 0; | ||
1055 | } | ||
1056 | |||
1057 | /** | ||
1058 | * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe | ||
1059 | * @buffer: source buffer | ||
1060 | * @frame: HDMI SPD infoframe | ||
1061 | * | ||
1062 | * Unpacks the information contained in binary @buffer into a structured | ||
1063 | * @frame of the HDMI Source Product Description (SPD) information frame. | ||
1064 | * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 | ||
1065 | * specification. | ||
1066 | * | ||
1067 | * Returns 0 on success or a negative error code on failure. | ||
1068 | */ | ||
1069 | static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, | ||
1070 | void *buffer) | ||
1071 | { | ||
1072 | u8 *ptr = buffer; | ||
1073 | int ret; | ||
1074 | |||
1075 | if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD || | ||
1076 | ptr[1] != 1 || | ||
1077 | ptr[2] != HDMI_SPD_INFOFRAME_SIZE) { | ||
1078 | return -EINVAL; | ||
1079 | } | ||
1080 | |||
1081 | if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0) | ||
1082 | return -EINVAL; | ||
1083 | |||
1084 | ptr += HDMI_INFOFRAME_HEADER_SIZE; | ||
1085 | |||
1086 | ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8); | ||
1087 | if (ret) | ||
1088 | return ret; | ||
1089 | |||
1090 | frame->sdi = ptr[24]; | ||
1091 | |||
1092 | return 0; | ||
1093 | } | ||
1094 | |||
1095 | /** | ||
1096 | * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe | ||
1097 | * @buffer: source buffer | ||
1098 | * @frame: HDMI Audio infoframe | ||
1099 | * | ||
1100 | * Unpacks the information contained in binary @buffer into a structured | ||
1101 | * @frame of the HDMI Audio information frame. | ||
1102 | * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 | ||
1103 | * specification. | ||
1104 | * | ||
1105 | * Returns 0 on success or a negative error code on failure. | ||
1106 | */ | ||
1107 | static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, | ||
1108 | void *buffer) | ||
1109 | { | ||
1110 | u8 *ptr = buffer; | ||
1111 | int ret; | ||
1112 | |||
1113 | if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO || | ||
1114 | ptr[1] != 1 || | ||
1115 | ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) { | ||
1116 | return -EINVAL; | ||
1117 | } | ||
1118 | |||
1119 | if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0) | ||
1120 | return -EINVAL; | ||
1121 | |||
1122 | ret = hdmi_audio_infoframe_init(frame); | ||
1123 | if (ret) | ||
1124 | return ret; | ||
1125 | |||
1126 | ptr += HDMI_INFOFRAME_HEADER_SIZE; | ||
1127 | |||
1128 | frame->channels = ptr[0] & 0x7; | ||
1129 | frame->coding_type = (ptr[0] >> 4) & 0xf; | ||
1130 | frame->sample_size = ptr[1] & 0x3; | ||
1131 | frame->sample_frequency = (ptr[1] >> 2) & 0x7; | ||
1132 | frame->coding_type_ext = ptr[2] & 0x1f; | ||
1133 | frame->channel_allocation = ptr[3]; | ||
1134 | frame->level_shift_value = (ptr[4] >> 3) & 0xf; | ||
1135 | frame->downmix_inhibit = ptr[4] & 0x80 ? true : false; | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | /** | ||
1141 | * hdmi_vendor_infoframe_unpack() - unpack binary buffer to a HDMI vendor infoframe | ||
1142 | * @buffer: source buffer | ||
1143 | * @frame: HDMI Vendor infoframe | ||
1144 | * | ||
1145 | * Unpacks the information contained in binary @buffer into a structured | ||
1146 | * @frame of the HDMI Vendor information frame. | ||
1147 | * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 | ||
1148 | * specification. | ||
1149 | * | ||
1150 | * Returns 0 on success or a negative error code on failure. | ||
1151 | */ | ||
1152 | static int | ||
1153 | hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, | ||
1154 | void *buffer) | ||
1155 | { | ||
1156 | u8 *ptr = buffer; | ||
1157 | size_t length; | ||
1158 | int ret; | ||
1159 | u8 hdmi_video_format; | ||
1160 | struct hdmi_vendor_infoframe *hvf = &frame->hdmi; | ||
1161 | |||
1162 | if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR || | ||
1163 | ptr[1] != 1 || | ||
1164 | (ptr[2] != 5 && ptr[2] != 6)) | ||
1165 | return -EINVAL; | ||
1166 | |||
1167 | length = ptr[2]; | ||
1168 | |||
1169 | if (hdmi_infoframe_checksum(buffer, | ||
1170 | HDMI_INFOFRAME_HEADER_SIZE + length) != 0) | ||
1171 | return -EINVAL; | ||
1172 | |||
1173 | ptr += HDMI_INFOFRAME_HEADER_SIZE; | ||
1174 | |||
1175 | /* HDMI OUI */ | ||
1176 | if ((ptr[0] != 0x03) || | ||
1177 | (ptr[1] != 0x0c) || | ||
1178 | (ptr[2] != 0x00)) | ||
1179 | return -EINVAL; | ||
1180 | |||
1181 | hdmi_video_format = ptr[3] >> 5; | ||
1182 | |||
1183 | if (hdmi_video_format > 0x2) | ||
1184 | return -EINVAL; | ||
1185 | |||
1186 | ret = hdmi_vendor_infoframe_init(hvf); | ||
1187 | if (ret) | ||
1188 | return ret; | ||
1189 | |||
1190 | hvf->length = length; | ||
1191 | |||
1192 | if (hdmi_video_format == 0x1) { | ||
1193 | hvf->vic = ptr[4]; | ||
1194 | } else if (hdmi_video_format == 0x2) { | ||
1195 | hvf->s3d_struct = ptr[4] >> 4; | ||
1196 | if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) { | ||
1197 | if (length == 6) | ||
1198 | hvf->s3d_ext_data = ptr[5] >> 4; | ||
1199 | else | ||
1200 | return -EINVAL; | ||
1201 | } | ||
1202 | } | ||
1203 | |||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1207 | /** | ||
1208 | * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe | ||
1209 | * @buffer: source buffer | ||
1210 | * @frame: HDMI infoframe | ||
1211 | * | ||
1212 | * Unpacks the information contained in binary buffer @buffer into a structured | ||
1213 | * @frame of a HDMI infoframe. | ||
1214 | * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 | ||
1215 | * specification. | ||
1216 | * | ||
1217 | * Returns 0 on success or a negative error code on failure. | ||
1218 | */ | ||
1219 | int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer) | ||
1220 | { | ||
1221 | int ret; | ||
1222 | u8 *ptr = buffer; | ||
1223 | |||
1224 | switch (ptr[0]) { | ||
1225 | case HDMI_INFOFRAME_TYPE_AVI: | ||
1226 | ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer); | ||
1227 | break; | ||
1228 | case HDMI_INFOFRAME_TYPE_SPD: | ||
1229 | ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer); | ||
1230 | break; | ||
1231 | case HDMI_INFOFRAME_TYPE_AUDIO: | ||
1232 | ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer); | ||
1233 | break; | ||
1234 | case HDMI_INFOFRAME_TYPE_VENDOR: | ||
1235 | ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer); | ||
1236 | break; | ||
1237 | default: | ||
1238 | ret = -EINVAL; | ||
1239 | break; | ||
1240 | } | ||
1241 | |||
1242 | return ret; | ||
1243 | } | ||
1244 | EXPORT_SYMBOL(hdmi_infoframe_unpack); | ||