@@ -30,6 +30,14 @@ static inline u8 hdmi_read(struct dw_hdmi_i2s_audio_data *audio, int offset)
3030 return audio -> read (hdmi , offset );
3131}
3232
33+ static inline void hdmi_update_bits (struct dw_hdmi_i2s_audio_data * audio ,
34+ u8 data , u8 mask , unsigned int reg )
35+ {
36+ struct dw_hdmi * hdmi = audio -> hdmi ;
37+
38+ audio -> mod (hdmi , data , mask , reg );
39+ }
40+
3341static int dw_hdmi_i2s_hw_params (struct device * dev , void * data ,
3442 struct hdmi_codec_daifmt * fmt ,
3543 struct hdmi_codec_params * hparms )
@@ -39,6 +47,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
3947 u8 conf0 = 0 ;
4048 u8 conf1 = 0 ;
4149 u8 inputclkfs = 0 ;
50+ u8 val ;
4251
4352 /* it cares I2S only */
4453 if ((fmt -> fmt != HDMI_I2S ) ||
@@ -47,7 +56,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
4756 return - EINVAL ;
4857 }
4958
50- inputclkfs = HDMI_AUD_INPUTCLKFS_64FS ;
59+ inputclkfs = HDMI_AUD_INPUTCLKFS_128FS ;
5160
5261 switch (hparms -> sample_width ) {
5362 case 16 :
@@ -80,19 +89,112 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
8089 return - EINVAL ;
8190 }
8291
83- dw_hdmi_set_sample_rate (hdmi , hparms -> sample_rate );
84-
85- hdmi_write (audio , inputclkfs , HDMI_AUD_INPUTCLKFS );
86- hdmi_write (audio , conf0 , HDMI_AUD_CONF0 );
87- hdmi_write (audio , conf1 , HDMI_AUD_CONF1 );
8892 /*
8993 * dw-hdmi introduced insert_pcuv bit in version 2.10a.
9094 * When set (1'b1), this bit enables the insertion of the PCUV
9195 * (Parity, Channel Status, User bit and Validity) bits on the
9296 * incoming audio stream (support limited to Linear PCM audio)
9397 */
94- if (hdmi_read (audio , HDMI_DESIGN_ID ) > 0x21 )
95- hdmi_write (audio , HDMI_AUD_CONF2_INSERT_PCUV , HDMI_AUD_CONF2 );
98+ val = 0 ;
99+ if (hdmi_read (audio , HDMI_DESIGN_ID ) >= 0x21 )
100+ val = HDMI_AUD_CONF2_INSERT_PCUV ;
101+
102+ /*Mask fifo empty and full int and reset fifo*/
103+ hdmi_update_bits (audio ,
104+ HDMI_AUD_INT_FIFO_EMPTY_MSK |
105+ HDMI_AUD_INT_FIFO_FULL_MSK ,
106+ HDMI_AUD_INT_FIFO_EMPTY_MSK |
107+ HDMI_AUD_INT_FIFO_FULL_MSK , HDMI_AUD_INT );
108+ hdmi_update_bits (audio , HDMI_AUD_CONF0_SW_RESET ,
109+ HDMI_AUD_CONF0_SW_RESET , HDMI_AUD_CONF0 );
110+ hdmi_update_bits (audio , HDMI_MC_SWRSTZ_I2S_RESET_MSK ,
111+ HDMI_MC_SWRSTZ_I2S_RESET_MSK , HDMI_MC_SWRSTZ );
112+
113+ switch (hparms -> mode ) {
114+ case NLPCM :
115+ hdmi_write (audio , HDMI_AUD_CONF2_NLPCM , HDMI_AUD_CONF2 );
116+ conf1 = HDMI_AUD_CONF1_WIDTH_21 ;
117+ break ;
118+ case HBR :
119+ hdmi_write (audio , HDMI_AUD_CONF2_HBR , HDMI_AUD_CONF2 );
120+ conf1 = HDMI_AUD_CONF1_WIDTH_21 ;
121+ break ;
122+ default :
123+ hdmi_write (audio , val , HDMI_AUD_CONF2 );
124+ break ;
125+ }
126+
127+ dw_hdmi_set_sample_rate (hdmi , hparms -> sample_rate );
128+
129+ hdmi_write (audio , inputclkfs , HDMI_AUD_INPUTCLKFS );
130+ hdmi_write (audio , conf0 , HDMI_AUD_CONF0 );
131+ hdmi_write (audio , conf1 , HDMI_AUD_CONF1 );
132+
133+ val = HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 ;
134+ if (hparms -> channels > 2 )
135+ val = HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 ;
136+ hdmi_update_bits (audio , val , HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK ,
137+ HDMI_FC_AUDSCONF );
138+
139+ switch (hparms -> sample_rate ) {
140+ case 32000 :
141+ val = HDMI_FC_AUDSCHNLS_32K ;
142+ break ;
143+ case 44100 :
144+ val = HDMI_FC_AUDSCHNLS_441K ;
145+ break ;
146+ case 48000 :
147+ val = HDMI_FC_AUDSCHNLS_48K ;
148+ break ;
149+ case 88200 :
150+ val = HDMI_FC_AUDSCHNLS_882K ;
151+ break ;
152+ case 96000 :
153+ val = HDMI_FC_AUDSCHNLS_96K ;
154+ break ;
155+ case 176400 :
156+ val = HDMI_FC_AUDSCHNLS_1764K ;
157+ break ;
158+ case 192000 :
159+ val = HDMI_FC_AUDSCHNLS_192K ;
160+ break ;
161+ default :
162+ val = HDMI_FC_AUDSCHNLS_441K ;
163+ break ;
164+ }
165+
166+ /* set channel status register */
167+ hdmi_update_bits (audio , val ,
168+ HDMI_FC_AUDSCHNLS7_SAMPFREQ_MASK ,
169+ HDMI_FC_AUDSCHNLS7 );
170+ hdmi_write (audio ,
171+ ((~val ) << HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET ),
172+ HDMI_FC_AUDSCHNLS8 );
173+
174+ /* Refer to CEA861-E Audio infoFrame
175+ * Set both Audio Channel Count and Audio Coding
176+ * Type Refer to Stream Head for HDMI
177+ */
178+ hdmi_update_bits (audio ,
179+ (hparms -> channels - 1 ) << HDMI_FC_AUDICONF0_CC_OFFSET ,
180+ HDMI_FC_AUDICONF0_CC_MASK , HDMI_FC_AUDICONF0 );
181+
182+ /* Set both Audio Sample Size and Sample Frequency
183+ * Refer to Stream Head for HDMI
184+ */
185+ hdmi_write (audio , 0x00 , HDMI_FC_AUDICONF1 );
186+
187+ /* Set Channel Allocation */
188+ hdmi_write (audio , 0x00 , HDMI_FC_AUDICONF2 );
189+
190+ /* Set LFEPBLDOWN-MIX INH and LSV */
191+ hdmi_write (audio , 0x00 , HDMI_FC_AUDICONF3 );
192+
193+ hdmi_update_bits (audio , HDMI_AUD_CONF0_SW_RESET ,
194+ HDMI_AUD_CONF0_SW_RESET , HDMI_AUD_CONF0 );
195+ hdmi_update_bits (audio , HDMI_MC_SWRSTZ_I2S_RESET_MSK ,
196+ HDMI_MC_SWRSTZ_I2S_RESET_MSK , HDMI_MC_SWRSTZ );
197+
96198 dw_hdmi_audio_enable (hdmi );
97199
98200 return 0 ;
0 commit comments