aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2015-08-06 05:52:05 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2015-09-15 11:19:49 -0400
commit96795df15c89ce30261a31289740b4621bcec0fe (patch)
treea9ccba4cd540747ef5f033be23fbabf7dbd9bec3
parentec5d3e83d332ac5dfde8e0a1f57393fc91d55030 (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.c71
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
643static 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
655static void 643static void
656tda998x_write_if(struct tda998x_priv *priv, u8 bit, u16 addr, 644tda998x_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
664static void 663static void
665tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) 664tda998x_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
684static void 685static void
685tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) 686tda998x_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
705static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) 696static void tda998x_audio_mute(struct tda998x_priv *priv, bool on)