/*
 *  Routines for Gravis UltraSound soundcards - Synthesizer
 *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
 *
 *
 *   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
 *
 */

#include <sound/driver.h>
#include <linux/time.h>
#include <sound/core.h>
#include <sound/gus.h>

/*
 *
 */

int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave,
			      char __user *data, long len, int atomic)
{
	struct snd_gus_card *gus = private_data;
	struct snd_gf1_mem_block *block;
	int err;

	if (wave->format & IWFFFF_WAVE_ROM)
		return 0;	/* it's probably ok - verify the address? */
	if (wave->format & IWFFFF_WAVE_STEREO)
		return -EINVAL;	/* not supported */
	block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
				  SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF,
				  NULL, wave->size,
				  wave->format & IWFFFF_WAVE_16BIT, 1,
				  wave->share_id);
	if (block == NULL)
		return -ENOMEM;
	err = snd_gus_dram_write(gus, data,
				 block->ptr, wave->size);
	if (err < 0) {
		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
		snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
		return err;
	}
	wave->address.memory = block->ptr;
	return 0;
}

int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave,
			      char __user *data, long len, int atomic)
{
	struct snd_gus_card *gus = private_data;

	return snd_gus_dram_read(gus, data, wave->address.memory, wave->size,
				 wave->format & IWFFFF_WAVE_ROM ? 1 : 0);
}

int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave,
				 int atomic)
{
	struct snd_gus_card *gus = private_data;

	if (wave->format & IWFFFF_WAVE_ROM)
		return 0;	/* it's probably ok - verify the address? */	
	return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
}

/*
 *
 */

int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave,
			   char __user *data, long len, int atomic)
{
	struct snd_gus_card *gus = private_data;
	struct snd_gf1_mem_block *block;
	int err;

	if (wave->format & GF1_WAVE_STEREO)
		return -EINVAL;	/* not supported */
	block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
				  SNDRV_GF1_MEM_OWNER_WAVE_GF1,
				  NULL, wave->size,
				  wave->format & GF1_WAVE_16BIT, 1,
				  wave->share_id);
	if (block == NULL)
		return -ENOMEM;
	err = snd_gus_dram_write(gus, data,
				 block->ptr, wave->size);
	if (err < 0) {
		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
		snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
		return err;
	}
	wave->address.memory = block->ptr;
	return 0;
}

int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave,
			   char __user *data, long len, int atomic)
{
	struct snd_gus_card *gus = private_data;

	return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 0);
}

int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave,
			      int atomic)
{
	struct snd_gus_card *gus = private_data;

	return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
}

/*
 *
 */

int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr,
			      char __user *data, long len, int atomic)
{
	struct snd_gus_card *gus = private_data;
	struct snd_gf1_mem_block *block;
	int err;

	if (instr->format & SIMPLE_WAVE_STEREO)
		return -EINVAL;	/* not supported */
	block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
				  SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE,
				  NULL, instr->size,
				  instr->format & SIMPLE_WAVE_16BIT, 1,
				  instr->share_id);
	if (block == NULL)
		return -ENOMEM;
	err = snd_gus_dram_write(gus, data, block->ptr, instr->size);
	if (err < 0) {
		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
		snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
		return err;
	}
	instr->address.memory = block->ptr;
	return 0;
}

int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr,
			      char __user *data, long len, int atomic)
{
	struct snd_gus_card *gus = private_data;

	return snd_gus_dram_read(gus, data, instr->address.memory, instr->size, 0);
}

int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr,
			         int atomic)
{
	struct snd_gus_card *gus = private_data;

	return snd_gf1_mem_free(&gus->gf1.mem_alloc, instr->address.memory);
}
