/*
 * ALSA SoC HMDI codec driver
 *
 * Author: Ricardo Neri <ricardo.neri@ti.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>

#include <plat/omap_hwmod.h>
#include <video/omapdss.h>
#include <video/hdmi_ti_4xxx_ip.h>

#include "../../../drivers/video/omap2/dss/dss_features.h"
#include "../../../drivers/video/omap2/dss/dss.h"

#define HDMI_WP		0x0
#define HDMI_CORE_SYS	0x400
#define HDMI_CORE_AV	0x900
#define HDMI_PLLCTRL	0x200
#define HDMI_PHY	0x300

/* hdmi configuration params */
struct hdmi_params {
	int format;
	int sample_freq;
	int channels_nr;
};


/* codec private data */
struct hdmi_codec_data {
	struct hdmi_audio_format audio_fmt;
	struct hdmi_audio_dma audio_dma;
	struct hdmi_core_audio_config audio_core_cfg;
	struct hdmi_core_infoframe_audio aud_if_cfg;
	struct hdmi_ip_data ip_data;
	struct omap_hwmod *oh;
	struct omap_dss_device *dssdev;
	struct notifier_block notifier;
	struct hdmi_params params;
	int active;
} hdmi_data;


static int hdmi_audio_set_configuration(struct hdmi_codec_data *priv)
{
	struct hdmi_audio_format *audio_format = &priv->audio_fmt;
	struct hdmi_audio_dma *audio_dma = &priv->audio_dma;
	struct hdmi_core_audio_config *core_cfg = &priv->audio_core_cfg;
	struct hdmi_core_infoframe_audio *aud_if_cfg = &priv->aud_if_cfg;
	int err, n, cts, channel_alloc;
	enum hdmi_core_audio_sample_freq sample_freq;
	u32 pclk = omapdss_hdmi_get_pixel_clock();

	switch (priv->params.format) {
	case SNDRV_PCM_FORMAT_S16_LE:
		core_cfg->i2s_cfg.word_max_length =
			HDMI_AUDIO_I2S_MAX_WORD_20BITS;
		core_cfg->i2s_cfg.word_length =
					HDMI_AUDIO_I2S_CHST_WORD_16_BITS;
		core_cfg->i2s_cfg.in_length_bits =
			HDMI_AUDIO_I2S_INPUT_LENGTH_16;
		core_cfg->i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
		audio_format->samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
		audio_format->sample_size = HDMI_AUDIO_SAMPLE_16BITS;
		audio_format->justification = HDMI_AUDIO_JUSTIFY_LEFT;
		audio_dma->transfer_size = 0x10;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		core_cfg->i2s_cfg.word_max_length =
			HDMI_AUDIO_I2S_MAX_WORD_24BITS;
		core_cfg->i2s_cfg.word_length =
					HDMI_AUDIO_I2S_CHST_WORD_24_BITS;
		core_cfg->i2s_cfg.in_length_bits =
			HDMI_AUDIO_I2S_INPUT_LENGTH_24;
		audio_format->samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
		audio_format->sample_size = HDMI_AUDIO_SAMPLE_24BITS;
		audio_format->justification = HDMI_AUDIO_JUSTIFY_RIGHT;
		core_cfg->i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
		audio_dma->transfer_size = 0x20;
		break;
	default:
		return -EINVAL;
	}


	switch (priv->params.sample_freq) {
	case 32000:
		sample_freq = HDMI_AUDIO_FS_32000;
		break;
	case 44100:
		sample_freq = HDMI_AUDIO_FS_44100;
		break;
	case 48000:
		sample_freq = HDMI_AUDIO_FS_48000;
		break;
	default:
		return -EINVAL;
	}

	err = hdmi_ti_4xxx_config_audio_acr(&priv->ip_data,
			priv->params.sample_freq, &n, &cts, pclk);
	if (err < 0)
		return err;

	/* Audio wrapper config */
	audio_format->type = HDMI_AUDIO_TYPE_LPCM;
	audio_format->sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
	/* Disable start/stop signals of IEC 60958 blocks */
	audio_format->en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF;

	audio_dma->block_size = 0xC0;
	audio_dma->mode = HDMI_AUDIO_TRANSF_DMA;
	audio_dma->fifo_threshold = 0x20; /* in number of samples */

	hdmi_ti_4xxx_wp_audio_config_dma(&priv->ip_data, audio_dma);
	hdmi_ti_4xxx_wp_audio_config_format(&priv->ip_data, audio_format);

	/*
	 * I2S config
	 */
	core_cfg->i2s_cfg.en_high_bitrate_aud = false;
	/* Only used with high bitrate audio */
	core_cfg->i2s_cfg.cbit_order = false;
	/* Serial data and word select should change on sck rising edge */
	core_cfg->i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
	core_cfg->i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
	/* Set I2S word select polarity */
	core_cfg->i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT;
	core_cfg->i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
	/* Set serial data to word select shift. See Phillips spec. */
	core_cfg->i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;

	/* Core audio config */
	core_cfg->freq_sample = sample_freq;
	core_cfg->n = n;
	core_cfg->cts = cts;
	if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
		core_cfg->aud_par_busclk = 0;
		core_cfg->cts_mode = HDMI_AUDIO_CTS_MODE_SW;
		core_cfg->use_mclk = cpu_is_omap446x();
	} else {
		core_cfg->aud_par_busclk = (((128 * 31) - 1) << 8);
		core_cfg->cts_mode = HDMI_AUDIO_CTS_MODE_HW;
		core_cfg->use_mclk = true;
		core_cfg->mclk_mode = HDMI_AUDIO_MCLK_128FS;
	}
	core_cfg->en_spdif = false;
	/* Use sample frequency from channel status word */
	core_cfg->fs_override = true;
	/* Enable ACR packets */
	core_cfg->en_acr_pkt = true;
	/* Disable direct streaming digital audio */
	core_cfg->en_dsd_audio = false;
	/* Use parallel audio interface */
	core_cfg->en_parallel_aud_input = true;

	/* Number of channels */

	switch (priv->params.channels_nr) {
	case 2:
		core_cfg->layout = HDMI_AUDIO_LAYOUT_2CH;
		channel_alloc = 0x0;
		audio_format->stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
		audio_format->active_chnnls_msk = 0x03;
		/* Enable one of the four available serial data channels */
		core_cfg->i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
		break;
	case 6:
		core_cfg->layout = HDMI_AUDIO_LAYOUT_8CH;
		channel_alloc = 0xB;
		audio_format->stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS;
		audio_format->active_chnnls_msk = 0x3f;
		/* Enable all of the four available serial data channels */
		core_cfg->i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN |
				HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |
				HDMI_AUDIO_I2S_SD3_EN;
		break;
	case 8:
		core_cfg->layout = HDMI_AUDIO_LAYOUT_8CH;
		channel_alloc = 0x13;
		audio_format->stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS;
		audio_format->active_chnnls_msk = 0xff;
		/* Enable all of the four available serial data channels */
		core_cfg->i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN |
				HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |
				HDMI_AUDIO_I2S_SD3_EN;
		break;
	default:
		pr_err("Unsupported number of channels\n");
		return -EINVAL;
	}

	hdmi_ti_4xxx_core_audio_config(&priv->ip_data, core_cfg);
	hdmi_ti_4xxx_wp_audio_config_format(&priv->ip_data, audio_format);

	/*
	 * Configure packet
	 * info frame audio see doc CEA861-D page 74
	 */
	aud_if_cfg->db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM;
	aud_if_cfg->db1_channel_count = priv->params.channels_nr;
	aud_if_cfg->db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM;
	aud_if_cfg->db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM;
	aud_if_cfg->db4_channel_alloc = channel_alloc;
	aud_if_cfg->db5_downmix_inh = false;
	aud_if_cfg->db5_lsv = 0;

	hdmi_ti_4xxx_core_audio_infoframe_config(&priv->ip_data, aud_if_cfg);
	return 0;

}

int hdmi_audio_notifier_callback(struct notifier_block *nb,
				unsigned long arg, void *ptr)
{
	enum omap_dss_display_state state = arg;

	if (state == OMAP_DSS_DISPLAY_ACTIVE) {
		/* this happens just after hdmi_power_on */
		if (hdmi_data.active)
			hdmi_ti_4xxx_audio_enable(&hdmi_data.ip_data, 0);
		hdmi_audio_set_configuration(&hdmi_data);
		if (hdmi_data.active) {
			omap_hwmod_set_slave_idlemode(hdmi_data.oh,
							HWMOD_IDLEMODE_NO);
			hdmi_ti_4xxx_audio_enable(&hdmi_data.ip_data, 1);

		}
	}
	return 0;
}

int hdmi_audio_match(struct omap_dss_device *dssdev, void *arg)
{
	return sysfs_streq(dssdev->name , "hdmi");
}

static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
				    struct snd_pcm_hw_params *params,
				    struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec *codec = rtd->codec;
	struct hdmi_codec_data *priv = snd_soc_codec_get_drvdata(codec);

	priv->params.format = params_format(params);
	priv->params.sample_freq = params_rate(params);
	priv->params.channels_nr = params_channels(params);
	return hdmi_audio_set_configuration(priv);
}

static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
				struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec *codec = rtd->codec;
	struct hdmi_codec_data *priv = snd_soc_codec_get_drvdata(codec);
	int err = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		/*
		 * switch to no-idle to avoid DSS_L3_ICLK clock
		 * to be shutdown during audio activity (as per TRM)
		 */
		omap_hwmod_set_slave_idlemode(priv->oh,
			HWMOD_IDLEMODE_NO);
		hdmi_ti_4xxx_audio_enable(&priv->ip_data, 1);
		priv->active = 1;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		priv->active = 0;
		hdmi_ti_4xxx_audio_enable(&priv->ip_data, 0);
		/*
		 * switch back to smart-idle & wakeup capable
		 * after audio activity stops
		 */
		omap_hwmod_set_slave_idlemode(priv->oh,
			HWMOD_IDLEMODE_SMART_WKUP);
		break;
	default:
		err = -EINVAL;
	}
	return err;
}

static int hdmi_audio_startup(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	if (!omapdss_hdmi_get_mode()) {
		pr_err("Current video settings do not support audio.\n");
		return -EIO;
	}
	return 0;
}
static int hdmi_probe(struct snd_soc_codec *codec)
{
	struct platform_device *pdev = to_platform_device(codec->dev);
	struct resource *hdmi_rsrc;
	int ret = 0;

	snd_soc_codec_set_drvdata(codec, &hdmi_data);

	hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!hdmi_rsrc) {
		dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n");
		ret = -EINVAL;
		goto res_err;
	}


	hdmi_data.oh = omap_hwmod_lookup("dss_hdmi");

	if (!hdmi_data.oh) {
		dev_err(&pdev->dev, "can't find omap_hwmod for hdmi\n");
		ret = -ENODEV;
		goto res_err;
	}

	/* Base address taken from platform */
	hdmi_data.ip_data.base_wp = ioremap(hdmi_rsrc->start,
					resource_size(hdmi_rsrc));

	if (!hdmi_data.ip_data.base_wp) {
		dev_err(&pdev->dev, "can't ioremap WP\n");
		ret = -ENOMEM;
		goto res_err;
	}

	hdmi_data.ip_data.hdmi_core_sys_offset = HDMI_CORE_SYS;
	hdmi_data.ip_data.hdmi_core_av_offset = HDMI_CORE_AV;
	hdmi_data.ip_data.hdmi_pll_offset = HDMI_PLLCTRL;
	hdmi_data.ip_data.hdmi_phy_offset = HDMI_PHY;

	hdmi_data.dssdev = omap_dss_find_device(NULL, hdmi_audio_match);

	if (!hdmi_data.dssdev) {
		dev_err(&pdev->dev, "can't find HDMI device\n");
		ret = -ENODEV;
		goto dssdev_err;
	}

	hdmi_data.notifier.notifier_call = hdmi_audio_notifier_callback;
	blocking_notifier_chain_register(&hdmi_data.dssdev->state_notifiers,
			&hdmi_data.notifier);

	return 0;

dssdev_err:
	iounmap(hdmi_data.ip_data.base_wp);
res_err:
	return ret;

}

static int hdmi_remove(struct snd_soc_codec *codec)
{
	struct hdmi_codec_data *priv = snd_soc_codec_get_drvdata(codec);

	blocking_notifier_chain_unregister(&priv->dssdev->state_notifiers,
						&priv->notifier);
	iounmap(priv->ip_data.base_wp);
	kfree(priv);
	return 0;
}


static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
	.probe = hdmi_probe,
	.remove = hdmi_remove,
};

static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
	.hw_params = hdmi_audio_hw_params,
	.trigger = hdmi_audio_trigger,
	.startup = hdmi_audio_startup,
};

static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
		.name = "hdmi-audio-codec",
		.playback = {
			.channels_min = 2,
			.channels_max = 8,
			.rates = SNDRV_PCM_RATE_32000 |
				SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
			.formats = SNDRV_PCM_FMTBIT_S16_LE |
				SNDRV_PCM_FMTBIT_S24_LE,
		},
		.ops = &hdmi_audio_codec_ops,
};

static __devinit int hdmi_codec_probe(struct platform_device *pdev)
{
	int r;

	/* Register ASoC codec DAI */
	r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
					&hdmi_codec_dai_drv, 1);
	if (r) {
		dev_err(&pdev->dev, "can't register ASoC HDMI audio codec\n");
		return r;
	}

	return 0;
}

static int __devexit hdmi_codec_remove(struct platform_device *pdev)
{
	snd_soc_unregister_codec(&pdev->dev);
	return 0;
}


static struct platform_driver hdmi_codec_driver = {
	.probe          = hdmi_codec_probe,
	.remove         = __devexit_p(hdmi_codec_remove),
	.driver         = {
		.name   = "omap-hdmi-codec",
		.owner  = THIS_MODULE,
	},
};


static int __init hdmi_codec_init(void)
{
	return platform_driver_register(&hdmi_codec_driver);
}
module_init(hdmi_codec_init);

static void __exit hdmi_codec_exit(void)
{
	platform_driver_unregister(&hdmi_codec_driver);
}
module_exit(hdmi_codec_exit);


MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
MODULE_DESCRIPTION("ASoC HDMI codec driver");
MODULE_LICENSE("GPL");
