[alsa-devel] [PATCH] ASoC: Tegra: Add support of tegra boards based on ALC5632 codec
Stephen Warren
swarren at nvidia.com
Wed Nov 23 22:50:39 CET 2011
Leon Romanovsky wrote at Monday, November 21, 2011 1:08 PM:
> At this stage only Toshiba AC100/Dynabook supported.
...
> diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
...
> +config SND_SOC_TEGRA_ALC5632
> + tristate "SoC Audio support for Tegra boards using an ALC5632 codec"
> + depends on SND_SOC_TEGRA && I2C
> + select SND_SOC_TEGRA_I2S
> + select SND_SOC_ALC5632
> + help
> + Say Y or M here if you want to add support for SoC audio on the
> + Toshiba AC100 netbook.
If this is going to be named tegra_acl5632 rather than something board-
specific such as tegra_paz00, then perhaps you should do Kconfig the
same way as the tegra_wm8903 driver; have a MACH_HAS_SND_SOC_TEGRA_ALC5632
variable that boards need to select, and make this depend on that?
> diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
...
> +static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params)
...
> + srate = params_rate(params);
> + switch (srate) {
> + case 64000:
> + case 88200:
> + case 96000:
> + mclk = 128 * srate;
> + break;
> + default:
> + mclk = 512 * srate;
> + break;
> + }
> + /* FIXME: Codec only requires >= 3MHz if OSR==0 */
> + while (mclk < 6000000)
> + mclk *= 2;
That is identical to the code in tegra_wm8903. Are you sure it's correct
for the ALC5632? At the very least, I think the comment is wrong; OSR is
a WM8903 register field, which I doubt exists on the ALC5632.
> + err = snd_soc_dai_set_fmt(cpu_dai,
> + SND_SOC_DAIFMT_I2S |
> + SND_SOC_DAIFMT_NB_NF |
> + SND_SOC_DAIFMT_CBS_CFS);
> + if (err < 0) {
> + dev_err(card->dev, "cpu_dai fmt not set\n");
> + return err;
> + }
> +
> + err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
> + SND_SOC_CLOCK_IN);
> + if (err < 0) {
> + dev_err(card->dev, "codec_dai clock not set\n");
> + return err;
> + }
Mark Brown wrote here:
> These should use the .dai_fmt member in the dai_link struct.
Mark, I guess you mean that we should remove those two snd_soc_dai_set_fmt
calls, and just set .dai_fmt to a constant value? If so, that should be
applied to the other two Tegra machine drivers too.
That said, while these values are constant right now, I think they won't
always be; I think we'll need to switch between DSP mode for mono and
I2S mode for stereo here; at least I /think/ that's what I remember our
downstream drivers doing...
> +static struct snd_soc_jack_gpio tegra_alc5632_hs_jack_gpios[] = {
> + {
> + .name = "Headset Detect",
> + .report = SND_JACK_HEADSET,
> + .debounce_time = 150,
> + }
> +};
You probably don't want to make this an array, since that'll make the
code that fills in tegra_alc5632_hs_jack_gpio [0].gpio have to hard-code
the "0" array index; better to make this just:
static struct snd_soc_jack_gpio tegra_alc5632_hs_jack_gpio = {
.name = "Headset Detect",
.report = SND_JACK_HEADSET,
.debounce_time = 150,
};
And then you can assign tegra_alc5632_hs_jack_gpio.gpio.
> +static const struct snd_soc_dapm_route tegra_alc5632_audio_map[] = {
> + /* Internal Mic */
> + {"MIC2", NULL, "Mic Bias 2"},
> + {"Mic Bias 2", NULL, "Int Mic"},
Yay, a separate mic bias for each microphone:-)
> +static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
...
> + snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
> + &tegra_alc5632_hs_jack);
> + snd_soc_jack_add_pins(&tegra_alc5632_hs_jack,
> + ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
> + tegra_alc5632_hs_jack_pins);
> + snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
> + ARRAY_SIZE(tegra_alc5632_hs_jack_gpios),
> + tegra_alc5632_hs_jack_gpios);
Do you need to call something in the ALC5632 codec driver here to start
mic detection? The tegra_wm8903 driver calls wm8903_mic_detect() here.
> + snd_soc_dapm_nc_pin(dapm, "AUXOUT");
> + snd_soc_dapm_nc_pin(dapm, "LINEINL");
> + snd_soc_dapm_nc_pin(dapm, "LINEINR");
> + snd_soc_dapm_nc_pin(dapm, "PHONEP");
> + snd_soc_dapm_nc_pin(dapm, "PHONEN");
> + snd_soc_dapm_nc_pin(dapm, "MIC2");
----------==========----------==========----------==========----------==========
You may be able to remove that if you set snd_soc_tegra_alc5632.fully_routed.
The patch for that was just merged into Mark's ASoC tree.
> +static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
...
> + alc5632 = kzalloc(sizeof(struct tegra_alc5632), GFP_KERNEL);
If you use devm_kzalloc there, it'll remove the need to manually free
it; see the very latest tegra_wm8903 driver.
> +err_clear_drvdata:
> + snd_soc_card_set_drvdata(card, NULL);
> + platform_set_drvdata(pdev, NULL);
> + card->dev = NULL;
There's no need for those last 3 lines.
> + tegra_asoc_utils_fini(&alc5632->util_data);
> +err_free_tegra_alc5632:
> + kfree(alc5632);
That kfree is what you could get rid of using devm_kzalloc.
> +static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
...
> + snd_soc_card_set_drvdata(card, NULL);
> + platform_set_drvdata(pdev, NULL);
> + card->dev = NULL;
Same here; no need for those last 3 lines.
> + tegra_asoc_utils_fini(&alc5632->util_data);
> +
> + kfree(alc5632);
That's another thing you could remove if using devm_kzalloc.
...
> +MODULE_LICENSE("GPL");
The comment at the top would imply "GPL v2", since no "or later" is
mentioned there. Yes, the existing Tegra code is probably wrong here too.
--
nvpublic
More information about the Alsa-devel
mailing list