/* Copyright (c) 2012-2013, 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/slab.h>
#include <linux/mutex.h>
#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>

struct wcd9xxx_slim_sch {
	u16 rx_port_ch_reg_base;
	u16 port_tx_cfg_reg_base;
	u16 port_rx_cfg_reg_base;
};

static struct wcd9xxx_slim_sch sh_ch;

static int wcd9xxx_alloc_slim_sh_ch(struct wcd9xxx *wcd9xxx,
				    u8 wcd9xxx_pgd_la, u32 cnt,
				    struct wcd9xxx_ch *channels, u32 path);

static int wcd9xxx_dealloc_slim_sh_ch(struct slim_device *slim,
				      u32 cnt, struct wcd9xxx_ch *channels);

static int wcd9xxx_configure_ports(struct wcd9xxx *wcd9xxx)
{
	if (wcd9xxx->slim_slave_type == WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA) {
		sh_ch.rx_port_ch_reg_base = 0x180;
		sh_ch.port_rx_cfg_reg_base = 0x040;
		sh_ch.port_tx_cfg_reg_base = 0x040;
	} else {
		sh_ch.rx_port_ch_reg_base =
			0x180 - (TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS * 4);
		sh_ch.port_rx_cfg_reg_base =
			0x040 - TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
		sh_ch.port_tx_cfg_reg_base = 0x050;
	}

	return 0;
}


int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la,
			   unsigned int tx_num, unsigned int *tx_slot,
			   unsigned int rx_num, unsigned int *rx_slot)
{
	int ret = 0;
	int i;

	ret = wcd9xxx_configure_ports(wcd9xxx);
	if (ret) {
		pr_err("%s: Failed to configure register address offset\n",
		       __func__);
		goto err;
	}

	if (wcd9xxx->rx_chs) {
		wcd9xxx->num_rx_port = rx_num;
		for (i = 0; i < rx_num; i++) {
			wcd9xxx->rx_chs[i].ch_num = rx_slot[i];
			INIT_LIST_HEAD(&wcd9xxx->rx_chs[i].list);
		}
		ret = wcd9xxx_alloc_slim_sh_ch(wcd9xxx, wcd9xxx_pgd_la,
						wcd9xxx->num_rx_port,
						wcd9xxx->rx_chs,
						SLIM_SINK);
		if (ret) {
			pr_err("%s: Failed to alloc %d rx slimbus channels\n",
				__func__, wcd9xxx->num_rx_port);
			kfree(wcd9xxx->rx_chs);
			wcd9xxx->rx_chs = NULL;
			wcd9xxx->num_rx_port = 0;
		}
	} else {
		pr_err("Not able to allocate memory for %d slimbus rx ports\n",
			wcd9xxx->num_rx_port);
	}

	if (wcd9xxx->tx_chs) {
		wcd9xxx->num_tx_port = tx_num;
		for (i = 0; i < tx_num; i++) {
			wcd9xxx->tx_chs[i].ch_num = tx_slot[i];
			INIT_LIST_HEAD(&wcd9xxx->tx_chs[i].list);
		}
		ret = wcd9xxx_alloc_slim_sh_ch(wcd9xxx, wcd9xxx_pgd_la,
						wcd9xxx->num_tx_port,
						wcd9xxx->tx_chs,
						SLIM_SRC);
		if (ret) {
			pr_err("%s: Failed to alloc %d tx slimbus channels\n",
				__func__, wcd9xxx->num_tx_port);
			kfree(wcd9xxx->tx_chs);
			wcd9xxx->tx_chs = NULL;
			wcd9xxx->num_tx_port = 0;
		}
	} else {
		pr_err("Not able to allocate memory for %d slimbus tx ports\n",
			wcd9xxx->num_tx_port);
	}

	return 0;
err:
	return ret;
}

int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx)
{
	if (wcd9xxx->num_rx_port) {
		wcd9xxx_dealloc_slim_sh_ch(wcd9xxx->slim,
					wcd9xxx->num_rx_port,
					wcd9xxx->rx_chs);
		wcd9xxx->num_rx_port = 0;
	}
	if (wcd9xxx->num_tx_port) {
		wcd9xxx_dealloc_slim_sh_ch(wcd9xxx->slim,
					wcd9xxx->num_tx_port,
					wcd9xxx->tx_chs);
		wcd9xxx->num_tx_port = 0;
	}
	return 0;
}


static int wcd9xxx_alloc_slim_sh_ch(struct wcd9xxx *wcd9xxx,
				    u8 wcd9xxx_pgd_la, u32 cnt,
				    struct wcd9xxx_ch *channels, u32 path)
{
	int ret = 0;
	u32 ch_idx ;

	/* The slimbus channel allocation seem take longer time
	 * so do the allocation up front to avoid delay in start of
	 * playback
	 */
	pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la);
	for (ch_idx = 0; ch_idx < cnt; ch_idx++) {
		ret = slim_get_slaveport(wcd9xxx_pgd_la,
					channels[ch_idx].port,
					&channels[ch_idx].sph, path);
		pr_debug("%s: pgd_la[%d] channels[%d].port[%d]\n"
			"channels[%d].sph[%d] path[%d]\n",
			__func__, wcd9xxx_pgd_la, ch_idx,
			channels[ch_idx].port,
			ch_idx, channels[ch_idx].sph, path);
		if (ret < 0) {
			pr_err("%s: slave port failure id[%d] ret[%d]\n",
				__func__, channels[ch_idx].ch_num, ret);
			goto err;
		}

		ret = slim_query_ch(wcd9xxx->slim,
				    channels[ch_idx].ch_num,
				    &channels[ch_idx].ch_h);
		if (ret < 0) {
			pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
				__func__, channels[ch_idx].ch_num, ret);
			goto err;
		}
	}
err:
	return ret;
}

static int wcd9xxx_dealloc_slim_sh_ch(struct slim_device *slim,
			u32 cnt, struct wcd9xxx_ch *channels)
{
	int idx = 0;
	int ret = 0;
	/* slim_dealloc_ch */
	for (idx = 0; idx < cnt; idx++) {
		ret = slim_dealloc_ch(slim, channels[idx].ch_h);
		if (ret < 0) {
			pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
				__func__, ret, channels[idx].ch_h);
		}
	}
	return ret;
}

/* Enable slimbus slave device for RX path */
int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx,
			    struct list_head *wcd9xxx_ch_list,
			    unsigned int rate, unsigned int bit_width,
			    u16 *grph)
{
	u8 ch_cnt = 0;
	u16 ch_h[SLIM_MAX_RX_PORTS] = {0};
	u8  payload = 0;
	u16 codec_port = 0;
	int ret;
	struct slim_ch prop;
	struct wcd9xxx_ch *rx;

	/* Configure slave interface device */

	list_for_each_entry(rx, wcd9xxx_ch_list, list) {
		payload |= 1 << rx->shift;
		ch_h[ch_cnt] = rx->ch_h;
		ch_cnt++;
		pr_debug("list ch->ch_h %d ch->sph %d\n", rx->ch_h, rx->sph);
	}
	pr_debug("%s: ch_cnt[%d] rate=%d WATER_MARK_VAL %d\n",
		 __func__, ch_cnt, rate, WATER_MARK_VAL);
	/* slim_define_ch api */
	prop.prot = SLIM_AUTO_ISO;
	prop.baser = SLIM_RATE_4000HZ;
	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
	prop.ratem = (rate/4000);
	prop.sampleszbits = bit_width;

	pr_debug("Before slim_define_ch:\n"
		 "ch_cnt %d,ch_h[0] %d ch_h[1] %d, grph %d\n",
		 ch_cnt, ch_h[0], ch_h[1], *grph);
	ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
			     true, grph);
	if (ret < 0) {
		pr_err("%s: slim_define_ch failed ret[%d]\n",
		       __func__, ret);
		goto err;
	}

	list_for_each_entry(rx, wcd9xxx_ch_list, list) {
		codec_port = rx->port;
		pr_debug("%s: codec_port %d rx 0x%x, payload %d\n"
			 "sh_ch.rx_port_ch_reg_base0 0x%x\n"
			 "sh_ch.port_rx_cfg_reg_base 0x%x\n",
			 __func__, codec_port, (u32)rx, payload,
			 sh_ch.rx_port_ch_reg_base,
			sh_ch.port_rx_cfg_reg_base);

		/* look for the valid port range and chose the
		 * payload accordingly
		 */
		/* write to interface device */
		ret = wcd9xxx_interface_reg_write(wcd9xxx,
				SB_PGD_RX_PORT_MULTI_CHANNEL_0(
				sh_ch.rx_port_ch_reg_base, codec_port),
				payload);

		if (ret < 0) {
			pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
				__func__,
				SB_PGD_RX_PORT_MULTI_CHANNEL_0(
				sh_ch.rx_port_ch_reg_base, codec_port),
				payload, ret);
			goto err;
		}
		/* configure the slave port for water mark and enable*/
		ret = wcd9xxx_interface_reg_write(wcd9xxx,
				SB_PGD_PORT_CFG_BYTE_ADDR(
				sh_ch.port_rx_cfg_reg_base, codec_port),
				WATER_MARK_VAL);
		if (ret < 0) {
			pr_err("%s:watermark set failure for port[%d] ret[%d]",
				__func__, codec_port, ret);
		}

		ret = slim_connect_sink(wcd9xxx->slim, &rx->sph, 1, rx->ch_h);
		if (ret < 0) {
			pr_err("%s: slim_connect_sink failed ret[%d]\n",
				__func__, ret);
			goto err_close_slim_sch;
		}
	}
	/* slim_control_ch */
	ret = slim_control_ch(wcd9xxx->slim, *grph, SLIM_CH_ACTIVATE,
			      true);
	if (ret < 0) {
		pr_err("%s: slim_control_ch failed ret[%d]\n",
			__func__, ret);
		goto err_close_slim_sch;
	}
	return 0;

err_close_slim_sch:
	/*  release all acquired handles */
	wcd9xxx_close_slim_sch_rx(wcd9xxx, wcd9xxx_ch_list, *grph);
err:
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_cfg_slim_sch_rx);

/* Enable slimbus slave device for RX path */
int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx,
			    struct list_head *wcd9xxx_ch_list,
			    unsigned int rate, unsigned int bit_width,
			    u16 *grph)
{
	u16 ch_cnt = 0;
	u16 payload = 0;
	u16 ch_h[SLIM_MAX_TX_PORTS] = {0};
	u16 codec_port;
	int ret = 0;
	struct wcd9xxx_ch *tx;

	struct slim_ch prop;

	list_for_each_entry(tx, wcd9xxx_ch_list, list) {
		payload |= 1 << tx->shift;
		ch_h[ch_cnt] = tx->ch_h;
		ch_cnt++;
	}

	/* slim_define_ch api */
	prop.prot = SLIM_AUTO_ISO;
	prop.baser = SLIM_RATE_4000HZ;
	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
	prop.ratem = (rate/4000);
	prop.sampleszbits = 16;
	ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
			     true, grph);
	if (ret < 0) {
		pr_err("%s: slim_define_ch failed ret[%d]\n",
		       __func__, ret);
		goto err;
	}

	pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate);
	list_for_each_entry(tx, wcd9xxx_ch_list, list) {
		codec_port = tx->port;
		pr_debug("%s: codec_port %d rx 0x%x, payload 0x%x\n",
			 __func__, codec_port, (u32)tx, payload);
		/* write to interface device */
		ret = wcd9xxx_interface_reg_write(wcd9xxx,
				SB_PGD_TX_PORT_MULTI_CHANNEL_0(codec_port),
				payload & 0x00FF);
		if (ret < 0) {
			pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
				__func__,
				SB_PGD_TX_PORT_MULTI_CHANNEL_0(codec_port),
				payload, ret);
			goto err;
		}
		/* ports 8,9 */
		ret = wcd9xxx_interface_reg_write(wcd9xxx,
				SB_PGD_TX_PORT_MULTI_CHANNEL_1(codec_port),
				(payload & 0xFF00)>>8);
		if (ret < 0) {
			pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
				__func__,
				SB_PGD_TX_PORT_MULTI_CHANNEL_1(codec_port),
				payload, ret);
			goto err;
		}
		/* configure the slave port for water mark and enable*/
		ret = wcd9xxx_interface_reg_write(wcd9xxx,
				SB_PGD_PORT_CFG_BYTE_ADDR(
				sh_ch.port_tx_cfg_reg_base, codec_port),
				WATER_MARK_VAL);
		if (ret < 0) {
			pr_err("%s:watermark set failure for port[%d] ret[%d]",
				__func__, codec_port, ret);
		}

		ret = slim_connect_src(wcd9xxx->slim, tx->sph, tx->ch_h);

		if (ret < 0) {
			pr_err("%s: slim_connect_src failed ret[%d]\n",
			       __func__, ret);
			goto err;
		}
	}
	/* slim_control_ch */
	ret = slim_control_ch(wcd9xxx->slim, *grph, SLIM_CH_ACTIVATE,
			      true);
	if (ret < 0) {
		pr_err("%s: slim_control_ch failed ret[%d]\n",
			__func__, ret);
		goto err;
	}
	return 0;
err:
	/* release all acquired handles */
	wcd9xxx_close_slim_sch_tx(wcd9xxx, wcd9xxx_ch_list, *grph);
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_cfg_slim_sch_tx);

int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx,
			      struct list_head *wcd9xxx_ch_list, u16 grph)
{
	u32 sph[SLIM_MAX_RX_PORTS] = {0};
	int ch_cnt = 0 ;
	int ret = 0;
	struct wcd9xxx_ch *rx;

	list_for_each_entry(rx, wcd9xxx_ch_list, list)
		sph[ch_cnt++] = rx->sph;

	pr_debug("%s ch_cht %d, sph[0] %d sph[1] %d\n", __func__, ch_cnt,
		sph[0], sph[1]);

	/* slim_control_ch (REMOVE) */
	pr_debug("%s before slim_control_ch grph %d\n", __func__, grph);
	ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
	if (ret < 0) {
		pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret);
		goto err;
	}
err:
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_close_slim_sch_rx);

int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx,
			      struct list_head *wcd9xxx_ch_list,
			      u16 grph)
{
	u32 sph[SLIM_MAX_TX_PORTS] = {0};
	int ret = 0;
	int ch_cnt = 0 ;
	struct wcd9xxx_ch *tx;

	pr_debug("%s\n", __func__);
	list_for_each_entry(tx, wcd9xxx_ch_list, list)
		sph[ch_cnt++] = tx->sph;

	pr_debug("%s ch_cht %d, sph[0] %d sph[1] %d\n",
		__func__, ch_cnt, sph[0], sph[1]);
	/* slim_control_ch (REMOVE) */
	ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
	if (ret < 0) {
		pr_err("%s: slim_control_ch failed ret[%d]\n",
			__func__, ret);
		goto err;
	}
err:
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_close_slim_sch_tx);

int wcd9xxx_get_slave_port(unsigned int ch_num)
{
	int ret = 0;

	ret = (ch_num - BASE_CH_NUM);
	pr_debug("%s: ch_num[%d] slave port[%d]\n", __func__, ch_num, ret);
	if (ret < 0) {
		pr_err("%s: Error:- Invalid slave port found = %d\n",
			__func__, ret);
		return -EINVAL;
	}
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_get_slave_port);

int wcd9xxx_disconnect_port(struct wcd9xxx *wcd9xxx,
			    struct list_head *wcd9xxx_ch_list, u16 grph)
{
	u32 sph[SLIM_MAX_TX_PORTS + SLIM_MAX_RX_PORTS] = {0};
	int ch_cnt = 0 ;
	int ret = 0;
	struct wcd9xxx_ch *slim_ch;

	list_for_each_entry(slim_ch, wcd9xxx_ch_list, list)
		sph[ch_cnt++] = slim_ch->sph;

	/* slim_disconnect_port */
	ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
	if (ret < 0) {
		pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
			__func__, ret);
	}
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_disconnect_port);

/* This function is called with mutex acquired */
int wcd9xxx_rx_vport_validation(u32 port_id,
				struct list_head *codec_dai_list)
{
	struct wcd9xxx_ch *ch;
	int ret = 0;

	pr_debug("%s: port_id %u\n", __func__, port_id);

	list_for_each_entry(ch,
		codec_dai_list, list) {
		pr_debug("%s: ch->port %u\n", __func__, ch->port);
		if (ch->port == port_id) {
			ret = -EINVAL;
			break;
		}
	}
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_rx_vport_validation);


/* This function is called with mutex acquired */
int wcd9xxx_tx_vport_validation(u32 vtable, u32 port_id,
				struct wcd9xxx_codec_dai_data *codec_dai)
{
	struct wcd9xxx_ch *ch;
	int ret = 0;
	u32 index;
	u32 size = sizeof(vtable) * 8;
	pr_debug("%s: vtable 0x%x port_id %u size %d\n", __func__,
		 vtable, port_id, size);
	for_each_set_bit(index, (unsigned long *)&vtable, size) {
		list_for_each_entry(ch,
				    &codec_dai[index].wcd9xxx_ch_list,
				    list) {
			pr_debug("%s: index %u ch->port %u vtable 0x%x\n",
				 __func__, index, ch->port, vtable);
			if (ch->port == port_id) {
				pr_err("%s: TX%u is used by AIF%u_CAP Mixer\n",
					__func__, port_id + 1,
					(index + 1)/2);
				ret = -EINVAL;
				break;
			}
		}
		if (ret)
			break;
	}
	return ret;
}
EXPORT_SYMBOL_GPL(wcd9xxx_tx_vport_validation);
