ASoC: tegra-alt: fix dspk driver issues

- Make the primary dais to be in sync with other ahub drivers
by renaming it to DAP/CIF, this would remove the dependency on
the link name dspk-playback-l/r for dspk and can use any generic
name.

- The second dais which was used for dual mono codec path can
avoid using the dai_ops callback, as there is no need of calling
hw_params, set_bclk etc.. multiple times per pcm_open. Only the
primary dai with name DAP will be used for callbacks.

- Support S32_LE format support for the dais.

- Change SND_SOC_DAPM_AIF_IN to SND_SOC_DAPM_AIF_OUT as the dspk is
audio output interface.

- Add proper DAPM route entry to machine driver and remove any check
 with dspk-playback-l to make it more generic usage.

- Cleanup aud_mclk parent configuration

Bug 200525217

Change-Id: I3a718f72ea0b442a7cf1716540e79d69a05a220a
Signed-off-by: Mohan Kumar <mkumard@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2133518
(cherry picked from commit a3233ef7bc78953a264c2729ace9ea0a0da59814)
Reviewed-on: https://git-master.nvidia.com/r/2145942
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Dara Ramesh <dramesh@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Mohan Kumar
2019-06-10 15:45:14 +05:30
committed by Sameer Pujar
parent bb5f984534
commit f1e0181664
5 changed files with 57 additions and 118 deletions

View File

@@ -54,7 +54,6 @@ struct tegra_asoc_audio_clock_info {
struct clk *clk_cdev1;
struct clk *clk_ahub;
struct reset_control *clk_cdev1_rst;
struct clk *clk_m;
struct clk *clk_pll_p_out1;
int set_mclk;
int lock_count;
@@ -76,9 +75,6 @@ void tegra_alt_asoc_utils_lock_clk_rate(
int lock);
int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
struct device *dev, struct snd_soc_card *card);
int tegra_alt_asoc_utils_set_extern_parent(
struct tegra_asoc_audio_clock_info *data, const char *parent);
int tegra_alt_asoc_utils_clk_enable(struct tegra_asoc_audio_clock_info *data);
int tegra_alt_asoc_utils_clk_disable(struct tegra_asoc_audio_clock_info *data);
int tegra_alt_asoc_utils_register_ctls(struct tegra_asoc_audio_clock_info *data);

View File

@@ -245,6 +245,7 @@ static const struct snd_soc_dapm_widget tegra_machine_dapm_widgets[] = {
SND_SOC_DAPM_SPK("d1 Headphone", NULL),
SND_SOC_DAPM_SPK("d2 Headphone", NULL),
SND_SOC_DAPM_SPK("d3 Headphone", NULL),
SND_SOC_DAPM_HP("w Headphone", NULL),
SND_SOC_DAPM_HP("x Headphone", NULL),
@@ -730,22 +731,6 @@ static int tegra_machine_suspend_pre(struct snd_soc_card *card)
return 0;
}
static int tegra_machine_dspk_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct snd_soc_dapm_context *dapm = &card->dapm;
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
int err;
err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
"pll_a_out0");
if (err < 0)
dev_err(card->dev, "Failed to set extern clk parent\n");
snd_soc_dapm_sync(dapm);
return err;
}
#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
static int tegra_machine_compr_startup(struct snd_compr_stream *cstream)
{
@@ -824,17 +809,9 @@ static int tegra_machine_fepi_init(struct snd_soc_pcm_runtime *rtd)
static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
struct snd_soc_jack *jack;
int err;
err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
"pll_a_out0");
if (err < 0) {
dev_err(card->dev, "Failed to set extern clk parent\n");
return err;
}
jack = devm_kzalloc(card->dev, sizeof(struct snd_soc_jack), GFP_KERNEL);
if (!jack)
return -ENOMEM;
@@ -923,14 +900,6 @@ static void dai_link_setup(struct platform_device *pdev)
tegra_machine_codec_links[i].init =
tegra_machine_rt565x_init;
}
} else if (strstr(tegra_machine_codec_links[i].name,
"dspk-playback-r")) {
tegra_machine_codec_links[i].init =
tegra_machine_dspk_init;
} else if (strstr(tegra_machine_codec_links[i].name,
"dspk-playback-l")) {
tegra_machine_codec_links[i].init =
tegra_machine_dspk_init;
} else if (strstr(tegra_machine_codec_links[i].name,
"fe-pi-audio-z-v2")) {
tegra_machine_codec_links[i].init =

View File

@@ -271,70 +271,75 @@ static struct snd_soc_dai_ops tegra186_dspk_dai_ops = {
.shutdown = tegra186_dspk_shutdown,
};
static struct snd_soc_dai_driver tegra186_dspk_dais[] = {
/* for left channel audio */
{
.name = "DAP Left",
.capture = {
.stream_name = "DSPK Left Transmit",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.ops = &tegra186_dspk_dai_ops,
.symmetric_rates = 1,
},
{
.name = "CIF Right",
.playback = {
.stream_name = "DSPK Receive Right",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.ops = &tegra186_dspk_dai_ops,
.symmetric_rates = 1,
},
static struct snd_soc_dai_ops tegra186_dspk_dai_ops2 = {
.set_bclk_ratio = tegra186_dspk_set_dai_bclk_ratio,
};
/* for right channel audio */
static struct snd_soc_dai_driver tegra186_dspk_dais[] = {
{
.name = "DAP Right",
.name = "DAP",
.capture = {
.stream_name = "DSPK Right Transmit",
.stream_name = "DAP Transmit",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
.ops = &tegra186_dspk_dai_ops,
.symmetric_rates = 1,
},
{
.name = "CIF Left",
.name = "CIF",
.playback = {
.stream_name = "DSPK Receive Left",
.stream_name = "CIF Receive",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
.ops = &tegra186_dspk_dai_ops,
},
/* The second DAI is used when the output of the DSPK is connected
* to two mono codecs. When the output of the DSPK is connected to
* a single stereo codec, then only the first DAI should be used.
*/
{
.name = "DAP2",
.capture = {
.stream_name = "DAP2 Transmit",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
.ops = &tegra186_dspk_dai_ops2,
.symmetric_rates = 1,
},
{
.name = "CIF2",
.playback = {
.stream_name = "CIF2 Receive",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
}
};
static const struct snd_soc_dapm_widget tegra186_dspk_widgets[] = {
SND_SOC_DAPM_AIF_IN("DSPK TX1", NULL, 0, TEGRA186_DSPK_ENABLE, 0, 0),
SND_SOC_DAPM_AIF_IN("DSPK TX2", NULL, 0, TEGRA186_DSPK_ENABLE, 0, 0),
SND_SOC_DAPM_AIF_OUT("DAP TX", NULL, 0, TEGRA186_DSPK_ENABLE, 0, 0),
SND_SOC_DAPM_AIF_OUT("DAP2 TX", NULL, 0, 0, 0, 0),
};
static const struct snd_soc_dapm_route tegra186_dspk_routes[] = {
{ "DSPK TX1", NULL, "DSPK Receive Left" },
{ "DSPK Left Transmit", NULL, "DSPK TX1" },
{ "DSPK TX2", NULL, "DSPK Receive Right" },
{ "DSPK Right Transmit", NULL, "DSPK TX2" },
{ "DAP TX", NULL, "CIF Receive" },
{ "DAP Transmit", NULL, "DAP TX" },
{ "DAP2 TX", NULL, "CIF2 Receive" },
{ "DAP2 Transmit", NULL, "DAP2 TX" },
};
static const char * const tegra186_dspk_osr_text[] = {

View File

@@ -3221,9 +3221,7 @@ struct snd_soc_dai_link *tegra_machine_new_codec_links(
/* special case to handle specifically for dspk, connected to
two mono amplifiers */
if (!strcmp(tegra_codec_links[i].name, "dspk-playback-r"))
tegra_codec_links[i].cpu_dai_name = "DAP Right";
else if (!strcmp(tegra_codec_links[i].name, "dspk-playback-l"))
tegra_codec_links[i].cpu_dai_name = "DAP Left";
tegra_codec_links[i].cpu_dai_name = "DAP2";
else
tegra_codec_links[i].cpu_dai_name = "DAP";
@@ -3289,9 +3287,7 @@ struct snd_soc_dai_link *tegra_machine_new_codec_links(
}
if (!strcmp(tegra_codec_links[i].name, "dspk-playback-r"))
tegra_codec_links[j].codec_dai_name = "CIF Right";
else if (!strcmp(tegra_codec_links[i].name, "dspk-playback-l"))
tegra_codec_links[j].codec_dai_name = "CIF Left";
tegra_codec_links[j].codec_dai_name = "CIF2";
else
tegra_codec_links[j].codec_dai_name = "CIF";

View File

@@ -187,6 +187,8 @@ EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_clk_disable);
int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
struct device *dev, struct snd_soc_card *card)
{
int ret;
data->dev = dev;
data->card = card;
@@ -201,12 +203,6 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
/* DT boot, but unknown SoC */
return -EINVAL;
data->clk_m = devm_clk_get(dev, "clk_m");
if (IS_ERR(data->clk_m)) {
dev_err(data->dev, "Can't retrieve clk clk_m\n");
return PTR_ERR(data->clk_m);
}
data->clk_pll_a = devm_clk_get(dev, "pll_a");
if (IS_ERR(data->clk_pll_a)) {
dev_err(data->dev, "Can't retrieve clk pll_a\n");
@@ -231,7 +227,7 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
*/
data->clk_mclk_parent = devm_clk_get(dev, "mclk_parent");
if (IS_ERR(data->clk_mclk_parent))
dev_dbg(data->dev, "Can't retrieve mclk parent clk\n");
data->clk_mclk_parent = data->clk_pll_a_out0;
if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) {
data->clk_ahub = devm_clk_get(dev, "ahub");
@@ -252,39 +248,16 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
reset_control_reset(data->clk_cdev1_rst);
}
ret = clk_set_parent(data->clk_cdev1, data->clk_mclk_parent);
if (ret < 0) {
dev_err(card->dev, "Failed to set extern clk parent\n");
return ret;
}
return 0;
}
EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_init);
int tegra_alt_asoc_utils_set_extern_parent(
struct tegra_asoc_audio_clock_info *data, const char *parent)
{
unsigned long rate;
int err = 0;
rate = clk_get_rate(data->clk_cdev1);
if (!IS_ERR(data->clk_mclk_parent))
err = clk_set_parent(data->clk_cdev1, data->clk_mclk_parent);
else if (!strcmp(parent, "clk_m"))
err = clk_set_parent(data->clk_cdev1, data->clk_m);
else if (!strcmp(parent, "pll_a_out0"))
err = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0);
if (err) {
dev_err(data->dev, "Can't set aud mclk clock parent");
return err;
}
err = clk_set_rate(data->clk_cdev1, rate);
if (err) {
dev_err(data->dev, "Can't set clk rate");
return err;
}
return 0;
}
EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_set_extern_parent);
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("Tegra ASoC utility code");
MODULE_LICENSE("GPL");