// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) STMicroelectronics SA 2015
 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
 *          for STMicroelectronics.
 */

#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/delay.h>

#include "uniperif.h"

/*
 * User frame size shall be 2, 4, 6 or 8 32-bits words length
 * (i.e. 8, 16, 24 or 32 bytes)
 * This constraint comes from allowed values for
 * UNIPERIF_I2S_FMT_NUM_CH register
 */
#define UNIPERIF_MAX_FRAME_SZ 0x20
#define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ)

struct sti_uniperiph_dev_data {
	unsigned int id; /* Nb available player instances */
	unsigned int version; /* player IP version */
	unsigned int stream;
	const char *dai_names;
	enum uniperif_type type;
};

static const struct sti_uniperiph_dev_data sti_uniplayer_hdmi = {
	.id = 0,
	.version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
	.stream = SNDRV_PCM_STREAM_PLAYBACK,
	.dai_names = "Uni Player #0 (HDMI)",
	.type = SND_ST_UNIPERIF_TYPE_HDMI
};

static const struct sti_uniperiph_dev_data sti_uniplayer_pcm_out = {
	.id = 1,
	.version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
	.stream = SNDRV_PCM_STREAM_PLAYBACK,
	.dai_names = "Uni Player #1 (PCM OUT)",
	.type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
};

static const struct sti_uniperiph_dev_data sti_uniplayer_dac = {
	.id = 2,
	.version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
	.stream = SNDRV_PCM_STREAM_PLAYBACK,
	.dai_names = "Uni Player #2 (DAC)",
	.type = SND_ST_UNIPERIF_TYPE_PCM,
};

static const struct sti_uniperiph_dev_data sti_uniplayer_spdif = {
	.id = 3,
	.version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
	.stream = SNDRV_PCM_STREAM_PLAYBACK,
	.dai_names = "Uni Player #3 (SPDIF)",
	.type = SND_ST_UNIPERIF_TYPE_SPDIF
};

static const struct sti_uniperiph_dev_data sti_unireader_pcm_in = {
	.id = 0,
	.version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
	.stream = SNDRV_PCM_STREAM_CAPTURE,
	.dai_names = "Uni Reader #0 (PCM IN)",
	.type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
};

static const struct sti_uniperiph_dev_data sti_unireader_hdmi_in = {
	.id = 1,
	.version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
	.stream = SNDRV_PCM_STREAM_CAPTURE,
	.dai_names = "Uni Reader #1 (HDMI IN)",
	.type = SND_ST_UNIPERIF_TYPE_PCM,
};

static const struct of_device_id snd_soc_sti_match[] = {
	{ .compatible = "st,stih407-uni-player-hdmi",
	  .data = &sti_uniplayer_hdmi
	},
	{ .compatible = "st,stih407-uni-player-pcm-out",
	  .data = &sti_uniplayer_pcm_out
	},
	{ .compatible = "st,stih407-uni-player-dac",
	  .data = &sti_uniplayer_dac
	},
	{ .compatible = "st,stih407-uni-player-spdif",
	  .data = &sti_uniplayer_spdif
	},
	{ .compatible = "st,stih407-uni-reader-pcm_in",
	  .data = &sti_unireader_pcm_in
	},
	{ .compatible = "st,stih407-uni-reader-hdmi",
	  .data = &sti_unireader_hdmi_in
	},
	{},
};
MODULE_DEVICE_TABLE(of, snd_soc_sti_match);

int  sti_uniperiph_reset(struct uniperif *uni)
{
	int count = 10;

	/* Reset uniperipheral uni */
	SET_UNIPERIF_SOFT_RST_SOFT_RST(uni);

	if (uni->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
		while (GET_UNIPERIF_SOFT_RST_SOFT_RST(uni) && count) {
			udelay(5);
			count--;
		}
	}

	if (!count) {
		dev_err(uni->dev, "Failed to reset uniperif\n");
		return -EIO;
	}

	return 0;
}

int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
			       unsigned int rx_mask, int slots,
			       int slot_width)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *uni = priv->dai_data.uni;
	int i, frame_size, avail_slots;

	if (!UNIPERIF_TYPE_IS_TDM(uni)) {
		dev_err(uni->dev, "cpu dai not in tdm mode\n");
		return -EINVAL;
	}

	/* store info in unip context */
	uni->tdm_slot.slots = slots;
	uni->tdm_slot.slot_width = slot_width;
	/* unip is unidirectionnal */
	uni->tdm_slot.mask = (tx_mask != 0) ? tx_mask : rx_mask;

	/* number of available timeslots */
	for (i = 0, avail_slots = 0; i < uni->tdm_slot.slots; i++) {
		if ((uni->tdm_slot.mask >> i) & 0x01)
			avail_slots++;
	}
	uni->tdm_slot.avail_slots = avail_slots;

	/* frame size in bytes */
	frame_size = uni->tdm_slot.avail_slots * uni->tdm_slot.slot_width / 8;

	/* check frame size is allowed */
	if ((frame_size > UNIPERIF_MAX_FRAME_SZ) ||
	    (frame_size & ~(int)UNIPERIF_ALLOWED_FRAME_SZ)) {
		dev_err(uni->dev, "frame size not allowed: %d bytes\n",
			frame_size);
		return -EINVAL;
	}

	return 0;
}

int sti_uniperiph_fix_tdm_chan(struct snd_pcm_hw_params *params,
			       struct snd_pcm_hw_rule *rule)
{
	struct uniperif *uni = rule->private;
	struct snd_interval t;

	t.min = uni->tdm_slot.avail_slots;
	t.max = uni->tdm_slot.avail_slots;
	t.openmin = 0;
	t.openmax = 0;
	t.integer = 0;

	return snd_interval_refine(hw_param_interval(params, rule->var), &t);
}

int sti_uniperiph_fix_tdm_format(struct snd_pcm_hw_params *params,
				 struct snd_pcm_hw_rule *rule)
{
	struct uniperif *uni = rule->private;
	struct snd_mask *maskp = hw_param_mask(params, rule->var);
	u64 format;

	switch (uni->tdm_slot.slot_width) {
	case 16:
		format = SNDRV_PCM_FMTBIT_S16_LE;
		break;
	case 32:
		format = SNDRV_PCM_FMTBIT_S32_LE;
		break;
	default:
		dev_err(uni->dev, "format not supported: %d bits\n",
			uni->tdm_slot.slot_width);
		return -EINVAL;
	}

	maskp->bits[0] &= (u_int32_t)format;
	maskp->bits[1] &= (u_int32_t)(format >> 32);
	/* clear remaining indexes */
	memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX - 64) / 8);

	if (!maskp->bits[0] && !maskp->bits[1])
		return -EINVAL;

	return 0;
}

int sti_uniperiph_get_tdm_word_pos(struct uniperif *uni,
				   unsigned int *word_pos)
{
	int slot_width = uni->tdm_slot.slot_width / 8;
	int slots_num = uni->tdm_slot.slots;
	unsigned int slots_mask = uni->tdm_slot.mask;
	int i, j, k;
	unsigned int word16_pos[4];

	/* word16_pos:
	 * word16_pos[0] = WORDX_LSB
	 * word16_pos[1] = WORDX_MSB,
	 * word16_pos[2] = WORDX+1_LSB
	 * word16_pos[3] = WORDX+1_MSB
	 */

	/* set unip word position */
	for (i = 0, j = 0, k = 0; (i < slots_num) && (k < WORD_MAX); i++) {
		if ((slots_mask >> i) & 0x01) {
			word16_pos[j] = i * slot_width;

			if (slot_width == 4) {
				word16_pos[j + 1] = word16_pos[j] + 2;
				j++;
			}
			j++;

			if (j > 3) {
				word_pos[k] = word16_pos[1] |
					      (word16_pos[0] << 8) |
					      (word16_pos[3] << 16) |
					      (word16_pos[2] << 24);
				j = 0;
				k++;
			}
		}
	}

	return 0;
}

/*
 * sti_uniperiph_dai_create_ctrl
 * This function is used to create Ctrl associated to DAI but also pcm device.
 * Request is done by front end to associate ctrl with pcm device id
 */
static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *uni = priv->dai_data.uni;
	struct snd_kcontrol_new *ctrl;
	int i;

	if (!uni->num_ctrls)
		return 0;

	for (i = 0; i < uni->num_ctrls; i++) {
		/*
		 * Several Control can have same name. Controls are indexed on
		 * Uniperipheral instance ID
		 */
		ctrl = &uni->snd_ctrls[i];
		ctrl->index = uni->id;
		ctrl->device = uni->id;
	}

	return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls);
}

/*
 * DAI
 */
int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_soc_dai *dai)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct uniperif *uni = priv->dai_data.uni;
	struct snd_dmaengine_dai_dma_data *dma_data;
	int transfer_size;

	if (uni->type == SND_ST_UNIPERIF_TYPE_TDM)
		/* transfer size = user frame size (in 32-bits FIFO cell) */
		transfer_size = snd_soc_params_to_frame_size(params) / 32;
	else
		transfer_size = params_channels(params) * UNIPERIF_FIFO_FRAMES;

	dma_data = snd_soc_dai_get_dma_data(dai, substream);
	dma_data->maxburst = transfer_size;

	return 0;
}

int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);

	priv->dai_data.uni->daifmt = fmt;

	return 0;
}

static int sti_uniperiph_suspend(struct snd_soc_component *component)
{
	struct sti_uniperiph_data *priv = snd_soc_component_get_drvdata(component);
	struct uniperif *uni = priv->dai_data.uni;
	int ret;

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

	/* Pinctrl: switch pinstate to sleep */
	ret = pinctrl_pm_select_sleep_state(uni->dev);
	if (ret)
		dev_err(uni->dev, "%s: failed to select pinctrl state\n",
			__func__);

	return ret;
}

static int sti_uniperiph_resume(struct snd_soc_component *component)
{
	struct sti_uniperiph_data *priv = snd_soc_component_get_drvdata(component);
	struct uniperif *uni = priv->dai_data.uni;
	int ret;

	if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
		ret = uni_player_resume(uni);
		if (ret)
			return ret;
	}

	/* pinctrl: switch pinstate to default */
	ret = pinctrl_pm_select_default_state(uni->dev);
	if (ret)
		dev_err(uni->dev, "%s: failed to select pinctrl state\n",
			__func__);

	return ret;
}

static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai)
{
	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
	struct sti_uniperiph_dai *dai_data = &priv->dai_data;

	/* DMA settings*/
	if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK)
		snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL);
	else
		snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data);

	dai_data->dma_data.addr = dai_data->uni->fifo_phys_address;
	dai_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;

	return sti_uniperiph_dai_create_ctrl(dai);
}

static const struct snd_soc_dai_ops sti_uniperiph_dai_ops = {
	.probe = sti_uniperiph_dai_probe,
};

static const struct snd_soc_dai_driver sti_uniperiph_dai_template = {
	.ops = &sti_uniperiph_dai_ops,
};

static const struct snd_soc_component_driver sti_uniperiph_dai_component = {
	.name = "sti_cpu_dai",
	.suspend = sti_uniperiph_suspend,
	.resume = sti_uniperiph_resume,
	.legacy_dai_naming = 1,
};

static int sti_uniperiph_cpu_dai_of(struct device_node *node,
				    struct sti_uniperiph_data *priv)
{
	struct device *dev = &priv->pdev->dev;
	struct sti_uniperiph_dai *dai_data = &priv->dai_data;
	struct snd_soc_dai_driver *dai = priv->dai;
	struct snd_soc_pcm_stream *stream;
	struct uniperif *uni;
	const struct of_device_id *of_id;
	const struct sti_uniperiph_dev_data *dev_data;
	const char *mode;
	int ret;

	/* Populate data structure depending on compatibility */
	of_id = of_match_node(snd_soc_sti_match, node);
	if (!of_id->data) {
		dev_err(dev, "data associated to device is missing\n");
		return -EINVAL;
	}
	dev_data = (struct sti_uniperiph_dev_data *)of_id->data;

	uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL);
	if (!uni)
		return -ENOMEM;

	uni->id = dev_data->id;
	uni->ver = dev_data->version;

	*dai = sti_uniperiph_dai_template;
	dai->name = dev_data->dai_names;

	/* Get resources and base address */
	uni->base = devm_platform_get_and_ioremap_resource(priv->pdev, 0, &uni->mem_region);
	if (IS_ERR(uni->base))
		return PTR_ERR(uni->base);

	uni->fifo_phys_address = uni->mem_region->start +
				     UNIPERIF_FIFO_DATA_OFFSET(uni);

	uni->irq = platform_get_irq(priv->pdev, 0);
	if (uni->irq < 0)
		return -ENXIO;

	uni->type = dev_data->type;

	/* check if player should be configured for tdm */
	if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) {
		if (!of_property_read_string(node, "st,tdm-mode", &mode))
			uni->type = SND_ST_UNIPERIF_TYPE_TDM;
		else
			uni->type = SND_ST_UNIPERIF_TYPE_PCM;
	}

	dai_data->uni = uni;
	dai_data->stream = dev_data->stream;

	if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
		ret = uni_player_init(priv->pdev, uni);
		stream = &dai->playback;
	} else {
		ret = uni_reader_init(priv->pdev, uni);
		stream = &dai->capture;
	}
	if (ret < 0)
		return ret;

	dai->ops = uni->dai_ops;

	stream->stream_name = dai->name;
	stream->channels_min = uni->hw->channels_min;
	stream->channels_max = uni->hw->channels_max;
	stream->rates = uni->hw->rates;
	stream->formats = uni->hw->formats;

	return 0;
}

static int sti_uniperiph_probe(struct platform_device *pdev)
{
	struct sti_uniperiph_data *priv;
	struct device_node *node = pdev->dev.of_node;
	int ret;

	/* Allocate the private data and the CPU_DAI array */
	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	priv->dai = devm_kzalloc(&pdev->dev, sizeof(*priv->dai), GFP_KERNEL);
	if (!priv->dai)
		return -ENOMEM;

	priv->pdev = pdev;

	ret = sti_uniperiph_cpu_dai_of(node, priv);
	if (ret < 0)
		return ret;

	dev_set_drvdata(&pdev->dev, priv);

	ret = devm_snd_soc_register_component(&pdev->dev,
					      &sti_uniperiph_dai_component,
					      priv->dai, 1);
	if (ret < 0)
		return ret;

	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
}

static struct platform_driver sti_uniperiph_driver = {
	.driver = {
		.name = "sti-uniperiph-dai",
		.of_match_table = snd_soc_sti_match,
	},
	.probe = sti_uniperiph_probe,
};
module_platform_driver(sti_uniperiph_driver);

MODULE_DESCRIPTION("uniperipheral DAI driver");
MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
MODULE_LICENSE("GPL v2");
