26
26
#include <sound/tlv.h>
27
27
#include "es8328.h"
28
28
29
- #define ES8328_SYSCLK_RATE_1X 11289600
30
- #define ES8328_SYSCLK_RATE_2X 22579200
29
+ static const unsigned int rates_12288 [] = {
30
+ 8000 , 12000 , 16000 , 24000 , 32000 , 48000 , 96000 ,
31
+ };
31
32
32
- /* Run the codec at 22.5792 or 11.2896 MHz to support these rates */
33
- static struct {
34
- int rate ;
35
- u8 ratio ;
36
- } mclk_ratios [] = {
37
- { 8000 , 9 },
38
- {11025 , 7 },
39
- {22050 , 4 },
40
- {44100 , 2 },
33
+ static const int ratios_12288 [] = {
34
+ 10 , 7 , 6 , 4 , 3 , 2 , 0 ,
35
+ };
36
+
37
+ static const struct snd_pcm_hw_constraint_list constraints_12288 = {
38
+ .count = ARRAY_SIZE (rates_12288 ),
39
+ .list = rates_12288 ,
40
+ };
41
+
42
+ static const unsigned int rates_11289 [] = {
43
+ 8018 , 11025 , 22050 , 44100 , 88200 ,
44
+ };
45
+
46
+ static const int ratios_11289 [] = {
47
+ 9 , 7 , 4 , 2 , 0 ,
48
+ };
49
+
50
+ static const struct snd_pcm_hw_constraint_list constraints_11289 = {
51
+ .count = ARRAY_SIZE (rates_11289 ),
52
+ .list = rates_11289 ,
41
53
};
42
54
43
55
/* regulator supplies for sgtl5000, VDDD is an optional external supply */
@@ -57,16 +69,28 @@ static const char * const supply_names[ES8328_SUPPLY_NUM] = {
57
69
"HPVDD" ,
58
70
};
59
71
60
- #define ES8328_RATES (SNDRV_PCM_RATE_44100 | \
72
+ #define ES8328_RATES (SNDRV_PCM_RATE_96000 | \
73
+ SNDRV_PCM_RATE_48000 | \
74
+ SNDRV_PCM_RATE_44100 | \
75
+ SNDRV_PCM_RATE_32000 | \
61
76
SNDRV_PCM_RATE_22050 | \
62
- SNDRV_PCM_RATE_11025)
63
- #define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
77
+ SNDRV_PCM_RATE_16000 | \
78
+ SNDRV_PCM_RATE_11025 | \
79
+ SNDRV_PCM_RATE_8000)
80
+ #define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
81
+ SNDRV_PCM_FMTBIT_S18_3LE | \
82
+ SNDRV_PCM_FMTBIT_S20_3LE | \
83
+ SNDRV_PCM_FMTBIT_S24_LE | \
84
+ SNDRV_PCM_FMTBIT_S32_LE)
64
85
65
86
struct es8328_priv {
66
87
struct regmap * regmap ;
67
88
struct clk * clk ;
68
89
int playback_fs ;
69
90
bool deemph ;
91
+ int mclkdiv2 ;
92
+ const struct snd_pcm_hw_constraint_list * sysclk_constraints ;
93
+ const int * mclk_ratios ;
70
94
struct regulator_bulk_data supplies [ES8328_SUPPLY_NUM ];
71
95
};
72
96
@@ -439,54 +463,131 @@ static int es8328_mute(struct snd_soc_dai *dai, int mute)
439
463
mute ? ES8328_DACCONTROL3_DACMUTE : 0 );
440
464
}
441
465
466
+ static int es8328_startup (struct snd_pcm_substream * substream ,
467
+ struct snd_soc_dai * dai )
468
+ {
469
+ struct snd_soc_codec * codec = dai -> codec ;
470
+ struct es8328_priv * es8328 = snd_soc_codec_get_drvdata (codec );
471
+
472
+ if (es8328 -> sysclk_constraints )
473
+ snd_pcm_hw_constraint_list (substream -> runtime , 0 ,
474
+ SNDRV_PCM_HW_PARAM_RATE ,
475
+ es8328 -> sysclk_constraints );
476
+
477
+ return 0 ;
478
+ }
479
+
442
480
static int es8328_hw_params (struct snd_pcm_substream * substream ,
443
481
struct snd_pcm_hw_params * params ,
444
482
struct snd_soc_dai * dai )
445
483
{
446
484
struct snd_soc_codec * codec = dai -> codec ;
447
485
struct es8328_priv * es8328 = snd_soc_codec_get_drvdata (codec );
448
- int clk_rate ;
449
486
int i ;
450
487
int reg ;
451
- u8 ratio ;
488
+ int wl ;
489
+ int ratio ;
490
+
491
+ if (!es8328 -> sysclk_constraints ) {
492
+ dev_err (codec -> dev , "No MCLK configured\n" );
493
+ return - EINVAL ;
494
+ }
452
495
453
496
if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
454
497
reg = ES8328_DACCONTROL2 ;
455
498
else
456
499
reg = ES8328_ADCCONTROL5 ;
457
500
458
- clk_rate = clk_get_rate (es8328 -> clk );
501
+ for (i = 0 ; i < es8328 -> sysclk_constraints -> count ; i ++ )
502
+ if (es8328 -> sysclk_constraints -> list [i ] == params_rate (params ))
503
+ break ;
459
504
460
- if ((clk_rate != ES8328_SYSCLK_RATE_1X ) &&
461
- (clk_rate != ES8328_SYSCLK_RATE_2X )) {
462
- dev_err (codec -> dev ,
463
- "%s: clock is running at %d Hz, not %d or %d Hz\n" ,
464
- __func__ , clk_rate ,
465
- ES8328_SYSCLK_RATE_1X , ES8328_SYSCLK_RATE_2X );
505
+ if (i == es8328 -> sysclk_constraints -> count ) {
506
+ dev_err (codec -> dev , "LRCLK %d unsupported with current clock\n" ,
507
+ params_rate (params ));
466
508
return - EINVAL ;
467
509
}
468
510
469
- /* find master mode MCLK to sampling frequency ratio */
470
- ratio = mclk_ratios [0 ].rate ;
471
- for (i = 1 ; i < ARRAY_SIZE (mclk_ratios ); i ++ )
472
- if (params_rate (params ) <= mclk_ratios [i ].rate )
473
- ratio = mclk_ratios [i ].ratio ;
511
+ ratio = es8328 -> mclk_ratios [i ];
512
+ snd_soc_update_bits (codec , ES8328_MASTERMODE ,
513
+ ES8328_MASTERMODE_MCLKDIV2 ,
514
+ es8328 -> mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0 );
515
+
516
+ switch (params_width (params )) {
517
+ case 16 :
518
+ wl = 3 ;
519
+ break ;
520
+ case 18 :
521
+ wl = 2 ;
522
+ break ;
523
+ case 20 :
524
+ wl = 1 ;
525
+ break ;
526
+ case 24 :
527
+ wl = 0 ;
528
+ break ;
529
+ case 32 :
530
+ wl = 4 ;
531
+ break ;
532
+ default :
533
+ return - EINVAL ;
534
+ }
474
535
475
536
if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
537
+ snd_soc_update_bits (codec , ES8328_DACCONTROL1 ,
538
+ ES8328_DACCONTROL1_DACWL_MASK ,
539
+ wl << ES8328_DACCONTROL1_DACWL_SHIFT );
540
+
476
541
es8328 -> playback_fs = params_rate (params );
477
542
es8328_set_deemph (codec );
478
- }
543
+ } else
544
+ snd_soc_update_bits (codec , ES8328_ADCCONTROL4 ,
545
+ ES8328_ADCCONTROL4_ADCWL_MASK ,
546
+ wl << ES8328_ADCCONTROL4_ADCWL_SHIFT );
479
547
480
548
return snd_soc_update_bits (codec , reg , ES8328_RATEMASK , ratio );
481
549
}
482
550
551
+ static int es8328_set_sysclk (struct snd_soc_dai * codec_dai ,
552
+ int clk_id , unsigned int freq , int dir )
553
+ {
554
+ struct snd_soc_codec * codec = codec_dai -> codec ;
555
+ struct es8328_priv * es8328 = snd_soc_codec_get_drvdata (codec );
556
+ int mclkdiv2 = 0 ;
557
+
558
+ switch (freq ) {
559
+ case 0 :
560
+ es8328 -> sysclk_constraints = NULL ;
561
+ es8328 -> mclk_ratios = NULL ;
562
+ break ;
563
+ case 22579200 :
564
+ mclkdiv2 = 1 ;
565
+ /* fallthru */
566
+ case 11289600 :
567
+ es8328 -> sysclk_constraints = & constraints_11289 ;
568
+ es8328 -> mclk_ratios = ratios_11289 ;
569
+ break ;
570
+ case 24576000 :
571
+ mclkdiv2 = 1 ;
572
+ /* fallthru */
573
+ case 12288000 :
574
+ es8328 -> sysclk_constraints = & constraints_12288 ;
575
+ es8328 -> mclk_ratios = ratios_12288 ;
576
+ break ;
577
+ default :
578
+ return - EINVAL ;
579
+ }
580
+
581
+ es8328 -> mclkdiv2 = mclkdiv2 ;
582
+ return 0 ;
583
+ }
584
+
483
585
static int es8328_set_dai_fmt (struct snd_soc_dai * codec_dai ,
484
586
unsigned int fmt )
485
587
{
486
588
struct snd_soc_codec * codec = codec_dai -> codec ;
487
- struct es8328_priv * es8328 = snd_soc_codec_get_drvdata (codec );
488
- int clk_rate ;
489
- u8 mode = ES8328_DACCONTROL1_DACWL_16 ;
589
+ u8 dac_mode = 0 ;
590
+ u8 adc_mode = 0 ;
490
591
491
592
/* set master/slave audio interface */
492
593
if ((fmt & SND_SOC_DAIFMT_MASTER_MASK ) != SND_SOC_DAIFMT_CBM_CFM )
@@ -495,13 +596,16 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
495
596
/* interface format */
496
597
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK ) {
497
598
case SND_SOC_DAIFMT_I2S :
498
- mode |= ES8328_DACCONTROL1_DACFORMAT_I2S ;
599
+ dac_mode |= ES8328_DACCONTROL1_DACFORMAT_I2S ;
600
+ adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_I2S ;
499
601
break ;
500
602
case SND_SOC_DAIFMT_RIGHT_J :
501
- mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST ;
603
+ dac_mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST ;
604
+ adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_RJUST ;
502
605
break ;
503
606
case SND_SOC_DAIFMT_LEFT_J :
504
- mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST ;
607
+ dac_mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST ;
608
+ adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_LJUST ;
505
609
break ;
506
610
default :
507
611
return - EINVAL ;
@@ -511,18 +615,14 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
511
615
if ((fmt & SND_SOC_DAIFMT_INV_MASK ) != SND_SOC_DAIFMT_NB_NF )
512
616
return - EINVAL ;
513
617
514
- snd_soc_write (codec , ES8328_DACCONTROL1 , mode );
515
- snd_soc_write (codec , ES8328_ADCCONTROL4 , mode );
618
+ snd_soc_update_bits (codec , ES8328_DACCONTROL1 ,
619
+ ES8328_DACCONTROL1_DACFORMAT_MASK , dac_mode );
620
+ snd_soc_update_bits (codec , ES8328_ADCCONTROL4 ,
621
+ ES8328_ADCCONTROL4_ADCFORMAT_MASK , adc_mode );
516
622
517
623
/* Master serial port mode, with BCLK generated automatically */
518
- clk_rate = clk_get_rate (es8328 -> clk );
519
- if (clk_rate == ES8328_SYSCLK_RATE_1X )
520
- snd_soc_write (codec , ES8328_MASTERMODE ,
521
- ES8328_MASTERMODE_MSC );
522
- else
523
- snd_soc_write (codec , ES8328_MASTERMODE ,
524
- ES8328_MASTERMODE_MCLKDIV2 |
525
- ES8328_MASTERMODE_MSC );
624
+ snd_soc_update_bits (codec , ES8328_MASTERMODE ,
625
+ ES8328_MASTERMODE_MSC , ES8328_MASTERMODE_MSC );
526
626
527
627
return 0 ;
528
628
}
@@ -579,8 +679,10 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
579
679
}
580
680
581
681
static const struct snd_soc_dai_ops es8328_dai_ops = {
682
+ .startup = es8328_startup ,
582
683
.hw_params = es8328_hw_params ,
583
684
.digital_mute = es8328_mute ,
685
+ .set_sysclk = es8328_set_sysclk ,
584
686
.set_fmt = es8328_set_dai_fmt ,
585
687
};
586
688
@@ -601,6 +703,7 @@ static struct snd_soc_dai_driver es8328_dai = {
601
703
.formats = ES8328_FORMATS ,
602
704
},
603
705
.ops = & es8328_dai_ops ,
706
+ .symmetric_rates = 1 ,
604
707
};
605
708
606
709
static int es8328_suspend (struct snd_soc_codec * codec )
@@ -708,6 +811,7 @@ const struct regmap_config es8328_regmap_config = {
708
811
.val_bits = 8 ,
709
812
.max_register = ES8328_REG_MAX ,
710
813
.cache_type = REGCACHE_RBTREE ,
814
+ .use_single_rw = true,
711
815
};
712
816
EXPORT_SYMBOL_GPL (es8328_regmap_config );
713
817
0 commit comments