mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
ASoC: tegra-alt: Add kcontrols for SFC output rate
1. Add kcontrols to vary SFC output rate 2. Rename d_audio to ahub clock during xbar probe Bug 1442940 Change-Id: If86bd476822c6cfe07af8fbc7d7ead8b21e2a7d2 Signed-off-by: Arun Shamanna Lakshmi <aruns@nvidia.com> Reviewed-on: http://git-master/r/417232 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Songhee Baek <sbaek@nvidia.com> Reviewed-by: Rahul Mittal <rmittal@nvidia.com> Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>
This commit is contained in:
committed by
Sameer Pujar
parent
790ac51a9d
commit
318dc455c5
@@ -72,11 +72,57 @@ static int tegra210_sfc_set_dai_sysclk(struct snd_soc_dai *dai,
|
|||||||
int clk_id, unsigned int freq, int dir)
|
int clk_id, unsigned int freq, int dir)
|
||||||
{
|
{
|
||||||
struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
|
struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
|
||||||
|
unsigned int value;
|
||||||
|
|
||||||
|
switch (freq) {
|
||||||
|
case 8000:
|
||||||
|
value = TEGRA210_SFC_FS8;
|
||||||
|
break;
|
||||||
|
case 11025:
|
||||||
|
value = TEGRA210_SFC_FS11_025;
|
||||||
|
break;
|
||||||
|
case 16000:
|
||||||
|
value = TEGRA210_SFC_FS16;
|
||||||
|
break;
|
||||||
|
case 22050:
|
||||||
|
value = TEGRA210_SFC_FS22_05;
|
||||||
|
break;
|
||||||
|
case 24000:
|
||||||
|
value = TEGRA210_SFC_FS24;
|
||||||
|
break;
|
||||||
|
case 32000:
|
||||||
|
value = TEGRA210_SFC_FS32;
|
||||||
|
break;
|
||||||
|
case 44100:
|
||||||
|
value = TEGRA210_SFC_FS44_1;
|
||||||
|
break;
|
||||||
|
case 48000:
|
||||||
|
value = TEGRA210_SFC_FS48;
|
||||||
|
break;
|
||||||
|
case 64000:
|
||||||
|
value = TEGRA210_SFC_FS64;
|
||||||
|
break;
|
||||||
|
case 88200:
|
||||||
|
value = TEGRA210_SFC_FS88_2;
|
||||||
|
break;
|
||||||
|
case 96000:
|
||||||
|
value = TEGRA210_SFC_FS96;
|
||||||
|
break;
|
||||||
|
case 176400:
|
||||||
|
value = TEGRA210_SFC_FS176_4;
|
||||||
|
break;
|
||||||
|
case 192000:
|
||||||
|
value = TEGRA210_SFC_FS192;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value = TEGRA210_SFC_FS8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (dir == SND_SOC_CLOCK_OUT)
|
if (dir == SND_SOC_CLOCK_OUT)
|
||||||
sfc->srate_out = freq;
|
sfc->srate_out = value;
|
||||||
else if (dir == SND_SOC_CLOCK_IN)
|
else if (dir == SND_SOC_CLOCK_IN)
|
||||||
sfc->srate_in = freq;
|
sfc->srate_in = value;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -125,7 +171,6 @@ static int tegra210_sfc_in_hw_params(struct snd_pcm_substream *substream,
|
|||||||
{
|
{
|
||||||
struct device *dev = dai->dev;
|
struct device *dev = dai->dev;
|
||||||
struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
|
struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
|
||||||
unsigned int value;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = tegra210_sfc_set_audio_cif(sfc, params,
|
ret = tegra210_sfc_set_audio_cif(sfc, params,
|
||||||
@@ -135,52 +180,7 @@ static int tegra210_sfc_in_hw_params(struct snd_pcm_substream *substream,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sfc->srate_in) {
|
regmap_write(sfc->regmap, TEGRA210_SFC_AXBAR_RX_FREQ, sfc->srate_in);
|
||||||
case 8000:
|
|
||||||
value = TEGRA210_SFC_FS8;
|
|
||||||
break;
|
|
||||||
case 11025:
|
|
||||||
value = TEGRA210_SFC_FS11_025;
|
|
||||||
break;
|
|
||||||
case 16000:
|
|
||||||
value = TEGRA210_SFC_FS16;
|
|
||||||
break;
|
|
||||||
case 22050:
|
|
||||||
value = TEGRA210_SFC_FS22_05;
|
|
||||||
break;
|
|
||||||
case 24000:
|
|
||||||
value = TEGRA210_SFC_FS24;
|
|
||||||
break;
|
|
||||||
case 32000:
|
|
||||||
value = TEGRA210_SFC_FS32;
|
|
||||||
break;
|
|
||||||
case 44100:
|
|
||||||
value = TEGRA210_SFC_FS44_1;
|
|
||||||
break;
|
|
||||||
case 48000:
|
|
||||||
value = TEGRA210_SFC_FS48;
|
|
||||||
break;
|
|
||||||
case 64000:
|
|
||||||
value = TEGRA210_SFC_FS64;
|
|
||||||
break;
|
|
||||||
case 88200:
|
|
||||||
value = TEGRA210_SFC_FS88_2;
|
|
||||||
break;
|
|
||||||
case 96000:
|
|
||||||
value = TEGRA210_SFC_FS96;
|
|
||||||
break;
|
|
||||||
case 176400:
|
|
||||||
value = TEGRA210_SFC_FS176_4;
|
|
||||||
break;
|
|
||||||
case 192000:
|
|
||||||
value = TEGRA210_SFC_FS192;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
value = TEGRA210_SFC_FS8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
regmap_write(sfc->regmap, TEGRA210_SFC_AXBAR_RX_FREQ, value);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,6 @@ static int tegra210_sfc_out_hw_params(struct snd_pcm_substream *substream,
|
|||||||
{
|
{
|
||||||
struct device *dev = dai->dev;
|
struct device *dev = dai->dev;
|
||||||
struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
|
struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
|
||||||
unsigned int value;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = tegra210_sfc_set_audio_cif(sfc, params,
|
ret = tegra210_sfc_set_audio_cif(sfc, params,
|
||||||
@@ -199,55 +198,41 @@ static int tegra210_sfc_out_hw_params(struct snd_pcm_substream *substream,
|
|||||||
dev_err(dev, "Can't set SFC TX CIF: %d\n", ret);
|
dev_err(dev, "Can't set SFC TX CIF: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
switch (sfc->srate_out) {
|
|
||||||
case 8000:
|
if (sfc->srate_out < 0) {
|
||||||
value = TEGRA210_SFC_FS8;
|
dev_err(dev, "SFC%d output rate not set: %d\n",
|
||||||
break;
|
dev->id, -EINVAL);
|
||||||
case 11025:
|
return -EINVAL;
|
||||||
value = TEGRA210_SFC_FS11_025;
|
|
||||||
break;
|
|
||||||
case 16000:
|
|
||||||
value = TEGRA210_SFC_FS16;
|
|
||||||
break;
|
|
||||||
case 22050:
|
|
||||||
value = TEGRA210_SFC_FS22_05;
|
|
||||||
break;
|
|
||||||
case 24000:
|
|
||||||
value = TEGRA210_SFC_FS24;
|
|
||||||
break;
|
|
||||||
case 32000:
|
|
||||||
value = TEGRA210_SFC_FS32;
|
|
||||||
break;
|
|
||||||
case 44100:
|
|
||||||
value = TEGRA210_SFC_FS44_1;
|
|
||||||
break;
|
|
||||||
case 48000:
|
|
||||||
value = TEGRA210_SFC_FS48;
|
|
||||||
break;
|
|
||||||
case 64000:
|
|
||||||
value = TEGRA210_SFC_FS64;
|
|
||||||
break;
|
|
||||||
case 88200:
|
|
||||||
value = TEGRA210_SFC_FS88_2;
|
|
||||||
break;
|
|
||||||
case 96000:
|
|
||||||
value = TEGRA210_SFC_FS96;
|
|
||||||
break;
|
|
||||||
case 176400:
|
|
||||||
value = TEGRA210_SFC_FS176_4;
|
|
||||||
break;
|
|
||||||
case 192000:
|
|
||||||
value = TEGRA210_SFC_FS192;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
value = TEGRA210_SFC_FS8;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
regmap_write(sfc->regmap, TEGRA210_SFC_AXBAR_TX_FREQ, value);
|
regmap_write(sfc->regmap, TEGRA210_SFC_AXBAR_TX_FREQ, sfc->srate_out);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tegra210_sfc_get_srate(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||||
|
struct tegra210_sfc *sfc = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
|
/* get the sfc output rate */
|
||||||
|
ucontrol->value.integer.value[0] = sfc->srate_out + 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tegra210_sfc_put_srate(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||||
|
struct tegra210_sfc *sfc = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
|
/* update the sfc output rate */
|
||||||
|
sfc->srate_out = ucontrol->value.integer.value[0] - 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int tegra210_sfc_codec_probe(struct snd_soc_codec *codec)
|
static int tegra210_sfc_codec_probe(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
struct tegra210_sfc *sfc = snd_soc_codec_get_drvdata(codec);
|
struct tegra210_sfc *sfc = snd_soc_codec_get_drvdata(codec);
|
||||||
@@ -310,12 +295,39 @@ static const struct snd_soc_dapm_route tegra210_sfc_routes[] = {
|
|||||||
{ "SFC Transmit", NULL, "SFC TX" },
|
{ "SFC Transmit", NULL, "SFC TX" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * const tegra210_sfc_srate_text[] = {
|
||||||
|
"None",
|
||||||
|
"8kHz",
|
||||||
|
"11kHz",
|
||||||
|
"16kHz",
|
||||||
|
"22kHz",
|
||||||
|
"24kHz",
|
||||||
|
"32kHz",
|
||||||
|
"44kHz",
|
||||||
|
"48kHz",
|
||||||
|
"64kHz",
|
||||||
|
"88kHz",
|
||||||
|
"96kHz",
|
||||||
|
"176kHz",
|
||||||
|
"192kHz",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct soc_enum tegra210_sfc_srate =
|
||||||
|
SOC_ENUM_SINGLE_EXT(14, tegra210_sfc_srate_text);
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new tegra210_sfc_controls[] = {
|
||||||
|
SOC_ENUM_EXT("output rate", tegra210_sfc_srate,
|
||||||
|
tegra210_sfc_get_srate, tegra210_sfc_put_srate),
|
||||||
|
};
|
||||||
|
|
||||||
static struct snd_soc_codec_driver tegra210_sfc_codec = {
|
static struct snd_soc_codec_driver tegra210_sfc_codec = {
|
||||||
.probe = tegra210_sfc_codec_probe,
|
.probe = tegra210_sfc_codec_probe,
|
||||||
.dapm_widgets = tegra210_sfc_widgets,
|
.dapm_widgets = tegra210_sfc_widgets,
|
||||||
.num_dapm_widgets = ARRAY_SIZE(tegra210_sfc_widgets),
|
.num_dapm_widgets = ARRAY_SIZE(tegra210_sfc_widgets),
|
||||||
.dapm_routes = tegra210_sfc_routes,
|
.dapm_routes = tegra210_sfc_routes,
|
||||||
.num_dapm_routes = ARRAY_SIZE(tegra210_sfc_routes),
|
.num_dapm_routes = ARRAY_SIZE(tegra210_sfc_routes),
|
||||||
|
.controls = tegra210_sfc_controls,
|
||||||
|
.num_controls = ARRAY_SIZE(tegra210_sfc_controls),
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool tegra210_sfc_wr_reg(struct device *dev, unsigned int reg)
|
static bool tegra210_sfc_wr_reg(struct device *dev, unsigned int reg)
|
||||||
@@ -459,7 +471,7 @@ static int tegra210_sfc_platform_probe(struct platform_device *pdev)
|
|||||||
sfc->soc_data = soc_data;
|
sfc->soc_data = soc_data;
|
||||||
|
|
||||||
/* initialize default output srate */
|
/* initialize default output srate */
|
||||||
sfc->srate_out = 48000;
|
sfc->srate_out = TEGRA210_SFC_FS48;
|
||||||
|
|
||||||
#ifndef CONFIG_MACH_GRENADA
|
#ifndef CONFIG_MACH_GRENADA
|
||||||
sfc->clk_sfc = devm_clk_get(&pdev->dev, NULL);
|
sfc->clk_sfc = devm_clk_get(&pdev->dev, NULL);
|
||||||
|
|||||||
@@ -810,9 +810,9 @@ static int tegra210_xbar_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
xbar->soc_data = soc_data;
|
xbar->soc_data = soc_data;
|
||||||
|
|
||||||
xbar->clk = devm_clk_get(&pdev->dev, "d_audio");
|
xbar->clk = devm_clk_get(&pdev->dev, "ahub");
|
||||||
if (IS_ERR(xbar->clk)) {
|
if (IS_ERR(xbar->clk)) {
|
||||||
dev_err(&pdev->dev, "Can't retrieve clock\n");
|
dev_err(&pdev->dev, "Can't retrieve ahub clock\n");
|
||||||
ret = PTR_ERR(xbar->clk);
|
ret = PTR_ERR(xbar->clk);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -826,7 +826,7 @@ static int tegra210_xbar_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
parent_clk = clk_get_parent(xbar->clk);
|
parent_clk = clk_get_parent(xbar->clk);
|
||||||
if (IS_ERR(parent_clk)) {
|
if (IS_ERR(parent_clk)) {
|
||||||
dev_err(&pdev->dev, "Can't get parent clock fo xbar\n");
|
dev_err(&pdev->dev, "Can't get parent clock for xbar\n");
|
||||||
ret = PTR_ERR(parent_clk);
|
ret = PTR_ERR(parent_clk);
|
||||||
goto err_clk_put;
|
goto err_clk_put;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user