@@ -149,6 +149,7 @@ static inline int ssp_set_config(struct dai *dai,
149149 uint32_t sample_width = 2 ;
150150
151151 bool inverted_frame = false;
152+ bool cfs = false;
152153 int ret = 0 ;
153154
154155 spin_lock (& ssp -> lock );
@@ -215,10 +216,13 @@ static inline int ssp_set_config(struct dai *dai,
215216 break ;
216217 case SOF_DAI_FMT_CBS_CFS :
217218 sscr1 |= SSCR1_SCFR ;
219+ cfs = true;
218220 break ;
219221 case SOF_DAI_FMT_CBM_CFS :
220222 sscr1 |= SSCR1_SCLKDIR ;
221223 /* FIXME: this mode has not been tested */
224+
225+ cfs = true;
222226 break ;
223227 case SOF_DAI_FMT_CBS_CFM :
224228 sscr1 |= SSCR1_SCFR | SSCR1_SFRMDIR ;
@@ -252,7 +256,43 @@ static inline int ssp_set_config(struct dai *dai,
252256
253257 sscr0 |= SSCR0_MOD | SSCR0_ACS ;
254258
255- mdivc = 0x1 ;
259+ mdivc = mn_reg_read (0x0 );
260+ mdivc |= 0x1 ;
261+
262+ /* Additional hardware settings */
263+
264+ /* Receiver Time-out Interrupt Disabled/Enabled */
265+ sscr1 |= (ssp -> params .quirks & SOF_DAI_INTEL_SSP_QUIRK_TINTE ) ?
266+ SSCR1_TINTE : 0 ;
267+
268+ /* Peripheral Trailing Byte Interrupts Disable/Enable */
269+ sscr1 |= (ssp -> params .quirks & SOF_DAI_INTEL_SSP_QUIRK_PINTE ) ?
270+ SSCR1_PINTE : 0 ;
271+
272+ /* Transmit data are driven at the same/opposite clock edge specified
273+ * in SSPSP.SCMODE[1:0]
274+ */
275+ sscr2 |= (ssp -> params .quirks & SOF_DAI_INTEL_SSP_QUIRK_SMTATF ) ?
276+ SSCR2_SMTATF : 0 ;
277+
278+ /* Receive data are sampled at the same/opposite clock edge specified
279+ * in SSPSP.SCMODE[1:0]
280+ */
281+ sscr2 |= (ssp -> params .quirks & SOF_DAI_INTEL_SSP_QUIRK_MMRATF ) ?
282+ SSCR2_MMRATF : 0 ;
283+
284+ /* Enable/disable the fix for PSP slave mode TXD wait for frame
285+ * de-assertion before starting the second channel
286+ */
287+ sscr2 |= (ssp -> params .quirks & SOF_DAI_INTEL_SSP_QUIRK_PSPSTWFDFD ) ?
288+ SSCR2_PSPSTWFDFD : 0 ;
289+
290+ /* Enable/disable the fix for PSP master mode FSRT with dummy stop &
291+ * frame end padding capability
292+ */
293+ sscr2 |= (ssp -> params .quirks & SOF_DAI_INTEL_SSP_QUIRK_PSPSRWFDFD ) ?
294+ SSCR2_PSPSRWFDFD : 0 ;
295+
256296#ifdef CONFIG_CANNONLAKE
257297 if (!config -> ssp .mclk_rate || config -> ssp .mclk_rate > F_24000_kHz ) {
258298 trace_ssp_error ("eci" );
@@ -501,7 +541,21 @@ static inline int ssp_set_config(struct dai *dai,
501541 sscr0 |= SSCR0_MOD | SSCR0_FRDC (config -> ssp .tdm_slots );
502542
503543 /* set asserted frame length */
504- frame_len = 1 ;
544+ frame_len = 1 ; /* default */
545+
546+ if (cfs && ssp -> params .frame_pulse_width > 0 &&
547+ ssp -> params .frame_pulse_width <=
548+ SOF_DAI_INTEL_SSP_FRAME_PULSE_WIDTH_MAX ) {
549+ frame_len = ssp -> params .frame_pulse_width ;
550+ }
551+
552+ /* frame_pulse_width must less or equal 38 */
553+ if (ssp -> params .frame_pulse_width >
554+ SOF_DAI_INTEL_SSP_FRAME_PULSE_WIDTH_MAX ) {
555+ trace_ssp_error ("efa" );
556+ ret = - EINVAL ;
557+ goto out ;
558+ }
505559
506560 /*
507561 * handle frame polarity, DSP_A default is rising/active high,
@@ -525,8 +579,21 @@ static inline int ssp_set_config(struct dai *dai,
525579 sscr0 |= SSCR0_MOD | SSCR0_FRDC (config -> ssp .tdm_slots );
526580
527581 /* set asserted frame length */
528- frame_len = 1 ;
582+ frame_len = 1 ; /* default */
583+
584+ if (cfs && ssp -> params .frame_pulse_width > 0 &&
585+ ssp -> params .frame_pulse_width <=
586+ SOF_DAI_INTEL_SSP_FRAME_PULSE_WIDTH_MAX ) {
587+ frame_len = ssp -> params .frame_pulse_width ;
588+ }
529589
590+ /* frame_pulse_width must less or equal 38 */
591+ if (ssp -> params .frame_pulse_width >
592+ SOF_DAI_INTEL_SSP_FRAME_PULSE_WIDTH_MAX ) {
593+ trace_ssp_error ("efb" );
594+ ret = - EINVAL ;
595+ goto out ;
596+ }
530597 /*
531598 * handle frame polarity, DSP_B default is rising/active high,
532599 * non-inverted(inverted_frame=0) -- active high(SFRMP=1),
0 commit comments