/*
 * ALSA SoC WL1273 codec driver
 *
 * Author:      Matti Aaltonen, <matti.j.aaltonen@nokia.com>
 *
 * Copyright:   (C) 2010, 2011 Nokia Corporation
 *
 * 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/mfd/wl1273-core.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>

#include "wl1273.h"

enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX };

/* codec private data */
struct wl1273_priv {
	enum wl1273_mode mode;
	struct wl1273_core *core;
	unsigned int channels;
};

static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core,
				      int rate, int width)
{
	struct device *dev = &core->client->dev;
	int r = 0;
	u16 mode;

	dev_dbg(dev, "rate: %d\n", rate);
	dev_dbg(dev, "width: %d\n", width);

	mutex_lock(&core->lock);

	mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE;

	switch (rate) {
	case 48000:
		mode |= WL1273_IS2_RATE_48K;
		break;
	case 44100:
		mode |= WL1273_IS2_RATE_44_1K;
		break;
	case 32000:
		mode |= WL1273_IS2_RATE_32K;
		break;
	case 22050:
		mode |= WL1273_IS2_RATE_22_05K;
		break;
	case 16000:
		mode |= WL1273_IS2_RATE_16K;
		break;
	case 12000:
		mode |= WL1273_IS2_RATE_12K;
		break;
	case 11025:
		mode |= WL1273_IS2_RATE_11_025;
		break;
	case 8000:
		mode |= WL1273_IS2_RATE_8K;
		break;
	default:
		dev_err(dev, "Sampling rate: %d not supported\n", rate);
		r = -EINVAL;
		goto out;
	}

	switch (width) {
	case 16:
		mode |= WL1273_IS2_WIDTH_32;
		break;
	case 20:
		mode |= WL1273_IS2_WIDTH_40;
		break;
	case 24:
		mode |= WL1273_IS2_WIDTH_48;
		break;
	case 25:
		mode |= WL1273_IS2_WIDTH_50;
		break;
	case 30:
		mode |= WL1273_IS2_WIDTH_60;
		break;
	case 32:
		mode |= WL1273_IS2_WIDTH_64;
		break;
	case 40:
		mode |= WL1273_IS2_WIDTH_80;
		break;
	case 48:
		mode |= WL1273_IS2_WIDTH_96;
		break;
	case 64:
		mode |= WL1273_IS2_WIDTH_128;
		break;
	default:
		dev_err(dev, "Data width: %d not supported\n", width);
		r = -EINVAL;
		goto out;
	}

	dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n",  WL1273_I2S_DEF_MODE);
	dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode);
	dev_dbg(dev, "mode: 0x%04x\n", mode);

	if (core->i2s_mode != mode) {
		r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode);
		if (r)
			goto out;

		core->i2s_mode = mode;
		r = core->write(core, WL1273_AUDIO_ENABLE,
				WL1273_AUDIO_ENABLE_I2S);
		if (r)
			goto out;
	}
out:
	mutex_unlock(&core->lock);

	return r;
}

static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,
					    int channel_number)
{
	struct device *dev = &core->client->dev;
	int r = 0;

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

	mutex_lock(&core->lock);

	if (core->channel_number == channel_number)
		goto out;

	if (channel_number == 1 && core->mode == WL1273_MODE_RX)
		r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
	else if (channel_number == 1 && core->mode == WL1273_MODE_TX)
		r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
	else if (channel_number == 2 && core->mode == WL1273_MODE_RX)
		r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
	else if (channel_number == 2 && core->mode == WL1273_MODE_TX)
		r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO);
	else
		r = -EINVAL;
out:
	mutex_unlock(&core->lock);

	return r;
}

static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	ucontrol->value.enumerated.item[0] = wl1273->mode;

	return 0;
}

/*
 * TODO: Implement the audio routing in the driver. Now this control
 * only indicates the setting that has been done elsewhere (in the user
 * space).
 */
static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };

static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	if (wl1273->mode == ucontrol->value.enumerated.item[0])
		return 0;

	/* Do not allow changes while stream is running */
	if (snd_soc_codec_is_active(codec))
		return -EPERM;

	if (ucontrol->value.enumerated.item[0] >=  ARRAY_SIZE(wl1273_audio_route))
		return -EINVAL;

	wl1273->mode = ucontrol->value.enumerated.item[0];

	return 1;
}

static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route);

static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

	ucontrol->value.enumerated.item[0] = wl1273->core->audio_mode;

	return 0;
}

static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
	int val, r = 0;

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

	val = ucontrol->value.enumerated.item[0];
	if (wl1273->core->audio_mode == val)
		return 0;

	r = wl1273->core->set_audio(wl1273->core, val);
	if (r < 0)
		return r;

	return 1;
}

static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };

static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings);

static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

	ucontrol->value.integer.value[0] = wl1273->core->volume;

	return 0;
}

static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
	int r;

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

	r = wl1273->core->set_volume(wl1273->core,
				     ucontrol->value.integer.value[0]);
	if (r)
		return r;

	return 1;
}

static const struct snd_kcontrol_new wl1273_controls[] = {
	SOC_ENUM_EXT("Codec Mode", wl1273_enum,
		     snd_wl1273_get_audio_route, snd_wl1273_set_audio_route),
	SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum,
		     snd_wl1273_fm_audio_get,  snd_wl1273_fm_audio_put),
	SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0,
		       snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),
};

static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] = {
	SND_SOC_DAPM_INPUT("RX"),

	SND_SOC_DAPM_OUTPUT("TX"),
};

static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {
	{ "Capture", NULL, "RX" },

	{ "TX", NULL, "Playback" },
};

static int wl1273_startup(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	switch (wl1273->mode) {
	case WL1273_MODE_BT:
		snd_pcm_hw_constraint_single(substream->runtime,
					     SNDRV_PCM_HW_PARAM_RATE, 8000);
		snd_pcm_hw_constraint_single(substream->runtime,
					     SNDRV_PCM_HW_PARAM_CHANNELS, 1);
		break;
	case WL1273_MODE_FM_RX:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			pr_err("Cannot play in RX mode.\n");
			return -EINVAL;
		}
		break;
	case WL1273_MODE_FM_TX:
		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
			pr_err("Cannot capture in TX mode.\n");
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
		break;
	}

	return 0;
}

static int wl1273_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(dai->codec);
	struct wl1273_core *core = wl1273->core;
	unsigned int rate, width, r;

	if (params_width(params) != 16) {
		dev_err(dai->dev, "%d bits/sample not supported\n",
			params_width(params));
		return -EINVAL;
	}

	rate = params_rate(params);
	width =  hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;

	if (wl1273->mode == WL1273_MODE_BT) {
		if (rate != 8000) {
			pr_err("Rate %d not supported.\n", params_rate(params));
			return -EINVAL;
		}

		if (params_channels(params) != 1) {
			pr_err("Only mono supported.\n");
			return -EINVAL;
		}

		return 0;
	}

	if (wl1273->mode == WL1273_MODE_FM_TX &&
	    substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		pr_err("Only playback supported with TX.\n");
		return -EINVAL;
	}

	if (wl1273->mode == WL1273_MODE_FM_RX  &&
	    substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		pr_err("Only capture supported with RX.\n");
		return -EINVAL;
	}

	if (wl1273->mode != WL1273_MODE_FM_RX  &&
	    wl1273->mode != WL1273_MODE_FM_TX) {
		pr_err("Unexpected mode: %d.\n", wl1273->mode);
		return -EINVAL;
	}

	r = snd_wl1273_fm_set_i2s_mode(core, rate, width);
	if (r)
		return r;

	wl1273->channels = params_channels(params);
	r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);
	if (r)
		return r;

	return 0;
}

static const struct snd_soc_dai_ops wl1273_dai_ops = {
	.startup	= wl1273_startup,
	.hw_params	= wl1273_hw_params,
};

static struct snd_soc_dai_driver wl1273_dai = {
	.name = "wl1273-fm",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE},
	.ops = &wl1273_dai_ops,
};

/* Audio interface format for the soc_card driver */
int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
{
	struct wl1273_priv *wl1273;

	if (codec == NULL || fmt == NULL)
		return -EINVAL;

	wl1273 = snd_soc_codec_get_drvdata(codec);

	switch (wl1273->mode) {
	case WL1273_MODE_FM_RX:
	case WL1273_MODE_FM_TX:
		*fmt =	SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF |
			SND_SOC_DAIFMT_CBM_CFM;

		break;
	case WL1273_MODE_BT:
		*fmt =	SND_SOC_DAIFMT_DSP_A |
			SND_SOC_DAIFMT_IB_NF |
			SND_SOC_DAIFMT_CBM_CFM;

		break;
	default:
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(wl1273_get_format);

static int wl1273_probe(struct snd_soc_codec *codec)
{
	struct wl1273_core **core = codec->dev->platform_data;
	struct wl1273_priv *wl1273;

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

	if (!core) {
		dev_err(codec->dev, "Platform data is missing.\n");
		return -EINVAL;
	}

	wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);
	if (!wl1273)
		return -ENOMEM;

	wl1273->mode = WL1273_MODE_BT;
	wl1273->core = *core;

	snd_soc_codec_set_drvdata(codec, wl1273);

	return 0;
}

static int wl1273_remove(struct snd_soc_codec *codec)
{
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s\n", __func__);
	kfree(wl1273);

	return 0;
}

static const struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
	.probe = wl1273_probe,
	.remove = wl1273_remove,

	.component_driver = {
		.controls		= wl1273_controls,
		.num_controls		= ARRAY_SIZE(wl1273_controls),
		.dapm_widgets		= wl1273_dapm_widgets,
		.num_dapm_widgets	= ARRAY_SIZE(wl1273_dapm_widgets),
		.dapm_routes		= wl1273_dapm_routes,
		.num_dapm_routes	= ARRAY_SIZE(wl1273_dapm_routes),
	},
};

static int wl1273_platform_probe(struct platform_device *pdev)
{
	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273,
				      &wl1273_dai, 1);
}

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

MODULE_ALIAS("platform:wl1273-codec");

static struct platform_driver wl1273_platform_driver = {
	.driver		= {
		.name	= "wl1273-codec",
	},
	.probe		= wl1273_platform_probe,
	.remove		= wl1273_platform_remove,
};

module_platform_driver(wl1273_platform_driver);

MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
MODULE_DESCRIPTION("ASoC WL1273 codec driver");
MODULE_LICENSE("GPL");
