4545#define trace_ssp_error (__e , ...) trace_error(TRACE_CLASS_SSP, __e, ##__VA_ARGS__)
4646#define tracev_ssp (__e , ...) tracev_event(TRACE_CLASS_SSP, __e, ##__VA_ARGS__)
4747
48- #define F_19200_kHz 19200000
49- #define F_24000_kHz 24000000
50- #define F_24576_kHz 24576000
51- #define F_38400_kHz 38400000
52-
5348/* FIXME: move this to a helper and optimize */
5449static int hweight_32 (uint32_t mask )
5550{
@@ -168,6 +163,9 @@ static inline int ssp_set_config(struct dai *dai,
168163 bool inverted_frame = false;
169164 bool cfs = false;
170165 bool start_delay = false;
166+
167+ int i ;
168+ int clk_index = -1 ;
171169 int ret = 0 ;
172170
173171 spin_lock (& dai -> lock );
@@ -328,14 +326,16 @@ static inline int ssp_set_config(struct dai *dai,
328326 sscr2 |= (ssp -> params .quirks & SOF_DAI_INTEL_SSP_QUIRK_PSPSRWFDFD ) ?
329327 SSCR2_PSPSRWFDFD : 0 ;
330328
331- # if defined( CONFIG_ICELAKE )
332- if (! config -> ssp . mclk_rate || config -> ssp .mclk_rate > F_38400_kHz ) {
329+ if (! config -> ssp . mclk_rate ||
330+ config -> ssp .mclk_rate > ssp_freq [ MAX_SSP_FREQ_INDEX ]. freq ) {
333331 trace_ssp_error ("ssp_set_config() error: "
334- "invalid MCLK = %d Hz (valid < 38400kHz)" ,
335- config -> ssp .mclk_rate );
332+ "invalid MCLK = %d Hz (valid < %d)" ,
333+ config -> ssp .mclk_rate ,
334+ ssp_freq [MAX_SSP_FREQ_INDEX ].freq );
336335 ret = - EINVAL ;
337336 goto out ;
338337 }
338+
339339 if (!config -> ssp .bclk_rate ||
340340 config -> ssp .bclk_rate > config -> ssp .mclk_rate ) {
341341 trace_ssp_error ("ssp_set_config() error: "
@@ -345,102 +345,53 @@ static inline int ssp_set_config(struct dai *dai,
345345 goto out ;
346346 }
347347
348- if (F_38400_kHz % config -> ssp .mclk_rate == 0 ) {
349- mdivr_val = F_38400_kHz / config -> ssp .mclk_rate ;
350- } else {
351- trace_ssp_error ("ssp_set_config() error: 38.4MHz / %d Hz MCLK not divisable" ,
352- config -> ssp .mclk_rate );
353- ret = - EINVAL ;
354- goto out ;
355- }
348+ /* MCLK config */
349+ /* searching the smallest possible mclk source */
350+ for (i = MAX_SSP_FREQ_INDEX ; i >= 0 ; i -- ) {
351+ if (config -> ssp .mclk_rate > ssp_freq [i ].freq )
352+ break ;
356353
357- if (F_38400_kHz % config -> ssp .bclk_rate == 0 ) {
358- mdiv = F_38400_kHz / config -> ssp .bclk_rate ;
359- } else {
360- trace_ssp_error ("ssp_set_config() error: 38.4MHz / %d Hz BCLK not divisable" ,
361- config -> ssp .bclk_rate );
362- ret = - EINVAL ;
363- goto out ;
364- }
365- #elif defined(CONFIG_CANNONLAKE )
366- if (!config -> ssp .mclk_rate || config -> ssp .mclk_rate > F_24000_kHz ) {
367- trace_ssp_error ("ssp_set_config() error: "
368- "invalid MCLK = %d Hz (valid < 24000kHz)" ,
369- config -> ssp .mclk_rate );
370- ret = - EINVAL ;
371- goto out ;
372- }
373- if (!config -> ssp .bclk_rate ||
374- config -> ssp .bclk_rate > config -> ssp .mclk_rate ) {
375- trace_ssp_error ("ssp_set_config() error: "
376- "BCLK %d Hz = 0 or > MCLK %d Hz" ,
377- config -> ssp .bclk_rate , config -> ssp .mclk_rate );
378- ret = - EINVAL ;
379- goto out ;
354+ if (ssp_freq [i ].freq % config -> ssp .mclk_rate == 0 )
355+ clk_index = i ;
380356 }
381357
382- if (F_24000_kHz % config -> ssp .mclk_rate == 0 ) {
383- mdivr_val = F_24000_kHz / config -> ssp .mclk_rate ;
358+ if (clk_index >= 0 ) {
359+ mdivc |= MCDSS (ssp_freq [clk_index ].enc );
360+ mdivr_val = ssp_freq [clk_index ].freq / config -> ssp .mclk_rate ;
384361 } else {
385- trace_ssp_error ("ssp_set_config() error: 24.0MHz / %d Hz MCLK not divisable " ,
362+ trace_ssp_error ("ssp_set_config() error: MCLK %d " ,
386363 config -> ssp .mclk_rate );
387364 ret = - EINVAL ;
388365 goto out ;
389366 }
390367
391- if (F_24000_kHz % config -> ssp .bclk_rate == 0 ) {
392- mdiv = F_24000_kHz / config -> ssp .bclk_rate ;
393- } else {
394- trace_ssp_error ("ssp_set_config() error: 24.0MHz / %d Hz BCLK not divisable" ,
395- config -> ssp .bclk_rate );
396- ret = - EINVAL ;
397- goto out ;
398- }
399- #else
400- if (!config -> ssp .mclk_rate || config -> ssp .mclk_rate > F_24576_kHz ) {
401- trace_ssp_error ("ssp_set_config() error: "
402- "invalid MCLK = %d Hz (valid < 24567kHz)" ,
403- config -> ssp .mclk_rate );
404- ret = - EINVAL ;
405- goto out ;
406- }
407- if (!config -> ssp .bclk_rate ||
408- config -> ssp .bclk_rate > config -> ssp .mclk_rate ) {
409- trace_ssp_error ("ssp_set_config() error: "
410- "BCLK %d Hz = 0 or > MCLK %d Hz" ,
411- config -> ssp .bclk_rate , config -> ssp .mclk_rate );
412- ret = - EINVAL ;
413- goto out ;
414- }
415- if (F_24576_kHz % config -> ssp .mclk_rate == 0 ) {
416- /* select Audio Cardinal clock for MCLK */
417- mdivc |= MCDSS (1 );
418- mdivr_val = F_24576_kHz / config -> ssp .mclk_rate ;
419- } else if (config -> ssp .mclk_rate <= F_19200_kHz &&
420- F_19200_kHz % config -> ssp .mclk_rate == 0 ) {
421- mdivr_val = F_19200_kHz / config -> ssp .mclk_rate ;
422- } else {
423- trace_ssp_error ("ssp_set_config() error: MCLK %d" ,
424- config -> ssp .mclk_rate );
425- ret = - EINVAL ;
426- goto out ;
368+ /* BCLK config */
369+ /* searching the smallest possible bclk source */
370+ clk_index = -1 ;
371+ for (i = MAX_SSP_FREQ_INDEX ; i >= 0 ; i -- ) {
372+ if (config -> ssp .bclk_rate > ssp_freq [i ].freq )
373+ break ;
374+
375+ if (ssp_freq [i ].freq % config -> ssp .bclk_rate == 0 )
376+ clk_index = i ;
427377 }
428378
429- if (F_24576_kHz % config -> ssp .bclk_rate == 0 ) {
430- /* select Audio Cardinal clock for M/N dividers */
431- mdivc |= MNDSS (1 );
432- mdiv = F_24576_kHz / config -> ssp .bclk_rate ;
433- /* select M/N output for bclk */
434- sscr0 |= SSCR0_ECS ;
435- } else if (F_19200_kHz % config -> ssp .bclk_rate == 0 ) {
436- mdiv = F_19200_kHz / config -> ssp .bclk_rate ;
379+ if (clk_index >= 0 ) {
380+ mdivc |= MNDSS (ssp_freq [clk_index ].enc );
381+ mdiv = ssp_freq [clk_index ].freq / config -> ssp .bclk_rate ;
382+
383+ /* select M/N output for bclk in case of Audio Cardinal
384+ * or PLL Fixed clock.
385+ */
386+ if (ssp_freq [clk_index ].enc != CLOCK_SSP_XTAL_OSCILLATOR )
387+ sscr0 |= SSCR0_ECS ;
437388 } else {
438389 trace_ssp_error ("ssp_set_config() error: BCLK %d" ,
439390 config -> ssp .bclk_rate );
440391 ret = - EINVAL ;
441392 goto out ;
442393 }
443- #endif
394+
444395
445396 switch (mdivr_val ) {
446397 case 1 :
0 commit comments