/*
* sound/oss/pss.c
*
* The low level driver for the Personal Sound System (ECHO ESC614).
*
*
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*
*
* Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
* Alan Cox modularisation, clean up.
*
* 98-02-21: Vladimir Michl <vladimir.michl@upol.cz>
* Added mixer device for Beethoven ADSP-16 (master volume,
* bass, treble, synth), only for speakers.
* Fixed bug in pss_write (exchange parameters)
* Fixed config port of SB
* Requested two regions for PSS (PSS mixer, PSS config)
* Modified pss_download_boot
* To probe_pss_mss added test for initialize AD1848
* 98-05-28: Vladimir Michl <vladimir.michl@upol.cz>
* Fixed computation of mixer volumes
* 04-05-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
* Added code that allows the user to enable his cdrom and/or
* joystick through the module parameters pss_cdrom_port and
* pss_enable_joystick. pss_cdrom_port takes a port address as its
* argument. pss_enable_joystick takes either a 0 or a non-0 as its
* argument.
* 04-06-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
* Separated some code into new functions for easier reuse.
* Cleaned up and streamlined new code. Added code to allow a user
* to only use this driver for enabling non-sound components
* through the new module parameter pss_no_sound (flag). Added
* code that would allow a user to decide whether the driver should
* reset the configured hardware settings for the PSS board through
* the module parameter pss_keep_settings (flag). This flag will
* allow a user to free up resources in use by this card if needbe,
* furthermore it allows him to use this driver to just enable the
* emulations and then be unloaded as it is no longer needed. Both
* new settings are only available to this driver if compiled as a
* module. The default settings of all new parameters are set to
* load the driver as it did in previous versions.
* 04-07-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
* Added module parameter pss_firmware to allow the user to tell
* the driver where the fireware file is located. The default
* setting is the previous hardcoded setting "/etc/sound/pss_synth".
* 00-03-03: Christoph Hellwig <chhellwig@infradead.org>
* Adapted to module_init/module_exit
* 11-10-2000: Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
* Added __init to probe_pss(), attach_pss() and probe_pss_mpu()
* 02-Jan-2001: Chris Rankin
* Specify that this module owns the coprocessor
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include "sound_config.h"
#include "sound_firmware.h"
#include "ad1848.h"
#include "mpu401.h"
/*
* PSS registers.
*/
#define REG(x) (devc->base+x)
#define PSS_DATA 0
#define PSS_STATUS 2
#define PSS_CONTROL 2
#define PSS_ID 4
#define PSS_IRQACK 4
#define PSS_PIO 0x1a
/*
* Config registers
*/
#define CONF_PSS 0x10
#define CONF_WSS 0x12
#define CONF_SB 0x14
#define CONF_CDROM 0x16
#define CONF_MIDI 0x18
/*
* Status bits.
*/
#define PSS_FLAG3 0x0800
#define PSS_FLAG2 0x0400
#define PSS_FLAG1 0x1000
#define PSS_FLAG0 0x0800
#define PSS_WRITE_EMPTY 0x8000
#define PSS_READ_FULL 0x4000
/*
* WSS registers
*/
#define WSS_INDEX 4
#define WSS_DATA 5
/*
* WSS status bits
*/
#define WSS_INITIALIZING 0x80
#define WSS_AUTOCALIBRATION 0x20
#define NO_WSS_MIXER -1
#include "coproc.h"
#include "pss_boot.h"
/* If compiled into kernel, it enable or disable pss mixer */
#ifdef CONFIG_PSS_MIXER
static int pss_mixer = 1;
#else
static int pss_mixer;
#endif
typedef struct pss_mixerdata {
unsigned int volume_l;
unsigned int volume_r;
unsigned int bass;
unsigned int treble;
unsigned int synth;
} pss_mixerdata;
typedef struct pss_confdata {
int base;
int irq;
int dma;
int *osp;
pss_mixerdata mixer;
int ad_mixer_dev;
} pss_confdata;
static pss_confdata pss_data;
static pss_confdata *devc = &pss_data;
static DEFINE_SPINLOCK(lock);
static int pss_initialized;
static int nonstandard_microcode;
static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */
static int pss_enable_joystick; /* Parameter for enabling the joystick */
static coproc_operations pss_coproc_operations;
static void pss_write(pss_confdata *devc, int data)
{
unsigned long i, limit;
limit = jiffies + HZ/10; /* The timeout is 0.1 seconds */
/*
* Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
* called while interrupts are disabled. This means that the timer is
* disabled also. However the timeout situation is a abnormal condition.
* Normally the DSP should be ready to accept commands after just couple of
* loops.
*/