/*
 * linux/sound/soc/pxa/brownstone.c
 *
 * Copyright (C) 2011 Marvell International Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 */

#include <linux/module.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/jack.h>

#include "../codecs/wm8994.h"
#include "mmp-sspa.h"

static const struct snd_kcontrol_new brownstone_dapm_control[] = {
	SOC_DAPM_PIN_SWITCH("Ext Spk"),
};

static const struct snd_soc_dapm_widget brownstone_dapm_widgets[] = {
	SND_SOC_DAPM_SPK("Ext Spk", NULL),
	SND_SOC_DAPM_HP("Headset Stereophone", NULL),
	SND_SOC_DAPM_MIC("Headset Mic", NULL),
	SND_SOC_DAPM_MIC("Main Mic", NULL),
};

static const struct snd_soc_dapm_route brownstone_audio_map[] = {
	{"Ext Spk", NULL, "SPKOUTLP"},
	{"Ext Spk", NULL, "SPKOUTLN"},
	{"Ext Spk", NULL, "SPKOUTRP"},
	{"Ext Spk", NULL, "SPKOUTRN"},

	{"Headset Stereophone", NULL, "HPOUT1L"},
	{"Headset Stereophone", NULL, "HPOUT1R"},

	{"IN1RN", NULL, "Headset Mic"},

	{"DMIC1DAT", NULL, "MICBIAS1"},
	{"MICBIAS1", NULL, "Main Mic"},
};

static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
				       struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	int freq_out, sspa_mclk, sysclk;

	if (params_rate(params) > 11025) {
		freq_out  = params_rate(params) * 512;
		sysclk    = params_rate(params) * 256;
		sspa_mclk = params_rate(params) * 64;
	} else {
		freq_out  = params_rate(params) * 1024;
		sysclk    = params_rate(params) * 512;
		sspa_mclk = params_rate(params) * 64;
	}

	snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
	snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
	snd_soc_dai_set_pll(cpu_dai, MMP_SSPA_CLK, 0, freq_out, sspa_mclk);

	/* set wm8994 sysclk */
	snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, sysclk, 0);

	return 0;
}

/* machine stream operations */
static const struct snd_soc_ops brownstone_ops = {
	.hw_params = brownstone_wm8994_hw_params,
};

static struct snd_soc_dai_link brownstone_wm8994_dai[] = {
{
	.name		= "WM8994",
	.stream_name	= "WM8994 HiFi",
	.cpu_dai_name	= "mmp-sspa-dai.0",
	.codec_dai_name	= "wm8994-aif1",
	.platform_name	= "mmp-pcm-audio",
	.codec_name	= "wm8994-codec",
	.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
				SND_SOC_DAIFMT_CBS_CFS,
	.ops		= &brownstone_ops,
},
};

/* audio machine driver */
static struct snd_soc_card brownstone = {
	.name         = "brownstone",
	.owner        = THIS_MODULE,
	.dai_link     = brownstone_wm8994_dai,
	.num_links    = ARRAY_SIZE(brownstone_wm8994_dai),

	.controls = brownstone_dapm_control,
	.num_controls = ARRAY_SIZE(brownstone_dapm_control),
	.dapm_widgets = brownstone_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(brownstone_dapm_widgets),
	.dapm_routes = brownstone_audio_map,
	.num_dapm_routes = ARRAY_SIZE(brownstone_audio_map),
	.fully_routed = true,
};

static int brownstone_probe(struct platform_device *pdev)
{
	int ret;

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

static struct platform_driver mmp_driver = {
	.driver		= {
		.name	= "brownstone-audio",
		.pm     = &snd_soc_pm_ops,
	},
	.probe		= brownstone_probe,
};

module_platform_driver(mmp_driver);

MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
MODULE_DESCRIPTION("ALSA SoC Brownstone");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:brownstone-audio");
