/*
 * APBridge ALSA SoC dummy codec driver
 * Copyright 2016 Google Inc.
 * Copyright 2016 Linaro Ltd.
 *
 * Released under the GPLv2 only.
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <uapi/linux/input.h>

#include "audio_codec.h"
#include "audio_apbridgea.h"
#include "audio_manager.h"

static struct gbaudio_codec_info *gbcodec;

static struct gbaudio_data_connection *
find_data(struct gbaudio_module_info *module, int id)
{
	struct gbaudio_data_connection *data;

	list_for_each_entry(data, &module->data_list, list) {
		if (id == data->id)
			return data;
	}
	return NULL;
}

static struct gbaudio_stream_params *
find_dai_stream_params(struct gbaudio_codec_info *codec, int id, int stream)
{
	struct gbaudio_codec_dai *dai;

	list_for_each_entry(dai, &codec->dai_list, list) {
		if (dai->id == id)
			return &dai->params[stream];
	}
	return NULL;
}

static int gbaudio_module_enable_tx(struct gbaudio_codec_info *codec,
				    struct gbaudio_module_info *module, int id)
{
	int module_state, ret = 0;
	u16 data_cport, i2s_port, cportid;
	u8 sig_bits, channels;
	uint32_t format, rate;
	struct gbaudio_data_connection *data;
	struct gbaudio_stream_params *params;

	/* find the dai */
	data = find_data(module, id);
	if (!data) {
		dev_err(module->dev, "%d:DATA connection missing\n", id);
		return -ENODEV;
	}
	module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK];

	params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_PLAYBACK);
	if (!params) {
		dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
		return -EINVAL;
	}

	/* register cport */
	if (module_state < GBAUDIO_CODEC_STARTUP) {
		i2s_port = 0;	/* fixed for now */
		cportid = data->connection->hd_cport_id;
		ret = gb_audio_apbridgea_register_cport(data->connection,
						i2s_port, cportid,
						AUDIO_APBRIDGEA_DIRECTION_TX);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "reg_cport failed:%d\n", ret);
			return ret;
		}
		data->state[SNDRV_PCM_STREAM_PLAYBACK] =
			GBAUDIO_CODEC_STARTUP;
		dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid);
	}

	/* hw_params */
	if (module_state < GBAUDIO_CODEC_HWPARAMS) {
		format = params->format;
		channels = params->channels;
		rate = params->rate;
		sig_bits = params->sig_bits;
		data_cport = data->connection->intf_cport_id;
		ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport,
					  format, rate, channels, sig_bits);
		if (ret) {
			dev_err_ratelimited(module->dev, "set_pcm failed:%d\n",
					    ret);
			return ret;
		}
		data->state[SNDRV_PCM_STREAM_PLAYBACK] =
			GBAUDIO_CODEC_HWPARAMS;
		dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport);
	}

	/* prepare */
	if (module_state < GBAUDIO_CODEC_PREPARE) {
		data_cport = data->connection->intf_cport_id;
		ret = gb_audio_gb_set_tx_data_size(module->mgmt_connection,
						   data_cport, 192);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "set_tx_data_size failed:%d\n",
					    ret);
			return ret;
		}
		ret = gb_audio_gb_activate_tx(module->mgmt_connection,
					      data_cport);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "activate_tx failed:%d\n", ret);
			return ret;
		}
		data->state[SNDRV_PCM_STREAM_PLAYBACK] =
			GBAUDIO_CODEC_PREPARE;
		dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport);
	}

	return 0;
}

static int gbaudio_module_disable_tx(struct gbaudio_module_info *module, int id)
{
	int ret;
	u16 data_cport, cportid, i2s_port;
	int module_state;
	struct gbaudio_data_connection *data;

	/* find the dai */
	data = find_data(module, id);
	if (!data) {
		dev_err(module->dev, "%d:DATA connection missing\n", id);
		return -ENODEV;
	}
	module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK];

	if (module_state > GBAUDIO_CODEC_HWPARAMS) {
		data_cport = data->connection->intf_cport_id;
		ret = gb_audio_gb_deactivate_tx(module->mgmt_connection,
						data_cport);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "deactivate_tx failed:%d\n", ret);
			return ret;
		}
		dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport);
		data->state[SNDRV_PCM_STREAM_PLAYBACK] =
			GBAUDIO_CODEC_HWPARAMS;
	}

	if (module_state > GBAUDIO_CODEC_SHUTDOWN) {
		i2s_port = 0;	/* fixed for now */
		cportid = data->connection->hd_cport_id;
		ret = gb_audio_apbridgea_unregister_cport(data->connection,
						i2s_port, cportid,
						AUDIO_APBRIDGEA_DIRECTION_TX);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "unregister_cport failed:%d\n",
					    ret);
			return ret;
		}
		dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid);
		data->state[SNDRV_PCM_STREAM_PLAYBACK] =
			GBAUDIO_CODEC_SHUTDOWN;
	}

	return 0;
}

static int gbaudio_module_enable_rx(struct gbaudio_codec_info *codec,
				    struct gbaudio_module_info *module, int id)
{
	int module_state, ret = 0;
	u16 data_cport, i2s_port, cportid;
	u8 sig_bits, channels;
	uint32_t format, rate;
	struct gbaudio_data_connection *data;
	struct gbaudio_stream_params *params;

	/* find the dai */
	data = find_data(module, id);
	if (!data) {
		dev_err(module->dev, "%d:DATA connection missing\n", id);
		return -ENODEV;
	}
	module_state = data->state[SNDRV_PCM_STREAM_CAPTURE];

	params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_CAPTURE);
	if (!params) {
		dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
		return -EINVAL;
	}

	/* register cport */
	if (module_state < GBAUDIO_CODEC_STARTUP) {
		i2s_port = 0;	/* fixed for now */
		cportid = data->connection->hd_cport_id;
		ret = gb_audio_apbridgea_register_cport(data->connection,
						i2s_port, cportid,
						AUDIO_APBRIDGEA_DIRECTION_RX);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "reg_cport failed:%d\n", ret);
			return ret;
		}
		data->state[SNDRV_PCM_STREAM_CAPTURE] =
			GBAUDIO_CODEC_STARTUP;
		dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid);
	}

	/* hw_params */
	if (module_state < GBAUDIO_CODEC_HWPARAMS) {
		format = params->format;
		channels = params->channels;
		rate = params->rate;
		sig_bits = params->sig_bits;
		data_cport = data->connection->intf_cport_id;
		ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport,
					  format, rate, channels, sig_bits);
		if (ret) {
			dev_err_ratelimited(module->dev, "set_pcm failed:%d\n",
					    ret);
			return ret;
		}
		data->state[SNDRV_PCM_STREAM_CAPTURE] =
			GBAUDIO_CODEC_HWPARAMS;
		dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport);
	}

	/* prepare */
	if (module_state < GBAUDIO_CODEC_PREPARE) {
		data_cport = data->connection->intf_cport_id;
		ret = gb_audio_gb_set_rx_data_size(module->mgmt_connection,
						   data_cport, 192);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "set_rx_data_size failed:%d\n",
					    ret);
			return ret;
		}
		ret = gb_audio_gb_activate_rx(module->mgmt_connection,
					      data_cport);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "activate_rx failed:%d\n", ret);
			return ret;
		}
		data->state[SNDRV_PCM_STREAM_CAPTURE] =
			GBAUDIO_CODEC_PREPARE;
		dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport);
	}

	return 0;
}

static int gbaudio_module_disable_rx(struct gbaudio_module_info *module, int id)
{
	int ret;
	u16 data_cport, cportid, i2s_port;
	int module_state;
	struct gbaudio_data_connection *data;

	/* find the dai */
	data = find_data(module, id);
	if (!data) {
		dev_err(module->dev, "%d:DATA connection missing\n", id);
		return -ENODEV;
	}
	module_state = data->state[SNDRV_PCM_STREAM_CAPTURE];

	if (module_state > GBAUDIO_CODEC_HWPARAMS) {
		data_cport = data->connection->intf_cport_id;
		ret = gb_audio_gb_deactivate_rx(module->mgmt_connection,
						data_cport);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "deactivate_rx failed:%d\n", ret);
			return ret;
		}
		dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport);
		data->state[SNDRV_PCM_STREAM_CAPTURE] =
			GBAUDIO_CODEC_HWPARAMS;
	}

	if (module_state > GBAUDIO_CODEC_SHUTDOWN) {
		i2s_port = 0;	/* fixed for now */
		cportid = data->connection->hd_cport_id;
		ret = gb_audio_apbridgea_unregister_cport(data->connection,
						i2s_port, cportid,
						AUDIO_APBRIDGEA_DIRECTION_RX);
		if (ret) {
			dev_err_ratelimited(module->dev,
					    "unregister_cport failed:%d\n",
					    ret);
			return ret;
		}
		dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid);
		data->state[SNDRV_PCM_STREAM_CAPTURE] =
			GBAUDIO_CODEC_SHUTDOWN;
	}

	return 0;
}

int gbaudio_module_update(struct gbaudio_codec_info *codec,
			  struct snd_soc_dapm_widget *w,
			  struct gbaudio_module_info *module, int enable)
{
	int dai_id, ret;
	char intf_name[NAME_SIZE], dir[NAME_SIZE];

	dev_dbg(module->dev, "%s:Module update %s sequence\n", w->name,
		enable ? "Enable":"Disable");

	if ((w->id != snd_soc_dapm_aif_in) && (w->id != snd_soc_dapm_aif_out)) {
		dev_dbg(codec->dev, "No action required for %s\n", w->name);
		return 0;
	}

	/* parse dai_id from AIF widget's stream_name */
	ret = sscanf(w->sname, "%s %d %s", intf_name, &dai_id, dir);
	if (ret < 3) {
		dev_err(codec->dev, "Error while parsing dai_id for %s\n",
			w->name);
		return -EINVAL;
	}

	mutex_lock(&codec->lock);
	if (w->id == snd_soc_dapm_aif_in) {
		if (enable)
			ret = gbaudio_module_enable_tx(codec, module, dai_id);
		else
			ret = gbaudio_module_disable_tx(module, dai_id);
	} else if (w->id == snd_soc_dapm_aif_out) {
		if (enable)
			ret = gbaudio_module_enable_rx(codec, module, dai_id);
		else
			ret = gbaudio_module_disable_rx(module, dai_id);
	}

	mutex_unlock(&codec->lock);

	return ret;
}
EXPORT_SYMBOL(gbaudio_module_update);

/*
 * codec DAI ops
 */
static int gbcodec_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
{
	struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
	struct gbaudio_stream_params *params;

	mutex_lock(&codec->lock);

	if (list_empty(&codec->module_list)) {
		dev_err(codec->dev, "No codec module available\n");
		mutex_unlock(&codec->lock);
		return -ENODEV;
	}

	params = find_dai_stream_params(codec, dai->id, substream->stream);
	if (!params) {
		dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}
	params->state = GBAUDIO_CODEC_STARTUP;
	mutex_unlock(&codec->lock);
	/* to prevent suspend in case of active audio */
	pm_stay_awake(dai->dev);

	return 0;
}

static void gbcodec_shutdown(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *dai)
{
	struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
	struct gbaudio_stream_params *params;

	mutex_lock(&codec->lock);

	if (list_empty(&codec->module_list))
		dev_info(codec->dev, "No codec module available during shutdown\n");

	params = find_dai_stream_params(codec, dai->id, substream->stream);
	if (!params) {
		dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
		mutex_unlock(&codec->lock);
		return;
	}
	params->state = GBAUDIO_CODEC_SHUTDOWN;
	mutex_unlock(&codec->lock);
	pm_relax(dai->dev);
	return;
}

static int gbcodec_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *hwparams,
			     struct snd_soc_dai *dai)
{
	int ret;
	u8 sig_bits, channels;
	uint32_t format, rate;
	struct gbaudio_module_info *module;
	struct gbaudio_data_connection *data;
	struct gb_bundle *bundle;
	struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
	struct gbaudio_stream_params *params;

	mutex_lock(&codec->lock);

	if (list_empty(&codec->module_list)) {
		dev_err(codec->dev, "No codec module available\n");
		mutex_unlock(&codec->lock);
		return -ENODEV;
	}

	/*
	 * assuming, currently only 48000 Hz, 16BIT_LE, stereo
	 * is supported, validate params before configuring codec
	 */
	if (params_channels(hwparams) != 2) {
		dev_err(dai->dev, "Invalid channel count:%d\n",
			params_channels(hwparams));
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}
	channels = params_channels(hwparams);

	if (params_rate(hwparams) != 48000) {
		dev_err(dai->dev, "Invalid sampling rate:%d\n",
			params_rate(hwparams));
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}
	rate = GB_AUDIO_PCM_RATE_48000;

	if (params_format(hwparams) != SNDRV_PCM_FORMAT_S16_LE) {
		dev_err(dai->dev, "Invalid format:%d\n",
			params_format(hwparams));
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}
	format = GB_AUDIO_PCM_FMT_S16_LE;

	/* find the data connection */
	list_for_each_entry(module, &codec->module_list, list) {
		data = find_data(module, dai->id);
		if (data)
			break;
	}

	if (!data) {
		dev_err(dai->dev, "DATA connection missing\n");
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}

	params = find_dai_stream_params(codec, dai->id, substream->stream);
	if (!params) {
		dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}

	bundle = to_gb_bundle(module->dev);
	ret = gb_pm_runtime_get_sync(bundle);
	if (ret) {
		mutex_unlock(&codec->lock);
		return ret;
	}

	ret = gb_audio_apbridgea_set_config(data->connection, 0,
					    AUDIO_APBRIDGEA_PCM_FMT_16,
					    AUDIO_APBRIDGEA_PCM_RATE_48000,
					    6144000);
	if (ret) {
		dev_err_ratelimited(dai->dev, "%d: Error during set_config\n",
				    ret);
		mutex_unlock(&codec->lock);
		return ret;
	}

	gb_pm_runtime_put_noidle(bundle);

	params->state = GBAUDIO_CODEC_HWPARAMS;
	params->format = format;
	params->rate = rate;
	params->channels = channels;
	params->sig_bits = sig_bits;

	mutex_unlock(&codec->lock);
	return 0;
}

static int gbcodec_prepare(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
{
	int ret;
	struct gbaudio_module_info *module;
	struct gbaudio_data_connection *data;
	struct gb_bundle *bundle;
	struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
	struct gbaudio_stream_params *params;

	mutex_lock(&codec->lock);

	if (list_empty(&codec->module_list)) {
		dev_err(codec->dev, "No codec module available\n");
		mutex_unlock(&codec->lock);
		return -ENODEV;
	}

	list_for_each_entry(module, &codec->module_list, list) {
		/* find the dai */
		data = find_data(module, dai->id);
		if (data)
			break;
	}
	if (!data) {
		dev_err(dai->dev, "DATA connection missing\n");
		mutex_unlock(&codec->lock);
		return -ENODEV;
	}

	params = find_dai_stream_params(codec, dai->id, substream->stream);
	if (!params) {
		dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}

	bundle = to_gb_bundle(module->dev);
	ret = gb_pm_runtime_get_sync(bundle);
	if (ret) {
		mutex_unlock(&codec->lock);
		return ret;
	}

	switch (substream->stream) {
	case SNDRV_PCM_STREAM_PLAYBACK:
		ret = gb_audio_apbridgea_set_tx_data_size(data->connection, 0,
							  192);
		break;
	case SNDRV_PCM_STREAM_CAPTURE:
		ret = gb_audio_apbridgea_set_rx_data_size(data->connection, 0,
							  192);
		break;
	}
	if (ret) {
		mutex_unlock(&codec->lock);
		dev_err_ratelimited(dai->dev, "set_data_size failed:%d\n",
				     ret);
		return ret;
	}

	gb_pm_runtime_put_noidle(bundle);

	params->state = GBAUDIO_CODEC_PREPARE;
	mutex_unlock(&codec->lock);
	return 0;
}

static int gbcodec_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
{
	int ret;
	struct gbaudio_data_connection *data;
	struct gbaudio_module_info *module;
	struct gb_bundle *bundle;
	struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
	struct gbaudio_stream_params *params;


	dev_dbg(dai->dev, "Mute:%d, Direction:%s\n", mute,
		stream ? "CAPTURE":"PLAYBACK");

	mutex_lock(&codec->lock);

	params = find_dai_stream_params(codec, dai->id, stream);
	if (!params) {
		dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
		mutex_unlock(&codec->lock);
		return -EINVAL;
	}

	if (list_empty(&codec->module_list)) {
		dev_err(codec->dev, "No codec module available\n");
		if (mute) {
			params->state = GBAUDIO_CODEC_STOP;
			ret = 0;
		} else {
			ret = -ENODEV;
		}
		mutex_unlock(&codec->lock);
		return ret;
	}

	list_for_each_entry(module, &codec->module_list, list) {
		/* find the dai */
		data = find_data(module, dai->id);
		if (data)
			break;
	}
	if (!data) {
		dev_err(dai->dev, "%s:%s DATA connection missing\n",
			dai->name, module->name);
		mutex_unlock(&codec->lock);
		return -ENODEV;
	}

	bundle = to_gb_bundle(module->dev);
	ret = gb_pm_runtime_get_sync(bundle);
	if (ret) {
		mutex_unlock(&codec->lock);
		return ret;
	}

	if (!mute && !stream) {/* start playback */
		ret = gb_audio_apbridgea_prepare_tx(data->connection,
						    0);
		if (!ret)
			ret = gb_audio_apbridgea_start_tx(data->connection,
							  0, 0);
		params->state = GBAUDIO_CODEC_START;
	} else if (!mute && stream) {/* start capture */
		ret = gb_audio_apbridgea_prepare_rx(data->connection,
						    0);
		if (!ret)
			ret = gb_audio_apbridgea_start_rx(data->connection,
							  0);
		params->state = GBAUDIO_CODEC_START;
	} else if (mute && !stream) {/* stop playback */
		ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
		if (!ret)
			ret = gb_audio_apbridgea_shutdown_tx(data->connection,
							     0);
		params->state = GBAUDIO_CODEC_STOP;
	} else if (mute && stream) {/* stop capture */
		ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
		if (!ret)
			ret = gb_audio_apbridgea_shutdown_rx(data->connection,
							     0);
		params->state = GBAUDIO_CODEC_STOP;
	} else
		ret = -EINVAL;
	if (ret)
		dev_err_ratelimited(dai->dev,
				    "%s:Error during %s %s stream:%d\n",
				    module->name, mute ? "Mute" : "Unmute",
				    stream ? "Capture" : "Playback", ret);

	gb_pm_runtime_put_noidle(bundle);
	mutex_unlock(&codec->lock);
	return ret;
}

static struct snd_soc_dai_ops gbcodec_dai_ops = {
	.startup = gbcodec_startup,
	.shutdown = gbcodec_shutdown,
	.hw_params = gbcodec_hw_params,
	.prepare = gbcodec_prepare,
	.mute_stream = gbcodec_mute_stream,
};

static struct snd_soc_dai_driver gbaudio_dai[] = {
	{
		.name = "apb-i2s0",
		.id = 0,
		.playback = {
			.stream_name = "I2S 0 Playback",
			.rates = SNDRV_PCM_RATE_48000,
			.formats = SNDRV_PCM_FORMAT_S16_LE,
			.rate_max = 48000,
			.rate_min = 48000,
			.channels_min = 1,
			.channels_max = 2,
		},
		.capture = {
			.stream_name = "I2S 0 Capture",
			.rates = SNDRV_PCM_RATE_48000,
			.formats = SNDRV_PCM_FORMAT_S16_LE,
			.rate_max = 48000,
			.rate_min = 48000,
			.channels_min = 1,
			.channels_max = 2,
		},
		.ops = &gbcodec_dai_ops,
	},
};

static int gbaudio_init_jack(struct gbaudio_module_info *module,
			     struct snd_soc_codec *codec)
{
	int ret;

	if (!module->jack_mask)
		return 0;

	snprintf(module->jack_name, NAME_SIZE, "GB %d Headset Jack",
		 module->dev_id);
	ret = snd_soc_jack_new(codec, module->jack_name, module->jack_mask,
			       &module->headset_jack);
	if (ret) {
		dev_err(module->dev, "Failed to create new jack\n");
		return ret;
	}

	if (!module->button_mask)
		return 0;

	snprintf(module->button_name, NAME_SIZE, "GB %d Button Jack",
		 module->dev_id);
	ret = snd_soc_jack_new(codec, module->button_name, module->button_mask,
			       &module->button_jack);
	if (ret) {
		dev_err(module->dev, "Failed to create button jack\n");
		return ret;
	}

	/*
	 * Currently, max 4 buttons are supported with following key mapping
	 * BTN_0 = KEY_MEDIA
	 * BTN_1 = KEY_VOICECOMMAND
	 * BTN_2 = KEY_VOLUMEUP
	 * BTN_3 = KEY_VOLUMEDOWN
	 */

	if (module->button_mask & SND_JACK_BTN_0) {
		ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_0,
				       KEY_MEDIA);
		if (ret) {
			dev_err(module->dev, "Failed to set BTN_0\n");
			return ret;
		}
	}

	if (module->button_mask & SND_JACK_BTN_1) {
		ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_1,
				       KEY_VOICECOMMAND);
		if (ret) {
			dev_err(module->dev, "Failed to set BTN_1\n");
			return ret;
		}
	}

	if (module->button_mask & SND_JACK_BTN_2) {
		ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_2,
				       KEY_VOLUMEUP);
		if (ret) {
			dev_err(module->dev, "Failed to set BTN_2\n");
			return ret;
		}
	}

	if (module->button_mask & SND_JACK_BTN_3) {
		ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_3,
				       KEY_VOLUMEDOWN);
		if (ret) {
			dev_err(module->dev, "Failed to set BTN_0\n");
			return ret;
		}
	}

	/* FIXME
	 * verify if this is really required
	set_bit(INPUT_PROP_NO_DUMMY_RELEASE,
		module->button_jack.jack->input_dev->propbit);
	*/

	return 0;
}

int gbaudio_register_module(struct gbaudio_module_info *module)
{
	int ret;
	struct snd_soc_codec *codec;
	struct snd_card *card;
	struct snd_soc_jack *jack = NULL;

	if (!gbcodec) {
		dev_err(module->dev, "GB Codec not yet probed\n");
		return -EAGAIN;
	}

	codec = gbcodec->codec;
	card = codec->card->snd_card;

	down_write(&card->controls_rwsem);

	if (module->num_dais) {
		dev_err(gbcodec->dev,
			"%d:DAIs not supported via gbcodec driver\n",
			module->num_dais);
		up_write(&card->controls_rwsem);
		return -EINVAL;
	}

	ret = gbaudio_init_jack(module, codec);
	if (ret) {
		up_write(&card->controls_rwsem);
		return ret;
	}

	if (module->dapm_widgets)
		snd_soc_dapm_new_controls(&codec->dapm, module->dapm_widgets,
					  module->num_dapm_widgets);
	if (module->controls)
		snd_soc_add_codec_controls(codec, module->controls,
				     module->num_controls);
	if (module->dapm_routes)
		snd_soc_dapm_add_routes(&codec->dapm, module->dapm_routes,
					module->num_dapm_routes);

	/* card already instantiated, create widgets here only */
	if (codec->card->instantiated) {
		snd_soc_dapm_link_component_dai_widgets(codec->card,
							&codec->dapm);
#ifdef CONFIG_SND_JACK
		/* register jack devices for this module from codec->jack_list */
		list_for_each_entry(jack, &codec->jack_list, list) {
			if ((jack == &module->headset_jack)
			    || (jack == &module->button_jack))
				snd_device_register(codec->card->snd_card,
						    jack->jack);
		}
#endif
	}

	mutex_lock(&gbcodec->lock);
	list_add(&module->list, &gbcodec->module_list);
	mutex_unlock(&gbcodec->lock);

	if (codec->card->instantiated)
		ret = snd_soc_dapm_new_widgets(&codec->dapm);
	dev_dbg(codec->dev, "Registered %s module\n", module->name);

	up_write(&card->controls_rwsem);
	return ret;
}
EXPORT_SYMBOL(gbaudio_register_module);

static void gbaudio_codec_clean_data_tx(struct gbaudio_data_connection *data)
{
	u16 i2s_port, cportid;
	int ret;

	if (list_is_singular(&gbcodec->module_list)) {
		ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
		if (ret)
			return;
		ret = gb_audio_apbridgea_shutdown_tx(data->connection,
						     0);
		if (ret)
			return;
	}
	i2s_port = 0;	/* fixed for now */
	cportid = data->connection->hd_cport_id;
	ret = gb_audio_apbridgea_unregister_cport(data->connection,
						  i2s_port, cportid,
						  AUDIO_APBRIDGEA_DIRECTION_TX);
	data->state[0] = GBAUDIO_CODEC_SHUTDOWN;
}

static void gbaudio_codec_clean_data_rx(struct gbaudio_data_connection *data)
{
	u16 i2s_port, cportid;
	int ret;

	if (list_is_singular(&gbcodec->module_list)) {
		ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
		if (ret)
			return;
		ret = gb_audio_apbridgea_shutdown_rx(data->connection,
						     0);
		if (ret)
			return;
	}
	i2s_port = 0;	/* fixed for now */
	cportid = data->connection->hd_cport_id;
	ret = gb_audio_apbridgea_unregister_cport(data->connection,
						  i2s_port, cportid,
						  AUDIO_APBRIDGEA_DIRECTION_RX);
	data->state[1] = GBAUDIO_CODEC_SHUTDOWN;
}


static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
{
	struct gbaudio_data_connection *data;
	int pb_state, cap_state;

	dev_dbg(gbcodec->dev, "%s: removed, cleanup APBridge\n", module->name);
	list_for_each_entry(data, &module->data_list, list) {
		pb_state = data->state[0];
		cap_state = data->state[1];

		if (pb_state > GBAUDIO_CODEC_SHUTDOWN)
			gbaudio_codec_clean_data_tx(data);

		if (cap_state > GBAUDIO_CODEC_SHUTDOWN)
			gbaudio_codec_clean_data_rx(data);

	}
}

void gbaudio_unregister_module(struct gbaudio_module_info *module)
{
	struct snd_soc_codec *codec = gbcodec->codec;
	struct snd_card *card = codec->card->snd_card;
	struct snd_soc_jack *jack, *next_j;
	int mask;

	dev_dbg(codec->dev, "Unregister %s module\n", module->name);

	down_write(&card->controls_rwsem);
	mutex_lock(&gbcodec->lock);
	gbaudio_codec_cleanup(module);
	list_del(&module->list);
	dev_dbg(codec->dev, "Process Unregister %s module\n", module->name);
	mutex_unlock(&gbcodec->lock);

#ifdef CONFIG_SND_JACK
	/* free jack devices for this module from codec->jack_list */
	list_for_each_entry_safe(jack, next_j, &codec->jack_list, list) {
		if (jack == &module->headset_jack)
			mask = GBCODEC_JACK_MASK;
		else if (jack == &module->button_jack)
			mask = GBCODEC_JACK_BUTTON_MASK;
		else
			mask = 0;
		if (mask) {
			dev_dbg(module->dev, "Report %s removal\n",
				jack->jack->id);
			snd_soc_jack_report(jack, 0, mask);
			snd_device_free(codec->card->snd_card, jack->jack);
			list_del(&jack->list);
		}
	}
#endif

	if (module->dapm_routes) {
		dev_dbg(codec->dev, "Removing %d routes\n",
			module->num_dapm_routes);
		snd_soc_dapm_del_routes(&codec->dapm, module->dapm_routes,
					module->num_dapm_routes);
	}
	if (module->controls) {
		dev_dbg(codec->dev, "Removing %d controls\n",
			module->num_controls);
		snd_soc_remove_codec_controls(codec, module->controls,
					  module->num_controls);
	}
	if (module->dapm_widgets) {
		dev_dbg(codec->dev, "Removing %d widgets\n",
			module->num_dapm_widgets);
		snd_soc_dapm_free_controls(&codec->dapm, module->dapm_widgets,
					   module->num_dapm_widgets);
	}

	dev_dbg(codec->dev, "Unregistered %s module\n", module->name);

	up_write(&card->controls_rwsem);
}
EXPORT_SYMBOL(gbaudio_unregister_module);

/*
 * codec driver ops
 */
static int gbcodec_probe(struct snd_soc_codec *codec)
{
	int i;
	struct gbaudio_codec_info *info;
	struct gbaudio_codec_dai *dai;

	info = devm_kzalloc(codec->dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = codec->dev;
	INIT_LIST_HEAD(&info->module_list);
	mutex_init(&info->lock);
	INIT_LIST_HEAD(&info->dai_list);

	/* init dai_list used to maintain runtime stream info */
	for (i = 0; i < ARRAY_SIZE(gbaudio_dai); i++) {
		dai = devm_kzalloc(codec->dev, sizeof(*dai), GFP_KERNEL);
		if (!dai)
			return -ENOMEM;
		dai->id = gbaudio_dai[i].id;
		list_add(&dai->list, &info->dai_list);
	}

	info->codec = codec;
	snd_soc_codec_set_drvdata(codec, info);
	gbcodec = info;

	device_init_wakeup(codec->dev, 1);
	return 0;
}

static int gbcodec_remove(struct snd_soc_codec *codec)
{
	/* Empty function for now */
	return 0;
}

static u8 gbcodec_reg[GBCODEC_REG_COUNT] = {
	[GBCODEC_CTL_REG] = GBCODEC_CTL_REG_DEFAULT,
	[GBCODEC_MUTE_REG] = GBCODEC_MUTE_REG_DEFAULT,
	[GBCODEC_PB_LVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT,
	[GBCODEC_PB_RVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT,
	[GBCODEC_CAP_LVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT,
	[GBCODEC_CAP_RVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT,
	[GBCODEC_APB1_MUX_REG] = GBCODEC_APB1_MUX_REG_DEFAULT,
	[GBCODEC_APB2_MUX_REG] = GBCODEC_APB2_MUX_REG_DEFAULT,
};

static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg,
			 unsigned int value)
{
	int ret = 0;

	if (reg == SND_SOC_NOPM)
		return 0;

	BUG_ON(reg >= GBCODEC_REG_COUNT);

	gbcodec_reg[reg] = value;
	dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, value);

	return ret;
}

static unsigned int gbcodec_read(struct snd_soc_codec *codec,
				 unsigned int reg)
{
	unsigned int val = 0;

	if (reg == SND_SOC_NOPM)
		return 0;

	BUG_ON(reg >= GBCODEC_REG_COUNT);

	val = gbcodec_reg[reg];
	dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, val);

	return val;
}

static struct snd_soc_codec_driver soc_codec_dev_gbaudio = {
	.probe	= gbcodec_probe,
	.remove	= gbcodec_remove,

	.read = gbcodec_read,
	.write = gbcodec_write,

	.reg_cache_size = GBCODEC_REG_COUNT,
	.reg_cache_default = gbcodec_reg_defaults,
	.reg_word_size = 1,

	.idle_bias_off = true,
	.ignore_pmdown_time = 1,
};

#ifdef CONFIG_PM
static int gbaudio_codec_suspend(struct device *dev)
{
	dev_dbg(dev, "%s: suspend\n", __func__);
	return 0;
}

static int gbaudio_codec_resume(struct device *dev)
{
	dev_dbg(dev, "%s: resume\n", __func__);
	return 0;
}

static const struct dev_pm_ops gbaudio_codec_pm_ops = {
	.suspend	= gbaudio_codec_suspend,
	.resume		= gbaudio_codec_resume,
};
#endif

static int gbaudio_codec_probe(struct platform_device *pdev)
{
	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_gbaudio,
			gbaudio_dai, ARRAY_SIZE(gbaudio_dai));
}

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

static const struct of_device_id greybus_asoc_machine_of_match[]  = {
	{ .compatible = "toshiba,apb-dummy-codec", },
	{},
};

static struct platform_driver gbaudio_codec_driver = {
	.driver = {
		.name = "apb-dummy-codec",
		.owner = THIS_MODULE,
#ifdef CONFIG_PM
		.pm = &gbaudio_codec_pm_ops,
#endif
		.of_match_table = greybus_asoc_machine_of_match,
	},
	.probe = gbaudio_codec_probe,
	.remove = gbaudio_codec_remove,
};
module_platform_driver(gbaudio_codec_driver);

MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:apb-dummy-codec");
