diff options
| -rw-r--r-- | sound/soc/codecs/tas2552.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index fe2e4d384a00..9c081344bd90 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c | |||
| @@ -46,7 +46,7 @@ static struct reg_default tas2552_reg_defs[] = { | |||
| 46 | {TAS2552_PDM_CFG, 0x01}, | 46 | {TAS2552_PDM_CFG, 0x01}, |
| 47 | {TAS2552_PGA_GAIN, 0x00}, | 47 | {TAS2552_PGA_GAIN, 0x00}, |
| 48 | {TAS2552_BOOST_PT_CTRL, 0x0f}, | 48 | {TAS2552_BOOST_PT_CTRL, 0x0f}, |
| 49 | {TAS2552_RESERVED_0D, 0x00}, | 49 | {TAS2552_RESERVED_0D, 0xbe}, |
| 50 | {TAS2552_LIMIT_RATE_HYS, 0x08}, | 50 | {TAS2552_LIMIT_RATE_HYS, 0x08}, |
| 51 | {TAS2552_CFG_2, 0xef}, | 51 | {TAS2552_CFG_2, 0xef}, |
| 52 | {TAS2552_SER_CTRL_1, 0x00}, | 52 | {TAS2552_SER_CTRL_1, 0x00}, |
| @@ -83,6 +83,29 @@ struct tas2552_data { | |||
| 83 | unsigned int tdm_delay; | 83 | unsigned int tdm_delay; |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | static int tas2552_post_event(struct snd_soc_dapm_widget *w, | ||
| 87 | struct snd_kcontrol *kcontrol, int event) | ||
| 88 | { | ||
| 89 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
| 90 | |||
| 91 | switch (event) { | ||
| 92 | case SND_SOC_DAPM_POST_PMU: | ||
| 93 | snd_soc_write(codec, TAS2552_RESERVED_0D, 0xc0); | ||
| 94 | snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5), | ||
| 95 | (1 << 5)); | ||
| 96 | snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 0); | ||
| 97 | snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS, 0); | ||
| 98 | break; | ||
| 99 | case SND_SOC_DAPM_POST_PMD: | ||
| 100 | snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS, | ||
| 101 | TAS2552_SWS); | ||
| 102 | snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 1); | ||
| 103 | snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0); | ||
| 104 | snd_soc_write(codec, TAS2552_RESERVED_0D, 0xbe); | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | return 0; | ||
| 108 | } | ||
| 86 | 109 | ||
| 87 | /* Input mux controls */ | 110 | /* Input mux controls */ |
| 88 | static const char * const tas2552_input_texts[] = { | 111 | static const char * const tas2552_input_texts[] = { |
| @@ -105,6 +128,7 @@ static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] = | |||
| 105 | SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), | 128 | SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), |
| 106 | SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0), | 129 | SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0), |
| 107 | SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0), | 130 | SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0), |
| 131 | SND_SOC_DAPM_POST("Post Event", tas2552_post_event), | ||
| 108 | 132 | ||
| 109 | SND_SOC_DAPM_OUTPUT("OUT") | 133 | SND_SOC_DAPM_OUTPUT("OUT") |
| 110 | }; | 134 | }; |
| @@ -413,10 +437,6 @@ static const struct snd_kcontrol_new tas2552_snd_controls[] = { | |||
| 413 | TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv), | 437 | TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv), |
| 414 | }; | 438 | }; |
| 415 | 439 | ||
| 416 | static const struct reg_default tas2552_init_regs[] = { | ||
| 417 | { TAS2552_RESERVED_0D, 0xc0 }, | ||
| 418 | }; | ||
| 419 | |||
| 420 | static int tas2552_codec_probe(struct snd_soc_codec *codec) | 440 | static int tas2552_codec_probe(struct snd_soc_codec *codec) |
| 421 | { | 441 | { |
| 422 | struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); | 442 | struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); |
| @@ -443,7 +463,7 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec) | |||
| 443 | goto probe_fail; | 463 | goto probe_fail; |
| 444 | } | 464 | } |
| 445 | 465 | ||
| 446 | snd_soc_write(codec, TAS2552_CFG_1, TAS2552_MUTE); | 466 | snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE); |
| 447 | snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL | | 467 | snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL | |
| 448 | TAS2552_DIN_SRC_SEL_AVG_L_R | TAS2552_88_96KHZ); | 468 | TAS2552_DIN_SRC_SEL_AVG_L_R | TAS2552_88_96KHZ); |
| 449 | snd_soc_write(codec, TAS2552_DOUT, TAS2552_PDM_DATA_I); | 469 | snd_soc_write(codec, TAS2552_DOUT, TAS2552_PDM_DATA_I); |
| @@ -451,21 +471,11 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec) | |||
| 451 | snd_soc_write(codec, TAS2552_BOOST_PT_CTRL, TAS2552_APT_DELAY_200 | | 471 | snd_soc_write(codec, TAS2552_BOOST_PT_CTRL, TAS2552_APT_DELAY_200 | |
| 452 | TAS2552_APT_THRESH_2_1_7); | 472 | TAS2552_APT_THRESH_2_1_7); |
| 453 | 473 | ||
| 454 | ret = regmap_register_patch(tas2552->regmap, tas2552_init_regs, | ||
| 455 | ARRAY_SIZE(tas2552_init_regs)); | ||
| 456 | if (ret != 0) { | ||
| 457 | dev_err(codec->dev, "Failed to write init registers: %d\n", | ||
| 458 | ret); | ||
| 459 | goto patch_fail; | ||
| 460 | } | ||
| 461 | |||
| 462 | snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | | 474 | snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | |
| 463 | TAS2552_APT_EN | TAS2552_LIM_EN); | 475 | TAS2552_APT_EN | TAS2552_LIM_EN); |
| 464 | 476 | ||
| 465 | return 0; | 477 | return 0; |
| 466 | 478 | ||
| 467 | patch_fail: | ||
| 468 | pm_runtime_put(codec->dev); | ||
| 469 | probe_fail: | 479 | probe_fail: |
| 470 | if (tas2552->enable_gpio) | 480 | if (tas2552->enable_gpio) |
| 471 | gpiod_set_value(tas2552->enable_gpio, 0); | 481 | gpiod_set_value(tas2552->enable_gpio, 0); |
| @@ -527,6 +537,8 @@ static struct snd_soc_codec_driver soc_codec_dev_tas2552 = { | |||
| 527 | .remove = tas2552_codec_remove, | 537 | .remove = tas2552_codec_remove, |
| 528 | .suspend = tas2552_suspend, | 538 | .suspend = tas2552_suspend, |
| 529 | .resume = tas2552_resume, | 539 | .resume = tas2552_resume, |
| 540 | .ignore_pmdown_time = true, | ||
| 541 | |||
| 530 | .controls = tas2552_snd_controls, | 542 | .controls = tas2552_snd_controls, |
| 531 | .num_controls = ARRAY_SIZE(tas2552_snd_controls), | 543 | .num_controls = ARRAY_SIZE(tas2552_snd_controls), |
| 532 | .dapm_widgets = tas2552_dapm_widgets, | 544 | .dapm_widgets = tas2552_dapm_widgets, |
