/*
 * aquila_wm8994.c
 *
 * Copyright (C) 2010 Samsung Electronics Co.Ltd
 * Author: Chanwoo Choi <cw00.choi@samsung.com>
 *
 *  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 <linux/moduleparam.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
#include <mach/gpio.h>
#include <mach/regs-clock.h>

#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
#include "../codecs/wm8994.h"
#include "s3c-dma.h"
#include "s3c64xx-i2s.h"

static struct snd_soc_card aquila;
static struct platform_device *aquila_snd_device;

/* 3.5 pie jack */
static struct snd_soc_jack jack;

/* 3.5 pie jack detection DAPM pins */
static struct snd_soc_jack_pin jack_pins[] = {
	{
		.pin = "Headset Mic",
		.mask = SND_JACK_MICROPHONE,
	}, {
		.pin = "Headset Stereophone",
		.mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL |
			SND_JACK_AVOUT,
	},
};

/* 3.5 pie jack detection gpios */
static struct snd_soc_jack_gpio jack_gpios[] = {
	{
		.gpio = S5PV210_GPH0(6),
		.name = "DET_3.5",
		.report = SND_JACK_HEADSET | SND_JACK_MECHANICAL |
			SND_JACK_AVOUT,
		.debounce_time = 200,
	},
};

static const struct snd_soc_dapm_widget aquila_dapm_widgets[] = {
	SND_SOC_DAPM_SPK("Ext Spk", NULL),
	SND_SOC_DAPM_SPK("Ext Rcv", NULL),
	SND_SOC_DAPM_HP("Headset Stereophone", NULL),
	SND_SOC_DAPM_MIC("Headset Mic", NULL),
	SND_SOC_DAPM_MIC("Main Mic", NULL),
	SND_SOC_DAPM_MIC("2nd Mic", NULL),
	SND_SOC_DAPM_LINE("Radio In", NULL),
};

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

	{"Ext Rcv", NULL, "HPOUT2N"},
	{"Ext Rcv", NULL, "HPOUT2P"},

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

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

	{"IN1RN", NULL, "2nd Mic"},
	{"IN1RP", NULL, "2nd Mic"},

	{"IN1LN", NULL, "Main Mic"},
	{"IN1LP", NULL, "Main Mic"},

	{"IN2LN", NULL, "Radio In"},
	{"IN2RN", NULL, "Radio In"},
};

static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	int ret;

	/* add aquila specific widgets */
	snd_soc_dapm_new_controls(codec, aquila_dapm_widgets,
			ARRAY_SIZE(aquila_dapm_widgets));

	/* set up aquila specific audio routes */
	snd_soc_dapm_add_routes(codec, aquila_dapm_routes,
			ARRAY_SIZE(aquila_dapm_routes));

	/* set endpoints to not connected */
	snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN");
	snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP");
	snd_soc_dapm_nc_pin(codec, "LINEOUT1N");
	snd_soc_dapm_nc_pin(codec, "LINEOUT1P");
	snd_soc_dapm_nc_pin(codec, "LINEOUT2N");
	snd_soc_dapm_nc_pin(codec, "LINEOUT2P");
	snd_soc_dapm_nc_pin(codec, "SPKOUTRN");
	snd_soc_dapm_nc_pin(codec, "SPKOUTRP");

	snd_soc_dapm_sync(codec);

	/* Headset jack detection */
	ret = snd_soc_jack_new(&aquila, "Headset Jack",
			SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
			&jack);
	if (ret)
		return ret;

	ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
	if (ret)
		return ret;

	ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
	if (ret)
		return ret;

	return 0;
}

static int aquila_hifi_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;
	unsigned int pll_out = 24000000;
	int ret = 0;

	/* set the cpu DAI configuration */
	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* set the cpu system clock */
	ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
			0, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	/* set codec DAI configuration */
	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* set the codec FLL */
	ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out,
			params_rate(params) * 256);
	if (ret < 0)
		return ret;

	/* set the codec system clock */
	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
			params_rate(params) * 256, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return 0;
}

static struct snd_soc_ops aquila_hifi_ops = {
	.hw_params = aquila_hifi_hw_params,
};

static int aquila_voice_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;
	unsigned int pll_out = 24000000;
	int ret = 0;

	if (params_rate(params) != 8000)
		return -EINVAL;

	/* set codec DAI configuration */
	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
			SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* set the codec FLL */
	ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out,
			params_rate(params) * 256);
	if (ret < 0)
		return ret;

	/* set the codec system clock */
	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
			params_rate(params) * 256, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return 0;
}

static struct snd_soc_dai_driver voice_dai = {
	.name = "aquila-voice-dai",
	.playback = {
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
	.capture = {
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
};

static struct snd_soc_ops aquila_voice_ops = {
	.hw_params = aquila_voice_hw_params,
};

static struct snd_soc_dai_link aquila_dai[] = {
{
	.name = "WM8994",
	.stream_name = "WM8994 HiFi",
	.cpu_dai_name = "s3c64xx-i2s-v4",
	.codec_dai_name = "wm8994-hifi",
	.platform_name = "s3c24xx-pcm-audio",
	.codec_name = "wm8994-codec.0-0x1a",
	.init = aquila_wm8994_init,
	.ops = &aquila_hifi_ops,
}, {
	.name = "WM8994 Voice",
	.stream_name = "Voice",
	.cpu_dai_name = "aquila-voice-dai",
	.codec_dai_name = "wm8994-voice",
	.platform_name = "s3c24xx-pcm-audio",
	.codec_name = "wm8994-codec.0-0x1a",
	.ops = &aquila_voice_ops,
},
};

static struct snd_soc_card aquila = {
	.name = "aquila",
	.dai_link = aquila_dai,
	.num_links = ARRAY_SIZE(aquila_dai),
};

static int __init aquila_init(void)
{
	int ret;

	if (!machine_is_aquila())
		return -ENODEV;

	aquila_snd_device = platform_device_alloc("soc-audio", -1);
	if (!aquila_snd_device)
		return -ENOMEM;

	/* register voice DAI here */
	ret = snd_soc_register_dai(&aquila_snd_device->dev, &voice_dai);
	if (ret)
		return ret;

	platform_set_drvdata(aquila_snd_device, &aquila);
	ret = platform_device_add(aquila_snd_device);

	if (ret)
		platform_device_put(aquila_snd_device);

	return ret;
}

static void __exit aquila_exit(void)
{
	platform_device_unregister(aquila_snd_device);
}

module_init(aquila_init);
module_exit(aquila_exit);

/* Module information */
MODULE_DESCRIPTION("ALSA SoC WM8994 Aquila(S5PC110)");
MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
MODULE_LICENSE("GPL");
