/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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/slimbus/slimbus.h>
#include <btfm_slim.h>
#include <btfm_slim_wcn3990.h>

/* WCN3990 Port assignment */
struct btfmslim_ch wcn3990_rxport[] = {
	{.id = BTFM_BT_SCO_A2DP_SLIM_RX, .name = "SCO_A2P_Rx",
	.port = CHRK_SB_PGD_PORT_RX_SCO},
	{.id = BTFM_BT_SPLIT_A2DP_SLIM_RX, .name = "A2P_Rx",
	.port = CHRK_SB_PGD_PORT_RX_A2P},
	{.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "",
	.port = BTFM_SLIM_PGD_PORT_LAST},
};

struct btfmslim_ch wcn3990_txport[] = {
	{.id = BTFM_FM_SLIM_TX, .name = "FM_Tx1",
	.port = CHRK_SB_PGD_PORT_TX1_FM},
	{.id = BTFM_FM_SLIM_TX, .name = "FM_Tx2",
	.port = CHRK_SB_PGD_PORT_TX2_FM},
	{.id = BTFM_BT_SCO_SLIM_TX, .name = "SCO_Tx",
	.port = CHRK_SB_PGD_PORT_TX_SCO},
	{.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "",
	.port = BTFM_SLIM_PGD_PORT_LAST},
};

/* Function description */
int btfm_slim_chrk_hw_init(struct btfmslim *btfmslim)
{
	int ret = 0;
	uint8_t reg_val;
	uint16_t reg;

	BTFMSLIM_DBG("");

	if (!btfmslim)
		return -EINVAL;

	/* Get SB_SLAVE_HW_REV_MSB value*/
	reg = CHRK_SB_SLAVE_HW_REV_MSB;
	ret = btfm_slim_read(btfmslim, reg,  1, &reg_val, IFD);
	if (ret) {
		BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
		goto error;
	}
	BTFMSLIM_DBG("Major Rev: 0x%x, Minor Rev: 0x%x",
		(reg_val & 0xF0) >> 4, (reg_val & 0x0F));

	/* Get SB_SLAVE_HW_REV_LSB value*/
	reg = CHRK_SB_SLAVE_HW_REV_LSB;
	ret = btfm_slim_read(btfmslim, reg,  1, &reg_val, IFD);
	if (ret) {
		BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
		goto error;
	}
	BTFMSLIM_DBG("Step Rev: 0x%x", reg_val);

error:
	return ret;
}

static inline int is_fm_port(uint8_t port_num)
{
	if (port_num == CHRK_SB_PGD_PORT_TX1_FM ||
		port_num == CHRKVER3_SB_PGD_PORT_TX1_FM ||
		port_num == CHRKVER3_SB_PGD_PORT_TX2_FM ||
		port_num == CHRK_SB_PGD_PORT_TX2_FM)
		return 1;
	else
		return 0;
}

int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num,
	uint8_t rxport, uint8_t enable)
{
	int ret = 0;
	uint8_t reg_val = 0, en;
	uint8_t rxport_num = 0;
	uint16_t reg;
	uint8_t prev_reg_val = 0;

	BTFMSLIM_DBG("port(%d) enable(%d)", port_num, enable);
	if (rxport) {
		BTFMSLIM_DBG("sample rate is %d", btfmslim->sample_rate);
		if (enable) {
			/* For SCO Rx, A2DP Rx other than 44.1 and 88.2Khz */
			if (port_num < 24) {
				rxport_num = port_num - 16;
				reg_val = 0x01 << rxport_num;
				reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_0(
					rxport_num);
			} else {
				rxport_num = port_num - 24;
				reg_val = 0x01 << rxport_num;
				reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_1(
					rxport_num);
			}

			if (btfmslim->sample_rate == 44100 ||
				btfmslim->sample_rate == 88200) {
				BTFMSLIM_DBG("unsetting multichannel bit");
				ret = btfm_slim_read(btfmslim, reg,  1,
							&prev_reg_val, IFD);
				if (ret < 0) {
					BTFMSLIM_ERR("error %d reading", ret);
					prev_reg_val = 0;
				}
				BTFMSLIM_DBG("prev_reg_val (%d) from reg(%x)",
						prev_reg_val, reg);
				reg_val = prev_reg_val & ~reg_val;
			} else
				BTFMSLIM_DBG("setting multichannel bit");

			BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
				reg_val, reg);
			ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
			if (ret) {
				BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
					ret, reg);
				goto error;
			}
		}
		/* Port enable */
		reg = CHRK_SB_PGD_PORT_RX_CFGN(port_num - 0x10);
		goto enable_disable_rxport;
	}
	if (!enable)
		goto enable_disable_txport;

	/* txport */
	/* Multiple Channel Setting */
	if (is_fm_port(port_num)) {
		if (port_num == CHRKVER3_SB_PGD_PORT_TX1_FM)
			reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX1_FM);
		else if (port_num == CHRKVER3_SB_PGD_PORT_TX2_FM)
			reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX2_FM);
		else
			reg_val = (0x1 << CHRK_SB_PGD_PORT_TX1_FM) |
					(0x1 << CHRK_SB_PGD_PORT_TX2_FM);

		reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
		BTFMSLIM_INFO("writing reg_val (%d) to reg(%x)", reg_val, reg);
		ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
		if (ret) {
			BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
			goto error;
		}
	} else if (port_num == CHRK_SB_PGD_PORT_TX_SCO) {
		/* SCO Tx */
		reg_val = 0x1 << CHRK_SB_PGD_PORT_TX_SCO;
		reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
		BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
				reg_val, reg);
		ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
		if (ret) {
			BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
					ret, reg);
			goto error;
		}
	}

	/* Enable Tx port hw auto recovery for underrun or overrun error */
	reg_val = (CHRK_ENABLE_OVERRUN_AUTO_RECOVERY |
				CHRK_ENABLE_UNDERRUN_AUTO_RECOVERY);
	reg = CHRK_SB_PGD_PORT_TX_OR_UR_CFGN(port_num);
	ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
	if (ret) {
		BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
		goto error;
	}

enable_disable_txport:
	/* Port enable */
	reg = CHRK_SB_PGD_PORT_TX_CFGN(port_num);

enable_disable_rxport:
	if (enable)
		en = CHRK_SB_PGD_PORT_ENABLE;
	else
		en = CHRK_SB_PGD_PORT_DISABLE;

	if (is_fm_port(port_num))
		reg_val = en | CHRK_SB_PGD_PORT_WM_L8;
	else if (port_num == CHRK_SB_PGD_PORT_TX_SCO)
		reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_L1 : en;
	else
		reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_LB : en;

	if (enable && port_num == CHRK_SB_PGD_PORT_TX_SCO)
		BTFMSLIM_INFO("programming SCO Tx with reg_val %d to reg 0x%x",
				reg_val, reg);

	ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
	if (ret)
		BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);

error:
	return ret;
}
