aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/tas2552.c44
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
86static 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 */
88static const char * const tas2552_input_texts[] = { 111static 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
416static const struct reg_default tas2552_init_regs[] = {
417 { TAS2552_RESERVED_0D, 0xc0 },
418};
419
420static int tas2552_codec_probe(struct snd_soc_codec *codec) 440static 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
467patch_fail:
468 pm_runtime_put(codec->dev);
469probe_fail: 479probe_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,