diff options
author | Mythri P K <mythripk@ti.com> | 2011-09-08 09:36:24 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-09-30 09:16:33 -0400 |
commit | 7334167bf18e708e275164a3c44bb3f0c193d0c4 (patch) | |
tree | f39303181dc41c1437f008b2d222a548f1febe81 /drivers | |
parent | 7d983f39ecc463a4fb94bc1fd7204be46e35d5e0 (diff) |
OMAP4: DSS2: HDMI: Move the HDMI IP dependent audio
Move HDMI IP dependent audio functions from HDMI DSS file to IP library.
Signed-off-by: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 257 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 260 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h | 22 |
3 files changed, 283 insertions, 256 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index b6d63c63c9fd..2a8a55d7c7dd 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -37,6 +37,7 @@ | |||
37 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | 37 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) |
38 | #include <sound/soc.h> | 38 | #include <sound/soc.h> |
39 | #include <sound/pcm_params.h> | 39 | #include <sound/pcm_params.h> |
40 | #include "ti_hdmi_4xxx_ip.h" | ||
40 | #endif | 41 | #endif |
41 | 42 | ||
42 | #include "ti_hdmi.h" | 43 | #include "ti_hdmi.h" |
@@ -630,229 +631,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) | |||
630 | 631 | ||
631 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 632 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ |
632 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | 633 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) |
633 | static void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, | ||
634 | struct hdmi_audio_format *aud_fmt) | ||
635 | { | ||
636 | u32 r; | ||
637 | |||
638 | DSSDBG("Enter hdmi_wp_audio_config_format\n"); | ||
639 | |||
640 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG); | ||
641 | r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); | ||
642 | r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); | ||
643 | r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); | ||
644 | r = FLD_MOD(r, aud_fmt->type, 4, 4); | ||
645 | r = FLD_MOD(r, aud_fmt->justification, 3, 3); | ||
646 | r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); | ||
647 | r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); | ||
648 | r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); | ||
649 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); | ||
650 | } | ||
651 | |||
652 | static void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, | ||
653 | struct hdmi_audio_dma *aud_dma) | ||
654 | { | ||
655 | u32 r; | ||
656 | |||
657 | DSSDBG("Enter hdmi_wp_audio_config_dma\n"); | ||
658 | |||
659 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2); | ||
660 | r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); | ||
661 | r = FLD_MOD(r, aud_dma->block_size, 7, 0); | ||
662 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2, r); | ||
663 | |||
664 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL); | ||
665 | r = FLD_MOD(r, aud_dma->mode, 9, 9); | ||
666 | r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); | ||
667 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); | ||
668 | } | ||
669 | |||
670 | static void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | ||
671 | struct hdmi_core_audio_config *cfg) | ||
672 | { | ||
673 | u32 r; | ||
674 | void __iomem *av_base = hdmi_av_base(ip_data); | ||
675 | |||
676 | /* audio clock recovery parameters */ | ||
677 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); | ||
678 | r = FLD_MOD(r, cfg->use_mclk, 2, 2); | ||
679 | r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1); | ||
680 | r = FLD_MOD(r, cfg->cts_mode, 0, 0); | ||
681 | hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r); | ||
682 | |||
683 | REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); | ||
684 | REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); | ||
685 | REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); | ||
686 | |||
687 | if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) { | ||
688 | REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0); | ||
689 | REG_FLD_MOD(av_base, | ||
690 | HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0); | ||
691 | REG_FLD_MOD(av_base, | ||
692 | HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); | ||
693 | } else { | ||
694 | /* | ||
695 | * HDMI IP uses this configuration to divide the MCLK to | ||
696 | * update CTS value. | ||
697 | */ | ||
698 | REG_FLD_MOD(av_base, | ||
699 | HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0); | ||
700 | |||
701 | /* Configure clock for audio packets */ | ||
702 | REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, | ||
703 | cfg->aud_par_busclk, 7, 0); | ||
704 | REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, | ||
705 | (cfg->aud_par_busclk >> 8), 7, 0); | ||
706 | REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3, | ||
707 | (cfg->aud_par_busclk >> 16), 7, 0); | ||
708 | } | ||
709 | |||
710 | /* Override of SPDIF sample frequency with value in I2S_CHST4 */ | ||
711 | REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, | ||
712 | cfg->fs_override, 1, 1); | ||
713 | |||
714 | /* I2S parameters */ | ||
715 | REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_CHST4, | ||
716 | cfg->freq_sample, 3, 0); | ||
717 | |||
718 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); | ||
719 | r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7); | ||
720 | r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); | ||
721 | r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5); | ||
722 | r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); | ||
723 | r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3); | ||
724 | r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); | ||
725 | r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); | ||
726 | r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); | ||
727 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); | ||
728 | |||
729 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_CHST5); | ||
730 | r = FLD_MOD(r, cfg->freq_sample, 7, 4); | ||
731 | r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1); | ||
732 | r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0); | ||
733 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, r); | ||
734 | |||
735 | REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, | ||
736 | cfg->i2s_cfg.in_length_bits, 3, 0); | ||
737 | |||
738 | /* Audio channels and mode parameters */ | ||
739 | REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1); | ||
740 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE); | ||
741 | r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4); | ||
742 | r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3); | ||
743 | r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); | ||
744 | r = FLD_MOD(r, cfg->en_spdif, 1, 1); | ||
745 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); | ||
746 | } | ||
747 | |||
748 | static void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | ||
749 | struct hdmi_core_infoframe_audio *info_aud) | ||
750 | { | ||
751 | u8 val; | ||
752 | u8 sum = 0, checksum = 0; | ||
753 | void __iomem *av_base = hdmi_av_base(ip_data); | ||
754 | |||
755 | /* | ||
756 | * Set audio info frame type, version and length as | ||
757 | * described in HDMI 1.4a Section 8.2.2 specification. | ||
758 | * Checksum calculation is defined in Section 5.3.5. | ||
759 | */ | ||
760 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84); | ||
761 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01); | ||
762 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); | ||
763 | sum += 0x84 + 0x001 + 0x00a; | ||
764 | |||
765 | val = (info_aud->db1_coding_type << 4) | ||
766 | | (info_aud->db1_channel_count - 1); | ||
767 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), val); | ||
768 | sum += val; | ||
769 | |||
770 | val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size; | ||
771 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), val); | ||
772 | sum += val; | ||
773 | |||
774 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), 0x00); | ||
775 | |||
776 | val = info_aud->db4_channel_alloc; | ||
777 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), val); | ||
778 | sum += val; | ||
779 | |||
780 | val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3); | ||
781 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), val); | ||
782 | sum += val; | ||
783 | |||
784 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); | ||
785 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); | ||
786 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00); | ||
787 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00); | ||
788 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00); | ||
789 | |||
790 | checksum = 0x100 - sum; | ||
791 | hdmi_write_reg(av_base, | ||
792 | HDMI_CORE_AV_AUDIO_CHSUM, checksum); | ||
793 | |||
794 | /* | ||
795 | * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing | ||
796 | * is available. | ||
797 | */ | ||
798 | } | ||
799 | |||
800 | static int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, | ||
801 | u32 sample_freq, u32 *n, u32 *cts) | ||
802 | { | ||
803 | u32 r; | ||
804 | u32 deep_color = 0; | ||
805 | u32 pclk = hdmi.cfg.timings.timings.pixel_clock; | ||
806 | |||
807 | if (n == NULL || cts == NULL) | ||
808 | return -EINVAL; | ||
809 | /* | ||
810 | * Obtain current deep color configuration. This needed | ||
811 | * to calculate the TMDS clock based on the pixel clock. | ||
812 | */ | ||
813 | r = REG_GET(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, 1, 0); | ||
814 | switch (r) { | ||
815 | case 1: /* No deep color selected */ | ||
816 | deep_color = 100; | ||
817 | break; | ||
818 | case 2: /* 10-bit deep color selected */ | ||
819 | deep_color = 125; | ||
820 | break; | ||
821 | case 3: /* 12-bit deep color selected */ | ||
822 | deep_color = 150; | ||
823 | break; | ||
824 | default: | ||
825 | return -EINVAL; | ||
826 | } | ||
827 | |||
828 | switch (sample_freq) { | ||
829 | case 32000: | ||
830 | if ((deep_color == 125) && ((pclk == 54054) | ||
831 | || (pclk == 74250))) | ||
832 | *n = 8192; | ||
833 | else | ||
834 | *n = 4096; | ||
835 | break; | ||
836 | case 44100: | ||
837 | *n = 6272; | ||
838 | break; | ||
839 | case 48000: | ||
840 | if ((deep_color == 125) && ((pclk == 54054) | ||
841 | || (pclk == 74250))) | ||
842 | *n = 8192; | ||
843 | else | ||
844 | *n = 6144; | ||
845 | break; | ||
846 | default: | ||
847 | *n = 0; | ||
848 | return -EINVAL; | ||
849 | } | ||
850 | |||
851 | /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ | ||
852 | *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); | ||
853 | |||
854 | return 0; | ||
855 | } | ||
856 | 634 | ||
857 | static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data, | 635 | static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data, |
858 | struct snd_pcm_substream *substream, | 636 | struct snd_pcm_substream *substream, |
@@ -988,39 +766,6 @@ static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data, | |||
988 | return 0; | 766 | return 0; |
989 | } | 767 | } |
990 | 768 | ||
991 | static int hdmi_audio_trigger(struct hdmi_ip_data *ip_data, | ||
992 | struct snd_pcm_substream *substream, int cmd, | ||
993 | struct snd_soc_dai *dai) | ||
994 | { | ||
995 | int err = 0; | ||
996 | switch (cmd) { | ||
997 | case SNDRV_PCM_TRIGGER_START: | ||
998 | case SNDRV_PCM_TRIGGER_RESUME: | ||
999 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
1000 | REG_FLD_MOD(hdmi_av_base(ip_data), | ||
1001 | HDMI_CORE_AV_AUD_MODE, 1, 0, 0); | ||
1002 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1003 | HDMI_WP_AUDIO_CTRL, 1, 31, 31); | ||
1004 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1005 | HDMI_WP_AUDIO_CTRL, 1, 30, 30); | ||
1006 | break; | ||
1007 | |||
1008 | case SNDRV_PCM_TRIGGER_STOP: | ||
1009 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
1010 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
1011 | REG_FLD_MOD(hdmi_av_base(ip_data), | ||
1012 | HDMI_CORE_AV_AUD_MODE, 0, 0, 0); | ||
1013 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1014 | HDMI_WP_AUDIO_CTRL, 0, 30, 30); | ||
1015 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1016 | HDMI_WP_AUDIO_CTRL, 0, 31, 31); | ||
1017 | break; | ||
1018 | default: | ||
1019 | err = -EINVAL; | ||
1020 | } | ||
1021 | return err; | ||
1022 | } | ||
1023 | |||
1024 | static int hdmi_audio_startup(struct snd_pcm_substream *substream, | 769 | static int hdmi_audio_startup(struct snd_pcm_substream *substream, |
1025 | struct snd_soc_dai *dai) | 770 | struct snd_soc_dai *dai) |
1026 | { | 771 | { |
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index b97a3c029584..c2a98f830b84 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | |||
@@ -765,3 +765,263 @@ void hdmi_basic_configure(struct hdmi_ip_data *ip_data) | |||
765 | repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; | 765 | repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; |
766 | hdmi_core_av_packet_config(ip_data, repeat_cfg); | 766 | hdmi_core_av_packet_config(ip_data, repeat_cfg); |
767 | } | 767 | } |
768 | |||
769 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | ||
770 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
771 | void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, | ||
772 | struct hdmi_audio_format *aud_fmt) | ||
773 | { | ||
774 | u32 r; | ||
775 | |||
776 | DSSDBG("Enter hdmi_wp_audio_config_format\n"); | ||
777 | |||
778 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG); | ||
779 | r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); | ||
780 | r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); | ||
781 | r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); | ||
782 | r = FLD_MOD(r, aud_fmt->type, 4, 4); | ||
783 | r = FLD_MOD(r, aud_fmt->justification, 3, 3); | ||
784 | r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); | ||
785 | r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); | ||
786 | r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); | ||
787 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); | ||
788 | } | ||
789 | |||
790 | void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, | ||
791 | struct hdmi_audio_dma *aud_dma) | ||
792 | { | ||
793 | u32 r; | ||
794 | |||
795 | DSSDBG("Enter hdmi_wp_audio_config_dma\n"); | ||
796 | |||
797 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2); | ||
798 | r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); | ||
799 | r = FLD_MOD(r, aud_dma->block_size, 7, 0); | ||
800 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2, r); | ||
801 | |||
802 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL); | ||
803 | r = FLD_MOD(r, aud_dma->mode, 9, 9); | ||
804 | r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); | ||
805 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); | ||
806 | } | ||
807 | |||
808 | void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | ||
809 | struct hdmi_core_audio_config *cfg) | ||
810 | { | ||
811 | u32 r; | ||
812 | void __iomem *av_base = hdmi_av_base(ip_data); | ||
813 | |||
814 | /* audio clock recovery parameters */ | ||
815 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); | ||
816 | r = FLD_MOD(r, cfg->use_mclk, 2, 2); | ||
817 | r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1); | ||
818 | r = FLD_MOD(r, cfg->cts_mode, 0, 0); | ||
819 | hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r); | ||
820 | |||
821 | REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); | ||
822 | REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); | ||
823 | REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); | ||
824 | |||
825 | if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) { | ||
826 | REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0); | ||
827 | REG_FLD_MOD(av_base, | ||
828 | HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0); | ||
829 | REG_FLD_MOD(av_base, | ||
830 | HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); | ||
831 | } else { | ||
832 | /* | ||
833 | * HDMI IP uses this configuration to divide the MCLK to | ||
834 | * update CTS value. | ||
835 | */ | ||
836 | REG_FLD_MOD(av_base, | ||
837 | HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0); | ||
838 | |||
839 | /* Configure clock for audio packets */ | ||
840 | REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, | ||
841 | cfg->aud_par_busclk, 7, 0); | ||
842 | REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, | ||
843 | (cfg->aud_par_busclk >> 8), 7, 0); | ||
844 | REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3, | ||
845 | (cfg->aud_par_busclk >> 16), 7, 0); | ||
846 | } | ||
847 | |||
848 | /* Override of SPDIF sample frequency with value in I2S_CHST4 */ | ||
849 | REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, | ||
850 | cfg->fs_override, 1, 1); | ||
851 | |||
852 | /* I2S parameters */ | ||
853 | REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_CHST4, | ||
854 | cfg->freq_sample, 3, 0); | ||
855 | |||
856 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); | ||
857 | r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7); | ||
858 | r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); | ||
859 | r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5); | ||
860 | r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); | ||
861 | r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3); | ||
862 | r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); | ||
863 | r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); | ||
864 | r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); | ||
865 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); | ||
866 | |||
867 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_CHST5); | ||
868 | r = FLD_MOD(r, cfg->freq_sample, 7, 4); | ||
869 | r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1); | ||
870 | r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0); | ||
871 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, r); | ||
872 | |||
873 | REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, | ||
874 | cfg->i2s_cfg.in_length_bits, 3, 0); | ||
875 | |||
876 | /* Audio channels and mode parameters */ | ||
877 | REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1); | ||
878 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE); | ||
879 | r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4); | ||
880 | r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3); | ||
881 | r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); | ||
882 | r = FLD_MOD(r, cfg->en_spdif, 1, 1); | ||
883 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); | ||
884 | } | ||
885 | |||
886 | void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | ||
887 | struct hdmi_core_infoframe_audio *info_aud) | ||
888 | { | ||
889 | u8 val; | ||
890 | u8 sum = 0, checksum = 0; | ||
891 | void __iomem *av_base = hdmi_av_base(ip_data); | ||
892 | |||
893 | /* | ||
894 | * Set audio info frame type, version and length as | ||
895 | * described in HDMI 1.4a Section 8.2.2 specification. | ||
896 | * Checksum calculation is defined in Section 5.3.5. | ||
897 | */ | ||
898 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84); | ||
899 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01); | ||
900 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); | ||
901 | sum += 0x84 + 0x001 + 0x00a; | ||
902 | |||
903 | val = (info_aud->db1_coding_type << 4) | ||
904 | | (info_aud->db1_channel_count - 1); | ||
905 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), val); | ||
906 | sum += val; | ||
907 | |||
908 | val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size; | ||
909 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), val); | ||
910 | sum += val; | ||
911 | |||
912 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), 0x00); | ||
913 | |||
914 | val = info_aud->db4_channel_alloc; | ||
915 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), val); | ||
916 | sum += val; | ||
917 | |||
918 | val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3); | ||
919 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), val); | ||
920 | sum += val; | ||
921 | |||
922 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); | ||
923 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); | ||
924 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00); | ||
925 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00); | ||
926 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00); | ||
927 | |||
928 | checksum = 0x100 - sum; | ||
929 | hdmi_write_reg(av_base, | ||
930 | HDMI_CORE_AV_AUDIO_CHSUM, checksum); | ||
931 | |||
932 | /* | ||
933 | * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing | ||
934 | * is available. | ||
935 | */ | ||
936 | } | ||
937 | |||
938 | int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, | ||
939 | u32 sample_freq, u32 *n, u32 *cts) | ||
940 | { | ||
941 | u32 r; | ||
942 | u32 deep_color = 0; | ||
943 | u32 pclk = ip_data->cfg.timings.timings.pixel_clock; | ||
944 | |||
945 | if (n == NULL || cts == NULL) | ||
946 | return -EINVAL; | ||
947 | /* | ||
948 | * Obtain current deep color configuration. This needed | ||
949 | * to calculate the TMDS clock based on the pixel clock. | ||
950 | */ | ||
951 | r = REG_GET(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, 1, 0); | ||
952 | switch (r) { | ||
953 | case 1: /* No deep color selected */ | ||
954 | deep_color = 100; | ||
955 | break; | ||
956 | case 2: /* 10-bit deep color selected */ | ||
957 | deep_color = 125; | ||
958 | break; | ||
959 | case 3: /* 12-bit deep color selected */ | ||
960 | deep_color = 150; | ||
961 | break; | ||
962 | default: | ||
963 | return -EINVAL; | ||
964 | } | ||
965 | |||
966 | switch (sample_freq) { | ||
967 | case 32000: | ||
968 | if ((deep_color == 125) && ((pclk == 54054) | ||
969 | || (pclk == 74250))) | ||
970 | *n = 8192; | ||
971 | else | ||
972 | *n = 4096; | ||
973 | break; | ||
974 | case 44100: | ||
975 | *n = 6272; | ||
976 | break; | ||
977 | case 48000: | ||
978 | if ((deep_color == 125) && ((pclk == 54054) | ||
979 | || (pclk == 74250))) | ||
980 | *n = 8192; | ||
981 | else | ||
982 | *n = 6144; | ||
983 | break; | ||
984 | default: | ||
985 | *n = 0; | ||
986 | return -EINVAL; | ||
987 | } | ||
988 | |||
989 | /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ | ||
990 | *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); | ||
991 | |||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | int hdmi_audio_trigger(struct hdmi_ip_data *ip_data, | ||
996 | struct snd_pcm_substream *substream, int cmd, | ||
997 | struct snd_soc_dai *dai) | ||
998 | { | ||
999 | int err = 0; | ||
1000 | switch (cmd) { | ||
1001 | case SNDRV_PCM_TRIGGER_START: | ||
1002 | case SNDRV_PCM_TRIGGER_RESUME: | ||
1003 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
1004 | REG_FLD_MOD(hdmi_av_base(ip_data), | ||
1005 | HDMI_CORE_AV_AUD_MODE, 1, 0, 0); | ||
1006 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1007 | HDMI_WP_AUDIO_CTRL, 1, 31, 31); | ||
1008 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1009 | HDMI_WP_AUDIO_CTRL, 1, 30, 30); | ||
1010 | break; | ||
1011 | |||
1012 | case SNDRV_PCM_TRIGGER_STOP: | ||
1013 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
1014 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
1015 | REG_FLD_MOD(hdmi_av_base(ip_data), | ||
1016 | HDMI_CORE_AV_AUD_MODE, 0, 0, 0); | ||
1017 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1018 | HDMI_WP_AUDIO_CTRL, 0, 30, 30); | ||
1019 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1020 | HDMI_WP_AUDIO_CTRL, 0, 31, 31); | ||
1021 | break; | ||
1022 | default: | ||
1023 | err = -EINVAL; | ||
1024 | } | ||
1025 | return err; | ||
1026 | } | ||
1027 | #endif | ||
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h index 7feead1d50d2..929de885f3f9 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h | |||
@@ -24,6 +24,11 @@ | |||
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <video/omapdss.h> | 25 | #include <video/omapdss.h> |
26 | #include "ti_hdmi.h" | 26 | #include "ti_hdmi.h" |
27 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | ||
28 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
29 | #include <sound/soc.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #endif | ||
27 | 32 | ||
28 | struct hdmi_reg { u16 idx; }; | 33 | struct hdmi_reg { u16 idx; }; |
29 | 34 | ||
@@ -572,4 +577,21 @@ struct hdmi_core_audio_config { | |||
572 | bool en_parallel_aud_input; | 577 | bool en_parallel_aud_input; |
573 | bool en_spdif; | 578 | bool en_spdif; |
574 | }; | 579 | }; |
580 | |||
581 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | ||
582 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
583 | int hdmi_audio_trigger(struct hdmi_ip_data *ip_data, | ||
584 | struct snd_pcm_substream *substream, int cmd, | ||
585 | struct snd_soc_dai *dai); | ||
586 | int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, | ||
587 | u32 sample_freq, u32 *n, u32 *cts); | ||
588 | void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | ||
589 | struct hdmi_core_infoframe_audio *info_aud); | ||
590 | void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | ||
591 | struct hdmi_core_audio_config *cfg); | ||
592 | void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, | ||
593 | struct hdmi_audio_dma *aud_dma); | ||
594 | void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, | ||
595 | struct hdmi_audio_format *aud_fmt); | ||
596 | #endif | ||
575 | #endif | 597 | #endif |