// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/bitops.h>
#include <linux/slimbus/slimbus.h>
#include <sound/soc.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "msm-slim-dma.h"

#define SLIM_DEV_NAME "msm-dai-slim"

#define SLIM_DAI_RATES (SNDRV_PCM_RATE_48000 | \
			SNDRV_PCM_RATE_8000 | \
			SNDRV_PCM_RATE_16000 | \
			SNDRV_PCM_RATE_96000 | \
			SNDRV_PCM_RATE_192000 | \
			SNDRV_PCM_RATE_384000)

#define SLIM_DAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
			  SNDRV_PCM_FMTBIT_S24_LE | \
			  SNDRV_PCM_FMTBIT_S32_LE)

#define DAI_STATE_INITIALIZED (0x01 << 0)
#define DAI_STATE_PREPARED (0x01 << 1)
#define DAI_STATE_RUNNING (0x01 << 2)

#define SET_DAI_STATE(status, state) \
	(status |= state)

#define CLR_DAI_STATE(status, state) \
	(status = status & (~state))

enum {
	MSM_DAI_SLIM0 = 0,
	NUM_SLIM_DAIS,
};

struct msm_slim_dai_data {
	unsigned int dai_id;
	u16 *chan_h;
	u16 *sh_ch;
	u16 grph;
	u32 rate;
	u16 bits;
	u16 ch_cnt;
	u8 status;
	struct snd_soc_dai_driver *dai_drv;
	struct msm_slim_dma_data dma_data;
	struct slim_port_cfg port_cfg;
};

struct msm_dai_slim_drv_data {
	struct slim_device *sdev;
	u16 num_dais;
	struct msm_slim_dai_data slim_dai_data[NUM_SLIM_DAIS];
};

struct msm_slim_dai_data *msm_slim_get_dai_data(
	struct msm_dai_slim_drv_data *drv_data,
	struct snd_soc_dai *dai)
{
	struct msm_slim_dai_data *dai_data_t;
	int i;

	for (i = 0; i < drv_data->num_dais; i++) {
		dai_data_t = &drv_data->slim_dai_data[i];
		if (dai_data_t->dai_id == dai->id)
			return dai_data_t;
	}

	dev_err(dai->dev,
		"%s: no dai data found for dai_id %d\n",
		__func__, dai->id);
	return NULL;
}

static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
	struct snd_soc_dai *dai, bool enable)
{
	struct slim_device *sdev;
	struct msm_dai_slim_drv_data *drv_data;
	struct msm_slim_dai_data *dai_data;
	int rc, rc1, i;

	if (!dma_data || !dma_data->sdev) {
		pr_err("%s: Invalid %s\n", __func__,
		       (!dma_data) ? "dma_data" : "slim_device");
		return -EINVAL;
	}

	sdev = dma_data->sdev;
	drv_data = dev_get_drvdata(&sdev->dev);
	dai_data = msm_slim_get_dai_data(drv_data, dai);

	if (!dai_data) {
		dev_err(dai->dev,
			"%s: Invalid dai_data for dai_id %d\n",
			__func__, dai->id);
		return -EINVAL;
	}

	dev_dbg(&sdev->dev,
		"%s: enable = %s, rate = %u\n", __func__,
		enable ? "true" : "false",
		dai_data->rate);

	if (enable) {
		if (!(dai_data->status & DAI_STATE_PREPARED)) {
			dev_err(&sdev->dev,
				"%s: dai id (%d) has invalid state 0x%x\n",
				__func__, dai->id, dai_data->status);
			return -EINVAL;
		}

		rc = slim_alloc_mgrports(sdev,
					 SLIM_REQ_DEFAULT, dai_data->ch_cnt,
					 &(dma_data->ph),
					 sizeof(dma_data->ph));
		if (rc < 0) {
			dev_err(&sdev->dev,
				"%s:alloc mgrport failed rc %d\n",
				__func__, rc);
			goto done;
		}

		rc = slim_config_mgrports(sdev, &(dma_data->ph),
					  dai_data->ch_cnt,
					  &(dai_data->port_cfg));
		if (rc < 0) {
			dev_err(&sdev->dev,
				"%s: config mgrport failed rc %d\n",
				__func__, rc);
			goto err_done;
		}

		for (i = 0; i < dai_data->ch_cnt; i++) {
			rc = slim_connect_sink(sdev,
					       &dma_data->ph, 1,
					       dai_data->chan_h[i]);
			if (rc < 0) {
				dev_err(&sdev->dev,
					"%s: slim_connect_sink failed, ch = %d, err = %d\n",
					__func__, i, rc);
				goto err_done;
			}
		}

		rc = slim_control_ch(sdev,
				     dai_data->grph,
				     SLIM_CH_ACTIVATE, true);
		if (rc < 0) {
			dev_err(&sdev->dev,
				"%s: slim activate ch failed, err = %d\n",
				__func__, rc);
			goto err_done;
		}
		/* Mark dai status as running */
		SET_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
	} else {
		if (!(dai_data->status & DAI_STATE_RUNNING)) {
			dev_err(&sdev->dev,
				"%s: dai id (%d) has invalid state 0x%x\n",
				__func__, dai->id, dai_data->status);
			return -EINVAL;
		}

		rc = slim_control_ch(sdev,
				     dai_data->grph,
				     SLIM_CH_REMOVE, true);
		if (rc < 0) {
			dev_err(&sdev->dev,
				"%s: slim activate ch failed, err = %d\n",
				__func__, rc);
			goto done;
		}

		rc = slim_dealloc_mgrports(sdev,
					   &dma_data->ph, 1);
		if (rc < 0) {
			dev_err(&sdev->dev,
				"%s: dealloc mgrport failed, err = %d\n",
				__func__, rc);
			goto done;
		}
		/* clear running state for dai*/
		CLR_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
	}

	return rc;

err_done:
	rc1 = slim_dealloc_mgrports(sdev,
				   &dma_data->ph, 1);
	if (rc1 < 0)
		dev_err(&sdev->dev,
			"%s: dealloc mgrport failed, err = %d\n",
			__func__, rc1);
done:
	return rc;
}

static int msm_dai_slim_hw_params(
		struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params,
		struct snd_soc_dai *dai)
{
	struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
	struct msm_slim_dai_data *dai_data;
	int rc = 0;

	dai_data = msm_slim_get_dai_data(drv_data, dai);
	if (!dai_data) {
		dev_err(dai->dev,
			"%s: Invalid dai_data for dai_id %d\n",
			__func__, dai->id);
		rc = -EINVAL;
		goto done;
	}

	if (!dai_data->ch_cnt || dai_data->ch_cnt != params_channels(params)) {
		dev_err(dai->dev, "%s: invalid ch_cnt %d %d\n",
			__func__, dai_data->ch_cnt, params_channels(params));
		rc = -EINVAL;
		goto done;
	}

	dai_data->rate = params_rate(params);
	dai_data->port_cfg.port_opts = SLIM_OPT_NONE;
	if (dai_data->rate >= SNDRV_PCM_RATE_48000)
		dai_data->port_cfg.watermark = 16;
	else
		dai_data->port_cfg.watermark = 8;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		dai_data->bits = 16;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		dai_data->bits = 24;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		dai_data->bits = 32;
		break;
	default:
		dev_err(dai->dev, "%s: invalid format %d\n", __func__,
			params_format(params));
		rc = -EINVAL;
		goto done;
	}

	dev_dbg(dai->dev, "%s: ch_cnt=%u rate=%u, bit_width = %u\n",
		__func__, dai_data->ch_cnt, dai_data->rate,
		dai_data->bits);
done:
	return rc;
}

static int msm_dai_slim_set_channel_map(struct snd_soc_dai *dai,
	unsigned int tx_num, unsigned int *tx_slot,
	unsigned int rx_num, unsigned int *rx_slot)
{
	struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
	struct msm_slim_dai_data *dai_data;
	struct snd_soc_dai_driver *dai_drv;
	u8 i = 0;

	dev_dbg(dai->dev,
		"%s: tx_num=%u, rx_num=%u\n",
		__func__, tx_num, rx_num);

	dai_data = msm_slim_get_dai_data(drv_data, dai);
	if (!dai_data) {
		dev_err(dai->dev,
			"%s: Invalid dai_data for dai_id %d\n",
			__func__, dai->id);
		return -EINVAL;
	}

	dai_drv = dai_data->dai_drv;

	if (tx_num > dai_drv->capture.channels_max) {
		dev_err(dai->dev, "%s: tx_num %u max out master port cnt\n",
			__func__, tx_num);
		return -EINVAL;
	}

	for (i = 0; i < tx_num; i++)
		dai_data->sh_ch[i] = tx_slot[i];

	dai_data->ch_cnt = tx_num;
	return 0;
}

static int msm_dai_slim_prepare(struct snd_pcm_substream *substream,
				   struct snd_soc_dai *dai)
{
	struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
	struct msm_slim_dma_data *dma_data;
	struct msm_slim_dai_data *dai_data = NULL;
	struct slim_ch prop;
	int rc;
	u8 i, j;

	dai_data = msm_slim_get_dai_data(drv_data, dai);
	if (!dai_data) {
		dev_err(dai->dev,
			"%s: Invalid dai_data for dai %d\n",
			__func__, dai->id);
		return -EINVAL;
	}

	if (!(dai_data->status & DAI_STATE_INITIALIZED)) {
		dev_err(dai->dev,
			"%s: dai id (%d) has invalid state 0x%x\n",
			__func__, dai->id, dai_data->status);
		return -EINVAL;
	}

	if (dai_data->status & DAI_STATE_PREPARED) {
		dev_dbg(dai->dev,
			"%s: dai id (%d) has already prepared.\n",
			__func__, dai->id);
		return 0;
	}

	dma_data = &dai_data->dma_data;
	snd_soc_dai_set_dma_data(dai, substream, dma_data);

	for (i = 0; i < dai_data->ch_cnt; i++) {
		rc = slim_query_ch(drv_data->sdev, dai_data->sh_ch[i],
				   &dai_data->chan_h[i]);
		if (rc) {
			dev_err(dai->dev, "%s:query chan handle failed rc %d\n",
				__func__, rc);
			goto error_chan_query;
		}
	}

	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 = (dai_data->rate/4000);
	prop.sampleszbits = dai_data->bits;

	rc = slim_define_ch(drv_data->sdev, &prop, dai_data->chan_h,
			    dai_data->ch_cnt, true, &dai_data->grph);

	if (rc) {
		dev_err(dai->dev, "%s:define chan failed rc %d\n",
				__func__, rc);
		goto error_define_chan;
	}

	/* Mark stream status as prepared */
	SET_DAI_STATE(dai_data->status, DAI_STATE_PREPARED);

	return rc;

error_define_chan:
error_chan_query:
	for (j = 0; j < i; j++)
		slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[j]);
	return rc;
}

static void msm_dai_slim_shutdown(struct snd_pcm_substream *stream,
		struct snd_soc_dai *dai)
{
	struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
	struct msm_slim_dma_data *dma_data = NULL;
	struct msm_slim_dai_data *dai_data;
	int i, rc = 0;

	dai_data = msm_slim_get_dai_data(drv_data, dai);
	dma_data = snd_soc_dai_get_dma_data(dai, stream);
	if (!dma_data || !dai_data) {
		dev_err(dai->dev,
			"%s: Invalid %s\n", __func__,
			(!dma_data) ? "dma_data" : "dai_data");
		return;
	}

	if ((!(dai_data->status & DAI_STATE_PREPARED)) ||
	     dai_data->status & DAI_STATE_RUNNING) {
		dev_err(dai->dev,
			"%s: dai id (%d) has invalid state 0x%x\n",
			__func__, dai->id, dai_data->status);
		return;
	}

	for (i = 0; i < dai_data->ch_cnt; i++) {
		rc = slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[i]);
		if (rc) {
			dev_err(dai->dev,
				"%s: dealloc_ch failed, err = %d\n",
				__func__, rc);
		}
	}

	snd_soc_dai_set_dma_data(dai, stream, NULL);
	/* clear prepared state for the dai */
	CLR_DAI_STATE(dai_data->status, DAI_STATE_PREPARED);
}

static const struct snd_soc_component_driver msm_dai_slim_component = {
	.name		= "msm-dai-slim-cmpnt",
};

static struct snd_soc_dai_ops msm_dai_slim_ops = {
	.prepare	= msm_dai_slim_prepare,
	.hw_params	= msm_dai_slim_hw_params,
	.shutdown	= msm_dai_slim_shutdown,
	.set_channel_map = msm_dai_slim_set_channel_map,
};

static struct snd_soc_dai_driver msm_slim_dais[] = {
	{
		/*
		 * The first dai name should be same as device name
		 * to support registering single and multile dais.
		 */
		.name = SLIM_DEV_NAME,
		.id = MSM_DAI_SLIM0,
		.capture = {
			.rates = SLIM_DAI_RATES,
			.formats = SLIM_DAI_FORMATS,
			.channels_min = 1,
			/*
			 * max channels allowed is
			 * dependent on platform and
			 * will be updated before this
			 * dai driver is registered.
			 */
			.channels_max = 1,
			.rate_min = 8000,
			.rate_max = 384000,
			.stream_name = "SLIM_DAI0 Capture",
		},
		.ops = &msm_dai_slim_ops,
	},
	/*
	 * If multiple dais are needed,
	 * add dais here and update the
	 * dai_id enum.
	 */
};

static void msm_dai_slim_remove_dai_data(
		struct device *dev,
		struct msm_dai_slim_drv_data *drv_data)
{
	int i;
	struct msm_slim_dai_data *dai_data_t;

	for (i = 0; i < drv_data->num_dais; i++) {
		dai_data_t = &drv_data->slim_dai_data[i];

		kfree(dai_data_t->chan_h);
		dai_data_t->chan_h = NULL;
		kfree(dai_data_t->sh_ch);
		dai_data_t->sh_ch = NULL;
	}
}

static int msm_dai_slim_populate_dai_data(struct device *dev,
		struct msm_dai_slim_drv_data *drv_data)
{
	struct snd_soc_dai_driver *dai_drv;
	struct msm_slim_dai_data *dai_data_t;
	u8 num_ch;
	int i, j, rc;

	for (i = 0; i < drv_data->num_dais; i++) {
		num_ch = 0;
		dai_drv = &msm_slim_dais[i];
		num_ch += dai_drv->capture.channels_max;
		num_ch += dai_drv->playback.channels_max;

		dai_data_t = &drv_data->slim_dai_data[i];
		dai_data_t->dai_drv = dai_drv;
		dai_data_t->dai_id = dai_drv->id;
		dai_data_t->dma_data.sdev = drv_data->sdev;
		dai_data_t->dma_data.dai_channel_ctl =
				msm_dai_slim_ch_ctl;
		SET_DAI_STATE(dai_data_t->status,
			      DAI_STATE_INITIALIZED);

		dai_data_t->chan_h = devm_kzalloc(dev,
					sizeof(u16) * num_ch,
					GFP_KERNEL);
		if (!dai_data_t->chan_h) {
			dev_err(dev,
				"%s: DAI ID %d, Failed to alloc channel handles\n",
				__func__, i);
			rc = -ENOMEM;
			goto err_mem_alloc;
		}

		dai_data_t->sh_ch = devm_kzalloc(dev,
					sizeof(u16) * num_ch,
					GFP_KERNEL);
		if (!dai_data_t->sh_ch) {
			dev_err(dev,
				"%s: DAI ID %d, Failed to alloc sh_ch\n",
				__func__, i);
			rc = -ENOMEM;
			goto err_mem_alloc;
		}
	}
	return 0;

err_mem_alloc:
	for (j = 0; j < i; j++) {
		dai_data_t = &drv_data->slim_dai_data[i];

		devm_kfree(dev, dai_data_t->chan_h);
		dai_data_t->chan_h = NULL;

		devm_kfree(dev, dai_data_t->sh_ch);
		dai_data_t->sh_ch = NULL;
	}
	return rc;
}

static int msm_dai_slim_dev_probe(struct slim_device *sdev)
{
	int rc, i;
	u8 max_channels;
	u32 apps_ch_pipes;
	struct msm_dai_slim_drv_data *drv_data;
	struct device *dev = &sdev->dev;
	struct snd_soc_dai_driver *dai_drv;

	if (!dev->of_node ||
	    !dev->of_node->parent) {
		dev_err(dev,
			"%s: Invalid %s\n", __func__,
			(!dev->of_node) ? "of_node" : "parent_of_node");
		return -EINVAL;
	}

	rc = of_property_read_u32(dev->of_node->parent,
					 "qcom,apps-ch-pipes",
					 &apps_ch_pipes);
	if (rc) {
		dev_err(dev,
			"%s: Failed to lookup property %s in node %s, err = %d\n",
			__func__, "qcom,apps-ch-pipes",
			dev->of_node->parent->full_name, rc);
		goto err_ret;
	}

	max_channels = hweight_long(apps_ch_pipes);
	if (max_channels <= 0) {
		dev_err(dev,
			"%s: Invalid apps owned ports %d\n",
			__func__, max_channels);
		goto err_ret;
	}

	dev_dbg(dev, "%s: max channels = %u\n",
		__func__, max_channels);

	for (i = 0; i < ARRAY_SIZE(msm_slim_dais); i++) {
		dai_drv = &msm_slim_dais[i];
		dai_drv->capture.channels_max = max_channels;
		dai_drv->playback.channels_max = max_channels;
	}

	drv_data = devm_kzalloc(dev, sizeof(*drv_data),
				GFP_KERNEL);
	if (!drv_data) {
		rc = -ENOMEM;
		goto err_ret;
	}

	drv_data->sdev = sdev;
	drv_data->num_dais = NUM_SLIM_DAIS;

	rc = msm_dai_slim_populate_dai_data(dev, drv_data);
	if (rc) {
		dev_err(dev,
			"%s: failed to setup dai_data, err = %d\n",
			__func__, rc);
		goto err_populate_dai;
	}

	rc = snd_soc_register_component(&sdev->dev, &msm_dai_slim_component,
					msm_slim_dais, NUM_SLIM_DAIS);
	if (rc < 0) {
		dev_err(dev, "%s: failed to register DAI, err = %d\n",
			__func__, rc);
		goto err_reg_comp;
	}

	dev_set_drvdata(dev, drv_data);
	return rc;

err_reg_comp:
	msm_dai_slim_remove_dai_data(dev, drv_data);

err_populate_dai:
	devm_kfree(dev, drv_data);

err_ret:
	return rc;
}

static int msm_dai_slim_dev_remove(struct slim_device *sdev)
{
	snd_soc_unregister_component(&sdev->dev);
	return 0;
}

static const struct slim_device_id msm_dai_slim_dt_match[] = {
	{SLIM_DEV_NAME, 0 },
	{}
};

static struct slim_driver msm_dai_slim_driver = {
	.driver = {
		.name = SLIM_DEV_NAME,
		.owner = THIS_MODULE,
	},
	.probe = msm_dai_slim_dev_probe,
	.remove = msm_dai_slim_dev_remove,
	.id_table = msm_dai_slim_dt_match,
};

int __init msm_dai_slim_init(void)
{
	int rc;

	rc = slim_driver_register(&msm_dai_slim_driver);
	if (rc)
		pr_err("%s: failed to register with slimbus driver rc = %d",
			__func__, rc);
	return rc;
}

void msm_dai_slim_exit(void)
{
	slim_driver_unregister(&msm_dai_slim_driver);
}

/* Module information */
MODULE_DESCRIPTION("Slimbus apps-owned channel handling driver");
MODULE_LICENSE("GPL v2");
