/*
 * mx27vis_wm8974.c  --  SoC audio for mx27vis
 *
 * Copyright 2009 Vista Silicon S.L.
 * Author: Javier Martin
 *         javier.martin@vista-silicon.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/device.h>
#include <linux/i2c.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>


#include "../codecs/wm8974.h"
#include "mx1_mx2-pcm.h"
#include "mxc-ssi.h"
#include <mach/gpio.h>
#include <mach/iomux.h>

#define IGNORED_ARG 0


static struct snd_soc_card mx27vis;

/**
  * This function connects SSI1 (HPCR1) as slave to
  * SSI1 external signals (PPCR1)
  * As slave, HPCR1 must set TFSDIR and TCLKDIR as inputs from
  * port 4
  */
void audmux_connect_1_4(void)
{
	pr_debug("AUDMUX: normal operation mode\n");
	/* Reset HPCR1 and PPCR1 */

	DAM_HPCR1 = 0x00000000;
	DAM_PPCR1 = 0x00000000;

	/* set to synchronous */
	DAM_HPCR1 |= AUDMUX_HPCR_SYN;
	DAM_PPCR1 |= AUDMUX_PPCR_SYN;


	/* set Rx sources 1 <--> 4 */
	DAM_HPCR1 |= AUDMUX_HPCR_RXDSEL(3); /* port 4 */
	DAM_PPCR1 |= AUDMUX_PPCR_RXDSEL(0); /* port 1 */

	/* set Tx frame and Clock direction and source  4 --> 1 output */
	DAM_HPCR1 |= AUDMUX_HPCR_TFSDIR | AUDMUX_HPCR_TCLKDIR;
	DAM_HPCR1 |= AUDMUX_HPCR_TFCSEL(3); /* TxDS and TxCclk from port 4 */

	return;
}

static int mx27vis_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->dai->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
	unsigned int pll_out = 0, bclk = 0, fmt = 0, mclk = 0;
	int ret = 0;

	/*
	 * The WM8974 is better at generating accurate audio clocks than the
	 * MX27 SSI controller, so we will use it as master when we can.
	 */
	switch (params_rate(params)) {
	case 8000:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		mclk = WM8974_MCLKDIV_12;
		pll_out = 24576000;
		break;
	case 16000:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		pll_out = 12288000;
		break;
	case 48000:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		bclk = WM8974_BCLKDIV_4;
		pll_out = 12288000;
		break;
	case 96000:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		bclk = WM8974_BCLKDIV_2;
		pll_out = 12288000;
		break;
	case 11025:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		bclk = WM8974_BCLKDIV_16;
		pll_out = 11289600;
		break;
	case 22050:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		bclk = WM8974_BCLKDIV_8;
		pll_out = 11289600;
		break;
	case 44100:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		bclk = WM8974_BCLKDIV_4;
		mclk = WM8974_MCLKDIV_2;
		pll_out = 11289600;
		break;
	case 88200:
		fmt = SND_SOC_DAIFMT_CBM_CFM;
		bclk = WM8974_BCLKDIV_2;
		pll_out = 11289600;
		break;
	}

	/* set codec DAI configuration */
	ret = codec_dai->ops->set_fmt(codec_dai,
		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
		SND_SOC_DAIFMT_SYNC | fmt);
	if (ret < 0) {
		printk(KERN_ERR "Error from codec DAI configuration\n");
		return ret;
	}

	/* set cpu DAI configuration */
	ret = cpu_dai->ops->set_fmt(cpu_dai,
		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
		SND_SOC_DAIFMT_SYNC | fmt);
	if (ret < 0) {
		printk(KERN_ERR "Error from cpu DAI configuration\n");
		return ret;
	}

	/* Put DC field of STCCR to 1 (not zero) */
	ret = cpu_dai->ops->set_tdm_slot(cpu_dai, 0, 2);

	/* set the SSI system clock as input */
	ret = cpu_dai->ops->set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
		SND_SOC_CLOCK_IN);
	if (ret < 0) {
		printk(KERN_ERR "Error when setting system SSI clk\n");
		return ret;
	}

	/* set codec BCLK division for sample rate */
	ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_BCLKDIV, bclk);
	if (ret < 0) {
		printk(KERN_ERR "Error when setting BCLK division\n");
		return ret;
	}


	/* codec PLL input is 25 MHz */
	ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG,
					25000000, pll_out);
	if (ret < 0) {
		printk(KERN_ERR "Error when setting PLL input\n");
		return ret;
	}

	/*set codec MCLK division for sample rate */
	ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_MCLKDIV, mclk);
	if (ret < 0) {
		printk(KERN_ERR "Error when setting MCLK division\n");
		return ret;
	}

	return 0;
}

static int mx27vis_hifi_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;

	/* disable the PLL */
	return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 0, 0);
}

/*
 * mx27vis WM8974 HiFi DAI opserations.
 */
static struct snd_soc_ops mx27vis_hifi_ops = {
	.hw_params = mx27vis_hifi_hw_params,
	.hw_free = mx27vis_hifi_hw_free,
};


static int mx27vis_suspend(struct platform_device *pdev, pm_message_t state)
{
	return 0;
}

static int mx27vis_resume(struct platform_device *pdev)
{
	return 0;
}

static int mx27vis_probe(struct platform_device *pdev)
{
	int ret = 0;

	ret = get_ssi_clk(0, &pdev->dev);

	if (ret < 0) {
		printk(KERN_ERR "%s: cant get ssi clock\n", __func__);
		return ret;
	}


	return 0;
}

static int mx27vis_remove(struct platform_device *pdev)
{
	put_ssi_clk(0);
	return 0;
}

static struct snd_soc_dai_link mx27vis_dai[] = {
{ /* Hifi Playback*/
	.name = "WM8974",
	.stream_name = "WM8974 HiFi",
	.cpu_dai = &imx_ssi_pcm_dai[0],
	.codec_dai = &wm8974_dai,
	.ops = &mx27vis_hifi_ops,
},
};

static struct snd_soc_card mx27vis = {
	.name = "mx27vis",
	.platform = &mx1_mx2_soc_platform,
	.probe = mx27vis_probe,
	.remove = mx27vis_remove,
	.suspend_pre = mx27vis_suspend,
	.resume_post = mx27vis_resume,
	.dai_link = mx27vis_dai,
	.num_links = ARRAY_SIZE(mx27vis_dai),
};

static struct snd_soc_device mx27vis_snd_devdata = {
	.card = &mx27vis,
	.codec_dev = &soc_codec_dev_wm8974,
};

static struct platform_device *mx27vis_snd_device;

/* Temporal definition of board specific behaviour */
void gpio_ssi_active(int ssi_num)
{
	int ret = 0;

	unsigned int ssi1_pins[] = {
		PC20_PF_SSI1_FS,
		PC21_PF_SSI1_RXD,
		PC22_PF_SSI1_TXD,
		PC23_PF_SSI1_CLK,
	};
	unsigned int ssi2_pins[] = {
		PC24_PF_SSI2_FS,
		PC25_PF_SSI2_RXD,
		PC26_PF_SSI2_TXD,
		PC27_PF_SSI2_CLK,
	};
	if (ssi_num == 0)
		ret = mxc_gpio_setup_multiple_pins(ssi1_pins,
				ARRAY_SIZE(ssi1_pins), "USB OTG");
	else
		ret = mxc_gpio_setup_multiple_pins(ssi2_pins,
				ARRAY_SIZE(ssi2_pins), "USB OTG");
	if (ret)
		printk(KERN_ERR "Error requesting ssi %x pins\n", ssi_num);
}


static int __init mx27vis_init(void)
{
	int ret;

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

	platform_set_drvdata(mx27vis_snd_device, &mx27vis_snd_devdata);
	mx27vis_snd_devdata.dev = &mx27vis_snd_device->dev;
	ret = platform_device_add(mx27vis_snd_device);

	if (ret) {
		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
		platform_device_put(mx27vis_snd_device);
	}

	/* WM8974 uses SSI1 (HPCR1) via AUDMUX port 4 for audio (PPCR1) */
	gpio_ssi_active(0);
	audmux_connect_1_4();

	return ret;
}

static void __exit mx27vis_exit(void)
{
	/* We should call some "ssi_gpio_inactive()" properly */
}

module_init(mx27vis_init);
module_exit(mx27vis_exit);


MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
MODULE_DESCRIPTION("ALSA SoC WM8974 mx27vis");
MODULE_LICENSE("GPL");
