@@ -1014,35 +1014,52 @@ static irqreturn_t nau8824_interrupt(int irq, void *data)
10141014 return IRQ_HANDLED ;
10151015}
10161016
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 )
10191019{
1020- int osrate ;
1020+ unsigned int osr ;
10211021
10221022 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 ;
10231026 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 ];
10261029 } else {
1030+ regmap_read (nau8824 -> regmap ,
1031+ NAU8824_REG_ADC_FILTER_CTRL , & osr );
1032+ osr &= NAU8824_ADC_SYNC_DOWN_MASK ;
10271033 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 ];
10301036 }
1037+ }
1038+
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 ;
10311045
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" );
1046+ osr = nau8824_get_osr ( nau8824 , substream -> stream );
1047+ if (! osr || ! osr -> osr )
10341048 return - EINVAL ;
1035- }
10361049
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 );
10381053}
10391054
10401055static int nau8824_hw_params (struct snd_pcm_substream * substream ,
10411056 struct snd_pcm_hw_params * params , struct snd_soc_dai * dai )
10421057{
10431058 struct snd_soc_component * component = dai -> component ;
10441059 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 ;
1062+ int err = - EINVAL ;
10461063
10471064 nau8824_sema_acquire (nau8824 , HZ );
10481065
@@ -1053,27 +1070,19 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
10531070 * than 6.144 MHz.
10541071 */
10551072 nau8824 -> fs = params_rate (params );
1056- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
1057- regmap_read (nau8824 -> regmap ,
1058- NAU8824_REG_DAC_FILTER_CTRL_1 , & osr );
1059- osr &= NAU8824_DAC_OVERSAMPLE_MASK ;
1060- if (nau8824_clock_check (nau8824 , substream -> stream ,
1061- nau8824 -> fs , osr ))
1062- return - EINVAL ;
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 )
10631079 regmap_update_bits (nau8824 -> regmap , NAU8824_REG_CLK_DIVIDER ,
10641080 NAU8824_CLK_DAC_SRC_MASK ,
1065- osr_dac_sel [osr ].clk_src << NAU8824_CLK_DAC_SRC_SFT );
1066- } else {
1067- regmap_read (nau8824 -> regmap ,
1068- NAU8824_REG_ADC_FILTER_CTRL , & osr );
1069- osr &= NAU8824_ADC_SYNC_DOWN_MASK ;
1070- if (nau8824_clock_check (nau8824 , substream -> stream ,
1071- nau8824 -> fs , osr ))
1072- return - EINVAL ;
1081+ osr -> clk_src << NAU8824_CLK_DAC_SRC_SFT );
1082+ else
10731083 regmap_update_bits (nau8824 -> regmap , NAU8824_REG_CLK_DIVIDER ,
10741084 NAU8824_CLK_ADC_SRC_MASK ,
1075- osr_adc_sel [osr ].clk_src << NAU8824_CLK_ADC_SRC_SFT );
1076- }
1085+ osr -> clk_src << NAU8824_CLK_ADC_SRC_SFT );
10771086
10781087 /* make BCLK and LRC divde configuration if the codec as master. */
10791088 regmap_read (nau8824 -> regmap ,
@@ -1090,7 +1099,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
10901099 else if (bclk_fs <= 256 )
10911100 bclk_div = 0 ;
10921101 else
1093- return - EINVAL ;
1102+ goto error ;
10941103 regmap_update_bits (nau8824 -> regmap ,
10951104 NAU8824_REG_PORT0_I2S_PCM_CTRL_2 ,
10961105 NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK ,
@@ -1111,15 +1120,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
11111120 val_len |= NAU8824_I2S_DL_32 ;
11121121 break ;
11131122 default :
1114- return - EINVAL ;
1123+ goto error ;
11151124 }
11161125
11171126 regmap_update_bits (nau8824 -> regmap , NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ,
11181127 NAU8824_I2S_DL_MASK , val_len );
1128+ err = 0 ;
11191129
1130+ error :
11201131 nau8824_sema_release (nau8824 );
11211132
1122- return 0 ;
1133+ return err ;
11231134}
11241135
11251136static int nau8824_set_fmt (struct snd_soc_dai * dai , unsigned int fmt )
@@ -1128,8 +1139,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
11281139 struct nau8824 * nau8824 = snd_soc_component_get_drvdata (component );
11291140 unsigned int ctrl1_val = 0 , ctrl2_val = 0 ;
11301141
1131- nau8824_sema_acquire (nau8824 , HZ );
1132-
11331142 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK ) {
11341143 case SND_SOC_DAIFMT_CBM_CFM :
11351144 ctrl2_val |= NAU8824_I2S_MS_MASTER ;
@@ -1171,6 +1180,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
11711180 return - EINVAL ;
11721181 }
11731182
1183+ nau8824_sema_acquire (nau8824 , HZ );
1184+
11741185 regmap_update_bits (nau8824 -> regmap , NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ,
11751186 NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK |
11761187 NAU8824_I2S_PCMB_EN , ctrl1_val );
@@ -1547,6 +1558,7 @@ static const struct snd_soc_component_driver nau8824_component_driver = {
15471558};
15481559
15491560static const struct snd_soc_dai_ops nau8824_dai_ops = {
1561+ .startup = nau8824_dai_startup ,
15501562 .hw_params = nau8824_hw_params ,
15511563 .set_fmt = nau8824_set_fmt ,
15521564 .set_tdm_slot = nau8824_set_tdm_slot ,
0 commit comments