diff options
| -rw-r--r-- | sound/soc/codecs/wm8731.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 5276062d6c79..456bb8c6d759 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
| @@ -45,6 +45,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { | |||
| 45 | struct wm8731_priv { | 45 | struct wm8731_priv { |
| 46 | struct regmap *regmap; | 46 | struct regmap *regmap; |
| 47 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; | 47 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; |
| 48 | const struct snd_pcm_hw_constraint_list *constraints; | ||
| 48 | unsigned int sysclk; | 49 | unsigned int sysclk; |
| 49 | int sysclk_type; | 50 | int sysclk_type; |
| 50 | int playback_fs; | 51 | int playback_fs; |
| @@ -290,6 +291,36 @@ static const struct _coeff_div coeff_div[] = { | |||
| 290 | {12000000, 88200, 136, 0xf, 0x1, 0x1}, | 291 | {12000000, 88200, 136, 0xf, 0x1, 0x1}, |
| 291 | }; | 292 | }; |
| 292 | 293 | ||
| 294 | /* rates constraints */ | ||
| 295 | static const unsigned int wm8731_rates_12000000[] = { | ||
| 296 | 8000, 32000, 44100, 48000, 96000, 88200, | ||
| 297 | }; | ||
| 298 | |||
| 299 | static const unsigned int wm8731_rates_12288000_18432000[] = { | ||
| 300 | 8000, 32000, 48000, 96000, | ||
| 301 | }; | ||
| 302 | |||
| 303 | static const unsigned int wm8731_rates_11289600_16934400[] = { | ||
| 304 | 8000, 44100, 88200, | ||
| 305 | }; | ||
| 306 | |||
| 307 | static const struct snd_pcm_hw_constraint_list wm8731_constraints_12000000 = { | ||
| 308 | .list = wm8731_rates_12000000, | ||
| 309 | .count = ARRAY_SIZE(wm8731_rates_12000000), | ||
| 310 | }; | ||
| 311 | |||
| 312 | static const | ||
| 313 | struct snd_pcm_hw_constraint_list wm8731_constraints_12288000_18432000 = { | ||
| 314 | .list = wm8731_rates_12288000_18432000, | ||
| 315 | .count = ARRAY_SIZE(wm8731_rates_12288000_18432000), | ||
| 316 | }; | ||
| 317 | |||
| 318 | static const | ||
| 319 | struct snd_pcm_hw_constraint_list wm8731_constraints_11289600_16934400 = { | ||
| 320 | .list = wm8731_rates_11289600_16934400, | ||
| 321 | .count = ARRAY_SIZE(wm8731_rates_11289600_16934400), | ||
| 322 | }; | ||
| 323 | |||
| 293 | static inline int get_coeff(int mclk, int rate) | 324 | static inline int get_coeff(int mclk, int rate) |
| 294 | { | 325 | { |
| 295 | int i; | 326 | int i; |
| @@ -362,17 +393,26 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
| 362 | } | 393 | } |
| 363 | 394 | ||
| 364 | switch (freq) { | 395 | switch (freq) { |
| 365 | case 11289600: | 396 | case 0: |
| 397 | wm8731->constraints = NULL; | ||
| 398 | break; | ||
| 366 | case 12000000: | 399 | case 12000000: |
| 400 | wm8731->constraints = &wm8731_constraints_12000000; | ||
| 401 | break; | ||
| 367 | case 12288000: | 402 | case 12288000: |
| 368 | case 16934400: | ||
| 369 | case 18432000: | 403 | case 18432000: |
| 370 | wm8731->sysclk = freq; | 404 | wm8731->constraints = &wm8731_constraints_12288000_18432000; |
| 405 | break; | ||
| 406 | case 16934400: | ||
| 407 | case 11289600: | ||
| 408 | wm8731->constraints = &wm8731_constraints_11289600_16934400; | ||
| 371 | break; | 409 | break; |
| 372 | default: | 410 | default: |
| 373 | return -EINVAL; | 411 | return -EINVAL; |
| 374 | } | 412 | } |
| 375 | 413 | ||
| 414 | wm8731->sysclk = freq; | ||
| 415 | |||
| 376 | snd_soc_dapm_sync(&codec->dapm); | 416 | snd_soc_dapm_sync(&codec->dapm); |
| 377 | 417 | ||
| 378 | return 0; | 418 | return 0; |
| @@ -475,12 +515,26 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
| 475 | return 0; | 515 | return 0; |
| 476 | } | 516 | } |
| 477 | 517 | ||
| 518 | static int wm8731_startup(struct snd_pcm_substream *substream, | ||
| 519 | struct snd_soc_dai *dai) | ||
| 520 | { | ||
| 521 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(dai->codec); | ||
| 522 | |||
| 523 | if (wm8731->constraints) | ||
| 524 | snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
| 525 | SNDRV_PCM_HW_PARAM_RATE, | ||
| 526 | wm8731->constraints); | ||
| 527 | |||
| 528 | return 0; | ||
| 529 | } | ||
| 530 | |||
| 478 | #define WM8731_RATES SNDRV_PCM_RATE_8000_96000 | 531 | #define WM8731_RATES SNDRV_PCM_RATE_8000_96000 |
| 479 | 532 | ||
| 480 | #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 533 | #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 481 | SNDRV_PCM_FMTBIT_S24_LE) | 534 | SNDRV_PCM_FMTBIT_S24_LE) |
| 482 | 535 | ||
| 483 | static const struct snd_soc_dai_ops wm8731_dai_ops = { | 536 | static const struct snd_soc_dai_ops wm8731_dai_ops = { |
| 537 | .startup = wm8731_startup, | ||
| 484 | .hw_params = wm8731_hw_params, | 538 | .hw_params = wm8731_hw_params, |
| 485 | .digital_mute = wm8731_mute, | 539 | .digital_mute = wm8731_mute, |
| 486 | .set_sysclk = wm8731_set_dai_sysclk, | 540 | .set_sysclk = wm8731_set_dai_sysclk, |
