#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
+
+#include <mach/harmony_audio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#define PREFIX DRV_NAME ": "
struct tegra_harmony {
+ struct harmony_audio_platform_data *pdata;
+ int gpio_spkr_en_requested;
};
static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
.hw_params = harmony_asoc_hw_params,
};
+static int harmony_event_int_spk(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_harmony *harmony = snd_soc_card_get_drvdata(card);
+ struct harmony_audio_platform_data *pdata = harmony->pdata;
+
+ gpio_set_value_cansleep(pdata->gpio_spkr_en,
+ !!SND_SOC_DAPM_EVENT_ON(event));
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = {
+ SND_SOC_DAPM_SPK("Int Spk", harmony_event_int_spk),
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Mic Jack", NULL),
};
static const struct snd_soc_dapm_route harmony_audio_map[] = {
{"Headphone Jack", NULL, "HPOUTR"},
{"Headphone Jack", NULL, "HPOUTL"},
+ {"Int Spk", NULL, "ROP"},
+ {"Int Spk", NULL, "RON"},
+ {"Int Spk", NULL, "LOP"},
+ {"Int Spk", NULL, "LON"},
{"Mic Bias", NULL, "Mic Jack"},
{"IN1L", NULL, "Mic Bias"},
};
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_card *card = codec->card;
+ struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
+ struct harmony_audio_platform_data *pdata = harmony->pdata;
+ int ret;
+
+ ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
+ if (ret) {
+ dev_err(card->dev, "cannot get spkr_en gpio\n");
+ return ret;
+ }
+ harmony->gpio_spkr_en_requested = 1;
+
+ gpio_direction_output(pdata->gpio_spkr_en, 0);
snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets,
ARRAY_SIZE(harmony_dapm_widgets));
ARRAY_SIZE(harmony_audio_map));
snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Int Spk");
snd_soc_dapm_enable_pin(dapm, "Mic Jack");
snd_soc_dapm_sync(dapm);
{
struct snd_soc_card *card = &snd_soc_harmony;
struct tegra_harmony *harmony;
+ struct harmony_audio_platform_data *pdata;
int ret;
if (!machine_is_harmony()) {
return -ENODEV;
}
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data supplied\n");
+ return -EINVAL;
+ }
+
harmony = kzalloc(sizeof(struct tegra_harmony), GFP_KERNEL);
if (!harmony) {
dev_err(&pdev->dev, "Can't allocate tegra_harmony\n");
return -ENOMEM;
}
+ harmony->pdata = pdata;
+
ret = tegra_asoc_utils_init();
if (ret)
goto err_free_harmony;
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
+ struct harmony_audio_platform_data *pdata = harmony->pdata;
snd_soc_unregister_card(card);
tegra_asoc_utils_fini();
+ if (harmony->gpio_spkr_en_requested)
+ gpio_free(pdata->gpio_spkr_en);
+
kfree(harmony);
return 0;