/*
 *  Interface for OSS sequencer emulation
 *
 *  Copyright (C) 1999 Takashi Iwai <tiwai@suse.de>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * Changes
 * 19990227   Steve Ratcliffe   Made separate file and merged in latest
 * 				midi emulation.
 */


#ifdef CONFIG_SND_SEQUENCER_OSS

#include <linux/export.h>
#include <asm/uaccess.h>
#include <sound/core.h>
#include "emux_voice.h"
#include <sound/asoundef.h>

static int snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
static int snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg);
static int snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
				  unsigned long ioarg);
static int snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
				       const char __user *buf, int offs, int count);
static int snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg);
static int snd_emux_event_oss_input(struct snd_seq_event *ev, int direct,
				    void *private, int atomic, int hop);
static void reset_port_mode(struct snd_emux_port *port, int midi_mode);
static void emuspec_control(struct snd_emux *emu, struct snd_emux_port *port,
			    int cmd, unsigned char *event, int atomic, int hop);
static void gusspec_control(struct snd_emux *emu, struct snd_emux_port *port,
			    int cmd, unsigned char *event, int atomic, int hop);
static void fake_event(struct snd_emux *emu, struct snd_emux_port *port,
		       int ch, int param, int val, int atomic, int hop);

/* operators */
static struct snd_seq_oss_callback oss_callback = {
	.owner = THIS_MODULE,
	.open = snd_emux_open_seq_oss,
	.close = snd_emux_close_seq_oss,
	.ioctl = snd_emux_ioctl_seq_oss,
	.load_patch = snd_emux_load_patch_seq_oss,
	.reset = snd_emux_reset_seq_oss,
};


/*
 * register OSS synth
 */

void
snd_emux_init_seq_oss(struct snd_emux *emu)
{
	struct snd_seq_oss_reg *arg;
	struct snd_seq_device *dev;

	if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS,
			       sizeof(struct snd_seq_oss_reg), &dev) < 0)
		return;

	emu->oss_synth = dev;
	strcpy(dev->name, emu->name);
	arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
	arg->type = SYNTH_TYPE_SAMPLE;
	arg->subtype = SAMPLE_TYPE_AWE32;
	arg->nvoices = emu->max_voices;
	arg->oper = oss_callback;
	arg->private_data = emu;

	/* register to OSS synth table */
	snd_device_register(emu->card, dev);
}


/*
 * unregister
 */
void
snd_emux_detach_seq_oss(struct snd_emux *emu)
{
	if (emu->oss_synth) {
		snd_device_free(emu->card, emu->oss_synth);
		emu->oss_synth = NULL;
	}
}


/* use port number as a unique soundfont client number */
#define SF_CLIENT_NO(p)	((p) + 0x1000)

/*
 * open port for OSS sequencer
 */
static int
snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
{
	struct snd_emux *emu;
	struct snd_emux_port *p;
	struct snd_seq_port_callback callback;
	char tmpname[64];

	emu = closure;
	if (snd_BUG_ON(!arg || !emu))
		return -ENXIO;

	mutex_lock(&emu->register_mutex);

	if (!snd_emux_inc_count(emu)) {
		mutex_unlock(&emu->register_mutex);
		return -EFAULT;
	}

	memset(&callback, 0, sizeof(callback));
	callback.owner = THIS_MODULE;
	callback.event_input = snd_emux_event_oss_input;

	sprintf(tmpname, "%s OSS Port", emu->name);
	p = snd_emux_create_port(emu, tmpname, 32,
				 1, &callback);
	if (p == NULL) {
		snd_printk(KERN_ERR "can't create port\n");
		snd_emux_dec_count(emu);
		mutex_unlock(&emu->register_mutex);
		return -ENOMEM;
	}

	/* fill the argument data */
	arg->private_data = p;
	arg->addr.client = p->chset.client;
	arg->addr.port = p->chset.port;
	p->oss_arg = arg;

	reset_port_mode(p, arg->seq_mode);

	snd_emux_reset_port(p);

	mutex_unlock(&emu->register_mutex);
	return 0;
}


#define DEFAULT_DRUM_FLAGS	((1<<9) | (1<<25))

/*
 * reset port mode
 */
static void
reset_port_mode(struct snd_emux_port *port, int midi_mode)
{
	if (midi_mode) {
		port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_MIDI;
		port->drum_flags = DEFAULT_DRUM_FLAGS;
		port->volume_atten = 0;
		port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_KEYPRESS;
	} else {
		port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_SYNTH;
		port->drum_flags = 0;
		port->volume_atten = 32;
		port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS;
	}
}


/*
 * close port
 */
static int
snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
{
	struct snd_emux *emu;
	struct snd_emux_port *p;

	if (snd_BUG_ON(!arg))
		return -ENXIO;
	p = arg->private_data;
	if (snd_BUG_ON(!p))
		return -ENXIO;

	emu = p->emu;
	if (snd_BUG_ON(!emu))
		return -ENXIO;

	mutex_lock(&emu->register_mutex);
	snd_emux_sounds_off_all(p);
	snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port));
	snd_seq_event_port_detach(p->chset.client, p->chset.port);
	snd_emux_dec_count(emu);

	mutex_unlock(&emu->register_mutex);
	return 0;
}


/*
 * load patch
 */
static int
snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
			    const char __user *buf, int offs, int count)
{
	struct snd_emux *emu;
	struct snd_emux_port *p;
	int rc;

	if (snd_BUG_ON(!arg))
		return -ENXIO;
	p = arg->private_data;
	if (snd_BUG_ON(!p))
		return -ENXIO;

	emu = p->emu;
	if (snd_BUG_ON(!emu))
		return -ENXIO;

	if (format == GUS_PATCH)
		rc = snd_soundfont_load_guspatch(emu->sflist, buf, count,
						 SF_CLIENT_NO(p->chset.port));
	else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
		struct soundfont_patch_info patch;
		if (count < (int)sizeof(patch))
			rc = -EINVAL;
		if (copy_from_user(&patch, buf, sizeof(patch)))
			rc = -EFAULT;
		if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
		    patch.type <= SNDRV_SFNT_PROBE_DATA)
			rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
		else {
			if (emu->ops.load_fx)
				rc = emu->ops.load_fx(emu, patch.type, patch.optarg, buf, count);
			else
				rc = -EINVAL;
		}
	} else
		rc = 0;
	return rc;
}


/*
 * ioctl
 */
static int
snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg)
{
	struct snd_emux_port *p;
	struct snd_emux *emu;

	if (snd_BUG_ON(!arg))
		return -ENXIO;
	p = arg->private_data;
	if (snd_BUG_ON(!p))
		return -ENXIO;

	emu = p->emu;
	if (snd_BUG_ON(!emu))
		return -ENXIO;

	switch (cmd) {
	case SNDCTL_SEQ_RESETSAMPLES:
		snd_soundfont_remove_samples(emu->sflist);
		return 0;
			
	case SNDCTL_SYNTH_MEMAVL:
		if (emu->memhdr)
			return snd_util_mem_avail(emu->memhdr);
		return 0;
	}

	return 0;
}


/*
 * reset device
 */
static int
snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg)
{
	struct snd_emux_port *p;

	if (snd_BUG_ON(!arg))
		return -ENXIO;
	p = arg->private_data;
	if (snd_BUG_ON(!p))
		return -ENXIO;
	snd_emux_reset_port(p);
	return 0;
}


/*
 * receive raw events: only SEQ_PRIVATE is accepted.
 */
static int
snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_data,
			 int atomic, int hop)
{
	struct snd_emux *emu;
	struct snd_emux_port *p;
	unsigned char cmd, *data;

	p = private_data;
	if (snd_BUG_ON(!p))
		return -EINVAL;
	emu = p->emu;
	if (snd_BUG_ON(!emu))
		return -EINVAL;
	if (ev->type != SNDRV_SEQ_EVENT_OSS)
		return snd_emux_event_input(ev, direct, private_data, atomic, hop);

	data = ev->data.raw8.d;
	/* only SEQ_PRIVATE is accepted */
	if (data[0] != 0xfe)
		return 0;
	cmd = data[2] & _EMUX_OSS_MODE_VALUE_MASK;
	if (data[2] & _EMUX_OSS_MODE_FLAG)
		emuspec_control(emu, p, cmd, data, atomic, hop);
	else
		gusspec_control(emu, p, cmd, data, atomic, hop);
	return 0;
}


/*
 * OSS/AWE driver specific h/w controls
 */
static void
emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
		unsigned char *event, int atomic, int hop)
{
	int voice;
	unsigned short p1;
	short p2;
	int i;
	struct snd_midi_channel *chan;

	voice = event[3];
	if (voice < 0 || voice >= port->chset.max_channels)
		chan = NULL;
	else
		chan = &port->chset.channels[voice];

	p1 = *(unsigned short *) &event[4];
	p2 = *(short *) &event[6];

	switch (cmd) {
#if 0 /* don't do this atomically */
	case _EMUX_OSS_REMOVE_LAST_SAMPLES:
		snd_soundfont_remove_unlocked(emu->sflist);
		break;
#endif
	case _EMUX_OSS_SEND_EFFECT:
		if (chan)
			snd_emux_send_effect_oss(port, chan, p1, p2);
		break;
		
	case _EMUX_OSS_TERMINATE_ALL:
		snd_emux_terminate_all(emu);
		break;

	case _EMUX_OSS_TERMINATE_CHANNEL:
		/*snd_emux_mute_channel(emu, chan);*/
		break;
	case _EMUX_OSS_RESET_CHANNEL:
		/*snd_emux_channel_init(chset, chan);*/
		break;

	case _EMUX_OSS_RELEASE_ALL:
		fake_event(emu, port, voice, MIDI_CTL_ALL_NOTES_OFF, 0, atomic, hop);
		break;
	case _EMUX_OSS_NOTEOFF_ALL:
		fake_event(emu, port, voice, MIDI_CTL_ALL_SOUNDS_OFF, 0, atomic, hop);
		break;

	case _EMUX_OSS_INITIAL_VOLUME:
		if (p2) {
			port->volume_atten = (short)p1;
			snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
		}
		break;

	case _EMUX_OSS_CHN_PRESSURE:
		if (chan) {
			chan->midi_pressure = p1;
			snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_FMMOD|SNDRV_EMUX_UPDATE_FM2FRQ2);
		}
		break;

	case _EMUX_OSS_CHANNEL_MODE:
		reset_port_mode(port, p1);
		snd_emux_reset_port(port);
		break;

	case _EMUX_OSS_DRUM_CHANNELS:
		port->drum_flags = *(unsigned int*)&event[4];
		for (i = 0; i < port->chset.max_channels; i++) {
			chan = &port->chset.channels[i];
			chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
		}
		break;

	case _EMUX_OSS_MISC_MODE:
		if (p1 < EMUX_MD_END)
			port->ctrls[p1] = p2;
		break;
	case _EMUX_OSS_DEBUG_MODE:
		break;

	default:
		if (emu->ops.oss_ioctl)
			emu->ops.oss_ioctl(emu, cmd, p1, p2);
		break;
	}
}

/*
 * GUS specific h/w controls
 */

#include <linux/ultrasound.h>

static void
gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
		unsigned char *event, int atomic, int hop)
{
	int voice;
	unsigned short p1;
	short p2;
	int plong;
	struct snd_midi_channel *chan;

	if (port->port_mode != SNDRV_EMUX_PORT_MODE_OSS_SYNTH)
		return;
	if (cmd == _GUS_NUMVOICES)
		return;
	voice = event[3];
	if (voice < 0 || voice >= port->chset.max_channels)
		return;

	chan = &port->chset.channels[voice];

	p1 = *(unsigned short *) &event[4];
	p2 = *(short *) &event[6];
	plong = *(int*) &event[4];

	switch (cmd) {
	case _GUS_VOICESAMPLE:
		chan->midi_program = p1;
		return;

	case _GUS_VOICEBALA:
		/* 0 to 15 --> 0 to 127 */
		chan->control[MIDI_CTL_MSB_PAN] = (int)p1 << 3;
		snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
		return;

	case _GUS_VOICEVOL:
	case _GUS_VOICEVOL2:
		/* not supported yet */
		return;

	case _GUS_RAMPRANGE:
	case _GUS_RAMPRATE:
	case _GUS_RAMPMODE:
	case _GUS_RAMPON:
	case _GUS_RAMPOFF:
		/* volume ramping not supported */
		return;

	case _GUS_VOLUME_SCALE:
		return;

	case _GUS_VOICE_POS:
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
		snd_emux_send_effect(port, chan, EMUX_FX_SAMPLE_START,
				     (short)(plong & 0x7fff),
				     EMUX_FX_FLAG_SET);
		snd_emux_send_effect(port, chan, EMUX_FX_COARSE_SAMPLE_START,
				     (plong >> 15) & 0xffff,
				     EMUX_FX_FLAG_SET);
#endif
		return;
	}
}


/*
 * send an event to midi emulation
 */
static void
fake_event(struct snd_emux *emu, struct snd_emux_port *port, int ch, int param, int val, int atomic, int hop)
{
	struct snd_seq_event ev;
	memset(&ev, 0, sizeof(ev));
	ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
	ev.data.control.channel = ch;
	ev.data.control.param = param;
	ev.data.control.value = val;
	snd_emux_event_input(&ev, 0, port, atomic, hop);
}

#endif /* CONFIG_SND_SEQUENCER_OSS */
