@@ -1014,35 +1014,52 @@ 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
+ }
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 ;
1031
1045
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 )
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 ;
1062
+ int err = - EINVAL ;
1046
1063
1047
1064
nau8824_sema_acquire (nau8824 , HZ );
1048
1065
@@ -1053,27 +1070,19 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
1053
1070
* than 6.144 MHz.
1054
1071
*/
1055
1072
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 )
1063
1079
regmap_update_bits (nau8824 -> regmap , NAU8824_REG_CLK_DIVIDER ,
1064
1080
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
1073
1083
regmap_update_bits (nau8824 -> regmap , NAU8824_REG_CLK_DIVIDER ,
1074
1084
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 );
1077
1086
1078
1087
/* make BCLK and LRC divde configuration if the codec as master. */
1079
1088
regmap_read (nau8824 -> regmap ,
@@ -1090,7 +1099,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
1090
1099
else if (bclk_fs <= 256 )
1091
1100
bclk_div = 0 ;
1092
1101
else
1093
- return - EINVAL ;
1102
+ goto error ;
1094
1103
regmap_update_bits (nau8824 -> regmap ,
1095
1104
NAU8824_REG_PORT0_I2S_PCM_CTRL_2 ,
1096
1105
NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK ,
@@ -1111,15 +1120,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
1111
1120
val_len |= NAU8824_I2S_DL_32 ;
1112
1121
break ;
1113
1122
default :
1114
- return - EINVAL ;
1123
+ goto error ;
1115
1124
}
1116
1125
1117
1126
regmap_update_bits (nau8824 -> regmap , NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ,
1118
1127
NAU8824_I2S_DL_MASK , val_len );
1128
+ err = 0 ;
1119
1129
1130
+ error :
1120
1131
nau8824_sema_release (nau8824 );
1121
1132
1122
- return 0 ;
1133
+ return err ;
1123
1134
}
1124
1135
1125
1136
static 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)
1128
1139
struct nau8824 * nau8824 = snd_soc_component_get_drvdata (component );
1129
1140
unsigned int ctrl1_val = 0 , ctrl2_val = 0 ;
1130
1141
1131
- nau8824_sema_acquire (nau8824 , HZ );
1132
-
1133
1142
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK ) {
1134
1143
case SND_SOC_DAIFMT_CBM_CFM :
1135
1144
ctrl2_val |= NAU8824_I2S_MS_MASTER ;
@@ -1171,6 +1180,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1171
1180
return - EINVAL ;
1172
1181
}
1173
1182
1183
+ nau8824_sema_acquire (nau8824 , HZ );
1184
+
1174
1185
regmap_update_bits (nau8824 -> regmap , NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ,
1175
1186
NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK |
1176
1187
NAU8824_I2S_PCMB_EN , ctrl1_val );
@@ -1547,6 +1558,7 @@ static const struct snd_soc_component_driver nau8824_component_driver = {
1547
1558
};
1548
1559
1549
1560
static const struct snd_soc_dai_ops nau8824_dai_ops = {
1561
+ .startup = nau8824_dai_startup ,
1550
1562
.hw_params = nau8824_hw_params ,
1551
1563
.set_fmt = nau8824_set_fmt ,
1552
1564
.set_tdm_slot = nau8824_set_tdm_slot ,
0 commit comments