/*
 * sound/soc/PJ203.c
 *
 * Author: Diao Chengdong <cddiao@ambarella.com>
 *
 * History:
 *    2012/05/17 - [Diao Chengdong] Created file
 *
 * 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/module.h>
#include <linux/moduleparam.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
#include <mach/gpio.h>
#include <plat/audio.h>

#include "ambarella_i2s.h"
#include "../codecs/tlv320dac31.h"

#define debug_pj203 (0)
#if debug_pj203
#define PRINTK(arg...) printk(arg)
#else
#define PRINTK(arg...)
#endif

/*  havn't test the headphone ,so set gpio_jack = 0*/
#define GPIO_JACK  0

#if GPIO_JACK
module_param(gpio_jack,uint,S_IRUGO);
MODULE_PARM_DESC(gpio_jack,"Whether or not use a head phone.");
/* Headset jack */
static struct snd_soc_jack hs_jack;
/* Headset jack detection DAPM pins */
static struct snd_soc_jack_pin hs_jack_pins[]={
	{
		.pin = "Headset Mic",
		.mask = SND_JACK_MICROPHONE,
	},
	{
		.pin = "Headset Stereophone",
		.mask = SND_JACK_HEADPHONE,
	},
};
/* Headset jack detection gpios */
static struct snd_soc_jack_gpio hs_jack_gpios[]={
	{
		.gpio = GPIO(82),
		.name = "hsdet-gpio",
		.report = SND_JACK_HEADSET,
		.debounce_time = 200,
	},
};
#endif

static const struct snd_soc_dapm_widget PJ203_dapm_widgets[] = {
	/*Output*/
	SND_SOC_DAPM_SPK("Main Spk", NULL),
#if GPIO_JACK
	SND_SOC_DAPM_HP("Headphone Jack",NULL),
#endif
};

static const struct snd_soc_dapm_route PJ203_dapm_routes[] = {
#if GPIO_JACK
	{"Headphone Jack",NULL,"HPL"},
	{"Headphone Jack",NULL,"HPR"},
#endif
	{"Main Spk",NULL,"LOL"},
	{"Main Spk",NULL,"LOL"},
};

static int PJ203_tlv320_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	PRINTK("in tlv320_init\n");
	snd_soc_dapm_new_controls(dapm,PJ203_dapm_widgets,
			ARRAY_SIZE(PJ203_dapm_widgets));

	snd_soc_dapm_add_routes(dapm,PJ203_dapm_routes,
			ARRAY_SIZE(PJ203_dapm_routes));

	snd_soc_dapm_sync(dapm);

	ambarella_i2s_add_controls(codec);

#if GPIO_JACK
{
	int errcode=0;
	errcode = snd_soc_jack_new(codec,"Headset Jack",SND_JACK_HEADSET,&hs_jack);
	if (errcode)
		return errcode;
	errcode = snd_soc_jack_add_pins(&hs_jack,ARRAY_SIZE(hs_jack_pins),hs_jack_pins);
	if (errcode)
		return errcode;
	errcode = snd_soc_jack_add_gpios(&hs_jack,ARRAY_SIZE(hs_jack_gpios),hs_jack_gpios);
	if (errcode)
		return errcode;
}
#endif

	return 0;
}


static int PJ203_board_startup(struct snd_pcm_substream *substream)
{
	PRINTK("in PJ203_board-statup\n");
	return 0;
}

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

	PRINTK("in PJ203_hifi_hw_params\n");
	switch (params_rate(params)) {
	case 8000:
		amb_mclk = AudioCodec_4_096M;
		mclk = 4096000;
		oversample = AudioCodec_512xfs;
		break;
	case 11025:
		amb_mclk = AudioCodec_5_6448M;
		mclk = 5644800;
		oversample = AudioCodec_512xfs;
		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 hifi_hw_params_exit;
	}

	errorCode = snd_soc_dai_set_fmt(codec_dai,
		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
	if (errorCode < 0) {
		pr_err("can't set codec DAI configuration\n");
		goto hifi_hw_params_exit;
	}
	errorCode = snd_soc_dai_set_fmt(cpu_dai,
		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
	if (errorCode < 0) {
		pr_err("can't set cpu DAI configuration\n");
		goto hifi_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 hifi_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 hifi_hw_params_exit;
	}
	errorCode = snd_soc_dai_set_sysclk(codec_dai, 1, mclk, 0);
	if (errorCode < 0) {
		pr_err("can't set cpu MCLK configuration\n");
		goto hifi_hw_params_exit;
	}

hifi_hw_params_exit:
	return errorCode;
}

static struct snd_soc_ops PJ203_hifi_ops = {
	.startup = PJ203_board_startup,
	.hw_params = PJ203_hifi_hw_params,
};

static struct snd_soc_dai_link PJ203_dai_link[] = {
	{
	.name = "dac31amb",
	.stream_name = "TLV320 HiFi",
	.cpu_dai_name = "ambarella-i2s.0",
	.codec_dai_name = "tlv320dac31",
	.platform_name = "ambarella-pcm-audio",
	.codec_name = "tlv320dac31-codec.0-0018",
	.init = PJ203_tlv320_init,
	.ops = &PJ203_hifi_ops,
	}
};

static struct snd_soc_card snd_soc_card_PJ203 = {
	.name      = "PJ203",
	.dai_link  = PJ203_dai_link,
	.num_links = 1,
};

static struct platform_device *PJ203_snd_device;

static int __init PJ203_board_init(void)
{
	int errCode = 0;
	PJ203_snd_device = platform_device_alloc("soc-audio",-1);
	if (!PJ203_snd_device) {
		pr_err("failed in device alloc \n");
		return -ENOMEM;
	}

	platform_set_drvdata(PJ203_snd_device,&snd_soc_card_PJ203);

	errCode = platform_device_add(PJ203_snd_device);
	if (errCode)
		goto PJ203_board_init_exit;
	PRINTK("success in PJ203_board_init\n");
	return 0;

PJ203_board_init_exit:
	platform_device_put(PJ203_snd_device);
	return errCode;
}

static void __exit PJ203_board_exit(void)
{
#if GPIO_JACK
	snd_soc_jack_free_gpios(&hs_jack,ARRAY_SIZE(hs_jack_gpios),hs_jack_gpios);
#endif
	platform_device_unregister(PJ203_snd_device);
}

module_init(PJ203_board_init);
module_exit(PJ203_board_exit);

MODULE_AUTHOR("Diao Chengdong <cddiao@ambarella.com>");
MODULE_DESCRIPTION("Ambarella PJ203 Board with tlv320DAC3100 Codec for ALSA");
MODULE_LICENSE("GPL");
