/*
 * ALSA SoC codec for HDMI encoder drivers
 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
 * Author: Jyri Sarha <jsarha@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.
 */
#include <linux/module.h>
#include <linux/string.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/pcm_drm_eld.h>
#include <sound/hdmi-codec.h>
#include <sound/pcm_iec958.h>

#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */

struct hdmi_device {
	struct device *dev;
	struct list_head list;
	int cnt;
};
#define pos_to_hdmi_device(pos)	container_of((pos), struct hdmi_device, list)
LIST_HEAD(hdmi_device_list);

#define DAI_NAME_SIZE 16
struct hdmi_codec_priv {
	struct hdmi_codec_pdata hcd;
	struct snd_soc_dai_driver *daidrv;
	struct hdmi_codec_daifmt daifmt[2];
	struct mutex current_stream_lock;
	struct snd_pcm_substream *current_stream;
	struct snd_pcm_hw_constraint_list ratec;
	uint8_t eld[MAX_ELD_BYTES];
};

static const struct snd_soc_dapm_widget hdmi_widgets[] = {
	SND_SOC_DAPM_OUTPUT("TX"),
};

static const struct snd_soc_dapm_route hdmi_routes[] = {
	{ "TX", NULL, "Playback" },
};

enum {
	DAI_ID_I2S = 0,
	DAI_ID_SPDIF,
};

static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_info *uinfo)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);

	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
	uinfo->count = sizeof(hcp->eld);

	return 0;
}

static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);

	memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld));

	return 0;
}

static const struct snd_kcontrol_new hdmi_controls[] = {
	{
		.access = SNDRV_CTL_ELEM_ACCESS_READ |
			  SNDRV_CTL_ELEM_ACCESS_VOLATILE,
		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
		.name = "ELD",
		.info = hdmi_eld_ctl_info,
		.get = hdmi_eld_ctl_get,
	},
};

static int hdmi_codec_new_stream(struct snd_pcm_substream *substream,
				 struct snd_soc_dai *dai)
{
	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
	int ret = 0;

	mutex_lock(&hcp->current_stream_lock);
	if (!hcp->current_stream) {
		hcp->current_stream = substream;
	} else if (hcp->current_stream != substream) {
		dev_err(dai->dev, "Only one simultaneous stream supported!\n");
		ret = -EINVAL;
	}
	mutex_unlock(&hcp->current_stream_lock);

	return ret;
}

static int hdmi_codec_startup(struct snd_pcm_substream *substream,
			      struct snd_soc_dai *dai)
{
	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
	int ret = 0;

	dev_dbg(dai->dev, "%s()\n", __func__);

	ret = hdmi_codec_new_stream(substream, dai);
	if (ret)
		return ret;

	if (hcp->hcd.ops->audio_startup) {
		ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
		if (ret) {
			mutex_lock(&hcp->current_stream_lock);
			hcp->current_stream = NULL;
			mutex_unlock(&hcp->current_stream_lock);
			return ret;
		}
	}

	if (hcp->hcd.ops->get_eld) {
		ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
					    hcp->eld, sizeof(hcp->eld));

		if (!ret) {
			ret = snd_pcm_hw_constraint_eld(substream->runtime,
							hcp->eld);
			if (ret) {
				mutex_lock(&hcp->current_stream_lock);
				hcp->current_stream = NULL;
				mutex_unlock(&hcp->current_stream_lock);
				return ret;
			}
		}
	}
	return 0;
}

static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{
	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);

	dev_dbg(dai->dev, "%s()\n", __func__);

	WARN_ON(hcp->current_stream != substream);

	hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);

	mutex_lock(&hcp->current_stream_lock);
	hcp->current_stream = NULL;
	mutex_unlock(&hcp->current_stream_lock);
}

static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_soc_dai *dai)
{
	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
	struct hdmi_codec_params hp = {
		.iec = {
			.status = { 0 },
			.subcode = { 0 },
			.pad = 0,
			.dig_subframe = { 0 },
		}
	};
	int ret;

	dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
		params_width(params), params_rate(params),
		params_channels(params));

	if (params_width(params) > 24)
		params->msbits = 24;

	ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status,
						       sizeof(hp.iec.status));
	if (ret < 0) {
		dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
			ret);
		return ret;
	}

	ret = hdmi_codec_new_stream(substream, dai);
	if (ret)
		return ret;

	hdmi_audio_infoframe_init(&hp.cea);
	hp.cea.channels = params_channels(params);
	hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
	hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
	hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;

	hp.sample_width = params_width(params);
	hp.sample_rate = params_rate(params);
	hp.channels = params_channels(params);

	return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
				       &hcp->daifmt[dai->id], &hp);
}

static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
			      unsigned int fmt)
{
	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
	struct hdmi_codec_daifmt cf = { 0 };
	int ret = 0;

	dev_dbg(dai->dev, "%s()\n", __func__);

	if (dai->id == DAI_ID_SPDIF) {
		cf.fmt = HDMI_SPDIF;
	} else {
		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
		case SND_SOC_DAIFMT_CBM_CFM:
			cf.bit_clk_master = 1;
			cf.frame_clk_master = 1;
			break;
		case SND_SOC_DAIFMT_CBS_CFM:
			cf.frame_clk_master = 1;
			break;
		case SND_SOC_DAIFMT_CBM_CFS:
			cf.bit_clk_master = 1;
			break;
		case SND_SOC_DAIFMT_CBS_CFS:
			break;
		default:
			return -EINVAL;
		}

		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
		case SND_SOC_DAIFMT_NB_NF:
			break;
		case SND_SOC_DAIFMT_NB_IF:
			cf.frame_clk_inv = 1;
			break;
		case SND_SOC_DAIFMT_IB_NF:
			cf.bit_clk_inv = 1;
			break;
		case SND_SOC_DAIFMT_IB_IF:
			cf.frame_clk_inv = 1;
			cf.bit_clk_inv = 1;
			break;
		}

		switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
		case SND_SOC_DAIFMT_I2S:
			cf.fmt = HDMI_I2S;
			break;
		case SND_SOC_DAIFMT_DSP_A:
			cf.fmt = HDMI_DSP_A;
			break;
		case SND_SOC_DAIFMT_DSP_B:
			cf.fmt = HDMI_DSP_B;
			break;
		case SND_SOC_DAIFMT_RIGHT_J:
			cf.fmt = HDMI_RIGHT_J;
			break;
		case SND_SOC_DAIFMT_LEFT_J:
			cf.fmt = HDMI_LEFT_J;
			break;
		case SND_SOC_DAIFMT_AC97:
			cf.fmt = HDMI_AC97;
			break;
		default:
			dev_err(dai->dev, "Invalid DAI interface format\n");
			return -EINVAL;
		}
	}

	hcp->daifmt[dai->id] = cf;

	return ret;
}

static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
{
	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);

	dev_dbg(dai->dev, "%s()\n", __func__);

	if (hcp->hcd.ops->digital_mute)
		return hcp->hcd.ops->digital_mute(dai->dev->parent,
						  hcp->hcd.data, mute);

	return 0;
}

static const struct snd_soc_dai_ops hdmi_dai_ops = {
	.startup	= hdmi_codec_startup,
	.shutdown	= hdmi_codec_shutdown,
	.hw_params	= hdmi_codec_hw_params,
	.set_fmt	= hdmi_codec_set_fmt,
	.digital_mute	= hdmi_codec_digital_mute,
};


#define HDMI_RATES	(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
			 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
			 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
			 SNDRV_PCM_RATE_192000)

#define SPDIF_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)

/*
 * This list is only for formats allowed on the I2S bus. So there is
 * some formats listed that are not supported by HDMI interface. For
 * instance allowing the 32-bit formats enables 24-precision with CPU
 * DAIs that do not support 24-bit formats. If the extra formats cause
 * problems, we should add the video side driver an option to disable
 * them.
 */
#define I2S_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)

static struct snd_soc_dai_driver hdmi_i2s_dai = {
	.id = DAI_ID_I2S,
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,
		.channels_max = 8,
		.rates = HDMI_RATES,
		.formats = I2S_FORMATS,
		.sig_bits = 24,
	},
	.ops = &hdmi_dai_ops,
};

static const struct snd_soc_dai_driver hdmi_spdif_dai = {
	.id = DAI_ID_SPDIF,
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = HDMI_RATES,
		.formats = SPDIF_FORMATS,
	},
	.ops = &hdmi_dai_ops,
};

static char hdmi_dai_name[][DAI_NAME_SIZE] = {
	"hdmi-hifi.0",
	"hdmi-hifi.1",
	"hdmi-hifi.2",
	"hdmi-hifi.3",
};

static int hdmi_of_xlate_dai_name(struct snd_soc_component *component,
				  struct of_phandle_args *args,
				  const char **dai_name)
{
	int id;

	if (args->args_count)
		id = args->args[0];
	else
		id = 0;

	if (id < ARRAY_SIZE(hdmi_dai_name)) {
		*dai_name = hdmi_dai_name[id];
		return 0;
	}

	return -EAGAIN;
}

static struct snd_soc_codec_driver hdmi_codec = {
	.component_driver = {
		.controls		= hdmi_controls,
		.num_controls		= ARRAY_SIZE(hdmi_controls),
		.dapm_widgets		= hdmi_widgets,
		.num_dapm_widgets	= ARRAY_SIZE(hdmi_widgets),
		.dapm_routes		= hdmi_routes,
		.num_dapm_routes	= ARRAY_SIZE(hdmi_routes),
		.of_xlate_dai_name	= hdmi_of_xlate_dai_name,
	},
};

static int hdmi_codec_probe(struct platform_device *pdev)
{
	struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
	struct device *dev = &pdev->dev;
	struct hdmi_codec_priv *hcp;
	struct hdmi_device *hd;
	struct list_head *pos;
	int dai_count, i = 0;
	int ret;

	dev_dbg(dev, "%s()\n", __func__);

	if (!hcd) {
		dev_err(dev, "%s: No plalform data\n", __func__);
		return -EINVAL;
	}

	dai_count = hcd->i2s + hcd->spdif;
	if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params ||
	    !hcd->ops->audio_shutdown) {
		dev_err(dev, "%s: Invalid parameters\n", __func__);
		return -EINVAL;
	}

	hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL);
	if (!hcp)
		return -ENOMEM;

	hd = NULL;
	list_for_each(pos, &hdmi_device_list) {
		struct hdmi_device *tmp = pos_to_hdmi_device(pos);

		if (tmp->dev == dev->parent) {
			hd = tmp;
			break;
		}
	}

	if (!hd) {
		hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL);
		if (!hd)
			return -ENOMEM;

		hd->dev = dev->parent;

		list_add_tail(&hd->list, &hdmi_device_list);
	}

	if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) {
		dev_err(dev, "too many hdmi codec are deteced\n");
		return -EINVAL;
	}

	hcp->hcd = *hcd;
	mutex_init(&hcp->current_stream_lock);

	hcp->daidrv = devm_kzalloc(dev, dai_count * sizeof(*hcp->daidrv),
				   GFP_KERNEL);
	if (!hcp->daidrv)
		return -ENOMEM;

	if (hcd->i2s) {
		hcp->daidrv[i] = hdmi_i2s_dai;
		hcp->daidrv[i].playback.channels_max =
			hcd->max_i2s_channels;
		hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++];
		i++;
	}

	if (hcd->spdif) {
		hcp->daidrv[i] = hdmi_spdif_dai;
		hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++];
	}

	ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
				     dai_count);
	if (ret) {
		dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n",
			__func__, ret);
		return ret;
	}

	dev_set_drvdata(dev, hcp);
	return 0;
}

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

static struct platform_driver hdmi_codec_driver = {
	.driver = {
		.name = HDMI_CODEC_DRV_NAME,
	},
	.probe = hdmi_codec_probe,
	.remove = hdmi_codec_remove,
};

module_platform_driver(hdmi_codec_driver);

MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
MODULE_DESCRIPTION("HDMI Audio Codec Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME);
