Chromium Code Reviews| Index: sound/soc/tegra/seaboard.c |
| diff --git a/sound/soc/tegra/seaboard.c b/sound/soc/tegra/seaboard.c |
| index 67e1fb08e5056a9ce946696ac6a4911218223898..70442e24f96901c1ac1008a86cd19c54af50b408 100644 |
| --- a/sound/soc/tegra/seaboard.c |
| +++ b/sound/soc/tegra/seaboard.c |
| @@ -32,6 +32,7 @@ |
| #include <linux/module.h> |
| #include <linux/platform_device.h> |
| +#include <linux/regulator/consumer.h> |
| #include <linux/slab.h> |
| #include <linux/gpio.h> |
| @@ -59,6 +60,8 @@ struct tegra_seaboard { |
| struct tegra_asoc_utils_data util_data; |
| struct seaboard_audio_platform_data *pdata; |
| int gpio_requested; |
| + struct regulator *vdd_dmic; |
| + bool first_dmic_event; |
|
jiesun
2011/04/25 18:21:04
I understand this is for preventing regulator_disa
Stephen Warren
2011/04/25 22:27:41
The issue isn't continual interleaving; it's a sta
|
| }; |
| static int seaboard_asoc_hw_params(struct snd_pcm_substream *substream, |
| @@ -229,11 +232,32 @@ static int seaboard_event_hp(struct snd_soc_dapm_widget *w, |
| return 0; |
| } |
| + |
| +static int seaboard_event_dmic(struct snd_soc_dapm_widget *w, |
| + struct snd_kcontrol *k, int event) |
| +{ |
| + struct snd_soc_codec *codec = w->codec; |
| + struct snd_soc_card *card = codec->card; |
| + struct tegra_seaboard *seaboard = snd_soc_card_get_drvdata(card); |
| + |
| + if (IS_ERR(seaboard->vdd_dmic)) |
| + return 0; |
| + |
| + if (SND_SOC_DAPM_EVENT_ON(event)) { |
| + return regulator_enable(seaboard->vdd_dmic); |
| + } else { |
| + if (!seaboard->first_dmic_event) |
| + return regulator_disable(seaboard->vdd_dmic); |
| + } |
| + |
| + seaboard->first_dmic_event = false; |
| +} |
| + |
| static const struct snd_soc_dapm_widget seaboard_dapm_widgets[] = { |
| SND_SOC_DAPM_SPK("Int Spk", seaboard_event_int_spk), |
| SND_SOC_DAPM_HP("Headphone Jack", seaboard_event_hp), |
| SND_SOC_DAPM_MIC("Mic Jack", NULL), |
| - SND_SOC_DAPM_MIC("Digital Mic", NULL), |
| + SND_SOC_DAPM_MIC("Digital Mic", seaboard_event_dmic), |
| }; |
| static const struct snd_soc_dapm_route seaboard_audio_map[] = { |
| @@ -425,6 +449,15 @@ static __devinit int tegra_snd_seaboard_probe(struct platform_device *pdev) |
| if (ret) |
| goto err_free_seaboard; |
| + seaboard->vdd_dmic = regulator_get(&pdev->dev, "vdd_dmic"); |
| + if (IS_ERR(seaboard->vdd_dmic)) { |
| + dev_info(&pdev->dev, "regulator_get() returned error %ld\n", |
| + PTR_ERR(seaboard->vdd_dmic)); |
| + ret = PTR_ERR(seaboard->vdd_dmic); |
| + goto err_fini_utils; |
| + } |
| + seaboard->first_dmic_event = true; |
| + |
| card->dev = &pdev->dev; |
| platform_set_drvdata(pdev, card); |
| snd_soc_card_set_drvdata(card, seaboard); |
| @@ -442,6 +475,7 @@ err_clear_drvdata: |
| snd_soc_card_set_drvdata(card, NULL); |
| platform_set_drvdata(pdev, NULL); |
| card->dev = NULL; |
|
jiesun
2011/04/25 18:21:04
missing a regulator_put here.
|
| +err_fini_utils: |
| tegra_asoc_utils_fini(&seaboard->util_data); |
| err_free_seaboard: |
| kfree(seaboard); |
| @@ -460,6 +494,8 @@ static int __devexit tegra_snd_seaboard_remove(struct platform_device *pdev) |
| platform_set_drvdata(pdev, NULL); |
| card->dev = NULL; |
| + regulator_put(seaboard->vdd_dmic); |
| + |
| tegra_asoc_utils_fini(&seaboard->util_data); |
| if (seaboard->gpio_requested & GPIO_HP_MUTE) |