/******************************************************************************
 *
 * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
 * All rights reserved worldwide.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Copyright 2018 NXP
 *
 ******************************************************************************
 *
 * API_HDMI_RX_Audio.c
 *
 ******************************************************************************
 */

#include "API_HDMI_RX_Audio.h"
#include "sink_aif_encoder.h"
#include "aif_pckt2smp.h"
#include "address.h"
#include "util.h"
#include "API_General.h"

CDN_API_STATUS CDN_API_RX_AudioAutoConfig(
						state_struct *state,
						u8 max_ch_num,
						u8 i2s_ports_num,
						u8 dis_port3,
						u8 enc_sample_width,
						u8 i2s_sample_width)
{
	u32 regread;
	u8 num_of_pairs_of_channels_per_port = max_ch_num / (i2s_ports_num * 2);
	u8 enc_size_code;
	u8 i2s_size_code;
	u8 i2s_port3_dis = (dis_port3 != 0 && i2s_ports_num == 4) ? 1 : 0;
	u8 times = 0;

	/* Valid values: 1/2/4. */
	/* 3 ports can be emulated with 'i2s_ports_num = 4' and 'dis_port3 = 1'. */
	if (i2s_ports_num == 0 || i2s_ports_num == 3 || i2s_ports_num > 4)
		return CDN_ERR;

	/* 'dis_port3' makes sense only with 4 ports enabled */
	if (dis_port3 != 0 && i2s_ports_num < 4)
		return CDN_ERR;

	switch (enc_sample_width) {
	case 16:
		enc_size_code = 0x0;
		break;
	case 24:
		enc_size_code = 0x1;
		break;
	case 32:
		enc_size_code = 0x2;
		break;
	default:
		return CDN_ERR;
	}

	switch (i2s_sample_width) {
	case 16:
		i2s_size_code = 0x0;
		break;
	case 24:
		i2s_size_code = 0x1;
		break;
	case 32:
		i2s_size_code = 0x2;
		break;
	default:
		return CDN_ERR;
	}

	/* Maximum number of channels has to be in range from 2 to 32 */
	if (max_ch_num < 2 || max_ch_num > 32)
		return CDN_ERR;
	/* Maximum number of channels has to be power of 2 */
	else if (!(max_ch_num * (max_ch_num - 1)))
		return CDN_ERR;
	/* Each active port shall carry the same number of sub-channels */
	else if (max_ch_num % i2s_ports_num)
		return CDN_ERR;

	/* Disable ACR during configuration */
	if (cdn_apb_write(state, ADDR_AIF_ENCODER + (ACR_CFG << 2), F_ACR_SW_RESET(1)))
		return CDN_ERR;

	/* Configuring audio FIFO */
	if (cdn_apb_write(state,
				ADDR_AIF_ENCODER + ((0x40 + FIFO_CNTL_ADDR) << 2),
				F_CFG_FIFO_SW_RST(0) | F_CFG_INDEX_SYNC_EN(1) |
				F_CFG_FIFO_DIR(1) |   F_CFG_DIS_PORT3(i2s_port3_dis)))
		return CDN_ERR;

	/* Configuring audio parameters */
	if (cdn_apb_write(state,
				ADDR_AIF_ENCODER + ((0x40 + AUDIO_SINK_CNFG) << 2),
				F_ENC_LOW_INDEX_MSB(0) | F_SINK_AUDIO_CH_NUM(max_ch_num - 1) |
				F_ENC_SAMPLE_JUST(0x0) | F_ENC_SMPL_WIDTH(enc_size_code) |
				F_I2S_ENC_WL_SIZE(i2s_size_code) | F_CNTL_SMPL_ONLY_EN(1) |
				F_CNTL_TYPE_OVRD(0x0) | F_CNTL_TYPE_OVRD_EN(0) |
				F_I2S_ENC_PORT_EN((1 << i2s_ports_num) - 1) | F_WS_POLARITY(0)))
		return CDN_ERR;

	/* Waiting for N value... */
	do {
		if (cdn_apb_read(state,
					ADDR_AIF_ENCODER + (AIF_ACR_N_ST << 2), &regread))
			return CDN_ERR;
		times++;
		udelay(10);
	} while (!(regread) && times < 100);

	if (times == 100)
		return CDN_ERR;

	/* Enable ACR */
	if (cdn_apb_write(state,
				ADDR_AIF_ENCODER + (ACR_CFG << 2), F_ACR_SW_RESET(0)))
		return CDN_ERR;

	/* Important: */
	/* Write to AIF_ACR_N_OFST_CFG register is interpreted as new N_CTS value. */
	/* The ACR has to be enabled (reset released) to register that event. */

	if (cdn_apb_write(state,
				ADDR_AIF_ENCODER + (AIF_ACR_N_OFST_CFG << 2),
				F_ACR_N_OFFSET(regread * (num_of_pairs_of_channels_per_port - 1))))
		return CDN_ERR;

	/* Enable sample decoder */
	if (cdn_apb_write(state,
				ADDR_AIF_ENCODER + (PKT2SMPL_CNTL << 2), F_PKT2SMPL_EN(1)))
		return CDN_ERR;

	/* Enable I2S encoder */
	if (cdn_apb_write(state,
				ADDR_AIF_ENCODER + ((0x40 + AUDIO_SINK_CNTL) << 2),	F_I2S_ENC_START(1)))
		return CDN_ERR;

	return CDN_OK;

}

CDN_API_STATUS CDN_API_RX_AudioAutoConfig_blocking(state_struct *state,
						   u8 max_ch_num,
						   u8 i2s_ports_num,
						   u8 dis_port3,
						   u8 enc_sample_width,
						   u8 i2s_sample_width)
{
	internal_block_function(&state->mutex,
							CDN_API_RX_AudioAutoConfig(state,
							max_ch_num,
							i2s_ports_num,
							dis_port3,
							enc_sample_width,
							i2s_sample_width));
}
