@@ -1014,35 +1014,51 @@ static irqreturn_t nau8824_interrupt(int irq, void *data)
1014
1014
return IRQ_HANDLED ;
1015
1015
}
1016
1016
1017
- static int nau8824_clock_check ( struct nau8824 * nau8824 ,
1018
- int stream , int rate , int osr )
1017
+ static const struct nau8824_osr_attr *
1018
+ nau8824_get_osr ( struct nau8824 * nau8824 , int stream )
1019
1019
{
1020
- int osrate ;
1020
+ unsigned int osr ;
1021
1021
1022
1022
if (stream == SNDRV_PCM_STREAM_PLAYBACK ) {
1023
+ regmap_read (nau8824 -> regmap ,
1024
+ NAU8824_REG_DAC_FILTER_CTRL_1 , & osr );
1025
+ osr &= NAU8824_DAC_OVERSAMPLE_MASK ;
1023
1026
if (osr >= ARRAY_SIZE (osr_dac_sel ))
1024
- return - EINVAL ;
1025
- osrate = osr_dac_sel [osr ]. osr ;
1027
+ return NULL ;
1028
+ return & osr_dac_sel [osr ];
1026
1029
} else {
1030
+ regmap_read (nau8824 -> regmap ,
1031
+ NAU8824_REG_ADC_FILTER_CTRL , & osr );
1032
+ osr &= NAU8824_ADC_SYNC_DOWN_MASK ;
1027
1033
if (osr >= ARRAY_SIZE (osr_adc_sel ))
1028
- return - EINVAL ;
1029
- osrate = osr_adc_sel [osr ]. osr ;
1034
+ return NULL ;
1035
+ return & osr_adc_sel [osr ];
1030
1036
}
1037
+ }
1031
1038
1032
- if (!osrate || rate * osr > CLK_DA_AD_MAX ) {
1033
- dev_err (nau8824 -> dev , "exceed the maximum frequency of CLK_ADC or CLK_DAC\n" );
1039
+ static int nau8824_dai_startup (struct snd_pcm_substream * substream ,
1040
+ struct snd_soc_dai * dai )
1041
+ {
1042
+ struct snd_soc_component * component = dai -> component ;
1043
+ struct nau8824 * nau8824 = snd_soc_component_get_drvdata (component );
1044
+ const struct nau8824_osr_attr * osr ;
1045
+
1046
+ osr = nau8824_get_osr (nau8824 , substream -> stream );
1047
+ if (!osr || !osr -> osr )
1034
1048
return - EINVAL ;
1035
- }
1036
1049
1037
- return 0 ;
1050
+ return snd_pcm_hw_constraint_minmax (substream -> runtime ,
1051
+ SNDRV_PCM_HW_PARAM_RATE ,
1052
+ 0 , CLK_DA_AD_MAX / osr -> osr );
1038
1053
}
1039
1054
1040
1055
static int nau8824_hw_params (struct snd_pcm_substream * substream ,
1041
1056
struct snd_pcm_hw_params * params , struct snd_soc_dai * dai )
1042
1057
{
1043
1058
struct snd_soc_component * component = dai -> component ;
1044
1059
struct nau8824 * nau8824 = snd_soc_component_get_drvdata (component );
1045
- unsigned int val_len = 0 , osr , ctrl_val , bclk_fs , bclk_div ;
1060
+ unsigned int val_len = 0 , ctrl_val , bclk_fs , bclk_div ;
1061
+ const struct nau8824_osr_attr * osr ;
1046
1062
int err = - EINVAL ;
1047
1063
1048
1064
nau8824_sema_acquire (nau8824 , HZ );
@@ -1054,27 +1070,19 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
1054
1070
* than 6.144 MHz.
1055
1071
*/
1056
1072
nau8824 -> fs = params_rate (params );
1057
- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
1058
- regmap_read (nau8824 -> regmap ,
1059
- NAU8824_REG_DAC_FILTER_CTRL_1 , & osr );
1060
- osr &= NAU8824_DAC_OVERSAMPLE_MASK ;
1061
- if (nau8824_clock_check (nau8824 , substream -> stream ,
1062
- nau8824 -> fs , osr ))
1063
- goto error ;
1073
+ osr = nau8824_get_osr (nau8824 , substream -> stream );
1074
+ if (!osr || !osr -> osr )
1075
+ goto error ;
1076
+ if (nau8824 -> fs * osr -> osr > CLK_DA_AD_MAX )
1077
+ goto error ;
1078
+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
1064
1079
regmap_update_bits (nau8824 -> regmap , NAU8824_REG_CLK_DIVIDER ,
1065
1080
NAU8824_CLK_DAC_SRC_MASK ,
1066
- osr_dac_sel [osr ].clk_src << NAU8824_CLK_DAC_SRC_SFT );
1067
- } else {
1068
- regmap_read (nau8824 -> regmap ,
1069
- NAU8824_REG_ADC_FILTER_CTRL , & osr );
1070
- osr &= NAU8824_ADC_SYNC_DOWN_MASK ;
1071
- if (nau8824_clock_check (nau8824 , substream -> stream ,
1072
- nau8824 -> fs , osr ))
1073
- goto error ;
1081
+ osr -> clk_src << NAU8824_CLK_DAC_SRC_SFT );
1082
+ else
1074
1083
regmap_update_bits (nau8824 -> regmap , NAU8824_REG_CLK_DIVIDER ,
1075
1084
NAU8824_CLK_ADC_SRC_MASK ,
1076
- osr_adc_sel [osr ].clk_src << NAU8824_CLK_ADC_SRC_SFT );
1077
- }
1085
+ osr -> clk_src << NAU8824_CLK_ADC_SRC_SFT );
1078
1086
1079
1087
/* make BCLK and LRC divde configuration if the codec as master. */
1080
1088
regmap_read (nau8824 -> regmap ,
@@ -1550,6 +1558,7 @@ static const struct snd_soc_component_driver nau8824_component_driver = {
1550
1558
};
1551
1559
1552
1560
static const struct snd_soc_dai_ops nau8824_dai_ops = {
1561
+ .startup = nau8824_dai_startup ,
1553
1562
.hw_params = nau8824_hw_params ,
1554
1563
.set_fmt = nau8824_set_fmt ,
1555
1564
.set_tdm_slot = nau8824_set_tdm_slot ,
0 commit comments