/*
 *  Advanced Linux Sound Architecture
 *  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>

#ifdef CONFIG_SND_OSSEMUL

#if !defined(CONFIG_SOUND) && !(defined(MODULE) && defined(CONFIG_SOUND_MODULE))
#error "Enable the OSS soundcore multiplexer (CONFIG_SOUND) in the kernel."
#endif

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/info.h>
#include <linux/sound.h>

#define SNDRV_OS_MINORS		256

static struct list_head snd_oss_minors_hash[SNDRV_CARDS];

static DECLARE_MUTEX(sound_oss_mutex);

static snd_minor_t *snd_oss_minor_search(int minor)
{
	struct list_head *list;
	snd_minor_t *mptr;

	list_for_each(list, &snd_oss_minors_hash[SNDRV_MINOR_OSS_CARD(minor)]) {
		mptr = list_entry(list, snd_minor_t, list);
		if (mptr->number == minor)
			return mptr;
	}
	return NULL;
}

static int snd_oss_kernel_minor(int type, snd_card_t * card, int dev)
{
	int minor;

	switch (type) {
	case SNDRV_OSS_DEVICE_TYPE_MIXER:
		snd_assert(card != NULL && dev <= 1, return -EINVAL);
		minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIXER1 : SNDRV_MINOR_OSS_MIXER));
		break;
	case SNDRV_OSS_DEVICE_TYPE_SEQUENCER:
		minor = SNDRV_MINOR_OSS_SEQUENCER;
		break;
	case SNDRV_OSS_DEVICE_TYPE_MUSIC:
		minor = SNDRV_MINOR_OSS_MUSIC;
		break;
	case SNDRV_OSS_DEVICE_TYPE_PCM:
		snd_assert(card != NULL && dev <= 1, return -EINVAL);
		minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_PCM1 : SNDRV_MINOR_OSS_PCM));
		break;
	case SNDRV_OSS_DEVICE_TYPE_MIDI:
		snd_assert(card != NULL && dev <= 1, return -EINVAL);
		minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIDI1 : SNDRV_MINOR_OSS_MIDI));
		break;
	case SNDRV_OSS_DEVICE_TYPE_DMFM:
		minor = SNDRV_MINOR_OSS(card->number, SNDRV_MINOR_OSS_DMFM);
		break;
	case SNDRV_OSS_DEVICE_TYPE_SNDSTAT:
		minor = SNDRV_MINOR_OSS_SNDSTAT;
		break;
	default:
		return -EINVAL;
	}
	snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL);
	return minor;
}

int snd_register_oss_device(int type, snd_card_t * card, int dev, snd_minor_t * reg, const char *name)
{
	int minor = snd_oss_kernel_minor(type, card, dev);
	int minor_unit;
	snd_minor_t *preg;
	int cidx = SNDRV_MINOR_OSS_CARD(minor);
	int track2 = -1;
	int register1 = -1, register2 = -1;

	if (minor < 0)
		return minor;
	preg = (snd_minor_t *)kmalloc(sizeof(snd_minor_t), GFP_KERNEL);
	if (preg == NULL)
		return -ENOMEM;
	*preg = *reg;
	preg->number = minor;
	preg->device = dev;
	down(&sound_oss_mutex);
	list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]);
	minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
	switch (minor_unit) {
	case SNDRV_MINOR_OSS_PCM:
		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO);
		break;
	case SNDRV_MINOR_OSS_MIDI:
		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI);
		break;
	case SNDRV_MINOR_OSS_MIDI1:
		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
		break;
	}
	register1 = register_sound_special(reg->f_ops, minor);
	if (register1 != minor)
		goto __end;
	if (track2 >= 0) {
		register2 = register_sound_special(reg->f_ops, track2);
		if (register2 != track2)
			goto __end;
	}
	up(&sound_oss_mutex);
	return 0;

      __end:
      	if (register2 >= 0)
      		unregister_sound_special(register2);
      	if (register1 >= 0)
      		unregister_sound_special(register1);
      	list_del(&preg->list);
	up(&sound_oss_mutex);
	kfree(preg);
      	return -EBUSY;
}

int snd_unregister_oss_device(int type, snd_card_t * card, int dev)
{
	int minor = snd_oss_kernel_minor(type, card, dev);
	int cidx = SNDRV_MINOR_OSS_CARD(minor);
	int track2 = -1;
	snd_minor_t *mptr;

	if (minor < 0)
		return minor;
	down(&sound_oss_mutex);
	mptr = snd_oss_minor_search(minor);
	if (mptr == NULL) {
		up(&sound_oss_mutex);
		return -ENOENT;
	}
	unregister_sound_special(minor);
	switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
	case SNDRV_MINOR_OSS_PCM:
		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO);
		break;
	case SNDRV_MINOR_OSS_MIDI:
		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI);
		break;
	case SNDRV_MINOR_OSS_MIDI1:
		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
		break;
	}
	if (track2 >= 0)
		unregister_sound_special(track2);
	list_del(&mptr->list);
	up(&sound_oss_mutex);
	kfree(mptr);
	return 0;
}

/*
 *  INFO PART
 */

#ifdef CONFIG_PROC_FS

static snd_info_entry_t *snd_minor_info_oss_entry = NULL;

static void snd_minor_info_oss_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
	int card, dev;
	struct list_head *list;
	snd_minor_t *mptr;

	down(&sound_oss_mutex);
	for (card = 0; card < SNDRV_CARDS; card++) {
		list_for_each(list, &snd_oss_minors_hash[card]) {
			mptr = list_entry(list, snd_minor_t, list);
			dev = SNDRV_MINOR_OSS_DEVICE(mptr->number);
		        if (dev != SNDRV_MINOR_OSS_SNDSTAT &&
			    dev != SNDRV_MINOR_OSS_SEQUENCER &&
			    dev != SNDRV_MINOR_OSS_MUSIC)
				snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, dev, mptr->comment);
			else
				snd_iprintf(buffer, "%3i:       : %s\n", mptr->number, mptr->comment);
		}
	}
	up(&sound_oss_mutex);
}

#endif /* CONFIG_PROC_FS */

int __init snd_minor_info_oss_init(void)
{
#ifdef CONFIG_PROC_FS
	snd_info_entry_t *entry;

	entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
	if (entry) {
		entry->c.text.read_size = PAGE_SIZE;
		entry->c.text.read = snd_minor_info_oss_read;
		if (snd_info_register(entry) < 0) {
			snd_info_free_entry(entry);
			entry = NULL;
		}
	}
	snd_minor_info_oss_entry = entry;
#endif
	return 0;
}

int __exit snd_minor_info_oss_done(void)
{
#ifdef CONFIG_PROC_FS
	if (snd_minor_info_oss_entry)
		snd_info_unregister(snd_minor_info_oss_entry);
#endif
	return 0;
}

int __init snd_oss_init_module(void)
{
	int card;
	
	for (card = 0; card < SNDRV_CARDS; card++)
		INIT_LIST_HEAD(&snd_oss_minors_hash[card]);
	return 0;
}

#endif /* CONFIG_SND_OSSEMUL */
