// SPDX-License-Identifier: GPL-2.0 OR MIT

/*
 * Xen para-virtual sound device
 *
 * Copyright (C) 2016-2018 EPAM Systems Inc.
 *
 * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
 */

#include <linux/platform_device.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>

#include <xen/xenbus.h>
#include <xen/xen-front-pgdir-shbuf.h>

#include "xen_snd_front.h"
#include "xen_snd_front_alsa.h"
#include "xen_snd_front_cfg.h"
#include "xen_snd_front_evtchnl.h"

struct xen_snd_front_pcm_stream_info {
	struct xen_snd_front_info *front_info;
	struct xen_snd_front_evtchnl_pair *evt_pair;

	/* This is the shared buffer with its backing storage. */
	struct xen_front_pgdir_shbuf shbuf;
	u8 *buffer;
	size_t buffer_sz;
	int num_pages;
	struct page **pages;

	int index;

	bool is_open;
	struct snd_pcm_hardware pcm_hw;

	/* Number of processed frames as reported by the backend. */
	snd_pcm_uframes_t be_cur_frame;
	/* Current HW pointer to be reported via .period callback. */
	atomic_t hw_ptr;
	/* Modulo of the number of processed frames - for period detection. */
	u32 out_frames;
};

struct xen_snd_front_pcm_instance_info {
	struct xen_snd_front_card_info *card_info;
	struct snd_pcm *pcm;
	struct snd_pcm_hardware pcm_hw;
	int num_pcm_streams_pb;
	struct xen_snd_front_pcm_stream_info *streams_pb;
	int num_pcm_streams_cap;
	struct xen_snd_front_pcm_stream_info *streams_cap;
};

struct xen_snd_front_card_info {
	struct xen_snd_front_info *front_info;
	struct snd_card *card;
	struct snd_pcm_hardware pcm_hw;
	int num_pcm_instances;
	struct xen_snd_front_pcm_instance_info *pcm_instances;
};

struct alsa_sndif_sample_format {
	u8 sndif;
	snd_pcm_format_t alsa;
};

static const struct alsa_sndif_sample_format ALSA_SNDIF_FORMATS[] = {
	{
		.sndif = XENSND_PCM_FORMAT_U8,
		.alsa = SNDRV_PCM_FORMAT_U8
	},
	{
		.sndif = XENSND_PCM_FORMAT_S8,
		.alsa = SNDRV_PCM_FORMAT_S8
	},
	{
		.sndif = XENSND_PCM_FORMAT_U16_LE,
		.alsa = SNDRV_PCM_FORMAT_U16_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_U16_BE,
		.alsa = SNDRV_PCM_FORMAT_U16_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_S16_LE,
		.alsa = SNDRV_PCM_FORMAT_S16_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_S16_BE,
		.alsa = SNDRV_PCM_FORMAT_S16_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_U24_LE,
		.alsa = SNDRV_PCM_FORMAT_U24_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_U24_BE,
		.alsa = SNDRV_PCM_FORMAT_U24_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_S24_LE,
		.alsa = SNDRV_PCM_FORMAT_S24_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_S24_BE,
		.alsa = SNDRV_PCM_FORMAT_S24_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_U32_LE,
		.alsa = SNDRV_PCM_FORMAT_U32_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_U32_BE,
		.alsa = SNDRV_PCM_FORMAT_U32_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_S32_LE,
		.alsa = SNDRV_PCM_FORMAT_S32_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_S32_BE,
		.alsa = SNDRV_PCM_FORMAT_S32_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_A_LAW,
		.alsa = SNDRV_PCM_FORMAT_A_LAW
	},
	{
		.sndif = XENSND_PCM_FORMAT_MU_LAW,
		.alsa = SNDRV_PCM_FORMAT_MU_LAW
	},
	{
		.sndif = XENSND_PCM_FORMAT_F32_LE,
		.alsa = SNDRV_PCM_FORMAT_FLOAT_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_F32_BE,
		.alsa = SNDRV_PCM_FORMAT_FLOAT_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_F64_LE,
		.alsa = SNDRV_PCM_FORMAT_FLOAT64_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_F64_BE,
		.alsa = SNDRV_PCM_FORMAT_FLOAT64_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE,
		.alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
	},
	{
		.sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE,
		.alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
	},
	{
		.sndif = XENSND_PCM_FORMAT_IMA_ADPCM,
		.alsa = SNDRV_PCM_FORMAT_IMA_ADPCM
	},
	{
		.sndif = XENSND_PCM_FORMAT_MPEG,
		.alsa = SNDRV_PCM_FORMAT_MPEG
	},
	{
		.sndif = XENSND_PCM_FORMAT_GSM,
		.alsa = SNDRV_PCM_FORMAT_GSM
	},
};

static int to_sndif_format(snd_pcm_format_t format)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++)
		if (ALSA_SNDIF_FORMATS[i].alsa == format)
			return ALSA_SNDIF_FORMATS[i].sndif;

	return -EINVAL;
}

static u64 to_sndif_formats_mask(u64 alsa_formats)
{
	u64 mask;
	int i;

	mask = 0;
	for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++)
		if (pcm_format_to_bits(ALSA_SNDIF_FORMATS[i].alsa) & alsa_formats)
			mask |= BIT_ULL(ALSA_SNDIF_FORMATS[i].sndif);

	return mask;
}

static u64 to_alsa_formats_mask(u64 sndif_formats)
{
	u64 mask;
	int i;

	mask = 0;
	for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++)
		if (BIT_ULL(ALSA_SNDIF_FORMATS[i].sndif) & sndif_formats)
			mask |= pcm_format_to_bits(ALSA_SNDIF_FORMATS[i].alsa);

	return mask;
}

static void stream_clear(struct xen_snd_front_pcm_stream_info *stream)
{
	stream->is_open = false;
	stream->be_cur_frame = 0;
	stream->out_frames = 0;
	atomic_set(&stream->hw_ptr, 0);
	xen_snd_front_evtchnl_pair_clear(stream->evt_pair);
	memset(&stream->shbuf, 0, sizeof(stream->shbuf));
	stream->buffer = NULL;
	stream->buffer_sz = 0;
	stream->pages = NULL;
	stream->num_pages = 0;
}

static void stream_free(struct xen_snd_front_pcm_stream_info *stream)
{
	xen_front_pgdir_shbuf_unmap(&stream->shbuf);
	xen_front_pgdir_shbuf_free(&stream->shbuf);
	if (stream->buffer)
		free_pages_exact(stream->buffer, stream->buffer_sz);
	kfree(stream->pages);
	stream_clear(stream);
}

static struct xen_snd_front_pcm_stream_info *
stream_get(struct snd_pcm_substream *substream)
{
	struct xen_snd_front_pcm_instance_info *pcm_instance =
			snd_pcm_substream_chip(substream);
	struct xen_snd_front_pcm_stream_info *stream;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		stream = &pcm_instance->streams_pb[substream->number];
	else
		stream = &pcm_instance->streams_cap[substream->number];

	return stream;
}

static int alsa_hw_rule(struct snd_pcm_hw_params *params,
			struct snd_pcm_hw_rule *rule)
{
	struct xen_snd_front_pcm_stream_info *stream = rule->private;
	struct device *dev = &stream->front_info->xb_dev->dev;
	struct snd_mask *formats =
			hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
	struct snd_interval *rates =
			hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	struct snd_interval *channels =
			hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
	struct snd_interval *period =
			hw_param_interval(params,
					  SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
	struct snd_interval *buffer =
			hw_param_interval(params,
					  SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
	struct xensnd_query_hw_param req;
	struct xensnd_query_hw_param resp;
	struct snd_interval interval;
	struct snd_mask mask;
	u64 sndif_formats;
	int changed, ret;

	/* Collect all the values we need for the query. */

	req.formats = to_sndif_formats_mask((u64)formats->bits[0] |
					    (u64)(formats->bits[1]) << 32);

	req.rates.min = rates->min;
	req.rates.max = rates->max;

	req.channels.min = channels->min;
	req.channels.max = channels->max;

	req.buffer.min = buffer->min;
	req.buffer.max = buffer->max;

	req.period.min = period->min;
	req.period.max = period->max;

	ret = xen_snd_front_stream_query_hw_param(&stream->evt_pair->req,
						  &req, &resp);
	if (ret < 0) {
		/* Check if this is due to backend communication error. */
		if (ret == -EIO || ret == -ETIMEDOUT)
			dev_err(dev, "Failed to query ALSA HW parameters\n");
		return ret;
	}

	/* Refine HW parameters after the query. */
	changed  = 0;

	sndif_formats = to_alsa_formats_mask(resp.formats);
	snd_mask_none(&mask);
	mask.bits[0] = (u32)sndif_formats;
	mask.bits[1] = (u32)(sndif_formats >> 32);
	ret = snd_mask_refine(formats, &mask);
	if (ret < 0)
		return ret;
	changed |= ret;

	interval.openmin = 0;
	interval.openmax = 0;
	interval.integer = 1;

	interval.min = resp.rates.min;
	interval.max = resp.rates.max;
	ret = snd_interval_refine(rates, &interval);
	if (ret < 0)
		return ret;
	changed |= ret;

	interval.min = resp.channels.min;
	interval.max = resp.channels.max;
	ret = snd_interval_refine(channels, &interval);
	if (ret < 0)
		return ret;
	changed |= ret;

	interval.min = resp.buffer.min;
	interval.max = resp.buffer.max;
	ret = snd_interval_refine(buffer, &interval);
	if (ret < 0)
		return ret;
	changed |= ret;

	interval.min = resp.period.min;
	interval.max = resp.period.max;
	ret = snd_interval_refine(period, &interval);
	if (ret < 0)
		return ret;
	changed |= ret;

	return changed;
}

static int alsa_open(struct snd_pcm_substream *substream)
{
	struct xen_snd_front_pcm_instance_info *pcm_instance =
			snd_pcm_substream_chip(substream);
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct xen_snd_front_info *front_info =
			pcm_instance->card_info->front_info;
	struct device *dev = &front_info->xb_dev->dev;
	int ret;

	/*
	 * Return our HW properties: override defaults with those configured
	 * via XenStore.
	 */
	runtime->hw = stream->pcm_hw;
	runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
			      SNDRV_PCM_INFO_MMAP_VALID |
			      SNDRV_PCM_INFO_DOUBLE |
			      SNDRV_PCM_INFO_BATCH |
			      SNDRV_PCM_INFO_NONINTERLEAVED |
			      SNDRV_PCM_INFO_RESUME |
			      SNDRV_PCM_INFO_PAUSE);
	runtime->hw.info |= SNDRV_PCM_INFO_INTERLEAVED;

	stream->evt_pair = &front_info->evt_pairs[stream->index];

	stream->front_info = front_info;

	stream->evt_pair->evt.u.evt.substream = substream;

	stream_clear(stream);

	xen_snd_front_evtchnl_pair_set_connected(stream->evt_pair, true);

	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
				  alsa_hw_rule, stream,
				  SNDRV_PCM_HW_PARAM_FORMAT, -1);
	if (ret) {
		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_FORMAT\n");
		return ret;
	}

	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  alsa_hw_rule, stream,
				  SNDRV_PCM_HW_PARAM_RATE, -1);
	if (ret) {
		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_RATE\n");
		return ret;
	}

	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
				  alsa_hw_rule, stream,
				  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
	if (ret) {
		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_CHANNELS\n");
		return ret;
	}

	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
				  alsa_hw_rule, stream,
				  SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
	if (ret) {
		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_PERIOD_SIZE\n");
		return ret;
	}

	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
				  alsa_hw_rule, stream,
				  SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
	if (ret) {
		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_BUFFER_SIZE\n");
		return ret;
	}

	return 0;
}

static int alsa_close(struct snd_pcm_substream *substream)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);

	xen_snd_front_evtchnl_pair_set_connected(stream->evt_pair, false);
	return 0;
}

static int shbuf_setup_backstore(struct xen_snd_front_pcm_stream_info *stream,
				 size_t buffer_sz)
{
	int i;

	stream->buffer = alloc_pages_exact(buffer_sz, GFP_KERNEL);
	if (!stream->buffer)
		return -ENOMEM;

	stream->buffer_sz = buffer_sz;
	stream->num_pages = DIV_ROUND_UP(stream->buffer_sz, PAGE_SIZE);
	stream->pages = kcalloc(stream->num_pages, sizeof(struct page *),
				GFP_KERNEL);
	if (!stream->pages)
		return -ENOMEM;

	for (i = 0; i < stream->num_pages; i++)
		stream->pages[i] = virt_to_page(stream->buffer + i * PAGE_SIZE);

	return 0;
}

static int alsa_hw_params(struct snd_pcm_substream *substream,
			  struct snd_pcm_hw_params *params)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
	struct xen_snd_front_info *front_info = stream->front_info;
	struct xen_front_pgdir_shbuf_cfg buf_cfg;
	int ret;

	/*
	 * This callback may be called multiple times,
	 * so free the previously allocated shared buffer if any.
	 */
	stream_free(stream);
	ret = shbuf_setup_backstore(stream, params_buffer_bytes(params));
	if (ret < 0)
		goto fail;

	memset(&buf_cfg, 0, sizeof(buf_cfg));
	buf_cfg.xb_dev = front_info->xb_dev;
	buf_cfg.pgdir = &stream->shbuf;
	buf_cfg.num_pages = stream->num_pages;
	buf_cfg.pages = stream->pages;

	ret = xen_front_pgdir_shbuf_alloc(&buf_cfg);
	if (ret < 0)
		goto fail;

	ret = xen_front_pgdir_shbuf_map(&stream->shbuf);
	if (ret < 0)
		goto fail;

	return 0;

fail:
	stream_free(stream);
	dev_err(&front_info->xb_dev->dev,
		"Failed to allocate buffers for stream with index %d\n",
		stream->index);
	return ret;
}

static int alsa_hw_free(struct snd_pcm_substream *substream)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
	int ret;

	ret = xen_snd_front_stream_close(&stream->evt_pair->req);
	stream_free(stream);
	return ret;
}

static int alsa_prepare(struct snd_pcm_substream *substream)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);

	if (!stream->is_open) {
		struct snd_pcm_runtime *runtime = substream->runtime;
		u8 sndif_format;
		int ret;

		ret = to_sndif_format(runtime->format);
		if (ret < 0) {
			dev_err(&stream->front_info->xb_dev->dev,
				"Unsupported sample format: %d\n",
				runtime->format);
			return ret;
		}
		sndif_format = ret;

		ret = xen_snd_front_stream_prepare(&stream->evt_pair->req,
						   &stream->shbuf,
						   sndif_format,
						   runtime->channels,
						   runtime->rate,
						   snd_pcm_lib_buffer_bytes(substream),
						   snd_pcm_lib_period_bytes(substream));
		if (ret < 0)
			return ret;

		stream->is_open = true;
	}

	return 0;
}

static int alsa_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
	int type;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		type = XENSND_OP_TRIGGER_START;
		break;

	case SNDRV_PCM_TRIGGER_RESUME:
		type = XENSND_OP_TRIGGER_RESUME;
		break;

	case SNDRV_PCM_TRIGGER_STOP:
		type = XENSND_OP_TRIGGER_STOP;
		break;

	case SNDRV_PCM_TRIGGER_SUSPEND:
		type = XENSND_OP_TRIGGER_PAUSE;
		break;

	default:
		return -EINVAL;
	}

	return xen_snd_front_stream_trigger(&stream->evt_pair->req, type);
}

void xen_snd_front_alsa_handle_cur_pos(struct xen_snd_front_evtchnl *evtchnl,
				       u64 pos_bytes)
{
	struct snd_pcm_substream *substream = evtchnl->u.evt.substream;
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
	snd_pcm_uframes_t delta, new_hw_ptr, cur_frame;

	cur_frame = bytes_to_frames(substream->runtime, pos_bytes);

	delta = cur_frame - stream->be_cur_frame;
	stream->be_cur_frame = cur_frame;

	new_hw_ptr = (snd_pcm_uframes_t)atomic_read(&stream->hw_ptr);
	new_hw_ptr = (new_hw_ptr + delta) % substream->runtime->buffer_size;
	atomic_set(&stream->hw_ptr, (int)new_hw_ptr);

	stream->out_frames += delta;
	if (stream->out_frames > substream->runtime->period_size) {
		stream->out_frames %= substream->runtime->period_size;
		snd_pcm_period_elapsed(substream);
	}
}

static snd_pcm_uframes_t alsa_pointer(struct snd_pcm_substream *substream)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);

	return (snd_pcm_uframes_t)atomic_read(&stream->hw_ptr);
}

static int alsa_pb_copy(struct snd_pcm_substream *substream,
			int channel, unsigned long pos, struct iov_iter *src,
			unsigned long count)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);

	if (unlikely(pos + count > stream->buffer_sz))
		return -EINVAL;

	if (copy_from_iter(stream->buffer + pos, count, src) != count)
		return -EFAULT;

	return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
}

static int alsa_cap_copy(struct snd_pcm_substream *substream,
			 int channel, unsigned long pos, struct iov_iter *dst,
			 unsigned long count)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
	int ret;

	if (unlikely(pos + count > stream->buffer_sz))
		return -EINVAL;

	ret = xen_snd_front_stream_read(&stream->evt_pair->req, pos, count);
	if (ret < 0)
		return ret;

	if (copy_to_iter(stream->buffer + pos, count, dst) != count)
		return -EFAULT;
	return 0;
}

static int alsa_pb_fill_silence(struct snd_pcm_substream *substream,
				int channel, unsigned long pos,
				unsigned long count)
{
	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);

	if (unlikely(pos + count > stream->buffer_sz))
		return -EINVAL;

	memset(stream->buffer + pos, 0, count);

	return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
}

/*
 * FIXME: The mmaped data transfer is asynchronous and there is no
 * ack signal from user-space when it is done. This is the
 * reason it is not implemented in the PV driver as we do need
 * to know when the buffer can be transferred to the backend.
 */

static const struct snd_pcm_ops snd_drv_alsa_playback_ops = {
	.open		= alsa_open,
	.close		= alsa_close,
	.hw_params	= alsa_hw_params,
	.hw_free	= alsa_hw_free,
	.prepare	= alsa_prepare,
	.trigger	= alsa_trigger,
	.pointer	= alsa_pointer,
	.copy		= alsa_pb_copy,
	.fill_silence	= alsa_pb_fill_silence,
};

static const struct snd_pcm_ops snd_drv_alsa_capture_ops = {
	.open		= alsa_open,
	.close		= alsa_close,
	.hw_params	= alsa_hw_params,
	.hw_free	= alsa_hw_free,
	.prepare	= alsa_prepare,
	.trigger	= alsa_trigger,
	.pointer	= alsa_pointer,
	.copy		= alsa_cap_copy,
};

static int new_pcm_instance(struct xen_snd_front_card_info *card_info,
			    struct xen_front_cfg_pcm_instance *instance_cfg,
			    struct xen_snd_front_pcm_instance_info *pcm_instance_info)
{
	struct snd_pcm *pcm;
	int ret, i;

	dev_dbg(&card_info->front_info->xb_dev->dev,
		"New PCM device \"%s\" with id %d playback %d capture %d",
		instance_cfg->name,
		instance_cfg->device_id,
		instance_cfg->num_streams_pb,
		instance_cfg->num_streams_cap);

	pcm_instance_info->card_info = card_info;

	pcm_instance_info->pcm_hw = instance_cfg->pcm_hw;

	if (instance_cfg->num_streams_pb) {
		pcm_instance_info->streams_pb =
				devm_kcalloc(&card_info->card->card_dev,
					     instance_cfg->num_streams_pb,
					     sizeof(struct xen_snd_front_pcm_stream_info),
					     GFP_KERNEL);
		if (!pcm_instance_info->streams_pb)
			return -ENOMEM;
	}

	if (instance_cfg->num_streams_cap) {
		pcm_instance_info->streams_cap =
				devm_kcalloc(&card_info->card->card_dev,
					     instance_cfg->num_streams_cap,
					     sizeof(struct xen_snd_front_pcm_stream_info),
					     GFP_KERNEL);
		if (!pcm_instance_info->streams_cap)
			return -ENOMEM;
	}

	pcm_instance_info->num_pcm_streams_pb =
			instance_cfg->num_streams_pb;
	pcm_instance_info->num_pcm_streams_cap =
			instance_cfg->num_streams_cap;

	for (i = 0; i < pcm_instance_info->num_pcm_streams_pb; i++) {
		pcm_instance_info->streams_pb[i].pcm_hw =
			instance_cfg->streams_pb[i].pcm_hw;
		pcm_instance_info->streams_pb[i].index =
			instance_cfg->streams_pb[i].index;
	}

	for (i = 0; i < pcm_instance_info->num_pcm_streams_cap; i++) {
		pcm_instance_info->streams_cap[i].pcm_hw =
			instance_cfg->streams_cap[i].pcm_hw;
		pcm_instance_info->streams_cap[i].index =
			instance_cfg->streams_cap[i].index;
	}

	ret = snd_pcm_new(card_info->card, instance_cfg->name,
			  instance_cfg->device_id,
			  instance_cfg->num_streams_pb,
			  instance_cfg->num_streams_cap,
			  &pcm);
	if (ret < 0)
		return ret;

	pcm->private_data = pcm_instance_info;
	pcm->info_flags = 0;
	/* we want to handle all PCM operations in non-atomic context */
	pcm->nonatomic = true;
	strscpy(pcm->name, "Virtual card PCM", sizeof(pcm->name));

	if (instance_cfg->num_streams_pb)
		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
				&snd_drv_alsa_playback_ops);

	if (instance_cfg->num_streams_cap)
		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
				&snd_drv_alsa_capture_ops);

	pcm_instance_info->pcm = pcm;
	return 0;
}

int xen_snd_front_alsa_init(struct xen_snd_front_info *front_info)
{
	struct device *dev = &front_info->xb_dev->dev;
	struct xen_front_cfg_card *cfg = &front_info->cfg;
	struct xen_snd_front_card_info *card_info;
	struct snd_card *card;
	int ret, i;

	dev_dbg(dev, "Creating virtual sound card\n");

	ret = snd_card_new(dev, 0, XENSND_DRIVER_NAME, THIS_MODULE,
			   sizeof(struct xen_snd_front_card_info), &card);
	if (ret < 0)
		return ret;

	card_info = card->private_data;
	card_info->front_info = front_info;
	front_info->card_info = card_info;
	card_info->card = card;
	card_info->pcm_instances =
			devm_kcalloc(dev, cfg->num_pcm_instances,
				     sizeof(struct xen_snd_front_pcm_instance_info),
				     GFP_KERNEL);
	if (!card_info->pcm_instances) {
		ret = -ENOMEM;
		goto fail;
	}

	card_info->num_pcm_instances = cfg->num_pcm_instances;
	card_info->pcm_hw = cfg->pcm_hw;

	for (i = 0; i < cfg->num_pcm_instances; i++) {
		ret = new_pcm_instance(card_info, &cfg->pcm_instances[i],
				       &card_info->pcm_instances[i]);
		if (ret < 0)
			goto fail;
	}

	strscpy(card->driver, XENSND_DRIVER_NAME, sizeof(card->driver));
	strscpy(card->shortname, cfg->name_short, sizeof(card->shortname));
	strscpy(card->longname, cfg->name_long, sizeof(card->longname));

	ret = snd_card_register(card);
	if (ret < 0)
		goto fail;

	return 0;

fail:
	snd_card_free(card);
	return ret;
}

void xen_snd_front_alsa_fini(struct xen_snd_front_info *front_info)
{
	struct xen_snd_front_card_info *card_info;
	struct snd_card *card;

	card_info = front_info->card_info;
	if (!card_info)
		return;

	card = card_info->card;
	if (!card)
		return;

	dev_dbg(&front_info->xb_dev->dev, "Removing virtual sound card %d\n",
		card->number);
	snd_card_free(card);

	/* Card_info will be freed when destroying front_info->xb_dev->dev. */
	card_info->card = NULL;
}
