/*
 * SiRF audio card driver
 *
 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
 *
 * Licensed under GPLv2 or later.
 */

#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>

struct sirf_audio_card {
	unsigned int            gpio_hp_pa;
	unsigned int            gpio_spk_pa;
};

static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w,
				struct snd_kcontrol *ctrl, int event)
{
	struct snd_soc_dapm_context *dapm = w->dapm;
	struct snd_soc_card *card = dapm->card;
	struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card);
	int on = !SND_SOC_DAPM_EVENT_OFF(event);

	if (gpio_is_valid(sirf_audio_card->gpio_hp_pa))
		gpio_set_value(sirf_audio_card->gpio_hp_pa, on);
	return 0;
}

static int sirf_audio_spk_event(struct snd_soc_dapm_widget *w,
				struct snd_kcontrol *ctrl, int event)
{
	struct snd_soc_dapm_context *dapm = w->dapm;
	struct snd_soc_card *card = dapm->card;
	struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card);
	int on = !SND_SOC_DAPM_EVENT_OFF(event);

	if (gpio_is_valid(sirf_audio_card->gpio_spk_pa))
		gpio_set_value(sirf_audio_card->gpio_spk_pa, on);

	return 0;
}
static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets[] = {
	SND_SOC_DAPM_HP("Hp", sirf_audio_hp_event),
	SND_SOC_DAPM_SPK("Ext Spk", sirf_audio_spk_event),
	SND_SOC_DAPM_MIC("Ext Mic", NULL),
};

static const struct snd_soc_dapm_route intercon[] = {
	{"Hp", NULL, "HPOUTL"},
	{"Hp", NULL, "HPOUTR"},
	{"Ext Spk", NULL, "SPKOUT"},
	{"MICIN1", NULL, "Mic Bias"},
	{"Mic Bias", NULL, "Ext Mic"},
};

/* Digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link sirf_audio_dai_link[] = {
	{
		.name = "SiRF audio card",
		.stream_name = "SiRF audio HiFi",
		.codec_dai_name = "sirf-audio-codec",
	},
};

/* Audio machine driver */
static struct snd_soc_card snd_soc_sirf_audio_card = {
	.name = "SiRF audio card",
	.owner = THIS_MODULE,
	.dai_link = sirf_audio_dai_link,
	.num_links = ARRAY_SIZE(sirf_audio_dai_link),
	.dapm_widgets = sirf_audio_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(sirf_audio_dapm_widgets),
	.dapm_routes = intercon,
	.num_dapm_routes = ARRAY_SIZE(intercon),
};

static int sirf_audio_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_sirf_audio_card;
	struct sirf_audio_card *sirf_audio_card;
	int ret;

	sirf_audio_card = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_card),
			GFP_KERNEL);
	if (sirf_audio_card == NULL)
		return -ENOMEM;

	sirf_audio_dai_link[0].cpu_of_node =
		of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0);
	sirf_audio_dai_link[0].platform_of_node =
		of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0);
	sirf_audio_dai_link[0].codec_of_node =
		of_parse_phandle(pdev->dev.of_node, "sirf,audio-codec", 0);
	sirf_audio_card->gpio_spk_pa = of_get_named_gpio(pdev->dev.of_node,
			"spk-pa-gpios", 0);
	sirf_audio_card->gpio_hp_pa =  of_get_named_gpio(pdev->dev.of_node,
			"hp-pa-gpios", 0);
	if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) {
		ret = devm_gpio_request_one(&pdev->dev,
				sirf_audio_card->gpio_spk_pa,
				GPIOF_OUT_INIT_LOW, "SPA_PA_SD");
		if (ret) {
			dev_err(&pdev->dev,
				"Failed to request GPIO_%d for reset: %d\n",
				sirf_audio_card->gpio_spk_pa, ret);
			return ret;
		}
	}
	if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) {
		ret = devm_gpio_request_one(&pdev->dev,
				sirf_audio_card->gpio_hp_pa,
				GPIOF_OUT_INIT_LOW, "HP_PA_SD");
		if (ret) {
			dev_err(&pdev->dev,
				"Failed to request GPIO_%d for reset: %d\n",
				sirf_audio_card->gpio_hp_pa, ret);
			return ret;
		}
	}

	card->dev = &pdev->dev;
	snd_soc_card_set_drvdata(card, sirf_audio_card);

	ret = devm_snd_soc_register_card(&pdev->dev, card);
	if (ret)
		dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret);

	return ret;
}

static const struct of_device_id sirf_audio_of_match[] = {
	{.compatible = "sirf,sirf-audio-card", },
	{ },
};
MODULE_DEVICE_TABLE(of, sirf_audio_of_match);

static struct platform_driver sirf_audio_driver = {
	.driver = {
		.name = "sirf-audio-card",
		.pm = &snd_soc_pm_ops,
		.of_match_table = sirf_audio_of_match,
	},
	.probe = sirf_audio_probe,
};
module_platform_driver(sirf_audio_driver);

MODULE_AUTHOR("RongJun Ying <RongJun.Ying@csr.com>");
MODULE_DESCRIPTION("ALSA SoC SIRF audio card driver");
MODULE_LICENSE("GPL v2");
