aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMythri P K <mythripk@ti.com>2011-09-08 09:36:24 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-09-30 09:16:33 -0400
commit7334167bf18e708e275164a3c44bb3f0c193d0c4 (patch)
treef39303181dc41c1437f008b2d222a548f1febe81 /drivers
parent7d983f39ecc463a4fb94bc1fd7204be46e35d5e0 (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.c257
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c260
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h22
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)
633static 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
652static 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
670static 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
748static 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
800static 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
857static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data, 635static 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
991static 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
1024static int hdmi_audio_startup(struct snd_pcm_substream *substream, 769static 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)
771void 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
790void 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
808void 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
886void 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
938int 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
995int 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
28struct hdmi_reg { u16 idx; }; 33struct 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)
583int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
584 struct snd_pcm_substream *substream, int cmd,
585 struct snd_soc_dai *dai);
586int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
587 u32 sample_freq, u32 *n, u32 *cts);
588void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
589 struct hdmi_core_infoframe_audio *info_aud);
590void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
591 struct hdmi_core_audio_config *cfg);
592void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data,
593 struct hdmi_audio_dma *aud_dma);
594void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data,
595 struct hdmi_audio_format *aud_fmt);
596#endif
575#endif 597#endif