/*
 * linux/kernel/chr_drv/sound/pcsp.c
 *
 * /dev/pcsp implementation
 *
 * Copyright (C) 1993  Michael Beck 
 */

#include <linux/pcsp.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/config.h>
#include <linux/kernel.h>

#include "local.h"

extern struct file_operations pcspeaker_pcsp_fops;
#ifdef PCSP_MIXER
extern struct file_operations pcspeaker_pcsp_fops, pcsp_mixer_fops;
#else
extern struct file_operations pcspeaker_pcsp_fops;
#endif
extern long pcspeaker_init(long);
extern long pcsp_mixer_init(long);
extern char pcsp_to_ulaw;

static int pcsp_open_dev(struct inode * inode, struct file * file)
{ int minor = MINOR(inode->i_rdev);

	pcsp_to_ulaw = 0;
	switch (minor) {
                case PCSP_AUD_MINOR:
                        pcsp_to_ulaw = 1;	/* input is ULAW */
		case PCSP_DSP_MINOR:
	                file->f_op = &pcspeaker_pcsp_fops;
	                break;
#ifdef PCSP_MIXER
		case PCSP_MIXER_MINOR:
			file->f_op = &pcsp_mixer_fops;
			break;
#endif
		default:
			return -ENODEV;
	}
        return file->f_op->open(inode,file);
}

static struct file_operations pcsp_fops = {
        NULL,		/* seek */
	NULL,		/* read */
	NULL,		/* write */
	NULL,		/* readdir */
	NULL,		/* select */
	NULL,		/* ioctl */
	NULL,		/* mmap */
        pcsp_open_dev,
        NULL		/* release */
};

long pcsp_init(long kmem_start)
{
	if (register_chrdev(PCSP_MAJOR, "pcsp", &pcsp_fops))
		printk("unable to get major 30 for pcsp devices\n");
	else {
		printk("PCSP-device 0.4 init:\n");
#ifdef PCSP_MIXER
		kmem_start = pcsp_mixer_init(kmem_start);
		printk("  PCSP-Mixer installed\n");
#endif
		kmem_start = pcspeaker_init(kmem_start);
	}
	return kmem_start;
}
