/*
 *   Simple (MOD player) - Instrument routines
 *   Copyright (c) 1999 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/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/ainstr_simple.h>
#include <sound/initval.h>
#include <asm/uaccess.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support.");
MODULE_LICENSE("GPL");

static unsigned int snd_seq_simple_size(unsigned int size, unsigned int format)
{
	unsigned int result = size;
	
	if (format & SIMPLE_WAVE_16BIT)
		result <<= 1;
	if (format & SIMPLE_WAVE_STEREO)
		result <<= 1;
	return result;
}

static void snd_seq_simple_instr_free(snd_simple_ops_t *ops,
				      simple_instrument_t *ip,
				      int atomic)
{
	if (ops->remove_sample)
		ops->remove_sample(ops->private_data, ip, atomic);
}

static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
			      char __user *instr_data, long len,
			      int atomic, int cmd)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
	simple_instrument_t *ip;
	simple_xinstrument_t ix;
	int err, gfp_mask;
	unsigned int real_size;

	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
		return -EINVAL;
	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
	/* copy instrument data */
	if (len < (long)sizeof(ix))
		return -EINVAL;
	if (copy_from_user(&ix, instr_data, sizeof(ix)))
		return -EFAULT;
	if (ix.stype != SIMPLE_STRU_INSTR)
		return -EINVAL;
	instr_data += sizeof(ix);
	len -= sizeof(ix);
	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	ip->share_id[0] = le32_to_cpu(ix.share_id[0]);
	ip->share_id[1] = le32_to_cpu(ix.share_id[1]);
	ip->share_id[2] = le32_to_cpu(ix.share_id[2]);
	ip->share_id[3] = le32_to_cpu(ix.share_id[3]);
	ip->format = le32_to_cpu(ix.format);
	ip->size = le32_to_cpu(ix.size);
	ip->start = le32_to_cpu(ix.start);
	ip->loop_start = le32_to_cpu(ix.loop_start);
	ip->loop_end = le32_to_cpu(ix.loop_end);
	ip->loop_repeat = le16_to_cpu(ix.loop_repeat);
	ip->effect1 = ix.effect1;
	ip->effect1_depth = ix.effect1_depth;
	ip->effect2 = ix.effect2;
	ip->effect2_depth = ix.effect2_depth;
	real_size = snd_seq_simple_size(ip->size, ip->format);
	if (len < (long)real_size)
		return -EINVAL;
	if (ops->put_sample) {
		err = ops->put_sample(ops->private_data, ip,
				      instr_data, real_size, atomic);
		if (err < 0)
			return err;
	}
	return 0;
}

static int snd_seq_simple_get(void *private_data, snd_seq_kinstr_t *instr,
			      char __user *instr_data, long len,
			      int atomic, int cmd)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
	simple_instrument_t *ip;
	simple_xinstrument_t ix;
	int err;
	unsigned int real_size;
	
	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
		return -EINVAL;
	if (len < (long)sizeof(ix))
		return -ENOMEM;
	memset(&ix, 0, sizeof(ix));
	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	ix.stype = SIMPLE_STRU_INSTR;
	ix.share_id[0] = cpu_to_le32(ip->share_id[0]);
	ix.share_id[1] = cpu_to_le32(ip->share_id[1]);
	ix.share_id[2] = cpu_to_le32(ip->share_id[2]);
	ix.share_id[3] = cpu_to_le32(ip->share_id[3]);
	ix.format = cpu_to_le32(ip->format);
	ix.size = cpu_to_le32(ip->size);
	ix.start = cpu_to_le32(ip->start);
	ix.loop_start = cpu_to_le32(ip->loop_start);
	ix.loop_end = cpu_to_le32(ip->loop_end);
	ix.loop_repeat = cpu_to_le32(ip->loop_repeat);
	ix.effect1 = cpu_to_le16(ip->effect1);
	ix.effect1_depth = cpu_to_le16(ip->effect1_depth);
	ix.effect2 = ip->effect2;
	ix.effect2_depth = ip->effect2_depth;
	if (copy_to_user(instr_data, &ix, sizeof(ix)))
		return -EFAULT;
	instr_data += sizeof(ix);
	len -= sizeof(ix);
	real_size = snd_seq_simple_size(ip->size, ip->format);
	if (len < (long)real_size)
		return -ENOMEM;
	if (ops->get_sample) {
		err = ops->get_sample(ops->private_data, ip,
				      instr_data, real_size, atomic);
		if (err < 0)
			return err;
	}
	return 0;
}

static int snd_seq_simple_get_size(void *private_data, snd_seq_kinstr_t *instr,
				   long *size)
{
	simple_instrument_t *ip;

	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	*size = sizeof(simple_xinstrument_t) + snd_seq_simple_size(ip->size, ip->format);
	return 0;
}

static int snd_seq_simple_remove(void *private_data,
			         snd_seq_kinstr_t *instr,
                                 int atomic)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
	simple_instrument_t *ip;

	ip = (simple_instrument_t *)KINSTR_DATA(instr);
	snd_seq_simple_instr_free(ops, ip, atomic);
	return 0;
}

static void snd_seq_simple_notify(void *private_data,
			          snd_seq_kinstr_t *instr,
                                  int what)
{
	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;

	if (ops->notify)
		ops->notify(ops->private_data, instr, what);
}

int snd_seq_simple_init(snd_simple_ops_t *ops,
		        void *private_data,
		        snd_seq_kinstr_ops_t *next)
{
	memset(ops, 0, sizeof(*ops));
	ops->private_data = private_data;
	ops->kops.private_data = ops;
	ops->kops.add_len = sizeof(simple_instrument_t);
	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_SIMPLE;
	ops->kops.put = snd_seq_simple_put;
	ops->kops.get = snd_seq_simple_get;
	ops->kops.get_size = snd_seq_simple_get_size;
	ops->kops.remove = snd_seq_simple_remove;
	ops->kops.notify = snd_seq_simple_notify;
	ops->kops.next = next;
	return 0;
}

/*
 *  Init part
 */

static int __init alsa_ainstr_simple_init(void)
{
	return 0;
}

static void __exit alsa_ainstr_simple_exit(void)
{
}

module_init(alsa_ainstr_simple_init)
module_exit(alsa_ainstr_simple_exit)

EXPORT_SYMBOL(snd_seq_simple_init);
