/*
 * Copyright (C) STMicroelectronics SA 2015
 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
 *          for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include <linux/clk.h>
#include <linux/mfd/syscon.h>

#include <sound/asoundef.h>
#include <sound/soc.h>

#include "uniperif.h"

/*
 * Some hardware-related definitions
 */

/* sys config registers definitions */
#define SYS_CFG_AUDIO_GLUE 0xA4

/*
 * Driver specific types.
 */

#define UNIPERIF_PLAYER_CLK_ADJ_MIN  -999999
#define UNIPERIF_PLAYER_CLK_ADJ_MAX  1000000
#define UNIPERIF_PLAYER_I2S_OUT 1 /* player id connected to I2S/TDM TX bus */

/*
 * Note: snd_pcm_hardware is linked to DMA controller but is declared here to
 * integrate  DAI_CPU capability in term of rate and supported channels
 */
static const struct snd_pcm_hardware uni_player_pcm_hw = {
	.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_MMAP_VALID,
	.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,

	.rates = SNDRV_PCM_RATE_CONTINUOUS,
	.rate_min = 8000,
	.rate_max = 192000,

	.channels_min = 2,
	.channels_max = 8,

	.periods_min = 2,
	.periods_max = 48,

	.period_bytes_min = 128,
	.period_bytes_max = 64 * PAGE_SIZE,
	.buffer_bytes_max = 256 * PAGE_SIZE
};

/*
 * uni_player_irq_handler
 * In case of error audio stream is stopped; stop action is protected via PCM
 * stream lock to avoid race condition with trigger callback.
 */
static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
{
	irqreturn_t ret = IRQ_NONE;
	struct uniperif *player = dev_id;
	unsigned int status;
	unsigned int tmp;

	spin_lock(&player->irq_lock);
	if (!player->substream)
		goto irq_spin_unlock;

	snd_pcm_stream_lock(player->substream);
	if (player->state == UNIPERIF_STATE_STOPPED)
		goto stream_unlock;

	/* Get interrupt status & clear them immediately */
	status = GET_UNIPERIF_ITS(player);
	SET_UNIPERIF_ITS_BCLR(player, status);

	/* Check for fifo error (underrun) */
	if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(player))) {
		dev_err(player->dev, "FIFO underflow error detected\n");

		/* Interrupt is just for information when underflow recovery */
		if (player->underflow_enabled) {
			/* Update state to underflow */
			player->state = UNIPERIF_STATE_UNDERFLOW;

		} else {
			/* Disable interrupt so doesn't continually fire */
			SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);

			/* Stop the player */
			snd_pcm_stop_xrun(player->substream);
		}

		ret = IRQ_HANDLED;
	}

	/* Check for dma error (overrun) */
	if (unlikely(status & UNIPERIF_ITS_DMA_ERROR_MASK(player))) {
		dev_err(player->dev, "DMA error detected\n");

		/* Disable interrupt so doesn't continually fire */
		SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);

		/* Stop the player */
		snd_pcm_stop_xrun(player->substream);

		ret = IRQ_HANDLED;
	}

	/* Check for underflow recovery done */
	if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) {
		if (!player->underflow_enabled) {
			dev_err(player->dev,
				"unexpected Underflow recovering\n");
			ret = -EPERM;
			goto stream_unlock;
		}
		/* Read the underflow recovery duration */
		tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
		dev_dbg(player->dev, "Underflow recovered (%d LR clocks max)\n",
			tmp);

		/* Clear the underflow recovery duration */
		SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(player);

		/* Update state to started */
		player->state = UNIPERIF_STATE_STARTED;

		ret = IRQ_HANDLED;
	}

	/* Check if underflow recovery failed */
	if (unlikely(status &
		     UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(player))) {
		dev_err(player->dev, "Underflow recovery failed\n");

		/* Stop the player */
		snd_pcm_stop_xrun(player->substream);

		ret = IRQ_HANDLED;
	}

stream_unlock:
	snd_pcm_stream_unlock(player->substream);
irq_spin_unlock:
	spin_unlock(&player->irq_lock);

	return ret;
}

static int uni_player_clk_set_rate(struct uniperif *player, unsigned long rate)
{
	int rate_adjusted, rate_achieved, delta, ret;
	int adjustment = player->clk_adj;

	/*
	 *             a
	 * F = f + --------- * f = f + d
	 *          1000000
	 *
	 *         a
	 * d = --------- * f
	 *      1000000
	 *
	 * where:
	 *   f - nominal rate
	 *   a - adjustment in ppm (parts per milion)
	 *   F - rate to be set in synthesizer
	 *   d - delta (difference) between f and F
	 */
	if (adjustment < 0) {
		/* div64_64 operates on unsigned values... */
		delta = -1;
		adjustment = -adjustment;
	} else {
		delta = 1;
	}
	/* 500000 ppm is 0.5, which is used to round up values */
	delta *= (int)div64_u64((uint64_t)rate *
				(uint64_t)adjustment + 500000, 1000000);
	rate_adjusted = rate + delta;

	/* Adjusted rate should never be == 0 */
	if (!rate_adjusted)
		return -EINVAL;

	ret = clk_set_rate(player->clk, rate_adjusted);
	if (ret < 0)
		return ret;

	rate_achieved = clk_get_rate(player->clk);
	if (!rate_achieved)
		/* If value is 0 means that clock or parent not valid */
		return -EINVAL;

	/*
	 * Using ALSA's adjustment control, we can modify the rate to be up
	 * to twice as much as requested, but no more
	 */
	delta = rate_achieved - rate;
	if (delta < 0) {
		/* div64_64 operates on unsigned values... */
		delta = -delta;
		adjustment = -1;
	} else {
		adjustment = 1;
	}
	/* Frequency/2 is added to round up result */
	adjustment *= (int)div64_u64((uint64_t)delta * 1000000 + rate / 2,
				     rate);
	player->clk_adj = adjustment;
	return 0;
}

static void uni_player_set_channel_status(struct uniperif *player,
					  struct snd_pcm_runtime *runtime)
{
	int n;
	unsigned int status;

	/*
	 * Some AVRs and TVs require the channel status to contain a correct
	 * sampling frequency. If no sample rate is already specified, then
	 * set one.
	 */
	if (runtime) {
		switch (runtime->rate) {
		case 22050:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_22050;
			break;
		case 44100:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_44100;
			break;
		case 88200:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_88200;
			break;
		case 176400:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_176400;
			break;
		case 24000:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_24000;
			break;
		case 48000:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_48000;
			break;
		case 96000:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_96000;
			break;
		case 192000:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_192000;
			break;
		case 32000:
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_32000;
			break;
		default:
			/* Mark as sampling frequency not indicated */
			player->stream_settings.iec958.status[3] =
						IEC958_AES3_CON_FS_NOTID;
			break;
		}
	}

	/* Audio mode:
	 * Use audio mode status to select PCM or encoded mode
	 */
	if (player->stream_settings.iec958.status[0] & IEC958_AES0_NONAUDIO)
		player->stream_settings.encoding_mode =
			UNIPERIF_IEC958_ENCODING_MODE_ENCODED;
	else
		player->stream_settings.encoding_mode =
			UNIPERIF_IEC958_ENCODING_MODE_PCM;

	if (player->stream_settings.encoding_mode ==
		UNIPERIF_IEC958_ENCODING_MODE_PCM)
		/* Clear user validity bits */
		SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
	else
		/* Set user validity bits */
		SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 1);

	/* Program the new channel status */
	for (n = 0; n < 6; ++n) {
		status  =
		player->stream_settings.iec958.status[0 + (n * 4)] & 0xf;
		status |=
		player->stream_settings.iec958.status[1 + (n * 4)] << 8;
		status |=
		player->stream_settings.iec958.status[2 + (n * 4)] << 16;
		status |=
		player->stream_settings.iec958.status[3 + (n * 4)] << 24;
		SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
	}

	/* Update the channel status */
	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
		SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
	else
		SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
}

static int uni_player_prepare_iec958(struct uniperif *player,
				     struct snd_pcm_runtime *runtime)
{
	int clk_div;

	clk_div = player->mclk / runtime->rate;

	/* Oversampling must be multiple of 128 as iec958 frame is 32-bits */
	if ((clk_div % 128) || (clk_div <= 0)) {
		dev_err(player->dev, "%s: invalid clk_div %d\n",
			__func__, clk_div);
		return -EINVAL;
	}

	switch (runtime->format) {
	case SNDRV_PCM_FORMAT_S16_LE:
		/* 16/16 memory format */
		SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
		/* 16-bits per sub-frame */
		SET_UNIPERIF_I2S_FMT_NBIT_32(player);
		/* Set 16-bit sample precision */
		SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		/* 16/0 memory format */
		SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
		/* 32-bits per sub-frame */
		SET_UNIPERIF_I2S_FMT_NBIT_32(player);
		/* Set 24-bit sample precision */
		SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(player);
		break;
	default:
		dev_err(player->dev, "format not supported\n");
		return -EINVAL;
	}

	/* Set parity to be calculated by the hardware */
	SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(player);

	/* Set channel status bits to be inserted by the hardware */
	SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(player);

	/* Set user data bits to be inserted by the hardware */
	SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(player);

	/* Set validity bits to be inserted by the hardware */
	SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(player);

	/* Set full software control to disabled */
	SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(player);

	SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);

	mutex_lock(&player->ctrl_lock);
	/* Update the channel status */
	uni_player_set_channel_status(player, runtime);
	mutex_unlock(&player->ctrl_lock);

	/* Clear the user validity user bits */
	SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);

	/* Disable one-bit audio mode */
	SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);

	/* Enable consecutive frames repetition of Z preamble (not for HBRA) */
	SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(player);

	/* Change to SUF0_SUBF1 and left/right channels swap! */
	SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(player);

	/* Set data output as MSB first */
	SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);

	if (player->stream_settings.encoding_mode ==
				UNIPERIF_IEC958_ENCODING_MODE_ENCODED)
		SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(player);
	else
		SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(player);

	SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);

	/* Set rounding to off */
	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);

	/* Set clock divisor */
	SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / 128);

	/* Set the spdif latency to not wait before starting player */
	SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);

	/*
	 * Ensure iec958 formatting is off. It will be enabled in function
	 * uni_player_start() at the same time as the operation
	 * mode is set to work around a silicon issue.
	 */
	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
		SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
	else
		SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);

	return 0;
}

static int uni_player_prepare_pcm(struct uniperif *player,
				  struct snd_pcm_runtime *runtime)
{
	int output_frame_size, slot_width, clk_div;

	/* Force slot width to 32 in I2S mode (HW constraint) */
	if ((player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
		SND_SOC_DAIFMT_I2S)
		slot_width = 32;
	else
		slot_width = snd_pcm_format_width(runtime->format);

	output_frame_size = slot_width * runtime->channels;

	clk_div = player->mclk / runtime->rate;
	/*
	 * For 32 bits subframe clk_div must be a multiple of 128,
	 * for 16 bits must be a multiple of 64
	 */
	if ((slot_width == 32) && (clk_div % 128)) {
		dev_err(player->dev, "%s: invalid clk_div\n", __func__);
		return -EINVAL;
	}

	if ((slot_width == 16) && (clk_div % 64)) {
		dev_err(player->dev, "%s: invalid clk_div\n", __func__);
		return -EINVAL;
	}

	/*
	 * Number of bits per subframe (which is one channel sample)
	 * on output - Transfer 16 or 32 bits from FIFO
	 */
	switch (slot_width) {
	case 32:
		SET_UNIPERIF_I2S_FMT_NBIT_32(player);
		SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
		break;
	case 16:
		SET_UNIPERIF_I2S_FMT_NBIT_16(player);
		SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
		break;
	default:
		dev_err(player->dev, "subframe format not supported\n");
		return -EINVAL;
	}

	/* Configure data memory format */
	switch (runtime->format) {
	case SNDRV_PCM_FORMAT_S16_LE:
		/* One data word contains two samples */
		SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
		break;

	case SNDRV_PCM_FORMAT_S32_LE:
		/*
		 * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
		 * on the left than zeros (if less than 32 bytes)"... ;-)
		 */
		SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
		break;

	default:
		dev_err(player->dev, "format not supported\n");
		return -EINVAL;
	}

	/* Set rounding to off */
	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);

	/* Set clock divisor */
	SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / (2 * output_frame_size));

	/* Number of channelsmust be even*/
	if ((runtime->channels % 2) || (runtime->channels < 2) ||
	    (runtime->channels > 10)) {
		dev_err(player->dev, "%s: invalid nb of channels\n", __func__);
		return -EINVAL;
	}

	SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);

	/* Set 1-bit audio format to disabled */
	SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);

	SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);

	/* No iec958 formatting as outputting to DAC  */
	SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);

	return 0;
}

static int uni_player_prepare_tdm(struct uniperif *player,
				  struct snd_pcm_runtime *runtime)
{
	int tdm_frame_size; /* unip tdm frame size in bytes */
	int user_frame_size; /* user tdm frame size in bytes */
	/* default unip TDM_WORD_POS_X_Y */
	unsigned int word_pos[4] = {
		0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};
	int freq, ret;

	tdm_frame_size =
		sti_uniperiph_get_unip_tdm_frame_size(player);
	user_frame_size =
		sti_uniperiph_get_user_frame_size(runtime);

	/* fix 16/0 format */
	SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
	SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);

	/* number of words inserted on the TDM line */
	SET_UNIPERIF_I2S_FMT_NUM_CH(player, user_frame_size / 4 / 2);

	SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
	SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);

	/* Enable the tdm functionality */
	SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(player);

	/* number of 8 bits timeslots avail in unip tdm frame */
	SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(player, tdm_frame_size);

	/* set the timeslot allocation for words in FIFO */
	sti_uniperiph_get_tdm_word_pos(player, word_pos);
	SET_UNIPERIF_TDM_WORD_POS(player, 1_2, word_pos[WORD_1_2]);
	SET_UNIPERIF_TDM_WORD_POS(player, 3_4, word_pos[WORD_3_4]);
	SET_UNIPERIF_TDM_WORD_POS(player, 5_6, word_pos[WORD_5_6]);
	SET_UNIPERIF_TDM_WORD_POS(player, 7_8, word_pos[WORD_7_8]);

	/* set unip clk rate (not done vai set_sysclk ops) */
	freq = runtime->rate * tdm_frame_size * 8;
	mutex_lock(&player->ctrl_lock);
	ret = uni_player_clk_set_rate(player, freq);
	if (!ret)
		player->mclk = freq;
	mutex_unlock(&player->ctrl_lock);

	return 0;
}

/*
 * ALSA uniperipheral iec958 controls
 */
static int  uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
	uinfo->count = 1;

	return 0;
}

static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;
	struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;

	mutex_lock(&player->ctrl_lock);
	ucontrol->value.iec958.status[0] = iec958->status[0];
	ucontrol->value.iec958.status[1] = iec958->status[1];
	ucontrol->value.iec958.status[2] = iec958->status[2];
	ucontrol->value.iec958.status[3] = iec958->status[3];
	mutex_unlock(&player->ctrl_lock);
	return 0;
}

static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;
	struct snd_aes_iec958 *iec958 =  &player->stream_settings.iec958;
	unsigned long flags;

	mutex_lock(&player->ctrl_lock);
	iec958->status[0] = ucontrol->value.iec958.status[0];
	iec958->status[1] = ucontrol->value.iec958.status[1];
	iec958->status[2] = ucontrol->value.iec958.status[2];
	iec958->status[3] = ucontrol->value.iec958.status[3];

	spin_lock_irqsave(&player->irq_lock, flags);
	if (player->substream && player->substream->runtime)
		uni_player_set_channel_status(player,
					      player->substream->runtime);
	else
		uni_player_set_channel_status(player, NULL);

	spin_unlock_irqrestore(&player->irq_lock, flags);
	mutex_unlock(&player->ctrl_lock);

	return 0;
}

static struct snd_kcontrol_new uni_player_iec958_ctl = {
	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
	.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
	.info = uni_player_ctl_iec958_info,
	.get = uni_player_ctl_iec958_get,
	.put = uni_player_ctl_iec958_put,
};

/*
 * uniperif rate adjustement control
 */
static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN;
	uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX;
	uinfo->value.integer.step = 1;

	return 0;
}

static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;

	mutex_lock(&player->ctrl_lock);
	ucontrol->value.integer.value[0] = player->clk_adj;
	mutex_unlock(&player->ctrl_lock);

	return 0;
}

static int snd_sti_clk_adjustment_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;
	int ret = 0;

	if ((ucontrol->value.integer.value[0] < UNIPERIF_PLAYER_CLK_ADJ_MIN) ||
	    (ucontrol->value.integer.value[0] > UNIPERIF_PLAYER_CLK_ADJ_MAX))
		return -EINVAL;

	mutex_lock(&player->ctrl_lock);
	player->clk_adj = ucontrol->value.integer.value[0];

	if (player->mclk)
		ret = uni_player_clk_set_rate(player, player->mclk);
	mutex_unlock(&player->ctrl_lock);

	return ret;
}

static struct snd_kcontrol_new uni_player_clk_adj_ctl = {
	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
	.name = "PCM Playback Oversampling Freq. Adjustment",
	.info = snd_sti_clk_adjustment_info,
	.get = snd_sti_clk_adjustment_get,
	.put = snd_sti_clk_adjustment_put,
};

static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = {
	&uni_player_clk_adj_ctl,
};

static struct snd_kcontrol_new *snd_sti_iec_ctl[] = {
	&uni_player_iec958_ctl,
	&uni_player_clk_adj_ctl,
};

static int uni_player_startup(struct snd_pcm_substream *substream,
			      struct snd_soc_dai *dai)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&player->irq_lock, flags);
	player->substream = substream;
	spin_unlock_irqrestore(&player->irq_lock, flags);

	player->clk_adj = 0;

	if (!UNIPERIF_TYPE_IS_TDM(player))
		return 0;

	/* refine hw constraint in tdm mode */
	ret = snd_pcm_hw_rule_add(substream->runtime, 0,
				  SNDRV_PCM_HW_PARAM_CHANNELS,
				  sti_uniperiph_fix_tdm_chan,
				  player, SNDRV_PCM_HW_PARAM_CHANNELS,
				  -1);
	if (ret < 0)
		return ret;

	return snd_pcm_hw_rule_add(substream->runtime, 0,
				   SNDRV_PCM_HW_PARAM_FORMAT,
				   sti_uniperiph_fix_tdm_format,
				   player, SNDRV_PCM_HW_PARAM_FORMAT,
				   -1);
}

static int uni_player_set_sysclk(struct snd_soc_dai *dai, int clk_id,
				 unsigned int freq, int dir)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;
	int ret;

	if (UNIPERIF_TYPE_IS_TDM(player) || (dir == SND_SOC_CLOCK_IN))
		return 0;

	if (clk_id != 0)
		return -EINVAL;

	mutex_lock(&player->ctrl_lock);
	ret = uni_player_clk_set_rate(player, freq);
	if (!ret)
		player->mclk = freq;
	mutex_unlock(&player->ctrl_lock);

	return ret;
}

static int uni_player_prepare(struct snd_pcm_substream *substream,
			      struct snd_soc_dai *dai)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;
	struct snd_pcm_runtime *runtime = substream->runtime;
	int transfer_size, trigger_limit;
	int ret;

	/* The player should be stopped */
	if (player->state != UNIPERIF_STATE_STOPPED) {
		dev_err(player->dev, "%s: invalid player state %d\n", __func__,
			player->state);
		return -EINVAL;
	}

	/* Calculate transfer size (in fifo cells and bytes) for frame count */
	if (player->type == SND_ST_UNIPERIF_TYPE_TDM) {
		/* transfer size = user frame size (in 32 bits FIFO cell) */
		transfer_size =
			sti_uniperiph_get_user_frame_size(runtime) / 4;
	} else {
		transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
	}

	/* Calculate number of empty cells available before asserting DREQ */
	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
		trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
	} else {
		/*
		 * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
		 * FDMA_TRIGGER_LIMIT also controls when the state switches
		 * from OFF or STANDBY to AUDIO DATA.
		 */
		trigger_limit = transfer_size;
	}

	/* Trigger limit must be an even number */
	if ((!trigger_limit % 2) || (trigger_limit != 1 && transfer_size % 2) ||
	    (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(player))) {
		dev_err(player->dev, "invalid trigger limit %d\n",
			trigger_limit);
		return -EINVAL;
	}

	SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit);

	/* Uniperipheral setup depends on player type */
	switch (player->type) {
	case SND_ST_UNIPERIF_TYPE_HDMI:
		ret = uni_player_prepare_iec958(player, runtime);
		break;
	case SND_ST_UNIPERIF_TYPE_PCM:
		ret = uni_player_prepare_pcm(player, runtime);
		break;
	case SND_ST_UNIPERIF_TYPE_SPDIF:
		ret = uni_player_prepare_iec958(player, runtime);
		break;
	case SND_ST_UNIPERIF_TYPE_TDM:
		ret = uni_player_prepare_tdm(player, runtime);
		break;
	default:
		dev_err(player->dev, "invalid player type\n");
		return -EINVAL;
	}

	if (ret)
		return ret;

	switch (player->daifmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
		break;
	case SND_SOC_DAIFMT_NB_IF:
		SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
		break;
	case SND_SOC_DAIFMT_IB_NF:
		SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
		break;
	case SND_SOC_DAIFMT_IB_IF:
		SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
		break;
	}

	switch (player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
		SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(player);
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
		SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(player);
		SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
		break;
	default:
		dev_err(player->dev, "format not supported\n");
		return -EINVAL;
	}

	SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(player, 0);


	return sti_uniperiph_reset(player);
}

static int uni_player_start(struct uniperif *player)
{
	int ret;

	/* The player should be stopped */
	if (player->state != UNIPERIF_STATE_STOPPED) {
		dev_err(player->dev, "%s: invalid player state\n", __func__);
		return -EINVAL;
	}

	ret = clk_prepare_enable(player->clk);
	if (ret) {
		dev_err(player->dev, "%s: Failed to enable clock\n", __func__);
		return ret;
	}

	/* Clear any pending interrupts */
	SET_UNIPERIF_ITS_BCLR(player, GET_UNIPERIF_ITS(player));

	/* Set the interrupt mask */
	SET_UNIPERIF_ITM_BSET_DMA_ERROR(player);
	SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player);

	/* Enable underflow recovery interrupts */
	if (player->underflow_enabled) {
		SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player);
		SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player);
	}

	ret = sti_uniperiph_reset(player);
	if (ret < 0) {
		clk_disable_unprepare(player->clk);
		return ret;
	}

	/*
	 * Does not use IEC61937 features of the uniperipheral hardware.
	 * Instead it performs IEC61937 in software and inserts it directly
	 * into the audio data stream. As such, when encoded mode is selected,
	 * linear pcm mode is still used, but with the differences of the
	 * channel status bits set for encoded mode and the validity bits set.
	 */
	SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(player);

	/*
	 * If iec958 formatting is required for hdmi or spdif, then it must be
	 * enabled after the operation mode is set. If set prior to this, it
	 * will not take affect and hang the player.
	 */
	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
		if (UNIPERIF_TYPE_IS_IEC958(player))
			SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);

	/* Force channel status update (no update if clk disable) */
	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
		SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
	else
		SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);

	/* Update state to started */
	player->state = UNIPERIF_STATE_STARTED;

	return 0;
}

static int uni_player_stop(struct uniperif *player)
{
	int ret;

	/* The player should not be in stopped state */
	if (player->state == UNIPERIF_STATE_STOPPED) {
		dev_err(player->dev, "%s: invalid player state\n", __func__);
		return -EINVAL;
	}

	/* Turn the player off */
	SET_UNIPERIF_CTRL_OPERATION_OFF(player);

	ret = sti_uniperiph_reset(player);
	if (ret < 0)
		return ret;

	/* Disable interrupts */
	SET_UNIPERIF_ITM_BCLR(player, GET_UNIPERIF_ITM(player));

	/* Disable clock */
	clk_disable_unprepare(player->clk);

	/* Update state to stopped and return */
	player->state = UNIPERIF_STATE_STOPPED;

	return 0;
}

int uni_player_resume(struct uniperif *player)
{
	int ret;

	/* Select the frequency synthesizer clock */
	if (player->clk_sel) {
		ret = regmap_field_write(player->clk_sel, 1);
		if (ret) {
			dev_err(player->dev,
				"%s: Failed to select freq synth clock\n",
				__func__);
			return ret;
		}
	}

	SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
	SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
	SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);

	return 0;
}
EXPORT_SYMBOL_GPL(uni_player_resume);

static int uni_player_trigger(struct snd_pcm_substream *substream,
			      int cmd, struct snd_soc_dai *dai)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		return uni_player_start(player);
	case SNDRV_PCM_TRIGGER_STOP:
		return uni_player_stop(player);
	case SNDRV_PCM_TRIGGER_RESUME:
		return uni_player_resume(player);
	default:
		return -EINVAL;
	}
}

static void uni_player_shutdown(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *player = priv->dai_data.uni;
	unsigned long flags;

	spin_lock_irqsave(&player->irq_lock, flags);
	if (player->state != UNIPERIF_STATE_STOPPED)
		/* Stop the player */
		uni_player_stop(player);

	player->substream = NULL;
	spin_unlock_irqrestore(&player->irq_lock, flags);
}

static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
					  struct uniperif *player)
{
	struct device_node *node = pdev->dev.of_node;
	struct regmap *regmap;
	struct reg_field regfield[2] = {
		/* PCM_CLK_SEL */
		REG_FIELD(SYS_CFG_AUDIO_GLUE,
			  8 + player->id,
			  8 + player->id),
		/* PCMP_VALID_SEL */
		REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1)
	};

	regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");

	if (IS_ERR(regmap)) {
		dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n");
		return PTR_ERR(regmap);
	}

	player->clk_sel = regmap_field_alloc(regmap, regfield[0]);
	player->valid_sel = regmap_field_alloc(regmap, regfield[1]);

	return 0;
}

static const struct snd_soc_dai_ops uni_player_dai_ops = {
		.startup = uni_player_startup,
		.shutdown = uni_player_shutdown,
		.prepare = uni_player_prepare,
		.trigger = uni_player_trigger,
		.hw_params = sti_uniperiph_dai_hw_params,
		.set_fmt = sti_uniperiph_dai_set_fmt,
		.set_sysclk = uni_player_set_sysclk,
		.set_tdm_slot = sti_uniperiph_set_tdm_slot
};

int uni_player_init(struct platform_device *pdev,
		    struct uniperif *player)
{
	int ret = 0;

	player->dev = &pdev->dev;
	player->state = UNIPERIF_STATE_STOPPED;
	player->dai_ops = &uni_player_dai_ops;

	/* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */
	ret = uni_player_parse_dt_audio_glue(pdev, player);

	if (ret < 0) {
		dev_err(player->dev, "Failed to parse DeviceTree\n");
		return ret;
	}

	/* Underflow recovery is only supported on later ip revisions */
	if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
		player->underflow_enabled = 1;

	if (UNIPERIF_TYPE_IS_TDM(player))
		player->hw = &uni_tdm_hw;
	else
		player->hw = &uni_player_pcm_hw;

	/* Get uniperif resource */
	player->clk = of_clk_get(pdev->dev.of_node, 0);
	if (IS_ERR(player->clk)) {
		dev_err(player->dev, "Failed to get clock\n");
		return PTR_ERR(player->clk);
	}

	/* Select the frequency synthesizer clock */
	if (player->clk_sel) {
		ret = regmap_field_write(player->clk_sel, 1);
		if (ret) {
			dev_err(player->dev,
				"%s: Failed to select freq synth clock\n",
				__func__);
			return ret;
		}
	}

	/* connect to I2S/TDM TX bus */
	if (player->valid_sel &&
	    (player->id == UNIPERIF_PLAYER_I2S_OUT)) {
		ret = regmap_field_write(player->valid_sel, player->id);
		if (ret) {
			dev_err(player->dev,
				"%s: unable to connect to tdm bus\n", __func__);
			return ret;
		}
	}

	ret = devm_request_irq(&pdev->dev, player->irq,
			       uni_player_irq_handler, IRQF_SHARED,
			       dev_name(&pdev->dev), player);
	if (ret < 0) {
		dev_err(player->dev, "unable to request IRQ %d\n", player->irq);
		return ret;
	}

	mutex_init(&player->ctrl_lock);
	spin_lock_init(&player->irq_lock);

	/* Ensure that disabled by default */
	SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
	SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
	SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);

	if (UNIPERIF_TYPE_IS_IEC958(player)) {
		/* Set default iec958 status bits  */

		/* Consumer, PCM, copyright, 2ch, mode 0 */
		player->stream_settings.iec958.status[0] = 0x00;
		/* Broadcast reception category */
		player->stream_settings.iec958.status[1] =
					IEC958_AES1_CON_GENERAL;
		/* Do not take into account source or channel number */
		player->stream_settings.iec958.status[2] =
					IEC958_AES2_CON_SOURCE_UNSPEC;
		/* Sampling frequency not indicated */
		player->stream_settings.iec958.status[3] =
					IEC958_AES3_CON_FS_NOTID;
		/* Max sample word 24-bit, sample word length not indicated */
		player->stream_settings.iec958.status[4] =
					IEC958_AES4_CON_MAX_WORDLEN_24 |
					IEC958_AES4_CON_WORDLEN_24_20;

		player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl);
		player->snd_ctrls = snd_sti_iec_ctl[0];
	} else {
		player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl);
		player->snd_ctrls = snd_sti_pcm_ctl[0];
	}

	return 0;
}
EXPORT_SYMBOL_GPL(uni_player_init);
