// SPDX-License-Identifier: GPL-2.0+
/*
 * virtio-snd: Virtio sound device
 * Copyright (C) 2021 OpenSynergy GmbH
 */
#include <linux/moduleparam.h>
#include <linux/virtio_config.h>

#include "virtio_card.h"

static u32 pcm_buffer_ms = 160;
module_param(pcm_buffer_ms, uint, 0644);
MODULE_PARM_DESC(pcm_buffer_ms, "PCM substream buffer time in milliseconds");

static u32 pcm_periods_min = 2;
module_param(pcm_periods_min, uint, 0644);
MODULE_PARM_DESC(pcm_periods_min, "Minimum number of PCM periods");

static u32 pcm_periods_max = 16;
module_param(pcm_periods_max, uint, 0644);
MODULE_PARM_DESC(pcm_periods_max, "Maximum number of PCM periods");

static u32 pcm_period_ms_min = 10;
module_param(pcm_period_ms_min, uint, 0644);
MODULE_PARM_DESC(pcm_period_ms_min, "Minimum PCM period time in milliseconds");

static u32 pcm_period_ms_max = 80;
module_param(pcm_period_ms_max, uint, 0644);
MODULE_PARM_DESC(pcm_period_ms_max, "Maximum PCM period time in milliseconds");

/* Map for converting VirtIO format to ALSA format. */
static const snd_pcm_format_t g_v2a_format_map[] = {
	[VIRTIO_SND_PCM_FMT_IMA_ADPCM] = SNDRV_PCM_FORMAT_IMA_ADPCM,
	[VIRTIO_SND_PCM_FMT_MU_LAW] = SNDRV_PCM_FORMAT_MU_LAW,
	[VIRTIO_SND_PCM_FMT_A_LAW] = SNDRV_PCM_FORMAT_A_LAW,
	[VIRTIO_SND_PCM_FMT_S8] = SNDRV_PCM_FORMAT_S8,
	[VIRTIO_SND_PCM_FMT_U8] = SNDRV_PCM_FORMAT_U8,
	[VIRTIO_SND_PCM_FMT_S16] = SNDRV_PCM_FORMAT_S16_LE,
	[VIRTIO_SND_PCM_FMT_U16] = SNDRV_PCM_FORMAT_U16_LE,
	[VIRTIO_SND_PCM_FMT_S18_3] = SNDRV_PCM_FORMAT_S18_3LE,
	[VIRTIO_SND_PCM_FMT_U18_3] = SNDRV_PCM_FORMAT_U18_3LE,
	[VIRTIO_SND_PCM_FMT_S20_3] = SNDRV_PCM_FORMAT_S20_3LE,
	[VIRTIO_SND_PCM_FMT_U20_3] = SNDRV_PCM_FORMAT_U20_3LE,
	[VIRTIO_SND_PCM_FMT_S24_3] = SNDRV_PCM_FORMAT_S24_3LE,
	[VIRTIO_SND_PCM_FMT_U24_3] = SNDRV_PCM_FORMAT_U24_3LE,
	[VIRTIO_SND_PCM_FMT_S20] = SNDRV_PCM_FORMAT_S20_LE,
	[VIRTIO_SND_PCM_FMT_U20] = SNDRV_PCM_FORMAT_U20_LE,
	[VIRTIO_SND_PCM_FMT_S24] = SNDRV_PCM_FORMAT_S24_LE,
	[VIRTIO_SND_PCM_FMT_U24] = SNDRV_PCM_FORMAT_U24_LE,
	[VIRTIO_SND_PCM_FMT_S32] = SNDRV_PCM_FORMAT_S32_LE,
	[VIRTIO_SND_PCM_FMT_U32] = SNDRV_PCM_FORMAT_U32_LE,
	[VIRTIO_SND_PCM_FMT_FLOAT] = SNDRV_PCM_FORMAT_FLOAT_LE,
	[VIRTIO_SND_PCM_FMT_FLOAT64] = SNDRV_PCM_FORMAT_FLOAT64_LE,
	[VIRTIO_SND_PCM_FMT_DSD_U8] = SNDRV_PCM_FORMAT_DSD_U8,
	[VIRTIO_SND_PCM_FMT_DSD_U16] = SNDRV_PCM_FORMAT_DSD_U16_LE,
	[VIRTIO_SND_PCM_FMT_DSD_U32] = SNDRV_PCM_FORMAT_DSD_U32_LE,
	[VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME] =
		SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
};

/* Map for converting VirtIO frame rate to ALSA frame rate. */
struct virtsnd_v2a_rate {
	unsigned int alsa_bit;
	unsigned int rate;
};

static const struct virtsnd_v2a_rate g_v2a_rate_map[] = {
	[VIRTIO_SND_PCM_RATE_5512] = { SNDRV_PCM_RATE_5512, 5512 },
	[VIRTIO_SND_PCM_RATE_8000] = { SNDRV_PCM_RATE_8000, 8000 },
	[VIRTIO_SND_PCM_RATE_11025] = { SNDRV_PCM_RATE_11025, 11025 },
	[VIRTIO_SND_PCM_RATE_16000] = { SNDRV_PCM_RATE_16000, 16000 },
	[VIRTIO_SND_PCM_RATE_22050] = { SNDRV_PCM_RATE_22050, 22050 },
	[VIRTIO_SND_PCM_RATE_32000] = { SNDRV_PCM_RATE_32000, 32000 },
	[VIRTIO_SND_PCM_RATE_44100] = { SNDRV_PCM_RATE_44100, 44100 },
	[VIRTIO_SND_PCM_RATE_48000] = { SNDRV_PCM_RATE_48000, 48000 },
	[VIRTIO_SND_PCM_RATE_64000] = { SNDRV_PCM_RATE_64000, 64000 },
	[VIRTIO_SND_PCM_RATE_88200] = { SNDRV_PCM_RATE_88200, 88200 },
	[VIRTIO_SND_PCM_RATE_96000] = { SNDRV_PCM_RATE_96000, 96000 },
	[VIRTIO_SND_PCM_RATE_176400] = { SNDRV_PCM_RATE_176400, 176400 },
	[VIRTIO_SND_PCM_RATE_192000] = { SNDRV_PCM_RATE_192000, 192000 }
};

/**
 * virtsnd_pcm_build_hw() - Parse substream config and build HW descriptor.
 * @vss: VirtIO substream.
 * @info: VirtIO substream information entry.
 *
 * Context: Any context.
 * Return: 0 on success, -EINVAL if configuration is invalid.
 */
static int virtsnd_pcm_build_hw(struct virtio_pcm_substream *vss,
				struct virtio_snd_pcm_info *info)
{
	struct virtio_device *vdev = vss->snd->vdev;
	unsigned int i;
	u64 values;
	size_t sample_max = 0;
	size_t sample_min = 0;

	vss->features = le32_to_cpu(info->features);

	/*
	 * TODO: set SNDRV_PCM_INFO_{BATCH,BLOCK_TRANSFER} if device supports
	 * only message-based transport.
	 */
	vss->hw.info =
		SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_BATCH |
		SNDRV_PCM_INFO_BLOCK_TRANSFER |
		SNDRV_PCM_INFO_INTERLEAVED |
		SNDRV_PCM_INFO_PAUSE;

	if (!info->channels_min || info->channels_min > info->channels_max) {
		dev_err(&vdev->dev,
			"SID %u: invalid channel range [%u %u]\n",
			vss->sid, info->channels_min, info->channels_max);
		return -EINVAL;
	}

	vss->hw.channels_min = info->channels_min;
	vss->hw.channels_max = info->channels_max;

	values = le64_to_cpu(info->formats);

	vss->hw.formats = 0;

	for (i = 0; i < ARRAY_SIZE(g_v2a_format_map); ++i)
		if (values & (1ULL << i)) {
			snd_pcm_format_t alsa_fmt = g_v2a_format_map[i];
			int bytes = snd_pcm_format_physical_width(alsa_fmt) / 8;

			if (!sample_min || sample_min > bytes)
				sample_min = bytes;

			if (sample_max < bytes)
				sample_max = bytes;

			vss->hw.formats |= pcm_format_to_bits(alsa_fmt);
		}

	if (!vss->hw.formats) {
		dev_err(&vdev->dev,
			"SID %u: no supported PCM sample formats found\n",
			vss->sid);
		return -EINVAL;
	}

	values = le64_to_cpu(info->rates);

	vss->hw.rates = 0;

	for (i = 0; i < ARRAY_SIZE(g_v2a_rate_map); ++i)
		if (values & (1ULL << i)) {
			if (!vss->hw.rate_min ||
			    vss->hw.rate_min > g_v2a_rate_map[i].rate)
				vss->hw.rate_min = g_v2a_rate_map[i].rate;

			if (vss->hw.rate_max < g_v2a_rate_map[i].rate)
				vss->hw.rate_max = g_v2a_rate_map[i].rate;

			vss->hw.rates |= g_v2a_rate_map[i].alsa_bit;
		}

	if (!vss->hw.rates) {
		dev_err(&vdev->dev,
			"SID %u: no supported PCM frame rates found\n",
			vss->sid);
		return -EINVAL;
	}

	vss->hw.periods_min = pcm_periods_min;
	vss->hw.periods_max = pcm_periods_max;

	/*
	 * We must ensure that there is enough space in the buffer to store
	 * pcm_buffer_ms ms for the combination (Cmax, Smax, Rmax), where:
	 *   Cmax = maximum supported number of channels,
	 *   Smax = maximum supported sample size in bytes,
	 *   Rmax = maximum supported frame rate.
	 */
	vss->hw.buffer_bytes_max =
		PAGE_ALIGN(sample_max * vss->hw.channels_max * pcm_buffer_ms *
			   (vss->hw.rate_max / MSEC_PER_SEC));

	/*
	 * We must ensure that the minimum period size is enough to store
	 * pcm_period_ms_min ms for the combination (Cmin, Smin, Rmin), where:
	 *   Cmin = minimum supported number of channels,
	 *   Smin = minimum supported sample size in bytes,
	 *   Rmin = minimum supported frame rate.
	 */
	vss->hw.period_bytes_min =
		sample_min * vss->hw.channels_min * pcm_period_ms_min *
		(vss->hw.rate_min / MSEC_PER_SEC);

	/*
	 * We must ensure that the maximum period size is enough to store
	 * pcm_period_ms_max ms for the combination (Cmax, Smax, Rmax).
	 */
	vss->hw.period_bytes_max =
		sample_max * vss->hw.channels_max * pcm_period_ms_max *
		(vss->hw.rate_max / MSEC_PER_SEC);

	return 0;
}

/**
 * virtsnd_pcm_find() - Find the PCM device for the specified node ID.
 * @snd: VirtIO sound device.
 * @nid: Function node ID.
 *
 * Context: Any context.
 * Return: a pointer to the PCM device or ERR_PTR(-ENOENT).
 */
struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid)
{
	struct virtio_pcm *vpcm;

	list_for_each_entry(vpcm, &snd->pcm_list, list)
		if (vpcm->nid == nid)
			return vpcm;

	return ERR_PTR(-ENOENT);
}

/**
 * virtsnd_pcm_find_or_create() - Find or create the PCM device for the
 *                                specified node ID.
 * @snd: VirtIO sound device.
 * @nid: Function node ID.
 *
 * Context: Any context that permits to sleep.
 * Return: a pointer to the PCM device or ERR_PTR(-errno).
 */
struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid)
{
	struct virtio_device *vdev = snd->vdev;
	struct virtio_pcm *vpcm;

	vpcm = virtsnd_pcm_find(snd, nid);
	if (!IS_ERR(vpcm))
		return vpcm;

	vpcm = devm_kzalloc(&vdev->dev, sizeof(*vpcm), GFP_KERNEL);
	if (!vpcm)
		return ERR_PTR(-ENOMEM);

	vpcm->nid = nid;
	list_add_tail(&vpcm->list, &snd->pcm_list);

	return vpcm;
}

/**
 * virtsnd_pcm_validate() - Validate if the device can be started.
 * @vdev: VirtIO parent device.
 *
 * Context: Any context.
 * Return: 0 on success, -EINVAL on failure.
 */
int virtsnd_pcm_validate(struct virtio_device *vdev)
{
	if (pcm_periods_min < 2 || pcm_periods_min > pcm_periods_max) {
		dev_err(&vdev->dev,
			"invalid range [%u %u] of the number of PCM periods\n",
			pcm_periods_min, pcm_periods_max);
		return -EINVAL;
	}

	if (!pcm_period_ms_min || pcm_period_ms_min > pcm_period_ms_max) {
		dev_err(&vdev->dev,
			"invalid range [%u %u] of the size of the PCM period\n",
			pcm_period_ms_min, pcm_period_ms_max);
		return -EINVAL;
	}

	if (pcm_buffer_ms < pcm_periods_min * pcm_period_ms_min) {
		dev_err(&vdev->dev,
			"pcm_buffer_ms(=%u) value cannot be < %u ms\n",
			pcm_buffer_ms, pcm_periods_min * pcm_period_ms_min);
		return -EINVAL;
	}

	if (pcm_period_ms_max > pcm_buffer_ms / 2) {
		dev_err(&vdev->dev,
			"pcm_period_ms_max(=%u) value cannot be > %u ms\n",
			pcm_period_ms_max, pcm_buffer_ms / 2);
		return -EINVAL;
	}

	return 0;
}

/**
 * virtsnd_pcm_period_elapsed() - Kernel work function to handle the elapsed
 *                                period state.
 * @work: Elapsed period work.
 *
 * The main purpose of this function is to call snd_pcm_period_elapsed() in
 * a process context, not in an interrupt context. This is necessary because PCM
 * devices operate in non-atomic mode.
 *
 * Context: Process context.
 */
static void virtsnd_pcm_period_elapsed(struct work_struct *work)
{
	struct virtio_pcm_substream *vss =
		container_of(work, struct virtio_pcm_substream, elapsed_period);

	snd_pcm_period_elapsed(vss->substream);
}

/**
 * virtsnd_pcm_parse_cfg() - Parse the stream configuration.
 * @snd: VirtIO sound device.
 *
 * This function is called during initial device initialization.
 *
 * Context: Any context that permits to sleep.
 * Return: 0 on success, -errno on failure.
 */
int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
{
	struct virtio_device *vdev = snd->vdev;
	struct virtio_snd_pcm_info *info;
	u32 i;
	int rc;

	virtio_cread_le(vdev, struct virtio_snd_config, streams,
			&snd->nsubstreams);
	if (!snd->nsubstreams)
		return 0;

	snd->substreams = devm_kcalloc(&vdev->dev, snd->nsubstreams,
				       sizeof(*snd->substreams), GFP_KERNEL);
	if (!snd->substreams)
		return -ENOMEM;

	/*
	 * Initialize critical substream fields early in case we hit an
	 * error path and end up trying to clean up uninitialized structures
	 * elsewhere.
	 */
	for (i = 0; i < snd->nsubstreams; ++i) {
		struct virtio_pcm_substream *vss = &snd->substreams[i];

		vss->snd = snd;
		vss->sid = i;
		INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
		init_waitqueue_head(&vss->msg_empty);
		spin_lock_init(&vss->lock);
	}

	info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_PCM_INFO, 0,
				    snd->nsubstreams, sizeof(*info), info);
	if (rc)
		goto on_exit;

	for (i = 0; i < snd->nsubstreams; ++i) {
		struct virtio_pcm_substream *vss = &snd->substreams[i];
		struct virtio_pcm *vpcm;

		rc = virtsnd_pcm_build_hw(vss, &info[i]);
		if (rc)
			goto on_exit;

		vss->nid = le32_to_cpu(info[i].hdr.hda_fn_nid);

		vpcm = virtsnd_pcm_find_or_create(snd, vss->nid);
		if (IS_ERR(vpcm)) {
			rc = PTR_ERR(vpcm);
			goto on_exit;
		}

		switch (info[i].direction) {
		case VIRTIO_SND_D_OUTPUT:
			vss->direction = SNDRV_PCM_STREAM_PLAYBACK;
			break;
		case VIRTIO_SND_D_INPUT:
			vss->direction = SNDRV_PCM_STREAM_CAPTURE;
			break;
		default:
			dev_err(&vdev->dev, "SID %u: unknown direction (%u)\n",
				vss->sid, info[i].direction);
			rc = -EINVAL;
			goto on_exit;
		}

		vpcm->streams[vss->direction].nsubstreams++;
	}

on_exit:
	kfree(info);

	return rc;
}

/**
 * virtsnd_pcm_build_devs() - Build ALSA PCM devices.
 * @snd: VirtIO sound device.
 *
 * Context: Any context that permits to sleep.
 * Return: 0 on success, -errno on failure.
 */
int virtsnd_pcm_build_devs(struct virtio_snd *snd)
{
	struct virtio_device *vdev = snd->vdev;
	struct virtio_pcm *vpcm;
	u32 i;
	int rc;

	list_for_each_entry(vpcm, &snd->pcm_list, list) {
		unsigned int npbs =
			vpcm->streams[SNDRV_PCM_STREAM_PLAYBACK].nsubstreams;
		unsigned int ncps =
			vpcm->streams[SNDRV_PCM_STREAM_CAPTURE].nsubstreams;

		if (!npbs && !ncps)
			continue;

		rc = snd_pcm_new(snd->card, VIRTIO_SND_CARD_DRIVER, vpcm->nid,
				 npbs, ncps, &vpcm->pcm);
		if (rc) {
			dev_err(&vdev->dev, "snd_pcm_new[%u] failed: %d\n",
				vpcm->nid, rc);
			return rc;
		}

		vpcm->pcm->info_flags = 0;
		vpcm->pcm->dev_class = SNDRV_PCM_CLASS_GENERIC;
		vpcm->pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
		snprintf(vpcm->pcm->name, sizeof(vpcm->pcm->name),
			 VIRTIO_SND_PCM_NAME " %u", vpcm->pcm->device);
		vpcm->pcm->private_data = vpcm;
		vpcm->pcm->nonatomic = true;

		for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) {
			struct virtio_pcm_stream *stream = &vpcm->streams[i];

			if (!stream->nsubstreams)
				continue;

			stream->substreams =
				devm_kcalloc(&vdev->dev, stream->nsubstreams,
					     sizeof(*stream->substreams),
					     GFP_KERNEL);
			if (!stream->substreams)
				return -ENOMEM;

			stream->nsubstreams = 0;
		}
	}

	for (i = 0; i < snd->nsubstreams; ++i) {
		struct virtio_pcm_stream *vs;
		struct virtio_pcm_substream *vss = &snd->substreams[i];

		vpcm = virtsnd_pcm_find(snd, vss->nid);
		if (IS_ERR(vpcm))
			return PTR_ERR(vpcm);

		vs = &vpcm->streams[vss->direction];
		vs->substreams[vs->nsubstreams++] = vss;
	}

	list_for_each_entry(vpcm, &snd->pcm_list, list) {
		for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) {
			struct virtio_pcm_stream *vs = &vpcm->streams[i];
			struct snd_pcm_str *ks = &vpcm->pcm->streams[i];
			struct snd_pcm_substream *kss;

			if (!vs->nsubstreams)
				continue;

			for (kss = ks->substream; kss; kss = kss->next)
				vs->substreams[kss->number]->substream = kss;

			snd_pcm_set_ops(vpcm->pcm, i, &virtsnd_pcm_ops);
		}

		snd_pcm_set_managed_buffer_all(vpcm->pcm,
					       SNDRV_DMA_TYPE_VMALLOC, NULL,
					       0, 0);
	}

	return 0;
}

/**
 * virtsnd_pcm_event() - Handle the PCM device event notification.
 * @snd: VirtIO sound device.
 * @event: VirtIO sound event.
 *
 * Context: Interrupt context.
 */
void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event)
{
	struct virtio_pcm_substream *vss;
	u32 sid = le32_to_cpu(event->data);

	if (sid >= snd->nsubstreams)
		return;

	vss = &snd->substreams[sid];

	switch (le32_to_cpu(event->hdr.code)) {
	case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED:
		/* TODO: deal with shmem elapsed period */
		break;
	case VIRTIO_SND_EVT_PCM_XRUN:
		spin_lock(&vss->lock);
		if (vss->xfer_enabled)
			vss->xfer_xrun = true;
		spin_unlock(&vss->lock);
		break;
	}
}
