/*
 * sound/soc/dropcam.c
 *
 * Author: Cao Rongrong <rrcao@ambarella.com>
 *
 * History:
 *	2009/08/20 - [Cao Rongrong] Created file
 *	2011/03/20 - [Cao Rongrong] Port to 2.6.38,
 *				    merge coconut and durian into dropcam
 *
 * Copyright (C) 2004-2009, Ambarella, Inc.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include <linux/platform_device.h>
#include <linux/delay.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>

#include <mach/hardware.h>
#include <plat/audio.h>

#include "../codecs/wm8974_amb.h"

static unsigned int dai_fmt = 0;
module_param(dai_fmt, uint, 0644);
MODULE_PARM_DESC(dai_fmt, "DAI format.");

static int dropcam_board_startup(struct snd_pcm_substream *substream)
{
	return 0;
}

static int dropcam_board_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 errorCode = 0, amb_mclk, mclk, oversample, i2s_mode;

	switch (params_rate(params)) {
	case 8000:
		amb_mclk = AudioCodec_2_048M;
		mclk = 2048000;
		oversample = AudioCodec_256xfs;
		break;
	case 11025:
		amb_mclk = AudioCodec_2_8224M;
		mclk = 2822400;
		oversample = AudioCodec_256xfs;
		break;
	case 12000:
		amb_mclk = AudioCodec_3_072M;
		mclk = 3072000;
		oversample = AudioCodec_256xfs;
		break;
	case 16000:
		amb_mclk = AudioCodec_4_096M;
		mclk = 4096000;
		oversample = AudioCodec_256xfs;
		break;
	case 22050:
		amb_mclk = AudioCodec_5_6448M;
		mclk = 5644800;
		oversample = AudioCodec_256xfs;
		break;
	case 24000:
		amb_mclk = AudioCodec_6_144;
		mclk = 6144000;
		oversample = AudioCodec_256xfs;
		break;
	case 32000:
		amb_mclk = AudioCodec_8_192M;
		mclk = 8192000;
		oversample = AudioCodec_256xfs;
		break;
	case 44100:
		amb_mclk = AudioCodec_11_2896M;
		mclk = 11289600;
		oversample = AudioCodec_256xfs;
		break;
	case 48000:
		amb_mclk = AudioCodec_12_288M;
		mclk = 12288000;
		oversample = AudioCodec_256xfs;
		break;
	default:
		errorCode = -EINVAL;
		goto hw_params_exit;
	}

	if (dai_fmt == 0)
		i2s_mode = SND_SOC_DAIFMT_I2S;
	else
		i2s_mode = SND_SOC_DAIFMT_DSP_A;

	/* set the I2S system data format*/
	errorCode = snd_soc_dai_set_fmt(codec_dai,
		i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
	if (errorCode < 0) {
		pr_err("can't set codec DAI configuration\n");
		goto hw_params_exit;
	}

	errorCode = snd_soc_dai_set_fmt(cpu_dai,
		i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
	if (errorCode < 0) {
		pr_err("can't set cpu DAI configuration\n");
		goto hw_params_exit;
	}

	/* set the I2S system clock*/
	errorCode = snd_soc_dai_set_sysclk(codec_dai, WM8974_SYSCLK, mclk, 0);
	if (errorCode < 0) {
		pr_err("can't set cpu MCLK configuration\n");
		goto hw_params_exit;
	}

	errorCode = snd_soc_dai_set_sysclk(cpu_dai, AMBARELLA_CLKSRC_ONCHIP, amb_mclk, 0);
	if (errorCode < 0) {
		pr_err("can't set cpu MCLK configuration\n");
		goto hw_params_exit;
	}

	errorCode = snd_soc_dai_set_clkdiv(cpu_dai, AMBARELLA_CLKDIV_LRCLK, oversample);
	if (errorCode < 0) {
		pr_err("can't set cpu MCLK/SF ratio\n");
		goto hw_params_exit;
	}

hw_params_exit:
	return errorCode;
}

static struct snd_soc_ops dropcam_board_ops = {
	.startup = dropcam_board_startup,
	.hw_params = dropcam_board_hw_params,
};

/* dropcam machine dapm widgets */
static const struct snd_soc_dapm_widget dropcam_dapm_widgets[] = {
	SND_SOC_DAPM_MIC("Mic External", NULL),
	SND_SOC_DAPM_SPK("Speaker", NULL),
};

/* dropcam machine audio map (connections to wm8974 pins) */
static const struct snd_soc_dapm_route dropcam_audio_map[] = {
  /*Mic External is connected to MICN , MICP, AUX*/
  {"MICN", NULL, "Mic External"},
  {"MICP", NULL, "Mic External"},
  {"AUX", NULL, "Mic External"},
  /* Speaker is connected to SPP, SPN */
  {"Speaker", NULL, "SPKOUTP"},
  {"Speaker", NULL, "SPKOUTN"},
  {"Speaker", NULL, "MONOOUT"},
};

static int dropcam_wm8974_init(struct snd_soc_pcm_runtime *rtd)
{
	int errorCode = 0;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	/* not connected */
	//snd_soc_dapm_nc_pin(dapm, "MONOOUT");
	//snd_soc_dapm_nc_pin(dapm, "AUX");

	/* Add dropcam specific widgets */
	errorCode = snd_soc_dapm_new_controls(dapm,
		dropcam_dapm_widgets,
		ARRAY_SIZE(dropcam_dapm_widgets));
	if (errorCode) {
		goto init_exit;
	}

	/* Set up dropcam specific audio path dropcam_audio_map */
	errorCode = snd_soc_dapm_add_routes(dapm,
		dropcam_audio_map,
		ARRAY_SIZE(dropcam_audio_map));
	if (errorCode) {
		goto init_exit;
	}

	errorCode = snd_soc_dapm_sync(dapm);

init_exit:
	return errorCode;
}

/* dropcam digital audio interface glue - connects codec <--> A2S */
static struct snd_soc_dai_link dropcam_dai_link = {
	.name = "WM8974",
	.stream_name = "WM8974-STREAM",
	.cpu_dai_name = "ambarella-i2s.0",
	.platform_name = "ambarella-pcm-audio",
	.codec_dai_name = "wm8974-hifi",
	.codec_name = "wm8974-codec.0-001a",
	.init = dropcam_wm8974_init,
	.ops = &dropcam_board_ops,
};


/* dropcam audio machine driver */
static struct snd_soc_card snd_soc_card_dropcam = {
	.name = "DROPCAM",
	.dai_link = &dropcam_dai_link,
	.num_links = 1,
};

static struct platform_device *dropcam_snd_device;

static int __init dropcam_board_init(void)
{
	int errorCode = 0;

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

	platform_set_drvdata(dropcam_snd_device, &snd_soc_card_dropcam);

	errorCode = platform_device_add(dropcam_snd_device);
	if (errorCode) {
		goto dropcam_board_init_exit;
	}

	return 0;

dropcam_board_init_exit:
	platform_device_put(dropcam_snd_device);
	return errorCode;
}

static void __exit dropcam_board_exit(void)
{
	platform_device_unregister(dropcam_snd_device);
}

module_init(dropcam_board_init);
module_exit(dropcam_board_exit);

MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
MODULE_DESCRIPTION("Dropcam Crown Royal Board with WM8974 Codec for ALSA");
MODULE_LICENSE("GPL");

