// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Patch transfer callback for Emu10k1
 *
 *  Copyright (C) 2000 Takashi iwai <tiwai@suse.de>
 */
/*
 * All the code for loading in a patch.  There is very little that is
 * chip specific here.  Just the actual writing to the board.
 */

#include "emu10k1_synth_local.h"

/*
 */
#define BLANK_LOOP_START	4
#define BLANK_LOOP_END		8
#define BLANK_LOOP_SIZE		12
#define BLANK_HEAD_SIZE		3

/*
 * allocate a sample block and copy data from userspace
 */
int
snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
		       struct snd_util_memhdr *hdr,
		       const void __user *data, long count)
{
	u8 fill;
	u32 xor;
	int shift;
	int offset;
	int truesize, size, blocksize;
	int loop_start, loop_end, loop_size, data_end, unroll;
	struct snd_emu10k1 *emu;

	emu = rec->hw;
	if (snd_BUG_ON(!sp || !hdr))
		return -EINVAL;

	if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP | SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
		/* should instead return -ENOTSUPP; but compatibility */
		printk(KERN_WARNING "Emu10k1 wavetable patch %d with unsupported loop feature\n",
		       sp->v.sample);
	}

	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS) {
		shift = 0;
		fill = 0x80;
		xor = (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) ? 0 : 0x80808080;
	} else {
		shift = 1;
		fill = 0;
		xor = (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) ? 0x80008000 : 0;
	}

	/* compute true data size to be loaded */
	truesize = sp->v.size + BLANK_HEAD_SIZE;
	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
		truesize += BLANK_LOOP_SIZE;
		/* if no blank loop is attached in the sample, add it */
		if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
			sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
			sp->v.loopend = sp->v.end + BLANK_LOOP_END;
		}
	}

	loop_start = sp->v.loopstart;
	loop_end = sp->v.loopend;
	loop_size = loop_end - loop_start;
	if (!loop_size)
		return -EINVAL;
	data_end = sp->v.end;

	/* recalculate offset */
	sp->v.start += BLANK_HEAD_SIZE;
	sp->v.end += BLANK_HEAD_SIZE;
	sp->v.loopstart += BLANK_HEAD_SIZE;
	sp->v.loopend += BLANK_HEAD_SIZE;

	// Automatic pre-filling of the cache does not work in the presence
	// of loops (*), and we don't want to fill it manually, as that is
	// fiddly and slow. So we unroll the loop until the loop end is
	// beyond the cache size.
	// (*) Strictly speaking, a single iteration is supported (that's
	// how it works when the playback engine runs), but handling this
	// special case is not worth it.
	unroll = 0;
	while (sp->v.loopend < 64) {
		truesize += loop_size;
		sp->v.loopstart += loop_size;
		sp->v.loopend += loop_size;
		sp->v.end += loop_size;
		unroll++;
	}

	/* try to allocate a memory block */
	blocksize = truesize << shift;
	sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
	if (sp->block == NULL) {
		dev_dbg(emu->card->dev,
			"synth malloc failed (size=%d)\n", blocksize);
		/* not ENOMEM (for compatibility with OSS) */
		return -ENOSPC;
	}
	/* set the total size */
	sp->v.truesize = blocksize;

	/* write blank samples at head */
	offset = 0;
	size = BLANK_HEAD_SIZE << shift;
	snd_emu10k1_synth_memset(emu, sp->block, offset, size, fill);
	offset += size;

	/* copy provided samples */
	if (unroll && loop_end <= data_end) {
		size = loop_end << shift;
		if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size, xor))
			goto faulty;
		offset += size;

		data += loop_start << shift;
		while (--unroll > 0) {
			size = loop_size << shift;
			if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size, xor))
				goto faulty;
			offset += size;
		}

		size = (data_end - loop_start) << shift;
	} else {
		size = data_end << shift;
	}
	if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size, xor))
		goto faulty;
	offset += size;

	/* clear rest of samples (if any) */
	if (offset < blocksize)
		snd_emu10k1_synth_memset(emu, sp->block, offset, blocksize - offset, fill);

	return 0;

faulty:
	snd_emu10k1_synth_free(emu, sp->block);
	sp->block = NULL;
	return -EFAULT;
}

/*
 * free a sample block
 */
int
snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
			struct snd_util_memhdr *hdr)
{
	struct snd_emu10k1 *emu;

	emu = rec->hw;
	if (snd_BUG_ON(!sp || !hdr))
		return -EINVAL;

	if (sp->block) {
		snd_emu10k1_synth_free(emu, sp->block);
		sp->block = NULL;
	}
	return 0;
}

