diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-08-06 05:52:05 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-09-15 11:19:49 -0400 |
commit | 96795df15c89ce30261a31289740b4621bcec0fe (patch) | |
tree | a9ccba4cd540747ef5f033be23fbabf7dbd9bec3 | |
parent | ec5d3e83d332ac5dfde8e0a1f57393fc91d55030 (diff) |
drm/i2c: tda998x: use more HDMI helpers
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 71 |
1 files changed, 31 insertions, 40 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 1285fb354813..1c6fc245514f 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
@@ -640,66 +640,57 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data) | |||
640 | return IRQ_RETVAL(handled); | 640 | return IRQ_RETVAL(handled); |
641 | } | 641 | } |
642 | 642 | ||
643 | static u8 tda998x_cksum(u8 *buf, size_t bytes) | ||
644 | { | ||
645 | int sum = 0; | ||
646 | |||
647 | while (bytes--) | ||
648 | sum -= *buf++; | ||
649 | return sum; | ||
650 | } | ||
651 | |||
652 | #define HB(x) (x) | ||
653 | #define PB(x) (HB(2) + 1 + (x)) | ||
654 | |||
655 | static void | 643 | static void |
656 | tda998x_write_if(struct tda998x_priv *priv, u8 bit, u16 addr, | 644 | tda998x_write_if(struct tda998x_priv *priv, u8 bit, u16 addr, |
657 | u8 *buf, size_t size) | 645 | union hdmi_infoframe *frame) |
658 | { | 646 | { |
647 | u8 buf[32]; | ||
648 | ssize_t len; | ||
649 | |||
650 | len = hdmi_infoframe_pack(frame, buf, sizeof(buf)); | ||
651 | if (len < 0) { | ||
652 | dev_err(&priv->hdmi->dev, | ||
653 | "hdmi_infoframe_pack() type=0x%02x failed: %zd\n", | ||
654 | frame->any.type, len); | ||
655 | return; | ||
656 | } | ||
657 | |||
659 | reg_clear(priv, REG_DIP_IF_FLAGS, bit); | 658 | reg_clear(priv, REG_DIP_IF_FLAGS, bit); |
660 | reg_write_range(priv, addr, buf, size); | 659 | reg_write_range(priv, addr, buf, len); |
661 | reg_set(priv, REG_DIP_IF_FLAGS, bit); | 660 | reg_set(priv, REG_DIP_IF_FLAGS, bit); |
662 | } | 661 | } |
663 | 662 | ||
664 | static void | 663 | static void |
665 | tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) | 664 | tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) |
666 | { | 665 | { |
667 | u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1]; | 666 | union hdmi_infoframe frame; |
667 | |||
668 | hdmi_audio_infoframe_init(&frame.audio); | ||
668 | 669 | ||
669 | memset(buf, 0, sizeof(buf)); | 670 | frame.audio.channels = p->audio_frame[1] & 0x07; |
670 | buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO; | 671 | frame.audio.channel_allocation = p->audio_frame[4]; |
671 | buf[HB(1)] = 0x01; | 672 | frame.audio.level_shift_value = (p->audio_frame[5] & 0x78) >> 3; |
672 | buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE; | 673 | frame.audio.downmix_inhibit = (p->audio_frame[5] & 0x80) >> 7; |
673 | buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ | ||
674 | buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ | ||
675 | buf[PB(4)] = p->audio_frame[4]; | ||
676 | buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */ | ||
677 | 674 | ||
678 | buf[PB(0)] = tda998x_cksum(buf, sizeof(buf)); | 675 | /* |
676 | * L-PCM and IEC61937 compressed audio shall always set sample | ||
677 | * frequency to "refer to stream". For others, see the HDMI | ||
678 | * specification. | ||
679 | */ | ||
680 | frame.audio.sample_frequency = (p->audio_frame[2] & 0x1c) >> 2; | ||
679 | 681 | ||
680 | tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, | 682 | tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, &frame); |
681 | sizeof(buf)); | ||
682 | } | 683 | } |
683 | 684 | ||
684 | static void | 685 | static void |
685 | tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) | 686 | tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) |
686 | { | 687 | { |
687 | struct hdmi_avi_infoframe frame; | 688 | union hdmi_infoframe frame; |
688 | u8 buf[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; | ||
689 | ssize_t len; | ||
690 | |||
691 | drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | ||
692 | 689 | ||
693 | frame.quantization_range = HDMI_QUANTIZATION_RANGE_FULL; | 690 | drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode); |
694 | 691 | frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL; | |
695 | len = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf)); | ||
696 | if (len < 0) { | ||
697 | dev_err(&priv->hdmi->dev, | ||
698 | "hdmi_avi_infoframe_pack() failed: %zd\n", len); | ||
699 | return; | ||
700 | } | ||
701 | 692 | ||
702 | tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, len); | 693 | tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame); |
703 | } | 694 | } |
704 | 695 | ||
705 | static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) | 696 | static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) |