@@ -1247,27 +1247,42 @@ static const struct snd_soc_dapm_route nau8825_dapm_routes[] = {
1247
1247
{"HPOR" , NULL , "Class G" },
1248
1248
};
1249
1249
1250
- static int nau8825_clock_check ( struct nau8825 * nau8825 ,
1251
- int stream , int rate , int osr )
1250
+ static const struct nau8825_osr_attr *
1251
+ nau8825_get_osr ( struct nau8825 * nau8825 , int stream )
1252
1252
{
1253
- int osrate ;
1253
+ unsigned int osr ;
1254
1254
1255
1255
if (stream == SNDRV_PCM_STREAM_PLAYBACK ) {
1256
+ regmap_read (nau8825 -> regmap ,
1257
+ NAU8825_REG_DAC_CTRL1 , & osr );
1258
+ osr &= NAU8825_DAC_OVERSAMPLE_MASK ;
1256
1259
if (osr >= ARRAY_SIZE (osr_dac_sel ))
1257
- return - EINVAL ;
1258
- osrate = osr_dac_sel [osr ]. osr ;
1260
+ return NULL ;
1261
+ return & osr_dac_sel [osr ];
1259
1262
} else {
1263
+ regmap_read (nau8825 -> regmap ,
1264
+ NAU8825_REG_ADC_RATE , & osr );
1265
+ osr &= NAU8825_ADC_SYNC_DOWN_MASK ;
1260
1266
if (osr >= ARRAY_SIZE (osr_adc_sel ))
1261
- return - EINVAL ;
1262
- osrate = osr_adc_sel [osr ]. osr ;
1267
+ return NULL ;
1268
+ return & osr_adc_sel [osr ];
1263
1269
}
1270
+ }
1264
1271
1265
- if (!osrate || rate * osr > CLK_DA_AD_MAX ) {
1266
- dev_err (nau8825 -> dev , "exceed the maximum frequency of CLK_ADC or CLK_DAC\n" );
1272
+ static int nau8825_dai_startup (struct snd_pcm_substream * substream ,
1273
+ struct snd_soc_dai * dai )
1274
+ {
1275
+ struct snd_soc_component * component = dai -> component ;
1276
+ struct nau8825 * nau8825 = snd_soc_component_get_drvdata (component );
1277
+ const struct nau8825_osr_attr * osr ;
1278
+
1279
+ osr = nau8825_get_osr (nau8825 , substream -> stream );
1280
+ if (!osr || !osr -> osr )
1267
1281
return - EINVAL ;
1268
- }
1269
1282
1270
- return 0 ;
1283
+ return snd_pcm_hw_constraint_minmax (substream -> runtime ,
1284
+ SNDRV_PCM_HW_PARAM_RATE ,
1285
+ 0 , CLK_DA_AD_MAX / osr -> osr );
1271
1286
}
1272
1287
1273
1288
static int nau8825_hw_params (struct snd_pcm_substream * substream ,
@@ -1276,7 +1291,9 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1276
1291
{
1277
1292
struct snd_soc_component * component = dai -> component ;
1278
1293
struct nau8825 * nau8825 = snd_soc_component_get_drvdata (component );
1279
- unsigned int val_len = 0 , osr , ctrl_val , bclk_fs , bclk_div ;
1294
+ unsigned int val_len = 0 , ctrl_val , bclk_fs , bclk_div ;
1295
+ const struct nau8825_osr_attr * osr ;
1296
+ int err = - EINVAL ;
1280
1297
1281
1298
nau8825_sema_acquire (nau8825 , 3 * HZ );
1282
1299
@@ -1286,29 +1303,19 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1286
1303
* values must be selected such that the maximum frequency is less
1287
1304
* than 6.144 MHz.
1288
1305
*/
1289
- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
1290
- regmap_read (nau8825 -> regmap , NAU8825_REG_DAC_CTRL1 , & osr );
1291
- osr &= NAU8825_DAC_OVERSAMPLE_MASK ;
1292
- if (nau8825_clock_check (nau8825 , substream -> stream ,
1293
- params_rate (params ), osr )) {
1294
- nau8825_sema_release (nau8825 );
1295
- return - EINVAL ;
1296
- }
1306
+ osr = nau8825_get_osr (nau8825 , substream -> stream );
1307
+ if (!osr || !osr -> osr )
1308
+ goto error ;
1309
+ if (params_rate (params ) * osr -> osr > CLK_DA_AD_MAX )
1310
+ goto error ;
1311
+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
1297
1312
regmap_update_bits (nau8825 -> regmap , NAU8825_REG_CLK_DIVIDER ,
1298
1313
NAU8825_CLK_DAC_SRC_MASK ,
1299
- osr_dac_sel [osr ].clk_src << NAU8825_CLK_DAC_SRC_SFT );
1300
- } else {
1301
- regmap_read (nau8825 -> regmap , NAU8825_REG_ADC_RATE , & osr );
1302
- osr &= NAU8825_ADC_SYNC_DOWN_MASK ;
1303
- if (nau8825_clock_check (nau8825 , substream -> stream ,
1304
- params_rate (params ), osr )) {
1305
- nau8825_sema_release (nau8825 );
1306
- return - EINVAL ;
1307
- }
1314
+ osr -> clk_src << NAU8825_CLK_DAC_SRC_SFT );
1315
+ else
1308
1316
regmap_update_bits (nau8825 -> regmap , NAU8825_REG_CLK_DIVIDER ,
1309
1317
NAU8825_CLK_ADC_SRC_MASK ,
1310
- osr_adc_sel [osr ].clk_src << NAU8825_CLK_ADC_SRC_SFT );
1311
- }
1318
+ osr -> clk_src << NAU8825_CLK_ADC_SRC_SFT );
1312
1319
1313
1320
/* make BCLK and LRC divde configuration if the codec as master. */
1314
1321
regmap_read (nau8825 -> regmap , NAU8825_REG_I2S_PCM_CTRL2 , & ctrl_val );
@@ -1321,10 +1328,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1321
1328
bclk_div = 1 ;
1322
1329
else if (bclk_fs <= 128 )
1323
1330
bclk_div = 0 ;
1324
- else {
1325
- nau8825_sema_release (nau8825 );
1326
- return - EINVAL ;
1327
- }
1331
+ else
1332
+ goto error ;
1328
1333
regmap_update_bits (nau8825 -> regmap , NAU8825_REG_I2S_PCM_CTRL2 ,
1329
1334
NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK ,
1330
1335
((bclk_div + 1 ) << NAU8825_I2S_LRC_DIV_SFT ) | bclk_div );
@@ -1344,17 +1349,18 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1344
1349
val_len |= NAU8825_I2S_DL_32 ;
1345
1350
break ;
1346
1351
default :
1347
- nau8825_sema_release (nau8825 );
1348
- return - EINVAL ;
1352
+ goto error ;
1349
1353
}
1350
1354
1351
1355
regmap_update_bits (nau8825 -> regmap , NAU8825_REG_I2S_PCM_CTRL1 ,
1352
1356
NAU8825_I2S_DL_MASK , val_len );
1357
+ err = 0 ;
1353
1358
1359
+ error :
1354
1360
/* Release the semaphore. */
1355
1361
nau8825_sema_release (nau8825 );
1356
1362
1357
- return 0 ;
1363
+ return err ;
1358
1364
}
1359
1365
1360
1366
static int nau8825_set_dai_fmt (struct snd_soc_dai * codec_dai , unsigned int fmt )
@@ -1420,6 +1426,7 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1420
1426
}
1421
1427
1422
1428
static const struct snd_soc_dai_ops nau8825_dai_ops = {
1429
+ .startup = nau8825_dai_startup ,
1423
1430
.hw_params = nau8825_hw_params ,
1424
1431
.set_fmt = nau8825_set_dai_fmt ,
1425
1432
};
0 commit comments