// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * pcm emulation on emu8000 wavetable
 *
 *  Copyright (C) 2002 Takashi Iwai <tiwai@suse.de>
 */

#include "emu8000_local.h"

#include <linux/sched/signal.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <sound/initval.h>
#include <sound/pcm.h>

/*
 * define the following if you want to use this pcm with non-interleaved mode
 */
/* #define USE_NONINTERLEAVE */

/* NOTE: for using the non-interleaved mode with alsa-lib, you have to set
 * mmap_emulation flag to 1 in your .asoundrc, such like
 *
 *	pcm.emu8k {
 *		type plug
 *		slave.pcm {
 *			type hw
 *			card 0
 *			device 1
 *			mmap_emulation 1
 *		}
 *	}
 *
 * besides, for the time being, the non-interleaved mode doesn't work well on
 * alsa-lib...
 */


struct snd_emu8k_pcm {
	struct snd_emu8000 *emu;
	struct snd_pcm_substream *substream;

	unsigned int allocated_bytes;
	struct snd_util_memblk *block;
	unsigned int offset;
	unsigned int buf_size;
	unsigned int period_size;
	unsigned int loop_start[2];
	unsigned int pitch;
	int panning[2];
	int last_ptr;
	int period_pos;
	int voices;
	unsigned int dram_opened: 1;
	unsigned int running: 1;
	unsigned int timer_running: 1;
	struct timer_list timer;
	spinlock_t timer_lock;
};

#define LOOP_BLANK_SIZE		8


/*
 * open up channels for the simultaneous data transfer and playback
 */
static int
emu8k_open_dram_for_pcm(struct snd_emu8000 *emu, int channels)
{
	int i;

	/* reserve up to 2 voices for playback */
	snd_emux_lock_voice(emu->emu, 0);
	if (channels > 1)
		snd_emux_lock_voice(emu->emu, 1);

	/* reserve 28 voices for loading */
	for (i = channels + 1; i < EMU8000_DRAM_VOICES; i++) {
		unsigned int mode = EMU8000_RAM_WRITE;
		snd_emux_lock_voice(emu->emu, i);
#ifndef USE_NONINTERLEAVE
		if (channels > 1 && (i & 1) != 0)
			mode |= EMU8000_RAM_RIGHT;
#endif
		snd_emu8000_dma_chan(emu, i, mode);
	}

	/* assign voice 31 and 32 to ROM */
	EMU8000_VTFT_WRITE(emu, 30, 0);
	EMU8000_PSST_WRITE(emu, 30, 0x1d8);
	EMU8000_CSL_WRITE(emu, 30, 0x1e0);
	EMU8000_CCCA_WRITE(emu, 30, 0x1d8);
	EMU8000_VTFT_WRITE(emu, 31, 0);
	EMU8000_PSST_WRITE(emu, 31, 0x1d8);
	EMU8000_CSL_WRITE(emu, 31, 0x1e0);
	EMU8000_CCCA_WRITE(emu, 31, 0x1d8);

	return 0;
}

/*
 */
static void
snd_emu8000_write_wait(struct snd_emu8000 *emu, int can_schedule)
{
	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
		if (can_schedule) {
			schedule_timeout_interruptible(1);
			if (signal_pending(current))
				break;
		}
	}
}

/*
 * close all channels
 */
static void
emu8k_close_dram(struct snd_emu8000 *emu)
{
	int i;

	for (i = 0; i < 2; i++)
		snd_emux_unlock_voice(emu->emu, i);
	for (; i < EMU8000_DRAM_VOICES; i++) {
		snd_emu8000_dma_chan(emu, i, EMU8000_RAM_CLOSE);
		snd_emux_unlock_voice(emu->emu, i);
	}
}

/*
 * convert Hz to AWE32 rate offset (see emux/soundfont.c)
 */

#define OFFSET_SAMPLERATE	1011119		/* base = 44100 */
#define SAMPLERATE_RATIO	4096

static int calc_rate_offset(int hz)
{
	return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
}


/*
 */

static const struct snd_pcm_hardware emu8k_pcm_hw = {
#ifdef USE_NONINTERLEAVE
	.info =			SNDRV_PCM_INFO_NONINTERLEAVED,
#else
	.info =			SNDRV_PCM_INFO_INTERLEAVED,
#endif
	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
	.rate_min =		4000,
	.rate_max =		48000,
	.channels_min =		1,
	.channels_max =		2,
	.buffer_bytes_max =	(128*1024),
	.period_bytes_min =	1024,
	.period_bytes_max =	(128*1024),
	.periods_min =		2,
	.periods_max =		1024,
	.fifo_size =		0,

};

/*
 * get the current position at the given channel from CCCA register
 */
static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch)
{
	int val = EMU8000_CCCA_READ(rec->emu, ch) & 0xfffffff;
	val -= rec->loop_start[ch] - 1;
	return val;
}


/*
 * timer interrupt handler
 * check the current position and update the period if necessary.
 */
static void emu8k_pcm_timer_func(struct timer_list *t)
{
	struct snd_emu8k_pcm *rec = from_timer(rec, t, timer);
	int ptr, delta;

	spin_lock(&rec->timer_lock);
	/* update the current pointer */
	ptr = emu8k_get_curpos(rec, 0);
	if (ptr < rec->last_ptr)
		delta = ptr + rec->buf_size - rec->last_ptr;
	else
		delta = ptr - rec->last_ptr;
	rec->period_pos += delta;
	rec->last_ptr = ptr;

	/* reprogram timer */
	mod_timer(&rec->timer, jiffies + 1);

	/* update period */
	if (rec->period_pos >= (int)rec->period_size) {
		rec->period_pos %= rec->period_size;
		spin_unlock(&rec->timer_lock);
		snd_pcm_period_elapsed(rec->substream);
		return;
	}
	spin_unlock(&rec->timer_lock);
}


/*
 * open pcm
 * creating an instance here
 */
static int emu8k_pcm_open(struct snd_pcm_substream *subs)
{
	struct snd_emu8000 *emu = snd_pcm_substream_chip(subs);
	struct snd_emu8k_pcm *rec;
	struct snd_pcm_runtime *runtime = subs->runtime;

	rec = kzalloc(sizeof(*rec), GFP_KERNEL);
	if (! rec)
		return -ENOMEM;

	rec->emu = emu;
	rec->substream = subs;
	runtime->private_data = rec;

	spin_lock_init(&rec->timer_lock);
	timer_setup(&rec->timer, emu8k_pcm_timer_func, 0);

	runtime->hw = emu8k_pcm_hw;
	runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3;
	runtime->hw.period_bytes_max = runtime->hw.buffer_bytes_max / 2;

	/* use timer to update periods.. (specified in msec) */
	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
				     DIV_ROUND_UP(1000000, HZ), UINT_MAX);

	return 0;
}

static int emu8k_pcm_close(struct snd_pcm_substream *subs)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
	kfree(rec);
	subs->runtime->private_data = NULL;
	return 0;
}

/*
 * calculate pitch target
 */
static int calc_pitch_target(int pitch)
{
	int ptarget = 1 << (pitch >> 12);
	if (pitch & 0x800) ptarget += (ptarget * 0x102e) / 0x2710;
	if (pitch & 0x400) ptarget += (ptarget * 0x764) / 0x2710;
	if (pitch & 0x200) ptarget += (ptarget * 0x389) / 0x2710;
	ptarget += (ptarget >> 1);
	if (ptarget > 0xffff) ptarget = 0xffff;
	return ptarget;
}

/*
 * set up the voice
 */
static void setup_voice(struct snd_emu8k_pcm *rec, int ch)
{
	struct snd_emu8000 *hw = rec->emu;
	unsigned int temp;

	/* channel to be silent and idle */
	EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080);
	EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF);
	EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF);
	EMU8000_PTRX_WRITE(hw, ch, 0);
	EMU8000_CPF_WRITE(hw, ch, 0);

	/* pitch offset */
	EMU8000_IP_WRITE(hw, ch, rec->pitch);
	/* set envelope parameters */
	EMU8000_ENVVAL_WRITE(hw, ch, 0x8000);
	EMU8000_ATKHLD_WRITE(hw, ch, 0x7f7f);
	EMU8000_DCYSUS_WRITE(hw, ch, 0x7f7f);
	EMU8000_ENVVOL_WRITE(hw, ch, 0x8000);
	EMU8000_ATKHLDV_WRITE(hw, ch, 0x7f7f);
	/* decay/sustain parameter for volume envelope is used
	   for triggerg the voice */
	/* modulation envelope heights */
	EMU8000_PEFE_WRITE(hw, ch, 0x0);
	/* lfo1/2 delay */
	EMU8000_LFO1VAL_WRITE(hw, ch, 0x8000);
	EMU8000_LFO2VAL_WRITE(hw, ch, 0x8000);
	/* lfo1 pitch & cutoff shift */
	EMU8000_FMMOD_WRITE(hw, ch, 0);
	/* lfo1 volume & freq */
	EMU8000_TREMFRQ_WRITE(hw, ch, 0);
	/* lfo2 pitch & freq */
	EMU8000_FM2FRQ2_WRITE(hw, ch, 0);
	/* pan & loop start */
	temp = rec->panning[ch];
	temp = (temp <<24) | ((unsigned int)rec->loop_start[ch] - 1);
	EMU8000_PSST_WRITE(hw, ch, temp);
	/* chorus & loop end (chorus 8bit, MSB) */
	temp = 0; // chorus
	temp = (temp << 24) | ((unsigned int)rec->loop_start[ch] + rec->buf_size - 1);
	EMU8000_CSL_WRITE(hw, ch, temp);
	/* Q & current address (Q 4bit value, MSB) */
	temp = 0; // filterQ
	temp = (temp << 28) | ((unsigned int)rec->loop_start[ch] - 1);
	EMU8000_CCCA_WRITE(hw, ch, temp);
	/* clear unknown registers */
	EMU8000_00A0_WRITE(hw, ch, 0);
	EMU8000_0080_WRITE(hw, ch, 0);
}

/*
 * trigger the voice
 */
static void start_voice(struct snd_emu8k_pcm *rec, int ch)
{
	unsigned long flags;
	struct snd_emu8000 *hw = rec->emu;
	unsigned int temp, aux;
	int pt = calc_pitch_target(rec->pitch);

	/* cutoff and volume */
	EMU8000_IFATN_WRITE(hw, ch, 0xff00);
	EMU8000_VTFT_WRITE(hw, ch, 0xffff);
	EMU8000_CVCF_WRITE(hw, ch, 0xffff);
	/* trigger envelope */
	EMU8000_DCYSUSV_WRITE(hw, ch, 0x7f7f);
	/* set reverb and pitch target */
	temp = 0; // reverb
	if (rec->panning[ch] == 0)
		aux = 0xff;
	else
		aux = (-rec->panning[ch]) & 0xff;
	temp = (temp << 8) | (pt << 16) | aux;
	EMU8000_PTRX_WRITE(hw, ch, temp);
	EMU8000_CPF_WRITE(hw, ch, pt << 16);

	/* start timer */
	spin_lock_irqsave(&rec->timer_lock, flags);
	if (! rec->timer_running) {
		mod_timer(&rec->timer, jiffies + 1);
		rec->timer_running = 1;
	}
	spin_unlock_irqrestore(&rec->timer_lock, flags);
}

/*
 * stop the voice immediately
 */
static void stop_voice(struct snd_emu8k_pcm *rec, int ch)
{
	unsigned long flags;
	struct snd_emu8000 *hw = rec->emu;

	EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);

	/* stop timer */
	spin_lock_irqsave(&rec->timer_lock, flags);
	if (rec->timer_running) {
		del_timer(&rec->timer);
		rec->timer_running = 0;
	}
	spin_unlock_irqrestore(&rec->timer_lock, flags);
}

static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
	int ch;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		for (ch = 0; ch < rec->voices; ch++)
			start_voice(rec, ch);
		rec->running = 1;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		rec->running = 0;
		for (ch = 0; ch < rec->voices; ch++)
			stop_voice(rec, ch);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}


/*
 * copy / silence ops
 */

/*
 * this macro should be inserted in the copy/silence loops
 * to reduce the latency.  without this, the system will hang up
 * during the whole loop.
 */
#define CHECK_SCHEDULER() \
do { \
	cond_resched();\
	if (signal_pending(current))\
		return -EAGAIN;\
} while (0)

#define GET_VAL(sval, iter)						\
	do {								\
		if (!iter)						\
			sval = 0;					\
		else if (copy_from_iter(&sval, 2, iter) != 2)		\
			return -EFAULT;					\
	} while (0)

#ifdef USE_NONINTERLEAVE

#define LOOP_WRITE(rec, offset, iter, count)			\
	do {							\
		struct snd_emu8000 *emu = (rec)->emu;		\
		snd_emu8000_write_wait(emu, 1);			\
		EMU8000_SMALW_WRITE(emu, offset);		\
		while (count > 0) {				\
			unsigned short sval;			\
			CHECK_SCHEDULER();			\
			GET_VAL(sval, iter);			\
			EMU8000_SMLD_WRITE(emu, sval);		\
			count--;				\
		}						\
	} while (0)

/* copy one channel block */
static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
			  int voice, unsigned long pos,
			  struct iov_iter *src, unsigned long count)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	/* convert to word unit */
	pos = (pos << 1) + rec->loop_start[voice];
	count <<= 1;
	LOOP_WRITE(rec, pos, src, count);
	return 0;
}

/* make a channel block silence */
static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
			     int voice, unsigned long pos, unsigned long count)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	/* convert to word unit */
	pos = (pos << 1) + rec->loop_start[voice];
	count <<= 1;
	LOOP_WRITE(rec, pos, NULL, count);
	return 0;
}

#else /* interleave */

#define LOOP_WRITE(rec, pos, iter, count)				\
	do {								\
		struct snd_emu8000 *emu = rec->emu;			\
		snd_emu8000_write_wait(emu, 1);				\
		EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]);	\
		if (rec->voices > 1)					\
			EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]); \
		while (count > 0) {					\
			unsigned short sval;				\
			CHECK_SCHEDULER();				\
			GET_VAL(sval, iter);				\
			EMU8000_SMLD_WRITE(emu, sval);			\
			if (rec->voices > 1) {				\
				CHECK_SCHEDULER();			\
				GET_VAL(sval, iter);			\
				EMU8000_SMRD_WRITE(emu, sval);		\
			}						\
			count--;					\
		}							\
	} while (0)


/*
 * copy the interleaved data can be done easily by using
 * DMA "left" and "right" channels on emu8k engine.
 */
static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
			  int voice, unsigned long pos,
			  struct iov_iter *src, unsigned long count)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	/* convert to frames */
	pos = bytes_to_frames(subs->runtime, pos);
	count = bytes_to_frames(subs->runtime, count);
	LOOP_WRITE(rec, pos, src, count);
	return 0;
}

static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
			     int voice, unsigned long pos, unsigned long count)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	/* convert to frames */
	pos = bytes_to_frames(subs->runtime, pos);
	count = bytes_to_frames(subs->runtime, count);
	LOOP_WRITE(rec, pos, NULL, count);
	return 0;
}
#endif


/*
 * allocate a memory block
 */
static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs,
			       struct snd_pcm_hw_params *hw_params)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	if (rec->block) {
		/* reallocation - release the old block */
		snd_util_mem_free(rec->emu->memhdr, rec->block);
		rec->block = NULL;
	}

	rec->allocated_bytes = params_buffer_bytes(hw_params) + LOOP_BLANK_SIZE * 4;
	rec->block = snd_util_mem_alloc(rec->emu->memhdr, rec->allocated_bytes);
	if (! rec->block)
		return -ENOMEM;
	rec->offset = EMU8000_DRAM_OFFSET + (rec->block->offset >> 1); /* in word */
	/* at least dma_bytes must be set for non-interleaved mode */
	subs->dma_buffer.bytes = params_buffer_bytes(hw_params);

	return 0;
}

/*
 * free the memory block
 */
static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	if (rec->block) {
		int ch;
		for (ch = 0; ch < rec->voices; ch++)
			stop_voice(rec, ch); // to be sure
		if (rec->dram_opened)
			emu8k_close_dram(rec->emu);
		snd_util_mem_free(rec->emu->memhdr, rec->block);
		rec->block = NULL;
	}
	return 0;
}

/*
 */
static int emu8k_pcm_prepare(struct snd_pcm_substream *subs)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate);
	rec->last_ptr = 0;
	rec->period_pos = 0;

	rec->buf_size = subs->runtime->buffer_size;
	rec->period_size = subs->runtime->period_size;
	rec->voices = subs->runtime->channels;
	rec->loop_start[0] = rec->offset + LOOP_BLANK_SIZE;
	if (rec->voices > 1)
		rec->loop_start[1] = rec->loop_start[0] + rec->buf_size + LOOP_BLANK_SIZE;
	if (rec->voices > 1) {
		rec->panning[0] = 0xff;
		rec->panning[1] = 0x00;
	} else
		rec->panning[0] = 0x80;

	if (! rec->dram_opened) {
		int err, i, ch;

		snd_emux_terminate_all(rec->emu->emu);
		err = emu8k_open_dram_for_pcm(rec->emu, rec->voices);
		if (err)
			return err;
		rec->dram_opened = 1;

		/* clear loop blanks */
		snd_emu8000_write_wait(rec->emu, 0);
		EMU8000_SMALW_WRITE(rec->emu, rec->offset);
		for (i = 0; i < LOOP_BLANK_SIZE; i++)
			EMU8000_SMLD_WRITE(rec->emu, 0);
		for (ch = 0; ch < rec->voices; ch++) {
			EMU8000_SMALW_WRITE(rec->emu, rec->loop_start[ch] + rec->buf_size);
			for (i = 0; i < LOOP_BLANK_SIZE; i++)
				EMU8000_SMLD_WRITE(rec->emu, 0);
		}
	}

	setup_voice(rec, 0);
	if (rec->voices > 1)
		setup_voice(rec, 1);
	return 0;
}

static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
	if (rec->running)
		return emu8k_get_curpos(rec, 0);
	return 0;
}


static const struct snd_pcm_ops emu8k_pcm_ops = {
	.open =		emu8k_pcm_open,
	.close =	emu8k_pcm_close,
	.hw_params =	emu8k_pcm_hw_params,
	.hw_free =	emu8k_pcm_hw_free,
	.prepare =	emu8k_pcm_prepare,
	.trigger =	emu8k_pcm_trigger,
	.pointer =	emu8k_pcm_pointer,
	.copy =		emu8k_pcm_copy,
	.fill_silence =	emu8k_pcm_silence,
};


static void snd_emu8000_pcm_free(struct snd_pcm *pcm)
{
	struct snd_emu8000 *emu = pcm->private_data;
	emu->pcm = NULL;
}

int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index)
{
	struct snd_pcm *pcm;
	int err;

	err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm);
	if (err < 0)
		return err;
	pcm->private_data = emu;
	pcm->private_free = snd_emu8000_pcm_free;
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &emu8k_pcm_ops);
	emu->pcm = pcm;

	snd_device_register(card, pcm);

	return 0;
}
