summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/sound/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/sound/drivers')
-rw-r--r--ANDROID_3.4.5/sound/drivers/Kconfig223
-rw-r--r--ANDROID_3.4.5/sound/drivers/Makefile25
-rw-r--r--ANDROID_3.4.5/sound/drivers/aloop.c1258
-rw-r--r--ANDROID_3.4.5/sound/drivers/dummy.c1157
-rw-r--r--ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c1344
-rw-r--r--ANDROID_3.4.5/sound/drivers/mpu401/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c288
-rw-r--r--ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c632
-rw-r--r--ANDROID_3.4.5/sound/drivers/mtpav.c792
-rw-r--r--ANDROID_3.4.5/sound/drivers/mts64.c1090
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c226
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c561
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c881
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c285
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c298
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c616
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h52
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c281
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h232
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c95
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c133
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c215
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c634
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/yrw801.c961
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcm-indirect2.c573
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcm-indirect2.h140
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/Makefile2
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c244
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h82
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c116
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h14
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c359
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c163
-rw-r--r--ANDROID_3.4.5/sound/drivers/portman2x4.c879
-rw-r--r--ANDROID_3.4.5/sound/drivers/serial-u16550.c1050
-rw-r--r--ANDROID_3.4.5/sound/drivers/virmidi.c197
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c109
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h246
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_core.c828
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c260
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c1028
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c1283
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_uer.c312
46 files changed, 0 insertions, 20206 deletions
diff --git a/ANDROID_3.4.5/sound/drivers/Kconfig b/ANDROID_3.4.5/sound/drivers/Kconfig
deleted file mode 100644
index fe5ae09f..00000000
--- a/ANDROID_3.4.5/sound/drivers/Kconfig
+++ /dev/null
@@ -1,223 +0,0 @@
-config SND_MPU401_UART
- tristate
- select SND_RAWMIDI
-
-config SND_OPL3_LIB
- tristate
- select SND_TIMER
- select SND_HWDEP
-
-config SND_OPL4_LIB
- tristate
- select SND_TIMER
- select SND_HWDEP
-
-config SND_VX_LIB
- tristate
- select SND_HWDEP
- select SND_PCM
-
-config SND_AC97_CODEC
- tristate
- select SND_PCM
- select AC97_BUS
- select SND_VMASTER
-
-menuconfig SND_DRIVERS
- bool "Generic sound devices"
- default y
- help
- Support for generic sound devices.
-
-if SND_DRIVERS
-
-config SND_PCSP
- tristate "PC-Speaker support (READ HELP!)"
- depends on PCSPKR_PLATFORM && X86 && HIGH_RES_TIMERS
- depends on INPUT
- depends on EXPERIMENTAL
- select SND_PCM
- help
- If you don't have a sound card in your computer, you can include a
- driver for the PC speaker which allows it to act like a primitive
- sound card.
- This driver also replaces the pcspkr driver for beeps.
-
- You can compile this as a module which will be called snd-pcsp.
-
- WARNING: if you already have a soundcard, enabling this
- driver may lead to a problem. Namely, it may get loaded
- before the other sound driver of yours, making the
- pc-speaker a default sound device. Which is likely not
- what you want. To make this driver play nicely with other
- sound driver, you can add this in a configuration file under
- /etc/modprobe.d/ directory:
- options snd-pcsp index=2
-
- You don't need this driver if you only want your pc-speaker to beep.
- You don't need this driver if you have a tablet piezo beeper
- in your PC instead of the real speaker.
-
- Say N if you have a sound card.
- Say M if you don't.
- Say Y only if you really know what you do.
-
-config SND_DUMMY
- tristate "Dummy (/dev/null) soundcard"
- select SND_PCM
- help
- Say Y here to include the dummy driver. This driver does
- nothing, but emulates various mixer controls and PCM devices.
-
- You don't need this unless you're testing the hardware support
- of programs using the ALSA API.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-dummy.
-
-config SND_ALOOP
- tristate "Generic loopback driver (PCM)"
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for the PCM loopback device.
- This module returns played samples back to the user space using
- the standard ALSA PCM device. The devices are routed 0->1 and
- 1->0, where first number is the playback PCM device and second
- number is the capture device. Module creates two PCM devices and
- configured number of substreams (see the pcm_substreams module
- parameter).
-
- The looback device allow time sychronization with an external
- timing source using the time shift universal control (+-20%
- of system time).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-aloop.
-
-config SND_VIRMIDI
- tristate "Virtual MIDI soundcard"
- depends on SND_SEQUENCER
- select SND_TIMER
- select SND_RAWMIDI
- help
- Say Y here to include the virtual MIDI driver. This driver
- allows to connect applications using raw MIDI devices to
- sequencer clients.
-
- If you don't know what MIDI is, say N here.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-virmidi.
-
-config SND_MTPAV
- tristate "MOTU MidiTimePiece AV multiport MIDI"
- select SND_RAWMIDI
- help
- To use a MOTU MidiTimePiece AV multiport MIDI adapter
- connected to the parallel port, say Y here and make sure that
- the standard parallel port driver isn't used for the port.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mtpav.
-
-config SND_MTS64
- tristate "ESI Miditerminal 4140 driver"
- depends on PARPORT
- select SND_RAWMIDI
- help
- The ESI Miditerminal 4140 is a 4 In 4 Out MIDI Interface with
- additional SMPTE Timecode capabilities for the parallel port.
-
- Say 'Y' to include support for this device.
-
- To compile this driver as a module, chose 'M' here: the module
- will be called snd-mts64.
-
-config SND_SERIAL_U16550
- tristate "UART16550 serial MIDI driver"
- select SND_RAWMIDI
- help
- To include support for MIDI serial port interfaces, say Y here
- and read <file:Documentation/sound/alsa/serial-u16550.txt>.
- This driver works with serial UARTs 16550 and better.
-
- This driver accesses the serial port hardware directly, so
- make sure that the standard serial driver isn't used or
- deactivated with setserial before loading this driver.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-serial-u16550.
-
-config SND_MPU401
- tristate "Generic MPU-401 UART driver"
- select SND_MPU401_UART
- help
- Say Y here to include support for MIDI ports compatible with
- the Roland MPU-401 interface in UART mode.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mpu401.
-
-config SND_PORTMAN2X4
- tristate "Portman 2x4 driver"
- depends on PARPORT
- select SND_RAWMIDI
- help
- Say Y here to include support for Midiman Portman 2x4 parallel
- port MIDI device.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-portman2x4.
-
-config SND_ML403_AC97CR
- tristate "Xilinx ML403 AC97 Controller Reference"
- depends on XILINX_VIRTEX
- select SND_AC97_CODEC
- help
- Say Y here to include support for the
- opb_ac97_controller_ref_v1_00_a ip core found in Xilinx's ML403
- reference design.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ml403_ac97cr.
-
-config SND_AC97_POWER_SAVE
- bool "AC97 Power-Saving Mode"
- depends on SND_AC97_CODEC
- default n
- help
- Say Y here to enable the aggressive power-saving support of
- AC97 codecs. In this mode, the power-mode is dynamically
- controlled at each open/close.
-
- The mode is activated by passing 'power_save=X' to the
- snd-ac97-codec driver module, where 'X' is the time-out
- value, a nonnegative integer that specifies how many
- seconds of idle time the driver must count before it may
- put the AC97 into power-save mode; a value of 0 (zero)
- disables the use of this power-save mode.
-
- After the snd-ac97-codec driver module has been loaded,
- the 'power_save' parameter can be set via sysfs as follows:
-
- echo 10 > /sys/module/snd_ac97_codec/parameters/power_save
-
- In this case, the time-out is set to 10 seconds; setting
- the time-out to 1 second (the minimum activation value)
- isn't recommended because many applications try to reopen
- the device frequently. A value of 10 seconds would be a
- good choice for normal operations.
-
- See Documentation/sound/alsa/powersave.txt for more details.
-
-config SND_AC97_POWER_SAVE_DEFAULT
- int "Default time-out for AC97 power-save mode"
- depends on SND_AC97_POWER_SAVE
- default 0
- help
- The default time-out value in seconds for AC97 automatic
- power-save mode. 0 means to disable the power-save mode.
-
- See SND_AC97_POWER_SAVE for more details.
-
-endif # SND_DRIVERS
diff --git a/ANDROID_3.4.5/sound/drivers/Makefile b/ANDROID_3.4.5/sound/drivers/Makefile
deleted file mode 100644
index 1a8440c8..00000000
--- a/ANDROID_3.4.5/sound/drivers/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-dummy-objs := dummy.o
-snd-aloop-objs := aloop.o
-snd-mtpav-objs := mtpav.o
-snd-mts64-objs := mts64.o
-snd-portman2x4-objs := portman2x4.o
-snd-serial-u16550-objs := serial-u16550.o
-snd-virmidi-objs := virmidi.o
-snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
-obj-$(CONFIG_SND_ALOOP) += snd-aloop.o
-obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o
-obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o
-obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
-obj-$(CONFIG_SND_MTS64) += snd-mts64.o
-obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
-obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403-ac97cr.o
-
-obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ pcsp/
diff --git a/ANDROID_3.4.5/sound/drivers/aloop.c b/ANDROID_3.4.5/sound/drivers/aloop.c
deleted file mode 100644
index ad079b63..00000000
--- a/ANDROID_3.4.5/sound/drivers/aloop.c
+++ /dev/null
@@ -1,1258 +0,0 @@
-/*
- * Loopback soundcard
- *
- * Original code:
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * More accurate positioning and full-duplex support:
- * Copyright (c) Ahmet İnan <ainan at mathematik.uni-freiburg.de>
- *
- * Major (almost complete) rewrite:
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * A next major update in 2010 (separate timers for playback and capture):
- * Copyright (c) Jaroslav Kysela <perex@perex.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 <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("A loopback soundcard");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}");
-
-#define MAX_PCM_SUBSTREAMS 8
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
-static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
-static int pcm_notify[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for loopback soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for loopback soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this loopback soundcard.");
-module_param_array(pcm_substreams, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
-module_param_array(pcm_notify, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
-
-#define NO_PITCH 100000
-
-struct loopback_pcm;
-
-struct loopback_cable {
- spinlock_t lock;
- struct loopback_pcm *streams[2];
- struct snd_pcm_hardware hw;
- /* flags */
- unsigned int valid;
- unsigned int running;
- unsigned int pause;
-};
-
-struct loopback_setup {
- unsigned int notify: 1;
- unsigned int rate_shift;
- unsigned int format;
- unsigned int rate;
- unsigned int channels;
- struct snd_ctl_elem_id active_id;
- struct snd_ctl_elem_id format_id;
- struct snd_ctl_elem_id rate_id;
- struct snd_ctl_elem_id channels_id;
-};
-
-struct loopback {
- struct snd_card *card;
- struct mutex cable_lock;
- struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2];
- struct snd_pcm *pcm[2];
- struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2];
-};
-
-struct loopback_pcm {
- struct loopback *loopback;
- struct snd_pcm_substream *substream;
- struct loopback_cable *cable;
- unsigned int pcm_buffer_size;
- unsigned int buf_pos; /* position in buffer */
- unsigned int silent_size;
- /* PCM parameters */
- unsigned int pcm_period_size;
- unsigned int pcm_bps; /* bytes per second */
- unsigned int pcm_salign; /* bytes per sample * channels */
- unsigned int pcm_rate_shift; /* rate shift value */
- /* flags */
- unsigned int period_update_pending :1;
- /* timer stuff */
- unsigned int irq_pos; /* fractional IRQ position */
- unsigned int period_size_frac;
- unsigned long last_jiffies;
- struct timer_list timer;
-};
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
-{
- if (dpcm->pcm_rate_shift == NO_PITCH) {
- x /= HZ;
- } else {
- x = div_u64(NO_PITCH * (unsigned long long)x,
- HZ * (unsigned long long)dpcm->pcm_rate_shift);
- }
- return x - (x % dpcm->pcm_salign);
-}
-
-static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
-{
- if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */
- return x * HZ;
- } else {
- x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ,
- NO_PITCH);
- }
- return x;
-}
-
-static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
-{
- int device = dpcm->substream->pstr->pcm->device;
-
- if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- device ^= 1;
- return &dpcm->loopback->setup[dpcm->substream->number][device];
-}
-
-static inline unsigned int get_notify(struct loopback_pcm *dpcm)
-{
- return get_setup(dpcm)->notify;
-}
-
-static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
-{
- return get_setup(dpcm)->rate_shift;
-}
-
-static void loopback_timer_start(struct loopback_pcm *dpcm)
-{
- unsigned long tick;
- unsigned int rate_shift = get_rate_shift(dpcm);
-
- if (rate_shift != dpcm->pcm_rate_shift) {
- dpcm->pcm_rate_shift = rate_shift;
- dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
- }
- if (dpcm->period_size_frac <= dpcm->irq_pos) {
- dpcm->irq_pos %= dpcm->period_size_frac;
- dpcm->period_update_pending = 1;
- }
- tick = dpcm->period_size_frac - dpcm->irq_pos;
- tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
- dpcm->timer.expires = jiffies + tick;
- add_timer(&dpcm->timer);
-}
-
-static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
-{
- del_timer(&dpcm->timer);
- dpcm->timer.expires = 0;
-}
-
-#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
-#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
-#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
-
-static int loopback_check_format(struct loopback_cable *cable, int stream)
-{
- struct snd_pcm_runtime *runtime, *cruntime;
- struct loopback_setup *setup;
- struct snd_card *card;
- int check;
-
- if (cable->valid != CABLE_VALID_BOTH) {
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- goto __notify;
- return 0;
- }
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream->runtime;
- check = runtime->format != cruntime->format ||
- runtime->rate != cruntime->rate ||
- runtime->channels != cruntime->channels;
- if (!check)
- return 0;
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
- return -EIO;
- } else {
- snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream, SNDRV_PCM_STATE_DRAINING);
- __notify:
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
- card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
- if (setup->format != runtime->format) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &setup->format_id);
- setup->format = runtime->format;
- }
- if (setup->rate != runtime->rate) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &setup->rate_id);
- setup->rate = runtime->rate;
- }
- if (setup->channels != runtime->channels) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &setup->channels_id);
- setup->channels = runtime->channels;
- }
- }
- return 0;
-}
-
-static void loopback_active_notify(struct loopback_pcm *dpcm)
-{
- snd_ctl_notify(dpcm->loopback->card,
- SNDRV_CTL_EVENT_MASK_VALUE,
- &get_setup(dpcm)->active_id);
-}
-
-static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
- int err, stream = 1 << substream->stream;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- err = loopback_check_format(cable, substream->stream);
- if (err < 0)
- return err;
- dpcm->last_jiffies = jiffies;
- dpcm->pcm_rate_shift = 0;
- spin_lock(&cable->lock);
- cable->running |= stream;
- cable->pause &= ~stream;
- spin_unlock(&cable->lock);
- loopback_timer_start(dpcm);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- loopback_active_notify(dpcm);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- spin_lock(&cable->lock);
- cable->running &= ~stream;
- cable->pause &= ~stream;
- spin_unlock(&cable->lock);
- loopback_timer_stop(dpcm);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- loopback_active_notify(dpcm);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock(&cable->lock);
- cable->pause |= stream;
- spin_unlock(&cable->lock);
- loopback_timer_stop(dpcm);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock(&cable->lock);
- dpcm->last_jiffies = jiffies;
- cable->pause &= ~stream;
- spin_unlock(&cable->lock);
- loopback_timer_start(dpcm);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static void params_change_substream(struct loopback_pcm *dpcm,
- struct snd_pcm_runtime *runtime)
-{
- struct snd_pcm_runtime *dst_runtime;
-
- if (dpcm == NULL || dpcm->substream == NULL)
- return;
- dst_runtime = dpcm->substream->runtime;
- if (dst_runtime == NULL)
- return;
- dst_runtime->hw = dpcm->cable->hw;
-}
-
-static void params_change(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
-
- cable->hw.formats = (1ULL << runtime->format);
- cable->hw.rate_min = runtime->rate;
- cable->hw.rate_max = runtime->rate;
- cable->hw.channels_min = runtime->channels;
- cable->hw.channels_max = runtime->channels;
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- runtime);
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- runtime);
-}
-
-static int loopback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
- int bps, salign;
-
- salign = (snd_pcm_format_width(runtime->format) *
- runtime->channels) / 8;
- bps = salign * runtime->rate;
- if (bps <= 0 || salign <= 0)
- return -EINVAL;
-
- dpcm->buf_pos = 0;
- dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- /* clear capture buffer */
- dpcm->silent_size = dpcm->pcm_buffer_size;
- snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
- runtime->buffer_size * runtime->channels);
- }
-
- dpcm->irq_pos = 0;
- dpcm->period_update_pending = 0;
- dpcm->pcm_bps = bps;
- dpcm->pcm_salign = salign;
- dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
-
- mutex_lock(&dpcm->loopback->cable_lock);
- if (!(cable->valid & ~(1 << substream->stream)) ||
- (get_setup(dpcm)->notify &&
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
- params_change(substream);
- cable->valid |= 1 << substream->stream;
- mutex_unlock(&dpcm->loopback->cable_lock);
-
- return 0;
-}
-
-static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
-{
- struct snd_pcm_runtime *runtime = dpcm->substream->runtime;
- char *dst = runtime->dma_area;
- unsigned int dst_off = dpcm->buf_pos;
-
- if (dpcm->silent_size >= dpcm->pcm_buffer_size)
- return;
- if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size)
- bytes = dpcm->pcm_buffer_size - dpcm->silent_size;
-
- for (;;) {
- unsigned int size = bytes;
- if (dst_off + size > dpcm->pcm_buffer_size)
- size = dpcm->pcm_buffer_size - dst_off;
- snd_pcm_format_set_silence(runtime->format, dst + dst_off,
- bytes_to_frames(runtime, size) *
- runtime->channels);
- dpcm->silent_size += size;
- bytes -= size;
- if (!bytes)
- break;
- dst_off = 0;
- }
-}
-
-static void copy_play_buf(struct loopback_pcm *play,
- struct loopback_pcm *capt,
- unsigned int bytes)
-{
- struct snd_pcm_runtime *runtime = play->substream->runtime;
- char *src = runtime->dma_area;
- char *dst = capt->substream->runtime->dma_area;
- unsigned int src_off = play->buf_pos;
- unsigned int dst_off = capt->buf_pos;
- unsigned int clear_bytes = 0;
-
- /* check if playback is draining, trim the capture copy size
- * when our pointer is at the end of playback ring buffer */
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
- snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) {
- snd_pcm_uframes_t appl_ptr, appl_ptr1, diff;
- appl_ptr = appl_ptr1 = runtime->control->appl_ptr;
- appl_ptr1 -= appl_ptr1 % runtime->buffer_size;
- appl_ptr1 += play->buf_pos / play->pcm_salign;
- if (appl_ptr < appl_ptr1)
- appl_ptr1 -= runtime->buffer_size;
- diff = (appl_ptr - appl_ptr1) * play->pcm_salign;
- if (diff < bytes) {
- clear_bytes = bytes - diff;
- bytes = diff;
- }
- }
-
- for (;;) {
- unsigned int size = bytes;
- if (src_off + size > play->pcm_buffer_size)
- size = play->pcm_buffer_size - src_off;
- if (dst_off + size > capt->pcm_buffer_size)
- size = capt->pcm_buffer_size - dst_off;
- memcpy(dst + dst_off, src + src_off, size);
- capt->silent_size = 0;
- bytes -= size;
- if (!bytes)
- break;
- src_off = (src_off + size) % play->pcm_buffer_size;
- dst_off = (dst_off + size) % capt->pcm_buffer_size;
- }
-
- if (clear_bytes > 0) {
- clear_capture_buf(capt, clear_bytes);
- capt->silent_size = 0;
- }
-}
-
-#define BYTEPOS_UPDATE_POSONLY 0
-#define BYTEPOS_UPDATE_CLEAR 1
-#define BYTEPOS_UPDATE_COPY 2
-
-static void loopback_bytepos_update(struct loopback_pcm *dpcm,
- unsigned int delta,
- unsigned int cmd)
-{
- unsigned int count;
- unsigned long last_pos;
-
- last_pos = byte_pos(dpcm, dpcm->irq_pos);
- dpcm->irq_pos += delta * dpcm->pcm_bps;
- count = byte_pos(dpcm, dpcm->irq_pos) - last_pos;
- if (!count)
- return;
- if (cmd == BYTEPOS_UPDATE_CLEAR)
- clear_capture_buf(dpcm, count);
- else if (cmd == BYTEPOS_UPDATE_COPY)
- copy_play_buf(dpcm->cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- dpcm->cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- count);
- dpcm->buf_pos += count;
- dpcm->buf_pos %= dpcm->pcm_buffer_size;
- if (dpcm->irq_pos >= dpcm->period_size_frac) {
- dpcm->irq_pos %= dpcm->period_size_frac;
- dpcm->period_update_pending = 1;
- }
-}
-
-static unsigned int loopback_pos_update(struct loopback_cable *cable)
-{
- struct loopback_pcm *dpcm_play =
- cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
- struct loopback_pcm *dpcm_capt =
- cable->streams[SNDRV_PCM_STREAM_CAPTURE];
- unsigned long delta_play = 0, delta_capt = 0;
- unsigned int running;
- unsigned long flags;
-
- spin_lock_irqsave(&cable->lock, flags);
- running = cable->running ^ cable->pause;
- if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
- delta_play = jiffies - dpcm_play->last_jiffies;
- dpcm_play->last_jiffies += delta_play;
- }
-
- if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
- delta_capt = jiffies - dpcm_capt->last_jiffies;
- dpcm_capt->last_jiffies += delta_capt;
- }
-
- if (delta_play == 0 && delta_capt == 0)
- goto unlock;
-
- if (delta_play > delta_capt) {
- loopback_bytepos_update(dpcm_play, delta_play - delta_capt,
- BYTEPOS_UPDATE_POSONLY);
- delta_play = delta_capt;
- } else if (delta_play < delta_capt) {
- loopback_bytepos_update(dpcm_capt, delta_capt - delta_play,
- BYTEPOS_UPDATE_CLEAR);
- delta_capt = delta_play;
- }
-
- if (delta_play == 0 && delta_capt == 0)
- goto unlock;
-
- /* note delta_capt == delta_play at this moment */
- loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY);
- loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY);
- unlock:
- spin_unlock_irqrestore(&cable->lock, flags);
- return running;
-}
-
-static void loopback_timer_function(unsigned long data)
-{
- struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
- unsigned int running;
-
- running = loopback_pos_update(dpcm->cable);
- if (running & (1 << dpcm->substream->stream)) {
- loopback_timer_start(dpcm);
- if (dpcm->period_update_pending) {
- dpcm->period_update_pending = 0;
- snd_pcm_period_elapsed(dpcm->substream);
- }
- }
-}
-
-static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
-
- loopback_pos_update(dpcm->cable);
- return bytes_to_frames(runtime, dpcm->buf_pos);
-}
-
-static struct snd_pcm_hardware loopback_pcm_hardware =
-{
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
- SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 32,
- .buffer_bytes_max = 2 * 1024 * 1024,
- .period_bytes_min = 64,
- /* note check overflow in frac_pos() using pcm_rate_shift before
- changing period_bytes_max value */
- .period_bytes_max = 1024 * 1024,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
-{
- struct loopback_pcm *dpcm = runtime->private_data;
- kfree(dpcm);
-}
-
-static int loopback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(params));
-}
-
-static int loopback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
-
- mutex_lock(&dpcm->loopback->cable_lock);
- cable->valid &= ~(1 << substream->stream);
- mutex_unlock(&dpcm->loopback->cable_lock);
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static unsigned int get_cable_index(struct snd_pcm_substream *substream)
-{
- if (!substream->pcm->device)
- return substream->stream;
- else
- return !substream->stream;
-}
-
-static int rule_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
-
- struct snd_pcm_hardware *hw = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
-
- maskp->bits[0] &= (u_int32_t)hw->formats;
- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
- if (! maskp->bits[0] && ! maskp->bits[1])
- return -EINVAL;
- return 0;
-}
-
-static int rule_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hardware *hw = rule->private;
- struct snd_interval t;
-
- t.min = hw->rate_min;
- t.max = hw->rate_max;
- t.openmin = t.openmax = 0;
- t.integer = 0;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int rule_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hardware *hw = rule->private;
- struct snd_interval t;
-
- t.min = hw->channels_min;
- t.max = hw->channels_max;
- t.openmin = t.openmax = 0;
- t.integer = 0;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int loopback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback *loopback = substream->private_data;
- struct loopback_pcm *dpcm;
- struct loopback_cable *cable;
- int err = 0;
- int dev = get_cable_index(substream);
-
- mutex_lock(&loopback->cable_lock);
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (!dpcm) {
- err = -ENOMEM;
- goto unlock;
- }
- dpcm->loopback = loopback;
- dpcm->substream = substream;
- setup_timer(&dpcm->timer, loopback_timer_function,
- (unsigned long)dpcm);
-
- cable = loopback->cables[substream->number][dev];
- if (!cable) {
- cable = kzalloc(sizeof(*cable), GFP_KERNEL);
- if (!cable) {
- kfree(dpcm);
- err = -ENOMEM;
- goto unlock;
- }
- spin_lock_init(&cable->lock);
- cable->hw = loopback_pcm_hardware;
- loopback->cables[substream->number][dev] = cable;
- }
- dpcm->cable = cable;
- cable->streams[substream->stream] = dpcm;
-
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
-
- /* use dynamic rules based on actual runtime->hw values */
- /* note that the default rules created in the PCM midlevel code */
- /* are cached -> they do not reflect the actual state */
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_FORMAT,
- rule_format, &runtime->hw,
- SNDRV_PCM_HW_PARAM_FORMAT, -1);
- if (err < 0)
- goto unlock;
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- rule_rate, &runtime->hw,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- goto unlock;
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- rule_channels, &runtime->hw,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- if (err < 0)
- goto unlock;
-
- runtime->private_data = dpcm;
- runtime->private_free = loopback_runtime_free;
- if (get_notify(dpcm))
- runtime->hw = loopback_pcm_hardware;
- else
- runtime->hw = cable->hw;
- unlock:
- mutex_unlock(&loopback->cable_lock);
- return err;
-}
-
-static int loopback_close(struct snd_pcm_substream *substream)
-{
- struct loopback *loopback = substream->private_data;
- struct loopback_pcm *dpcm = substream->runtime->private_data;
- struct loopback_cable *cable;
- int dev = get_cable_index(substream);
-
- loopback_timer_stop(dpcm);
- mutex_lock(&loopback->cable_lock);
- cable = loopback->cables[substream->number][dev];
- if (cable->streams[!substream->stream]) {
- /* other stream is still alive */
- cable->streams[substream->stream] = NULL;
- } else {
- /* free the cable */
- loopback->cables[substream->number][dev] = NULL;
- kfree(cable);
- }
- mutex_unlock(&loopback->cable_lock);
- return 0;
-}
-
-static struct snd_pcm_ops loopback_playback_ops = {
- .open = loopback_open,
- .close = loopback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = loopback_hw_params,
- .hw_free = loopback_hw_free,
- .prepare = loopback_prepare,
- .trigger = loopback_trigger,
- .pointer = loopback_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops loopback_capture_ops = {
- .open = loopback_open,
- .close = loopback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = loopback_hw_params,
- .hw_free = loopback_hw_free,
- .prepare = loopback_prepare,
- .trigger = loopback_trigger,
- .pointer = loopback_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static int __devinit loopback_pcm_new(struct loopback *loopback,
- int device, int substreams)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(loopback->card, "Loopback PCM", device,
- substreams, substreams, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops);
-
- pcm->private_data = loopback;
- pcm->info_flags = 0;
- strcpy(pcm->name, "Loopback PCM");
-
- loopback->pcm[device] = pcm;
- return 0;
-}
-
-static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 80000;
- uinfo->value.integer.max = 120000;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate_shift;
- return 0;
-}
-
-static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.integer.value[0];
- if (val < 80000)
- val = 80000;
- if (val > 120000)
- val = 120000;
- mutex_lock(&loopback->cable_lock);
- if (val != loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate_shift) {
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate_shift = val;
- change = 1;
- }
- mutex_unlock(&loopback->cable_lock);
- return change;
-}
-
-static int loopback_notify_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].notify;
- return 0;
-}
-
-static int loopback_notify_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.integer.value[0] ? 1 : 0;
- if (val != loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].notify) {
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].notify = val;
- change = 1;
- }
- return change;
-}
-
-static int loopback_active_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- struct loopback_cable *cable = loopback->cables
- [kcontrol->id.subdevice][kcontrol->id.device ^ 1];
- unsigned int val = 0;
-
- if (cable != NULL)
- val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
- 1 : 0;
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-static int loopback_format_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_format_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].format;
- return 0;
-}
-
-static int loopback_rate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 192000;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate;
- return 0;
-}
-
-static int loopback_channels_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 1;
- uinfo->value.integer.max = 1024;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_channels_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].channels;
- return 0;
-}
-
-static struct snd_kcontrol_new loopback_controls[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Rate Shift 100000",
- .info = loopback_rate_shift_info,
- .get = loopback_rate_shift_get,
- .put = loopback_rate_shift_put,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Notify",
- .info = snd_ctl_boolean_mono_info,
- .get = loopback_notify_get,
- .put = loopback_notify_put,
-},
-#define ACTIVE_IDX 2
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Active",
- .info = snd_ctl_boolean_mono_info,
- .get = loopback_active_get,
-},
-#define FORMAT_IDX 3
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Format",
- .info = loopback_format_info,
- .get = loopback_format_get
-},
-#define RATE_IDX 4
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Rate",
- .info = loopback_rate_info,
- .get = loopback_rate_get
-},
-#define CHANNELS_IDX 5
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Channels",
- .info = loopback_channels_info,
- .get = loopback_channels_get
-}
-};
-
-static int __devinit loopback_mixer_new(struct loopback *loopback, int notify)
-{
- struct snd_card *card = loopback->card;
- struct snd_pcm *pcm;
- struct snd_kcontrol *kctl;
- struct loopback_setup *setup;
- int err, dev, substr, substr_count, idx;
-
- strcpy(card->mixername, "Loopback Mixer");
- for (dev = 0; dev < 2; dev++) {
- pcm = loopback->pcm[dev];
- substr_count =
- pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
- for (substr = 0; substr < substr_count; substr++) {
- setup = &loopback->setup[substr][dev];
- setup->notify = notify;
- setup->rate_shift = NO_PITCH;
- setup->format = SNDRV_PCM_FORMAT_S16_LE;
- setup->rate = 48000;
- setup->channels = 2;
- for (idx = 0; idx < ARRAY_SIZE(loopback_controls);
- idx++) {
- kctl = snd_ctl_new1(&loopback_controls[idx],
- loopback);
- if (!kctl)
- return -ENOMEM;
- kctl->id.device = dev;
- kctl->id.subdevice = substr;
- switch (idx) {
- case ACTIVE_IDX:
- setup->active_id = kctl->id;
- break;
- case FORMAT_IDX:
- setup->format_id = kctl->id;
- break;
- case RATE_IDX:
- setup->rate_id = kctl->id;
- break;
- case CHANNELS_IDX:
- setup->channels_id = kctl->id;
- break;
- default:
- break;
- }
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- }
- }
- }
- return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void print_dpcm_info(struct snd_info_buffer *buffer,
- struct loopback_pcm *dpcm,
- const char *id)
-{
- snd_iprintf(buffer, " %s\n", id);
- if (dpcm == NULL) {
- snd_iprintf(buffer, " inactive\n");
- return;
- }
- snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size);
- snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos);
- snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size);
- snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size);
- snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps);
- snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign);
- snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift);
- snd_iprintf(buffer, " update_pending:\t%u\n",
- dpcm->period_update_pending);
- snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos);
- snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac);
- snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n",
- dpcm->last_jiffies, jiffies);
- snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires);
-}
-
-static void print_substream_info(struct snd_info_buffer *buffer,
- struct loopback *loopback,
- int sub,
- int num)
-{
- struct loopback_cable *cable = loopback->cables[sub][num];
-
- snd_iprintf(buffer, "Cable %i substream %i:\n", num, sub);
- if (cable == NULL) {
- snd_iprintf(buffer, " inactive\n");
- return;
- }
- snd_iprintf(buffer, " valid: %u\n", cable->valid);
- snd_iprintf(buffer, " running: %u\n", cable->running);
- snd_iprintf(buffer, " pause: %u\n", cable->pause);
- print_dpcm_info(buffer, cable->streams[0], "Playback");
- print_dpcm_info(buffer, cable->streams[1], "Capture");
-}
-
-static void print_cable_info(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct loopback *loopback = entry->private_data;
- int sub, num;
-
- mutex_lock(&loopback->cable_lock);
- num = entry->name[strlen(entry->name)-1];
- num = num == '0' ? 0 : 1;
- for (sub = 0; sub < MAX_PCM_SUBSTREAMS; sub++)
- print_substream_info(buffer, loopback, sub, num);
- mutex_unlock(&loopback->cable_lock);
-}
-
-static int __devinit loopback_proc_new(struct loopback *loopback, int cidx)
-{
- char name[32];
- struct snd_info_entry *entry;
- int err;
-
- snprintf(name, sizeof(name), "cable#%d", cidx);
- err = snd_card_proc_new(loopback->card, name, &entry);
- if (err < 0)
- return err;
-
- snd_info_set_text_ops(entry, loopback, print_cable_info);
- return 0;
-}
-
-#else /* !CONFIG_PROC_FS */
-
-#define loopback_proc_new(loopback, cidx) do { } while (0)
-
-#endif
-
-static int __devinit loopback_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct loopback *loopback;
- int dev = devptr->id;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct loopback), &card);
- if (err < 0)
- return err;
- loopback = card->private_data;
-
- if (pcm_substreams[dev] < 1)
- pcm_substreams[dev] = 1;
- if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
- pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
-
- loopback->card = card;
- mutex_init(&loopback->cable_lock);
-
- err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
- if (err < 0)
- goto __nodev;
- err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
- if (err < 0)
- goto __nodev;
- err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
- if (err < 0)
- goto __nodev;
- loopback_proc_new(loopback, 0);
- loopback_proc_new(loopback, 1);
- strcpy(card->driver, "Loopback");
- strcpy(card->shortname, "Loopback");
- sprintf(card->longname, "Loopback %i", dev + 1);
- err = snd_card_register(card);
- if (!err) {
- platform_set_drvdata(devptr, card);
- return 0;
- }
- __nodev:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit loopback_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int loopback_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct loopback *loopback = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(loopback->pcm[0]);
- snd_pcm_suspend_all(loopback->pcm[1]);
- return 0;
-}
-
-static int loopback_resume(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-#define SND_LOOPBACK_DRIVER "snd_aloop"
-
-static struct platform_driver loopback_driver = {
- .probe = loopback_probe,
- .remove = __devexit_p(loopback_remove),
-#ifdef CONFIG_PM
- .suspend = loopback_suspend,
- .resume = loopback_resume,
-#endif
- .driver = {
- .name = SND_LOOPBACK_DRIVER
- },
-};
-
-static void loopback_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&loopback_driver);
-}
-
-static int __init alsa_card_loopback_init(void)
-{
- int i, err, cards;
-
- err = platform_driver_register(&loopback_driver);
- if (err < 0)
- return err;
-
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (!enable[i])
- continue;
- device = platform_device_register_simple(SND_LOOPBACK_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "aloop: No loopback enabled\n");
-#endif
- loopback_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_loopback_exit(void)
-{
- loopback_unregister_all();
-}
-
-module_init(alsa_card_loopback_init)
-module_exit(alsa_card_loopback_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/dummy.c b/ANDROID_3.4.5/sound/drivers/dummy.c
deleted file mode 100644
index ad9434fd..00000000
--- a/ANDROID_3.4.5/sound/drivers/dummy.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- * Dummy soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.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 <linux/init.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/hrtimer.h>
-#include <linux/math64.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Dummy soundcard (/dev/null)");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
-
-#define MAX_PCM_DEVICES 4
-#define MAX_PCM_SUBSTREAMS 128
-#define MAX_MIDI_DEVICES 2
-
-/* defaults */
-#define MAX_BUFFER_SIZE (64*1024)
-#define MIN_PERIOD_SIZE 64
-#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
-#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
-#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
-#define USE_RATE_MIN 5500
-#define USE_RATE_MAX 48000
-#define USE_CHANNELS_MIN 1
-#define USE_CHANNELS_MAX 2
-#define USE_PERIODS_MIN 1
-#define USE_PERIODS_MAX 1024
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
-static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
-static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
-//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-#ifdef CONFIG_HIGH_RES_TIMERS
-static bool hrtimer = 1;
-#endif
-static bool fake_buffer = 1;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
-module_param_array(model, charp, NULL, 0444);
-MODULE_PARM_DESC(model, "Soundcard model.");
-module_param_array(pcm_devs, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
-module_param_array(pcm_substreams, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
-//module_param_array(midi_devs, int, NULL, 0444);
-//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
-module_param(fake_buffer, bool, 0444);
-MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
-#ifdef CONFIG_HIGH_RES_TIMERS
-module_param(hrtimer, bool, 0644);
-MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
-#endif
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-#define MIXER_ADDR_MASTER 0
-#define MIXER_ADDR_LINE 1
-#define MIXER_ADDR_MIC 2
-#define MIXER_ADDR_SYNTH 3
-#define MIXER_ADDR_CD 4
-#define MIXER_ADDR_LAST 4
-
-struct dummy_timer_ops {
- int (*create)(struct snd_pcm_substream *);
- void (*free)(struct snd_pcm_substream *);
- int (*prepare)(struct snd_pcm_substream *);
- int (*start)(struct snd_pcm_substream *);
- int (*stop)(struct snd_pcm_substream *);
- snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
-};
-
-struct dummy_model {
- const char *name;
- int (*playback_constraints)(struct snd_pcm_runtime *runtime);
- int (*capture_constraints)(struct snd_pcm_runtime *runtime);
- u64 formats;
- size_t buffer_bytes_max;
- size_t period_bytes_min;
- size_t period_bytes_max;
- unsigned int periods_min;
- unsigned int periods_max;
- unsigned int rates;
- unsigned int rate_min;
- unsigned int rate_max;
- unsigned int channels_min;
- unsigned int channels_max;
-};
-
-struct snd_dummy {
- struct snd_card *card;
- struct dummy_model *model;
- struct snd_pcm *pcm;
- struct snd_pcm_hardware pcm_hw;
- spinlock_t mixer_lock;
- int mixer_volume[MIXER_ADDR_LAST+1][2];
- int capture_source[MIXER_ADDR_LAST+1][2];
- const struct dummy_timer_ops *timer_ops;
-};
-
-/*
- * card models
- */
-
-static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
-{
- int err;
- err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- return err;
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
- if (err < 0)
- return err;
- return 0;
-}
-
-struct dummy_model model_emu10k1 = {
- .name = "emu10k1",
- .playback_constraints = emu10k1_playback_constraints,
- .buffer_bytes_max = 128 * 1024,
-};
-
-struct dummy_model model_rme9652 = {
- .name = "rme9652",
- .buffer_bytes_max = 26 * 64 * 1024,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .channels_min = 26,
- .channels_max = 26,
- .periods_min = 2,
- .periods_max = 2,
-};
-
-struct dummy_model model_ice1712 = {
- .name = "ice1712",
- .buffer_bytes_max = 256 * 1024,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .channels_min = 10,
- .channels_max = 10,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-struct dummy_model model_uda1341 = {
- .name = "uda1341",
- .buffer_bytes_max = 16380,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 2,
- .channels_max = 2,
- .periods_min = 2,
- .periods_max = 255,
-};
-
-struct dummy_model model_ac97 = {
- .name = "ac97",
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
-};
-
-struct dummy_model model_ca0106 = {
- .name = "ca0106",
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .buffer_bytes_max = ((65536-64)*8),
- .period_bytes_max = (65536-64),
- .periods_min = 2,
- .periods_max = 8,
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000,
- .rate_min = 48000,
- .rate_max = 192000,
-};
-
-struct dummy_model *dummy_models[] = {
- &model_emu10k1,
- &model_rme9652,
- &model_ice1712,
- &model_uda1341,
- &model_ac97,
- &model_ca0106,
- NULL
-};
-
-/*
- * system timer interface
- */
-
-struct dummy_systimer_pcm {
- spinlock_t lock;
- struct timer_list timer;
- unsigned long base_time;
- unsigned int frac_pos; /* fractional sample position (based HZ) */
- unsigned int frac_period_rest;
- unsigned int frac_buffer_size; /* buffer_size * HZ */
- unsigned int frac_period_size; /* period_size * HZ */
- unsigned int rate;
- int elapsed;
- struct snd_pcm_substream *substream;
-};
-
-static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
-{
- dpcm->timer.expires = jiffies +
- (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate;
- add_timer(&dpcm->timer);
-}
-
-static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
-{
- unsigned long delta;
-
- delta = jiffies - dpcm->base_time;
- if (!delta)
- return;
- dpcm->base_time += delta;
- delta *= dpcm->rate;
- dpcm->frac_pos += delta;
- while (dpcm->frac_pos >= dpcm->frac_buffer_size)
- dpcm->frac_pos -= dpcm->frac_buffer_size;
- while (dpcm->frac_period_rest <= delta) {
- dpcm->elapsed++;
- dpcm->frac_period_rest += dpcm->frac_period_size;
- }
- dpcm->frac_period_rest -= delta;
-}
-
-static int dummy_systimer_start(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- spin_lock(&dpcm->lock);
- dpcm->base_time = jiffies;
- dummy_systimer_rearm(dpcm);
- spin_unlock(&dpcm->lock);
- return 0;
-}
-
-static int dummy_systimer_stop(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- spin_lock(&dpcm->lock);
- del_timer(&dpcm->timer);
- spin_unlock(&dpcm->lock);
- return 0;
-}
-
-static int dummy_systimer_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct dummy_systimer_pcm *dpcm = runtime->private_data;
-
- dpcm->frac_pos = 0;
- dpcm->rate = runtime->rate;
- dpcm->frac_buffer_size = runtime->buffer_size * HZ;
- dpcm->frac_period_size = runtime->period_size * HZ;
- dpcm->frac_period_rest = dpcm->frac_period_size;
- dpcm->elapsed = 0;
-
- return 0;
-}
-
-static void dummy_systimer_callback(unsigned long data)
-{
- struct dummy_systimer_pcm *dpcm = (struct dummy_systimer_pcm *)data;
- unsigned long flags;
- int elapsed = 0;
-
- spin_lock_irqsave(&dpcm->lock, flags);
- dummy_systimer_update(dpcm);
- dummy_systimer_rearm(dpcm);
- elapsed = dpcm->elapsed;
- dpcm->elapsed = 0;
- spin_unlock_irqrestore(&dpcm->lock, flags);
- if (elapsed)
- snd_pcm_period_elapsed(dpcm->substream);
-}
-
-static snd_pcm_uframes_t
-dummy_systimer_pointer(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- snd_pcm_uframes_t pos;
-
- spin_lock(&dpcm->lock);
- dummy_systimer_update(dpcm);
- pos = dpcm->frac_pos / HZ;
- spin_unlock(&dpcm->lock);
- return pos;
-}
-
-static int dummy_systimer_create(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm;
-
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (!dpcm)
- return -ENOMEM;
- substream->runtime->private_data = dpcm;
- init_timer(&dpcm->timer);
- dpcm->timer.data = (unsigned long) dpcm;
- dpcm->timer.function = dummy_systimer_callback;
- spin_lock_init(&dpcm->lock);
- dpcm->substream = substream;
- return 0;
-}
-
-static void dummy_systimer_free(struct snd_pcm_substream *substream)
-{
- kfree(substream->runtime->private_data);
-}
-
-static struct dummy_timer_ops dummy_systimer_ops = {
- .create = dummy_systimer_create,
- .free = dummy_systimer_free,
- .prepare = dummy_systimer_prepare,
- .start = dummy_systimer_start,
- .stop = dummy_systimer_stop,
- .pointer = dummy_systimer_pointer,
-};
-
-#ifdef CONFIG_HIGH_RES_TIMERS
-/*
- * hrtimer interface
- */
-
-struct dummy_hrtimer_pcm {
- ktime_t base_time;
- ktime_t period_time;
- atomic_t running;
- struct hrtimer timer;
- struct tasklet_struct tasklet;
- struct snd_pcm_substream *substream;
-};
-
-static void dummy_hrtimer_pcm_elapsed(unsigned long priv)
-{
- struct dummy_hrtimer_pcm *dpcm = (struct dummy_hrtimer_pcm *)priv;
- if (atomic_read(&dpcm->running))
- snd_pcm_period_elapsed(dpcm->substream);
-}
-
-static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer)
-{
- struct dummy_hrtimer_pcm *dpcm;
-
- dpcm = container_of(timer, struct dummy_hrtimer_pcm, timer);
- if (!atomic_read(&dpcm->running))
- return HRTIMER_NORESTART;
- tasklet_schedule(&dpcm->tasklet);
- hrtimer_forward_now(timer, dpcm->period_time);
- return HRTIMER_RESTART;
-}
-
-static int dummy_hrtimer_start(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
-
- dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer);
- hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL);
- atomic_set(&dpcm->running, 1);
- return 0;
-}
-
-static int dummy_hrtimer_stop(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
-
- atomic_set(&dpcm->running, 0);
- hrtimer_cancel(&dpcm->timer);
- return 0;
-}
-
-static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
-{
- tasklet_kill(&dpcm->tasklet);
-}
-
-static snd_pcm_uframes_t
-dummy_hrtimer_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
- u64 delta;
- u32 pos;
-
- delta = ktime_us_delta(hrtimer_cb_get_time(&dpcm->timer),
- dpcm->base_time);
- delta = div_u64(delta * runtime->rate + 999999, 1000000);
- div_u64_rem(delta, runtime->buffer_size, &pos);
- return pos;
-}
-
-static int dummy_hrtimer_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
- unsigned int period, rate;
- long sec;
- unsigned long nsecs;
-
- dummy_hrtimer_sync(dpcm);
- period = runtime->period_size;
- rate = runtime->rate;
- sec = period / rate;
- period %= rate;
- nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate);
- dpcm->period_time = ktime_set(sec, nsecs);
-
- return 0;
-}
-
-static int dummy_hrtimer_create(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm;
-
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (!dpcm)
- return -ENOMEM;
- substream->runtime->private_data = dpcm;
- hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- dpcm->timer.function = dummy_hrtimer_callback;
- dpcm->substream = substream;
- atomic_set(&dpcm->running, 0);
- tasklet_init(&dpcm->tasklet, dummy_hrtimer_pcm_elapsed,
- (unsigned long)dpcm);
- return 0;
-}
-
-static void dummy_hrtimer_free(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
- dummy_hrtimer_sync(dpcm);
- kfree(dpcm);
-}
-
-static struct dummy_timer_ops dummy_hrtimer_ops = {
- .create = dummy_hrtimer_create,
- .free = dummy_hrtimer_free,
- .prepare = dummy_hrtimer_prepare,
- .start = dummy_hrtimer_start,
- .stop = dummy_hrtimer_stop,
- .pointer = dummy_hrtimer_pointer,
-};
-
-#endif /* CONFIG_HIGH_RES_TIMERS */
-
-/*
- * PCM interface
- */
-
-static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- return dummy->timer_ops->start(substream);
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- return dummy->timer_ops->stop(substream);
- }
- return -EINVAL;
-}
-
-static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
- return dummy->timer_ops->prepare(substream);
-}
-
-static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
- return dummy->timer_ops->pointer(substream);
-}
-
-static struct snd_pcm_hardware dummy_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = USE_FORMATS,
- .rates = USE_RATE,
- .rate_min = USE_RATE_MIN,
- .rate_max = USE_RATE_MAX,
- .channels_min = USE_CHANNELS_MIN,
- .channels_max = USE_CHANNELS_MAX,
- .buffer_bytes_max = MAX_BUFFER_SIZE,
- .period_bytes_min = MIN_PERIOD_SIZE,
- .period_bytes_max = MAX_PERIOD_SIZE,
- .periods_min = USE_PERIODS_MIN,
- .periods_max = USE_PERIODS_MAX,
- .fifo_size = 0,
-};
-
-static int dummy_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- if (fake_buffer) {
- /* runtime->dma_bytes has to be set manually to allow mmap */
- substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
- return 0;
- }
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int dummy_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- if (fake_buffer)
- return 0;
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int dummy_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
- struct dummy_model *model = dummy->model;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- dummy->timer_ops = &dummy_systimer_ops;
-#ifdef CONFIG_HIGH_RES_TIMERS
- if (hrtimer)
- dummy->timer_ops = &dummy_hrtimer_ops;
-#endif
-
- err = dummy->timer_ops->create(substream);
- if (err < 0)
- return err;
-
- runtime->hw = dummy->pcm_hw;
- if (substream->pcm->device & 1) {
- runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
- runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
- }
- if (substream->pcm->device & 2)
- runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID);
-
- if (model == NULL)
- return 0;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (model->playback_constraints)
- err = model->playback_constraints(substream->runtime);
- } else {
- if (model->capture_constraints)
- err = model->capture_constraints(substream->runtime);
- }
- if (err < 0) {
- dummy->timer_ops->free(substream);
- return err;
- }
- return 0;
-}
-
-static int dummy_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
- dummy->timer_ops->free(substream);
- return 0;
-}
-
-/*
- * dummy buffer handling
- */
-
-static void *dummy_page[2];
-
-static void free_fake_buffer(void)
-{
- if (fake_buffer) {
- int i;
- for (i = 0; i < 2; i++)
- if (dummy_page[i]) {
- free_page((unsigned long)dummy_page[i]);
- dummy_page[i] = NULL;
- }
- }
-}
-
-static int alloc_fake_buffer(void)
-{
- int i;
-
- if (!fake_buffer)
- return 0;
- for (i = 0; i < 2; i++) {
- dummy_page[i] = (void *)get_zeroed_page(GFP_KERNEL);
- if (!dummy_page[i]) {
- free_fake_buffer();
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-static int dummy_pcm_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t pos,
- void __user *dst, snd_pcm_uframes_t count)
-{
- return 0; /* do nothing */
-}
-
-static int dummy_pcm_silence(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- return 0; /* do nothing */
-}
-
-static struct page *dummy_pcm_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- return virt_to_page(dummy_page[substream->stream]); /* the same page */
-}
-
-static struct snd_pcm_ops dummy_pcm_ops = {
- .open = dummy_pcm_open,
- .close = dummy_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = dummy_pcm_hw_params,
- .hw_free = dummy_pcm_hw_free,
- .prepare = dummy_pcm_prepare,
- .trigger = dummy_pcm_trigger,
- .pointer = dummy_pcm_pointer,
-};
-
-static struct snd_pcm_ops dummy_pcm_ops_no_buf = {
- .open = dummy_pcm_open,
- .close = dummy_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = dummy_pcm_hw_params,
- .hw_free = dummy_pcm_hw_free,
- .prepare = dummy_pcm_prepare,
- .trigger = dummy_pcm_trigger,
- .pointer = dummy_pcm_pointer,
- .copy = dummy_pcm_copy,
- .silence = dummy_pcm_silence,
- .page = dummy_pcm_page,
-};
-
-static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
- int substreams)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_ops *ops;
- int err;
-
- err = snd_pcm_new(dummy->card, "Dummy PCM", device,
- substreams, substreams, &pcm);
- if (err < 0)
- return err;
- dummy->pcm = pcm;
- if (fake_buffer)
- ops = &dummy_pcm_ops_no_buf;
- else
- ops = &dummy_pcm_ops;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ops);
- pcm->private_data = dummy;
- pcm->info_flags = 0;
- strcpy(pcm->name, "Dummy PCM");
- if (!fake_buffer) {
- snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 0, 64*1024);
- }
- return 0;
-}
-
-/*
- * mixer interface
- */
-
-#define DUMMY_VOLUME(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .index = xindex, \
- .info = snd_dummy_volume_info, \
- .get = snd_dummy_volume_get, .put = snd_dummy_volume_put, \
- .private_value = addr, \
- .tlv = { .p = db_scale_dummy } }
-
-static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = -50;
- uinfo->value.integer.max = 100;
- return 0;
-}
-
-static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int addr = kcontrol->private_value;
-
- spin_lock_irq(&dummy->mixer_lock);
- ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0];
- ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1];
- spin_unlock_irq(&dummy->mixer_lock);
- return 0;
-}
-
-static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int change, addr = kcontrol->private_value;
- int left, right;
-
- left = ucontrol->value.integer.value[0];
- if (left < -50)
- left = -50;
- if (left > 100)
- left = 100;
- right = ucontrol->value.integer.value[1];
- if (right < -50)
- right = -50;
- if (right > 100)
- right = 100;
- spin_lock_irq(&dummy->mixer_lock);
- change = dummy->mixer_volume[addr][0] != left ||
- dummy->mixer_volume[addr][1] != right;
- dummy->mixer_volume[addr][0] = left;
- dummy->mixer_volume[addr][1] = right;
- spin_unlock_irq(&dummy->mixer_lock);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
-
-#define DUMMY_CAPSRC(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_dummy_capsrc_info, \
- .get = snd_dummy_capsrc_get, .put = snd_dummy_capsrc_put, \
- .private_value = addr }
-
-#define snd_dummy_capsrc_info snd_ctl_boolean_stereo_info
-
-static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int addr = kcontrol->private_value;
-
- spin_lock_irq(&dummy->mixer_lock);
- ucontrol->value.integer.value[0] = dummy->capture_source[addr][0];
- ucontrol->value.integer.value[1] = dummy->capture_source[addr][1];
- spin_unlock_irq(&dummy->mixer_lock);
- return 0;
-}
-
-static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int change, addr = kcontrol->private_value;
- int left, right;
-
- left = ucontrol->value.integer.value[0] & 1;
- right = ucontrol->value.integer.value[1] & 1;
- spin_lock_irq(&dummy->mixer_lock);
- change = dummy->capture_source[addr][0] != left &&
- dummy->capture_source[addr][1] != right;
- dummy->capture_source[addr][0] = left;
- dummy->capture_source[addr][1] = right;
- spin_unlock_irq(&dummy->mixer_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_dummy_controls[] = {
-DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
-DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
-DUMMY_VOLUME("Synth Volume", 0, MIXER_ADDR_SYNTH),
-DUMMY_CAPSRC("Synth Capture Switch", 0, MIXER_ADDR_SYNTH),
-DUMMY_VOLUME("Line Volume", 0, MIXER_ADDR_LINE),
-DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE),
-DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
-DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
-DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
-DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
-};
-
-static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
-{
- struct snd_card *card = dummy->card;
- unsigned int idx;
- int err;
-
- spin_lock_init(&dummy->mixer_lock);
- strcpy(card->mixername, "Dummy Mixer");
-
- for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_PROC_FS)
-/*
- * proc interface
- */
-static void print_formats(struct snd_dummy *dummy,
- struct snd_info_buffer *buffer)
-{
- int i;
-
- for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
- if (dummy->pcm_hw.formats & (1ULL << i))
- snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
- }
-}
-
-static void print_rates(struct snd_dummy *dummy,
- struct snd_info_buffer *buffer)
-{
- static int rates[] = {
- 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
- 64000, 88200, 96000, 176400, 192000,
- };
- int i;
-
- if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
- snd_iprintf(buffer, " continuous");
- if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT)
- snd_iprintf(buffer, " knot");
- for (i = 0; i < ARRAY_SIZE(rates); i++)
- if (dummy->pcm_hw.rates & (1 << i))
- snd_iprintf(buffer, " %d", rates[i]);
-}
-
-#define get_dummy_int_ptr(dummy, ofs) \
- (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
-#define get_dummy_ll_ptr(dummy, ofs) \
- (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
-
-struct dummy_hw_field {
- const char *name;
- const char *format;
- unsigned int offset;
- unsigned int size;
-};
-#define FIELD_ENTRY(item, fmt) { \
- .name = #item, \
- .format = fmt, \
- .offset = offsetof(struct snd_pcm_hardware, item), \
- .size = sizeof(dummy_pcm_hardware.item) }
-
-static struct dummy_hw_field fields[] = {
- FIELD_ENTRY(formats, "%#llx"),
- FIELD_ENTRY(rates, "%#x"),
- FIELD_ENTRY(rate_min, "%d"),
- FIELD_ENTRY(rate_max, "%d"),
- FIELD_ENTRY(channels_min, "%d"),
- FIELD_ENTRY(channels_max, "%d"),
- FIELD_ENTRY(buffer_bytes_max, "%ld"),
- FIELD_ENTRY(period_bytes_min, "%ld"),
- FIELD_ENTRY(period_bytes_max, "%ld"),
- FIELD_ENTRY(periods_min, "%d"),
- FIELD_ENTRY(periods_max, "%d"),
-};
-
-static void dummy_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_dummy *dummy = entry->private_data;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fields); i++) {
- snd_iprintf(buffer, "%s ", fields[i].name);
- if (fields[i].size == sizeof(int))
- snd_iprintf(buffer, fields[i].format,
- *get_dummy_int_ptr(dummy, fields[i].offset));
- else
- snd_iprintf(buffer, fields[i].format,
- *get_dummy_ll_ptr(dummy, fields[i].offset));
- if (!strcmp(fields[i].name, "formats"))
- print_formats(dummy, buffer);
- else if (!strcmp(fields[i].name, "rates"))
- print_rates(dummy, buffer);
- snd_iprintf(buffer, "\n");
- }
-}
-
-static void dummy_proc_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_dummy *dummy = entry->private_data;
- char line[64];
-
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- char item[20];
- const char *ptr;
- unsigned long long val;
- int i;
-
- ptr = snd_info_get_str(item, line, sizeof(item));
- for (i = 0; i < ARRAY_SIZE(fields); i++) {
- if (!strcmp(item, fields[i].name))
- break;
- }
- if (i >= ARRAY_SIZE(fields))
- continue;
- snd_info_get_str(item, ptr, sizeof(item));
- if (strict_strtoull(item, 0, &val))
- continue;
- if (fields[i].size == sizeof(int))
- *get_dummy_int_ptr(dummy, fields[i].offset) = val;
- else
- *get_dummy_ll_ptr(dummy, fields[i].offset) = val;
- }
-}
-
-static void __devinit dummy_proc_init(struct snd_dummy *chip)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(chip->card, "dummy_pcm", &entry)) {
- snd_info_set_text_ops(entry, chip, dummy_proc_read);
- entry->c.text.write = dummy_proc_write;
- entry->mode |= S_IWUSR;
- entry->private_data = chip;
- }
-}
-#else
-#define dummy_proc_init(x)
-#endif /* CONFIG_SND_DEBUG && CONFIG_PROC_FS */
-
-static int __devinit snd_dummy_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct snd_dummy *dummy;
- struct dummy_model *m = NULL, **mdl;
- int idx, err;
- int dev = devptr->id;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_dummy), &card);
- if (err < 0)
- return err;
- dummy = card->private_data;
- dummy->card = card;
- for (mdl = dummy_models; *mdl && model[dev]; mdl++) {
- if (strcmp(model[dev], (*mdl)->name) == 0) {
- printk(KERN_INFO
- "snd-dummy: Using model '%s' for card %i\n",
- (*mdl)->name, card->number);
- m = dummy->model = *mdl;
- break;
- }
- }
- for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
- if (pcm_substreams[dev] < 1)
- pcm_substreams[dev] = 1;
- if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
- pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
- err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]);
- if (err < 0)
- goto __nodev;
- }
-
- dummy->pcm_hw = dummy_pcm_hardware;
- if (m) {
- if (m->formats)
- dummy->pcm_hw.formats = m->formats;
- if (m->buffer_bytes_max)
- dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max;
- if (m->period_bytes_min)
- dummy->pcm_hw.period_bytes_min = m->period_bytes_min;
- if (m->period_bytes_max)
- dummy->pcm_hw.period_bytes_max = m->period_bytes_max;
- if (m->periods_min)
- dummy->pcm_hw.periods_min = m->periods_min;
- if (m->periods_max)
- dummy->pcm_hw.periods_max = m->periods_max;
- if (m->rates)
- dummy->pcm_hw.rates = m->rates;
- if (m->rate_min)
- dummy->pcm_hw.rate_min = m->rate_min;
- if (m->rate_max)
- dummy->pcm_hw.rate_max = m->rate_max;
- if (m->channels_min)
- dummy->pcm_hw.channels_min = m->channels_min;
- if (m->channels_max)
- dummy->pcm_hw.channels_max = m->channels_max;
- }
-
- err = snd_card_dummy_new_mixer(dummy);
- if (err < 0)
- goto __nodev;
- strcpy(card->driver, "Dummy");
- strcpy(card->shortname, "Dummy");
- sprintf(card->longname, "Dummy %i", dev + 1);
-
- dummy_proc_init(dummy);
-
- snd_card_set_dev(card, &devptr->dev);
-
- err = snd_card_register(card);
- if (err == 0) {
- platform_set_drvdata(devptr, card);
- return 0;
- }
- __nodev:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_dummy_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct snd_dummy *dummy = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(dummy->pcm);
- return 0;
-}
-
-static int snd_dummy_resume(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-#define SND_DUMMY_DRIVER "snd_dummy"
-
-static struct platform_driver snd_dummy_driver = {
- .probe = snd_dummy_probe,
- .remove = __devexit_p(snd_dummy_remove),
-#ifdef CONFIG_PM
- .suspend = snd_dummy_suspend,
- .resume = snd_dummy_resume,
-#endif
- .driver = {
- .name = SND_DUMMY_DRIVER
- },
-};
-
-static void snd_dummy_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_dummy_driver);
- free_fake_buffer();
-}
-
-static int __init alsa_card_dummy_init(void)
-{
- int i, cards, err;
-
- err = platform_driver_register(&snd_dummy_driver);
- if (err < 0)
- return err;
-
- err = alloc_fake_buffer();
- if (err < 0) {
- platform_driver_unregister(&snd_dummy_driver);
- return err;
- }
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_DUMMY_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "Dummy soundcard not found or device busy\n");
-#endif
- snd_dummy_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_dummy_exit(void)
-{
- snd_dummy_unregister_all();
-}
-
-module_init(alsa_card_dummy_init)
-module_exit(alsa_card_dummy_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c b/ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c
deleted file mode 100644
index 6c83b1ae..00000000
--- a/ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/*
- * ALSA driver for Xilinx ML403 AC97 Controller Reference
- * IP: opb_ac97_controller_ref_v1_00_a (EDK 8.1i)
- * IP: opb_ac97_controller_ref_v1_00_a (EDK 9.1i)
- *
- * Copyright (c) by 2007 Joachim Foerster <JOFT@gmx.de>
- *
- * 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
- *
- */
-
-/* Some notes / status of this driver:
- *
- * - Don't wonder about some strange implementations of things - especially the
- * (heavy) shadowing of codec registers, with which I tried to reduce read
- * accesses to a minimum, because after a variable amount of accesses, the AC97
- * controller doesn't raise the register access finished bit anymore ...
- *
- * - Playback support seems to be pretty stable - no issues here.
- * - Capture support "works" now, too. Overruns don't happen any longer so often.
- * But there might still be some ...
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/platform_device.h>
-
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-
-/* HZ */
-#include <linux/param.h>
-/* jiffies, time_*() */
-#include <linux/jiffies.h>
-/* schedule_timeout*() */
-#include <linux/sched.h>
-/* spin_lock*() */
-#include <linux/spinlock.h>
-/* struct mutex, mutex_init(), mutex_*lock() */
-#include <linux/mutex.h>
-
-/* snd_printk(), snd_printd() */
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/ac97_codec.h>
-
-#include "pcm-indirect2.h"
-
-
-#define SND_ML403_AC97CR_DRIVER "ml403-ac97cr"
-
-MODULE_AUTHOR("Joachim Foerster <JOFT@gmx.de>");
-MODULE_DESCRIPTION("Xilinx ML403 AC97 Controller Reference");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Xilinx,ML403 AC97 Controller Reference}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ML403 AC97 Controller Reference.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ML403 AC97 Controller Reference.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this ML403 AC97 Controller Reference.");
-
-/* Special feature options */
-/*#define CODEC_WRITE_CHECK_RAF*/ /* don't return after a write to a codec
- * register, while RAF bit is not set
- */
-/* Debug options for code which may be removed completely in a final version */
-#ifdef CONFIG_SND_DEBUG
-/*#define CODEC_STAT*/ /* turn on some minimal "statistics"
- * about codec register usage
- */
-#define SND_PCM_INDIRECT2_STAT /* turn on some "statistics" about the
- * process of copying bytes from the
- * intermediate buffer to the hardware
- * fifo and the other way round
- */
-#endif
-
-/* Definition of a "level/facility dependent" printk(); may be removed
- * completely in a final version
- */
-#undef PDEBUG
-#ifdef CONFIG_SND_DEBUG
-/* "facilities" for PDEBUG */
-#define UNKNOWN (1<<0)
-#define CODEC_SUCCESS (1<<1)
-#define CODEC_FAKE (1<<2)
-#define INIT_INFO (1<<3)
-#define INIT_FAILURE (1<<4)
-#define WORK_INFO (1<<5)
-#define WORK_FAILURE (1<<6)
-
-#define PDEBUG_FACILITIES (UNKNOWN | INIT_FAILURE | WORK_FAILURE)
-
-#define PDEBUG(fac, fmt, args...) do { \
- if (fac & PDEBUG_FACILITIES) \
- snd_printd(KERN_DEBUG SND_ML403_AC97CR_DRIVER ": " \
- fmt, ##args); \
- } while (0)
-#else
-#define PDEBUG(fac, fmt, args...) /* nothing */
-#endif
-
-
-
-/* Defines for "waits"/timeouts (portions of HZ=250 on arch/ppc by default) */
-#define CODEC_TIMEOUT_ON_INIT 5 /* timeout for checking for codec
- * readiness (after insmod)
- */
-#ifndef CODEC_WRITE_CHECK_RAF
-#define CODEC_WAIT_AFTER_WRITE 100 /* general, static wait after a write
- * access to a codec register, may be
- * 0 to completely remove wait
- */
-#else
-#define CODEC_TIMEOUT_AFTER_WRITE 5 /* timeout after a write access to a
- * codec register, if RAF bit is used
- */
-#endif
-#define CODEC_TIMEOUT_AFTER_READ 5 /* timeout after a read access to a
- * codec register (checking RAF bit)
- */
-
-/* Infrastructure for codec register shadowing */
-#define LM4550_REG_OK (1<<0) /* register exists */
-#define LM4550_REG_DONEREAD (1<<1) /* read register once, value should be
- * the same currently in the register
- */
-#define LM4550_REG_NOSAVE (1<<2) /* values written to this register will
- * not be saved in the register
- */
-#define LM4550_REG_NOSHADOW (1<<3) /* don't do register shadowing, use plain
- * hardware access
- */
-#define LM4550_REG_READONLY (1<<4) /* register is read only */
-#define LM4550_REG_FAKEPROBE (1<<5) /* fake write _and_ read actions during
- * probe() correctly
- */
-#define LM4550_REG_FAKEREAD (1<<6) /* fake read access, always return
- * default value
- */
-#define LM4550_REG_ALLFAKE (LM4550_REG_FAKEREAD | LM4550_REG_FAKEPROBE)
-
-struct lm4550_reg {
- u16 value;
- u16 flag;
- u16 wmask;
- u16 def;
-};
-
-struct lm4550_reg lm4550_regfile[64] = {
- [AC97_RESET / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_NOSAVE \
- | LM4550_REG_FAKEREAD,
- .def = 0x0D50},
- [AC97_MASTER / 2] = {.flag = LM4550_REG_OK
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8000},
- [AC97_HEADPHONE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8000},
- [AC97_MASTER_MONO / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x801F,
- .def = 0x8000},
- [AC97_PC_BEEP / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x801E,
- .def = 0x0},
- [AC97_PHONE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x801F,
- .def = 0x8008},
- [AC97_MIC / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x805F,
- .def = 0x8008},
- [AC97_LINE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_CD / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_VIDEO / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_AUX / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_PCM / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8008},
- [AC97_REC_SEL / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x707,
- .def = 0x0},
- [AC97_REC_GAIN / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x8F0F,
- .def = 0x8000},
- [AC97_GENERAL_PURPOSE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .def = 0x0,
- .wmask = 0xA380},
- [AC97_3D_CONTROL / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEREAD \
- | LM4550_REG_READONLY,
- .def = 0x0101},
- [AC97_POWERDOWN / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_NOSHADOW \
- | LM4550_REG_NOSAVE,
- .wmask = 0xFF00},
- /* may not write ones to
- * REF/ANL/DAC/ADC bits
- * FIXME: Is this ok?
- */
- [AC97_EXTENDED_ID / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEREAD \
- | LM4550_REG_READONLY,
- .def = 0x0201}, /* primary codec */
- [AC97_EXTENDED_STATUS / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_NOSHADOW \
- | LM4550_REG_NOSAVE,
- .wmask = 0x1},
- [AC97_PCM_FRONT_DAC_RATE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .def = 0xBB80,
- .wmask = 0xFFFF},
- [AC97_PCM_LR_ADC_RATE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .def = 0xBB80,
- .wmask = 0xFFFF},
- [AC97_VENDOR_ID1 / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_READONLY \
- | LM4550_REG_FAKEREAD,
- .def = 0x4E53},
- [AC97_VENDOR_ID2 / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_READONLY \
- | LM4550_REG_FAKEREAD,
- .def = 0x4350}
-};
-
-#define LM4550_RF_OK(reg) (lm4550_regfile[reg / 2].flag & LM4550_REG_OK)
-
-static void lm4550_regfile_init(void)
-{
- int i;
- for (i = 0; i < 64; i++)
- if (lm4550_regfile[i].flag & LM4550_REG_FAKEPROBE)
- lm4550_regfile[i].value = lm4550_regfile[i].def;
-}
-
-static void lm4550_regfile_write_values_after_init(struct snd_ac97 *ac97)
-{
- int i;
- for (i = 0; i < 64; i++)
- if ((lm4550_regfile[i].flag & LM4550_REG_FAKEPROBE) &&
- (lm4550_regfile[i].value != lm4550_regfile[i].def)) {
- PDEBUG(CODEC_FAKE, "lm4550_regfile_write_values_after_"
- "init(): reg=0x%x value=0x%x / %d is different "
- "from def=0x%x / %d\n",
- i, lm4550_regfile[i].value,
- lm4550_regfile[i].value, lm4550_regfile[i].def,
- lm4550_regfile[i].def);
- snd_ac97_write(ac97, i * 2, lm4550_regfile[i].value);
- lm4550_regfile[i].flag |= LM4550_REG_DONEREAD;
- }
-}
-
-
-/* direct registers */
-#define CR_REG(ml403_ac97cr, x) ((ml403_ac97cr)->port + CR_REG_##x)
-
-#define CR_REG_PLAYFIFO 0x00
-#define CR_PLAYDATA(a) ((a) & 0xFFFF)
-
-#define CR_REG_RECFIFO 0x04
-#define CR_RECDATA(a) ((a) & 0xFFFF)
-
-#define CR_REG_STATUS 0x08
-#define CR_RECOVER (1<<7)
-#define CR_PLAYUNDER (1<<6)
-#define CR_CODECREADY (1<<5)
-#define CR_RAF (1<<4)
-#define CR_RECEMPTY (1<<3)
-#define CR_RECFULL (1<<2)
-#define CR_PLAYHALF (1<<1)
-#define CR_PLAYFULL (1<<0)
-
-#define CR_REG_RESETFIFO 0x0C
-#define CR_RECRESET (1<<1)
-#define CR_PLAYRESET (1<<0)
-
-#define CR_REG_CODEC_ADDR 0x10
-/* UG082 says:
- * #define CR_CODEC_ADDR(a) ((a) << 1)
- * #define CR_CODEC_READ (1<<0)
- * #define CR_CODEC_WRITE (0<<0)
- */
-/* RefDesign example says: */
-#define CR_CODEC_ADDR(a) ((a) << 0)
-#define CR_CODEC_READ (1<<7)
-#define CR_CODEC_WRITE (0<<7)
-
-#define CR_REG_CODEC_DATAREAD 0x14
-#define CR_CODEC_DATAREAD(v) ((v) & 0xFFFF)
-
-#define CR_REG_CODEC_DATAWRITE 0x18
-#define CR_CODEC_DATAWRITE(v) ((v) & 0xFFFF)
-
-#define CR_FIFO_SIZE 32
-
-struct snd_ml403_ac97cr {
- /* lock for access to (controller) registers */
- spinlock_t reg_lock;
- /* mutex for the whole sequence of accesses to (controller) registers
- * which affect codec registers
- */
- struct mutex cdc_mutex;
-
- int irq; /* for playback */
- int enable_irq; /* for playback */
-
- int capture_irq;
- int enable_capture_irq;
-
- struct resource *res_port;
- void *port;
-
- struct snd_ac97 *ac97;
- int ac97_fake;
-#ifdef CODEC_STAT
- int ac97_read;
- int ac97_write;
-#endif
-
- struct platform_device *pfdev;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
- struct snd_pcm_indirect2 ind_rec; /* for playback */
- struct snd_pcm_indirect2 capture_ind2_rec;
-};
-
-static struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000),
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = CR_FIFO_SIZE/2,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = (128*1024)/(CR_FIFO_SIZE/2),
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_ml403_ac97cr_capture = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000),
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = CR_FIFO_SIZE/2,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = (128*1024)/(CR_FIFO_SIZE/2),
- .fifo_size = 0,
-};
-
-static size_t
-snd_ml403_ac97cr_playback_ind2_zero(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int copied_words = 0;
- u32 full = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while ((full = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_PLAYFULL)) != CR_PLAYFULL) {
- out_be32(CR_REG(ml403_ac97cr, PLAYFIFO), 0);
- copied_words++;
- }
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static size_t
-snd_ml403_ac97cr_playback_ind2_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- size_t bytes)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- u16 *src;
- int copied_words = 0;
- u32 full = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- src = (u16 *)(substream->runtime->dma_area + rec->sw_data);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while (((full = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_PLAYFULL)) != CR_PLAYFULL) && (bytes > 1)) {
- out_be32(CR_REG(ml403_ac97cr, PLAYFIFO),
- CR_PLAYDATA(src[copied_words]));
- copied_words++;
- bytes = bytes - 2;
- }
- if (full != CR_PLAYFULL)
- rec->hw_ready = 1;
- else
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static size_t
-snd_ml403_ac97cr_capture_ind2_null(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int copied_words = 0;
- u32 empty = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while ((empty = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RECEMPTY)) != CR_RECEMPTY) {
- volatile u32 trash;
-
- trash = CR_RECDATA(in_be32(CR_REG(ml403_ac97cr, RECFIFO)));
- /* Hmmmm, really necessary? Don't want call to in_be32()
- * to be optimised away!
- */
- trash++;
- copied_words++;
- }
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static size_t
-snd_ml403_ac97cr_capture_ind2_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec, size_t bytes)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- u16 *dst;
- int copied_words = 0;
- u32 empty = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- dst = (u16 *)(substream->runtime->dma_area + rec->sw_data);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while (((empty = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RECEMPTY)) != CR_RECEMPTY) && (bytes > 1)) {
- dst[copied_words] = CR_RECDATA(in_be32(CR_REG(ml403_ac97cr,
- RECFIFO)));
- copied_words++;
- bytes = bytes - 2;
- }
- if (empty != CR_RECEMPTY)
- rec->hw_ready = 1;
- else
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static snd_pcm_uframes_t
-snd_ml403_ac97cr_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_indirect2 *ind2_rec = NULL;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- if (substream == ml403_ac97cr->playback_substream)
- ind2_rec = &ml403_ac97cr->ind_rec;
- if (substream == ml403_ac97cr->capture_substream)
- ind2_rec = &ml403_ac97cr->capture_ind2_rec;
-
- if (ind2_rec != NULL)
- return snd_pcm_indirect2_pointer(substream, ind2_rec);
- return (snd_pcm_uframes_t) 0;
-}
-
-static int
-snd_ml403_ac97cr_pcm_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int err = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- PDEBUG(WORK_INFO, "trigger(playback): START\n");
- ml403_ac97cr->ind_rec.hw_ready = 1;
-
- /* clear play FIFO */
- out_be32(CR_REG(ml403_ac97cr, RESETFIFO), CR_PLAYRESET);
-
- /* enable play irq */
- ml403_ac97cr->enable_irq = 1;
- enable_irq(ml403_ac97cr->irq);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- PDEBUG(WORK_INFO, "trigger(playback): STOP\n");
- ml403_ac97cr->ind_rec.hw_ready = 0;
-#ifdef SND_PCM_INDIRECT2_STAT
- snd_pcm_indirect2_stat(substream, &ml403_ac97cr->ind_rec);
-#endif
- /* disable play irq */
- disable_irq_nosync(ml403_ac97cr->irq);
- ml403_ac97cr->enable_irq = 0;
- break;
- default:
- err = -EINVAL;
- break;
- }
- PDEBUG(WORK_INFO, "trigger(playback): (done)\n");
- return err;
-}
-
-static int
-snd_ml403_ac97cr_pcm_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int err = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- PDEBUG(WORK_INFO, "trigger(capture): START\n");
- ml403_ac97cr->capture_ind2_rec.hw_ready = 0;
-
- /* clear record FIFO */
- out_be32(CR_REG(ml403_ac97cr, RESETFIFO), CR_RECRESET);
-
- /* enable record irq */
- ml403_ac97cr->enable_capture_irq = 1;
- enable_irq(ml403_ac97cr->capture_irq);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- PDEBUG(WORK_INFO, "trigger(capture): STOP\n");
- ml403_ac97cr->capture_ind2_rec.hw_ready = 0;
-#ifdef SND_PCM_INDIRECT2_STAT
- snd_pcm_indirect2_stat(substream,
- &ml403_ac97cr->capture_ind2_rec);
-#endif
- /* disable capture irq */
- disable_irq_nosync(ml403_ac97cr->capture_irq);
- ml403_ac97cr->enable_capture_irq = 0;
- break;
- default:
- err = -EINVAL;
- break;
- }
- PDEBUG(WORK_INFO, "trigger(capture): (done)\n");
- return err;
-}
-
-static int
-snd_ml403_ac97cr_pcm_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO,
- "prepare(): period_bytes=%d, minperiod_bytes=%d\n",
- snd_pcm_lib_period_bytes(substream), CR_FIFO_SIZE / 2);
-
- /* set sampling rate */
- snd_ac97_set_rate(ml403_ac97cr->ac97, AC97_PCM_FRONT_DAC_RATE,
- runtime->rate);
- PDEBUG(WORK_INFO, "prepare(): rate=%d\n", runtime->rate);
-
- /* init struct for intermediate buffer */
- memset(&ml403_ac97cr->ind_rec, 0,
- sizeof(struct snd_pcm_indirect2));
- ml403_ac97cr->ind_rec.hw_buffer_size = CR_FIFO_SIZE;
- ml403_ac97cr->ind_rec.sw_buffer_size =
- snd_pcm_lib_buffer_bytes(substream);
- ml403_ac97cr->ind_rec.min_periods = -1;
- ml403_ac97cr->ind_rec.min_multiple =
- snd_pcm_lib_period_bytes(substream) / (CR_FIFO_SIZE / 2);
- PDEBUG(WORK_INFO, "prepare(): hw_buffer_size=%d, "
- "sw_buffer_size=%d, min_multiple=%d\n",
- CR_FIFO_SIZE, ml403_ac97cr->ind_rec.sw_buffer_size,
- ml403_ac97cr->ind_rec.min_multiple);
- return 0;
-}
-
-static int
-snd_ml403_ac97cr_pcm_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO,
- "prepare(capture): period_bytes=%d, minperiod_bytes=%d\n",
- snd_pcm_lib_period_bytes(substream), CR_FIFO_SIZE / 2);
-
- /* set sampling rate */
- snd_ac97_set_rate(ml403_ac97cr->ac97, AC97_PCM_LR_ADC_RATE,
- runtime->rate);
- PDEBUG(WORK_INFO, "prepare(capture): rate=%d\n", runtime->rate);
-
- /* init struct for intermediate buffer */
- memset(&ml403_ac97cr->capture_ind2_rec, 0,
- sizeof(struct snd_pcm_indirect2));
- ml403_ac97cr->capture_ind2_rec.hw_buffer_size = CR_FIFO_SIZE;
- ml403_ac97cr->capture_ind2_rec.sw_buffer_size =
- snd_pcm_lib_buffer_bytes(substream);
- ml403_ac97cr->capture_ind2_rec.min_multiple =
- snd_pcm_lib_period_bytes(substream) / (CR_FIFO_SIZE / 2);
- PDEBUG(WORK_INFO, "prepare(capture): hw_buffer_size=%d, "
- "sw_buffer_size=%d, min_multiple=%d\n", CR_FIFO_SIZE,
- ml403_ac97cr->capture_ind2_rec.sw_buffer_size,
- ml403_ac97cr->capture_ind2_rec.min_multiple);
- return 0;
-}
-
-static int snd_ml403_ac97cr_hw_free(struct snd_pcm_substream *substream)
-{
- PDEBUG(WORK_INFO, "hw_free()\n");
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int
-snd_ml403_ac97cr_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- PDEBUG(WORK_INFO, "hw_params(): desired buffer bytes=%d, desired "
- "period bytes=%d\n",
- params_buffer_bytes(hw_params), params_period_bytes(hw_params));
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_ml403_ac97cr_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO, "open(playback)\n");
- ml403_ac97cr->playback_substream = substream;
- runtime->hw = snd_ml403_ac97cr_playback;
-
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- CR_FIFO_SIZE / 2);
- return 0;
-}
-
-static int snd_ml403_ac97cr_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO, "open(capture)\n");
- ml403_ac97cr->capture_substream = substream;
- runtime->hw = snd_ml403_ac97cr_capture;
-
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- CR_FIFO_SIZE / 2);
- return 0;
-}
-
-static int snd_ml403_ac97cr_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- PDEBUG(WORK_INFO, "close(playback)\n");
- ml403_ac97cr->playback_substream = NULL;
- return 0;
-}
-
-static int snd_ml403_ac97cr_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- PDEBUG(WORK_INFO, "close(capture)\n");
- ml403_ac97cr->capture_substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
- .open = snd_ml403_ac97cr_playback_open,
- .close = snd_ml403_ac97cr_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ml403_ac97cr_hw_params,
- .hw_free = snd_ml403_ac97cr_hw_free,
- .prepare = snd_ml403_ac97cr_pcm_playback_prepare,
- .trigger = snd_ml403_ac97cr_pcm_playback_trigger,
- .pointer = snd_ml403_ac97cr_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = {
- .open = snd_ml403_ac97cr_capture_open,
- .close = snd_ml403_ac97cr_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ml403_ac97cr_hw_params,
- .hw_free = snd_ml403_ac97cr_hw_free,
- .prepare = snd_ml403_ac97cr_pcm_capture_prepare,
- .trigger = snd_ml403_ac97cr_pcm_capture_trigger,
- .pointer = snd_ml403_ac97cr_pcm_pointer,
-};
-
-static irqreturn_t snd_ml403_ac97cr_irq(int irq, void *dev_id)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct platform_device *pfdev;
- int cmp_irq;
-
- ml403_ac97cr = (struct snd_ml403_ac97cr *)dev_id;
- if (ml403_ac97cr == NULL)
- return IRQ_NONE;
-
- pfdev = ml403_ac97cr->pfdev;
-
- /* playback interrupt */
- cmp_irq = platform_get_irq(pfdev, 0);
- if (irq == cmp_irq) {
- if (ml403_ac97cr->enable_irq)
- snd_pcm_indirect2_playback_interrupt(
- ml403_ac97cr->playback_substream,
- &ml403_ac97cr->ind_rec,
- snd_ml403_ac97cr_playback_ind2_copy,
- snd_ml403_ac97cr_playback_ind2_zero);
- else
- goto __disable_irq;
- } else {
- /* record interrupt */
- cmp_irq = platform_get_irq(pfdev, 1);
- if (irq == cmp_irq) {
- if (ml403_ac97cr->enable_capture_irq)
- snd_pcm_indirect2_capture_interrupt(
- ml403_ac97cr->capture_substream,
- &ml403_ac97cr->capture_ind2_rec,
- snd_ml403_ac97cr_capture_ind2_copy,
- snd_ml403_ac97cr_capture_ind2_null);
- else
- goto __disable_irq;
- } else
- return IRQ_NONE;
- }
- return IRQ_HANDLED;
-
-__disable_irq:
- PDEBUG(INIT_INFO, "irq(): irq %d is meant to be disabled! So, now try "
- "to disable it _really_!\n", irq);
- disable_irq_nosync(irq);
- return IRQ_HANDLED;
-}
-
-static unsigned short
-snd_ml403_ac97cr_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = ac97->private_data;
-#ifdef CODEC_STAT
- u32 stat;
- u32 rafaccess = 0;
-#endif
- unsigned long end_time;
- u16 value = 0;
-
- if (!LM4550_RF_OK(reg)) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "access to unknown/unused codec register 0x%x "
- "ignored!\n", reg);
- return 0;
- }
- /* check if we can fake/answer this access from our shadow register */
- if ((lm4550_regfile[reg / 2].flag &
- (LM4550_REG_DONEREAD | LM4550_REG_ALLFAKE)) &&
- !(lm4550_regfile[reg / 2].flag & LM4550_REG_NOSHADOW)) {
- if (lm4550_regfile[reg / 2].flag & LM4550_REG_FAKEREAD) {
- PDEBUG(CODEC_FAKE, "codec_read(): faking read from "
- "reg=0x%x, val=0x%x / %d\n",
- reg, lm4550_regfile[reg / 2].def,
- lm4550_regfile[reg / 2].def);
- return lm4550_regfile[reg / 2].def;
- } else if ((lm4550_regfile[reg / 2].flag &
- LM4550_REG_FAKEPROBE) &&
- ml403_ac97cr->ac97_fake) {
- PDEBUG(CODEC_FAKE, "codec_read(): faking read from "
- "reg=0x%x, val=0x%x / %d (probe)\n",
- reg, lm4550_regfile[reg / 2].value,
- lm4550_regfile[reg / 2].value);
- return lm4550_regfile[reg / 2].value;
- } else {
-#ifdef CODEC_STAT
- PDEBUG(CODEC_FAKE, "codec_read(): read access "
- "answered by shadow register 0x%x (value=0x%x "
- "/ %d) (cw=%d cr=%d)\n",
- reg, lm4550_regfile[reg / 2].value,
- lm4550_regfile[reg / 2].value,
- ml403_ac97cr->ac97_write,
- ml403_ac97cr->ac97_read);
-#else
- PDEBUG(CODEC_FAKE, "codec_read(): read access "
- "answered by shadow register 0x%x (value=0x%x "
- "/ %d)\n",
- reg, lm4550_regfile[reg / 2].value,
- lm4550_regfile[reg / 2].value);
-#endif
- return lm4550_regfile[reg / 2].value;
- }
- }
- /* if we are here, we _have_ to access the codec really, no faking */
- if (mutex_lock_interruptible(&ml403_ac97cr->cdc_mutex) != 0)
- return 0;
-#ifdef CODEC_STAT
- ml403_ac97cr->ac97_read++;
-#endif
- spin_lock(&ml403_ac97cr->reg_lock);
- out_be32(CR_REG(ml403_ac97cr, CODEC_ADDR),
- CR_CODEC_ADDR(reg) | CR_CODEC_READ);
- spin_unlock(&ml403_ac97cr->reg_lock);
- end_time = jiffies + (HZ / CODEC_TIMEOUT_AFTER_READ);
- do {
- spin_lock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_STAT
- rafaccess++;
- stat = in_be32(CR_REG(ml403_ac97cr, STATUS));
- if ((stat & CR_RAF) == CR_RAF) {
- value = CR_CODEC_DATAREAD(
- in_be32(CR_REG(ml403_ac97cr, CODEC_DATAREAD)));
- PDEBUG(CODEC_SUCCESS, "codec_read(): (done) reg=0x%x, "
- "value=0x%x / %d (STATUS=0x%x)\n",
- reg, value, value, stat);
-#else
- if ((in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RAF) == CR_RAF) {
- value = CR_CODEC_DATAREAD(
- in_be32(CR_REG(ml403_ac97cr, CODEC_DATAREAD)));
- PDEBUG(CODEC_SUCCESS, "codec_read(): (done) "
- "reg=0x%x, value=0x%x / %d\n",
- reg, value, value);
-#endif
- lm4550_regfile[reg / 2].value = value;
- lm4550_regfile[reg / 2].flag |= LM4550_REG_DONEREAD;
- spin_unlock(&ml403_ac97cr->reg_lock);
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return value;
- }
- spin_unlock(&ml403_ac97cr->reg_lock);
- schedule_timeout_uninterruptible(1);
- } while (time_after(end_time, jiffies));
- /* read the DATAREAD register anyway, see comment below */
- spin_lock(&ml403_ac97cr->reg_lock);
- value =
- CR_CODEC_DATAREAD(in_be32(CR_REG(ml403_ac97cr, CODEC_DATAREAD)));
- spin_unlock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_STAT
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec read! "
- "(reg=0x%x, last STATUS=0x%x, DATAREAD=0x%x / %d, %d) "
- "(cw=%d, cr=%d)\n",
- reg, stat, value, value, rafaccess,
- ml403_ac97cr->ac97_write, ml403_ac97cr->ac97_read);
-#else
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec read! "
- "(reg=0x%x, DATAREAD=0x%x / %d)\n",
- reg, value, value);
-#endif
- /* BUG: This is PURE speculation! But after _most_ read timeouts the
- * value in the register is ok!
- */
- lm4550_regfile[reg / 2].value = value;
- lm4550_regfile[reg / 2].flag |= LM4550_REG_DONEREAD;
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return value;
-}
-
-static void
-snd_ml403_ac97cr_codec_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = ac97->private_data;
-
-#ifdef CODEC_STAT
- u32 stat;
- u32 rafaccess = 0;
-#endif
-#ifdef CODEC_WRITE_CHECK_RAF
- unsigned long end_time;
-#endif
-
- if (!LM4550_RF_OK(reg)) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "access to unknown/unused codec register 0x%x "
- "ignored!\n", reg);
- return;
- }
- if (lm4550_regfile[reg / 2].flag & LM4550_REG_READONLY) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "write access to read only codec register 0x%x "
- "ignored!\n", reg);
- return;
- }
- if ((val & lm4550_regfile[reg / 2].wmask) != val) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "write access to codec register 0x%x "
- "with bad value 0x%x / %d!\n",
- reg, val, val);
- val = val & lm4550_regfile[reg / 2].wmask;
- }
- if (((lm4550_regfile[reg / 2].flag & LM4550_REG_FAKEPROBE) &&
- ml403_ac97cr->ac97_fake) &&
- !(lm4550_regfile[reg / 2].flag & LM4550_REG_NOSHADOW)) {
- PDEBUG(CODEC_FAKE, "codec_write(): faking write to reg=0x%x, "
- "val=0x%x / %d\n", reg, val, val);
- lm4550_regfile[reg / 2].value = (val &
- lm4550_regfile[reg / 2].wmask);
- return;
- }
- if (mutex_lock_interruptible(&ml403_ac97cr->cdc_mutex) != 0)
- return;
-#ifdef CODEC_STAT
- ml403_ac97cr->ac97_write++;
-#endif
- spin_lock(&ml403_ac97cr->reg_lock);
- out_be32(CR_REG(ml403_ac97cr, CODEC_DATAWRITE),
- CR_CODEC_DATAWRITE(val));
- out_be32(CR_REG(ml403_ac97cr, CODEC_ADDR),
- CR_CODEC_ADDR(reg) | CR_CODEC_WRITE);
- spin_unlock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_WRITE_CHECK_RAF
- /* check CR_CODEC_RAF bit to see if write access to register is done;
- * loop until bit is set or timeout happens
- */
- end_time = jiffies + HZ / CODEC_TIMEOUT_AFTER_WRITE;
- do {
- spin_lock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_STAT
- rafaccess++;
- stat = in_be32(CR_REG(ml403_ac97cr, STATUS))
- if ((stat & CR_RAF) == CR_RAF) {
-#else
- if ((in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RAF) == CR_RAF) {
-#endif
- PDEBUG(CODEC_SUCCESS, "codec_write(): (done) "
- "reg=0x%x, value=%d / 0x%x\n",
- reg, val, val);
- if (!(lm4550_regfile[reg / 2].flag &
- LM4550_REG_NOSHADOW) &&
- !(lm4550_regfile[reg / 2].flag &
- LM4550_REG_NOSAVE))
- lm4550_regfile[reg / 2].value = val;
- lm4550_regfile[reg / 2].flag |= LM4550_REG_DONEREAD;
- spin_unlock(&ml403_ac97cr->reg_lock);
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return;
- }
- spin_unlock(&ml403_ac97cr->reg_lock);
- schedule_timeout_uninterruptible(1);
- } while (time_after(end_time, jiffies));
-#ifdef CODEC_STAT
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec write "
- "(reg=0x%x, val=0x%x / %d, last STATUS=0x%x, %d) "
- "(cw=%d, cr=%d)\n",
- reg, val, val, stat, rafaccess, ml403_ac97cr->ac97_write,
- ml403_ac97cr->ac97_read);
-#else
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec write (reg=0x%x, val=0x%x / %d)\n",
- reg, val, val);
-#endif
-#else /* CODEC_WRITE_CHECK_RAF */
-#if CODEC_WAIT_AFTER_WRITE > 0
- /* officially, in AC97 spec there is no possibility for a AC97
- * controller to determine, if write access is done or not - so: How
- * is Xilinx able to provide a RAF bit for write access?
- * => very strange, thus just don't check RAF bit (compare with
- * Xilinx's example app in EDK 8.1i) and wait
- */
- schedule_timeout_uninterruptible(HZ / CODEC_WAIT_AFTER_WRITE);
-#endif
- PDEBUG(CODEC_SUCCESS, "codec_write(): (done) "
- "reg=0x%x, value=%d / 0x%x (no RAF check)\n",
- reg, val, val);
-#endif
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return;
-}
-
-static int __devinit
-snd_ml403_ac97cr_chip_init(struct snd_ml403_ac97cr *ml403_ac97cr)
-{
- unsigned long end_time;
- PDEBUG(INIT_INFO, "chip_init():\n");
- end_time = jiffies + HZ / CODEC_TIMEOUT_ON_INIT;
- do {
- if (in_be32(CR_REG(ml403_ac97cr, STATUS)) & CR_CODECREADY) {
- /* clear both hardware FIFOs */
- out_be32(CR_REG(ml403_ac97cr, RESETFIFO),
- CR_RECRESET | CR_PLAYRESET);
- PDEBUG(INIT_INFO, "chip_init(): (done)\n");
- return 0;
- }
- schedule_timeout_uninterruptible(1);
- } while (time_after(end_time, jiffies));
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "timeout while waiting for codec, "
- "not ready!\n");
- return -EBUSY;
-}
-
-static int snd_ml403_ac97cr_free(struct snd_ml403_ac97cr *ml403_ac97cr)
-{
- PDEBUG(INIT_INFO, "free():\n");
- /* irq release */
- if (ml403_ac97cr->irq >= 0)
- free_irq(ml403_ac97cr->irq, ml403_ac97cr);
- if (ml403_ac97cr->capture_irq >= 0)
- free_irq(ml403_ac97cr->capture_irq, ml403_ac97cr);
- /* give back "port" */
- if (ml403_ac97cr->port != NULL)
- iounmap(ml403_ac97cr->port);
- kfree(ml403_ac97cr);
- PDEBUG(INIT_INFO, "free(): (done)\n");
- return 0;
-}
-
-static int snd_ml403_ac97cr_dev_free(struct snd_device *snddev)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = snddev->device_data;
- PDEBUG(INIT_INFO, "dev_free():\n");
- return snd_ml403_ac97cr_free(ml403_ac97cr);
-}
-
-static int __devinit
-snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
- struct snd_ml403_ac97cr **rml403_ac97cr)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_ml403_ac97cr_dev_free,
- };
- struct resource *resource;
- int irq;
-
- *rml403_ac97cr = NULL;
- ml403_ac97cr = kzalloc(sizeof(*ml403_ac97cr), GFP_KERNEL);
- if (ml403_ac97cr == NULL)
- return -ENOMEM;
- spin_lock_init(&ml403_ac97cr->reg_lock);
- mutex_init(&ml403_ac97cr->cdc_mutex);
- ml403_ac97cr->card = card;
- ml403_ac97cr->pfdev = pfdev;
- ml403_ac97cr->irq = -1;
- ml403_ac97cr->enable_irq = 0;
- ml403_ac97cr->capture_irq = -1;
- ml403_ac97cr->enable_capture_irq = 0;
- ml403_ac97cr->port = NULL;
- ml403_ac97cr->res_port = NULL;
-
- PDEBUG(INIT_INFO, "Trying to reserve resources now ...\n");
- resource = platform_get_resource(pfdev, IORESOURCE_MEM, 0);
- /* get "port" */
- ml403_ac97cr->port = ioremap_nocache(resource->start,
- (resource->end) -
- (resource->start) + 1);
- if (ml403_ac97cr->port == NULL) {
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to remap memory region (%pR)\n",
- resource);
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return -EBUSY;
- }
- snd_printk(KERN_INFO SND_ML403_AC97CR_DRIVER ": "
- "remap controller memory region to "
- "0x%x done\n", (unsigned int)ml403_ac97cr->port);
- /* get irq */
- irq = platform_get_irq(pfdev, 0);
- if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
- dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to grab IRQ %d\n",
- irq);
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return -EBUSY;
- }
- ml403_ac97cr->irq = irq;
- snd_printk(KERN_INFO SND_ML403_AC97CR_DRIVER ": "
- "request (playback) irq %d done\n",
- ml403_ac97cr->irq);
- irq = platform_get_irq(pfdev, 1);
- if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
- dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to grab IRQ %d\n",
- irq);
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return -EBUSY;
- }
- ml403_ac97cr->capture_irq = irq;
- snd_printk(KERN_INFO SND_ML403_AC97CR_DRIVER ": "
- "request (capture) irq %d done\n",
- ml403_ac97cr->capture_irq);
-
- err = snd_ml403_ac97cr_chip_init(ml403_ac97cr);
- if (err < 0) {
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return err;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ml403_ac97cr, &ops);
- if (err < 0) {
- PDEBUG(INIT_FAILURE, "probe(): snd_device_new() failed!\n");
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return err;
- }
-
- *rml403_ac97cr = ml403_ac97cr;
- return 0;
-}
-
-static void snd_ml403_ac97cr_mixer_free(struct snd_ac97 *ac97)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = ac97->private_data;
- PDEBUG(INIT_INFO, "mixer_free():\n");
- ml403_ac97cr->ac97 = NULL;
- PDEBUG(INIT_INFO, "mixer_free(): (done)\n");
-}
-
-static int __devinit
-snd_ml403_ac97cr_mixer(struct snd_ml403_ac97cr *ml403_ac97cr)
-{
- struct snd_ac97_bus *bus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_ml403_ac97cr_codec_write,
- .read = snd_ml403_ac97cr_codec_read,
- };
- PDEBUG(INIT_INFO, "mixer():\n");
- err = snd_ac97_bus(ml403_ac97cr->card, 0, &ops, NULL, &bus);
- if (err < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ml403_ac97cr->ac97_fake = 1;
- lm4550_regfile_init();
-#ifdef CODEC_STAT
- ml403_ac97cr->ac97_read = 0;
- ml403_ac97cr->ac97_write = 0;
-#endif
- ac97.private_data = ml403_ac97cr;
- ac97.private_free = snd_ml403_ac97cr_mixer_free;
- ac97.scaps = AC97_SCAP_AUDIO | AC97_SCAP_SKIP_MODEM |
- AC97_SCAP_NO_SPDIF;
- err = snd_ac97_mixer(bus, &ac97, &ml403_ac97cr->ac97);
- ml403_ac97cr->ac97_fake = 0;
- lm4550_regfile_write_values_after_init(ml403_ac97cr->ac97);
- PDEBUG(INIT_INFO, "mixer(): (done) snd_ac97_mixer()=%d\n", err);
- return err;
-}
-
-static int __devinit
-snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device,
- struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- err = snd_pcm_new(ml403_ac97cr->card, "ML403AC97CR/1", device, 1, 1,
- &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_ml403_ac97cr_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_ml403_ac97cr_capture_ops);
- pcm->private_data = ml403_ac97cr;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ML403AC97CR DAC/ADC");
- ml403_ac97cr->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64 * 1024,
- 128 * 1024);
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static int __devinit snd_ml403_ac97cr_probe(struct platform_device *pfdev)
-{
- struct snd_card *card;
- struct snd_ml403_ac97cr *ml403_ac97cr = NULL;
- int err;
- int dev = pfdev->id;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev])
- return -ENOENT;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- err = snd_ml403_ac97cr_create(card, pfdev, &ml403_ac97cr);
- if (err < 0) {
- PDEBUG(INIT_FAILURE, "probe(): create failed!\n");
- snd_card_free(card);
- return err;
- }
- PDEBUG(INIT_INFO, "probe(): create done\n");
- card->private_data = ml403_ac97cr;
- err = snd_ml403_ac97cr_mixer(ml403_ac97cr);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- PDEBUG(INIT_INFO, "probe(): mixer done\n");
- err = snd_ml403_ac97cr_pcm(ml403_ac97cr, 0, NULL);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- PDEBUG(INIT_INFO, "probe(): PCM done\n");
- strcpy(card->driver, SND_ML403_AC97CR_DRIVER);
- strcpy(card->shortname, "ML403 AC97 Controller Reference");
- sprintf(card->longname, "%s %s at 0x%lx, irq %i & %i, device %i",
- card->shortname, card->driver,
- (unsigned long)ml403_ac97cr->port, ml403_ac97cr->irq,
- ml403_ac97cr->capture_irq, dev + 1);
-
- snd_card_set_dev(card, &pfdev->dev);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- platform_set_drvdata(pfdev, card);
- PDEBUG(INIT_INFO, "probe(): (done)\n");
- return 0;
-}
-
-static int snd_ml403_ac97cr_remove(struct platform_device *pfdev)
-{
- snd_card_free(platform_get_drvdata(pfdev));
- platform_set_drvdata(pfdev, NULL);
- return 0;
-}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:" SND_ML403_AC97CR_DRIVER);
-
-static struct platform_driver snd_ml403_ac97cr_driver = {
- .probe = snd_ml403_ac97cr_probe,
- .remove = snd_ml403_ac97cr_remove,
- .driver = {
- .name = SND_ML403_AC97CR_DRIVER,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(snd_ml403_ac97cr_driver);
diff --git a/ANDROID_3.4.5/sound/drivers/mpu401/Makefile b/ANDROID_3.4.5/sound/drivers/mpu401/Makefile
deleted file mode 100644
index 918f83f3..00000000
--- a/ANDROID_3.4.5/sound/drivers/mpu401/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-mpu401-objs := mpu401.o
-snd-mpu401-uart-objs := mpu401_uart.o
-
-obj-$(CONFIG_SND_MPU401_UART) += snd-mpu401-uart.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_MPU401) += snd-mpu401.o
diff --git a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c b/ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c
deleted file mode 100644
index 86f5fbc2..00000000
--- a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Driver for generic MPU-401 boards (UART mode only)
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Copyright (c) 2004 by Castet Matthieu <castet.matthieu@free.fr>
- *
- *
- * 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 <linux/init.h>
-#include <linux/pnp.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/mpu401.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("MPU-401 UART");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
-static bool uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for MPU-401 device.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable MPU-401 device.");
-#ifdef CONFIG_PNP
-module_param_array(pnp, bool, NULL, 0444);
-MODULE_PARM_DESC(pnp, "PnP detection for MPU-401 device.");
-#endif
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
-module_param_array(uart_enter, bool, NULL, 0444);
-MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open.");
-
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
-static unsigned int snd_mpu401_devices;
-
-static int snd_mpu401_create(int dev, struct snd_card **rcard)
-{
- struct snd_card *card;
- int err;
-
- if (!uart_enter[dev])
- snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n");
-
- *rcard = NULL;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- strcpy(card->driver, "MPU-401 UART");
- strcpy(card->shortname, card->driver);
- sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]);
- if (irq[dev] >= 0) {
- sprintf(card->longname + strlen(card->longname), "irq %d", irq[dev]);
- } else {
- strcat(card->longname, "polled");
- }
-
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0,
- irq[dev], NULL);
- if (err < 0) {
- printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
- goto _err;
- }
-
- *rcard = card;
- return 0;
-
- _err:
- snd_card_free(card);
- return err;
-}
-
-static int __devinit snd_mpu401_probe(struct platform_device *devptr)
-{
- int dev = devptr->id;
- int err;
- struct snd_card *card;
-
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify port\n");
- return -EINVAL;
- }
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- snd_printk(KERN_ERR "specify or disable IRQ\n");
- return -EINVAL;
- }
- err = snd_mpu401_create(dev, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, &devptr->dev);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- platform_set_drvdata(devptr, card);
- return 0;
-}
-
-static int __devexit snd_mpu401_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_MPU401_DRIVER "snd_mpu401"
-
-static struct platform_driver snd_mpu401_driver = {
- .probe = snd_mpu401_probe,
- .remove = __devexit_p(snd_mpu401_remove),
- .driver = {
- .name = SND_MPU401_DRIVER
- },
-};
-
-
-#ifdef CONFIG_PNP
-
-#define IO_EXTENT 2
-
-static struct pnp_device_id snd_mpu401_pnpids[] = {
- { .id = "PNPb006" },
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids);
-
-static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device,
- const struct pnp_device_id *id)
-{
- if (!pnp_port_valid(device, 0) ||
- pnp_port_flags(device, 0) & IORESOURCE_DISABLED) {
- snd_printk(KERN_ERR "no PnP port\n");
- return -ENODEV;
- }
- if (pnp_port_len(device, 0) < IO_EXTENT) {
- snd_printk(KERN_ERR "PnP port length is %llu, expected %d\n",
- (unsigned long long)pnp_port_len(device, 0),
- IO_EXTENT);
- return -ENODEV;
- }
- port[dev] = pnp_port_start(device, 0);
-
- if (!pnp_irq_valid(device, 0) ||
- pnp_irq_flags(device, 0) & IORESOURCE_DISABLED) {
- snd_printk(KERN_WARNING "no PnP irq, using polling\n");
- irq[dev] = -1;
- } else {
- irq[dev] = pnp_irq(device, 0);
- }
- return 0;
-}
-
-static int __devinit snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
- const struct pnp_device_id *id)
-{
- static int dev;
- struct snd_card *card;
- int err;
-
- for ( ; dev < SNDRV_CARDS; ++dev) {
- if (!enable[dev] || !pnp[dev])
- continue;
- err = snd_mpu401_pnp(dev, pnp_dev, id);
- if (err < 0)
- return err;
- err = snd_mpu401_create(dev, &card);
- if (err < 0)
- return err;
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pnp_dev->dev);
- pnp_set_drvdata(pnp_dev, card);
- snd_mpu401_devices++;
- ++dev;
- return 0;
- }
- return -ENODEV;
-}
-
-static void __devexit snd_mpu401_pnp_remove(struct pnp_dev *dev)
-{
- struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev);
-
- snd_card_disconnect(card);
- snd_card_free_when_closed(card);
-}
-
-static struct pnp_driver snd_mpu401_pnp_driver = {
- .name = "mpu401",
- .id_table = snd_mpu401_pnpids,
- .probe = snd_mpu401_pnp_probe,
- .remove = __devexit_p(snd_mpu401_pnp_remove),
-};
-#else
-static struct pnp_driver snd_mpu401_pnp_driver;
-#endif
-
-static void snd_mpu401_unregister_all(void)
-{
- int i;
-
- if (pnp_registered)
- pnp_unregister_driver(&snd_mpu401_pnp_driver);
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_mpu401_driver);
-}
-
-static int __init alsa_card_mpu401_init(void)
-{
- int i, err;
-
- if ((err = platform_driver_register(&snd_mpu401_driver)) < 0)
- return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
-#ifdef CONFIG_PNP
- if (pnp[i])
- continue;
-#endif
- device = platform_device_register_simple(SND_MPU401_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- snd_mpu401_devices++;
- }
- err = pnp_register_driver(&snd_mpu401_pnp_driver);
- if (!err)
- pnp_registered = 1;
-
- if (!snd_mpu401_devices) {
-#ifdef MODULE
- printk(KERN_ERR "MPU-401 device not found or device busy\n");
-#endif
- snd_mpu401_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_mpu401_exit(void)
-{
- snd_mpu401_unregister_all();
-}
-
-module_init(alsa_card_mpu401_init)
-module_exit(alsa_card_mpu401_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c b/ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c
deleted file mode 100644
index 1cff331a..00000000
--- a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of MPU-401 in UART mode
- *
- * MPU-401 supports UART mode which is not capable generate transmit
- * interrupts thus output is done via polling. Without interrupt,
- * input is done also via polling. Do not expect good performance.
- *
- *
- * 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
- *
- * 13-03-2003:
- * Added support for different kind of hardware I/O. Build in choices
- * are port and mmio. For other kind of I/O, set mpu->read and
- * mpu->write to your own I/O functions.
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <sound/core.h>
-#include <sound/mpu401.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for control of MPU-401 in UART mode");
-MODULE_LICENSE("GPL");
-
-static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu);
-static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu);
-
-/*
-
- */
-
-#define snd_mpu401_input_avail(mpu) \
- (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_RX_EMPTY))
-#define snd_mpu401_output_ready(mpu) \
- (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_TX_FULL))
-
-/* Build in lowlevel io */
-static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data,
- unsigned long addr)
-{
- outb(data, addr);
-}
-
-static unsigned char mpu401_read_port(struct snd_mpu401 *mpu,
- unsigned long addr)
-{
- return inb(addr);
-}
-
-static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data,
- unsigned long addr)
-{
- writeb(data, (void __iomem *)addr);
-}
-
-static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu,
- unsigned long addr)
-{
- return readb((void __iomem *)addr);
-}
-/* */
-
-static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
-{
- int timeout = 100000;
- for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--)
- mpu->read(mpu, MPU401D(mpu));
-#ifdef CONFIG_SND_DEBUG
- if (timeout <= 0)
- snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n",
- mpu->read(mpu, MPU401C(mpu)));
-#endif
-}
-
-static void uart_interrupt_tx(struct snd_mpu401 *mpu)
-{
- unsigned long flags;
-
- if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
- test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
- spin_lock_irqsave(&mpu->output_lock, flags);
- snd_mpu401_uart_output_write(mpu);
- spin_unlock_irqrestore(&mpu->output_lock, flags);
- }
-}
-
-static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
-{
- unsigned long flags;
-
- if (mpu->info_flags & MPU401_INFO_INPUT) {
- spin_lock_irqsave(&mpu->input_lock, flags);
- if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
- snd_mpu401_uart_input_read(mpu);
- else
- snd_mpu401_uart_clear_rx(mpu);
- spin_unlock_irqrestore(&mpu->input_lock, flags);
- }
- if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
- /* ok. for better Tx performance try do some output
- when input is done */
- uart_interrupt_tx(mpu);
-}
-
-/**
- * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
- * @irq: the irq number
- * @dev_id: mpu401 instance
- *
- * Processes the interrupt for MPU401-UART i/o.
- */
-irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id)
-{
- struct snd_mpu401 *mpu = dev_id;
-
- if (mpu == NULL)
- return IRQ_NONE;
- _snd_mpu401_uart_interrupt(mpu);
- return IRQ_HANDLED;
-}
-
-EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
-
-/**
- * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler
- * @irq: the irq number
- * @dev_id: mpu401 instance
- *
- * Processes the interrupt for MPU401-UART output.
- */
-irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id)
-{
- struct snd_mpu401 *mpu = dev_id;
-
- if (mpu == NULL)
- return IRQ_NONE;
- uart_interrupt_tx(mpu);
- return IRQ_HANDLED;
-}
-
-EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);
-
-/*
- * timer callback
- * reprogram the timer and call the interrupt job
- */
-static void snd_mpu401_uart_timer(unsigned long data)
-{
- struct snd_mpu401 *mpu = (struct snd_mpu401 *)data;
- unsigned long flags;
-
- spin_lock_irqsave(&mpu->timer_lock, flags);
- /*mpu->mode |= MPU401_MODE_TIMER;*/
- mpu->timer.expires = 1 + jiffies;
- add_timer(&mpu->timer);
- spin_unlock_irqrestore(&mpu->timer_lock, flags);
- if (mpu->rmidi)
- _snd_mpu401_uart_interrupt(mpu);
-}
-
-/*
- * initialize the timer callback if not programmed yet
- */
-static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
-{
- unsigned long flags;
-
- spin_lock_irqsave (&mpu->timer_lock, flags);
- if (mpu->timer_invoked == 0) {
- init_timer(&mpu->timer);
- mpu->timer.data = (unsigned long)mpu;
- mpu->timer.function = snd_mpu401_uart_timer;
- mpu->timer.expires = 1 + jiffies;
- add_timer(&mpu->timer);
- }
- mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :
- MPU401_MODE_OUTPUT_TIMER;
- spin_unlock_irqrestore (&mpu->timer_lock, flags);
-}
-
-/*
- * remove the timer callback if still active
- */
-static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
-{
- unsigned long flags;
-
- spin_lock_irqsave (&mpu->timer_lock, flags);
- if (mpu->timer_invoked) {
- mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER :
- ~MPU401_MODE_OUTPUT_TIMER;
- if (! mpu->timer_invoked)
- del_timer(&mpu->timer);
- }
- spin_unlock_irqrestore (&mpu->timer_lock, flags);
-}
-
-/*
- * send a UART command
- * return zero if successful, non-zero for some errors
- */
-
-static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
- int ack)
-{
- unsigned long flags;
- int timeout, ok;
-
- spin_lock_irqsave(&mpu->input_lock, flags);
- if (mpu->hardware != MPU401_HW_TRID4DWAVE) {
- mpu->write(mpu, 0x00, MPU401D(mpu));
- /*snd_mpu401_uart_clear_rx(mpu);*/
- }
- /* ok. standard MPU-401 initialization */
- if (mpu->hardware != MPU401_HW_SB) {
- for (timeout = 1000; timeout > 0 &&
- !snd_mpu401_output_ready(mpu); timeout--)
- udelay(10);
-#ifdef CONFIG_SND_DEBUG
- if (!timeout)
- snd_printk(KERN_ERR "cmd: tx timeout (status = 0x%x)\n",
- mpu->read(mpu, MPU401C(mpu)));
-#endif
- }
- mpu->write(mpu, cmd, MPU401C(mpu));
- if (ack && !(mpu->info_flags & MPU401_INFO_NO_ACK)) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (snd_mpu401_input_avail(mpu)) {
- if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
- ok = 1;
- }
- }
- if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
- ok = 1;
- } else
- ok = 1;
- spin_unlock_irqrestore(&mpu->input_lock, flags);
- if (!ok) {
- snd_printk(KERN_ERR "cmd: 0x%x failed at 0x%lx "
- "(status = 0x%x, data = 0x%x)\n", cmd, mpu->port,
- mpu->read(mpu, MPU401C(mpu)),
- mpu->read(mpu, MPU401D(mpu)));
- return 1;
- }
- return 0;
-}
-
-static int snd_mpu401_do_reset(struct snd_mpu401 *mpu)
-{
- if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
- return -EIO;
- if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 0))
- return -EIO;
- return 0;
-}
-
-/*
- * input/output open/close - protected by open_mutex in rawmidi.c
- */
-static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err;
-
- mpu = substream->rmidi->private_data;
- if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
- return err;
- if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
- if (snd_mpu401_do_reset(mpu) < 0)
- goto error_out;
- }
- mpu->substream_input = substream;
- set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
- return 0;
-
-error_out:
- if (mpu->open_input && mpu->close_input)
- mpu->close_input(mpu);
- return -EIO;
-}
-
-static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err;
-
- mpu = substream->rmidi->private_data;
- if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
- return err;
- if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
- if (snd_mpu401_do_reset(mpu) < 0)
- goto error_out;
- }
- mpu->substream_output = substream;
- set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
- return 0;
-
-error_out:
- if (mpu->open_output && mpu->close_output)
- mpu->close_output(mpu);
- return -EIO;
-}
-
-static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err = 0;
-
- mpu = substream->rmidi->private_data;
- clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
- mpu->substream_input = NULL;
- if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode))
- err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
- if (mpu->close_input)
- mpu->close_input(mpu);
- if (err)
- return -EIO;
- return 0;
-}
-
-static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err = 0;
-
- mpu = substream->rmidi->private_data;
- clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
- mpu->substream_output = NULL;
- if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
- err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
- if (mpu->close_output)
- mpu->close_output(mpu);
- if (err)
- return -EIO;
- return 0;
-}
-
-/*
- * trigger input callback
- */
-static void
-snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_mpu401 *mpu;
- int max = 64;
-
- mpu = substream->rmidi->private_data;
- if (up) {
- if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER,
- &mpu->mode)) {
- /* first time - flush FIFO */
- while (max-- > 0)
- mpu->read(mpu, MPU401D(mpu));
- if (mpu->info_flags & MPU401_INFO_USE_TIMER)
- snd_mpu401_uart_add_timer(mpu, 1);
- }
-
- /* read data in advance */
- spin_lock_irqsave(&mpu->input_lock, flags);
- snd_mpu401_uart_input_read(mpu);
- spin_unlock_irqrestore(&mpu->input_lock, flags);
- } else {
- if (mpu->info_flags & MPU401_INFO_USE_TIMER)
- snd_mpu401_uart_remove_timer(mpu, 1);
- clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
- }
-
-}
-
-/*
- * transfer input pending data
- * call with input_lock spinlock held
- */
-static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu)
-{
- int max = 128;
- unsigned char byte;
-
- while (max-- > 0) {
- if (! snd_mpu401_input_avail(mpu))
- break; /* input not available */
- byte = mpu->read(mpu, MPU401D(mpu));
- if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
- snd_rawmidi_receive(mpu->substream_input, &byte, 1);
- }
-}
-
-/*
- * Tx FIFO sizes:
- * CS4237B - 16 bytes
- * AudioDrive ES1688 - 12 bytes
- * S3 SonicVibes - 8 bytes
- * SoundBlaster AWE 64 - 2 bytes (ugly hardware)
- */
-
-/*
- * write output pending bytes
- * call with output_lock spinlock held
- */
-static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
-{
- unsigned char byte;
- int max = 256;
-
- do {
- if (snd_rawmidi_transmit_peek(mpu->substream_output,
- &byte, 1) == 1) {
- /*
- * Try twice because there is hardware that insists on
- * setting the output busy bit after each write.
- */
- if (!snd_mpu401_output_ready(mpu) &&
- !snd_mpu401_output_ready(mpu))
- break; /* Tx FIFO full - try again later */
- mpu->write(mpu, byte, MPU401D(mpu));
- snd_rawmidi_transmit_ack(mpu->substream_output, 1);
- } else {
- snd_mpu401_uart_remove_timer (mpu, 0);
- break; /* no other data - leave the tx loop */
- }
- } while (--max > 0);
-}
-
-/*
- * output trigger callback
- */
-static void
-snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_mpu401 *mpu;
-
- mpu = substream->rmidi->private_data;
- if (up) {
- set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
-
- /* try to add the timer at each output trigger,
- * since the output timer might have been removed in
- * snd_mpu401_uart_output_write().
- */
- if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
- snd_mpu401_uart_add_timer(mpu, 0);
-
- /* output pending data */
- spin_lock_irqsave(&mpu->output_lock, flags);
- snd_mpu401_uart_output_write(mpu);
- spin_unlock_irqrestore(&mpu->output_lock, flags);
- } else {
- if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
- snd_mpu401_uart_remove_timer(mpu, 0);
- clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
- }
-}
-
-/*
-
- */
-
-static struct snd_rawmidi_ops snd_mpu401_uart_output =
-{
- .open = snd_mpu401_uart_output_open,
- .close = snd_mpu401_uart_output_close,
- .trigger = snd_mpu401_uart_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_mpu401_uart_input =
-{
- .open = snd_mpu401_uart_input_open,
- .close = snd_mpu401_uart_input_close,
- .trigger = snd_mpu401_uart_input_trigger,
-};
-
-static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
-{
- struct snd_mpu401 *mpu = rmidi->private_data;
- if (mpu->irq >= 0)
- free_irq(mpu->irq, (void *) mpu);
- release_and_free_resource(mpu->res);
- kfree(mpu);
-}
-
-/**
- * snd_mpu401_uart_new - create an MPU401-UART instance
- * @card: the card instance
- * @device: the device index, zero-based
- * @hardware: the hardware type, MPU401_HW_XXXX
- * @port: the base address of MPU401 port
- * @info_flags: bitflags MPU401_INFO_XXX
- * @irq: the ISA irq number, -1 if not to be allocated
- * @rrawmidi: the pointer to store the new rawmidi instance
- *
- * Creates a new MPU-401 instance.
- *
- * Note that the rawmidi instance is returned on the rrawmidi argument,
- * not the mpu401 instance itself. To access to the mpu401 instance,
- * cast from rawmidi->private_data (with struct snd_mpu401 magic-cast).
- *
- * Returns zero if successful, or a negative error code.
- */
-int snd_mpu401_uart_new(struct snd_card *card, int device,
- unsigned short hardware,
- unsigned long port,
- unsigned int info_flags,
- int irq,
- struct snd_rawmidi ** rrawmidi)
-{
- struct snd_mpu401 *mpu;
- struct snd_rawmidi *rmidi;
- int in_enable, out_enable;
- int err;
-
- if (rrawmidi)
- *rrawmidi = NULL;
- if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT)))
- info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT;
- in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0;
- out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0;
- if ((err = snd_rawmidi_new(card, "MPU-401U", device,
- out_enable, in_enable, &rmidi)) < 0)
- return err;
- mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
- if (mpu == NULL) {
- snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n");
- snd_device_free(card, rmidi);
- return -ENOMEM;
- }
- rmidi->private_data = mpu;
- rmidi->private_free = snd_mpu401_uart_free;
- spin_lock_init(&mpu->input_lock);
- spin_lock_init(&mpu->output_lock);
- spin_lock_init(&mpu->timer_lock);
- mpu->hardware = hardware;
- if (! (info_flags & MPU401_INFO_INTEGRATED)) {
- int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
- mpu->res = request_region(port, res_size, "MPU401 UART");
- if (mpu->res == NULL) {
- snd_printk(KERN_ERR "mpu401_uart: "
- "unable to grab port 0x%lx size %d\n",
- port, res_size);
- snd_device_free(card, rmidi);
- return -EBUSY;
- }
- }
- if (info_flags & MPU401_INFO_MMIO) {
- mpu->write = mpu401_write_mmio;
- mpu->read = mpu401_read_mmio;
- } else {
- mpu->write = mpu401_write_port;
- mpu->read = mpu401_read_port;
- }
- mpu->port = port;
- if (hardware == MPU401_HW_PC98II)
- mpu->cport = port + 2;
- else
- mpu->cport = port + 1;
- if (irq >= 0) {
- if (request_irq(irq, snd_mpu401_uart_interrupt, 0,
- "MPU401 UART", (void *) mpu)) {
- snd_printk(KERN_ERR "mpu401_uart: "
- "unable to grab IRQ %d\n", irq);
- snd_device_free(card, rmidi);
- return -EBUSY;
- }
- }
- if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK))
- info_flags |= MPU401_INFO_USE_TIMER;
- mpu->info_flags = info_flags;
- mpu->irq = irq;
- if (card->shortname[0])
- snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
- card->shortname);
- else
- sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device);
- if (out_enable) {
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_mpu401_uart_output);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
- }
- if (in_enable) {
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_mpu401_uart_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
- if (out_enable)
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
- }
- mpu->rmidi = rmidi;
- if (rrawmidi)
- *rrawmidi = rmidi;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_mpu401_uart_new);
-
-/*
- * INIT part
- */
-
-static int __init alsa_mpu401_uart_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_mpu401_uart_exit(void)
-{
-}
-
-module_init(alsa_mpu401_uart_init)
-module_exit(alsa_mpu401_uart_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/mtpav.c b/ANDROID_3.4.5/sound/drivers/mtpav.c
deleted file mode 100644
index 76930793..00000000
--- a/ANDROID_3.4.5/sound/drivers/mtpav.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * MOTU Midi Timepiece ALSA Main routines
- * Copyright by Michael T. Mayers (c) Jan 09, 2000
- * mail: michael@tweakoz.com
- * Thanks to John Galbraith
- *
- * 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
- *
- *
- * This driver is for the 'Mark Of The Unicorn' (MOTU)
- * MidiTimePiece AV multiport MIDI interface
- *
- * IOPORTS
- * -------
- * 8 MIDI Ins and 8 MIDI outs
- * Video Sync In (BNC), Word Sync Out (BNC),
- * ADAT Sync Out (DB9)
- * SMPTE in/out (1/4")
- * 2 programmable pedal/footswitch inputs and 4 programmable MIDI controller knobs.
- * Macintosh RS422 serial port
- * RS422 "network" port for ganging multiple MTP's
- * PC Parallel Port ( which this driver currently uses )
- *
- * MISC FEATURES
- * -------------
- * Hardware MIDI routing, merging, and filtering
- * MIDI Synchronization to Video, ADAT, SMPTE and other Clock sources
- * 128 'scene' memories, recallable from MIDI program change
- *
- *
- * ChangeLog
- * Jun 11 2001 Takashi Iwai <tiwai@suse.de>
- * - Recoded & debugged
- * - Added timer interrupt for midi outputs
- * - hwports is between 1 and 8, which specifies the number of hardware ports.
- * The three global ports, computer, adat and broadcast ports, are created
- * always after h/w and remote ports.
- *
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <linux/delay.h>
-
-/*
- * globals
- */
-MODULE_AUTHOR("Michael T. Mayers");
-MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{MOTU,MidiTimePiece AV multiport MIDI}}");
-
-// io resources
-#define MTPAV_IOBASE 0x378
-#define MTPAV_IRQ 7
-#define MTPAV_MAX_PORTS 8
-
-static int index = SNDRV_DEFAULT_IDX1;
-static char *id = SNDRV_DEFAULT_STR1;
-static long port = MTPAV_IOBASE; /* 0x378, 0x278 */
-static int irq = MTPAV_IRQ; /* 7, 5 */
-static int hwports = MTPAV_MAX_PORTS; /* use hardware ports 1-8 */
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for MotuMTPAV MIDI.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for MotuMTPAV MIDI.");
-module_param(port, long, 0444);
-MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
-module_param(irq, int, 0444);
-MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
-module_param(hwports, int, 0444);
-MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
-
-static struct platform_device *device;
-
-/*
- * defines
- */
-//#define USE_FAKE_MTP // don't actually read/write to MTP device (for debugging without an actual unit) (does not work yet)
-
-// parallel port usage masks
-#define SIGS_BYTE 0x08
-#define SIGS_RFD 0x80
-#define SIGS_IRQ 0x40
-#define SIGS_IN0 0x10
-#define SIGS_IN1 0x20
-
-#define SIGC_WRITE 0x04
-#define SIGC_READ 0x08
-#define SIGC_INTEN 0x10
-
-#define DREG 0
-#define SREG 1
-#define CREG 2
-
-//
-#define MTPAV_MODE_INPUT_OPENED 0x01
-#define MTPAV_MODE_OUTPUT_OPENED 0x02
-#define MTPAV_MODE_INPUT_TRIGGERED 0x04
-#define MTPAV_MODE_OUTPUT_TRIGGERED 0x08
-
-#define NUMPORTS (0x12+1)
-
-
-/*
- */
-
-struct mtpav_port {
- u8 number;
- u8 hwport;
- u8 mode;
- u8 running_status;
- struct snd_rawmidi_substream *input;
- struct snd_rawmidi_substream *output;
-};
-
-struct mtpav {
- struct snd_card *card;
- unsigned long port;
- struct resource *res_port;
- int irq; /* interrupt (for inputs) */
- spinlock_t spinlock;
- int share_irq; /* number of accesses to input interrupts */
- int istimer; /* number of accesses to timer interrupts */
- struct timer_list timer; /* timer interrupts for outputs */
- struct snd_rawmidi *rmidi;
- int num_ports; /* number of hw ports (1-8) */
- struct mtpav_port ports[NUMPORTS]; /* all ports including computer, adat and bc */
-
- u32 inmidiport; /* selected input midi port */
- u32 inmidistate; /* during midi command 0xf5 */
-
- u32 outmidihwport; /* selected output midi hw port */
-};
-
-
-/*
- * possible hardware ports (selected by 0xf5 port message)
- * 0x00 all ports
- * 0x01 .. 0x08 this MTP's ports 1..8
- * 0x09 .. 0x10 networked MTP's ports (9..16)
- * 0x11 networked MTP's computer port
- * 0x63 to ADAT
- *
- * mappig:
- * subdevice 0 - (X-1) ports
- * X - (2*X-1) networked ports
- * X computer
- * X+1 ADAT
- * X+2 all ports
- *
- * where X = chip->num_ports
- */
-
-#define MTPAV_PIDX_COMPUTER 0
-#define MTPAV_PIDX_ADAT 1
-#define MTPAV_PIDX_BROADCAST 2
-
-
-static int translate_subdevice_to_hwport(struct mtpav *chip, int subdev)
-{
- if (subdev < 0)
- return 0x01; /* invalid - use port 0 as default */
- else if (subdev < chip->num_ports)
- return subdev + 1; /* single mtp port */
- else if (subdev < chip->num_ports * 2)
- return subdev - chip->num_ports + 0x09; /* remote port */
- else if (subdev == chip->num_ports * 2 + MTPAV_PIDX_COMPUTER)
- return 0x11; /* computer port */
- else if (subdev == chip->num_ports + MTPAV_PIDX_ADAT)
- return 0x63; /* ADAT */
- return 0; /* all ports */
-}
-
-static int translate_hwport_to_subdevice(struct mtpav *chip, int hwport)
-{
- int p;
- if (hwport <= 0x00) /* all ports */
- return chip->num_ports + MTPAV_PIDX_BROADCAST;
- else if (hwport <= 0x08) { /* single port */
- p = hwport - 1;
- if (p >= chip->num_ports)
- p = 0;
- return p;
- } else if (hwport <= 0x10) { /* remote port */
- p = hwport - 0x09 + chip->num_ports;
- if (p >= chip->num_ports * 2)
- p = chip->num_ports;
- return p;
- } else if (hwport == 0x11) /* computer port */
- return chip->num_ports + MTPAV_PIDX_COMPUTER;
- else /* ADAT */
- return chip->num_ports + MTPAV_PIDX_ADAT;
-}
-
-
-/*
- */
-
-static u8 snd_mtpav_getreg(struct mtpav *chip, u16 reg)
-{
- u8 rval = 0;
-
- if (reg == SREG) {
- rval = inb(chip->port + SREG);
- rval = (rval & 0xf8);
- } else if (reg == CREG) {
- rval = inb(chip->port + CREG);
- rval = (rval & 0x1c);
- }
-
- return rval;
-}
-
-/*
- */
-
-static inline void snd_mtpav_mputreg(struct mtpav *chip, u16 reg, u8 val)
-{
- if (reg == DREG || reg == CREG)
- outb(val, chip->port + reg);
-}
-
-/*
- */
-
-static void snd_mtpav_wait_rfdhi(struct mtpav *chip)
-{
- int counts = 10000;
- u8 sbyte;
-
- sbyte = snd_mtpav_getreg(chip, SREG);
- while (!(sbyte & SIGS_RFD) && counts--) {
- sbyte = snd_mtpav_getreg(chip, SREG);
- udelay(10);
- }
-}
-
-static void snd_mtpav_send_byte(struct mtpav *chip, u8 byte)
-{
- u8 tcbyt;
- u8 clrwrite;
- u8 setwrite;
-
- snd_mtpav_wait_rfdhi(chip);
-
- /////////////////
-
- tcbyt = snd_mtpav_getreg(chip, CREG);
- clrwrite = tcbyt & (SIGC_WRITE ^ 0xff);
- setwrite = tcbyt | SIGC_WRITE;
-
- snd_mtpav_mputreg(chip, DREG, byte);
- snd_mtpav_mputreg(chip, CREG, clrwrite); // clear write bit
-
- snd_mtpav_mputreg(chip, CREG, setwrite); // set write bit
-
-}
-
-
-/*
- */
-
-/* call this with spin lock held */
-static void snd_mtpav_output_port_write(struct mtpav *mtp_card,
- struct mtpav_port *portp,
- struct snd_rawmidi_substream *substream)
-{
- u8 outbyte;
-
- // Get the outbyte first, so we can emulate running status if
- // necessary
- if (snd_rawmidi_transmit(substream, &outbyte, 1) != 1)
- return;
-
- // send port change command if necessary
-
- if (portp->hwport != mtp_card->outmidihwport) {
- mtp_card->outmidihwport = portp->hwport;
-
- snd_mtpav_send_byte(mtp_card, 0xf5);
- snd_mtpav_send_byte(mtp_card, portp->hwport);
- /*
- snd_printk(KERN_DEBUG "new outport: 0x%x\n",
- (unsigned int) portp->hwport);
- */
- if (!(outbyte & 0x80) && portp->running_status)
- snd_mtpav_send_byte(mtp_card, portp->running_status);
- }
-
- // send data
-
- do {
- if (outbyte & 0x80)
- portp->running_status = outbyte;
-
- snd_mtpav_send_byte(mtp_card, outbyte);
- } while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1);
-}
-
-static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- snd_mtpav_output_port_write(mtp_card, portp, substream);
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
-}
-
-
-/*
- * mtpav control
- */
-
-static void snd_mtpav_portscan(struct mtpav *chip) // put mtp into smart routing mode
-{
- u8 p;
-
- for (p = 0; p < 8; p++) {
- snd_mtpav_send_byte(chip, 0xf5);
- snd_mtpav_send_byte(chip, p);
- snd_mtpav_send_byte(chip, 0xfe);
- }
-}
-
-/*
- */
-
-static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode |= MTPAV_MODE_INPUT_OPENED;
- portp->input = substream;
- if (mtp_card->share_irq++ == 0)
- snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-}
-
-/*
- */
-
-static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
- portp->input = NULL;
- if (--mtp_card->share_irq == 0)
- snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-}
-
-/*
- */
-
-static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- if (up)
- portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
- else
- portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
-
-}
-
-
-/*
- * timer interrupt for outputs
- */
-
-static void snd_mtpav_output_timer(unsigned long data)
-{
- unsigned long flags;
- struct mtpav *chip = (struct mtpav *)data;
- int p;
-
- spin_lock_irqsave(&chip->spinlock, flags);
- /* reprogram timer */
- chip->timer.expires = 1 + jiffies;
- add_timer(&chip->timer);
- /* process each port */
- for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
- struct mtpav_port *portp = &chip->ports[p];
- if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
- snd_mtpav_output_port_write(chip, portp, portp->output);
- }
- spin_unlock_irqrestore(&chip->spinlock, flags);
-}
-
-/* spinlock held! */
-static void snd_mtpav_add_output_timer(struct mtpav *chip)
-{
- chip->timer.expires = 1 + jiffies;
- add_timer(&chip->timer);
-}
-
-/* spinlock held! */
-static void snd_mtpav_remove_output_timer(struct mtpav *chip)
-{
- del_timer(&chip->timer);
-}
-
-/*
- */
-
-static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
- portp->output = substream;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-};
-
-/*
- */
-
-static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
- portp->output = NULL;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-};
-
-/*
- */
-
-static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- if (up) {
- if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
- if (mtp_card->istimer++ == 0)
- snd_mtpav_add_output_timer(mtp_card);
- portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
- }
- } else {
- portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
- if (--mtp_card->istimer == 0)
- snd_mtpav_remove_output_timer(mtp_card);
- }
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
-
- if (up)
- snd_mtpav_output_write(substream);
-}
-
-/*
- * midi interrupt for inputs
- */
-
-static void snd_mtpav_inmidi_process(struct mtpav *mcrd, u8 inbyte)
-{
- struct mtpav_port *portp;
-
- if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
- return;
-
- portp = &mcrd->ports[mcrd->inmidiport];
- if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(portp->input, &inbyte, 1);
-}
-
-static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
-{
- if (inbyte >= 0xf8) {
- /* real-time midi code */
- snd_mtpav_inmidi_process(mcrd, inbyte);
- return;
- }
-
- if (mcrd->inmidistate == 0) { // awaiting command
- if (inbyte == 0xf5) // MTP port #
- mcrd->inmidistate = 1;
- else
- snd_mtpav_inmidi_process(mcrd, inbyte);
- } else if (mcrd->inmidistate) {
- mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte);
- mcrd->inmidistate = 0;
- }
-}
-
-static void snd_mtpav_read_bytes(struct mtpav *mcrd)
-{
- u8 clrread, setread;
- u8 mtp_read_byte;
- u8 sr, cbyt;
- int i;
-
- u8 sbyt = snd_mtpav_getreg(mcrd, SREG);
-
- /* printk(KERN_DEBUG "snd_mtpav_read_bytes() sbyt: 0x%x\n", sbyt); */
-
- if (!(sbyt & SIGS_BYTE))
- return;
-
- cbyt = snd_mtpav_getreg(mcrd, CREG);
- clrread = cbyt & (SIGC_READ ^ 0xff);
- setread = cbyt | SIGC_READ;
-
- do {
-
- mtp_read_byte = 0;
- for (i = 0; i < 4; i++) {
- snd_mtpav_mputreg(mcrd, CREG, setread);
- sr = snd_mtpav_getreg(mcrd, SREG);
- snd_mtpav_mputreg(mcrd, CREG, clrread);
-
- sr &= SIGS_IN0 | SIGS_IN1;
- sr >>= 4;
- mtp_read_byte |= sr << (i * 2);
- }
-
- snd_mtpav_inmidi_h(mcrd, mtp_read_byte);
-
- sbyt = snd_mtpav_getreg(mcrd, SREG);
-
- } while (sbyt & SIGS_BYTE);
-}
-
-static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
-{
- struct mtpav *mcard = dev_id;
-
- spin_lock(&mcard->spinlock);
- snd_mtpav_read_bytes(mcard);
- spin_unlock(&mcard->spinlock);
- return IRQ_HANDLED;
-}
-
-/*
- * get ISA resources
- */
-static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard)
-{
- if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
- snd_printk(KERN_ERR "MTVAP port 0x%lx is busy\n", port);
- return -EBUSY;
- }
- mcard->port = port;
- if (request_irq(irq, snd_mtpav_irqh, 0, "MOTU MTPAV", mcard)) {
- snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq);
- return -EBUSY;
- }
- mcard->irq = irq;
- return 0;
-}
-
-
-/*
- */
-
-static struct snd_rawmidi_ops snd_mtpav_output = {
- .open = snd_mtpav_output_open,
- .close = snd_mtpav_output_close,
- .trigger = snd_mtpav_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_mtpav_input = {
- .open = snd_mtpav_input_open,
- .close = snd_mtpav_input_close,
- .trigger = snd_mtpav_input_trigger,
-};
-
-
-/*
- * get RAWMIDI resources
- */
-
-static void __devinit snd_mtpav_set_name(struct mtpav *chip,
- struct snd_rawmidi_substream *substream)
-{
- if (substream->number >= 0 && substream->number < chip->num_ports)
- sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
- else if (substream->number >= 8 && substream->number < chip->num_ports * 2)
- sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1);
- else if (substream->number == chip->num_ports * 2)
- strcpy(substream->name, "MTP computer");
- else if (substream->number == chip->num_ports * 2 + 1)
- strcpy(substream->name, "MTP ADAT");
- else
- strcpy(substream->name, "MTP broadcast");
-}
-
-static int __devinit snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
-{
- int rval;
- struct snd_rawmidi *rawmidi;
- struct snd_rawmidi_substream *substream;
- struct list_head *list;
-
- if (hwports < 1)
- hwports = 1;
- else if (hwports > 8)
- hwports = 8;
- mcard->num_ports = hwports;
-
- if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
- mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
- mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
- &mcard->rmidi)) < 0)
- return rval;
- rawmidi = mcard->rmidi;
- rawmidi->private_data = mcard;
-
- list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- snd_mtpav_set_name(mcard, substream);
- substream->ops = &snd_mtpav_input;
- }
- list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- snd_mtpav_set_name(mcard, substream);
- substream->ops = &snd_mtpav_output;
- mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number);
- }
- rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- sprintf(rawmidi->name, "MTP AV MIDI");
- return 0;
-}
-
-/*
- */
-
-static void snd_mtpav_free(struct snd_card *card)
-{
- struct mtpav *crd = card->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&crd->spinlock, flags);
- if (crd->istimer > 0)
- snd_mtpav_remove_output_timer(crd);
- spin_unlock_irqrestore(&crd->spinlock, flags);
- if (crd->irq >= 0)
- free_irq(crd->irq, (void *)crd);
- release_and_free_resource(crd->res_port);
-}
-
-/*
- */
-static int __devinit snd_mtpav_probe(struct platform_device *dev)
-{
- struct snd_card *card;
- int err;
- struct mtpav *mtp_card;
-
- err = snd_card_create(index, id, THIS_MODULE, sizeof(*mtp_card), &card);
- if (err < 0)
- return err;
-
- mtp_card = card->private_data;
- spin_lock_init(&mtp_card->spinlock);
- init_timer(&mtp_card->timer);
- mtp_card->card = card;
- mtp_card->irq = -1;
- mtp_card->share_irq = 0;
- mtp_card->inmidistate = 0;
- mtp_card->outmidihwport = 0xffffffff;
- init_timer(&mtp_card->timer);
- mtp_card->timer.function = snd_mtpav_output_timer;
- mtp_card->timer.data = (unsigned long) mtp_card;
-
- card->private_free = snd_mtpav_free;
-
- err = snd_mtpav_get_RAWMIDI(mtp_card);
- if (err < 0)
- goto __error;
-
- mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST;
-
- err = snd_mtpav_get_ISA(mtp_card);
- if (err < 0)
- goto __error;
-
- strcpy(card->driver, "MTPAV");
- strcpy(card->shortname, "MTPAV on parallel port");
- snprintf(card->longname, sizeof(card->longname),
- "MTPAV on parallel port at 0x%lx", port);
-
- snd_mtpav_portscan(mtp_card);
-
- snd_card_set_dev(card, &dev->dev);
- err = snd_card_register(mtp_card->card);
- if (err < 0)
- goto __error;
-
- platform_set_drvdata(dev, card);
- printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
- return 0;
-
- __error:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_mtpav_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_MTPAV_DRIVER "snd_mtpav"
-
-static struct platform_driver snd_mtpav_driver = {
- .probe = snd_mtpav_probe,
- .remove = __devexit_p(snd_mtpav_remove),
- .driver = {
- .name = SND_MTPAV_DRIVER
- },
-};
-
-static int __init alsa_card_mtpav_init(void)
-{
- int err;
-
- if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
- return err;
-
- device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
- if (!IS_ERR(device)) {
- if (platform_get_drvdata(device))
- return 0;
- platform_device_unregister(device);
- err = -ENODEV;
- } else
- err = PTR_ERR(device);
- platform_driver_unregister(&snd_mtpav_driver);
- return err;
-}
-
-static void __exit alsa_card_mtpav_exit(void)
-{
- platform_device_unregister(device);
- platform_driver_unregister(&snd_mtpav_driver);
-}
-
-module_init(alsa_card_mtpav_init)
-module_exit(alsa_card_mtpav_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/mts64.c b/ANDROID_3.4.5/sound/drivers/mts64.c
deleted file mode 100644
index 621e60e2..00000000
--- a/ANDROID_3.4.5/sound/drivers/mts64.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * ALSA Driver for Ego Systems Inc. (ESI) Miditerminal 4140
- * Copyright (c) 2006 by Matthias König <mk@phasorlab.de>
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/parport.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <sound/control.h>
-
-#define CARD_NAME "Miditerminal 4140"
-#define DRIVER_NAME "MTS64"
-#define PLATFORM_DRIVER "snd_mts64"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int device_count;
-
-module_param_array(index, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, S_IRUGO);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, S_IRUGO);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-
-MODULE_AUTHOR("Matthias Koenig <mk@phasorlab.de>");
-MODULE_DESCRIPTION("ESI Miditerminal 4140");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESI,Miditerminal 4140}}");
-
-/*********************************************************************
- * Chip specific
- *********************************************************************/
-#define MTS64_NUM_INPUT_PORTS 5
-#define MTS64_NUM_OUTPUT_PORTS 4
-#define MTS64_SMPTE_SUBSTREAM 4
-
-struct mts64 {
- spinlock_t lock;
- struct snd_card *card;
- struct snd_rawmidi *rmidi;
- struct pardevice *pardev;
- int pardev_claimed;
-
- int open_count;
- int current_midi_output_port;
- int current_midi_input_port;
- u8 mode[MTS64_NUM_INPUT_PORTS];
- struct snd_rawmidi_substream *midi_input_substream[MTS64_NUM_INPUT_PORTS];
- int smpte_switch;
- u8 time[4]; /* [0]=hh, [1]=mm, [2]=ss, [3]=ff */
- u8 fps;
-};
-
-static int snd_mts64_free(struct mts64 *mts)
-{
- kfree(mts);
- return 0;
-}
-
-static int __devinit snd_mts64_create(struct snd_card *card,
- struct pardevice *pardev,
- struct mts64 **rchip)
-{
- struct mts64 *mts;
-
- *rchip = NULL;
-
- mts = kzalloc(sizeof(struct mts64), GFP_KERNEL);
- if (mts == NULL)
- return -ENOMEM;
-
- /* Init chip specific data */
- spin_lock_init(&mts->lock);
- mts->card = card;
- mts->pardev = pardev;
- mts->current_midi_output_port = -1;
- mts->current_midi_input_port = -1;
-
- *rchip = mts;
-
- return 0;
-}
-
-/*********************************************************************
- * HW register related constants
- *********************************************************************/
-
-/* Status Bits */
-#define MTS64_STAT_BSY 0x80
-#define MTS64_STAT_BIT_SET 0x20 /* readout process, bit is set */
-#define MTS64_STAT_PORT 0x10 /* read byte is a port number */
-
-/* Control Bits */
-#define MTS64_CTL_READOUT 0x08 /* enable readout */
-#define MTS64_CTL_WRITE_CMD 0x06
-#define MTS64_CTL_WRITE_DATA 0x02
-#define MTS64_CTL_STROBE 0x01
-
-/* Command */
-#define MTS64_CMD_RESET 0xfe
-#define MTS64_CMD_PROBE 0x8f /* Used in probing procedure */
-#define MTS64_CMD_SMPTE_SET_TIME 0xe8
-#define MTS64_CMD_SMPTE_SET_FPS 0xee
-#define MTS64_CMD_SMPTE_STOP 0xef
-#define MTS64_CMD_SMPTE_FPS_24 0xe3
-#define MTS64_CMD_SMPTE_FPS_25 0xe2
-#define MTS64_CMD_SMPTE_FPS_2997 0xe4
-#define MTS64_CMD_SMPTE_FPS_30D 0xe1
-#define MTS64_CMD_SMPTE_FPS_30 0xe0
-#define MTS64_CMD_COM_OPEN 0xf8 /* setting the communication mode */
-#define MTS64_CMD_COM_CLOSE1 0xff /* clearing communication mode */
-#define MTS64_CMD_COM_CLOSE2 0xf5
-
-/*********************************************************************
- * Hardware specific functions
- *********************************************************************/
-static void mts64_enable_readout(struct parport *p);
-static void mts64_disable_readout(struct parport *p);
-static int mts64_device_ready(struct parport *p);
-static int mts64_device_init(struct parport *p);
-static int mts64_device_open(struct mts64 *mts);
-static int mts64_device_close(struct mts64 *mts);
-static u8 mts64_map_midi_input(u8 c);
-static int mts64_probe(struct parport *p);
-static u16 mts64_read(struct parport *p);
-static u8 mts64_read_char(struct parport *p);
-static void mts64_smpte_start(struct parport *p,
- u8 hours, u8 minutes,
- u8 seconds, u8 frames,
- u8 idx);
-static void mts64_smpte_stop(struct parport *p);
-static void mts64_write_command(struct parport *p, u8 c);
-static void mts64_write_data(struct parport *p, u8 c);
-static void mts64_write_midi(struct mts64 *mts, u8 c, int midiport);
-
-
-/* Enables the readout procedure
- *
- * Before we can read a midi byte from the device, we have to set
- * bit 3 of control port.
- */
-static void mts64_enable_readout(struct parport *p)
-{
- u8 c;
-
- c = parport_read_control(p);
- c |= MTS64_CTL_READOUT;
- parport_write_control(p, c);
-}
-
-/* Disables readout
- *
- * Readout is disabled by clearing bit 3 of control
- */
-static void mts64_disable_readout(struct parport *p)
-{
- u8 c;
-
- c = parport_read_control(p);
- c &= ~MTS64_CTL_READOUT;
- parport_write_control(p, c);
-}
-
-/* waits for device ready
- *
- * Checks if BUSY (Bit 7 of status) is clear
- * 1 device ready
- * 0 failure
- */
-static int mts64_device_ready(struct parport *p)
-{
- int i;
- u8 c;
-
- for (i = 0; i < 0xffff; ++i) {
- c = parport_read_status(p);
- c &= MTS64_STAT_BSY;
- if (c != 0)
- return 1;
- }
-
- return 0;
-}
-
-/* Init device (LED blinking startup magic)
- *
- * Returns:
- * 0 init ok
- * -EIO failure
- */
-static int __devinit mts64_device_init(struct parport *p)
-{
- int i;
-
- mts64_write_command(p, MTS64_CMD_RESET);
-
- for (i = 0; i < 64; ++i) {
- msleep(100);
-
- if (mts64_probe(p) == 0) {
- /* success */
- mts64_disable_readout(p);
- return 0;
- }
- }
- mts64_disable_readout(p);
-
- return -EIO;
-}
-
-/*
- * Opens the device (set communication mode)
- */
-static int mts64_device_open(struct mts64 *mts)
-{
- int i;
- struct parport *p = mts->pardev->port;
-
- for (i = 0; i < 5; ++i)
- mts64_write_command(p, MTS64_CMD_COM_OPEN);
-
- return 0;
-}
-
-/*
- * Close device (clear communication mode)
- */
-static int mts64_device_close(struct mts64 *mts)
-{
- int i;
- struct parport *p = mts->pardev->port;
-
- for (i = 0; i < 5; ++i) {
- mts64_write_command(p, MTS64_CMD_COM_CLOSE1);
- mts64_write_command(p, MTS64_CMD_COM_CLOSE2);
- }
-
- return 0;
-}
-
-/* map hardware port to substream number
- *
- * When reading a byte from the device, the device tells us
- * on what port the byte is. This HW port has to be mapped to
- * the midiport (substream number).
- * substream 0-3 are Midiports 1-4
- * substream 4 is SMPTE Timecode
- * The mapping is done by the table:
- * HW | 0 | 1 | 2 | 3 | 4
- * SW | 0 | 1 | 4 | 2 | 3
- */
-static u8 mts64_map_midi_input(u8 c)
-{
- static u8 map[] = { 0, 1, 4, 2, 3 };
-
- return map[c];
-}
-
-
-/* Probe parport for device
- *
- * Do we have a Miditerminal 4140 on parport?
- * Returns:
- * 0 device found
- * -ENODEV no device
- */
-static int __devinit mts64_probe(struct parport *p)
-{
- u8 c;
-
- mts64_smpte_stop(p);
- mts64_write_command(p, MTS64_CMD_PROBE);
-
- msleep(50);
-
- c = mts64_read(p);
-
- c &= 0x00ff;
- if (c != MTS64_CMD_PROBE)
- return -ENODEV;
- else
- return 0;
-
-}
-
-/* Read byte incl. status from device
- *
- * Returns:
- * data in lower 8 bits and status in upper 8 bits
- */
-static u16 mts64_read(struct parport *p)
-{
- u8 data, status;
-
- mts64_device_ready(p);
- mts64_enable_readout(p);
- status = parport_read_status(p);
- data = mts64_read_char(p);
- mts64_disable_readout(p);
-
- return (status << 8) | data;
-}
-
-/* Read a byte from device
- *
- * Note, that readout mode has to be enabled.
- * readout procedure is as follows:
- * - Write number of the Bit to read to DATA
- * - Read STATUS
- * - Bit 5 of STATUS indicates if Bit is set
- *
- * Returns:
- * Byte read from device
- */
-static u8 mts64_read_char(struct parport *p)
-{
- u8 c = 0;
- u8 status;
- u8 i;
-
- for (i = 0; i < 8; ++i) {
- parport_write_data(p, i);
- c >>= 1;
- status = parport_read_status(p);
- if (status & MTS64_STAT_BIT_SET)
- c |= 0x80;
- }
-
- return c;
-}
-
-/* Starts SMPTE Timecode generation
- *
- * The device creates SMPTE Timecode by hardware.
- * 0 24 fps
- * 1 25 fps
- * 2 29.97 fps
- * 3 30 fps (Drop-frame)
- * 4 30 fps
- */
-static void mts64_smpte_start(struct parport *p,
- u8 hours, u8 minutes,
- u8 seconds, u8 frames,
- u8 idx)
-{
- static u8 fps[5] = { MTS64_CMD_SMPTE_FPS_24,
- MTS64_CMD_SMPTE_FPS_25,
- MTS64_CMD_SMPTE_FPS_2997,
- MTS64_CMD_SMPTE_FPS_30D,
- MTS64_CMD_SMPTE_FPS_30 };
-
- mts64_write_command(p, MTS64_CMD_SMPTE_SET_TIME);
- mts64_write_command(p, frames);
- mts64_write_command(p, seconds);
- mts64_write_command(p, minutes);
- mts64_write_command(p, hours);
-
- mts64_write_command(p, MTS64_CMD_SMPTE_SET_FPS);
- mts64_write_command(p, fps[idx]);
-}
-
-/* Stops SMPTE Timecode generation
- */
-static void mts64_smpte_stop(struct parport *p)
-{
- mts64_write_command(p, MTS64_CMD_SMPTE_STOP);
-}
-
-/* Write a command byte to device
- */
-static void mts64_write_command(struct parport *p, u8 c)
-{
- mts64_device_ready(p);
-
- parport_write_data(p, c);
-
- parport_write_control(p, MTS64_CTL_WRITE_CMD);
- parport_write_control(p, MTS64_CTL_WRITE_CMD | MTS64_CTL_STROBE);
- parport_write_control(p, MTS64_CTL_WRITE_CMD);
-}
-
-/* Write a data byte to device
- */
-static void mts64_write_data(struct parport *p, u8 c)
-{
- mts64_device_ready(p);
-
- parport_write_data(p, c);
-
- parport_write_control(p, MTS64_CTL_WRITE_DATA);
- parport_write_control(p, MTS64_CTL_WRITE_DATA | MTS64_CTL_STROBE);
- parport_write_control(p, MTS64_CTL_WRITE_DATA);
-}
-
-/* Write a MIDI byte to midiport
- *
- * midiport ranges from 0-3 and maps to Ports 1-4
- * assumptions: communication mode is on
- */
-static void mts64_write_midi(struct mts64 *mts, u8 c,
- int midiport)
-{
- struct parport *p = mts->pardev->port;
-
- /* check current midiport */
- if (mts->current_midi_output_port != midiport)
- mts64_write_command(p, midiport);
-
- /* write midi byte */
- mts64_write_data(p, c);
-}
-
-/*********************************************************************
- * Control elements
- *********************************************************************/
-
-/* SMPTE Switch */
-#define snd_mts64_ctl_smpte_switch_info snd_ctl_boolean_mono_info
-
-static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
-
- spin_lock_irq(&mts->lock);
- uctl->value.integer.value[0] = mts->smpte_switch;
- spin_unlock_irq(&mts->lock);
-
- return 0;
-}
-
-/* smpte_switch is not accessed from IRQ handler, so we just need
- to protect the HW access */
-static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int changed = 0;
- int val = !!uctl->value.integer.value[0];
-
- spin_lock_irq(&mts->lock);
- if (mts->smpte_switch == val)
- goto __out;
-
- changed = 1;
- mts->smpte_switch = val;
- if (mts->smpte_switch) {
- mts64_smpte_start(mts->pardev->port,
- mts->time[0], mts->time[1],
- mts->time[2], mts->time[3],
- mts->fps);
- } else {
- mts64_smpte_stop(mts->pardev->port);
- }
-__out:
- spin_unlock_irq(&mts->lock);
- return changed;
-}
-
-static struct snd_kcontrol_new mts64_ctl_smpte_switch __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Playback Switch",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_mts64_ctl_smpte_switch_info,
- .get = snd_mts64_ctl_smpte_switch_get,
- .put = snd_mts64_ctl_smpte_switch_put
-};
-
-/* Time */
-static int snd_mts64_ctl_smpte_time_h_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 23;
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_f_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 99;
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 59;
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int idx = kctl->private_value;
-
- spin_lock_irq(&mts->lock);
- uctl->value.integer.value[0] = mts->time[idx];
- spin_unlock_irq(&mts->lock);
-
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int idx = kctl->private_value;
- unsigned int time = uctl->value.integer.value[0] % 60;
- int changed = 0;
-
- spin_lock_irq(&mts->lock);
- if (mts->time[idx] != time) {
- changed = 1;
- mts->time[idx] = time;
- }
- spin_unlock_irq(&mts->lock);
-
- return changed;
-}
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_hours __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Hours",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_mts64_ctl_smpte_time_h_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_minutes __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Minutes",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 1,
- .info = snd_mts64_ctl_smpte_time_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_seconds __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Seconds",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 2,
- .info = snd_mts64_ctl_smpte_time_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_frames __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Frames",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 3,
- .info = snd_mts64_ctl_smpte_time_f_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-/* FPS */
-static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[5] = { "24",
- "25",
- "29.97",
- "30D",
- "30" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item > 4)
- uinfo->value.enumerated.item = 4;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
-
- spin_lock_irq(&mts->lock);
- uctl->value.enumerated.item[0] = mts->fps;
- spin_unlock_irq(&mts->lock);
-
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int changed = 0;
-
- if (uctl->value.enumerated.item[0] >= 5)
- return -EINVAL;
- spin_lock_irq(&mts->lock);
- if (mts->fps != uctl->value.enumerated.item[0]) {
- changed = 1;
- mts->fps = uctl->value.enumerated.item[0];
- }
- spin_unlock_irq(&mts->lock);
-
- return changed;
-}
-
-static struct snd_kcontrol_new mts64_ctl_smpte_fps __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Fps",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_mts64_ctl_smpte_fps_info,
- .get = snd_mts64_ctl_smpte_fps_get,
- .put = snd_mts64_ctl_smpte_fps_put
-};
-
-
-static int __devinit snd_mts64_ctl_create(struct snd_card *card,
- struct mts64 *mts)
-{
- int err, i;
- static struct snd_kcontrol_new *control[] __devinitdata = {
- &mts64_ctl_smpte_switch,
- &mts64_ctl_smpte_time_hours,
- &mts64_ctl_smpte_time_minutes,
- &mts64_ctl_smpte_time_seconds,
- &mts64_ctl_smpte_time_frames,
- &mts64_ctl_smpte_fps,
- NULL };
-
- for (i = 0; control[i]; ++i) {
- err = snd_ctl_add(card, snd_ctl_new1(control[i], mts));
- if (err < 0) {
- snd_printd("Cannot create control: %s\n",
- control[i]->name);
- return err;
- }
- }
-
- return 0;
-}
-
-/*********************************************************************
- * Rawmidi
- *********************************************************************/
-#define MTS64_MODE_INPUT_TRIGGERED 0x01
-
-static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream)
-{
- struct mts64 *mts = substream->rmidi->private_data;
-
- if (mts->open_count == 0) {
- /* We don't need a spinlock here, because this is just called
- if the device has not been opened before.
- So there aren't any IRQs from the device */
- mts64_device_open(mts);
-
- msleep(50);
- }
- ++(mts->open_count);
-
- return 0;
-}
-
-static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream)
-{
- struct mts64 *mts = substream->rmidi->private_data;
- unsigned long flags;
-
- --(mts->open_count);
- if (mts->open_count == 0) {
- /* We need the spinlock_irqsave here because we can still
- have IRQs at this point */
- spin_lock_irqsave(&mts->lock, flags);
- mts64_device_close(mts);
- spin_unlock_irqrestore(&mts->lock, flags);
-
- msleep(500);
-
- } else if (mts->open_count < 0)
- mts->open_count = 0;
-
- return 0;
-}
-
-static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct mts64 *mts = substream->rmidi->private_data;
- u8 data;
- unsigned long flags;
-
- spin_lock_irqsave(&mts->lock, flags);
- while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
- mts64_write_midi(mts, data, substream->number+1);
- snd_rawmidi_transmit_ack(substream, 1);
- }
- spin_unlock_irqrestore(&mts->lock, flags);
-}
-
-static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct mts64 *mts = substream->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&mts->lock, flags);
- if (up)
- mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED;
- else
- mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED;
-
- spin_unlock_irqrestore(&mts->lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {
- .open = snd_mts64_rawmidi_open,
- .close = snd_mts64_rawmidi_close,
- .trigger = snd_mts64_rawmidi_output_trigger
-};
-
-static struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = {
- .open = snd_mts64_rawmidi_open,
- .close = snd_mts64_rawmidi_close,
- .trigger = snd_mts64_rawmidi_input_trigger
-};
-
-/* Create and initialize the rawmidi component */
-static int __devinit snd_mts64_rawmidi_create(struct snd_card *card)
-{
- struct mts64 *mts = card->private_data;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *substream;
- struct list_head *list;
- int err;
-
- err = snd_rawmidi_new(card, CARD_NAME, 0,
- MTS64_NUM_OUTPUT_PORTS,
- MTS64_NUM_INPUT_PORTS,
- &rmidi);
- if (err < 0)
- return err;
-
- rmidi->private_data = mts;
- strcpy(rmidi->name, CARD_NAME);
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
-
- mts->rmidi = rmidi;
-
- /* register rawmidi ops */
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_mts64_rawmidi_output_ops);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_mts64_rawmidi_input_ops);
-
- /* name substreams */
- /* output */
- list_for_each(list,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- sprintf(substream->name,
- "Miditerminal %d", substream->number+1);
- }
- /* input */
- list_for_each(list,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- mts->midi_input_substream[substream->number] = substream;
- switch(substream->number) {
- case MTS64_SMPTE_SUBSTREAM:
- strcpy(substream->name, "Miditerminal SMPTE");
- break;
- default:
- sprintf(substream->name,
- "Miditerminal %d", substream->number+1);
- }
- }
-
- /* controls */
- err = snd_mts64_ctl_create(card, mts);
-
- return err;
-}
-
-/*********************************************************************
- * parport stuff
- *********************************************************************/
-static void snd_mts64_interrupt(void *private)
-{
- struct mts64 *mts = ((struct snd_card*)private)->private_data;
- u16 ret;
- u8 status, data;
- struct snd_rawmidi_substream *substream;
-
- spin_lock(&mts->lock);
- ret = mts64_read(mts->pardev->port);
- data = ret & 0x00ff;
- status = ret >> 8;
-
- if (status & MTS64_STAT_PORT) {
- mts->current_midi_input_port = mts64_map_midi_input(data);
- } else {
- if (mts->current_midi_input_port == -1)
- goto __out;
- substream = mts->midi_input_substream[mts->current_midi_input_port];
- if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(substream, &data, 1);
- }
-__out:
- spin_unlock(&mts->lock);
-}
-
-static int __devinit snd_mts64_probe_port(struct parport *p)
-{
- struct pardevice *pardev;
- int res;
-
- pardev = parport_register_device(p, DRIVER_NAME,
- NULL, NULL, NULL,
- 0, NULL);
- if (!pardev)
- return -EIO;
-
- if (parport_claim(pardev)) {
- parport_unregister_device(pardev);
- return -EIO;
- }
-
- res = mts64_probe(p);
-
- parport_release(pardev);
- parport_unregister_device(pardev);
-
- return res;
-}
-
-static void __devinit snd_mts64_attach(struct parport *p)
-{
- struct platform_device *device;
-
- device = platform_device_alloc(PLATFORM_DRIVER, device_count);
- if (!device)
- return;
-
- /* Temporary assignment to forward the parport */
- platform_set_drvdata(device, p);
-
- if (platform_device_add(device) < 0) {
- platform_device_put(device);
- return;
- }
-
- /* Since we dont get the return value of probe
- * We need to check if device probing succeeded or not */
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- return;
- }
-
- /* register device in global table */
- platform_devices[device_count] = device;
- device_count++;
-}
-
-static void snd_mts64_detach(struct parport *p)
-{
- /* nothing to do here */
-}
-
-static struct parport_driver mts64_parport_driver = {
- .name = "mts64",
- .attach = snd_mts64_attach,
- .detach = snd_mts64_detach
-};
-
-/*********************************************************************
- * platform stuff
- *********************************************************************/
-static void snd_mts64_card_private_free(struct snd_card *card)
-{
- struct mts64 *mts = card->private_data;
- struct pardevice *pardev = mts->pardev;
-
- if (pardev) {
- if (mts->pardev_claimed)
- parport_release(pardev);
- parport_unregister_device(pardev);
- }
-
- snd_mts64_free(mts);
-}
-
-static int __devinit snd_mts64_probe(struct platform_device *pdev)
-{
- struct pardevice *pardev;
- struct parport *p;
- int dev = pdev->id;
- struct snd_card *card = NULL;
- struct mts64 *mts = NULL;
- int err;
-
- p = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev])
- return -ENOENT;
- if ((err = snd_mts64_probe_port(p)) < 0)
- return err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printd("Cannot create card\n");
- return err;
- }
- strcpy(card->driver, DRIVER_NAME);
- strcpy(card->shortname, "ESI " CARD_NAME);
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, p->base, p->irq);
-
- pardev = parport_register_device(p, /* port */
- DRIVER_NAME, /* name */
- NULL, /* preempt */
- NULL, /* wakeup */
- snd_mts64_interrupt, /* ISR */
- PARPORT_DEV_EXCL, /* flags */
- (void *)card); /* private */
- if (pardev == NULL) {
- snd_printd("Cannot register pardevice\n");
- err = -EIO;
- goto __err;
- }
-
- if ((err = snd_mts64_create(card, pardev, &mts)) < 0) {
- snd_printd("Cannot create main component\n");
- parport_unregister_device(pardev);
- goto __err;
- }
- card->private_data = mts;
- card->private_free = snd_mts64_card_private_free;
-
- if ((err = snd_mts64_rawmidi_create(card)) < 0) {
- snd_printd("Creating Rawmidi component failed\n");
- goto __err;
- }
-
- /* claim parport */
- if (parport_claim(pardev)) {
- snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
- err = -EIO;
- goto __err;
- }
- mts->pardev_claimed = 1;
-
- /* init device */
- if ((err = mts64_device_init(p)) < 0)
- goto __err;
-
- platform_set_drvdata(pdev, card);
-
- snd_card_set_dev(card, &pdev->dev);
-
- /* At this point card will be usable */
- if ((err = snd_card_register(card)) < 0) {
- snd_printd("Cannot register card\n");
- goto __err;
- }
-
- snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base);
- return 0;
-
-__err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_mts64_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- if (card)
- snd_card_free(card);
-
- return 0;
-}
-
-
-static struct platform_driver snd_mts64_driver = {
- .probe = snd_mts64_probe,
- .remove = __devexit_p(snd_mts64_remove),
- .driver = {
- .name = PLATFORM_DRIVER
- }
-};
-
-/*********************************************************************
- * module init stuff
- *********************************************************************/
-static void snd_mts64_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < SNDRV_CARDS; ++i) {
- if (platform_devices[i]) {
- platform_device_unregister(platform_devices[i]);
- platform_devices[i] = NULL;
- }
- }
- platform_driver_unregister(&snd_mts64_driver);
- parport_unregister_driver(&mts64_parport_driver);
-}
-
-static int __init snd_mts64_module_init(void)
-{
- int err;
-
- if ((err = platform_driver_register(&snd_mts64_driver)) < 0)
- return err;
-
- if (parport_register_driver(&mts64_parport_driver) != 0) {
- platform_driver_unregister(&snd_mts64_driver);
- return -EIO;
- }
-
- if (device_count == 0) {
- snd_mts64_unregister_all();
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit snd_mts64_module_exit(void)
-{
- snd_mts64_unregister_all();
-}
-
-module_init(snd_mts64_module_init);
-module_exit(snd_mts64_module_exit);
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/Makefile b/ANDROID_3.4.5/sound/drivers/opl3/Makefile
deleted file mode 100644
index 7f2c2a10..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-opl3-lib-objs := opl3_lib.o opl3_synth.o
-snd-opl3-synth-y := opl3_seq.o opl3_midi.o opl3_drums.o
-snd-opl3-synth-$(CONFIG_SND_SEQUENCER_OSS) += opl3_oss.o
-
-obj-$(CONFIG_SND_OPL3_LIB) += snd-opl3-lib.o
-obj-$(CONFIG_SND_OPL4_LIB) += snd-opl3-lib.o
-obj-$(CONFIG_SND_OPL3_LIB_SEQ) += snd-opl3-synth.o
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c
deleted file mode 100644
index 73694380..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * OPL2/OPL3/OPL4 FM routines for internal percussion channels
- *
- * 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 "opl3_voice.h"
-
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
-
-static char snd_opl3_drum_table[47] =
-{
- OPL3_BASSDRUM_ON, OPL3_BASSDRUM_ON, OPL3_HIHAT_ON, /* 35 - 37 */
- OPL3_SNAREDRUM_ON, OPL3_HIHAT_ON, OPL3_SNAREDRUM_ON, /* 38 - 40 */
- OPL3_BASSDRUM_ON, OPL3_HIHAT_ON, OPL3_BASSDRUM_ON, /* 41 - 43 */
- OPL3_HIHAT_ON, OPL3_TOMTOM_ON, OPL3_HIHAT_ON, /* 44 - 46 */
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_CYMBAL_ON, /* 47 - 49 */
-
- OPL3_TOMTOM_ON, OPL3_CYMBAL_ON, OPL3_CYMBAL_ON, /* 50 - 52 */
- OPL3_CYMBAL_ON, OPL3_CYMBAL_ON, OPL3_CYMBAL_ON, /* 53 - 55 */
- OPL3_HIHAT_ON, OPL3_CYMBAL_ON, OPL3_TOMTOM_ON, /* 56 - 58 */
- OPL3_CYMBAL_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 59 - 61 */
- OPL3_HIHAT_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 62 - 64 */
-
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 65 - 67 */
- OPL3_TOMTOM_ON, OPL3_HIHAT_ON, OPL3_HIHAT_ON, /* 68 - 70 */
- OPL3_HIHAT_ON, OPL3_HIHAT_ON, OPL3_TOMTOM_ON, /* 71 - 73 */
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 74 - 76 */
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 77 - 79 */
- OPL3_CYMBAL_ON, OPL3_CYMBAL_ON /* 80 - 81 */
-};
-
-struct snd_opl3_drum_voice {
- int voice;
- int op;
- unsigned char am_vib;
- unsigned char ksl_level;
- unsigned char attack_decay;
- unsigned char sustain_release;
- unsigned char feedback_connection;
- unsigned char wave_select;
-};
-
-struct snd_opl3_drum_note {
- int voice;
- unsigned char fnum;
- unsigned char octave_f;
- unsigned char feedback_connection;
-};
-
-static struct snd_opl3_drum_voice bass_op0 = {6, 0, 0x00, 0x32, 0xf8, 0x66, 0x30, 0x00};
-static struct snd_opl3_drum_voice bass_op1 = {6, 1, 0x00, 0x03, 0xf6, 0x57, 0x30, 0x00};
-static struct snd_opl3_drum_note bass_note = {6, 0x90, 0x09};
-
-static struct snd_opl3_drum_voice hihat = {7, 0, 0x00, 0x03, 0xf0, 0x06, 0x20, 0x00};
-
-static struct snd_opl3_drum_voice snare = {7, 1, 0x00, 0x03, 0xf0, 0x07, 0x20, 0x02};
-static struct snd_opl3_drum_note snare_note = {7, 0xf4, 0x0d};
-
-static struct snd_opl3_drum_voice tomtom = {8, 0, 0x02, 0x03, 0xf0, 0x06, 0x10, 0x00};
-static struct snd_opl3_drum_note tomtom_note = {8, 0xf4, 0x09};
-
-static struct snd_opl3_drum_voice cymbal = {8, 1, 0x04, 0x03, 0xf0, 0x06, 0x10, 0x00};
-
-/*
- * set drum voice characteristics
- */
-static void snd_opl3_drum_voice_set(struct snd_opl3 *opl3,
- struct snd_opl3_drum_voice *data)
-{
- unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
- unsigned char voice_offset = data->voice;
- unsigned short opl3_reg;
-
- /* Set OPL3 AM_VIB register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_AM_VIB + op_offset);
- opl3->command(opl3, opl3_reg, data->am_vib);
-
- /* Set OPL3 KSL_LEVEL register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, data->ksl_level);
-
- /* Set OPL3 ATTACK_DECAY register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_ATTACK_DECAY + op_offset);
- opl3->command(opl3, opl3_reg, data->attack_decay);
-
- /* Set OPL3 SUSTAIN_RELEASE register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
- opl3->command(opl3, opl3_reg, data->sustain_release);
-
- /* Set OPL3 FEEDBACK_CONNECTION register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, data->feedback_connection);
-
- /* Select waveform */
- opl3_reg = OPL3_LEFT | (OPL3_REG_WAVE_SELECT + op_offset);
- opl3->command(opl3, opl3_reg, data->wave_select);
-}
-
-/*
- * Set drum voice pitch
- */
-static void snd_opl3_drum_note_set(struct snd_opl3 *opl3,
- struct snd_opl3_drum_note *data)
-{
- unsigned char voice_offset = data->voice;
- unsigned short opl3_reg;
-
- /* Set OPL3 FNUM_LOW register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, data->fnum);
-
- /* Set OPL3 KEYON_BLOCK register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, data->octave_f);
-}
-
-/*
- * Set drum voice volume and position
- */
-static void snd_opl3_drum_vol_set(struct snd_opl3 *opl3,
- struct snd_opl3_drum_voice *data,
- int vel, struct snd_midi_channel *chan)
-{
- unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
- unsigned char voice_offset = data->voice;
- unsigned char reg_val;
- unsigned short opl3_reg;
-
- /* Set OPL3 KSL_LEVEL register */
- reg_val = data->ksl_level;
- snd_opl3_calc_volume(&reg_val, vel, chan);
- opl3_reg = OPL3_LEFT | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 FEEDBACK_CONNECTION register */
- /* Set output voice connection */
- reg_val = data->feedback_connection | OPL3_STEREO_BITS;
- if (chan->gm_pan < 43)
- reg_val &= ~OPL3_VOICE_TO_RIGHT;
- if (chan->gm_pan > 85)
- reg_val &= ~OPL3_VOICE_TO_LEFT;
- opl3_reg = OPL3_LEFT | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-}
-
-/*
- * Loads drum voices at init time
- */
-void snd_opl3_load_drums(struct snd_opl3 *opl3)
-{
- snd_opl3_drum_voice_set(opl3, &bass_op0);
- snd_opl3_drum_voice_set(opl3, &bass_op1);
- snd_opl3_drum_note_set(opl3, &bass_note);
-
- snd_opl3_drum_voice_set(opl3, &hihat);
-
- snd_opl3_drum_voice_set(opl3, &snare);
- snd_opl3_drum_note_set(opl3, &snare_note);
-
- snd_opl3_drum_voice_set(opl3, &tomtom);
- snd_opl3_drum_note_set(opl3, &tomtom_note);
-
- snd_opl3_drum_voice_set(opl3, &cymbal);
-}
-
-/*
- * Switch drum voice on or off
- */
-void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int vel, int on_off,
- struct snd_midi_channel *chan)
-{
- unsigned char drum_mask;
- struct snd_opl3_drum_voice *drum_voice;
-
- if (!(opl3->drum_reg & OPL3_PERCUSSION_ENABLE))
- return;
-
- if ((note < 35) || (note > 81))
- return;
- drum_mask = snd_opl3_drum_table[note - 35];
-
- if (on_off) {
- switch (drum_mask) {
- case OPL3_BASSDRUM_ON:
- drum_voice = &bass_op1;
- break;
- case OPL3_HIHAT_ON:
- drum_voice = &hihat;
- break;
- case OPL3_SNAREDRUM_ON:
- drum_voice = &snare;
- break;
- case OPL3_TOMTOM_ON:
- drum_voice = &tomtom;
- break;
- case OPL3_CYMBAL_ON:
- drum_voice = &cymbal;
- break;
- default:
- drum_voice = &tomtom;
- }
-
- snd_opl3_drum_vol_set(opl3, drum_voice, vel, chan);
- opl3->drum_reg |= drum_mask;
- } else {
- opl3->drum_reg &= ~drum_mask;
- }
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
- opl3->drum_reg);
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c
deleted file mode 100644
index 33d9a857..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
- * Hannu Savolainen 1993-1996,
- * Rob Hooft
- *
- * Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)
- *
- * Most if code is ported from OSS/Lite.
- *
- * 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/opl3.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <sound/minors.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
-MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
-MODULE_LICENSE("GPL");
-
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
-
-static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
-{
- unsigned long flags;
- unsigned long port;
-
- /*
- * The original 2-OP synth requires a quite long delay
- * after writing to a register.
- */
-
- port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
-
- spin_lock_irqsave(&opl3->reg_lock, flags);
-
- outb((unsigned char) cmd, port);
- udelay(10);
-
- outb((unsigned char) val, port + 1);
- udelay(30);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
-}
-
-static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
-{
- unsigned long flags;
- unsigned long port;
-
- /*
- * The OPL-3 survives with just two INBs
- * after writing to a register.
- */
-
- port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
-
- spin_lock_irqsave(&opl3->reg_lock, flags);
-
- outb((unsigned char) cmd, port);
- inb(opl3->l_port);
- inb(opl3->l_port);
-
- outb((unsigned char) val, port + 1);
- inb(opl3->l_port);
- inb(opl3->l_port);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
-}
-
-static int snd_opl3_detect(struct snd_opl3 * opl3)
-{
- /*
- * This function returns 1 if the FM chip is present at the given I/O port
- * The detection algorithm plays with the timer built in the FM chip and
- * looks for a change in the status register.
- *
- * Note! The timers of the FM chip are not connected to AdLib (and compatible)
- * boards.
- *
- * Note2! The chip is initialized if detected.
- */
-
- unsigned char stat1, stat2, signature;
-
- /* Reset timers 1 and 2 */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
- /* Reset the IRQ of the FM chip */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
- signature = stat1 = inb(opl3->l_port); /* Status register */
- if ((stat1 & 0xe0) != 0x00) { /* Should be 0x00 */
- snd_printd("OPL3: stat1 = 0x%x\n", stat1);
- return -ENODEV;
- }
- /* Set timer1 to 0xff */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 0xff);
- /* Unmask and start timer 1 */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER2_MASK | OPL3_TIMER1_START);
- /* Now we have to delay at least 80us */
- udelay(200);
- /* Read status after timers have expired */
- stat2 = inb(opl3->l_port);
- /* Stop the timers */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
- /* Reset the IRQ of the FM chip */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
- if ((stat2 & 0xe0) != 0xc0) { /* There is no YM3812 */
- snd_printd("OPL3: stat2 = 0x%x\n", stat2);
- return -ENODEV;
- }
-
- /* If the toplevel code knows exactly the type of chip, don't try
- to detect it. */
- if (opl3->hardware != OPL3_HW_AUTO)
- return 0;
-
- /* There is a FM chip on this address. Detect the type (OPL2 to OPL4) */
- if (signature == 0x06) { /* OPL2 */
- opl3->hardware = OPL3_HW_OPL2;
- } else {
- /*
- * If we had an OPL4 chip, opl3->hardware would have been set
- * by the OPL4 driver; so we can assume OPL3 here.
- */
- if (snd_BUG_ON(!opl3->r_port))
- return -ENODEV;
- opl3->hardware = OPL3_HW_OPL3;
- }
- return 0;
-}
-
-/*
- * AdLib timers
- */
-
-/*
- * Timer 1 - 80us
- */
-
-static int snd_opl3_timer1_start(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- unsigned int ticks;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- ticks = timer->sticks;
- tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks); /* timer 1 count */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-static int snd_opl3_timer1_stop(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-/*
- * Timer 2 - 320us
- */
-
-static int snd_opl3_timer2_start(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- unsigned int ticks;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- ticks = timer->sticks;
- tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks); /* timer 1 count */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-static int snd_opl3_timer2_stop(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-/*
-
- */
-
-static struct snd_timer_hardware snd_opl3_timer1 =
-{
- .flags = SNDRV_TIMER_HW_STOP,
- .resolution = 80000,
- .ticks = 256,
- .start = snd_opl3_timer1_start,
- .stop = snd_opl3_timer1_stop,
-};
-
-static struct snd_timer_hardware snd_opl3_timer2 =
-{
- .flags = SNDRV_TIMER_HW_STOP,
- .resolution = 320000,
- .ticks = 256,
- .start = snd_opl3_timer2_start,
- .stop = snd_opl3_timer2_stop,
-};
-
-static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_id tid;
- int err;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = opl3->card->number;
- tid.device = timer_no;
- tid.subdevice = 0;
- if ((err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer)) >= 0) {
- strcpy(timer->name, "AdLib timer #1");
- timer->private_data = opl3;
- timer->hw = snd_opl3_timer1;
- }
- opl3->timer1 = timer;
- return err;
-}
-
-static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_id tid;
- int err;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = opl3->card->number;
- tid.device = timer_no;
- tid.subdevice = 0;
- if ((err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer)) >= 0) {
- strcpy(timer->name, "AdLib timer #2");
- timer->private_data = opl3;
- timer->hw = snd_opl3_timer2;
- }
- opl3->timer2 = timer;
- return err;
-}
-
-/*
-
- */
-
-void snd_opl3_interrupt(struct snd_hwdep * hw)
-{
- unsigned char status;
- struct snd_opl3 *opl3;
- struct snd_timer *timer;
-
- if (hw == NULL)
- return;
-
- opl3 = hw->private_data;
- status = inb(opl3->l_port);
-#if 0
- snd_printk(KERN_DEBUG "AdLib IRQ status = 0x%x\n", status);
-#endif
- if (!(status & 0x80))
- return;
-
- if (status & 0x40) {
- timer = opl3->timer1;
- snd_timer_interrupt(timer, timer->sticks);
- }
- if (status & 0x20) {
- timer = opl3->timer2;
- snd_timer_interrupt(timer, timer->sticks);
- }
-}
-
-EXPORT_SYMBOL(snd_opl3_interrupt);
-
-/*
-
- */
-
-static int snd_opl3_free(struct snd_opl3 *opl3)
-{
- if (snd_BUG_ON(!opl3))
- return -ENXIO;
- if (opl3->private_free)
- opl3->private_free(opl3);
- snd_opl3_clear_patches(opl3);
- release_and_free_resource(opl3->res_l_port);
- release_and_free_resource(opl3->res_r_port);
- kfree(opl3);
- return 0;
-}
-
-static int snd_opl3_dev_free(struct snd_device *device)
-{
- struct snd_opl3 *opl3 = device->device_data;
- return snd_opl3_free(opl3);
-}
-
-int snd_opl3_new(struct snd_card *card,
- unsigned short hardware,
- struct snd_opl3 **ropl3)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_opl3_dev_free,
- };
- struct snd_opl3 *opl3;
- int err;
-
- *ropl3 = NULL;
- opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
- if (opl3 == NULL) {
- snd_printk(KERN_ERR "opl3: cannot allocate\n");
- return -ENOMEM;
- }
-
- opl3->card = card;
- opl3->hardware = hardware;
- spin_lock_init(&opl3->reg_lock);
- spin_lock_init(&opl3->timer_lock);
-
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
- snd_opl3_free(opl3);
- return err;
- }
-
- *ropl3 = opl3;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_new);
-
-int snd_opl3_init(struct snd_opl3 *opl3)
-{
- if (! opl3->command) {
- printk(KERN_ERR "snd_opl3_init: command not defined!\n");
- return -EINVAL;
- }
-
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
- /* Melodic mode */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
-
- switch (opl3->hardware & OPL3_HW_MASK) {
- case OPL3_HW_OPL2:
- opl3->max_voices = MAX_OPL2_VOICES;
- break;
- case OPL3_HW_OPL3:
- case OPL3_HW_OPL4:
- opl3->max_voices = MAX_OPL3_VOICES;
- /* Enter OPL3 mode */
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_init);
-
-int snd_opl3_create(struct snd_card *card,
- unsigned long l_port,
- unsigned long r_port,
- unsigned short hardware,
- int integrated,
- struct snd_opl3 ** ropl3)
-{
- struct snd_opl3 *opl3;
- int err;
-
- *ropl3 = NULL;
- if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
- return err;
- if (! integrated) {
- if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
- snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
- snd_device_free(card, opl3);
- return -EBUSY;
- }
- if (r_port != 0 &&
- (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
- snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
- snd_device_free(card, opl3);
- return -EBUSY;
- }
- }
- opl3->l_port = l_port;
- opl3->r_port = r_port;
-
- switch (opl3->hardware) {
- /* some hardware doesn't support timers */
- case OPL3_HW_OPL3_SV:
- case OPL3_HW_OPL3_CS:
- case OPL3_HW_OPL3_FM801:
- opl3->command = &snd_opl3_command;
- break;
- default:
- opl3->command = &snd_opl2_command;
- if ((err = snd_opl3_detect(opl3)) < 0) {
- snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
- opl3->l_port, opl3->r_port);
- snd_device_free(card, opl3);
- return err;
- }
- /* detect routine returns correct hardware type */
- switch (opl3->hardware & OPL3_HW_MASK) {
- case OPL3_HW_OPL3:
- case OPL3_HW_OPL4:
- opl3->command = &snd_opl3_command;
- }
- }
-
- snd_opl3_init(opl3);
-
- *ropl3 = opl3;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_create);
-
-int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
-{
- int err;
-
- if (timer1_dev >= 0)
- if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
- return err;
- if (timer2_dev >= 0) {
- if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
- snd_device_free(opl3->card, opl3->timer1);
- opl3->timer1 = NULL;
- return err;
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_timer_new);
-
-int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
- int device, int seq_device,
- struct snd_hwdep ** rhwdep)
-{
- struct snd_hwdep *hw;
- struct snd_card *card = opl3->card;
- int err;
-
- if (rhwdep)
- *rhwdep = NULL;
-
- /* create hardware dependent device (direct FM) */
-
- if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
- snd_device_free(card, opl3);
- return err;
- }
- hw->private_data = opl3;
- hw->exclusive = 1;
-#ifdef CONFIG_SND_OSSEMUL
- if (device == 0) {
- hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
- sprintf(hw->oss_dev, "dmfm%i", card->number);
- }
-#endif
- strcpy(hw->name, hw->id);
- switch (opl3->hardware & OPL3_HW_MASK) {
- case OPL3_HW_OPL2:
- strcpy(hw->name, "OPL2 FM");
- hw->iface = SNDRV_HWDEP_IFACE_OPL2;
- break;
- case OPL3_HW_OPL3:
- strcpy(hw->name, "OPL3 FM");
- hw->iface = SNDRV_HWDEP_IFACE_OPL3;
- break;
- case OPL3_HW_OPL4:
- strcpy(hw->name, "OPL4 FM");
- hw->iface = SNDRV_HWDEP_IFACE_OPL4;
- break;
- }
-
- /* operators - only ioctl */
- hw->ops.open = snd_opl3_open;
- hw->ops.ioctl = snd_opl3_ioctl;
- hw->ops.write = snd_opl3_write;
- hw->ops.release = snd_opl3_release;
-
- opl3->hwdep = hw;
- opl3->seq_dev_num = seq_device;
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
- sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
- strcpy(opl3->seq_dev->name, hw->name);
- *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
- }
-#endif
- if (rhwdep)
- *rhwdep = hw;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_hwdep_new);
-
-/*
- * INIT part
- */
-
-static int __init alsa_opl3_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_opl3_exit(void)
-{
-}
-
-module_init(alsa_opl3_init)
-module_exit(alsa_opl3_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c
deleted file mode 100644
index 2bfe4bcb..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * Midi synth routines for OPL2/OPL3/OPL4 FM
- *
- * 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
- *
- */
-
-#undef DEBUG_ALLOC
-#undef DEBUG_MIDI
-
-#include "opl3_voice.h"
-#include <sound/asoundef.h>
-
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
-
-extern bool use_internal_drums;
-
-static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
- struct snd_midi_channel *chan);
-/*
- * The next table looks magical, but it certainly is not. Its values have
- * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
- * for i=0. This log-table converts a linear volume-scaling (0..127) to a
- * logarithmic scaling as present in the FM-synthesizer chips. so : Volume
- * 64 = 0 db = relative volume 0 and: Volume 32 = -6 db = relative
- * volume -8 it was implemented as a table because it is only 128 bytes and
- * it saves a lot of log() calculations. (Rob Hooft <hooft@chem.ruu.nl>)
- */
-
-static char opl3_volume_table[128] =
-{
- -63, -48, -40, -35, -32, -29, -27, -26,
- -24, -23, -21, -20, -19, -18, -18, -17,
- -16, -15, -15, -14, -13, -13, -12, -12,
- -11, -11, -10, -10, -10, -9, -9, -8,
- -8, -8, -7, -7, -7, -6, -6, -6,
- -5, -5, -5, -5, -4, -4, -4, -4,
- -3, -3, -3, -3, -2, -2, -2, -2,
- -2, -1, -1, -1, -1, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 4,
- 4, 4, 4, 4, 4, 4, 4, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8
-};
-
-void snd_opl3_calc_volume(unsigned char *volbyte, int vel,
- struct snd_midi_channel *chan)
-{
- int oldvol, newvol, n;
- int volume;
-
- volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127);
- if (volume > 127)
- volume = 127;
-
- oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK);
-
- newvol = opl3_volume_table[volume] + oldvol;
- if (newvol > OPL3_TOTAL_LEVEL_MASK)
- newvol = OPL3_TOTAL_LEVEL_MASK;
- else if (newvol < 0)
- newvol = 0;
-
- n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK);
-
- *volbyte = (*volbyte & OPL3_KSL_MASK) | (n & OPL3_TOTAL_LEVEL_MASK);
-}
-
-/*
- * Converts the note frequency to block and fnum values for the FM chip
- */
-static short opl3_note_table[16] =
-{
- 305, 323, /* for pitch bending, -2 semitones */
- 343, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647,
- 686, 726 /* for pitch bending, +2 semitones */
-};
-
-static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum,
- int note, struct snd_midi_channel *chan)
-{
- int block = ((note / 12) & 0x07) - 1;
- int idx = (note % 12) + 2;
- int freq;
-
- if (chan->midi_pitchbend) {
- int pitchbend = chan->midi_pitchbend;
- int segment;
-
- if (pitchbend > 0x1FFF)
- pitchbend = 0x1FFF;
-
- segment = pitchbend / 0x1000;
- freq = opl3_note_table[idx+segment];
- freq += ((opl3_note_table[idx+segment+1] - freq) *
- (pitchbend % 0x1000)) / 0x1000;
- } else {
- freq = opl3_note_table[idx];
- }
-
- *fnum = (unsigned char) freq;
- *blocknum = ((freq >> 8) & OPL3_FNUM_HIGH_MASK) |
- ((block << 2) & OPL3_BLOCKNUM_MASK);
-}
-
-
-#ifdef DEBUG_ALLOC
-static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
- int i;
- char *str = "x.24";
-
- printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
- for (i = 0; i < opl3->max_voices; i++)
- printk("%c", *(str + opl3->voices[i].state + 1));
- printk("\n");
-}
-#endif
-
-/*
- * Get a FM voice (channel) to play a note on.
- */
-static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
- struct snd_midi_channel *chan) {
- int chan_4op_1; /* first voice for 4op instrument */
- int chan_4op_2; /* second voice for 4op instrument */
-
- struct snd_opl3_voice *vp, *vp2;
- unsigned int voice_time;
- int i;
-
-#ifdef DEBUG_ALLOC
- char *alloc_type[3] = { "FREE ", "CHEAP ", "EXPENSIVE" };
-#endif
-
- /* This is our "allocation cost" table */
- enum {
- FREE = 0, CHEAP, EXPENSIVE, END
- };
-
- /* Keeps track of what we are finding */
- struct best {
- unsigned int time;
- int voice;
- } best[END];
- struct best *bp;
-
- for (i = 0; i < END; i++) {
- best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
- best[i].voice = -1;
- }
-
- /* Look through all the channels for the most suitable. */
- for (i = 0; i < opl3->max_voices; i++) {
- vp = &opl3->voices[i];
-
- if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL)
- /* skip unavailable channels, allocated by
- drum voices or by bounded 4op voices) */
- continue;
-
- voice_time = vp->time;
- bp = best;
-
- chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
- chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
- if (instr_4op) {
- /* allocate 4op voice */
- /* skip channels unavailable to 4op instrument */
- if (!chan_4op_1)
- continue;
-
- if (vp->state)
- /* kill one voice, CHEAP */
- bp++;
- /* get state of bounded 2op channel
- to be allocated for 4op instrument */
- vp2 = &opl3->voices[i + 3];
- if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
- /* kill two voices, EXPENSIVE */
- bp++;
- voice_time = (voice_time > vp->time) ?
- voice_time : vp->time;
- }
- } else {
- /* allocate 2op voice */
- if ((chan_4op_1) || (chan_4op_2))
- /* use bounded channels for 2op, CHEAP */
- bp++;
- else if (vp->state)
- /* kill one voice on 2op channel, CHEAP */
- bp++;
- /* raise kill cost to EXPENSIVE for all channels */
- if (vp->state)
- bp++;
- }
- if (voice_time < bp->time) {
- bp->time = voice_time;
- bp->voice = i;
- }
- }
-
- for (i = 0; i < END; i++) {
- if (best[i].voice >= 0) {
-#ifdef DEBUG_ALLOC
- printk(KERN_DEBUG "%s %iop allocation on voice %i\n",
- alloc_type[i], instr_4op ? 4 : 2,
- best[i].voice);
-#endif
- return best[i].voice;
- }
- }
- /* not found */
- return -1;
-}
-
-/* ------------------------------ */
-
-/*
- * System timer interrupt function
- */
-void snd_opl3_timer_func(unsigned long data)
-{
-
- struct snd_opl3 *opl3 = (struct snd_opl3 *)data;
- unsigned long flags;
- int again = 0;
- int i;
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
- for (i = 0; i < opl3->max_voices; i++) {
- struct snd_opl3_voice *vp = &opl3->voices[i];
- if (vp->state > 0 && vp->note_off_check) {
- if (vp->note_off == jiffies)
- snd_opl3_note_off_unsafe(opl3, vp->note, 0,
- vp->chan);
- else
- again++;
- }
- }
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
- if (again) {
- opl3->tlist.expires = jiffies + 1; /* invoke again */
- add_timer(&opl3->tlist);
- } else {
- opl3->sys_timer_status = 0;
- }
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
-}
-
-/*
- * Start system timer
- */
-static void snd_opl3_start_timer(struct snd_opl3 *opl3)
-{
- unsigned long flags;
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
- if (! opl3->sys_timer_status) {
- opl3->tlist.expires = jiffies + 1;
- add_timer(&opl3->tlist);
- opl3->sys_timer_status = 1;
- }
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
-}
-
-/* ------------------------------ */
-
-
-static int snd_opl3_oss_map[MAX_OPL3_VOICES] = {
- 0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14
-};
-
-/*
- * Start a note.
- */
-void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
- int instr_4op;
-
- int voice;
- struct snd_opl3_voice *vp, *vp2;
- unsigned short connect_mask;
- unsigned char connection;
- unsigned char vol_op[4];
-
- int extra_prg = 0;
-
- unsigned short reg_side;
- unsigned char op_offset;
- unsigned char voice_offset;
- unsigned short opl3_reg;
- unsigned char reg_val;
- unsigned char prg, bank;
-
- int key = note;
- unsigned char fnum, blocknum;
- int i;
-
- struct fm_patch *patch;
- struct fm_instrument *fm;
- unsigned long flags;
-
- opl3 = p;
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Note on, ch %i, inst %i, note %i, vel %i\n",
- chan->number, chan->midi_program, note, vel);
-#endif
-
- /* in SYNTH mode, application takes care of voices */
- /* in SEQ mode, drum voice numbers are notes on drum channel */
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- if (chan->drum_channel) {
- /* percussion instruments are located in bank 128 */
- bank = 128;
- prg = note;
- } else {
- bank = chan->gm_bank_select;
- prg = chan->midi_program;
- }
- } else {
- /* Prepare for OSS mode */
- if (chan->number >= MAX_OPL3_VOICES)
- return;
-
- /* OSS instruments are located in bank 127 */
- bank = 127;
- prg = chan->midi_program;
- }
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
-
- if (use_internal_drums) {
- snd_opl3_drum_switch(opl3, note, vel, 1, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
- return;
- }
-
- __extra_prg:
- patch = snd_opl3_find_patch(opl3, prg, bank, 0);
- if (!patch) {
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
- return;
- }
-
- fm = &patch->inst;
- switch (patch->type) {
- case FM_PATCH_OPL2:
- instr_4op = 0;
- break;
- case FM_PATCH_OPL3:
- if (opl3->hardware >= OPL3_HW_OPL3) {
- instr_4op = 1;
- break;
- }
- default:
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
- return;
- }
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> OPL%i instrument: %s\n",
- instr_4op ? 3 : 2, patch->name);
-#endif
- /* in SYNTH mode, application takes care of voices */
- /* in SEQ mode, allocate voice on free OPL3 channel */
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- voice = opl3_get_voice(opl3, instr_4op, chan);
- } else {
- /* remap OSS voice */
- voice = snd_opl3_oss_map[chan->number];
- }
-
- if (voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice;
- connect_mask = (OPL3_LEFT_4OP_0 << voice_offset) & 0x07;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice - MAX_OPL2_VOICES;
- connect_mask = (OPL3_RIGHT_4OP_0 << voice_offset) & 0x38;
- }
-
- /* kill voice on channel */
- vp = &opl3->voices[voice];
- if (vp->state > 0) {
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
- opl3->command(opl3, opl3_reg, reg_val);
- }
- if (instr_4op) {
- vp2 = &opl3->voices[voice + 3];
- if (vp->state > 0) {
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK +
- voice_offset + 3);
- reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
- opl3->command(opl3, opl3_reg, reg_val);
- }
- }
-
- /* set connection register */
- if (instr_4op) {
- if ((opl3->connection_reg ^ connect_mask) & connect_mask) {
- opl3->connection_reg |= connect_mask;
- /* set connection bit */
- opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
- opl3->command(opl3, opl3_reg, opl3->connection_reg);
- }
- } else {
- if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) {
- opl3->connection_reg &= ~connect_mask;
- /* clear connection bit */
- opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
- opl3->command(opl3, opl3_reg, opl3->connection_reg);
- }
- }
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> setting OPL3 connection: 0x%x\n",
- opl3->connection_reg);
-#endif
- /*
- * calculate volume depending on connection
- * between FM operators (see include/opl3.h)
- */
- for (i = 0; i < (instr_4op ? 4 : 2); i++)
- vol_op[i] = fm->op[i].ksl_level;
-
- connection = fm->feedback_connection[0] & 0x01;
- if (instr_4op) {
- connection <<= 1;
- connection |= fm->feedback_connection[1] & 0x01;
-
- snd_opl3_calc_volume(&vol_op[3], vel, chan);
- switch (connection) {
- case 0x03:
- snd_opl3_calc_volume(&vol_op[2], vel, chan);
- /* fallthru */
- case 0x02:
- snd_opl3_calc_volume(&vol_op[0], vel, chan);
- break;
- case 0x01:
- snd_opl3_calc_volume(&vol_op[1], vel, chan);
- }
- } else {
- snd_opl3_calc_volume(&vol_op[1], vel, chan);
- if (connection)
- snd_opl3_calc_volume(&vol_op[0], vel, chan);
- }
-
- /* Program the FM voice characteristics */
- for (i = 0; i < (instr_4op ? 4 : 2); i++) {
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> programming operator %i\n", i);
-#endif
- op_offset = snd_opl3_regmap[voice_offset][i];
-
- /* Set OPL3 AM_VIB register of requested voice/operator */
- reg_val = fm->op[i].am_vib;
- opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 KSL_LEVEL register of requested voice/operator */
- reg_val = vol_op[i];
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 ATTACK_DECAY register of requested voice/operator */
- reg_val = fm->op[i].attack_decay;
- opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */
- reg_val = fm->op[i].sustain_release;
- opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Select waveform */
- reg_val = fm->op[i].wave_select;
- opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
- }
-
- /* Set operator feedback and 2op inter-operator connection */
- reg_val = fm->feedback_connection[0];
- /* Set output voice connection */
- reg_val |= OPL3_STEREO_BITS;
- if (chan->gm_pan < 43)
- reg_val &= ~OPL3_VOICE_TO_RIGHT;
- if (chan->gm_pan > 85)
- reg_val &= ~OPL3_VOICE_TO_LEFT;
- opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- if (instr_4op) {
- /* Set 4op inter-operator connection */
- reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT;
- /* Set output voice connection */
- reg_val |= OPL3_STEREO_BITS;
- if (chan->gm_pan < 43)
- reg_val &= ~OPL3_VOICE_TO_RIGHT;
- if (chan->gm_pan > 85)
- reg_val &= ~OPL3_VOICE_TO_LEFT;
- opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION +
- voice_offset + 3);
- opl3->command(opl3, opl3_reg, reg_val);
- }
-
- /*
- * Special treatment of percussion notes for fm:
- * Requested pitch is really program, and pitch for
- * device is whatever was specified in the patch library.
- */
- if (fm->fix_key)
- note = fm->fix_key;
- /*
- * use transpose if defined in patch library
- */
- if (fm->trnsps)
- note += (fm->trnsps - 64);
-
- snd_opl3_calc_pitch(&fnum, &blocknum, note, chan);
-
- /* Set OPL3 FNUM_LOW register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, fnum);
-
- opl3->voices[voice].keyon_reg = blocknum;
-
- /* Set output sound flag */
- blocknum |= OPL3_KEYON_BIT;
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> trigger voice %i\n", voice);
-#endif
- /* Set OPL3 KEYON_BLOCK register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, blocknum);
-
- /* kill note after fixed duration (in centiseconds) */
- if (fm->fix_dur) {
- opl3->voices[voice].note_off = jiffies +
- (fm->fix_dur * HZ) / 100;
- snd_opl3_start_timer(opl3);
- opl3->voices[voice].note_off_check = 1;
- } else
- opl3->voices[voice].note_off_check = 0;
-
- /* get extra pgm, but avoid possible loops */
- extra_prg = (extra_prg) ? 0 : fm->modes;
-
- /* do the bookkeeping */
- vp->time = opl3->use_time++;
- vp->note = key;
- vp->chan = chan;
-
- if (instr_4op) {
- vp->state = SNDRV_OPL3_ST_ON_4OP;
-
- vp2 = &opl3->voices[voice + 3];
- vp2->time = opl3->use_time++;
- vp2->note = key;
- vp2->chan = chan;
- vp2->state = SNDRV_OPL3_ST_NOT_AVAIL;
- } else {
- if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
- /* 4op killed by 2op, release bounded voice */
- vp2 = &opl3->voices[voice + 3];
- vp2->time = opl3->use_time++;
- vp2->state = SNDRV_OPL3_ST_OFF;
- }
- vp->state = SNDRV_OPL3_ST_ON_2OP;
- }
-
-#ifdef DEBUG_ALLOC
- debug_alloc(opl3, "note on ", voice);
-#endif
-
- /* allocate extra program if specified in patch library */
- if (extra_prg) {
- if (extra_prg > 128) {
- bank = 128;
- /* percussions start at 35 */
- prg = extra_prg - 128 + 35 - 1;
- } else {
- bank = 0;
- prg = extra_prg - 1;
- }
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " *** allocating extra program\n");
-#endif
- goto __extra_prg;
- }
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-}
-
-static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
-{
- unsigned short reg_side;
- unsigned char voice_offset;
- unsigned short opl3_reg;
-
- struct snd_opl3_voice *vp, *vp2;
-
- if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
- return;
-
- vp = &opl3->voices[voice];
- if (voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice - MAX_OPL2_VOICES;
- }
-
- /* kill voice */
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> kill voice %i\n", voice);
-#endif
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- /* clear Key ON bit */
- opl3->command(opl3, opl3_reg, vp->keyon_reg);
-
- /* do the bookkeeping */
- vp->time = opl3->use_time++;
-
- if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
- vp2 = &opl3->voices[voice + 3];
-
- vp2->time = opl3->use_time++;
- vp2->state = SNDRV_OPL3_ST_OFF;
- }
- vp->state = SNDRV_OPL3_ST_OFF;
-#ifdef DEBUG_ALLOC
- debug_alloc(opl3, "note off", voice);
-#endif
-
-}
-
-/*
- * Release a note in response to a midi note off.
- */
-static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
- struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- int voice;
- struct snd_opl3_voice *vp;
-
- opl3 = p;
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Note off, ch %i, inst %i, note %i\n",
- chan->number, chan->midi_program, note);
-#endif
-
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- if (chan->drum_channel && use_internal_drums) {
- snd_opl3_drum_switch(opl3, note, vel, 0, chan);
- return;
- }
- /* this loop will hopefully kill all extra voices, because
- they are grouped by the same channel and note values */
- for (voice = 0; voice < opl3->max_voices; voice++) {
- vp = &opl3->voices[voice];
- if (vp->state > 0 && vp->chan == chan && vp->note == note) {
- snd_opl3_kill_voice(opl3, voice);
- }
- }
- } else {
- /* remap OSS voices */
- if (chan->number < MAX_OPL3_VOICES) {
- voice = snd_opl3_oss_map[chan->number];
- snd_opl3_kill_voice(opl3, voice);
- }
- }
-}
-
-void snd_opl3_note_off(void *p, int note, int vel,
- struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3 = p;
- unsigned long flags;
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
- snd_opl3_note_off_unsafe(p, note, vel, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-}
-
-/*
- * key pressure change
- */
-void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Key pressure, ch#: %i, inst#: %i\n",
- chan->number, chan->midi_program);
-#endif
-}
-
-/*
- * terminate note
- */
-void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Terminate note, ch#: %i, inst#: %i\n",
- chan->number, chan->midi_program);
-#endif
-}
-
-static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
-{
- unsigned short reg_side;
- unsigned char voice_offset;
- unsigned short opl3_reg;
-
- unsigned char fnum, blocknum;
-
- struct snd_opl3_voice *vp;
-
- if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
- return;
-
- vp = &opl3->voices[voice];
- if (vp->chan == NULL)
- return; /* not allocated? */
-
- if (voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice - MAX_OPL2_VOICES;
- }
-
- snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan);
-
- /* Set OPL3 FNUM_LOW register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, fnum);
-
- vp->keyon_reg = blocknum;
-
- /* Set output sound flag */
- blocknum |= OPL3_KEYON_BIT;
-
- /* Set OPL3 KEYON_BLOCK register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, blocknum);
-
- vp->time = opl3->use_time++;
-}
-
-/*
- * Update voice pitch controller
- */
-static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *chan)
-{
- int voice;
- struct snd_opl3_voice *vp;
-
- unsigned long flags;
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
-
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- for (voice = 0; voice < opl3->max_voices; voice++) {
- vp = &opl3->voices[voice];
- if (vp->state > 0 && vp->chan == chan) {
- snd_opl3_update_pitch(opl3, voice);
- }
- }
- } else {
- /* remap OSS voices */
- if (chan->number < MAX_OPL3_VOICES) {
- voice = snd_opl3_oss_map[chan->number];
- snd_opl3_update_pitch(opl3, voice);
- }
- }
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-}
-
-/*
- * Deal with a controller type event. This includes all types of
- * control events, not just the midi controllers
- */
-void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Controller, TYPE = %i, ch#: %i, inst#: %i\n",
- type, chan->number, chan->midi_program);
-#endif
-
- switch (type) {
- case MIDI_CTL_MSB_MODWHEEL:
- if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63)
- opl3->drum_reg |= OPL3_VIBRATO_DEPTH;
- else
- opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
- opl3->drum_reg);
- break;
- case MIDI_CTL_E2_TREMOLO_DEPTH:
- if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63)
- opl3->drum_reg |= OPL3_TREMOLO_DEPTH;
- else
- opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
- opl3->drum_reg);
- break;
- case MIDI_CTL_PITCHBEND:
- snd_opl3_pitch_ctrl(opl3, chan);
- break;
- }
-}
-
-/*
- * NRPN events
- */
-void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "NRPN, ch#: %i, inst#: %i\n",
- chan->number, chan->midi_program);
-#endif
-}
-
-/*
- * receive sysex
- */
-void snd_opl3_sysex(void *p, unsigned char *buf, int len,
- int parsed, struct snd_midi_channel_set *chset)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "SYSEX\n");
-#endif
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c
deleted file mode 100644
index c1cb249a..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Interface for OSS sequencer emulation
- *
- * Copyright (C) 2000 Uros Bizjak <uros@kss-loka.si>
- *
- * 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 <linux/export.h>
-#include "opl3_voice.h"
-
-static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
-static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg);
-static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg);
-static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, const char __user *buf, int offs, int count);
-static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg);
-
-/* */
-
-static inline mm_segment_t snd_enter_user(void)
-{
- mm_segment_t fs = get_fs();
- set_fs(get_ds());
- return fs;
-}
-
-static inline void snd_leave_user(mm_segment_t fs)
-{
- set_fs(fs);
-}
-
-/* operators */
-
-extern struct snd_midi_op opl3_ops;
-
-static struct snd_seq_oss_callback oss_callback = {
- .owner = THIS_MODULE,
- .open = snd_opl3_open_seq_oss,
- .close = snd_opl3_close_seq_oss,
- .ioctl = snd_opl3_ioctl_seq_oss,
- .load_patch = snd_opl3_load_patch_seq_oss,
- .reset = snd_opl3_reset_seq_oss,
-};
-
-static int snd_opl3_oss_event_input(struct snd_seq_event *ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct snd_opl3 *opl3 = private_data;
-
- if (ev->type != SNDRV_SEQ_EVENT_OSS)
- snd_midi_process_event(&opl3_ops, ev, opl3->oss_chset);
- return 0;
-}
-
-/* ------------------------------ */
-
-static void snd_opl3_oss_free_port(void *private_data)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_midi_channel_free_set(opl3->oss_chset);
-}
-
-static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
-{
- struct snd_seq_port_callback callbacks;
- char name[32];
- int voices, opl_ver;
-
- voices = (opl3->hardware < OPL3_HW_OPL3) ?
- MAX_OPL2_VOICES : MAX_OPL3_VOICES;
- opl3->oss_chset = snd_midi_channel_alloc_set(voices);
- if (opl3->oss_chset == NULL)
- return -ENOMEM;
- opl3->oss_chset->private_data = opl3;
-
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.owner = THIS_MODULE;
- callbacks.event_input = snd_opl3_oss_event_input;
- callbacks.private_free = snd_opl3_oss_free_port;
- callbacks.private_data = opl3;
-
- opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
- sprintf(name, "OPL%i OSS Port", opl_ver);
-
- opl3->oss_chset->client = opl3->seq_client;
- opl3->oss_chset->port = snd_seq_event_port_attach(opl3->seq_client, &callbacks,
- SNDRV_SEQ_PORT_CAP_WRITE,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_MIDI_GM |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
- voices, voices,
- name);
- if (opl3->oss_chset->port < 0) {
- int port;
- port = opl3->oss_chset->port;
- snd_midi_channel_free_set(opl3->oss_chset);
- return port;
- }
- return 0;
-}
-
-/* ------------------------------ */
-
-/* register OSS synth */
-void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name)
-{
- struct snd_seq_oss_reg *arg;
- struct snd_seq_device *dev;
-
- if (snd_seq_device_new(opl3->card, 0, SNDRV_SEQ_DEV_ID_OSS,
- sizeof(struct snd_seq_oss_reg), &dev) < 0)
- return;
-
- opl3->oss_seq_dev = dev;
- strlcpy(dev->name, name, sizeof(dev->name));
- arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
- arg->type = SYNTH_TYPE_FM;
- if (opl3->hardware < OPL3_HW_OPL3) {
- arg->subtype = FM_TYPE_ADLIB;
- arg->nvoices = MAX_OPL2_VOICES;
- } else {
- arg->subtype = FM_TYPE_OPL3;
- arg->nvoices = MAX_OPL3_VOICES;
- }
- arg->oper = oss_callback;
- arg->private_data = opl3;
-
- if (snd_opl3_oss_create_port(opl3)) {
- /* register to OSS synth table */
- snd_device_register(opl3->card, dev);
- }
-}
-
-/* unregister */
-void snd_opl3_free_seq_oss(struct snd_opl3 *opl3)
-{
- if (opl3->oss_seq_dev) {
- /* The instance should have been released in prior */
- opl3->oss_seq_dev = NULL;
- }
-}
-
-/* ------------------------------ */
-
-/* open OSS sequencer */
-static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
-{
- struct snd_opl3 *opl3 = closure;
- int err;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
-
- if ((err = snd_opl3_synth_setup(opl3)) < 0)
- return err;
-
- /* fill the argument data */
- arg->private_data = opl3;
- arg->addr.client = opl3->oss_chset->client;
- arg->addr.port = opl3->oss_chset->port;
-
- if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
- return err;
-
- opl3->synth_mode = SNDRV_OPL3_MODE_SYNTH;
- return 0;
-}
-
-/* close OSS sequencer */
-static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg)
-{
- struct snd_opl3 *opl3;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
-
- snd_opl3_synth_cleanup(opl3);
-
- snd_opl3_synth_use_dec(opl3);
- return 0;
-}
-
-/* load patch */
-
-/* from sound_config.h */
-#define SBFM_MAXINSTR 256
-
-static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
- const char __user *buf, int offs, int count)
-{
- struct snd_opl3 *opl3;
- struct sbi_instrument sbi;
- char name[32];
- int err, type;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
-
- if (format == FM_PATCH)
- type = FM_PATCH_OPL2;
- else if (format == OPL3_PATCH)
- type = FM_PATCH_OPL3;
- else
- return -EINVAL;
-
- if (count < (int)sizeof(sbi)) {
- snd_printk(KERN_ERR "FM Error: Patch record too short\n");
- return -EINVAL;
- }
- if (copy_from_user(&sbi, buf, sizeof(sbi)))
- return -EFAULT;
-
- if (sbi.channel < 0 || sbi.channel >= SBFM_MAXINSTR) {
- snd_printk(KERN_ERR "FM Error: Invalid instrument number %d\n",
- sbi.channel);
- return -EINVAL;
- }
-
- memset(name, 0, sizeof(name));
- sprintf(name, "Chan%d", sbi.channel);
-
- err = snd_opl3_load_patch(opl3, sbi.channel, 127, type, name, NULL,
- sbi.operators);
- if (err < 0)
- return err;
-
- return sizeof(sbi);
-}
-
-/* ioctl */
-static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
- unsigned long ioarg)
-{
- struct snd_opl3 *opl3;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
- switch (cmd) {
- case SNDCTL_FM_LOAD_INSTR:
- snd_printk(KERN_ERR "OPL3: "
- "Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. "
- "Fix the program.\n");
- return -EINVAL;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
-
- case SNDCTL_FM_4OP_ENABLE:
- // handled automatically by OPL instrument type
- return 0;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/* reset device */
-static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg)
-{
- struct snd_opl3 *opl3;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c
deleted file mode 100644
index 68399538..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * Midi Sequencer interface routines for OPL2/OPL3/OPL4 FM
- *
- * OPL2/3 FM instrument loader:
- * alsa-tools/seq/sbiload/
- *
- * 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 "opl3_voice.h"
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include <linux/module.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ALSA driver for OPL3 FM synth");
-
-bool use_internal_drums = 0;
-module_param(use_internal_drums, bool, 0444);
-MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums.");
-
-int snd_opl3_synth_use_inc(struct snd_opl3 * opl3)
-{
- if (!try_module_get(opl3->card->module))
- return -EFAULT;
- return 0;
-
-}
-
-void snd_opl3_synth_use_dec(struct snd_opl3 * opl3)
-{
- module_put(opl3->card->module);
-}
-
-int snd_opl3_synth_setup(struct snd_opl3 * opl3)
-{
- int idx;
- struct snd_hwdep *hwdep = opl3->hwdep;
-
- mutex_lock(&hwdep->open_mutex);
- if (hwdep->used) {
- mutex_unlock(&hwdep->open_mutex);
- return -EBUSY;
- }
- hwdep->used++;
- mutex_unlock(&hwdep->open_mutex);
-
- snd_opl3_reset(opl3);
-
- for (idx = 0; idx < MAX_OPL3_VOICES; idx++) {
- opl3->voices[idx].state = SNDRV_OPL3_ST_OFF;
- opl3->voices[idx].time = 0;
- opl3->voices[idx].keyon_reg = 0x00;
- }
- opl3->use_time = 0;
- opl3->connection_reg = 0x00;
- if (opl3->hardware >= OPL3_HW_OPL3) {
- /* Clear 4-op connections */
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT,
- opl3->connection_reg);
- opl3->max_voices = MAX_OPL3_VOICES;
- }
- return 0;
-}
-
-void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
-{
- unsigned long flags;
- struct snd_hwdep *hwdep;
-
- /* Stop system timer */
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
- if (opl3->sys_timer_status) {
- del_timer(&opl3->tlist);
- opl3->sys_timer_status = 0;
- }
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
-
- snd_opl3_reset(opl3);
- hwdep = opl3->hwdep;
- mutex_lock(&hwdep->open_mutex);
- hwdep->used--;
- mutex_unlock(&hwdep->open_mutex);
- wake_up(&hwdep->open_wait);
-}
-
-static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
-{
- struct snd_opl3 *opl3 = private_data;
- int err;
-
- if ((err = snd_opl3_synth_setup(opl3)) < 0)
- return err;
-
- if (use_internal_drums) {
- /* Percussion mode */
- opl3->voices[6].state = opl3->voices[7].state =
- opl3->voices[8].state = SNDRV_OPL3_ST_NOT_AVAIL;
- snd_opl3_load_drums(opl3);
- opl3->drum_reg = OPL3_PERCUSSION_ENABLE;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, opl3->drum_reg);
- } else {
- opl3->drum_reg = 0x00;
- }
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
- if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
- return err;
- }
- opl3->synth_mode = SNDRV_OPL3_MODE_SEQ;
- return 0;
-}
-
-static int snd_opl3_synth_unuse(void *private_data, struct snd_seq_port_subscribe * info)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_opl3_synth_cleanup(opl3);
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
- snd_opl3_synth_use_dec(opl3);
- return 0;
-}
-
-/*
- * MIDI emulation operators
- */
-struct snd_midi_op opl3_ops = {
- .note_on = snd_opl3_note_on,
- .note_off = snd_opl3_note_off,
- .key_press = snd_opl3_key_press,
- .note_terminate = snd_opl3_terminate_note,
- .control = snd_opl3_control,
- .nrpn = snd_opl3_nrpn,
- .sysex = snd_opl3_sysex,
-};
-
-static int snd_opl3_synth_event_input(struct snd_seq_event * ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_midi_process_event(&opl3_ops, ev, opl3->chset);
- return 0;
-}
-
-/* ------------------------------ */
-
-static void snd_opl3_synth_free_port(void *private_data)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_midi_channel_free_set(opl3->chset);
-}
-
-static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
-{
- struct snd_seq_port_callback callbacks;
- char name[32];
- int voices, opl_ver;
-
- voices = (opl3->hardware < OPL3_HW_OPL3) ?
- MAX_OPL2_VOICES : MAX_OPL3_VOICES;
- opl3->chset = snd_midi_channel_alloc_set(16);
- if (opl3->chset == NULL)
- return -ENOMEM;
- opl3->chset->private_data = opl3;
-
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.owner = THIS_MODULE;
- callbacks.use = snd_opl3_synth_use;
- callbacks.unuse = snd_opl3_synth_unuse;
- callbacks.event_input = snd_opl3_synth_event_input;
- callbacks.private_free = snd_opl3_synth_free_port;
- callbacks.private_data = opl3;
-
- opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
- sprintf(name, "OPL%i FM Port", opl_ver);
-
- opl3->chset->client = opl3->seq_client;
- opl3->chset->port = snd_seq_event_port_attach(opl3->seq_client, &callbacks,
- SNDRV_SEQ_PORT_CAP_WRITE |
- SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_MIDI_GM |
- SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
- 16, voices,
- name);
- if (opl3->chset->port < 0) {
- int port;
- port = opl3->chset->port;
- snd_midi_channel_free_set(opl3->chset);
- return port;
- }
- return 0;
-}
-
-/* ------------------------------ */
-
-static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
-{
- struct snd_opl3 *opl3;
- int client, err;
- char name[32];
- int opl_ver;
-
- opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (opl3 == NULL)
- return -EINVAL;
-
- spin_lock_init(&opl3->voice_lock);
-
- opl3->seq_client = -1;
-
- /* allocate new client */
- opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
- sprintf(name, "OPL%i FM synth", opl_ver);
- client = opl3->seq_client =
- snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num,
- name);
- if (client < 0)
- return client;
-
- if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
- snd_seq_delete_kernel_client(client);
- opl3->seq_client = -1;
- return err;
- }
-
- /* setup system timer */
- init_timer(&opl3->tlist);
- opl3->tlist.function = snd_opl3_timer_func;
- opl3->tlist.data = (unsigned long) opl3;
- spin_lock_init(&opl3->sys_timer_lock);
- opl3->sys_timer_status = 0;
-
-#ifdef CONFIG_SND_SEQUENCER_OSS
- snd_opl3_init_seq_oss(opl3, name);
-#endif
- return 0;
-}
-
-static int snd_opl3_seq_delete_device(struct snd_seq_device *dev)
-{
- struct snd_opl3 *opl3;
-
- opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (opl3 == NULL)
- return -EINVAL;
-
-#ifdef CONFIG_SND_SEQUENCER_OSS
- snd_opl3_free_seq_oss(opl3);
-#endif
- if (opl3->seq_client >= 0) {
- snd_seq_delete_kernel_client(opl3->seq_client);
- opl3->seq_client = -1;
- }
- return 0;
-}
-
-static int __init alsa_opl3_seq_init(void)
-{
- static struct snd_seq_dev_ops ops =
- {
- snd_opl3_seq_new_device,
- snd_opl3_seq_delete_device
- };
-
- return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL3, &ops,
- sizeof(struct snd_opl3 *));
-}
-
-static void __exit alsa_opl3_seq_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL3);
-}
-
-module_init(alsa_opl3_seq_init)
-module_exit(alsa_opl3_seq_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c
deleted file mode 100644
index 742a4b64..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * Routines for OPL2/OPL3/OPL4 control
- *
- * 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 <linux/slab.h>
-#include <linux/export.h>
-#include <sound/opl3.h>
-#include <sound/asound_fm.h>
-
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
-#define OPL3_SUPPORT_SYNTH
-#endif
-
-/*
- * There is 18 possible 2 OP voices
- * (9 in the left and 9 in the right).
- * The first OP is the modulator and 2nd is the carrier.
- *
- * The first three voices in the both sides may be connected
- * with another voice to a 4 OP voice. For example voice 0
- * can be connected with voice 3. The operators of voice 3 are
- * used as operators 3 and 4 of the new 4 OP voice.
- * In this case the 2 OP voice number 0 is the 'first half' and
- * voice 3 is the second.
- */
-
-
-/*
- * Register offset table for OPL2/3 voices,
- * OPL2 / one OPL3 register array side only
- */
-
-char snd_opl3_regmap[MAX_OPL2_VOICES][4] =
-{
-/* OP1 OP2 OP3 OP4 */
-/* ------------------------ */
- { 0x00, 0x03, 0x08, 0x0b },
- { 0x01, 0x04, 0x09, 0x0c },
- { 0x02, 0x05, 0x0a, 0x0d },
-
- { 0x08, 0x0b, 0x00, 0x00 },
- { 0x09, 0x0c, 0x00, 0x00 },
- { 0x0a, 0x0d, 0x00, 0x00 },
-
- { 0x10, 0x13, 0x00, 0x00 }, /* used by percussive voices */
- { 0x11, 0x14, 0x00, 0x00 }, /* if the percussive mode */
- { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */
-};
-
-EXPORT_SYMBOL(snd_opl3_regmap);
-
-/*
- * prototypes
- */
-static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note);
-static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice);
-static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params);
-static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode);
-static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection);
-
-/* ------------------------------ */
-
-/*
- * open the device exclusively
- */
-int snd_opl3_open(struct snd_hwdep * hw, struct file *file)
-{
- return 0;
-}
-
-/*
- * ioctl for hwdep device:
- */
-int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct snd_opl3 *opl3 = hw->private_data;
- void __user *argp = (void __user *)arg;
-
- if (snd_BUG_ON(!opl3))
- return -EINVAL;
-
- switch (cmd) {
- /* get information */
- case SNDRV_DM_FM_IOCTL_INFO:
- {
- struct snd_dm_fm_info info;
-
- info.fm_mode = opl3->fm_mode;
- info.rhythm = opl3->rhythm;
- if (copy_to_user(argp, &info, sizeof(struct snd_dm_fm_info)))
- return -EFAULT;
- return 0;
- }
-
- case SNDRV_DM_FM_IOCTL_RESET:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_RESET:
-#endif
- snd_opl3_reset(opl3);
- return 0;
-
- case SNDRV_DM_FM_IOCTL_PLAY_NOTE:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE:
-#endif
- {
- struct snd_dm_fm_note note;
- if (copy_from_user(&note, argp, sizeof(struct snd_dm_fm_note)))
- return -EFAULT;
- return snd_opl3_play_note(opl3, &note);
- }
-
- case SNDRV_DM_FM_IOCTL_SET_VOICE:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_VOICE:
-#endif
- {
- struct snd_dm_fm_voice voice;
- if (copy_from_user(&voice, argp, sizeof(struct snd_dm_fm_voice)))
- return -EFAULT;
- return snd_opl3_set_voice(opl3, &voice);
- }
-
- case SNDRV_DM_FM_IOCTL_SET_PARAMS:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS:
-#endif
- {
- struct snd_dm_fm_params params;
- if (copy_from_user(&params, argp, sizeof(struct snd_dm_fm_params)))
- return -EFAULT;
- return snd_opl3_set_params(opl3, &params);
- }
-
- case SNDRV_DM_FM_IOCTL_SET_MODE:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_MODE:
-#endif
- return snd_opl3_set_mode(opl3, (int) arg);
-
- case SNDRV_DM_FM_IOCTL_SET_CONNECTION:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_OPL:
-#endif
- return snd_opl3_set_connection(opl3, (int) arg);
-
-#ifdef OPL3_SUPPORT_SYNTH
- case SNDRV_DM_FM_IOCTL_CLEAR_PATCHES:
- snd_opl3_clear_patches(opl3);
- return 0;
-#endif
-
-#ifdef CONFIG_SND_DEBUG
- default:
- snd_printk(KERN_WARNING "unknown IOCTL: 0x%x\n", cmd);
-#endif
- }
- return -ENOTTY;
-}
-
-/*
- * close the device
- */
-int snd_opl3_release(struct snd_hwdep * hw, struct file *file)
-{
- struct snd_opl3 *opl3 = hw->private_data;
-
- snd_opl3_reset(opl3);
- return 0;
-}
-
-#ifdef OPL3_SUPPORT_SYNTH
-/*
- * write the device - load patches
- */
-long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
- loff_t *offset)
-{
- struct snd_opl3 *opl3 = hw->private_data;
- long result = 0;
- int err = 0;
- struct sbi_patch inst;
-
- while (count >= sizeof(inst)) {
- unsigned char type;
- if (copy_from_user(&inst, buf, sizeof(inst)))
- return -EFAULT;
- if (!memcmp(inst.key, FM_KEY_SBI, 4) ||
- !memcmp(inst.key, FM_KEY_2OP, 4))
- type = FM_PATCH_OPL2;
- else if (!memcmp(inst.key, FM_KEY_4OP, 4))
- type = FM_PATCH_OPL3;
- else /* invalid type */
- break;
- err = snd_opl3_load_patch(opl3, inst.prog, inst.bank, type,
- inst.name, inst.extension,
- inst.data);
- if (err < 0)
- break;
- result += sizeof(inst);
- count -= sizeof(inst);
- }
- return result > 0 ? result : err;
-}
-
-
-/*
- * Patch management
- */
-
-/* offsets for SBI params */
-#define AM_VIB 0
-#define KSL_LEVEL 2
-#define ATTACK_DECAY 4
-#define SUSTAIN_RELEASE 6
-#define WAVE_SELECT 8
-
-/* offset for SBI instrument */
-#define CONNECTION 10
-#define OFFSET_4OP 11
-
-/*
- * load a patch, obviously.
- *
- * loaded on the given program and bank numbers with the given type
- * (FM_PATCH_OPLx).
- * data is the pointer of SBI record _without_ header (key and name).
- * name is the name string of the patch.
- * ext is the extension data of 7 bytes long (stored in name of SBI
- * data up to offset 25), or NULL to skip.
- * return 0 if successful or a negative error code.
- */
-int snd_opl3_load_patch(struct snd_opl3 *opl3,
- int prog, int bank, int type,
- const char *name,
- const unsigned char *ext,
- const unsigned char *data)
-{
- struct fm_patch *patch;
- int i;
-
- patch = snd_opl3_find_patch(opl3, prog, bank, 1);
- if (!patch)
- return -ENOMEM;
-
- patch->type = type;
-
- for (i = 0; i < 2; i++) {
- patch->inst.op[i].am_vib = data[AM_VIB + i];
- patch->inst.op[i].ksl_level = data[KSL_LEVEL + i];
- patch->inst.op[i].attack_decay = data[ATTACK_DECAY + i];
- patch->inst.op[i].sustain_release = data[SUSTAIN_RELEASE + i];
- patch->inst.op[i].wave_select = data[WAVE_SELECT + i];
- }
- patch->inst.feedback_connection[0] = data[CONNECTION];
-
- if (type == FM_PATCH_OPL3) {
- for (i = 0; i < 2; i++) {
- patch->inst.op[i+2].am_vib =
- data[OFFSET_4OP + AM_VIB + i];
- patch->inst.op[i+2].ksl_level =
- data[OFFSET_4OP + KSL_LEVEL + i];
- patch->inst.op[i+2].attack_decay =
- data[OFFSET_4OP + ATTACK_DECAY + i];
- patch->inst.op[i+2].sustain_release =
- data[OFFSET_4OP + SUSTAIN_RELEASE + i];
- patch->inst.op[i+2].wave_select =
- data[OFFSET_4OP + WAVE_SELECT + i];
- }
- patch->inst.feedback_connection[1] =
- data[OFFSET_4OP + CONNECTION];
- }
-
- if (ext) {
- patch->inst.echo_delay = ext[0];
- patch->inst.echo_atten = ext[1];
- patch->inst.chorus_spread = ext[2];
- patch->inst.trnsps = ext[3];
- patch->inst.fix_dur = ext[4];
- patch->inst.modes = ext[5];
- patch->inst.fix_key = ext[6];
- }
-
- if (name)
- strlcpy(patch->name, name, sizeof(patch->name));
-
- return 0;
-}
-EXPORT_SYMBOL(snd_opl3_load_patch);
-
-/*
- * find a patch with the given program and bank numbers, returns its pointer
- * if no matching patch is found and create_patch is set, it creates a
- * new patch object.
- */
-struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank,
- int create_patch)
-{
- /* pretty dumb hash key */
- unsigned int key = (prog + bank) % OPL3_PATCH_HASH_SIZE;
- struct fm_patch *patch;
-
- for (patch = opl3->patch_table[key]; patch; patch = patch->next) {
- if (patch->prog == prog && patch->bank == bank)
- return patch;
- }
- if (!create_patch)
- return NULL;
-
- patch = kzalloc(sizeof(*patch), GFP_KERNEL);
- if (!patch)
- return NULL;
- patch->prog = prog;
- patch->bank = bank;
- patch->next = opl3->patch_table[key];
- opl3->patch_table[key] = patch;
- return patch;
-}
-EXPORT_SYMBOL(snd_opl3_find_patch);
-
-/*
- * Clear all patches of the given OPL3 instance
- */
-void snd_opl3_clear_patches(struct snd_opl3 *opl3)
-{
- int i;
- for (i = 0; i < OPL3_PATCH_HASH_SIZE; i++) {
- struct fm_patch *patch, *next;
- for (patch = opl3->patch_table[i]; patch; patch = next) {
- next = patch->next;
- kfree(patch);
- }
- }
- memset(opl3->patch_table, 0, sizeof(opl3->patch_table));
-}
-#endif /* OPL3_SUPPORT_SYNTH */
-
-/* ------------------------------ */
-
-void snd_opl3_reset(struct snd_opl3 * opl3)
-{
- unsigned short opl3_reg;
-
- unsigned short reg_side;
- unsigned char voice_offset;
-
- int max_voices, i;
-
- max_voices = (opl3->hardware < OPL3_HW_OPL3) ?
- MAX_OPL2_VOICES : MAX_OPL3_VOICES;
-
- for (i = 0; i < max_voices; i++) {
- /* Get register array side and offset of voice */
- if (i < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = i;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = i - MAX_OPL2_VOICES;
- }
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][0]);
- opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 1 volume */
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][1]);
- opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 2 volume */
-
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, 0x00); /* Note off */
- }
-
- opl3->max_voices = MAX_OPL2_VOICES;
- opl3->fm_mode = SNDRV_DM_FM_MODE_OPL2;
-
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */
- opl3->rhythm = 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_reset);
-
-static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note)
-{
- unsigned short reg_side;
- unsigned char voice_offset;
-
- unsigned short opl3_reg;
- unsigned char reg_val;
-
- /* Voices 0 - 8 in OPL2 mode */
- /* Voices 0 - 17 in OPL3 mode */
- if (note->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ?
- MAX_OPL3_VOICES : MAX_OPL2_VOICES))
- return -EINVAL;
-
- /* Get register array side and offset of voice */
- if (note->voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = note->voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = note->voice - MAX_OPL2_VOICES;
- }
-
- /* Set lower 8 bits of note frequency */
- reg_val = (unsigned char) note->fnum;
- opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- reg_val = 0x00;
- /* Set output sound flag */
- if (note->key_on)
- reg_val |= OPL3_KEYON_BIT;
- /* Set octave */
- reg_val |= (note->octave << 2) & OPL3_BLOCKNUM_MASK;
- /* Set higher 2 bits of note frequency */
- reg_val |= (unsigned char) (note->fnum >> 8) & OPL3_FNUM_HIGH_MASK;
-
- /* Set OPL3 KEYON_BLOCK register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- return 0;
-}
-
-
-static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice)
-{
- unsigned short reg_side;
- unsigned char op_offset;
- unsigned char voice_offset;
-
- unsigned short opl3_reg;
- unsigned char reg_val;
-
- /* Only operators 1 and 2 */
- if (voice->op > 1)
- return -EINVAL;
- /* Voices 0 - 8 in OPL2 mode */
- /* Voices 0 - 17 in OPL3 mode */
- if (voice->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ?
- MAX_OPL3_VOICES : MAX_OPL2_VOICES))
- return -EINVAL;
-
- /* Get register array side and offset of voice */
- if (voice->voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice->voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice->voice - MAX_OPL2_VOICES;
- }
- /* Get register offset of operator */
- op_offset = snd_opl3_regmap[voice_offset][voice->op];
-
- reg_val = 0x00;
- /* Set amplitude modulation (tremolo) effect */
- if (voice->am)
- reg_val |= OPL3_TREMOLO_ON;
- /* Set vibrato effect */
- if (voice->vibrato)
- reg_val |= OPL3_VIBRATO_ON;
- /* Set sustaining sound phase */
- if (voice->do_sustain)
- reg_val |= OPL3_SUSTAIN_ON;
- /* Set keyboard scaling bit */
- if (voice->kbd_scale)
- reg_val |= OPL3_KSR;
- /* Set harmonic or frequency multiplier */
- reg_val |= voice->harmonic & OPL3_MULTIPLE_MASK;
-
- /* Set OPL3 AM_VIB register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set decreasing volume of higher notes */
- reg_val = (voice->scale_level << 6) & OPL3_KSL_MASK;
- /* Set output volume */
- reg_val |= ~voice->volume & OPL3_TOTAL_LEVEL_MASK;
-
- /* Set OPL3 KSL_LEVEL register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set attack phase level */
- reg_val = (voice->attack << 4) & OPL3_ATTACK_MASK;
- /* Set decay phase level */
- reg_val |= voice->decay & OPL3_DECAY_MASK;
-
- /* Set OPL3 ATTACK_DECAY register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set sustain phase level */
- reg_val = (voice->sustain << 4) & OPL3_SUSTAIN_MASK;
- /* Set release phase level */
- reg_val |= voice->release & OPL3_RELEASE_MASK;
-
- /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set inter-operator feedback */
- reg_val = (voice->feedback << 1) & OPL3_FEEDBACK_MASK;
- /* Set inter-operator connection */
- if (voice->connection)
- reg_val |= OPL3_CONNECTION_BIT;
- /* OPL-3 only */
- if (opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) {
- if (voice->left)
- reg_val |= OPL3_VOICE_TO_LEFT;
- if (voice->right)
- reg_val |= OPL3_VOICE_TO_RIGHT;
- }
- /* Feedback/connection bits are applicable to voice */
- opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Select waveform */
- reg_val = voice->waveform & OPL3_WAVE_SELECT_MASK;
- opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- return 0;
-}
-
-static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params)
-{
- unsigned char reg_val;
-
- reg_val = 0x00;
- /* Set keyboard split method */
- if (params->kbd_split)
- reg_val |= OPL3_KEYBOARD_SPLIT;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_KBD_SPLIT, reg_val);
-
- reg_val = 0x00;
- /* Set amplitude modulation (tremolo) depth */
- if (params->am_depth)
- reg_val |= OPL3_TREMOLO_DEPTH;
- /* Set vibrato depth */
- if (params->vib_depth)
- reg_val |= OPL3_VIBRATO_DEPTH;
- /* Set percussion mode */
- if (params->rhythm) {
- reg_val |= OPL3_PERCUSSION_ENABLE;
- opl3->rhythm = 1;
- } else {
- opl3->rhythm = 0;
- }
- /* Play percussion instruments */
- if (params->bass)
- reg_val |= OPL3_BASSDRUM_ON;
- if (params->snare)
- reg_val |= OPL3_SNAREDRUM_ON;
- if (params->tomtom)
- reg_val |= OPL3_TOMTOM_ON;
- if (params->cymbal)
- reg_val |= OPL3_CYMBAL_ON;
- if (params->hihat)
- reg_val |= OPL3_HIHAT_ON;
-
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, reg_val);
- return 0;
-}
-
-static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode)
-{
- if ((mode == SNDRV_DM_FM_MODE_OPL3) && (opl3->hardware < OPL3_HW_OPL3))
- return -EINVAL;
-
- opl3->fm_mode = mode;
- if (opl3->hardware >= OPL3_HW_OPL3)
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, 0x00); /* Clear 4-op connections */
-
- return 0;
-}
-
-static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection)
-{
- unsigned char reg_val;
-
- /* OPL-3 only */
- if (opl3->fm_mode != SNDRV_DM_FM_MODE_OPL3)
- return -EINVAL;
-
- reg_val = connection & (OPL3_RIGHT_4OP_0 | OPL3_RIGHT_4OP_1 | OPL3_RIGHT_4OP_2 |
- OPL3_LEFT_4OP_0 | OPL3_LEFT_4OP_1 | OPL3_LEFT_4OP_2);
- /* Set 4-op connections */
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, reg_val);
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h b/ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h
deleted file mode 100644
index a371c075..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __OPL3_VOICE_H
-#define __OPL3_VOICE_H
-
-/*
- * Copyright (c) 2000 Uros Bizjak <uros@kss-loka.si>
- *
- * 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/opl3.h>
-
-/* Prototypes for opl3_seq.c */
-int snd_opl3_synth_use_inc(struct snd_opl3 * opl3);
-void snd_opl3_synth_use_dec(struct snd_opl3 * opl3);
-int snd_opl3_synth_setup(struct snd_opl3 * opl3);
-void snd_opl3_synth_cleanup(struct snd_opl3 * opl3);
-
-/* Prototypes for opl3_midi.c */
-void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan);
-void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan);
-void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, struct snd_midi_channel_set *chset);
-void snd_opl3_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);
-
-void snd_opl3_calc_volume(unsigned char *reg, int vel, struct snd_midi_channel *chan);
-void snd_opl3_timer_func(unsigned long data);
-
-/* Prototypes for opl3_drums.c */
-void snd_opl3_load_drums(struct snd_opl3 *opl3);
-void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int on_off, int vel, struct snd_midi_channel *chan);
-
-/* Prototypes for opl3_oss.c */
-#ifdef CONFIG_SND_SEQUENCER_OSS
-void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name);
-void snd_opl3_free_seq_oss(struct snd_opl3 *opl3);
-#endif
-
-#endif
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/Makefile b/ANDROID_3.4.5/sound/drivers/opl4/Makefile
deleted file mode 100644
index b94009b0..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-opl4-lib-objs := opl4_lib.o opl4_mixer.o opl4_proc.o
-snd-opl4-synth-objs := opl4_seq.o opl4_synth.o yrw801.o
-
-obj-$(CONFIG_SND_OPL4_LIB) += snd-opl4-lib.o
-obj-$(CONFIG_SND_OPL4_LIB_SEQ) += snd-opl4-synth.o
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c
deleted file mode 100644
index b953fb4a..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Functions for accessing OPL4 devices
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- *
- * 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 "opl4_local.h"
-#include <sound/initval.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <asm/io.h>
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("OPL4 driver");
-MODULE_LICENSE("GPL");
-
-static void inline snd_opl4_wait(struct snd_opl4 *opl4)
-{
- int timeout = 10;
- while ((inb(opl4->fm_port) & OPL4_STATUS_BUSY) && --timeout > 0)
- ;
-}
-
-void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value)
-{
- snd_opl4_wait(opl4);
- outb(reg, opl4->pcm_port);
-
- snd_opl4_wait(opl4);
- outb(value, opl4->pcm_port + 1);
-}
-
-EXPORT_SYMBOL(snd_opl4_write);
-
-u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg)
-{
- snd_opl4_wait(opl4);
- outb(reg, opl4->pcm_port);
-
- snd_opl4_wait(opl4);
- return inb(opl4->pcm_port + 1);
-}
-
-EXPORT_SYMBOL(snd_opl4_read);
-
-void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size)
-{
- unsigned long flags;
- u8 memcfg;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
-
- memcfg = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg | OPL4_MODE_BIT);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_HIGH, offset >> 16);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_MID, offset >> 8);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_LOW, offset);
-
- snd_opl4_wait(opl4);
- outb(OPL4_REG_MEMORY_DATA, opl4->pcm_port);
- snd_opl4_wait(opl4);
- insb(opl4->pcm_port + 1, buf, size);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg);
-
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-EXPORT_SYMBOL(snd_opl4_read_memory);
-
-void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size)
-{
- unsigned long flags;
- u8 memcfg;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
-
- memcfg = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg | OPL4_MODE_BIT);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_HIGH, offset >> 16);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_MID, offset >> 8);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_LOW, offset);
-
- snd_opl4_wait(opl4);
- outb(OPL4_REG_MEMORY_DATA, opl4->pcm_port);
- snd_opl4_wait(opl4);
- outsb(opl4->pcm_port + 1, buf, size);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg);
-
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-EXPORT_SYMBOL(snd_opl4_write_memory);
-
-static void snd_opl4_enable_opl4(struct snd_opl4 *opl4)
-{
- outb(OPL3_REG_MODE, opl4->fm_port + 2);
- inb(opl4->fm_port);
- inb(opl4->fm_port);
- outb(OPL3_OPL3_ENABLE | OPL3_OPL4_ENABLE, opl4->fm_port + 3);
- inb(opl4->fm_port);
- inb(opl4->fm_port);
-}
-
-static int snd_opl4_detect(struct snd_opl4 *opl4)
-{
- u8 id1, id2;
-
- snd_opl4_enable_opl4(opl4);
-
- id1 = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
- snd_printdd("OPL4[02]=%02x\n", id1);
- switch (id1 & OPL4_DEVICE_ID_MASK) {
- case 0x20:
- opl4->hardware = OPL3_HW_OPL4;
- break;
- case 0x40:
- opl4->hardware = OPL3_HW_OPL4_ML;
- break;
- default:
- return -ENODEV;
- }
-
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_FM, 0x00);
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_PCM, 0xff);
- id1 = snd_opl4_read(opl4, OPL4_REG_MIX_CONTROL_FM);
- id2 = snd_opl4_read(opl4, OPL4_REG_MIX_CONTROL_PCM);
- snd_printdd("OPL4 id1=%02x id2=%02x\n", id1, id2);
- if (id1 != 0x00 || id2 != 0xff)
- return -ENODEV;
-
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_FM, 0x3f);
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_PCM, 0x3f);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, 0x00);
- return 0;
-}
-
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-static void snd_opl4_seq_dev_free(struct snd_seq_device *seq_dev)
-{
- struct snd_opl4 *opl4 = seq_dev->private_data;
- opl4->seq_dev = NULL;
-}
-
-static int snd_opl4_create_seq_dev(struct snd_opl4 *opl4, int seq_device)
-{
- opl4->seq_dev_num = seq_device;
- if (snd_seq_device_new(opl4->card, seq_device, SNDRV_SEQ_DEV_ID_OPL4,
- sizeof(struct snd_opl4 *), &opl4->seq_dev) >= 0) {
- strcpy(opl4->seq_dev->name, "OPL4 Wavetable");
- *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(opl4->seq_dev) = opl4;
- opl4->seq_dev->private_data = opl4;
- opl4->seq_dev->private_free = snd_opl4_seq_dev_free;
- }
- return 0;
-}
-#endif
-
-static void snd_opl4_free(struct snd_opl4 *opl4)
-{
-#ifdef CONFIG_PROC_FS
- snd_opl4_free_proc(opl4);
-#endif
- release_and_free_resource(opl4->res_fm_port);
- release_and_free_resource(opl4->res_pcm_port);
- kfree(opl4);
-}
-
-static int snd_opl4_dev_free(struct snd_device *device)
-{
- struct snd_opl4 *opl4 = device->device_data;
- snd_opl4_free(opl4);
- return 0;
-}
-
-int snd_opl4_create(struct snd_card *card,
- unsigned long fm_port, unsigned long pcm_port,
- int seq_device,
- struct snd_opl3 **ropl3, struct snd_opl4 **ropl4)
-{
- struct snd_opl4 *opl4;
- struct snd_opl3 *opl3;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_opl4_dev_free
- };
-
- if (ropl3)
- *ropl3 = NULL;
- if (ropl4)
- *ropl4 = NULL;
-
- opl4 = kzalloc(sizeof(*opl4), GFP_KERNEL);
- if (!opl4)
- return -ENOMEM;
-
- opl4->res_fm_port = request_region(fm_port, 8, "OPL4 FM");
- opl4->res_pcm_port = request_region(pcm_port, 8, "OPL4 PCM/MIX");
- if (!opl4->res_fm_port || !opl4->res_pcm_port) {
- snd_printk(KERN_ERR "opl4: can't grab ports 0x%lx, 0x%lx\n", fm_port, pcm_port);
- snd_opl4_free(opl4);
- return -EBUSY;
- }
-
- opl4->card = card;
- opl4->fm_port = fm_port;
- opl4->pcm_port = pcm_port;
- spin_lock_init(&opl4->reg_lock);
- mutex_init(&opl4->access_mutex);
-
- err = snd_opl4_detect(opl4);
- if (err < 0) {
- snd_opl4_free(opl4);
- snd_printd("OPL4 chip not detected at %#lx/%#lx\n", fm_port, pcm_port);
- return err;
- }
-
- err = snd_device_new(card, SNDRV_DEV_CODEC, opl4, &ops);
- if (err < 0) {
- snd_opl4_free(opl4);
- return err;
- }
-
- err = snd_opl3_create(card, fm_port, fm_port + 2, opl4->hardware, 1, &opl3);
- if (err < 0) {
- snd_device_free(card, opl4);
- return err;
- }
-
- /* opl3 initialization disabled opl4, so reenable */
- snd_opl4_enable_opl4(opl4);
-
- snd_opl4_create_mixer(opl4);
-#ifdef CONFIG_PROC_FS
- snd_opl4_create_proc(opl4);
-#endif
-
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- opl4->seq_client = -1;
- if (opl4->hardware < OPL3_HW_OPL4_ML)
- snd_opl4_create_seq_dev(opl4, seq_device);
-#endif
-
- if (ropl3)
- *ropl3 = opl3;
- if (ropl4)
- *ropl4 = opl4;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl4_create);
-
-static int __init alsa_opl4_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_opl4_exit(void)
-{
-}
-
-module_init(alsa_opl4_init)
-module_exit(alsa_opl4_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h b/ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h
deleted file mode 100644
index 470e5a75..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Local definitions for the OPL4 driver
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified 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 SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef __OPL4_LOCAL_H
-#define __OPL4_LOCAL_H
-
-#include <sound/opl4.h>
-
-/*
- * Register numbers
- */
-
-#define OPL4_REG_TEST0 0x00
-#define OPL4_REG_TEST1 0x01
-
-#define OPL4_REG_MEMORY_CONFIGURATION 0x02
-#define OPL4_MODE_BIT 0x01
-#define OPL4_MTYPE_BIT 0x02
-#define OPL4_TONE_HEADER_MASK 0x1c
-#define OPL4_DEVICE_ID_MASK 0xe0
-
-#define OPL4_REG_MEMORY_ADDRESS_HIGH 0x03
-#define OPL4_REG_MEMORY_ADDRESS_MID 0x04
-#define OPL4_REG_MEMORY_ADDRESS_LOW 0x05
-#define OPL4_REG_MEMORY_DATA 0x06
-
-/*
- * Offsets to the register banks for voices. To get the
- * register number just add the voice number to the bank offset.
- *
- * Wave Table Number low bits (0x08 to 0x1F)
- */
-#define OPL4_REG_TONE_NUMBER 0x08
-
-/* Wave Table Number high bit, F-Number low bits (0x20 to 0x37) */
-#define OPL4_REG_F_NUMBER 0x20
-#define OPL4_TONE_NUMBER_BIT8 0x01
-#define OPL4_F_NUMBER_LOW_MASK 0xfe
-
-/* F-Number high bits, Octave, Pseudo-Reverb (0x38 to 0x4F) */
-#define OPL4_REG_OCTAVE 0x38
-#define OPL4_F_NUMBER_HIGH_MASK 0x07
-#define OPL4_BLOCK_MASK 0xf0
-#define OPL4_PSEUDO_REVERB_BIT 0x08
-
-/* Total Level, Level Direct (0x50 to 0x67) */
-#define OPL4_REG_LEVEL 0x50
-#define OPL4_TOTAL_LEVEL_MASK 0xfe
-#define OPL4_LEVEL_DIRECT_BIT 0x01
-
-/* Key On, Damp, LFO RST, CH, Panpot (0x68 to 0x7F) */
-#define OPL4_REG_MISC 0x68
-#define OPL4_KEY_ON_BIT 0x80
-#define OPL4_DAMP_BIT 0x40
-#define OPL4_LFO_RESET_BIT 0x20
-#define OPL4_OUTPUT_CHANNEL_BIT 0x10
-#define OPL4_PAN_POT_MASK 0x0f
-
-/* LFO, VIB (0x80 to 0x97) */
-#define OPL4_REG_LFO_VIBRATO 0x80
-#define OPL4_LFO_FREQUENCY_MASK 0x38
-#define OPL4_VIBRATO_DEPTH_MASK 0x07
-#define OPL4_CHORUS_SEND_MASK 0xc0 /* ML only */
-
-/* Attack / Decay 1 rate (0x98 to 0xAF) */
-#define OPL4_REG_ATTACK_DECAY1 0x98
-#define OPL4_ATTACK_RATE_MASK 0xf0
-#define OPL4_DECAY1_RATE_MASK 0x0f
-
-/* Decay level / 2 rate (0xB0 to 0xC7) */
-#define OPL4_REG_LEVEL_DECAY2 0xb0
-#define OPL4_DECAY_LEVEL_MASK 0xf0
-#define OPL4_DECAY2_RATE_MASK 0x0f
-
-/* Release rate / Rate correction (0xC8 to 0xDF) */
-#define OPL4_REG_RELEASE_CORRECTION 0xc8
-#define OPL4_RELEASE_RATE_MASK 0x0f
-#define OPL4_RATE_INTERPOLATION_MASK 0xf0
-
-/* AM (0xE0 to 0xF7) */
-#define OPL4_REG_TREMOLO 0xe0
-#define OPL4_TREMOLO_DEPTH_MASK 0x07
-#define OPL4_REVERB_SEND_MASK 0xe0 /* ML only */
-
-/* Mixer */
-#define OPL4_REG_MIX_CONTROL_FM 0xf8
-#define OPL4_REG_MIX_CONTROL_PCM 0xf9
-#define OPL4_MIX_LEFT_MASK 0x07
-#define OPL4_MIX_RIGHT_MASK 0x38
-
-#define OPL4_REG_ATC 0xfa
-#define OPL4_ATC_BIT 0x01 /* ???, ML only */
-
-/* bits in the OPL3 Status register */
-#define OPL4_STATUS_BUSY 0x01
-#define OPL4_STATUS_LOAD 0x02
-
-
-#define OPL4_MAX_VOICES 24
-
-#define SNDRV_SEQ_DEV_ID_OPL4 "opl4-synth"
-
-
-struct opl4_sound {
- u16 tone;
- s16 pitch_offset;
- u8 key_scaling;
- s8 panpot;
- u8 vibrato;
- u8 tone_attenuate;
- u8 volume_factor;
- u8 reg_lfo_vibrato;
- u8 reg_attack_decay1;
- u8 reg_level_decay2;
- u8 reg_release_correction;
- u8 reg_tremolo;
-};
-
-struct opl4_region {
- u8 key_min, key_max;
- struct opl4_sound sound;
-};
-
-struct opl4_region_ptr {
- int count;
- const struct opl4_region *regions;
-};
-
-struct opl4_voice {
- struct list_head list;
- int number;
- struct snd_midi_channel *chan;
- int note;
- int velocity;
- const struct opl4_sound *sound;
- u8 level_direct;
- u8 reg_f_number;
- u8 reg_misc;
- u8 reg_lfo_vibrato;
-};
-
-struct snd_opl4 {
- unsigned long fm_port;
- unsigned long pcm_port;
- struct resource *res_fm_port;
- struct resource *res_pcm_port;
- unsigned short hardware;
- spinlock_t reg_lock;
- struct snd_card *card;
-
-#ifdef CONFIG_PROC_FS
- struct snd_info_entry *proc_entry;
- int memory_access;
-#endif
- struct mutex access_mutex;
-
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
- int used;
-
- int seq_dev_num;
- int seq_client;
- struct snd_seq_device *seq_dev;
-
- struct snd_midi_channel_set *chset;
- struct opl4_voice voices[OPL4_MAX_VOICES];
- struct list_head off_voices;
- struct list_head on_voices;
-#endif
-};
-
-/* opl4_lib.c */
-void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value);
-u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg);
-void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size);
-void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size);
-
-/* opl4_mixer.c */
-int snd_opl4_create_mixer(struct snd_opl4 *opl4);
-
-#ifdef CONFIG_PROC_FS
-/* opl4_proc.c */
-int snd_opl4_create_proc(struct snd_opl4 *opl4);
-void snd_opl4_free_proc(struct snd_opl4 *opl4);
-#endif
-
-/* opl4_seq.c */
-extern int volume_boost;
-
-/* opl4_synth.c */
-void snd_opl4_synth_reset(struct snd_opl4 *opl4);
-void snd_opl4_synth_shutdown(struct snd_opl4 *opl4);
-void snd_opl4_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl4_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl4_terminate_note(void *p, int note, struct snd_midi_channel *chan);
-void snd_opl4_control(void *p, int type, struct snd_midi_channel *chan);
-void snd_opl4_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);
-
-/* yrw801.c */
-int snd_yrw801_detect(struct snd_opl4 *opl4);
-extern const struct opl4_region_ptr snd_yrw801_regions[];
-
-#endif /* __OPL4_LOCAL_H */
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c
deleted file mode 100644
index 04079de4..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * OPL4 mixer functions
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- *
- * 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 "opl4_local.h"
-#include <sound/control.h>
-
-static int snd_opl4_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 7;
- return 0;
-}
-
-static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- u8 reg = kcontrol->private_value;
- u8 value;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- value = snd_opl4_read(opl4, reg);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
- ucontrol->value.integer.value[0] = 7 - (value & 7);
- ucontrol->value.integer.value[1] = 7 - ((value >> 3) & 7);
- return 0;
-}
-
-static int snd_opl4_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- u8 reg = kcontrol->private_value;
- u8 value, old_value;
-
- value = (7 - (ucontrol->value.integer.value[0] & 7)) |
- ((7 - (ucontrol->value.integer.value[1] & 7)) << 3);
- spin_lock_irqsave(&opl4->reg_lock, flags);
- old_value = snd_opl4_read(opl4, reg);
- snd_opl4_write(opl4, reg, value);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
- return value != old_value;
-}
-
-static struct snd_kcontrol_new snd_opl4_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "FM Playback Volume",
- .info = snd_opl4_ctl_info,
- .get = snd_opl4_ctl_get,
- .put = snd_opl4_ctl_put,
- .private_value = OPL4_REG_MIX_CONTROL_FM
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Wavetable Playback Volume",
- .info = snd_opl4_ctl_info,
- .get = snd_opl4_ctl_get,
- .put = snd_opl4_ctl_put,
- .private_value = OPL4_REG_MIX_CONTROL_PCM
- }
-};
-
-int snd_opl4_create_mixer(struct snd_opl4 *opl4)
-{
- struct snd_card *card = opl4->card;
- int i, err;
-
- strcat(card->mixername, ",OPL4");
-
- for (i = 0; i < 2; ++i) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_opl4_controls[i], opl4));
- if (err < 0)
- return err;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c
deleted file mode 100644
index 9b824bfc..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Functions for the OPL4 proc file
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- *
- * 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 "opl4_local.h"
-#include <linux/vmalloc.h>
-#include <linux/export.h>
-#include <sound/info.h>
-
-#ifdef CONFIG_PROC_FS
-
-static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
- unsigned short mode, void **file_private_data)
-{
- struct snd_opl4 *opl4 = entry->private_data;
-
- mutex_lock(&opl4->access_mutex);
- if (opl4->memory_access) {
- mutex_unlock(&opl4->access_mutex);
- return -EBUSY;
- }
- opl4->memory_access++;
- mutex_unlock(&opl4->access_mutex);
- return 0;
-}
-
-static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
- unsigned short mode, void *file_private_data)
-{
- struct snd_opl4 *opl4 = entry->private_data;
-
- mutex_lock(&opl4->access_mutex);
- opl4->memory_access--;
- mutex_unlock(&opl4->access_mutex);
- return 0;
-}
-
-static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *_buf,
- size_t count, loff_t pos)
-{
- struct snd_opl4 *opl4 = entry->private_data;
- char* buf;
-
- buf = vmalloc(count);
- if (!buf)
- return -ENOMEM;
- snd_opl4_read_memory(opl4, buf, pos, count);
- if (copy_to_user(_buf, buf, count)) {
- vfree(buf);
- return -EFAULT;
- }
- vfree(buf);
- return count;
-}
-
-static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file,
- const char __user *_buf,
- size_t count, loff_t pos)
-{
- struct snd_opl4 *opl4 = entry->private_data;
- char *buf;
-
- buf = vmalloc(count);
- if (!buf)
- return -ENOMEM;
- if (copy_from_user(buf, _buf, count)) {
- vfree(buf);
- return -EFAULT;
- }
- snd_opl4_write_memory(opl4, buf, pos, count);
- vfree(buf);
- return count;
-}
-
-static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
- .open = snd_opl4_mem_proc_open,
- .release = snd_opl4_mem_proc_release,
- .read = snd_opl4_mem_proc_read,
- .write = snd_opl4_mem_proc_write,
-};
-
-int snd_opl4_create_proc(struct snd_opl4 *opl4)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_card_entry(opl4->card, "opl4-mem", opl4->card->proc_root);
- if (entry) {
- if (opl4->hardware < OPL3_HW_OPL4_ML) {
- /* OPL4 can access 4 MB external ROM/SRAM */
- entry->mode |= S_IWUSR;
- entry->size = 4 * 1024 * 1024;
- } else {
- /* OPL4-ML has 1 MB internal ROM */
- entry->size = 1 * 1024 * 1024;
- }
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->c.ops = &snd_opl4_mem_proc_ops;
- entry->module = THIS_MODULE;
- entry->private_data = opl4;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- opl4->proc_entry = entry;
- return 0;
-}
-
-void snd_opl4_free_proc(struct snd_opl4 *opl4)
-{
- snd_info_free_entry(opl4->proc_entry);
-}
-
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c
deleted file mode 100644
index 99197699..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * OPL4 sequencer functions
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified 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 SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "opl4_local.h"
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include <linux/module.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("OPL4 wavetable synth driver");
-MODULE_LICENSE("Dual BSD/GPL");
-
-int volume_boost = 8;
-
-module_param(volume_boost, int, 0644);
-MODULE_PARM_DESC(volume_boost, "Additional volume for OPL4 wavetable sounds.");
-
-static int snd_opl4_seq_use_inc(struct snd_opl4 *opl4)
-{
- if (!try_module_get(opl4->card->module))
- return -EFAULT;
- return 0;
-}
-
-static void snd_opl4_seq_use_dec(struct snd_opl4 *opl4)
-{
- module_put(opl4->card->module);
-}
-
-static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_opl4 *opl4 = private_data;
- int err;
-
- mutex_lock(&opl4->access_mutex);
-
- if (opl4->used) {
- mutex_unlock(&opl4->access_mutex);
- return -EBUSY;
- }
- opl4->used++;
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
- err = snd_opl4_seq_use_inc(opl4);
- if (err < 0) {
- mutex_unlock(&opl4->access_mutex);
- return err;
- }
- }
-
- mutex_unlock(&opl4->access_mutex);
-
- snd_opl4_synth_reset(opl4);
- return 0;
-}
-
-static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_opl4_synth_shutdown(opl4);
-
- mutex_lock(&opl4->access_mutex);
- opl4->used--;
- mutex_unlock(&opl4->access_mutex);
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
- snd_opl4_seq_use_dec(opl4);
- return 0;
-}
-
-static struct snd_midi_op opl4_ops = {
- .note_on = snd_opl4_note_on,
- .note_off = snd_opl4_note_off,
- .note_terminate = snd_opl4_terminate_note,
- .control = snd_opl4_control,
- .sysex = snd_opl4_sysex,
-};
-
-static int snd_opl4_seq_event_input(struct snd_seq_event *ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_midi_process_event(&opl4_ops, ev, opl4->chset);
- return 0;
-}
-
-static void snd_opl4_seq_free_port(void *private_data)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_midi_channel_free_set(opl4->chset);
-}
-
-static int snd_opl4_seq_new_device(struct snd_seq_device *dev)
-{
- struct snd_opl4 *opl4;
- int client;
- struct snd_seq_port_callback pcallbacks;
-
- opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (!opl4)
- return -EINVAL;
-
- if (snd_yrw801_detect(opl4) < 0)
- return -ENODEV;
-
- opl4->chset = snd_midi_channel_alloc_set(16);
- if (!opl4->chset)
- return -ENOMEM;
- opl4->chset->private_data = opl4;
-
- /* allocate new client */
- client = snd_seq_create_kernel_client(opl4->card, opl4->seq_dev_num,
- "OPL4 Wavetable");
- if (client < 0) {
- snd_midi_channel_free_set(opl4->chset);
- return client;
- }
- opl4->seq_client = client;
- opl4->chset->client = client;
-
- /* create new port */
- memset(&pcallbacks, 0, sizeof(pcallbacks));
- pcallbacks.owner = THIS_MODULE;
- pcallbacks.use = snd_opl4_seq_use;
- pcallbacks.unuse = snd_opl4_seq_unuse;
- pcallbacks.event_input = snd_opl4_seq_event_input;
- pcallbacks.private_free = snd_opl4_seq_free_port;
- pcallbacks.private_data = opl4;
-
- opl4->chset->port = snd_seq_event_port_attach(client, &pcallbacks,
- SNDRV_SEQ_PORT_CAP_WRITE |
- SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_MIDI_GM |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
- 16, 24,
- "OPL4 Wavetable Port");
- if (opl4->chset->port < 0) {
- int err = opl4->chset->port;
- snd_midi_channel_free_set(opl4->chset);
- snd_seq_delete_kernel_client(client);
- opl4->seq_client = -1;
- return err;
- }
- return 0;
-}
-
-static int snd_opl4_seq_delete_device(struct snd_seq_device *dev)
-{
- struct snd_opl4 *opl4;
-
- opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (!opl4)
- return -EINVAL;
-
- if (opl4->seq_client >= 0) {
- snd_seq_delete_kernel_client(opl4->seq_client);
- opl4->seq_client = -1;
- }
- return 0;
-}
-
-static int __init alsa_opl4_synth_init(void)
-{
- static struct snd_seq_dev_ops ops = {
- snd_opl4_seq_new_device,
- snd_opl4_seq_delete_device
- };
-
- return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL4, &ops,
- sizeof(struct snd_opl4 *));
-}
-
-static void __exit alsa_opl4_synth_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL4);
-}
-
-module_init(alsa_opl4_synth_init)
-module_exit(alsa_opl4_synth_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c
deleted file mode 100644
index 49b9e240..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * OPL4 MIDI synthesizer functions
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified 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 SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "opl4_local.h"
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <sound/asoundef.h>
-
-/* GM2 controllers */
-#ifndef MIDI_CTL_RELEASE_TIME
-#define MIDI_CTL_RELEASE_TIME 0x48
-#define MIDI_CTL_ATTACK_TIME 0x49
-#define MIDI_CTL_DECAY_TIME 0x4b
-#define MIDI_CTL_VIBRATO_RATE 0x4c
-#define MIDI_CTL_VIBRATO_DEPTH 0x4d
-#define MIDI_CTL_VIBRATO_DELAY 0x4e
-#endif
-
-/*
- * This table maps 100/128 cents to F_NUMBER.
- */
-static const s16 snd_opl4_pitch_map[0x600] = {
- 0x000,0x000,0x001,0x001,0x002,0x002,0x003,0x003,
- 0x004,0x004,0x005,0x005,0x006,0x006,0x006,0x007,
- 0x007,0x008,0x008,0x009,0x009,0x00a,0x00a,0x00b,
- 0x00b,0x00c,0x00c,0x00d,0x00d,0x00d,0x00e,0x00e,
- 0x00f,0x00f,0x010,0x010,0x011,0x011,0x012,0x012,
- 0x013,0x013,0x014,0x014,0x015,0x015,0x015,0x016,
- 0x016,0x017,0x017,0x018,0x018,0x019,0x019,0x01a,
- 0x01a,0x01b,0x01b,0x01c,0x01c,0x01d,0x01d,0x01e,
- 0x01e,0x01e,0x01f,0x01f,0x020,0x020,0x021,0x021,
- 0x022,0x022,0x023,0x023,0x024,0x024,0x025,0x025,
- 0x026,0x026,0x027,0x027,0x028,0x028,0x029,0x029,
- 0x029,0x02a,0x02a,0x02b,0x02b,0x02c,0x02c,0x02d,
- 0x02d,0x02e,0x02e,0x02f,0x02f,0x030,0x030,0x031,
- 0x031,0x032,0x032,0x033,0x033,0x034,0x034,0x035,
- 0x035,0x036,0x036,0x037,0x037,0x038,0x038,0x038,
- 0x039,0x039,0x03a,0x03a,0x03b,0x03b,0x03c,0x03c,
- 0x03d,0x03d,0x03e,0x03e,0x03f,0x03f,0x040,0x040,
- 0x041,0x041,0x042,0x042,0x043,0x043,0x044,0x044,
- 0x045,0x045,0x046,0x046,0x047,0x047,0x048,0x048,
- 0x049,0x049,0x04a,0x04a,0x04b,0x04b,0x04c,0x04c,
- 0x04d,0x04d,0x04e,0x04e,0x04f,0x04f,0x050,0x050,
- 0x051,0x051,0x052,0x052,0x053,0x053,0x054,0x054,
- 0x055,0x055,0x056,0x056,0x057,0x057,0x058,0x058,
- 0x059,0x059,0x05a,0x05a,0x05b,0x05b,0x05c,0x05c,
- 0x05d,0x05d,0x05e,0x05e,0x05f,0x05f,0x060,0x060,
- 0x061,0x061,0x062,0x062,0x063,0x063,0x064,0x064,
- 0x065,0x065,0x066,0x066,0x067,0x067,0x068,0x068,
- 0x069,0x069,0x06a,0x06a,0x06b,0x06b,0x06c,0x06c,
- 0x06d,0x06d,0x06e,0x06e,0x06f,0x06f,0x070,0x071,
- 0x071,0x072,0x072,0x073,0x073,0x074,0x074,0x075,
- 0x075,0x076,0x076,0x077,0x077,0x078,0x078,0x079,
- 0x079,0x07a,0x07a,0x07b,0x07b,0x07c,0x07c,0x07d,
- 0x07d,0x07e,0x07e,0x07f,0x07f,0x080,0x081,0x081,
- 0x082,0x082,0x083,0x083,0x084,0x084,0x085,0x085,
- 0x086,0x086,0x087,0x087,0x088,0x088,0x089,0x089,
- 0x08a,0x08a,0x08b,0x08b,0x08c,0x08d,0x08d,0x08e,
- 0x08e,0x08f,0x08f,0x090,0x090,0x091,0x091,0x092,
- 0x092,0x093,0x093,0x094,0x094,0x095,0x096,0x096,
- 0x097,0x097,0x098,0x098,0x099,0x099,0x09a,0x09a,
- 0x09b,0x09b,0x09c,0x09c,0x09d,0x09d,0x09e,0x09f,
- 0x09f,0x0a0,0x0a0,0x0a1,0x0a1,0x0a2,0x0a2,0x0a3,
- 0x0a3,0x0a4,0x0a4,0x0a5,0x0a6,0x0a6,0x0a7,0x0a7,
- 0x0a8,0x0a8,0x0a9,0x0a9,0x0aa,0x0aa,0x0ab,0x0ab,
- 0x0ac,0x0ad,0x0ad,0x0ae,0x0ae,0x0af,0x0af,0x0b0,
- 0x0b0,0x0b1,0x0b1,0x0b2,0x0b2,0x0b3,0x0b4,0x0b4,
- 0x0b5,0x0b5,0x0b6,0x0b6,0x0b7,0x0b7,0x0b8,0x0b8,
- 0x0b9,0x0ba,0x0ba,0x0bb,0x0bb,0x0bc,0x0bc,0x0bd,
- 0x0bd,0x0be,0x0be,0x0bf,0x0c0,0x0c0,0x0c1,0x0c1,
- 0x0c2,0x0c2,0x0c3,0x0c3,0x0c4,0x0c4,0x0c5,0x0c6,
- 0x0c6,0x0c7,0x0c7,0x0c8,0x0c8,0x0c9,0x0c9,0x0ca,
- 0x0cb,0x0cb,0x0cc,0x0cc,0x0cd,0x0cd,0x0ce,0x0ce,
- 0x0cf,0x0d0,0x0d0,0x0d1,0x0d1,0x0d2,0x0d2,0x0d3,
- 0x0d3,0x0d4,0x0d5,0x0d5,0x0d6,0x0d6,0x0d7,0x0d7,
- 0x0d8,0x0d8,0x0d9,0x0da,0x0da,0x0db,0x0db,0x0dc,
- 0x0dc,0x0dd,0x0de,0x0de,0x0df,0x0df,0x0e0,0x0e0,
- 0x0e1,0x0e1,0x0e2,0x0e3,0x0e3,0x0e4,0x0e4,0x0e5,
- 0x0e5,0x0e6,0x0e7,0x0e7,0x0e8,0x0e8,0x0e9,0x0e9,
- 0x0ea,0x0eb,0x0eb,0x0ec,0x0ec,0x0ed,0x0ed,0x0ee,
- 0x0ef,0x0ef,0x0f0,0x0f0,0x0f1,0x0f1,0x0f2,0x0f3,
- 0x0f3,0x0f4,0x0f4,0x0f5,0x0f5,0x0f6,0x0f7,0x0f7,
- 0x0f8,0x0f8,0x0f9,0x0f9,0x0fa,0x0fb,0x0fb,0x0fc,
- 0x0fc,0x0fd,0x0fd,0x0fe,0x0ff,0x0ff,0x100,0x100,
- 0x101,0x101,0x102,0x103,0x103,0x104,0x104,0x105,
- 0x106,0x106,0x107,0x107,0x108,0x108,0x109,0x10a,
- 0x10a,0x10b,0x10b,0x10c,0x10c,0x10d,0x10e,0x10e,
- 0x10f,0x10f,0x110,0x111,0x111,0x112,0x112,0x113,
- 0x114,0x114,0x115,0x115,0x116,0x116,0x117,0x118,
- 0x118,0x119,0x119,0x11a,0x11b,0x11b,0x11c,0x11c,
- 0x11d,0x11e,0x11e,0x11f,0x11f,0x120,0x120,0x121,
- 0x122,0x122,0x123,0x123,0x124,0x125,0x125,0x126,
- 0x126,0x127,0x128,0x128,0x129,0x129,0x12a,0x12b,
- 0x12b,0x12c,0x12c,0x12d,0x12e,0x12e,0x12f,0x12f,
- 0x130,0x131,0x131,0x132,0x132,0x133,0x134,0x134,
- 0x135,0x135,0x136,0x137,0x137,0x138,0x138,0x139,
- 0x13a,0x13a,0x13b,0x13b,0x13c,0x13d,0x13d,0x13e,
- 0x13e,0x13f,0x140,0x140,0x141,0x141,0x142,0x143,
- 0x143,0x144,0x144,0x145,0x146,0x146,0x147,0x148,
- 0x148,0x149,0x149,0x14a,0x14b,0x14b,0x14c,0x14c,
- 0x14d,0x14e,0x14e,0x14f,0x14f,0x150,0x151,0x151,
- 0x152,0x153,0x153,0x154,0x154,0x155,0x156,0x156,
- 0x157,0x157,0x158,0x159,0x159,0x15a,0x15b,0x15b,
- 0x15c,0x15c,0x15d,0x15e,0x15e,0x15f,0x160,0x160,
- 0x161,0x161,0x162,0x163,0x163,0x164,0x165,0x165,
- 0x166,0x166,0x167,0x168,0x168,0x169,0x16a,0x16a,
- 0x16b,0x16b,0x16c,0x16d,0x16d,0x16e,0x16f,0x16f,
- 0x170,0x170,0x171,0x172,0x172,0x173,0x174,0x174,
- 0x175,0x175,0x176,0x177,0x177,0x178,0x179,0x179,
- 0x17a,0x17a,0x17b,0x17c,0x17c,0x17d,0x17e,0x17e,
- 0x17f,0x180,0x180,0x181,0x181,0x182,0x183,0x183,
- 0x184,0x185,0x185,0x186,0x187,0x187,0x188,0x188,
- 0x189,0x18a,0x18a,0x18b,0x18c,0x18c,0x18d,0x18e,
- 0x18e,0x18f,0x190,0x190,0x191,0x191,0x192,0x193,
- 0x193,0x194,0x195,0x195,0x196,0x197,0x197,0x198,
- 0x199,0x199,0x19a,0x19a,0x19b,0x19c,0x19c,0x19d,
- 0x19e,0x19e,0x19f,0x1a0,0x1a0,0x1a1,0x1a2,0x1a2,
- 0x1a3,0x1a4,0x1a4,0x1a5,0x1a6,0x1a6,0x1a7,0x1a8,
- 0x1a8,0x1a9,0x1a9,0x1aa,0x1ab,0x1ab,0x1ac,0x1ad,
- 0x1ad,0x1ae,0x1af,0x1af,0x1b0,0x1b1,0x1b1,0x1b2,
- 0x1b3,0x1b3,0x1b4,0x1b5,0x1b5,0x1b6,0x1b7,0x1b7,
- 0x1b8,0x1b9,0x1b9,0x1ba,0x1bb,0x1bb,0x1bc,0x1bd,
- 0x1bd,0x1be,0x1bf,0x1bf,0x1c0,0x1c1,0x1c1,0x1c2,
- 0x1c3,0x1c3,0x1c4,0x1c5,0x1c5,0x1c6,0x1c7,0x1c7,
- 0x1c8,0x1c9,0x1c9,0x1ca,0x1cb,0x1cb,0x1cc,0x1cd,
- 0x1cd,0x1ce,0x1cf,0x1cf,0x1d0,0x1d1,0x1d1,0x1d2,
- 0x1d3,0x1d3,0x1d4,0x1d5,0x1d5,0x1d6,0x1d7,0x1d7,
- 0x1d8,0x1d9,0x1d9,0x1da,0x1db,0x1db,0x1dc,0x1dd,
- 0x1dd,0x1de,0x1df,0x1df,0x1e0,0x1e1,0x1e1,0x1e2,
- 0x1e3,0x1e4,0x1e4,0x1e5,0x1e6,0x1e6,0x1e7,0x1e8,
- 0x1e8,0x1e9,0x1ea,0x1ea,0x1eb,0x1ec,0x1ec,0x1ed,
- 0x1ee,0x1ee,0x1ef,0x1f0,0x1f0,0x1f1,0x1f2,0x1f3,
- 0x1f3,0x1f4,0x1f5,0x1f5,0x1f6,0x1f7,0x1f7,0x1f8,
- 0x1f9,0x1f9,0x1fa,0x1fb,0x1fb,0x1fc,0x1fd,0x1fe,
- 0x1fe,0x1ff,0x200,0x200,0x201,0x202,0x202,0x203,
- 0x204,0x205,0x205,0x206,0x207,0x207,0x208,0x209,
- 0x209,0x20a,0x20b,0x20b,0x20c,0x20d,0x20e,0x20e,
- 0x20f,0x210,0x210,0x211,0x212,0x212,0x213,0x214,
- 0x215,0x215,0x216,0x217,0x217,0x218,0x219,0x21a,
- 0x21a,0x21b,0x21c,0x21c,0x21d,0x21e,0x21e,0x21f,
- 0x220,0x221,0x221,0x222,0x223,0x223,0x224,0x225,
- 0x226,0x226,0x227,0x228,0x228,0x229,0x22a,0x22b,
- 0x22b,0x22c,0x22d,0x22d,0x22e,0x22f,0x230,0x230,
- 0x231,0x232,0x232,0x233,0x234,0x235,0x235,0x236,
- 0x237,0x237,0x238,0x239,0x23a,0x23a,0x23b,0x23c,
- 0x23c,0x23d,0x23e,0x23f,0x23f,0x240,0x241,0x241,
- 0x242,0x243,0x244,0x244,0x245,0x246,0x247,0x247,
- 0x248,0x249,0x249,0x24a,0x24b,0x24c,0x24c,0x24d,
- 0x24e,0x24f,0x24f,0x250,0x251,0x251,0x252,0x253,
- 0x254,0x254,0x255,0x256,0x257,0x257,0x258,0x259,
- 0x259,0x25a,0x25b,0x25c,0x25c,0x25d,0x25e,0x25f,
- 0x25f,0x260,0x261,0x262,0x262,0x263,0x264,0x265,
- 0x265,0x266,0x267,0x267,0x268,0x269,0x26a,0x26a,
- 0x26b,0x26c,0x26d,0x26d,0x26e,0x26f,0x270,0x270,
- 0x271,0x272,0x273,0x273,0x274,0x275,0x276,0x276,
- 0x277,0x278,0x279,0x279,0x27a,0x27b,0x27c,0x27c,
- 0x27d,0x27e,0x27f,0x27f,0x280,0x281,0x282,0x282,
- 0x283,0x284,0x285,0x285,0x286,0x287,0x288,0x288,
- 0x289,0x28a,0x28b,0x28b,0x28c,0x28d,0x28e,0x28e,
- 0x28f,0x290,0x291,0x291,0x292,0x293,0x294,0x294,
- 0x295,0x296,0x297,0x298,0x298,0x299,0x29a,0x29b,
- 0x29b,0x29c,0x29d,0x29e,0x29e,0x29f,0x2a0,0x2a1,
- 0x2a1,0x2a2,0x2a3,0x2a4,0x2a5,0x2a5,0x2a6,0x2a7,
- 0x2a8,0x2a8,0x2a9,0x2aa,0x2ab,0x2ab,0x2ac,0x2ad,
- 0x2ae,0x2af,0x2af,0x2b0,0x2b1,0x2b2,0x2b2,0x2b3,
- 0x2b4,0x2b5,0x2b5,0x2b6,0x2b7,0x2b8,0x2b9,0x2b9,
- 0x2ba,0x2bb,0x2bc,0x2bc,0x2bd,0x2be,0x2bf,0x2c0,
- 0x2c0,0x2c1,0x2c2,0x2c3,0x2c4,0x2c4,0x2c5,0x2c6,
- 0x2c7,0x2c7,0x2c8,0x2c9,0x2ca,0x2cb,0x2cb,0x2cc,
- 0x2cd,0x2ce,0x2ce,0x2cf,0x2d0,0x2d1,0x2d2,0x2d2,
- 0x2d3,0x2d4,0x2d5,0x2d6,0x2d6,0x2d7,0x2d8,0x2d9,
- 0x2da,0x2da,0x2db,0x2dc,0x2dd,0x2dd,0x2de,0x2df,
- 0x2e0,0x2e1,0x2e1,0x2e2,0x2e3,0x2e4,0x2e5,0x2e5,
- 0x2e6,0x2e7,0x2e8,0x2e9,0x2e9,0x2ea,0x2eb,0x2ec,
- 0x2ed,0x2ed,0x2ee,0x2ef,0x2f0,0x2f1,0x2f1,0x2f2,
- 0x2f3,0x2f4,0x2f5,0x2f5,0x2f6,0x2f7,0x2f8,0x2f9,
- 0x2f9,0x2fa,0x2fb,0x2fc,0x2fd,0x2fd,0x2fe,0x2ff,
- 0x300,0x301,0x302,0x302,0x303,0x304,0x305,0x306,
- 0x306,0x307,0x308,0x309,0x30a,0x30a,0x30b,0x30c,
- 0x30d,0x30e,0x30f,0x30f,0x310,0x311,0x312,0x313,
- 0x313,0x314,0x315,0x316,0x317,0x318,0x318,0x319,
- 0x31a,0x31b,0x31c,0x31c,0x31d,0x31e,0x31f,0x320,
- 0x321,0x321,0x322,0x323,0x324,0x325,0x326,0x326,
- 0x327,0x328,0x329,0x32a,0x32a,0x32b,0x32c,0x32d,
- 0x32e,0x32f,0x32f,0x330,0x331,0x332,0x333,0x334,
- 0x334,0x335,0x336,0x337,0x338,0x339,0x339,0x33a,
- 0x33b,0x33c,0x33d,0x33e,0x33e,0x33f,0x340,0x341,
- 0x342,0x343,0x343,0x344,0x345,0x346,0x347,0x348,
- 0x349,0x349,0x34a,0x34b,0x34c,0x34d,0x34e,0x34e,
- 0x34f,0x350,0x351,0x352,0x353,0x353,0x354,0x355,
- 0x356,0x357,0x358,0x359,0x359,0x35a,0x35b,0x35c,
- 0x35d,0x35e,0x35f,0x35f,0x360,0x361,0x362,0x363,
- 0x364,0x364,0x365,0x366,0x367,0x368,0x369,0x36a,
- 0x36a,0x36b,0x36c,0x36d,0x36e,0x36f,0x370,0x370,
- 0x371,0x372,0x373,0x374,0x375,0x376,0x377,0x377,
- 0x378,0x379,0x37a,0x37b,0x37c,0x37d,0x37d,0x37e,
- 0x37f,0x380,0x381,0x382,0x383,0x383,0x384,0x385,
- 0x386,0x387,0x388,0x389,0x38a,0x38a,0x38b,0x38c,
- 0x38d,0x38e,0x38f,0x390,0x391,0x391,0x392,0x393,
- 0x394,0x395,0x396,0x397,0x398,0x398,0x399,0x39a,
- 0x39b,0x39c,0x39d,0x39e,0x39f,0x39f,0x3a0,0x3a1,
- 0x3a2,0x3a3,0x3a4,0x3a5,0x3a6,0x3a7,0x3a7,0x3a8,
- 0x3a9,0x3aa,0x3ab,0x3ac,0x3ad,0x3ae,0x3ae,0x3af,
- 0x3b0,0x3b1,0x3b2,0x3b3,0x3b4,0x3b5,0x3b6,0x3b6,
- 0x3b7,0x3b8,0x3b9,0x3ba,0x3bb,0x3bc,0x3bd,0x3be,
- 0x3bf,0x3bf,0x3c0,0x3c1,0x3c2,0x3c3,0x3c4,0x3c5,
- 0x3c6,0x3c7,0x3c7,0x3c8,0x3c9,0x3ca,0x3cb,0x3cc,
- 0x3cd,0x3ce,0x3cf,0x3d0,0x3d1,0x3d1,0x3d2,0x3d3,
- 0x3d4,0x3d5,0x3d6,0x3d7,0x3d8,0x3d9,0x3da,0x3da,
- 0x3db,0x3dc,0x3dd,0x3de,0x3df,0x3e0,0x3e1,0x3e2,
- 0x3e3,0x3e4,0x3e4,0x3e5,0x3e6,0x3e7,0x3e8,0x3e9,
- 0x3ea,0x3eb,0x3ec,0x3ed,0x3ee,0x3ef,0x3ef,0x3f0,
- 0x3f1,0x3f2,0x3f3,0x3f4,0x3f5,0x3f6,0x3f7,0x3f8,
- 0x3f9,0x3fa,0x3fa,0x3fb,0x3fc,0x3fd,0x3fe,0x3ff
-};
-
-/*
- * Attenuation according to GM recommendations, in -0.375 dB units.
- * table[v] = 40 * log(v / 127) / -0.375
- */
-static unsigned char snd_opl4_volume_table[128] = {
- 255,224,192,173,160,150,141,134,
- 128,122,117,113,109,105,102, 99,
- 96, 93, 90, 88, 85, 83, 81, 79,
- 77, 75, 73, 71, 70, 68, 67, 65,
- 64, 62, 61, 59, 58, 57, 56, 54,
- 53, 52, 51, 50, 49, 48, 47, 46,
- 45, 44, 43, 42, 41, 40, 39, 39,
- 38, 37, 36, 35, 34, 34, 33, 32,
- 31, 31, 30, 29, 29, 28, 27, 27,
- 26, 25, 25, 24, 24, 23, 22, 22,
- 21, 21, 20, 19, 19, 18, 18, 17,
- 17, 16, 16, 15, 15, 14, 14, 13,
- 13, 12, 12, 11, 11, 10, 10, 9,
- 9, 9, 8, 8, 7, 7, 6, 6,
- 6, 5, 5, 4, 4, 4, 3, 3,
- 2, 2, 2, 1, 1, 0, 0, 0
-};
-
-/*
- * Initializes all voices.
- */
-void snd_opl4_synth_reset(struct snd_opl4 *opl4)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++)
- snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-
- INIT_LIST_HEAD(&opl4->off_voices);
- INIT_LIST_HEAD(&opl4->on_voices);
- memset(opl4->voices, 0, sizeof(opl4->voices));
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- opl4->voices[i].number = i;
- list_add_tail(&opl4->voices[i].list, &opl4->off_voices);
- }
-
- snd_midi_channel_set_clear(opl4->chset);
-}
-
-/*
- * Shuts down all voices.
- */
-void snd_opl4_synth_shutdown(struct snd_opl4 *opl4)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++)
- snd_opl4_write(opl4, OPL4_REG_MISC + i,
- opl4->voices[i].reg_misc & ~OPL4_KEY_ON_BIT);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-/*
- * Executes the callback for all voices playing the specified note.
- */
-static void snd_opl4_do_for_note(struct snd_opl4 *opl4, int note, struct snd_midi_channel *chan,
- void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
-{
- int i;
- unsigned long flags;
- struct opl4_voice *voice;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- voice = &opl4->voices[i];
- if (voice->chan == chan && voice->note == note) {
- func(opl4, voice);
- }
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-/*
- * Executes the callback for all voices of to the specified channel.
- */
-static void snd_opl4_do_for_channel(struct snd_opl4 *opl4,
- struct snd_midi_channel *chan,
- void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
-{
- int i;
- unsigned long flags;
- struct opl4_voice *voice;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- voice = &opl4->voices[i];
- if (voice->chan == chan) {
- func(opl4, voice);
- }
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-/*
- * Executes the callback for all active voices.
- */
-static void snd_opl4_do_for_all(struct snd_opl4 *opl4,
- void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
-{
- int i;
- unsigned long flags;
- struct opl4_voice *voice;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- voice = &opl4->voices[i];
- if (voice->chan)
- func(opl4, voice);
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-static void snd_opl4_update_volume(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- int att;
-
- att = voice->sound->tone_attenuate;
- att += snd_opl4_volume_table[opl4->chset->gs_master_volume & 0x7f];
- att += snd_opl4_volume_table[voice->chan->gm_volume & 0x7f];
- att += snd_opl4_volume_table[voice->chan->gm_expression & 0x7f];
- att += snd_opl4_volume_table[voice->velocity];
- att = 0x7f - (0x7f - att) * (voice->sound->volume_factor) / 0xfe - volume_boost;
- if (att < 0)
- att = 0;
- else if (att > 0x7e)
- att = 0x7e;
- snd_opl4_write(opl4, OPL4_REG_LEVEL + voice->number,
- (att << 1) | voice->level_direct);
- voice->level_direct = 0;
-}
-
-static void snd_opl4_update_pan(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- int pan = voice->sound->panpot;
-
- if (!voice->chan->drum_channel)
- pan += (voice->chan->control[MIDI_CTL_MSB_PAN] - 0x40) >> 3;
- if (pan < -7)
- pan = -7;
- else if (pan > 7)
- pan = 7;
- voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK)
- | (pan & OPL4_PAN_POT_MASK);
- snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
-}
-
-static void snd_opl4_update_vibrato_depth(struct snd_opl4 *opl4,
- struct opl4_voice *voice)
-{
- int depth;
-
- if (voice->chan->drum_channel)
- return;
- depth = (7 - voice->sound->vibrato)
- * (voice->chan->control[MIDI_CTL_VIBRATO_DEPTH] & 0x7f);
- depth = (depth >> 7) + voice->sound->vibrato;
- voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK;
- voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK;
- snd_opl4_write(opl4, OPL4_REG_LFO_VIBRATO + voice->number,
- voice->reg_lfo_vibrato);
-}
-
-static void snd_opl4_update_pitch(struct snd_opl4 *opl4,
- struct opl4_voice *voice)
-{
- struct snd_midi_channel *chan = voice->chan;
- int note, pitch, octave;
-
- note = chan->drum_channel ? 60 : voice->note;
- /*
- * pitch is in 100/128 cents, so 0x80 is one semitone and
- * 0x600 is one octave.
- */
- pitch = ((note - 60) << 7) * voice->sound->key_scaling / 100 + (60 << 7);
- pitch += voice->sound->pitch_offset;
- if (!chan->drum_channel)
- pitch += chan->gm_rpn_coarse_tuning;
- pitch += chan->gm_rpn_fine_tuning >> 7;
- pitch += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 0x2000;
- if (pitch < 0)
- pitch = 0;
- else if (pitch >= 0x6000)
- pitch = 0x5fff;
- octave = pitch / 0x600 - 8;
- pitch = snd_opl4_pitch_map[pitch % 0x600];
-
- snd_opl4_write(opl4, OPL4_REG_OCTAVE + voice->number,
- (octave << 4) | ((pitch >> 7) & OPL4_F_NUMBER_HIGH_MASK));
- voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8)
- | ((pitch << 1) & OPL4_F_NUMBER_LOW_MASK);
- snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number);
-}
-
-static void snd_opl4_update_tone_parameters(struct snd_opl4 *opl4,
- struct opl4_voice *voice)
-{
- snd_opl4_write(opl4, OPL4_REG_ATTACK_DECAY1 + voice->number,
- voice->sound->reg_attack_decay1);
- snd_opl4_write(opl4, OPL4_REG_LEVEL_DECAY2 + voice->number,
- voice->sound->reg_level_decay2);
- snd_opl4_write(opl4, OPL4_REG_RELEASE_CORRECTION + voice->number,
- voice->sound->reg_release_correction);
- snd_opl4_write(opl4, OPL4_REG_TREMOLO + voice->number,
- voice->sound->reg_tremolo);
-}
-
-/* allocate one voice */
-static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
-{
- /* first, try to get the oldest key-off voice */
- if (!list_empty(&opl4->off_voices))
- return list_entry(opl4->off_voices.next, struct opl4_voice, list);
- /* then get the oldest key-on voice */
- snd_BUG_ON(list_empty(&opl4->on_voices));
- return list_entry(opl4->on_voices.next, struct opl4_voice, list);
-}
-
-static void snd_opl4_wait_for_wave_headers(struct snd_opl4 *opl4)
-{
- int timeout = 200;
-
- while ((inb(opl4->fm_port) & OPL4_STATUS_LOAD) && --timeout > 0)
- udelay(10);
-}
-
-void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
- const struct opl4_region_ptr *regions;
- struct opl4_voice *voice[2];
- const struct opl4_sound *sound[2];
- int voices = 0, i;
- unsigned long flags;
-
- /* determine the number of voices and voice parameters */
- i = chan->drum_channel ? 0x80 : (chan->midi_program & 0x7f);
- regions = &snd_yrw801_regions[i];
- for (i = 0; i < regions->count; i++) {
- if (note >= regions->regions[i].key_min &&
- note <= regions->regions[i].key_max) {
- sound[voices] = &regions->regions[i].sound;
- if (++voices >= 2)
- break;
- }
- }
-
- /* allocate and initialize the needed voices */
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < voices; i++) {
- voice[i] = snd_opl4_get_voice(opl4);
- list_del(&voice[i]->list);
- list_add_tail(&voice[i]->list, &opl4->on_voices);
- voice[i]->chan = chan;
- voice[i]->note = note;
- voice[i]->velocity = vel & 0x7f;
- voice[i]->sound = sound[i];
- }
-
- /* set tone number (triggers header loading) */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_f_number =
- (sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
- snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
- voice[i]->reg_f_number);
- snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
- sound[i]->tone & 0xff);
- }
-
- /* set parameters which can be set while loading */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
- snd_opl4_update_pan(opl4, voice[i]);
- snd_opl4_update_pitch(opl4, voice[i]);
- voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
- snd_opl4_update_volume(opl4, voice[i]);
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-
- /* wait for completion of loading */
- snd_opl4_wait_for_wave_headers(opl4);
-
- /* set remaining parameters */
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < voices; i++) {
- snd_opl4_update_tone_parameters(opl4, voice[i]);
- voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
- snd_opl4_update_vibrato_depth(opl4, voice[i]);
- }
-
- /* finally, switch on all voices */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_misc =
- (voice[i]->reg_misc & 0x1f) | OPL4_KEY_ON_BIT;
- snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
- voice[i]->reg_misc);
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- list_del(&voice->list);
- list_add_tail(&voice->list, &opl4->off_voices);
-
- voice->reg_misc &= ~OPL4_KEY_ON_BIT;
- snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
-}
-
-void snd_opl4_note_off(void *private_data, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
-}
-
-static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- list_del(&voice->list);
- list_add_tail(&voice->list, &opl4->off_voices);
-
- voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
- snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
-}
-
-void snd_opl4_terminate_note(void *private_data, int note, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
-}
-
-void snd_opl4_control(void *private_data, int type, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
-
- switch (type) {
- case MIDI_CTL_MSB_MODWHEEL:
- chan->control[MIDI_CTL_VIBRATO_DEPTH] = chan->control[MIDI_CTL_MSB_MODWHEEL];
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
- break;
- case MIDI_CTL_MSB_MAIN_VOLUME:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
- break;
- case MIDI_CTL_MSB_PAN:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pan);
- break;
- case MIDI_CTL_MSB_EXPRESSION:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
- break;
- case MIDI_CTL_VIBRATO_RATE:
- /* not yet supported */
- break;
- case MIDI_CTL_VIBRATO_DEPTH:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
- break;
- case MIDI_CTL_VIBRATO_DELAY:
- /* not yet supported */
- break;
- case MIDI_CTL_E1_REVERB_DEPTH:
- /*
- * Each OPL4 voice has a bit called "Pseudo-Reverb", but
- * IMHO _not_ using it enhances the listening experience.
- */
- break;
- case MIDI_CTL_PITCHBEND:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pitch);
- break;
- }
-}
-
-void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
- int parsed, struct snd_midi_channel_set *chset)
-{
- struct snd_opl4 *opl4 = private_data;
-
- if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
- snd_opl4_do_for_all(opl4, snd_opl4_update_volume);
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/yrw801.c b/ANDROID_3.4.5/sound/drivers/opl4/yrw801.c
deleted file mode 100644
index 6c335492..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/yrw801.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
- * Information about the Yamaha YRW801 wavetable ROM chip
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified 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 SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "opl4_local.h"
-
-int snd_yrw801_detect(struct snd_opl4 *opl4)
-{
- char buf[15];
-
- snd_opl4_read_memory(opl4, buf, 0x001200, 15);
- if (memcmp(buf, "CopyrightYAMAHA", 15))
- return -ENODEV;
- snd_opl4_read_memory(opl4, buf, 0x1ffffe, 2);
- if (buf[0] != 0x01)
- return -ENODEV;
- snd_printdd("YRW801 ROM version %02x.%02x\n", buf[0], buf[1]);
- return 0;
-}
-
-/*
- * The instrument definitions are stored statically because, in practice, the
- * OPL4 is always coupled with a YRW801. Dynamic instrument loading would be
- * required if downloading sample data to external SRAM was actually supported
- * by this driver.
- */
-
-static const struct opl4_region regions_00[] = { /* Acoustic Grand Piano */
- {0x14, 0x27, {0x12c,7474,100, 0,0,0x00,0xc8,0x20,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6816,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5899,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5290,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4260,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3625,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3116,100, 0,0,0x04,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2081,100, 0,0,0x03,0xc8,0x20,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1444,100, 0,0,0x07,0xc8,0x20,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1915,100, 0,0,0x00,0xc8,0x20,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_01[] = { /* Bright Acoustic Piano */
- {0x14, 0x2d, {0x12c,7474,100, 0,0,0x00,0xc8,0x20,0xf2,0x13,0x08,0x0}},
- {0x2e, 0x33, {0x12d,6816,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12e,5899,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x12f,5290,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x130,4260,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x131,3625,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x132,3116,100, 0,0,0x04,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x53, 0x58, {0x133,2081,100, 0,0,0x07,0xc8,0x20,0xf2,0x14,0x18,0x0}},
- {0x59, 0x5e, {0x134,1444,100, 0,0,0x0a,0xc8,0x20,0xf3,0x14,0x18,0x0}},
- {0x5f, 0x6d, {0x135,1915,100, 0,0,0x00,0xc8,0x20,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_02[] = { /* Electric Grand Piano */
- {0x14, 0x2d, {0x12c,7476,100, 1,0,0x00,0xae,0x20,0xf2,0x13,0x07,0x0}},
- {0x2e, 0x33, {0x12d,6818,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x34, 0x39, {0x12e,5901,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x3a, 0x3f, {0x12f,5292,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x40, 0x45, {0x130,4262,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x46, 0x4b, {0x131,3627,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x4c, 0x52, {0x132,3118,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x53, 0x58, {0x133,2083,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x17,0x0}},
- {0x59, 0x5e, {0x134,1446,100, 1,0,0x00,0xae,0x20,0xf3,0x14,0x17,0x0}},
- {0x5f, 0x6d, {0x135,1917,100, 1,0,0x00,0xae,0x20,0xf4,0x15,0x07,0x0}},
- {0x00, 0x7f, {0x06c,6375,100,-1,0,0x00,0xc2,0x28,0xf4,0x23,0x18,0x0}}
-};
-static const struct opl4_region regions_03[] = { /* Honky-Tonk Piano */
- {0x14, 0x27, {0x12c,7474,100, 0,0,0x00,0xb4,0x20,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6816,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5899,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5290,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4260,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3625,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3116,100, 0,0,0x04,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2081,100, 0,0,0x03,0xb4,0x20,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1444,100, 0,0,0x07,0xb4,0x20,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1915,100, 0,0,0x00,0xb4,0x20,0xf4,0x15,0x08,0x0}},
- {0x14, 0x27, {0x12c,7486,100, 0,0,0x00,0xb4,0x20,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6803,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5912,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5275,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4274,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3611,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3129,100, 0,0,0x04,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2074,100, 0,0,0x07,0xb4,0x20,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1457,100, 0,0,0x01,0xb4,0x20,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1903,100, 0,0,0x00,0xb4,0x20,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_04[] = { /* Electric Piano 1 */
- {0x15, 0x6c, {0x00b,6570,100, 0,0,0x00,0x28,0x38,0xf0,0x00,0x0c,0x0}},
- {0x00, 0x7f, {0x06c,6375,100, 0,2,0x00,0xb0,0x22,0xf4,0x23,0x19,0x0}}
-};
-static const struct opl4_region regions_05[] = { /* Electric Piano 2 */
- {0x14, 0x27, {0x12c,7476,100, 0,3,0x00,0xa2,0x1b,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6818,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5901,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5292,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4262,100, 0,3,0x0a,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3627,100, 0,3,0x0a,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3118,100, 0,3,0x04,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2083,100, 0,3,0x03,0xa2,0x1b,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1446,100, 0,3,0x07,0xa2,0x1b,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1917,100, 0,3,0x00,0xa2,0x1b,0xf4,0x15,0x08,0x0}},
- {0x14, 0x2d, {0x12c,7472,100, 0,0,0x00,0xa2,0x18,0xf2,0x13,0x08,0x0}},
- {0x2e, 0x33, {0x12d,6814,100, 0,0,0x00,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12e,5897,100, 0,0,0x00,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x12f,5288,100, 0,0,0x00,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x130,4258,100, 0,0,0x0a,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x131,3623,100, 0,0,0x0a,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x132,3114,100, 0,0,0x04,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x53, 0x58, {0x133,2079,100, 0,0,0x07,0xa2,0x18,0xf2,0x14,0x18,0x0}},
- {0x59, 0x5e, {0x134,1442,100, 0,0,0x0a,0xa2,0x18,0xf3,0x14,0x18,0x0}},
- {0x5f, 0x6d, {0x135,1913,100, 0,0,0x00,0xa2,0x18,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_06[] = { /* Harpsichord */
- {0x15, 0x39, {0x080,5158,100, 0,0,0x00,0xb2,0x20,0xf5,0x24,0x19,0x0}},
- {0x3a, 0x3f, {0x081,4408,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x09,0x0}},
- {0x40, 0x45, {0x082,3622,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x09,0x0}},
- {0x46, 0x4d, {0x083,2843,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x19,0x0}},
- {0x4e, 0x6c, {0x084,1307,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x29,0x0}}
-};
-static const struct opl4_region regions_07[] = { /* Clavinet */
- {0x15, 0x51, {0x027,5009,100, 0,0,0x00,0xd2,0x28,0xf5,0x13,0x2b,0x0}},
- {0x52, 0x6c, {0x028,3495,100, 0,0,0x00,0xd2,0x28,0xf5,0x13,0x3b,0x0}}
-};
-static const struct opl4_region regions_08[] = { /* Celesta */
- {0x15, 0x6c, {0x02b,3267,100, 0,0,0x00,0xdc,0x20,0xf4,0x15,0x07,0x3}}
-};
-static const struct opl4_region regions_09[] = { /* Glockenspiel */
- {0x15, 0x78, {0x0f3, 285,100, 0,0,0x00,0xc2,0x28,0xf6,0x25,0x25,0x0}}
-};
-static const struct opl4_region regions_0a[] = { /* Music Box */
- {0x15, 0x6c, {0x0f3,3362,100, 0,0,0x00,0xb6,0x20,0xa6,0x25,0x25,0x0}},
- {0x15, 0x6c, {0x101,4773,100, 0,0,0x00,0xaa,0x20,0xd4,0x14,0x16,0x0}}
-};
-static const struct opl4_region regions_0b[] = { /* Vibraphone */
- {0x15, 0x6c, {0x101,4778,100, 0,0,0x00,0xc0,0x28,0xf4,0x14,0x16,0x4}}
-};
-static const struct opl4_region regions_0c[] = { /* Marimba */
- {0x15, 0x3f, {0x0f4,4778,100, 0,0,0x00,0xc4,0x38,0xf7,0x47,0x08,0x0}},
- {0x40, 0x4c, {0x0f5,3217,100, 0,0,0x00,0xc4,0x38,0xf7,0x47,0x08,0x0}},
- {0x4d, 0x5a, {0x0f5,3217,100, 0,0,0x00,0xc4,0x38,0xf7,0x48,0x08,0x0}},
- {0x5b, 0x7f, {0x0f5,3218,100, 0,0,0x00,0xc4,0x38,0xf7,0x48,0x18,0x0}}
-};
-static const struct opl4_region regions_0d[] = { /* Xylophone */
- {0x00, 0x7f, {0x136,1729,100, 0,0,0x00,0xd2,0x38,0xf0,0x06,0x36,0x0}}
-};
-static const struct opl4_region regions_0e[] = { /* Tubular Bell */
- {0x01, 0x7f, {0x0ff,3999,100, 0,1,0x00,0x90,0x21,0xf4,0xa3,0x25,0x1}}
-};
-static const struct opl4_region regions_0f[] = { /* Dulcimer */
- {0x00, 0x7f, {0x03f,4236,100, 0,1,0x00,0xbc,0x29,0xf5,0x16,0x07,0x0}},
- {0x00, 0x7f, {0x040,4236,100, 0,2,0x0e,0x94,0x2a,0xf5,0x16,0x07,0x0}}
-};
-static const struct opl4_region regions_10[] = { /* Drawbar Organ */
- {0x01, 0x7f, {0x08e,4394,100, 0,2,0x14,0xc2,0x3a,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_11[] = { /* Percussive Organ */
- {0x15, 0x3b, {0x08c,6062,100, 0,3,0x00,0xbe,0x3b,0xf0,0x00,0x09,0x0}},
- {0x3c, 0x6c, {0x08d,2984,100, 0,3,0x00,0xbe,0x3b,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_12[] = { /* Rock Organ */
- {0x15, 0x30, {0x128,6574,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x31, 0x3c, {0x129,5040,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x3d, 0x48, {0x12a,3498,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x49, 0x54, {0x12b,1957,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x55, 0x6c, {0x127, 423,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_13[] = { /* Church Organ */
- {0x15, 0x29, {0x087,7466,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x2a, 0x30, {0x088,6456,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x31, 0x38, {0x089,5428,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x39, 0x41, {0x08a,4408,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x42, 0x6c, {0x08b,3406,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_14[] = { /* Reed Organ */
- {0x00, 0x53, {0x0ac,5570,100, 0,0,0x06,0xc0,0x38,0xf0,0x00,0x09,0x1}},
- {0x54, 0x7f, {0x0ad,2497,100, 0,0,0x00,0xc0,0x38,0xf0,0x00,0x09,0x1}}
-};
-static const struct opl4_region regions_15[] = { /* Accordion */
- {0x15, 0x4c, {0x006,4261,100, 0,2,0x00,0xa4,0x22,0x90,0x00,0x09,0x0}},
- {0x4d, 0x6c, {0x007,1530,100, 0,2,0x00,0xa4,0x22,0x90,0x00,0x09,0x0}},
- {0x15, 0x6c, {0x070,4391,100, 0,3,0x00,0x8a,0x23,0xa0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_16[] = { /* Harmonica */
- {0x15, 0x6c, {0x070,4408,100, 0,0,0x00,0xae,0x30,0xa0,0x00,0x09,0x2}}
-};
-static const struct opl4_region regions_17[] = { /* Tango Accordion */
- {0x00, 0x53, {0x0ac,5573,100, 0,0,0x00,0xae,0x38,0xf0,0x00,0x09,0x0}},
- {0x54, 0x7f, {0x0ad,2500,100, 0,0,0x00,0xae,0x38,0xf0,0x00,0x09,0x0}},
- {0x15, 0x6c, {0x041,8479,100, 0,2,0x00,0x6a,0x3a,0x75,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_18[] = { /* Nylon Guitar */
- {0x15, 0x2f, {0x0b3,6964,100, 0,0,0x05,0xca,0x28,0xf5,0x34,0x09,0x0}},
- {0x30, 0x36, {0x0b7,5567,100, 0,0,0x0c,0xca,0x28,0xf5,0x34,0x09,0x0}},
- {0x37, 0x3c, {0x0b5,4653,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
- {0x3d, 0x43, {0x0b4,3892,100, 0,0,0x00,0xca,0x28,0xf6,0x35,0x09,0x0}},
- {0x44, 0x60, {0x0b6,2723,100, 0,0,0x00,0xca,0x28,0xf6,0x35,0x19,0x0}}
-};
-static const struct opl4_region regions_19[] = { /* Steel Guitar */
- {0x15, 0x31, {0x00c,6937,100, 0,0,0x00,0xbc,0x28,0xf0,0x04,0x19,0x0}},
- {0x32, 0x38, {0x00d,5410,100, 0,0,0x00,0xbc,0x28,0xf0,0x05,0x09,0x0}},
- {0x39, 0x47, {0x00e,4379,100, 0,0,0x00,0xbc,0x28,0xf5,0x94,0x09,0x0}},
- {0x48, 0x6c, {0x00f,2843,100, 0,0,0x00,0xbc,0x28,0xf6,0x95,0x09,0x0}}
-};
-static const struct opl4_region regions_1a[] = { /* Jazz Guitar */
- {0x15, 0x31, {0x05a,6832,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
- {0x32, 0x3f, {0x05b,4897,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
- {0x40, 0x6c, {0x05c,3218,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}}
-};
-static const struct opl4_region regions_1b[] = { /* Clean Guitar */
- {0x15, 0x2c, {0x061,7053,100, 0,1,0x00,0xb4,0x29,0xf5,0x54,0x0a,0x0}},
- {0x2d, 0x31, {0x060,6434,100, 0,1,0x00,0xb4,0x29,0xf5,0x54,0x0a,0x0}},
- {0x32, 0x38, {0x063,5764,100, 0,1,0x00,0xbe,0x29,0xf5,0x55,0x0a,0x0}},
- {0x39, 0x3f, {0x062,4627,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x0a,0x0}},
- {0x40, 0x44, {0x065,3963,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x1a,0x0}},
- {0x45, 0x4b, {0x064,3313,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x1a,0x0}},
- {0x4c, 0x54, {0x066,2462,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x2a,0x0}},
- {0x55, 0x6c, {0x067,1307,100, 0,1,0x00,0xb4,0x29,0xf6,0x56,0x0a,0x0}}
-};
-static const struct opl4_region regions_1c[] = { /* Muted Guitar */
- {0x01, 0x7f, {0x068,4408,100, 0,0,0x00,0xcc,0x28,0xf6,0x15,0x09,0x0}}
-};
-static const struct opl4_region regions_1d[] = { /* Overdriven Guitar */
- {0x00, 0x40, {0x0a5,6589,100, 0,1,0x00,0xc0,0x29,0xf2,0x11,0x09,0x0}},
- {0x41, 0x7f, {0x0a6,5428,100, 0,1,0x00,0xc0,0x29,0xf2,0x11,0x09,0x0}}
-};
-static const struct opl4_region regions_1e[] = { /* Distortion Guitar */
- {0x15, 0x2a, {0x051,6928,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x2b, 0x2e, {0x052,6433,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x2f, 0x32, {0x053,5944,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x33, 0x36, {0x054,5391,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x37, 0x3a, {0x055,4897,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x3b, 0x3e, {0x056,4408,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x3f, 0x42, {0x057,3892,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x43, 0x46, {0x058,3361,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x47, 0x6c, {0x059,2784,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}}
-};
-static const struct opl4_region regions_1f[] = { /* Guitar Harmonics */
- {0x15, 0x44, {0x05e,5499,100, 0,0,0x00,0xce,0x28,0xf4,0x24,0x09,0x0}},
- {0x45, 0x49, {0x05d,4850,100, 0,0,0x00,0xe2,0x28,0xf4,0x24,0x09,0x0}},
- {0x4a, 0x6c, {0x05f,4259,100, 0,0,0x00,0xce,0x28,0xf4,0x24,0x09,0x0}}
-};
-static const struct opl4_region regions_20[] = { /* Acoustic Bass */
- {0x15, 0x30, {0x004,8053,100, 0,0,0x00,0xe2,0x18,0xf5,0x15,0x09,0x0}},
- {0x31, 0x6c, {0x005,4754,100, 0,0,0x00,0xe2,0x18,0xf5,0x15,0x09,0x0}}
-};
-static const struct opl4_region regions_21[] = { /* Fingered Bass */
- {0x01, 0x20, {0x04a,8762,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
- {0x21, 0x25, {0x04b,8114,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
- {0x26, 0x2a, {0x04c,7475,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
- {0x2b, 0x7f, {0x04d,6841,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}}
-};
-static const struct opl4_region regions_22[] = { /* Picked Bass */
- {0x15, 0x23, {0x04f,7954,100, 0,0,0x00,0xcc,0x18,0xf3,0x90,0x0a,0x0}},
- {0x24, 0x2a, {0x050,7318,100, 0,0,0x05,0xcc,0x18,0xf3,0x90,0x1a,0x0}},
- {0x2b, 0x2f, {0x06b,6654,100, 0,0,0x00,0xcc,0x18,0xf3,0x90,0x2a,0x0}},
- {0x30, 0x47, {0x069,6031,100, 0,0,0x00,0xcc,0x18,0xf5,0xb0,0x0a,0x0}},
- {0x48, 0x6c, {0x06a,5393,100, 0,0,0x00,0xcc,0x18,0xf5,0xb0,0x0a,0x0}}
-};
-static const struct opl4_region regions_23[] = { /* Fretless Bass */
- {0x01, 0x7f, {0x04e,5297,100, 0,0,0x00,0xd2,0x10,0xf3,0x63,0x19,0x0}}
-};
-static const struct opl4_region regions_24[] = { /* Slap Bass 1 */
- {0x15, 0x6c, {0x0a3,7606,100, 0,1,0x00,0xde,0x19,0xf5,0x32,0x1a,0x0}}
-};
-static const struct opl4_region regions_25[] = { /* Slap Bass 2 */
- {0x01, 0x7f, {0x0a2,6694,100, 0,0,0x00,0xda,0x20,0xb0,0x02,0x09,0x0}}
-};
-static const struct opl4_region regions_26[] = { /* Synth Bass 1 */
- {0x15, 0x6c, {0x0be,7466,100, 0,1,0x00,0xb8,0x39,0xf4,0x14,0x09,0x0}}
-};
-static const struct opl4_region regions_27[] = { /* Synth Bass 2 */
- {0x00, 0x7f, {0x117,8103,100, 0,1,0x00,0xca,0x39,0xf3,0x50,0x08,0x0}}
-};
-static const struct opl4_region regions_28[] = { /* Violin */
- {0x15, 0x3a, {0x105,5158,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x3b, 0x3f, {0x102,4754,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x40, 0x41, {0x106,4132,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x42, 0x44, {0x107,4033,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x45, 0x47, {0x108,3580,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x48, 0x4a, {0x10a,2957,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x4b, 0x4c, {0x10b,2724,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x4d, 0x4e, {0x10c,2530,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x4f, 0x51, {0x10d,2166,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x52, 0x6c, {0x109,1825,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_29[] = { /* Viola */
- {0x15, 0x32, {0x103,5780,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x33, 0x35, {0x104,5534,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x36, 0x38, {0x105,5158,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x39, 0x3d, {0x102,4754,100, 0,3,0x00,0xca,0x3b,0xa3,0x20,0x09,0x0}},
- {0x3e, 0x3f, {0x106,4132,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x40, 0x42, {0x107,4033,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x43, 0x45, {0x108,3580,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}},
- {0x46, 0x48, {0x10a,2957,100, 0,3,0x00,0xca,0x3b,0xa3,0x20,0x09,0x0}},
- {0x49, 0x4a, {0x10b,2724,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}},
- {0x4b, 0x4c, {0x10c,2530,100, 0,3,0x00,0xca,0x3b,0xa3,0x20,0x09,0x0}},
- {0x4d, 0x4f, {0x10d,2166,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}},
- {0x50, 0x6c, {0x109,1825,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_2a[] = { /* Cello */
- {0x15, 0x2d, {0x112,6545,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x08,0x0}},
- {0x2e, 0x37, {0x113,5764,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x08,0x0}},
- {0x38, 0x3e, {0x115,4378,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}},
- {0x3f, 0x44, {0x116,3998,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}},
- {0x45, 0x6c, {0x114,3218,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}}
-};
-static const struct opl4_region regions_2b[] = { /* Contrabass */
- {0x15, 0x29, {0x110,7713,100, 0,1,0x00,0xc2,0x19,0x90,0x00,0x09,0x0}},
- {0x2a, 0x6c, {0x111,6162,100, 0,1,0x00,0xc2,0x19,0x90,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_2c[] = { /* Tremolo Strings */
- {0x15, 0x3b, {0x0b0,4810,100, 0,0,0x0a,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x3c, 0x41, {0x035,4035,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x42, 0x47, {0x033,3129,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x48, 0x52, {0x034,2625,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x53, 0x6c, {0x0af, 936,100, 0,0,0x00,0xde,0x38,0xf0,0x00,0x07,0x6}}
-};
-static const struct opl4_region regions_2d[] = { /* Pizzicato Strings */
- {0x15, 0x32, {0x0b8,6186,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
- {0x33, 0x3b, {0x0b9,5031,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
- {0x3c, 0x42, {0x0bb,4146,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
- {0x43, 0x48, {0x0ba,3245,100, 0,0,0x00,0xc2,0x28,0xf0,0x00,0x05,0x0}},
- {0x49, 0x6c, {0x0bc,2352,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}}
-};
-static const struct opl4_region regions_2e[] = { /* Harp */
- {0x15, 0x46, {0x07e,3740,100, 0,1,0x00,0xd2,0x29,0xf5,0x25,0x07,0x0}},
- {0x47, 0x6c, {0x07f,2319,100, 0,1,0x00,0xd2,0x29,0xf5,0x25,0x07,0x0}}
-};
-static const struct opl4_region regions_2f[] = { /* Timpani */
- {0x15, 0x6c, {0x100,6570,100, 0,0,0x00,0xf8,0x28,0xf0,0x05,0x16,0x0}}
-};
-static const struct opl4_region regions_30[] = { /* Strings */
- {0x15, 0x3b, {0x13c,4806,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
- {0x3c, 0x41, {0x13e,4035,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
- {0x42, 0x47, {0x13d,3122,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
- {0x48, 0x52, {0x13f,2629,100, 0,0,0x00,0xbe,0x20,0x80,0x00,0x07,0x0}},
- {0x53, 0x6c, {0x140, 950,100, 0,0,0x00,0xbe,0x20,0x80,0x00,0x07,0x0}}
-};
-static const struct opl4_region regions_31[] = { /* Slow Strings */
- {0x15, 0x3b, {0x0b0,4810,100, 0,1,0x0a,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x3c, 0x41, {0x035,4035,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x42, 0x47, {0x033,3129,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x48, 0x52, {0x034,2625,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x53, 0x6c, {0x0af, 936,100, 0,1,0x00,0xbe,0x19,0xf0,0x00,0x07,0x0}}
-};
-static const struct opl4_region regions_32[] = { /* Synth Strings 1 */
- {0x05, 0x71, {0x002,6045,100,-2,0,0x00,0xa6,0x20,0x93,0x22,0x06,0x0}},
- {0x15, 0x6c, {0x0ae,3261,100, 2,0,0x00,0xc6,0x20,0x70,0x01,0x06,0x0}}
-};
-static const struct opl4_region regions_33[] = { /* Synth Strings 2 */
- {0x15, 0x6c, {0x002,4513,100, 5,1,0x00,0xb4,0x19,0x70,0x00,0x06,0x0}},
- {0x15, 0x6c, {0x002,4501,100,-5,1,0x00,0xb4,0x19,0x70,0x00,0x06,0x0}}
-};
-static const struct opl4_region regions_34[] = { /* Choir Aahs */
- {0x15, 0x3a, {0x018,5010,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
- {0x3b, 0x40, {0x019,4370,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
- {0x41, 0x47, {0x01a,3478,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
- {0x48, 0x6c, {0x01b,2197,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}}
-};
-static const struct opl4_region regions_35[] = { /* Voice Oohs */
- {0x15, 0x6c, {0x029,3596,100, 0,0,0x00,0xe6,0x20,0xf7,0x20,0x08,0x0}}
-};
-static const struct opl4_region regions_36[] = { /* Synth Voice */
- {0x15, 0x6c, {0x02a,3482,100, 0,1,0x00,0xc2,0x19,0x85,0x21,0x07,0x0}}
-};
-static const struct opl4_region regions_37[] = { /* Orchestra Hit */
- {0x15, 0x6c, {0x049,4394,100, 0,0,0x00,0xfe,0x30,0x80,0x05,0x05,0x0}}
-};
-static const struct opl4_region regions_38[] = { /* Trumpet */
- {0x15, 0x3c, {0x0f6,4706,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x3d, 0x43, {0x0f8,3894,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x44, 0x48, {0x0f7,3118,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x49, 0x4e, {0x0fa,2322,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x4f, 0x55, {0x0f9,1634,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x56, 0x6c, {0x0fb, 786,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_39[] = { /* Trombone */
- {0x15, 0x3a, {0x0f0,5053,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}},
- {0x3b, 0x3f, {0x0f1,4290,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}},
- {0x40, 0x6c, {0x0f2,3580,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_3a[] = { /* Tuba */
- {0x15, 0x2d, {0x085,7096,100, 0,1,0x00,0xde,0x21,0xf5,0x10,0x09,0x0}},
- {0x2e, 0x6c, {0x086,6014,100, 0,1,0x00,0xde,0x21,0xf5,0x10,0x09,0x0}}
-};
-static const struct opl4_region regions_3b[] = { /* Muted Trumpet */
- {0x15, 0x45, {0x0b1,4135,100, 0,0,0x00,0xcc,0x28,0xf3,0x10,0x0a,0x1}},
- {0x46, 0x6c, {0x0b2,2599,100, 0,0,0x00,0xcc,0x28,0x83,0x10,0x0a,0x1}}
-};
-static const struct opl4_region regions_3c[] = { /* French Horns */
- {0x15, 0x49, {0x07c,3624,100, 0,2,0x00,0xd0,0x1a,0xf0,0x00,0x09,0x0}},
- {0x4a, 0x6c, {0x07d,2664,100, 0,2,0x00,0xd0,0x1a,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_3d[] = { /* Brass Section */
- {0x15, 0x42, {0x0fc,4375,100, 0,0,0x00,0xd6,0x28,0xf0,0x00,0x0a,0x0}},
- {0x43, 0x6c, {0x0fd,2854,100, 0,0,0x00,0xd6,0x28,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_3e[] = { /* Synth Brass 1 */
- {0x01, 0x27, {0x0d3,9094,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x28, 0x2d, {0x0da,8335,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x2e, 0x33, {0x0d4,7558,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x34, 0x39, {0x0db,6785,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x3a, 0x3f, {0x0d5,6042,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x40, 0x45, {0x0dc,5257,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x46, 0x4b, {0x0d6,4493,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x4c, 0x51, {0x0dd,3741,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x52, 0x57, {0x0d7,3012,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x58, 0x5d, {0x0de,2167,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x5e, 0x63, {0x0d8,1421,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x64, 0x7f, {0x0d9,-115,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x01, 0x27, {0x118,9103,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x28, 0x2d, {0x119,8340,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x2e, 0x33, {0x11a,7565,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x34, 0x39, {0x11b,6804,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x3a, 0x3f, {0x11c,6042,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x40, 0x45, {0x11d,5277,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x46, 0x4b, {0x11e,4520,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x4c, 0x51, {0x11f,3741,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x52, 0x57, {0x120,3012,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x58, 0x5d, {0x121,2166,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x5e, 0x64, {0x122,1421,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x65, 0x7f, {0x123,-115,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}}
-};
-static const struct opl4_region regions_3f[] = { /* Synth Brass 2 */
- {0x01, 0x27, {0x118,9113,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x28, 0x2d, {0x119,8350,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x2e, 0x33, {0x11a,7575,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x34, 0x39, {0x11b,6814,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x3a, 0x3f, {0x11c,6052,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x40, 0x45, {0x11d,5287,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x46, 0x4b, {0x11e,4530,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x4c, 0x51, {0x11f,3751,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x52, 0x57, {0x120,3022,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x58, 0x5d, {0x121,2176,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x5e, 0x64, {0x122,1431,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x65, 0x7f, {0x123,-105,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x00, 0x7f, {0x124,4034,100,-3,2,0x00,0xea,0x22,0x85,0x23,0x08,0x0}}
-};
-static const struct opl4_region regions_40[] = { /* Soprano Sax */
- {0x15, 0x3f, {0x0e3,4228,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}},
- {0x40, 0x45, {0x0e4,3495,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}},
- {0x46, 0x4b, {0x0e5,2660,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
- {0x4c, 0x51, {0x0e6,2002,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
- {0x52, 0x59, {0x0e7,1186,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
- {0x59, 0x6c, {0x0e8,1730,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_41[] = { /* Alto Sax */
- {0x15, 0x32, {0x092,6204,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x33, 0x35, {0x096,5812,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x36, 0x3a, {0x099,5318,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x3b, 0x3b, {0x08f,5076,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x3c, 0x3e, {0x093,4706,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x3f, 0x41, {0x097,4321,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x42, 0x44, {0x09a,3893,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x45, 0x47, {0x090,3497,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x48, 0x4a, {0x094,3119,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x4b, 0x4d, {0x098,2726,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x4e, 0x50, {0x09b,2393,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x51, 0x53, {0x091,2088,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x54, 0x6c, {0x095,1732,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}}
-};
-static const struct opl4_region regions_42[] = { /* Tenor Sax */
- {0x24, 0x30, {0x0e9,6301,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x31, 0x34, {0x0ea,5781,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x35, 0x3a, {0x0eb,5053,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x3b, 0x41, {0x0ed,4165,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x42, 0x47, {0x0ec,3218,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x48, 0x51, {0x0ee,2462,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x52, 0x6c, {0x0ef,1421,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}}
-};
-static const struct opl4_region regions_43[] = { /* Baritone Sax */
- {0x15, 0x2d, {0x0df,6714,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
- {0x2e, 0x34, {0x0e1,5552,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
- {0x35, 0x39, {0x0e2,5178,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
- {0x3a, 0x6c, {0x0e0,4437,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_44[] = { /* Oboe */
- {0x15, 0x3c, {0x042,4493,100, 0,1,0x00,0xe6,0x39,0xf4,0x10,0x0a,0x0}},
- {0x3d, 0x43, {0x044,3702,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x44, 0x49, {0x043,2956,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x4a, 0x4f, {0x046,2166,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x50, 0x55, {0x045,1420,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x56, 0x6c, {0x047, 630,100, 0,1,0x00,0xe6,0x39,0xf4,0x10,0x0a,0x0}}
-};
-static const struct opl4_region regions_45[] = { /* English Horn */
- {0x15, 0x38, {0x03c,5098,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}},
- {0x39, 0x3e, {0x03b,4291,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}},
- {0x3f, 0x6c, {0x03d,3540,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_46[] = { /* Bassoon */
- {0x15, 0x22, {0x038,7833,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}},
- {0x23, 0x2e, {0x03a,7070,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}},
- {0x2f, 0x6c, {0x039,6302,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}}
-};
-static const struct opl4_region regions_47[] = { /* Clarinet */
- {0x15, 0x3b, {0x09e,5900,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
- {0x3c, 0x41, {0x0a0,5158,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
- {0x42, 0x4a, {0x09f,4260,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
- {0x4b, 0x6c, {0x0a1,2957,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_48[] = { /* Piccolo */
- {0x15, 0x40, {0x071,4803,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x41, 0x4d, {0x072,3314,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x4e, 0x53, {0x073,1731,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x54, 0x5f, {0x074,2085,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x60, 0x6c, {0x075,1421,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}}
-};
-static const struct opl4_region regions_49[] = { /* Flute */
- {0x15, 0x40, {0x071,4803,100, 0,0,0x00,0xdc,0x38,0xf0,0x00,0x0a,0x2}},
- {0x41, 0x4d, {0x072,3314,100, 0,0,0x00,0xdc,0x38,0xf0,0x00,0x0a,0x2}},
- {0x4e, 0x6c, {0x073,1731,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}}
-};
-static const struct opl4_region regions_4a[] = { /* Recorder */
- {0x15, 0x6f, {0x0bd,4897,100, 0,0,0x00,0xec,0x30,0x70,0x00,0x09,0x1}}
-};
-static const struct opl4_region regions_4b[] = { /* Pan Flute */
- {0x15, 0x6c, {0x077,2359,100, 0,0,0x00,0xde,0x38,0xf0,0x00,0x09,0x3}}
-};
-static const struct opl4_region regions_4c[] = { /* Bottle Blow */
- {0x15, 0x6c, {0x077,2359,100, 0,0,0x00,0xc8,0x38,0xf0,0x00,0x09,0x1}},
- {0x01, 0x7f, {0x125,7372,100, 0,0,0x1e,0x80,0x00,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_4d[] = { /* Shakuhachi */
- {0x00, 0x7f, {0x0ab,4548,100, 0,0,0x00,0xd6,0x30,0xf0,0x00,0x0a,0x3}},
- {0x15, 0x6c, {0x076,3716,100, 0,0,0x00,0xa2,0x28,0x70,0x00,0x09,0x2}}
-};
-static const struct opl4_region regions_4e[] = { /* Whistle */
- {0x00, 0x7f, {0x0aa,1731,100, 0,4,0x00,0xd2,0x2c,0x70,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_4f[] = { /* Ocarina */
- {0x00, 0x7f, {0x0aa,1731,100, 0,1,0x00,0xce,0x29,0x90,0x00,0x0a,0x1}}
-};
-static const struct opl4_region regions_50[] = { /* Square Lead */
- {0x01, 0x2a, {0x0cc,9853,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x2b, 0x36, {0x0cd,6785,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x37, 0x42, {0x0ca,5248,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x43, 0x4e, {0x0cf,3713,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x4f, 0x5a, {0x0ce,2176,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x5b, 0x7f, {0x0cb, 640,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x01, 0x2a, {0x0cc,9844,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x2b, 0x36, {0x0cd,6776,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x37, 0x42, {0x0ca,5239,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x43, 0x4e, {0x0cf,3704,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x4f, 0x5a, {0x0ce,2167,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x5b, 0x7f, {0x0cb, 631,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}}
-};
-static const struct opl4_region regions_51[] = { /* Sawtooth Lead */
- {0x01, 0x27, {0x118,9108,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x28, 0x2d, {0x119,8345,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x2e, 0x33, {0x11a,7570,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x34, 0x39, {0x11b,6809,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x3a, 0x3f, {0x11c,6047,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x40, 0x45, {0x11d,5282,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x46, 0x4b, {0x11e,4525,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x4c, 0x51, {0x11f,3746,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x52, 0x57, {0x120,3017,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x58, 0x5d, {0x121,2171,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x5e, 0x66, {0x122,1426,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x67, 0x7f, {0x123,-110,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x01, 0x27, {0x118,9098,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x28, 0x2d, {0x119,8335,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x2e, 0x33, {0x11a,7560,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x34, 0x39, {0x11b,6799,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x3a, 0x3f, {0x11c,6037,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x40, 0x45, {0x11d,5272,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x46, 0x4b, {0x11e,4515,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x4c, 0x51, {0x11f,3736,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x52, 0x57, {0x120,3007,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x58, 0x5d, {0x121,2161,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x5e, 0x66, {0x122,1416,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x67, 0x7f, {0x123,-120,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}}
-};
-static const struct opl4_region regions_52[] = { /* Calliope Lead */
- {0x00, 0x7f, {0x0aa,1731,100, 0,0,0x00,0xc2,0x28,0x90,0x00,0x0a,0x2}},
- {0x15, 0x6c, {0x076,3716,100, 0,0,0x00,0xb6,0x28,0xb0,0x00,0x09,0x2}}
-};
-static const struct opl4_region regions_53[] = { /* Chiffer Lead */
- {0x00, 0x7f, {0x13a,3665,100, 0,2,0x00,0xcc,0x2a,0xf0,0x10,0x09,0x1}},
- {0x01, 0x7f, {0x0fe,3660,100, 0,0,0x00,0xbe,0x28,0xf3,0x10,0x17,0x0}}
-};
-static const struct opl4_region regions_54[] = { /* Charang Lead */
- {0x00, 0x40, {0x0a5,6594,100, 0,3,0x00,0xba,0x33,0xf2,0x11,0x09,0x0}},
- {0x41, 0x7f, {0x0a6,5433,100, 0,3,0x00,0xba,0x33,0xf2,0x11,0x09,0x0}},
- {0x01, 0x27, {0x118,9098,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x28, 0x2d, {0x119,8335,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x2e, 0x33, {0x11a,7560,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x34, 0x39, {0x11b,6799,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x3a, 0x3f, {0x11c,6037,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x40, 0x45, {0x11d,5272,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x46, 0x4b, {0x11e,4515,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x4c, 0x51, {0x11f,3736,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x52, 0x57, {0x120,3007,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x58, 0x5d, {0x121,2161,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x5e, 0x66, {0x122,1416,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x67, 0x7f, {0x123,-120,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}}
-};
-static const struct opl4_region regions_55[] = { /* Voice Lead */
- {0x00, 0x7f, {0x0aa,1739,100, 0,6,0x00,0x8c,0x2e,0x90,0x00,0x0a,0x0}},
- {0x15, 0x6c, {0x02a,3474,100, 0,1,0x00,0xd8,0x29,0xf0,0x05,0x0a,0x0}}
-};
-static const struct opl4_region regions_56[] = { /* 5ths Lead */
- {0x01, 0x27, {0x118,8468,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x28, 0x2d, {0x119,7705,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x2e, 0x33, {0x11a,6930,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x34, 0x39, {0x11b,6169,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x3a, 0x3f, {0x11c,5407,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x40, 0x45, {0x11d,4642,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x46, 0x4b, {0x11e,3885,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x4c, 0x51, {0x11f,3106,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x52, 0x57, {0x120,2377,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x58, 0x5d, {0x121,1531,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x5e, 0x64, {0x122, 786,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x65, 0x7f, {0x123,-750,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x05, 0x71, {0x002,4503,100, 0,1,0x00,0xb8,0x31,0xb3,0x20,0x0b,0x0}}
-};
-static const struct opl4_region regions_57[] = { /* Bass & Lead */
- {0x00, 0x7f, {0x117,8109,100, 0,1,0x00,0xbc,0x29,0xf3,0x50,0x08,0x0}},
- {0x01, 0x27, {0x118,9097,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x28, 0x2d, {0x119,8334,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x2e, 0x33, {0x11a,7559,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x34, 0x39, {0x11b,6798,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x3a, 0x3f, {0x11c,6036,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x40, 0x45, {0x11d,5271,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x46, 0x4b, {0x11e,4514,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x4c, 0x51, {0x11f,3735,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x52, 0x57, {0x120,3006,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x58, 0x5d, {0x121,2160,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x5e, 0x66, {0x122,1415,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x67, 0x7f, {0x123,-121,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_58[] = { /* New Age Pad */
- {0x15, 0x6c, {0x002,4501,100, 0,4,0x00,0xa4,0x24,0x80,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x0f3,4253,100, 0,3,0x00,0x8c,0x23,0xa2,0x14,0x06,0x1}}
-};
-static const struct opl4_region regions_59[] = { /* Warm Pad */
- {0x15, 0x6c, {0x04e,5306,100, 2,2,0x00,0x92,0x2a,0x34,0x23,0x05,0x2}},
- {0x15, 0x6c, {0x029,3575,100,-2,2,0x00,0xbe,0x22,0x31,0x23,0x06,0x0}}
-};
-static const struct opl4_region regions_5a[] = { /* Polysynth Pad */
- {0x01, 0x27, {0x118,9111,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x28, 0x2d, {0x119,8348,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x2e, 0x33, {0x11a,7573,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x34, 0x39, {0x11b,6812,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x3a, 0x3f, {0x11c,6050,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x40, 0x45, {0x11d,5285,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x46, 0x4b, {0x11e,4528,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x4c, 0x51, {0x11f,3749,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x52, 0x57, {0x120,3020,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x58, 0x5d, {0x121,2174,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x5e, 0x66, {0x122,1429,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x67, 0x7f, {0x123,-107,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x00, 0x7f, {0x124,4024,100, 0,2,0x00,0xae,0x22,0xe5,0x20,0x08,0x0}}
-};
-static const struct opl4_region regions_5b[] = { /* Choir Pad */
- {0x15, 0x3a, {0x018,5010,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x3b, 0x40, {0x019,4370,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x41, 0x47, {0x01a,3478,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x48, 0x6c, {0x01b,2197,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x15, 0x6c, {0x02a,3482,100, 0,4,0x00,0x98,0x24,0x65,0x21,0x06,0x0}}
-};
-static const struct opl4_region regions_5c[] = { /* Bowed Pad */
- {0x15, 0x6c, {0x101,4790,100,-1,1,0x00,0xbe,0x19,0x44,0x14,0x16,0x0}},
- {0x00, 0x7f, {0x0aa,1720,100, 1,1,0x00,0x94,0x19,0x40,0x00,0x06,0x0}}
-};
-static const struct opl4_region regions_5d[] = { /* Metallic Pad */
- {0x15, 0x31, {0x00c,6943,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x32, 0x38, {0x00d,5416,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x39, 0x47, {0x00e,4385,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x48, 0x6c, {0x00f,2849,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x00, 0x7f, {0x03f,4224,100, 0,1,0x00,0x9c,0x31,0x65,0x16,0x07,0x0}}
-};
-static const struct opl4_region regions_5e[] = { /* Halo Pad */
- {0x00, 0x7f, {0x124,4038,100, 0,2,0x00,0xa6,0x1a,0x85,0x23,0x08,0x0}},
- {0x15, 0x6c, {0x02a,3471,100, 0,3,0x00,0xc0,0x1b,0xc0,0x05,0x06,0x0}}
-};
-static const struct opl4_region regions_5f[] = { /* Sweep Pad */
- {0x01, 0x27, {0x0d3,9100,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x28, 0x2d, {0x0da,8341,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x2e, 0x33, {0x0d4,7564,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x34, 0x39, {0x0db,6791,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x3a, 0x3f, {0x0d5,6048,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x40, 0x45, {0x0dc,5263,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x46, 0x4b, {0x0d6,4499,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x4c, 0x51, {0x0dd,3747,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x52, 0x57, {0x0d7,3018,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x58, 0x5d, {0x0de,2173,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x5e, 0x63, {0x0d8,1427,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x64, 0x7f, {0x0d9,-109,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x01, 0x27, {0x0d3,9088,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x28, 0x2d, {0x0da,8329,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x2e, 0x33, {0x0d4,7552,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x34, 0x39, {0x0db,6779,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x3a, 0x3f, {0x0d5,6036,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x40, 0x45, {0x0dc,5251,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x46, 0x4b, {0x0d6,4487,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x4c, 0x51, {0x0dd,3735,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x52, 0x57, {0x0d7,3006,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x58, 0x5d, {0x0de,2161,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x5e, 0x63, {0x0d8,1415,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x64, 0x7f, {0x0d9,-121,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}}
-};
-static const struct opl4_region regions_60[] = { /* Ice Rain */
- {0x01, 0x7f, {0x04e,9345,100, 0,2,0x00,0xcc,0x22,0xa3,0x63,0x17,0x0}},
- {0x00, 0x7f, {0x143,5586, 20, 0,2,0x00,0x6e,0x2a,0xf0,0x05,0x05,0x0}}
-};
-static const struct opl4_region regions_61[] = { /* Soundtrack */
- {0x15, 0x6c, {0x002,4501,100, 0,2,0x00,0xb6,0x2a,0x60,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x0f3,1160,100, 0,5,0x00,0xa8,0x2d,0x52,0x14,0x06,0x2}}
-};
-static const struct opl4_region regions_62[] = { /* Crystal */
- {0x15, 0x6c, {0x0f3,1826,100, 0,3,0x00,0xb8,0x33,0xf6,0x25,0x25,0x0}},
- {0x15, 0x2c, {0x06d,7454,100, 0,3,0x00,0xac,0x3b,0x85,0x24,0x06,0x0}},
- {0x2d, 0x36, {0x06e,5925,100, 0,3,0x00,0xac,0x3b,0x85,0x24,0x06,0x0}},
- {0x37, 0x6c, {0x06f,4403,100, 0,3,0x09,0xac,0x3b,0x85,0x24,0x06,0x0}}
-};
-static const struct opl4_region regions_63[] = { /* Atmosphere */
- {0x05, 0x71, {0x002,4509,100, 0,2,0x00,0xc8,0x32,0x73,0x22,0x06,0x1}},
- {0x15, 0x2f, {0x0b3,6964,100, 0,2,0x05,0xc2,0x32,0xf5,0x34,0x07,0x2}},
- {0x30, 0x36, {0x0b7,5567,100, 0,2,0x0c,0xc2,0x32,0xf5,0x34,0x07,0x2}},
- {0x37, 0x3c, {0x0b5,4653,100, 0,2,0x00,0xc2,0x32,0xf6,0x34,0x07,0x2}},
- {0x3d, 0x43, {0x0b4,3892,100, 0,2,0x00,0xc2,0x32,0xf6,0x35,0x07,0x2}},
- {0x44, 0x60, {0x0b6,2723,100, 0,2,0x00,0xc2,0x32,0xf6,0x35,0x17,0x2}}
-};
-static const struct opl4_region regions_64[] = { /* Brightness */
- {0x00, 0x7f, {0x137,5285,100, 0,2,0x00,0xbe,0x2a,0xa5,0x18,0x08,0x0}},
- {0x15, 0x6c, {0x02a,3481,100, 0,1,0x00,0xc8,0x29,0x80,0x05,0x05,0x0}}
-};
-static const struct opl4_region regions_65[] = { /* Goblins */
- {0x15, 0x6c, {0x002,4501,100,-1,2,0x00,0xca,0x2a,0x40,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x009,9679, 20, 1,4,0x00,0x3c,0x0c,0x22,0x11,0x06,0x0}}
-};
-static const struct opl4_region regions_66[] = { /* Echoes */
- {0x15, 0x6c, {0x02a,3487,100, 0,3,0x00,0xae,0x2b,0xf5,0x21,0x06,0x0}},
- {0x00, 0x7f, {0x124,4027,100, 0,3,0x00,0xae,0x2b,0x85,0x23,0x07,0x0}}
-};
-static const struct opl4_region regions_67[] = { /* Sci-Fi */
- {0x15, 0x31, {0x00c,6940,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x32, 0x38, {0x00d,5413,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x39, 0x47, {0x00e,4382,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x48, 0x6c, {0x00f,2846,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x15, 0x6c, {0x002,4498,100, 0,2,0x00,0xd4,0x22,0x80,0x01,0x05,0x0}}
-};
-static const struct opl4_region regions_68[] = { /* Sitar */
- {0x00, 0x7f, {0x10f,4408,100, 0,2,0x00,0xc4,0x32,0xf4,0x15,0x16,0x1}}
-};
-static const struct opl4_region regions_69[] = { /* Banjo */
- {0x15, 0x34, {0x013,5685,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x35, 0x38, {0x014,5009,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x39, 0x3c, {0x012,4520,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x3d, 0x44, {0x015,3622,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x45, 0x4c, {0x017,2661,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x4d, 0x6d, {0x016,1632,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}}
-};
-static const struct opl4_region regions_6a[] = { /* Shamisen */
- {0x15, 0x6c, {0x10e,3273,100, 0,0,0x00,0xc0,0x28,0xf7,0x76,0x08,0x0}}
-};
-static const struct opl4_region regions_6b[] = { /* Koto */
- {0x00, 0x7f, {0x0a9,4033,100, 0,0,0x00,0xc6,0x20,0xf0,0x06,0x07,0x0}}
-};
-static const struct opl4_region regions_6c[] = { /* Kalimba */
- {0x00, 0x7f, {0x137,3749,100, 0,0,0x00,0xce,0x38,0xf5,0x18,0x08,0x0}}
-};
-static const struct opl4_region regions_6d[] = { /* Bagpipe */
- {0x15, 0x39, {0x0a4,7683,100, 0,4,0x00,0xc0,0x1c,0xf0,0x00,0x09,0x0}},
- {0x15, 0x39, {0x0a7,7680,100, 0,1,0x00,0xaa,0x19,0xf0,0x00,0x09,0x0}},
- {0x3a, 0x6c, {0x0a8,3697,100, 0,1,0x00,0xaa,0x19,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_6e[] = { /* Fiddle */
- {0x15, 0x3a, {0x105,5158,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x3b, 0x3f, {0x102,4754,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x40, 0x41, {0x106,4132,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x42, 0x44, {0x107,4033,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x45, 0x47, {0x108,3580,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x48, 0x4a, {0x10a,2957,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x4b, 0x4c, {0x10b,2724,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x4d, 0x4e, {0x10c,2530,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x4f, 0x51, {0x10d,2166,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x52, 0x6c, {0x109,1825,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_6f[] = { /* Shanai */
- {0x15, 0x6c, {0x041,6946,100, 0,1,0x00,0xc4,0x31,0x95,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_70[] = { /* Tinkle Bell */
- {0x15, 0x73, {0x0f3,1821,100, 0,3,0x00,0xc8,0x3b,0xd6,0x25,0x25,0x0}},
- {0x00, 0x7f, {0x137,5669,100, 0,3,0x00,0x66,0x3b,0xf5,0x18,0x08,0x0}}
-};
-static const struct opl4_region regions_71[] = { /* Agogo */
- {0x15, 0x74, {0x00b,2474,100, 0,0,0x00,0xd2,0x38,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_72[] = { /* Steel Drums */
- {0x01, 0x7f, {0x0fe,3670,100, 0,0,0x00,0xca,0x38,0xf3,0x06,0x17,0x1}},
- {0x15, 0x6c, {0x100,9602,100, 0,0,0x00,0x54,0x38,0xb0,0x05,0x16,0x1}}
-};
-static const struct opl4_region regions_73[] = { /* Woodblock */
- {0x15, 0x6c, {0x02c,2963, 50, 0,0,0x07,0xd4,0x00,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_74[] = { /* Taiko Drum */
- {0x13, 0x6c, {0x03e,1194, 50, 0,0,0x00,0xaa,0x38,0xf0,0x04,0x04,0x0}}
-};
-static const struct opl4_region regions_75[] = { /* Melodic Tom */
- {0x15, 0x6c, {0x0c7,6418, 50, 0,0,0x00,0xe4,0x38,0xf0,0x05,0x01,0x0}}
-};
-static const struct opl4_region regions_76[] = { /* Synth Drum */
- {0x15, 0x6c, {0x026,3898, 50, 0,0,0x00,0xd0,0x38,0xf0,0x04,0x04,0x0}}
-};
-static const struct opl4_region regions_77[] = { /* Reverse Cymbal */
- {0x15, 0x6c, {0x031,4138, 50, 0,0,0x00,0xfe,0x38,0x3a,0xf0,0x09,0x0}}
-};
-static const struct opl4_region regions_78[] = { /* Guitar Fret Noise */
- {0x15, 0x6c, {0x138,5266,100, 0,0,0x00,0xa0,0x38,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_79[] = { /* Breath Noise */
- {0x01, 0x7f, {0x125,4269,100, 0,0,0x1e,0xd0,0x38,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_7a[] = { /* Seashore */
- {0x15, 0x6c, {0x008,2965, 20,-2,0,0x00,0xfe,0x00,0x20,0x03,0x04,0x0}},
- {0x01, 0x7f, {0x037,4394, 20, 2,0,0x14,0xfe,0x00,0x20,0x04,0x05,0x0}}
-};
-static const struct opl4_region regions_7b[] = { /* Bird Tweet */
- {0x15, 0x6c, {0x009,8078, 5,-4,7,0x00,0xc2,0x0f,0x22,0x12,0x07,0x0}},
- {0x15, 0x6c, {0x009,3583, 5, 4,5,0x00,0xae,0x15,0x72,0x12,0x07,0x0}}
-};
-static const struct opl4_region regions_7c[] = { /* Telephone Ring */
- {0x15, 0x6c, {0x003,3602, 10, 0,0,0x00,0xce,0x00,0xf0,0x00,0x0f,0x0}}
-};
-static const struct opl4_region regions_7d[] = { /* Helicopter */
- {0x0c, 0x7f, {0x001,2965, 10,-2,0,0x00,0xe0,0x08,0x30,0x01,0x07,0x0}},
- {0x01, 0x7f, {0x037,4394, 10, 2,0,0x44,0x76,0x00,0x30,0x01,0x07,0x0}}
-};
-static const struct opl4_region regions_7e[] = { /* Applause */
- {0x15, 0x6c, {0x036,8273, 20,-6,7,0x00,0xc4,0x0f,0x70,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x036,8115, 5, 6,7,0x00,0xc6,0x07,0x70,0x01,0x05,0x0}}
-};
-static const struct opl4_region regions_7f[] = { /* Gun Shot */
- {0x15, 0x6c, {0x139,2858, 20, 0,0,0x00,0xbe,0x38,0xf0,0x03,0x00,0x0}}
-};
-static const struct opl4_region regions_drums[] = {
- {0x18, 0x18, {0x0cb,6397,100, 3,0,0x00,0xf4,0x38,0xc9,0x1c,0x0c,0x0}},
- {0x19, 0x19, {0x0c4,3714,100, 0,0,0x00,0xe0,0x00,0x97,0x19,0x09,0x0}},
- {0x1a, 0x1a, {0x0c4,3519,100, 0,0,0x00,0xea,0x00,0x61,0x01,0x07,0x0}},
- {0x1b, 0x1b, {0x0c4,3586,100, 0,0,0x00,0xea,0x00,0xf7,0x19,0x09,0x0}},
- {0x1c, 0x1c, {0x0c4,3586,100, 0,0,0x00,0xea,0x00,0x81,0x01,0x07,0x0}},
- {0x1e, 0x1e, {0x0c3,4783,100, 0,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x1f, 0x1f, {0x0d1,4042,100, 0,0,0x00,0xd6,0x00,0xf0,0x05,0x05,0x0}},
- {0x20, 0x20, {0x0d2,5943,100, 0,0,0x00,0xcc,0x00,0xf0,0x00,0x09,0x0}},
- {0x21, 0x21, {0x011,3842,100, 0,0,0x00,0xea,0x00,0xf0,0x16,0x06,0x0}},
- {0x23, 0x23, {0x011,4098,100, 0,0,0x00,0xea,0x00,0xf0,0x16,0x06,0x0}},
- {0x24, 0x24, {0x011,4370,100, 0,0,0x00,0xea,0x00,0xf0,0x00,0x06,0x0}},
- {0x25, 0x25, {0x0d2,4404,100, 0,0,0x00,0xd6,0x00,0xf0,0x00,0x06,0x0}},
- {0x26, 0x26, {0x0d1,4298,100, 0,0,0x00,0xd6,0x00,0xf0,0x05,0x05,0x0}},
- {0x27, 0x27, {0x00a,4403,100,-1,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x28, 0x28, {0x0d1,4554,100, 0,0,0x00,0xdc,0x00,0xf0,0x07,0x07,0x0}},
- {0x29, 0x29, {0x0c8,4242,100,-4,0,0x00,0xd6,0x00,0xf6,0x16,0x06,0x0}},
- {0x2a, 0x2a, {0x079,6160,100, 2,0,0x00,0xe0,0x00,0xf5,0x19,0x09,0x0}},
- {0x2b, 0x2b, {0x0c8,4626,100,-3,0,0x00,0xd6,0x00,0xf6,0x16,0x06,0x0}},
- {0x2c, 0x2c, {0x07b,6039,100, 2,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x2d, 0x2d, {0x0c8,5394,100,-2,0,0x00,0xd6,0x00,0xf6,0x16,0x06,0x0}},
- {0x2e, 0x2e, {0x07a,5690,100, 2,0,0x00,0xd6,0x00,0xf0,0x00,0x05,0x0}},
- {0x2f, 0x2f, {0x0c7,5185,100, 2,0,0x00,0xe0,0x00,0xf6,0x17,0x07,0x0}},
- {0x30, 0x30, {0x0c7,5650,100, 3,0,0x00,0xe0,0x00,0xf6,0x17,0x07,0x0}},
- {0x31, 0x31, {0x031,4395,100, 2,0,0x00,0xea,0x00,0xf0,0x05,0x05,0x0}},
- {0x32, 0x32, {0x0c7,6162,100, 4,0,0x00,0xe0,0x00,0xf6,0x17,0x07,0x0}},
- {0x33, 0x33, {0x02e,4391,100,-2,0,0x00,0xea,0x00,0xf0,0x05,0x05,0x0}},
- {0x34, 0x34, {0x07a,3009,100,-2,0,0x00,0xea,0x00,0xf2,0x15,0x05,0x0}},
- {0x35, 0x35, {0x021,4522,100,-3,0,0x00,0xd6,0x00,0xf0,0x05,0x05,0x0}},
- {0x36, 0x36, {0x025,5163,100, 1,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x37, 0x37, {0x031,5287,100,-1,0,0x00,0xea,0x00,0xf5,0x16,0x06,0x0}},
- {0x38, 0x38, {0x01d,4395,100, 2,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x39, 0x39, {0x031,4647,100,-2,0,0x00,0xea,0x00,0xf4,0x16,0x06,0x0}},
- {0x3a, 0x3a, {0x09d,4426,100,-4,0,0x00,0xe0,0x00,0xf4,0x17,0x07,0x0}},
- {0x3b, 0x3b, {0x02e,4659,100,-2,0,0x00,0xea,0x00,0xf0,0x06,0x06,0x0}},
- {0x3c, 0x3c, {0x01c,4769,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x3d, 0x3d, {0x01c,4611,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x3e, 0x3e, {0x01e,4402,100,-3,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x3f, 0x3f, {0x01f,4387,100,-3,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x40, 0x40, {0x01f,3983,100,-2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x41, 0x41, {0x09c,4526,100, 2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x42, 0x42, {0x09c,4016,100, 2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x43, 0x43, {0x00b,4739,100,-4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x44, 0x44, {0x00b,4179,100,-4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x45, 0x45, {0x02f,4787,100,-4,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x46, 0x46, {0x030,4665,100,-4,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x47, 0x47, {0x144,4519,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x0b,0x0}},
- {0x48, 0x48, {0x144,4111,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x0b,0x0}},
- {0x49, 0x49, {0x024,6408,100, 3,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x4a, 0x4a, {0x024,4144,100, 3,0,0x00,0xcc,0x00,0xf0,0x00,0x09,0x0}},
- {0x4b, 0x4b, {0x020,4001,100, 2,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x4c, 0x4c, {0x02c,4402,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x4d, 0x4d, {0x02c,3612,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x4e, 0x4e, {0x022,4129,100,-2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x4f, 0x4f, {0x023,4147,100,-2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x50, 0x50, {0x032,4412,100,-4,0,0x00,0xd6,0x00,0xf0,0x08,0x09,0x0}},
- {0x51, 0x51, {0x032,4385,100,-4,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x52, 0x52, {0x02f,5935,100,-1,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}}
-};
-
-#define REGION(num) { ARRAY_SIZE(regions ## num), regions ## num }
-const struct opl4_region_ptr snd_yrw801_regions[0x81] = {
- REGION(_00), REGION(_01), REGION(_02), REGION(_03),
- REGION(_04), REGION(_05), REGION(_06), REGION(_07),
- REGION(_08), REGION(_09), REGION(_0a), REGION(_0b),
- REGION(_0c), REGION(_0d), REGION(_0e), REGION(_0f),
- REGION(_10), REGION(_11), REGION(_12), REGION(_13),
- REGION(_14), REGION(_15), REGION(_16), REGION(_17),
- REGION(_18), REGION(_19), REGION(_1a), REGION(_1b),
- REGION(_1c), REGION(_1d), REGION(_1e), REGION(_1f),
- REGION(_20), REGION(_21), REGION(_22), REGION(_23),
- REGION(_24), REGION(_25), REGION(_26), REGION(_27),
- REGION(_28), REGION(_29), REGION(_2a), REGION(_2b),
- REGION(_2c), REGION(_2d), REGION(_2e), REGION(_2f),
- REGION(_30), REGION(_31), REGION(_32), REGION(_33),
- REGION(_34), REGION(_35), REGION(_36), REGION(_37),
- REGION(_38), REGION(_39), REGION(_3a), REGION(_3b),
- REGION(_3c), REGION(_3d), REGION(_3e), REGION(_3f),
- REGION(_40), REGION(_41), REGION(_42), REGION(_43),
- REGION(_44), REGION(_45), REGION(_46), REGION(_47),
- REGION(_48), REGION(_49), REGION(_4a), REGION(_4b),
- REGION(_4c), REGION(_4d), REGION(_4e), REGION(_4f),
- REGION(_50), REGION(_51), REGION(_52), REGION(_53),
- REGION(_54), REGION(_55), REGION(_56), REGION(_57),
- REGION(_58), REGION(_59), REGION(_5a), REGION(_5b),
- REGION(_5c), REGION(_5d), REGION(_5e), REGION(_5f),
- REGION(_60), REGION(_61), REGION(_62), REGION(_63),
- REGION(_64), REGION(_65), REGION(_66), REGION(_67),
- REGION(_68), REGION(_69), REGION(_6a), REGION(_6b),
- REGION(_6c), REGION(_6d), REGION(_6e), REGION(_6f),
- REGION(_70), REGION(_71), REGION(_72), REGION(_73),
- REGION(_74), REGION(_75), REGION(_76), REGION(_77),
- REGION(_78), REGION(_79), REGION(_7a), REGION(_7b),
- REGION(_7c), REGION(_7d), REGION(_7e), REGION(_7f),
- REGION(_drums)
-};
diff --git a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.c b/ANDROID_3.4.5/sound/drivers/pcm-indirect2.c
deleted file mode 100644
index e73fafd7..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Helper functions for indirect PCM data transfer to a simple FIFO in
- * hardware (small, no possibility to read "hardware io position",
- * updating position done by interrupt, ...)
- *
- * Copyright (c) by 2007 Joachim Foerster <JOFT@gmx.de>
- *
- * Based on "pcm-indirect.h" (alsa-driver-1.0.13) by
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* snd_printk/d() */
-#include <sound/core.h>
-/* struct snd_pcm_substream, struct snd_pcm_runtime, snd_pcm_uframes_t
- * snd_pcm_period_elapsed() */
-#include <sound/pcm.h>
-
-#include "pcm-indirect2.h"
-
-#ifdef SND_PCM_INDIRECT2_STAT
-/* jiffies */
-#include <linux/jiffies.h>
-
-void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int i;
- int j;
- int k;
- int seconds = (rec->lastbytetime - rec->firstbytetime) / HZ;
-
- snd_printk(KERN_DEBUG "STAT: mul_elapsed: %u, mul_elapsed_real: %d, "
- "irq_occured: %d\n",
- rec->mul_elapsed, rec->mul_elapsed_real, rec->irq_occured);
- snd_printk(KERN_DEBUG "STAT: min_multiple: %d (irqs/period)\n",
- rec->min_multiple);
- snd_printk(KERN_DEBUG "STAT: firstbytetime: %lu, lastbytetime: %lu, "
- "firstzerotime: %lu\n",
- rec->firstbytetime, rec->lastbytetime, rec->firstzerotime);
- snd_printk(KERN_DEBUG "STAT: bytes2hw: %u Bytes => (by runtime->rate) "
- "length: %d s\n",
- rec->bytes2hw, rec->bytes2hw / 2 / 2 / runtime->rate);
- snd_printk(KERN_DEBUG "STAT: (by measurement) length: %d => "
- "rate: %d Bytes/s = %d Frames/s|Hz\n",
- seconds, rec->bytes2hw / seconds,
- rec->bytes2hw / 2 / 2 / seconds);
- snd_printk(KERN_DEBUG
- "STAT: zeros2hw: %u = %d ms ~ %d * %d zero copies\n",
- rec->zeros2hw, ((rec->zeros2hw / 2 / 2) * 1000) /
- runtime->rate,
- rec->zeros2hw / (rec->hw_buffer_size / 2),
- (rec->hw_buffer_size / 2));
- snd_printk(KERN_DEBUG "STAT: pointer_calls: %u, lastdifftime: %u\n",
- rec->pointer_calls, rec->lastdifftime);
- snd_printk(KERN_DEBUG "STAT: sw_io: %d, sw_data: %d\n", rec->sw_io,
- rec->sw_data);
- snd_printk(KERN_DEBUG "STAT: byte_sizes[]:\n");
- k = 0;
- for (j = 0; j < 8; j++) {
- for (i = j * 8; i < (j + 1) * 8; i++)
- if (rec->byte_sizes[i] != 0) {
- snd_printk(KERN_DEBUG "%u: %u",
- i, rec->byte_sizes[i]);
- k++;
- }
- if (((k % 8) == 0) && (k != 0)) {
- snd_printk(KERN_DEBUG "\n");
- k = 0;
- }
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG "STAT: zero_sizes[]:\n");
- for (j = 0; j < 8; j++) {
- k = 0;
- for (i = j * 8; i < (j + 1) * 8; i++)
- if (rec->zero_sizes[i] != 0)
- snd_printk(KERN_DEBUG "%u: %u",
- i, rec->zero_sizes[i]);
- else
- k++;
- if (!k)
- snd_printk(KERN_DEBUG "\n");
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG "STAT: min_adds[]:\n");
- for (j = 0; j < 8; j++) {
- if (rec->min_adds[j] != 0)
- snd_printk(KERN_DEBUG "%u: %u", j, rec->min_adds[j]);
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG "STAT: mul_adds[]:\n");
- for (j = 0; j < 8; j++) {
- if (rec->mul_adds[j] != 0)
- snd_printk(KERN_DEBUG "%u: %u", j, rec->mul_adds[j]);
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG
- "STAT: zero_times_saved: %d, zero_times_notsaved: %d\n",
- rec->zero_times_saved, rec->zero_times_notsaved);
- /* snd_printk(KERN_DEBUG "STAT: zero_times[]\n");
- i = 0;
- for (j = 0; j < 3750; j++) {
- if (rec->zero_times[j] != 0) {
- snd_printk(KERN_DEBUG "%u: %u", j, rec->zero_times[j]);
- i++;
- }
- if (((i % 8) == 0) && (i != 0))
- snd_printk(KERN_DEBUG "\n");
- }
- snd_printk(KERN_DEBUG "\n"); */
- return;
-}
-#endif
-
-/*
- * _internal_ helper function for playback/capture transfer function
- */
-static void
-snd_pcm_indirect2_increase_min_periods(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- int isplay, int iscopy,
- unsigned int bytes)
-{
- if (rec->min_periods >= 0) {
- if (iscopy) {
- rec->sw_io += bytes;
- if (rec->sw_io >= rec->sw_buffer_size)
- rec->sw_io -= rec->sw_buffer_size;
- } else if (isplay) {
- /* If application does not write data in multiples of
- * a period, move sw_data to the next correctly aligned
- * position, so that sw_io can converge to it (in the
- * next step).
- */
- if (!rec->check_alignment) {
- if (rec->bytes2hw %
- snd_pcm_lib_period_bytes(substream)) {
- unsigned bytes2hw_aligned =
- (1 +
- (rec->bytes2hw /
- snd_pcm_lib_period_bytes
- (substream))) *
- snd_pcm_lib_period_bytes
- (substream);
- rec->sw_data =
- bytes2hw_aligned %
- rec->sw_buffer_size;
-#ifdef SND_PCM_INDIRECT2_STAT
- snd_printk(KERN_DEBUG
- "STAT: @re-align: aligned "
- "bytes2hw to next period "
- "size boundary: %d "
- "(instead of %d)\n",
- bytes2hw_aligned,
- rec->bytes2hw);
- snd_printk(KERN_DEBUG
- "STAT: @re-align: sw_data "
- "moves to: %d\n",
- rec->sw_data);
-#endif
- }
- rec->check_alignment = 1;
- }
- /* We are at the end and are copying zeros into the
- * fifo.
- * Now, we have to make sure that sw_io is increased
- * until the position of sw_data: Filling the fifo with
- * the first zeros means, the last bytes were played.
- */
- if (rec->sw_io != rec->sw_data) {
- unsigned int diff;
- if (rec->sw_data > rec->sw_io)
- diff = rec->sw_data - rec->sw_io;
- else
- diff = (rec->sw_buffer_size -
- rec->sw_io) +
- rec->sw_data;
- if (bytes >= diff)
- rec->sw_io = rec->sw_data;
- else {
- rec->sw_io += bytes;
- if (rec->sw_io >= rec->sw_buffer_size)
- rec->sw_io -=
- rec->sw_buffer_size;
- }
- }
- }
- rec->min_period_count += bytes;
- if (rec->min_period_count >= (rec->hw_buffer_size / 2)) {
- rec->min_periods += (rec->min_period_count /
- (rec->hw_buffer_size / 2));
-#ifdef SND_PCM_INDIRECT2_STAT
- if ((rec->min_period_count /
- (rec->hw_buffer_size / 2)) > 7)
- snd_printk(KERN_DEBUG
- "STAT: more than 7 (%d) min_adds "
- "at once - too big to save!\n",
- (rec->min_period_count /
- (rec->hw_buffer_size / 2)));
- else
- rec->min_adds[(rec->min_period_count /
- (rec->hw_buffer_size / 2))]++;
-#endif
- rec->min_period_count = (rec->min_period_count %
- (rec->hw_buffer_size / 2));
- }
- } else if (isplay && iscopy)
- rec->min_periods = 0;
-}
-
-/*
- * helper function for playback/capture pointer callback
- */
-snd_pcm_uframes_t
-snd_pcm_indirect2_pointer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->pointer_calls++;
-#endif
- return bytes_to_frames(substream->runtime, rec->sw_io);
-}
-
-/*
- * _internal_ helper function for playback interrupt callback
- */
-static void
-snd_pcm_indirect2_playback_transfer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t zero)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
-
- /* runtime->control->appl_ptr: position where ALSA will write next time
- * rec->appl_ptr: position where ALSA was last time
- * diff: obviously ALSA wrote that much bytes into the intermediate
- * buffer since we checked last time
- */
- snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
-
- if (diff) {
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->lastdifftime = jiffies;
-#endif
- if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
- diff += runtime->boundary;
- /* number of bytes "added" by ALSA increases the number of
- * bytes which are ready to "be transferred to HW"/"played"
- * Then, set rec->appl_ptr to not count bytes twice next time.
- */
- rec->sw_ready += (int)frames_to_bytes(runtime, diff);
- rec->appl_ptr = appl_ptr;
- }
- if (rec->hw_ready && (rec->sw_ready <= 0)) {
- unsigned int bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstzerotime == 0) {
- rec->firstzerotime = jiffies;
- snd_printk(KERN_DEBUG
- "STAT: @firstzerotime: mul_elapsed: %d, "
- "min_period_count: %d\n",
- rec->mul_elapsed, rec->min_period_count);
- snd_printk(KERN_DEBUG
- "STAT: @firstzerotime: sw_io: %d, "
- "sw_data: %d, appl_ptr: %u\n",
- rec->sw_io, rec->sw_data,
- (unsigned int)appl_ptr);
- }
- if ((jiffies - rec->firstzerotime) < 3750) {
- rec->zero_times[(jiffies - rec->firstzerotime)]++;
- rec->zero_times_saved++;
- } else
- rec->zero_times_notsaved++;
-#endif
- bytes = zero(substream, rec);
-
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->zeros2hw += bytes;
- if (bytes < 64)
- rec->zero_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: %d zero Bytes copied to hardware at "
- "once - too big to save!\n",
- bytes);
-#endif
- snd_pcm_indirect2_increase_min_periods(substream, rec, 1, 0,
- bytes);
- return;
- }
- while (rec->hw_ready && (rec->sw_ready > 0)) {
- /* sw_to_end: max. number of bytes that can be read/take from
- * the current position (sw_data) in _one_ step
- */
- unsigned int sw_to_end = rec->sw_buffer_size - rec->sw_data;
-
- /* bytes: number of bytes we have available (for reading) */
- unsigned int bytes = rec->sw_ready;
-
- if (sw_to_end < bytes)
- bytes = sw_to_end;
- if (!bytes)
- break;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstbytetime == 0)
- rec->firstbytetime = jiffies;
- rec->lastbytetime = jiffies;
-#endif
- /* copy bytes from intermediate buffer position sw_data to the
- * HW and return number of bytes actually written
- * Furthermore, set hw_ready to 0, if the fifo isn't empty
- * now => more could be transferred to fifo
- */
- bytes = copy(substream, rec, bytes);
- rec->bytes2hw += bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (bytes < 64)
- rec->byte_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: %d Bytes copied to hardware at once "
- "- too big to save!\n",
- bytes);
-#endif
- /* increase sw_data by the number of actually written bytes
- * (= number of taken bytes from intermediate buffer)
- */
- rec->sw_data += bytes;
- if (rec->sw_data == rec->sw_buffer_size)
- rec->sw_data = 0;
- /* now sw_data is the position where ALSA is going to write
- * in the intermediate buffer next time = position we are going
- * to read from next time
- */
-
- snd_pcm_indirect2_increase_min_periods(substream, rec, 1, 1,
- bytes);
-
- /* we read bytes from intermediate buffer, so we need to say
- * that the number of bytes ready for transfer are decreased
- * now
- */
- rec->sw_ready -= bytes;
- }
- return;
-}
-
-/*
- * helper function for playback interrupt routine
- */
-void
-snd_pcm_indirect2_playback_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t zero)
-{
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->irq_occured++;
-#endif
- /* hardware played some bytes, so there is room again (in fifo) */
- rec->hw_ready = 1;
-
- /* don't call ack() now, instead call transfer() function directly
- * (normally called by ack() )
- */
- snd_pcm_indirect2_playback_transfer(substream, rec, copy, zero);
-
- if (rec->min_periods >= rec->min_multiple) {
-#ifdef SND_PCM_INDIRECT2_STAT
- if ((rec->min_periods / rec->min_multiple) > 7)
- snd_printk(KERN_DEBUG
- "STAT: more than 7 (%d) mul_adds - too big "
- "to save!\n",
- (rec->min_periods / rec->min_multiple));
- else
- rec->mul_adds[(rec->min_periods /
- rec->min_multiple)]++;
- rec->mul_elapsed_real += (rec->min_periods /
- rec->min_multiple);
- rec->mul_elapsed++;
-#endif
- rec->min_periods = (rec->min_periods % rec->min_multiple);
- snd_pcm_period_elapsed(substream);
- }
-}
-
-/*
- * _internal_ helper function for capture interrupt callback
- */
-static void
-snd_pcm_indirect2_capture_transfer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t null)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
- snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
-
- if (diff) {
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->lastdifftime = jiffies;
-#endif
- if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
- diff += runtime->boundary;
- rec->sw_ready -= frames_to_bytes(runtime, diff);
- rec->appl_ptr = appl_ptr;
- }
- /* if hardware has something, but the intermediate buffer is full
- * => skip contents of buffer
- */
- if (rec->hw_ready && (rec->sw_ready >= (int)rec->sw_buffer_size)) {
- unsigned int bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstzerotime == 0) {
- rec->firstzerotime = jiffies;
- snd_printk(KERN_DEBUG "STAT: (capture) "
- "@firstzerotime: mul_elapsed: %d, "
- "min_period_count: %d\n",
- rec->mul_elapsed, rec->min_period_count);
- snd_printk(KERN_DEBUG "STAT: (capture) "
- "@firstzerotime: sw_io: %d, sw_data: %d, "
- "appl_ptr: %u\n",
- rec->sw_io, rec->sw_data,
- (unsigned int)appl_ptr);
- }
- if ((jiffies - rec->firstzerotime) < 3750) {
- rec->zero_times[(jiffies - rec->firstzerotime)]++;
- rec->zero_times_saved++;
- } else
- rec->zero_times_notsaved++;
-#endif
- bytes = null(substream, rec);
-
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->zeros2hw += bytes;
- if (bytes < 64)
- rec->zero_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: (capture) %d zero Bytes copied to "
- "hardware at once - too big to save!\n",
- bytes);
-#endif
- snd_pcm_indirect2_increase_min_periods(substream, rec, 0, 0,
- bytes);
- /* report an overrun */
- rec->sw_io = SNDRV_PCM_POS_XRUN;
- return;
- }
- while (rec->hw_ready && (rec->sw_ready < (int)rec->sw_buffer_size)) {
- /* sw_to_end: max. number of bytes that we can write to the
- * intermediate buffer (until it's end)
- */
- size_t sw_to_end = rec->sw_buffer_size - rec->sw_data;
-
- /* bytes: max. number of bytes, which may be copied to the
- * intermediate buffer without overflow (in _one_ step)
- */
- size_t bytes = rec->sw_buffer_size - rec->sw_ready;
-
- /* limit number of bytes (for transfer) by available room in
- * the intermediate buffer
- */
- if (sw_to_end < bytes)
- bytes = sw_to_end;
- if (!bytes)
- break;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstbytetime == 0)
- rec->firstbytetime = jiffies;
- rec->lastbytetime = jiffies;
-#endif
- /* copy bytes from the intermediate buffer (position sw_data)
- * to the HW at most and return number of bytes actually copied
- * from HW
- * Furthermore, set hw_ready to 0, if the fifo is empty now.
- */
- bytes = copy(substream, rec, bytes);
- rec->bytes2hw += bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (bytes < 64)
- rec->byte_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: (capture) %d Bytes copied to "
- "hardware at once - too big to save!\n",
- bytes);
-#endif
- /* increase sw_data by the number of actually copied bytes from
- * HW
- */
- rec->sw_data += bytes;
- if (rec->sw_data == rec->sw_buffer_size)
- rec->sw_data = 0;
-
- snd_pcm_indirect2_increase_min_periods(substream, rec, 0, 1,
- bytes);
-
- /* number of bytes in the intermediate buffer, which haven't
- * been fetched by ALSA yet.
- */
- rec->sw_ready += bytes;
- }
- return;
-}
-
-/*
- * helper function for capture interrupt routine
- */
-void
-snd_pcm_indirect2_capture_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t null)
-{
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->irq_occured++;
-#endif
- /* hardware recorded some bytes, so there is something to read from the
- * record fifo:
- */
- rec->hw_ready = 1;
-
- /* don't call ack() now, instead call transfer() function directly
- * (normally called by ack() )
- */
- snd_pcm_indirect2_capture_transfer(substream, rec, copy, null);
-
- if (rec->min_periods >= rec->min_multiple) {
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if ((rec->min_periods / rec->min_multiple) > 7)
- snd_printk(KERN_DEBUG
- "STAT: more than 7 (%d) mul_adds - "
- "too big to save!\n",
- (rec->min_periods / rec->min_multiple));
- else
- rec->mul_adds[(rec->min_periods /
- rec->min_multiple)]++;
- rec->mul_elapsed_real += (rec->min_periods /
- rec->min_multiple);
- rec->mul_elapsed++;
-#endif
- rec->min_periods = (rec->min_periods % rec->min_multiple);
- snd_pcm_period_elapsed(substream);
- }
-}
diff --git a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.h b/ANDROID_3.4.5/sound/drivers/pcm-indirect2.h
deleted file mode 100644
index 2ea6e460..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Helper functions for indirect PCM data transfer to a simple FIFO in
- * hardware (small, no possibility to read "hardware io position",
- * updating position done by interrupt, ...)
- *
- * Copyright (c) by 2007 Joachim Foerster <JOFT@gmx.de>
- *
- * Based on "pcm-indirect.h" (alsa-driver-1.0.13) by
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __SOUND_PCM_INDIRECT2_H
-#define __SOUND_PCM_INDIRECT2_H
-
-/* struct snd_pcm_substream, struct snd_pcm_runtime, snd_pcm_uframes_t */
-#include <sound/pcm.h>
-
-/* Debug options for code which may be removed completely in a final version */
-#ifdef CONFIG_SND_DEBUG
-#define SND_PCM_INDIRECT2_STAT /* turn on some "statistics" about the
- * process of copying bytes from the
- * intermediate buffer to the hardware
- * fifo and the other way round
- */
-#endif
-
-struct snd_pcm_indirect2 {
- unsigned int hw_buffer_size; /* Byte size of hardware buffer */
- int hw_ready; /* playback: 1 = hw fifo has room left,
- * 0 = hw fifo is full
- */
- unsigned int min_multiple;
- int min_periods; /* counts number of min. periods until
- * min_multiple is reached
- */
- int min_period_count; /* counts bytes to count number of
- * min. periods
- */
-
- unsigned int sw_buffer_size; /* Byte size of software buffer */
-
- /* sw_data: position in intermediate buffer, where we will read (or
- * write) from/to next time (to transfer data to/from HW)
- */
- unsigned int sw_data; /* Offset to next dst (or src) in sw
- * ring buffer
- */
- /* easiest case (playback):
- * sw_data is nearly the same as ~ runtime->control->appl_ptr, with the
- * exception that sw_data is "behind" by the number if bytes ALSA wrote
- * to the intermediate buffer last time.
- * A call to ack() callback synchronizes both indirectly.
- */
-
- /* We have no real sw_io pointer here. Usually sw_io is pointing to the
- * current playback/capture position _inside_ the hardware. Devices
- * with plain FIFOs often have no possibility to publish this position.
- * So we say: if sw_data is updated, that means bytes were copied to
- * the hardware, we increase sw_io by that amount, because there have
- * to be as much bytes which were played. So sw_io will stay behind
- * sw_data all the time and has to converge to sw_data at the end of
- * playback.
- */
- unsigned int sw_io; /* Current software pointer in bytes */
-
- /* sw_ready: number of bytes ALSA copied to the intermediate buffer, so
- * it represents the number of bytes which wait for transfer to the HW
- */
- int sw_ready; /* Bytes ready to be transferred to/from hw */
-
- /* appl_ptr: last known position of ALSA (where ALSA is going to write
- * next time into the intermediate buffer
- */
- snd_pcm_uframes_t appl_ptr; /* Last seen appl_ptr */
-
- unsigned int bytes2hw;
- int check_alignment;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- unsigned int zeros2hw;
- unsigned int mul_elapsed;
- unsigned int mul_elapsed_real;
- unsigned long firstbytetime;
- unsigned long lastbytetime;
- unsigned long firstzerotime;
- unsigned int byte_sizes[64];
- unsigned int zero_sizes[64];
- unsigned int min_adds[8];
- unsigned int mul_adds[8];
- unsigned int zero_times[3750]; /* = 15s */
- unsigned int zero_times_saved;
- unsigned int zero_times_notsaved;
- unsigned int irq_occured;
- unsigned int pointer_calls;
- unsigned int lastdifftime;
-#endif
-};
-
-typedef size_t (*snd_pcm_indirect2_copy_t) (struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- size_t bytes);
-typedef size_t (*snd_pcm_indirect2_zero_t) (struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec);
-
-#ifdef SND_PCM_INDIRECT2_STAT
-void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec);
-#endif
-
-snd_pcm_uframes_t
-snd_pcm_indirect2_pointer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec);
-void
-snd_pcm_indirect2_playback_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t zero);
-void
-snd_pcm_indirect2_capture_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t null);
-
-#endif /* __SOUND_PCM_INDIRECT2_H */
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/Makefile b/ANDROID_3.4.5/sound/drivers/pcsp/Makefile
deleted file mode 100644
index b19555b4..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-snd-pcsp-objs := pcsp.o pcsp_lib.o pcsp_mixer.o pcsp_input.o
-obj-$(CONFIG_SND_PCSP) += snd-pcsp.o
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c
deleted file mode 100644
index 99704e6a..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 1997-2001 David Woodhouse
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <linux/input.h>
-#include <linux/delay.h>
-#include <asm/bitops.h>
-#include "pcsp_input.h"
-#include "pcsp.h"
-
-MODULE_AUTHOR("Stas Sergeev <stsp@users.sourceforge.net>");
-MODULE_DESCRIPTION("PC-Speaker driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{PC-Speaker, pcsp}}");
-MODULE_ALIAS("platform:pcspkr");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
-static bool nopcm; /* Disable PCM capability of the driver */
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for pcsp soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for pcsp soundcard.");
-module_param(enable, bool, 0444);
-MODULE_PARM_DESC(enable, "Enable PC-Speaker sound.");
-module_param(nopcm, bool, 0444);
-MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain.");
-
-struct snd_pcsp pcsp_chip;
-
-static int __devinit snd_pcsp_create(struct snd_card *card)
-{
- static struct snd_device_ops ops = { };
- struct timespec tp;
- int err;
- int div, min_div, order;
-
- if (!nopcm) {
- hrtimer_get_res(CLOCK_MONOTONIC, &tp);
- if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) {
- printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
- "(%linS)\n", tp.tv_nsec);
- printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
- "enabled.\n");
- printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");
- nopcm = 1;
- }
- }
-
- if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS)
- min_div = MIN_DIV;
- else
- min_div = MAX_DIV;
-#if PCSP_DEBUG
- printk(KERN_DEBUG "PCSP: lpj=%li, min_div=%i, res=%li\n",
- loops_per_jiffy, min_div, tp.tv_nsec);
-#endif
-
- div = MAX_DIV / min_div;
- order = fls(div) - 1;
-
- pcsp_chip.max_treble = min(order, PCSP_MAX_TREBLE);
- pcsp_chip.treble = min(pcsp_chip.max_treble, PCSP_DEFAULT_TREBLE);
- pcsp_chip.playback_ptr = 0;
- pcsp_chip.period_ptr = 0;
- atomic_set(&pcsp_chip.timer_active, 0);
- pcsp_chip.enable = 1;
- pcsp_chip.pcspkr = 1;
-
- spin_lock_init(&pcsp_chip.substream_lock);
-
- pcsp_chip.card = card;
- pcsp_chip.port = 0x61;
- pcsp_chip.irq = -1;
- pcsp_chip.dma = -1;
-
- /* Register device */
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, &pcsp_chip, &ops);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
-{
- struct snd_card *card;
- int err;
-
- if (devnum != 0)
- return -EINVAL;
-
- hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- pcsp_chip.timer.function = pcsp_do_timer;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_pcsp_create(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- if (!nopcm) {
- err = snd_pcsp_new_pcm(&pcsp_chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
- err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_card_set_dev(pcsp_chip.card, dev);
-
- strcpy(card->driver, "PC-Speaker");
- strcpy(card->shortname, "pcsp");
- sprintf(card->longname, "Internal PC-Speaker at port 0x%x",
- pcsp_chip.port);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- return 0;
-}
-
-static int __devinit alsa_card_pcsp_init(struct device *dev)
-{
- int err;
-
- err = snd_card_pcsp_probe(0, dev);
- if (err) {
- printk(KERN_ERR "PC-Speaker initialization failed.\n");
- return err;
- }
-
-#ifdef CONFIG_DEBUG_PAGEALLOC
- /* Well, CONFIG_DEBUG_PAGEALLOC makes the sound horrible. Lets alert */
- printk(KERN_WARNING "PCSP: CONFIG_DEBUG_PAGEALLOC is enabled, "
- "which may make the sound noisy.\n");
-#endif
-
- return 0;
-}
-
-static void __devexit alsa_card_pcsp_exit(struct snd_pcsp *chip)
-{
- snd_card_free(chip->card);
-}
-
-static int __devinit pcsp_probe(struct platform_device *dev)
-{
- int err;
-
- err = pcspkr_input_init(&pcsp_chip.input_dev, &dev->dev);
- if (err < 0)
- return err;
-
- err = alsa_card_pcsp_init(&dev->dev);
- if (err < 0) {
- pcspkr_input_remove(pcsp_chip.input_dev);
- return err;
- }
-
- platform_set_drvdata(dev, &pcsp_chip);
- return 0;
-}
-
-static int __devexit pcsp_remove(struct platform_device *dev)
-{
- struct snd_pcsp *chip = platform_get_drvdata(dev);
- alsa_card_pcsp_exit(chip);
- pcspkr_input_remove(chip->input_dev);
- platform_set_drvdata(dev, NULL);
- return 0;
-}
-
-static void pcsp_stop_beep(struct snd_pcsp *chip)
-{
- pcsp_sync_stop(chip);
- pcspkr_stop_sound();
-}
-
-#ifdef CONFIG_PM
-static int pcsp_suspend(struct platform_device *dev, pm_message_t state)
-{
- struct snd_pcsp *chip = platform_get_drvdata(dev);
- pcsp_stop_beep(chip);
- snd_pcm_suspend_all(chip->pcm);
- return 0;
-}
-#else
-#define pcsp_suspend NULL
-#endif /* CONFIG_PM */
-
-static void pcsp_shutdown(struct platform_device *dev)
-{
- struct snd_pcsp *chip = platform_get_drvdata(dev);
- pcsp_stop_beep(chip);
-}
-
-static struct platform_driver pcsp_platform_driver = {
- .driver = {
- .name = "pcspkr",
- .owner = THIS_MODULE,
- },
- .probe = pcsp_probe,
- .remove = __devexit_p(pcsp_remove),
- .suspend = pcsp_suspend,
- .shutdown = pcsp_shutdown,
-};
-
-static int __init pcsp_init(void)
-{
- if (!enable)
- return -ENODEV;
- return platform_driver_register(&pcsp_platform_driver);
-}
-
-static void __exit pcsp_exit(void)
-{
- platform_driver_unregister(&pcsp_platform_driver);
-}
-
-module_init(pcsp_init);
-module_exit(pcsp_exit);
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h
deleted file mode 100644
index fc7a2dc4..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 1993-1997 Michael Beck
- * Copyright (C) 1997-2001 David Woodhouse
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#ifndef __PCSP_H__
-#define __PCSP_H__
-
-#include <linux/hrtimer.h>
-#include <linux/i8253.h>
-#include <linux/timex.h>
-
-#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */
-#define PCSP_DEBUG 0
-
-/* default timer freq for PC-Speaker: 18643 Hz */
-#define DIV_18KHZ 64
-#define MAX_DIV DIV_18KHZ
-#define CALC_DIV(d) (MAX_DIV >> (d))
-#define CUR_DIV() CALC_DIV(chip->treble)
-#define PCSP_MAX_TREBLE 1
-
-/* unfortunately, with hrtimers 37KHz does not work very well :( */
-#define PCSP_DEFAULT_TREBLE 0
-#define MIN_DIV (MAX_DIV >> PCSP_MAX_TREBLE)
-
-/* wild guess */
-#define PCSP_MIN_LPJ 1000000
-#define PCSP_DEFAULT_SDIV (DIV_18KHZ >> 1)
-#define PCSP_DEFAULT_SRATE (PIT_TICK_RATE / PCSP_DEFAULT_SDIV)
-#define PCSP_INDEX_INC() (1 << (PCSP_MAX_TREBLE - chip->treble))
-#define PCSP_CALC_RATE(i) (PIT_TICK_RATE / CALC_DIV(i))
-#define PCSP_RATE() PCSP_CALC_RATE(chip->treble)
-#define PCSP_MIN_RATE__1 MAX_DIV/PIT_TICK_RATE
-#define PCSP_MAX_RATE__1 MIN_DIV/PIT_TICK_RATE
-#define PCSP_MAX_PERIOD_NS (1000000000ULL * PCSP_MIN_RATE__1)
-#define PCSP_MIN_PERIOD_NS (1000000000ULL * PCSP_MAX_RATE__1)
-#define PCSP_CALC_NS(div) ({ \
- u64 __val = 1000000000ULL * (div); \
- do_div(__val, PIT_TICK_RATE); \
- __val; \
-})
-#define PCSP_PERIOD_NS() PCSP_CALC_NS(CUR_DIV())
-
-#define PCSP_MAX_PERIOD_SIZE (64*1024)
-#define PCSP_MAX_PERIODS 512
-#define PCSP_BUFFER_SIZE (128*1024)
-
-struct snd_pcsp {
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct input_dev *input_dev;
- struct hrtimer timer;
- unsigned short port, irq, dma;
- spinlock_t substream_lock;
- struct snd_pcm_substream *playback_substream;
- unsigned int fmt_size;
- unsigned int is_signed;
- size_t playback_ptr;
- size_t period_ptr;
- atomic_t timer_active;
- int thalf;
- u64 ns_rem;
- unsigned char val61;
- int enable;
- int max_treble;
- int treble;
- int pcspkr;
-};
-
-extern struct snd_pcsp pcsp_chip;
-
-extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
-extern void pcsp_sync_stop(struct snd_pcsp *chip);
-
-extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
-extern int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c
deleted file mode 100644
index b5e2b54c..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * PC Speaker beeper driver for Linux
- *
- * Copyright (c) 2002 Vojtech Pavlik
- * Copyright (c) 1992 Orest Zborowski
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation
- */
-
-#include <linux/init.h>
-#include <linux/input.h>
-#include <asm/io.h>
-#include "pcsp.h"
-
-static void pcspkr_do_sound(unsigned int count)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&i8253_lock, flags);
-
- if (count) {
- /* set command for counter 2, 2 byte write */
- outb_p(0xB6, 0x43);
- /* select desired HZ */
- outb_p(count & 0xff, 0x42);
- outb((count >> 8) & 0xff, 0x42);
- /* enable counter 2 */
- outb_p(inb_p(0x61) | 3, 0x61);
- } else {
- /* disable counter 2 */
- outb(inb_p(0x61) & 0xFC, 0x61);
- }
-
- raw_spin_unlock_irqrestore(&i8253_lock, flags);
-}
-
-void pcspkr_stop_sound(void)
-{
- pcspkr_do_sound(0);
-}
-
-static int pcspkr_input_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int value)
-{
- unsigned int count = 0;
-
- if (atomic_read(&pcsp_chip.timer_active) || !pcsp_chip.pcspkr)
- return 0;
-
- switch (type) {
- case EV_SND:
- switch (code) {
- case SND_BELL:
- if (value)
- value = 1000;
- case SND_TONE:
- break;
- default:
- return -1;
- }
- break;
-
- default:
- return -1;
- }
-
- if (value > 20 && value < 32767)
- count = PIT_TICK_RATE / value;
-
- pcspkr_do_sound(count);
-
- return 0;
-}
-
-int __devinit pcspkr_input_init(struct input_dev **rdev, struct device *dev)
-{
- int err;
-
- struct input_dev *input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- input_dev->name = "PC Speaker";
- input_dev->phys = "isa0061/input0";
- input_dev->id.bustype = BUS_ISA;
- input_dev->id.vendor = 0x001f;
- input_dev->id.product = 0x0001;
- input_dev->id.version = 0x0100;
- input_dev->dev.parent = dev;
-
- input_dev->evbit[0] = BIT(EV_SND);
- input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
- input_dev->event = pcspkr_input_event;
-
- err = input_register_device(input_dev);
- if (err) {
- input_free_device(input_dev);
- return err;
- }
-
- *rdev = input_dev;
- return 0;
-}
-
-int pcspkr_input_remove(struct input_dev *dev)
-{
- pcspkr_stop_sound();
- input_unregister_device(dev); /* this also does kfree() */
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h
deleted file mode 100644
index e66738c7..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#ifndef __PCSP_INPUT_H__
-#define __PCSP_INPUT_H__
-
-int __devinit pcspkr_input_init(struct input_dev **rdev, struct device *dev);
-int pcspkr_input_remove(struct input_dev *dev);
-void pcspkr_stop_sound(void);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c
deleted file mode 100644
index 434981dd..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 1993-1997 Michael Beck
- * Copyright (C) 1997-2001 David Woodhouse
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#include <linux/module.h>
-#include <linux/gfp.h>
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <sound/pcm.h>
-#include <asm/io.h>
-#include "pcsp.h"
-
-static bool nforce_wa;
-module_param(nforce_wa, bool, 0444);
-MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
- "(expect bad sound)");
-
-#define DMIX_WANTS_S16 1
-
-/*
- * Call snd_pcm_period_elapsed in a tasklet
- * This avoids spinlock messes and long-running irq contexts
- */
-static void pcsp_call_pcm_elapsed(unsigned long priv)
-{
- if (atomic_read(&pcsp_chip.timer_active)) {
- struct snd_pcm_substream *substream;
- substream = pcsp_chip.playback_substream;
- if (substream)
- snd_pcm_period_elapsed(substream);
- }
-}
-
-static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
-
-/* write the port and returns the next expire time in ns;
- * called at the trigger-start and in hrtimer callback
- */
-static u64 pcsp_timer_update(struct snd_pcsp *chip)
-{
- unsigned char timer_cnt, val;
- u64 ns;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned long flags;
-
- if (chip->thalf) {
- outb(chip->val61, 0x61);
- chip->thalf = 0;
- return chip->ns_rem;
- }
-
- substream = chip->playback_substream;
- if (!substream)
- return 0;
-
- runtime = substream->runtime;
- /* assume it is mono! */
- val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
- if (chip->is_signed)
- val ^= 0x80;
- timer_cnt = val * CUR_DIV() / 256;
-
- if (timer_cnt && chip->enable) {
- raw_spin_lock_irqsave(&i8253_lock, flags);
- if (!nforce_wa) {
- outb_p(chip->val61, 0x61);
- outb_p(timer_cnt, 0x42);
- outb(chip->val61 ^ 1, 0x61);
- } else {
- outb(chip->val61 ^ 2, 0x61);
- chip->thalf = 1;
- }
- raw_spin_unlock_irqrestore(&i8253_lock, flags);
- }
-
- chip->ns_rem = PCSP_PERIOD_NS();
- ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
- chip->ns_rem -= ns;
- return ns;
-}
-
-static void pcsp_pointer_update(struct snd_pcsp *chip)
-{
- struct snd_pcm_substream *substream;
- size_t period_bytes, buffer_bytes;
- int periods_elapsed;
- unsigned long flags;
-
- /* update the playback position */
- substream = chip->playback_substream;
- if (!substream)
- return;
-
- period_bytes = snd_pcm_lib_period_bytes(substream);
- buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-
- spin_lock_irqsave(&chip->substream_lock, flags);
- chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size;
- periods_elapsed = chip->playback_ptr - chip->period_ptr;
- if (periods_elapsed < 0) {
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: buffer_bytes mod period_bytes != 0 ? "
- "(%zi %zi %zi)\n",
- chip->playback_ptr, period_bytes, buffer_bytes);
-#endif
- periods_elapsed += buffer_bytes;
- }
- periods_elapsed /= period_bytes;
- /* wrap the pointer _before_ calling snd_pcm_period_elapsed(),
- * or ALSA will BUG on us. */
- chip->playback_ptr %= buffer_bytes;
-
- if (periods_elapsed) {
- chip->period_ptr += periods_elapsed * period_bytes;
- chip->period_ptr %= buffer_bytes;
- }
- spin_unlock_irqrestore(&chip->substream_lock, flags);
-
- if (periods_elapsed)
- tasklet_schedule(&pcsp_pcm_tasklet);
-}
-
-enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
-{
- struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
- int pointer_update;
- u64 ns;
-
- if (!atomic_read(&chip->timer_active) || !chip->playback_substream)
- return HRTIMER_NORESTART;
-
- pointer_update = !chip->thalf;
- ns = pcsp_timer_update(chip);
- if (!ns) {
- printk(KERN_WARNING "PCSP: unexpected stop\n");
- return HRTIMER_NORESTART;
- }
-
- if (pointer_update)
- pcsp_pointer_update(chip);
-
- hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
-
- return HRTIMER_RESTART;
-}
-
-static int pcsp_start_playing(struct snd_pcsp *chip)
-{
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: start_playing called\n");
-#endif
- if (atomic_read(&chip->timer_active)) {
- printk(KERN_ERR "PCSP: Timer already active\n");
- return -EIO;
- }
-
- raw_spin_lock(&i8253_lock);
- chip->val61 = inb(0x61) | 0x03;
- outb_p(0x92, 0x43); /* binary, mode 1, LSB only, ch 2 */
- raw_spin_unlock(&i8253_lock);
- atomic_set(&chip->timer_active, 1);
- chip->thalf = 0;
-
- hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL);
- return 0;
-}
-
-static void pcsp_stop_playing(struct snd_pcsp *chip)
-{
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: stop_playing called\n");
-#endif
- if (!atomic_read(&chip->timer_active))
- return;
-
- atomic_set(&chip->timer_active, 0);
- raw_spin_lock(&i8253_lock);
- /* restore the timer */
- outb_p(0xb6, 0x43); /* binary, mode 3, LSB/MSB, ch 2 */
- outb(chip->val61 & 0xFC, 0x61);
- raw_spin_unlock(&i8253_lock);
-}
-
-/*
- * Force to stop and sync the stream
- */
-void pcsp_sync_stop(struct snd_pcsp *chip)
-{
- local_irq_disable();
- pcsp_stop_playing(chip);
- local_irq_enable();
- hrtimer_cancel(&chip->timer);
- tasklet_kill(&pcsp_pcm_tasklet);
-}
-
-static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: close called\n");
-#endif
- pcsp_sync_stop(chip);
- chip->playback_substream = NULL;
- return 0;
-}
-
-static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- int err;
- pcsp_sync_stop(chip);
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- return 0;
-}
-
-static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: hw_free called\n");
-#endif
- pcsp_sync_stop(chip);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- pcsp_sync_stop(chip);
- chip->playback_ptr = 0;
- chip->period_ptr = 0;
- chip->fmt_size =
- snd_pcm_format_physical_width(substream->runtime->format) >> 3;
- chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: prepare called, "
- "size=%zi psize=%zi f=%zi f1=%i fsize=%i\n",
- snd_pcm_lib_buffer_bytes(substream),
- snd_pcm_lib_period_bytes(substream),
- snd_pcm_lib_buffer_bytes(substream) /
- snd_pcm_lib_period_bytes(substream),
- substream->runtime->periods,
- chip->fmt_size);
-#endif
- return 0;
-}
-
-static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: trigger called\n");
-#endif
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- return pcsp_start_playing(chip);
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- pcsp_stop_playing(chip);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
- *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- unsigned int pos;
- spin_lock(&chip->substream_lock);
- pos = chip->playback_ptr;
- spin_unlock(&chip->substream_lock);
- return bytes_to_frames(substream->runtime, pos);
-}
-
-static struct snd_pcm_hardware snd_pcsp_playback = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_HALF_DUPLEX |
- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_U8
-#if DMIX_WANTS_S16
- | SNDRV_PCM_FMTBIT_S16_LE
-#endif
- ),
- .rates = SNDRV_PCM_RATE_KNOT,
- .rate_min = PCSP_DEFAULT_SRATE,
- .rate_max = PCSP_DEFAULT_SRATE,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = PCSP_BUFFER_SIZE,
- .period_bytes_min = 64,
- .period_bytes_max = PCSP_MAX_PERIOD_SIZE,
- .periods_min = 2,
- .periods_max = PCSP_MAX_PERIODS,
- .fifo_size = 0,
-};
-
-static int snd_pcsp_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: open called\n");
-#endif
- if (atomic_read(&chip->timer_active)) {
- printk(KERN_ERR "PCSP: still active!!\n");
- return -EBUSY;
- }
- runtime->hw = snd_pcsp_playback;
- chip->playback_substream = substream;
- return 0;
-}
-
-static struct snd_pcm_ops snd_pcsp_playback_ops = {
- .open = snd_pcsp_playback_open,
- .close = snd_pcsp_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_pcsp_playback_hw_params,
- .hw_free = snd_pcsp_playback_hw_free,
- .prepare = snd_pcsp_playback_prepare,
- .trigger = snd_pcsp_trigger,
- .pointer = snd_pcsp_playback_pointer,
-};
-
-int __devinit snd_pcsp_new_pcm(struct snd_pcsp *chip)
-{
- int err;
-
- err = snd_pcm_new(chip->card, "pcspeaker", 0, 1, 0, &chip->pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(chip->pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_pcsp_playback_ops);
-
- chip->pcm->private_data = chip;
- chip->pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
- strcpy(chip->pcm->name, "pcsp");
-
- snd_pcm_lib_preallocate_pages_for_all(chip->pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data
- (GFP_KERNEL), PCSP_BUFFER_SIZE,
- PCSP_BUFFER_SIZE);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c
deleted file mode 100644
index 6f633f4f..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Mixer implementation.
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include "pcsp.h"
-
-
-static int pcsp_enable_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int pcsp_enable_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = chip->enable;
- return 0;
-}
-
-static int pcsp_enable_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int enab = ucontrol->value.integer.value[0];
- if (enab != chip->enable) {
- chip->enable = enab;
- changed = 1;
- }
- return changed;
-}
-
-static int pcsp_treble_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = chip->max_treble + 1;
- if (uinfo->value.enumerated.item > chip->max_treble)
- uinfo->value.enumerated.item = chip->max_treble;
- sprintf(uinfo->value.enumerated.name, "%lu",
- (unsigned long)PCSP_CALC_RATE(uinfo->value.enumerated.item));
- return 0;
-}
-
-static int pcsp_treble_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = chip->treble;
- return 0;
-}
-
-static int pcsp_treble_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int treble = ucontrol->value.enumerated.item[0];
- if (treble != chip->treble) {
- chip->treble = treble;
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE());
-#endif
- changed = 1;
- }
- return changed;
-}
-
-static int pcsp_pcspkr_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int pcsp_pcspkr_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = chip->pcspkr;
- return 0;
-}
-
-static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int spkr = ucontrol->value.integer.value[0];
- if (spkr != chip->pcspkr) {
- chip->pcspkr = spkr;
- changed = 1;
- }
- return changed;
-}
-
-#define PCSP_MIXER_CONTROL(ctl_type, ctl_name) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = ctl_name, \
- .info = pcsp_##ctl_type##_info, \
- .get = pcsp_##ctl_type##_get, \
- .put = pcsp_##ctl_type##_put, \
-}
-
-static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm[] = {
- PCSP_MIXER_CONTROL(enable, "Master Playback Switch"),
- PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"),
-};
-
-static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = {
- PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
-};
-
-static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip,
- struct snd_kcontrol_new *ctls, int num)
-{
- int i, err;
- struct snd_card *card = chip->card;
- for (i = 0; i < num; i++) {
- err = snd_ctl_add(card, snd_ctl_new1(ctls + i, chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
-{
- int err;
- struct snd_card *card = chip->card;
-
- if (!nopcm) {
- err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_pcm,
- ARRAY_SIZE(snd_pcsp_controls_pcm));
- if (err < 0)
- return err;
- }
- err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_spkr,
- ARRAY_SIZE(snd_pcsp_controls_spkr));
- if (err < 0)
- return err;
-
- strcpy(card->mixername, "PC-Speaker");
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/portman2x4.c b/ANDROID_3.4.5/sound/drivers/portman2x4.c
deleted file mode 100644
index 3e32bd3d..00000000
--- a/ANDROID_3.4.5/sound/drivers/portman2x4.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * Driver for Midiman Portman2x4 parallel port midi interface
- *
- * Copyright (c) by Levent Guendogdu <levon@feature-it.com>
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ChangeLog
- * Jan 24 2007 Matthias Koenig <mkoenig@suse.de>
- * - cleanup and rewrite
- * Sep 30 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - source code cleanup
- * Sep 03 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - fixed compilation problem with alsa 1.0.6a (removed MODULE_CLASSES,
- * MODULE_PARM_SYNTAX and changed MODULE_DEVICES to
- * MODULE_SUPPORTED_DEVICE)
- * Mar 24 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - added 2.6 kernel support
- * Mar 18 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - added parport_unregister_driver to the startup routine if the driver fails to detect a portman
- * - added support for all 4 output ports in portman_putmidi
- * Mar 17 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - added checks for opened input device in interrupt handler
- * Feb 20 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - ported from alsa 0.5 to 1.0
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/parport.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <sound/control.h>
-
-#define CARD_NAME "Portman 2x4"
-#define DRIVER_NAME "portman"
-#define PLATFORM_DRIVER "snd_portman2x4"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int device_count;
-
-module_param_array(index, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, S_IRUGO);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, S_IRUGO);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-
-MODULE_AUTHOR("Levent Guendogdu, Tobias Gehrig, Matthias Koenig");
-MODULE_DESCRIPTION("Midiman Portman2x4");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Midiman,Portman2x4}}");
-
-/*********************************************************************
- * Chip specific
- *********************************************************************/
-#define PORTMAN_NUM_INPUT_PORTS 2
-#define PORTMAN_NUM_OUTPUT_PORTS 4
-
-struct portman {
- spinlock_t reg_lock;
- struct snd_card *card;
- struct snd_rawmidi *rmidi;
- struct pardevice *pardev;
- int pardev_claimed;
-
- int open_count;
- int mode[PORTMAN_NUM_INPUT_PORTS];
- struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS];
-};
-
-static int portman_free(struct portman *pm)
-{
- kfree(pm);
- return 0;
-}
-
-static int __devinit portman_create(struct snd_card *card,
- struct pardevice *pardev,
- struct portman **rchip)
-{
- struct portman *pm;
-
- *rchip = NULL;
-
- pm = kzalloc(sizeof(struct portman), GFP_KERNEL);
- if (pm == NULL)
- return -ENOMEM;
-
- /* Init chip specific data */
- spin_lock_init(&pm->reg_lock);
- pm->card = card;
- pm->pardev = pardev;
-
- *rchip = pm;
-
- return 0;
-}
-
-/*********************************************************************
- * HW related constants
- *********************************************************************/
-
-/* Standard PC parallel port status register equates. */
-#define PP_STAT_BSY 0x80 /* Busy status. Inverted. */
-#define PP_STAT_ACK 0x40 /* Acknowledge. Non-Inverted. */
-#define PP_STAT_POUT 0x20 /* Paper Out. Non-Inverted. */
-#define PP_STAT_SEL 0x10 /* Select. Non-Inverted. */
-#define PP_STAT_ERR 0x08 /* Error. Non-Inverted. */
-
-/* Standard PC parallel port command register equates. */
-#define PP_CMD_IEN 0x10 /* IRQ Enable. Non-Inverted. */
-#define PP_CMD_SELI 0x08 /* Select Input. Inverted. */
-#define PP_CMD_INIT 0x04 /* Init Printer. Non-Inverted. */
-#define PP_CMD_FEED 0x02 /* Auto Feed. Inverted. */
-#define PP_CMD_STB 0x01 /* Strobe. Inverted. */
-
-/* Parallel Port Command Register as implemented by PCP2x4. */
-#define INT_EN PP_CMD_IEN /* Interrupt enable. */
-#define STROBE PP_CMD_STB /* Command strobe. */
-
-/* The parallel port command register field (b1..b3) selects the
- * various "registers" within the PC/P 2x4. These are the internal
- * address of these "registers" that must be written to the parallel
- * port command register.
- */
-#define RXDATA0 (0 << 1) /* PCP RxData channel 0. */
-#define RXDATA1 (1 << 1) /* PCP RxData channel 1. */
-#define GEN_CTL (2 << 1) /* PCP General Control Register. */
-#define SYNC_CTL (3 << 1) /* PCP Sync Control Register. */
-#define TXDATA0 (4 << 1) /* PCP TxData channel 0. */
-#define TXDATA1 (5 << 1) /* PCP TxData channel 1. */
-#define TXDATA2 (6 << 1) /* PCP TxData channel 2. */
-#define TXDATA3 (7 << 1) /* PCP TxData channel 3. */
-
-/* Parallel Port Status Register as implemented by PCP2x4. */
-#define ESTB PP_STAT_POUT /* Echoed strobe. */
-#define INT_REQ PP_STAT_ACK /* Input data int request. */
-#define BUSY PP_STAT_ERR /* Interface Busy. */
-
-/* Parallel Port Status Register BUSY and SELECT lines are multiplexed
- * between several functions. Depending on which 2x4 "register" is
- * currently selected (b1..b3), the BUSY and SELECT lines are
- * assigned as follows:
- *
- * SELECT LINE: A3 A2 A1
- * --------
- */
-#define RXAVAIL PP_STAT_SEL /* Rx Available, channel 0. 0 0 0 */
-// RXAVAIL1 PP_STAT_SEL /* Rx Available, channel 1. 0 0 1 */
-#define SYNC_STAT PP_STAT_SEL /* Reserved - Sync Status. 0 1 0 */
-// /* Reserved. 0 1 1 */
-#define TXEMPTY PP_STAT_SEL /* Tx Empty, channel 0. 1 0 0 */
-// TXEMPTY1 PP_STAT_SEL /* Tx Empty, channel 1. 1 0 1 */
-// TXEMPTY2 PP_STAT_SEL /* Tx Empty, channel 2. 1 1 0 */
-// TXEMPTY3 PP_STAT_SEL /* Tx Empty, channel 3. 1 1 1 */
-
-/* BUSY LINE: A3 A2 A1
- * --------
- */
-#define RXDATA PP_STAT_BSY /* Rx Input Data, channel 0. 0 0 0 */
-// RXDATA1 PP_STAT_BSY /* Rx Input Data, channel 1. 0 0 1 */
-#define SYNC_DATA PP_STAT_BSY /* Reserved - Sync Data. 0 1 0 */
- /* Reserved. 0 1 1 */
-#define DATA_ECHO PP_STAT_BSY /* Parallel Port Data Echo. 1 0 0 */
-#define A0_ECHO PP_STAT_BSY /* Address 0 Echo. 1 0 1 */
-#define A1_ECHO PP_STAT_BSY /* Address 1 Echo. 1 1 0 */
-#define A2_ECHO PP_STAT_BSY /* Address 2 Echo. 1 1 1 */
-
-#define PORTMAN2X4_MODE_INPUT_TRIGGERED 0x01
-
-/*********************************************************************
- * Hardware specific functions
- *********************************************************************/
-static inline void portman_write_command(struct portman *pm, u8 value)
-{
- parport_write_control(pm->pardev->port, value);
-}
-
-static inline u8 portman_read_command(struct portman *pm)
-{
- return parport_read_control(pm->pardev->port);
-}
-
-static inline u8 portman_read_status(struct portman *pm)
-{
- return parport_read_status(pm->pardev->port);
-}
-
-static inline u8 portman_read_data(struct portman *pm)
-{
- return parport_read_data(pm->pardev->port);
-}
-
-static inline void portman_write_data(struct portman *pm, u8 value)
-{
- parport_write_data(pm->pardev->port, value);
-}
-
-static void portman_write_midi(struct portman *pm,
- int port, u8 mididata)
-{
- int command = ((port + 4) << 1);
-
- /* Get entering data byte and port number in BL and BH respectively.
- * Set up Tx Channel address field for use with PP Cmd Register.
- * Store address field in BH register.
- * Inputs: AH = Output port number (0..3).
- * AL = Data byte.
- * command = TXDATA0 | INT_EN;
- * Align port num with address field (b1...b3),
- * set address for TXDatax, Strobe=0
- */
- command |= INT_EN;
-
- /* Disable interrupts so that the process is not interrupted, then
- * write the address associated with the current Tx channel to the
- * PP Command Reg. Do not set the Strobe signal yet.
- */
-
- do {
- portman_write_command(pm, command);
-
- /* While the address lines settle, write parallel output data to
- * PP Data Reg. This has no effect until Strobe signal is asserted.
- */
-
- portman_write_data(pm, mididata);
-
- /* If PCP channel's TxEmpty is set (TxEmpty is read through the PP
- * Status Register), then go write data. Else go back and wait.
- */
- } while ((portman_read_status(pm) & TXEMPTY) != TXEMPTY);
-
- /* TxEmpty is set. Maintain PC/P destination address and assert
- * Strobe through the PP Command Reg. This will Strobe data into
- * the PC/P transmitter and set the PC/P BUSY signal.
- */
-
- portman_write_command(pm, command | STROBE);
-
- /* Wait for strobe line to settle and echo back through hardware.
- * Once it has echoed back, assume that the address and data lines
- * have settled!
- */
-
- while ((portman_read_status(pm) & ESTB) == 0)
- cpu_relax();
-
- /* Release strobe and immediately re-allow interrupts. */
- portman_write_command(pm, command);
-
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax();
-
- /* PC/P BUSY is now set. We must wait until BUSY resets itself.
- * We'll reenable ints while we're waiting.
- */
-
- while ((portman_read_status(pm) & BUSY) == BUSY)
- cpu_relax();
-
- /* Data sent. */
-}
-
-
-/*
- * Read MIDI byte from port
- * Attempt to read input byte from specified hardware input port (0..).
- * Return -1 if no data
- */
-static int portman_read_midi(struct portman *pm, int port)
-{
- unsigned char midi_data = 0;
- unsigned char cmdout; /* Saved address+IE bit. */
-
- /* Make sure clocking edge is down before starting... */
- portman_write_data(pm, 0); /* Make sure edge is down. */
-
- /* Set destination address to PCP. */
- cmdout = (port << 1) | INT_EN; /* Address + IE + No Strobe. */
- portman_write_command(pm, cmdout);
-
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax(); /* Wait for strobe echo. */
-
- /* After the address lines settle, check multiplexed RxAvail signal.
- * If data is available, read it.
- */
- if ((portman_read_status(pm) & RXAVAIL) == 0)
- return -1; /* No data. */
-
- /* Set the Strobe signal to enable the Rx clocking circuitry. */
- portman_write_command(pm, cmdout | STROBE); /* Write address+IE+Strobe. */
-
- while ((portman_read_status(pm) & ESTB) == 0)
- cpu_relax(); /* Wait for strobe echo. */
-
- /* The first data bit (msb) is already sitting on the input line. */
- midi_data = (portman_read_status(pm) & 128);
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 6. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 1) & 64;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 5. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 2) & 32;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 4. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 3) & 16;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 3. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 4) & 8;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 2. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 5) & 4;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 1. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 6) & 2;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 0. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 7) & 1;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
- portman_write_data(pm, 0); /* Return data clock low. */
-
-
- /* De-assert Strobe and return data. */
- portman_write_command(pm, cmdout); /* Output saved address+IE. */
-
- /* Wait for strobe echo. */
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax();
-
- return (midi_data & 255); /* Shift back and return value. */
-}
-
-/*
- * Checks if any input data on the given channel is available
- * Checks RxAvail
- */
-static int portman_data_avail(struct portman *pm, int channel)
-{
- int command = INT_EN;
- switch (channel) {
- case 0:
- command |= RXDATA0;
- break;
- case 1:
- command |= RXDATA1;
- break;
- }
- /* Write hardware (assumme STROBE=0) */
- portman_write_command(pm, command);
- /* Check multiplexed RxAvail signal */
- if ((portman_read_status(pm) & RXAVAIL) == RXAVAIL)
- return 1; /* Data available */
-
- /* No Data available */
- return 0;
-}
-
-
-/*
- * Flushes any input
- */
-static void portman_flush_input(struct portman *pm, unsigned char port)
-{
- /* Local variable for counting things */
- unsigned int i = 0;
- unsigned char command = 0;
-
- switch (port) {
- case 0:
- command = RXDATA0;
- break;
- case 1:
- command = RXDATA1;
- break;
- default:
- snd_printk(KERN_WARNING
- "portman_flush_input() Won't flush port %i\n",
- port);
- return;
- }
-
- /* Set address for specified channel in port and allow to settle. */
- portman_write_command(pm, command);
-
- /* Assert the Strobe and wait for echo back. */
- portman_write_command(pm, command | STROBE);
-
- /* Wait for ESTB */
- while ((portman_read_status(pm) & ESTB) == 0)
- cpu_relax();
-
- /* Output clock cycles to the Rx circuitry. */
- portman_write_data(pm, 0);
-
- /* Flush 250 bits... */
- for (i = 0; i < 250; i++) {
- portman_write_data(pm, 1);
- portman_write_data(pm, 0);
- }
-
- /* Deassert the Strobe signal of the port and wait for it to settle. */
- portman_write_command(pm, command | INT_EN);
-
- /* Wait for settling */
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax();
-}
-
-static int portman_probe(struct parport *p)
-{
- /* Initialize the parallel port data register. Will set Rx clocks
- * low in case we happen to be addressing the Rx ports at this time.
- */
- /* 1 */
- parport_write_data(p, 0);
-
- /* Initialize the parallel port command register, thus initializing
- * hardware handshake lines to midi box:
- *
- * Strobe = 0
- * Interrupt Enable = 0
- */
- /* 2 */
- parport_write_control(p, 0);
-
- /* Check if Portman PC/P 2x4 is out there. */
- /* 3 */
- parport_write_control(p, RXDATA0); /* Write Strobe=0 to command reg. */
-
- /* Check for ESTB to be clear */
- /* 4 */
- if ((parport_read_status(p) & ESTB) == ESTB)
- return 1; /* CODE 1 - Strobe Failure. */
-
- /* Set for RXDATA0 where no damage will be done. */
- /* 5 */
- parport_write_control(p, RXDATA0 + STROBE); /* Write Strobe=1 to command reg. */
-
- /* 6 */
- if ((parport_read_status(p) & ESTB) != ESTB)
- return 1; /* CODE 1 - Strobe Failure. */
-
- /* 7 */
- parport_write_control(p, 0); /* Reset Strobe=0. */
-
- /* Check if Tx circuitry is functioning properly. If initialized
- * unit TxEmpty is false, send out char and see if if goes true.
- */
- /* 8 */
- parport_write_control(p, TXDATA0); /* Tx channel 0, strobe off. */
-
- /* If PCP channel's TxEmpty is set (TxEmpty is read through the PP
- * Status Register), then go write data. Else go back and wait.
- */
- /* 9 */
- if ((parport_read_status(p) & TXEMPTY) == 0)
- return 2;
-
- /* Return OK status. */
- return 0;
-}
-
-static int portman_device_init(struct portman *pm)
-{
- portman_flush_input(pm, 0);
- portman_flush_input(pm, 1);
-
- return 0;
-}
-
-/*********************************************************************
- * Rawmidi
- *********************************************************************/
-static int snd_portman_midi_open(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static int snd_portman_midi_close(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static void snd_portman_midi_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct portman *pm = substream->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&pm->reg_lock, flags);
- if (up)
- pm->mode[substream->number] |= PORTMAN2X4_MODE_INPUT_TRIGGERED;
- else
- pm->mode[substream->number] &= ~PORTMAN2X4_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&pm->reg_lock, flags);
-}
-
-static void snd_portman_midi_output_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct portman *pm = substream->rmidi->private_data;
- unsigned long flags;
- unsigned char byte;
-
- spin_lock_irqsave(&pm->reg_lock, flags);
- if (up) {
- while ((snd_rawmidi_transmit(substream, &byte, 1) == 1))
- portman_write_midi(pm, substream->number, byte);
- }
- spin_unlock_irqrestore(&pm->reg_lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_portman_midi_output = {
- .open = snd_portman_midi_open,
- .close = snd_portman_midi_close,
- .trigger = snd_portman_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_portman_midi_input = {
- .open = snd_portman_midi_open,
- .close = snd_portman_midi_close,
- .trigger = snd_portman_midi_input_trigger,
-};
-
-/* Create and initialize the rawmidi component */
-static int __devinit snd_portman_rawmidi_create(struct snd_card *card)
-{
- struct portman *pm = card->private_data;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *substream;
- int err;
-
- err = snd_rawmidi_new(card, CARD_NAME, 0,
- PORTMAN_NUM_OUTPUT_PORTS,
- PORTMAN_NUM_INPUT_PORTS,
- &rmidi);
- if (err < 0)
- return err;
-
- rmidi->private_data = pm;
- strcpy(rmidi->name, CARD_NAME);
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
-
- pm->rmidi = rmidi;
-
- /* register rawmidi ops */
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_portman_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_portman_midi_input);
-
- /* name substreams */
- /* output */
- list_for_each_entry(substream,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
- list) {
- sprintf(substream->name,
- "Portman2x4 %d", substream->number+1);
- }
- /* input */
- list_for_each_entry(substream,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams,
- list) {
- pm->midi_input[substream->number] = substream;
- sprintf(substream->name,
- "Portman2x4 %d", substream->number+1);
- }
-
- return err;
-}
-
-/*********************************************************************
- * parport stuff
- *********************************************************************/
-static void snd_portman_interrupt(void *userdata)
-{
- unsigned char midivalue = 0;
- struct portman *pm = ((struct snd_card*)userdata)->private_data;
-
- spin_lock(&pm->reg_lock);
-
- /* While any input data is waiting */
- while ((portman_read_status(pm) & INT_REQ) == INT_REQ) {
- /* If data available on channel 0,
- read it and stuff it into the queue. */
- if (portman_data_avail(pm, 0)) {
- /* Read Midi */
- midivalue = portman_read_midi(pm, 0);
- /* put midi into queue... */
- if (pm->mode[0] & PORTMAN2X4_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(pm->midi_input[0],
- &midivalue, 1);
-
- }
- /* If data available on channel 1,
- read it and stuff it into the queue. */
- if (portman_data_avail(pm, 1)) {
- /* Read Midi */
- midivalue = portman_read_midi(pm, 1);
- /* put midi into queue... */
- if (pm->mode[1] & PORTMAN2X4_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(pm->midi_input[1],
- &midivalue, 1);
- }
-
- }
-
- spin_unlock(&pm->reg_lock);
-}
-
-static int __devinit snd_portman_probe_port(struct parport *p)
-{
- struct pardevice *pardev;
- int res;
-
- pardev = parport_register_device(p, DRIVER_NAME,
- NULL, NULL, NULL,
- 0, NULL);
- if (!pardev)
- return -EIO;
-
- if (parport_claim(pardev)) {
- parport_unregister_device(pardev);
- return -EIO;
- }
-
- res = portman_probe(p);
-
- parport_release(pardev);
- parport_unregister_device(pardev);
-
- return res ? -EIO : 0;
-}
-
-static void __devinit snd_portman_attach(struct parport *p)
-{
- struct platform_device *device;
-
- device = platform_device_alloc(PLATFORM_DRIVER, device_count);
- if (!device)
- return;
-
- /* Temporary assignment to forward the parport */
- platform_set_drvdata(device, p);
-
- if (platform_device_add(device) < 0) {
- platform_device_put(device);
- return;
- }
-
- /* Since we dont get the return value of probe
- * We need to check if device probing succeeded or not */
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- return;
- }
-
- /* register device in global table */
- platform_devices[device_count] = device;
- device_count++;
-}
-
-static void snd_portman_detach(struct parport *p)
-{
- /* nothing to do here */
-}
-
-static struct parport_driver portman_parport_driver = {
- .name = "portman2x4",
- .attach = snd_portman_attach,
- .detach = snd_portman_detach
-};
-
-/*********************************************************************
- * platform stuff
- *********************************************************************/
-static void snd_portman_card_private_free(struct snd_card *card)
-{
- struct portman *pm = card->private_data;
- struct pardevice *pardev = pm->pardev;
-
- if (pardev) {
- if (pm->pardev_claimed)
- parport_release(pardev);
- parport_unregister_device(pardev);
- }
-
- portman_free(pm);
-}
-
-static int __devinit snd_portman_probe(struct platform_device *pdev)
-{
- struct pardevice *pardev;
- struct parport *p;
- int dev = pdev->id;
- struct snd_card *card = NULL;
- struct portman *pm = NULL;
- int err;
-
- p = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev])
- return -ENOENT;
-
- if ((err = snd_portman_probe_port(p)) < 0)
- return err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printd("Cannot create card\n");
- return err;
- }
- strcpy(card->driver, DRIVER_NAME);
- strcpy(card->shortname, CARD_NAME);
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, p->base, p->irq);
-
- pardev = parport_register_device(p, /* port */
- DRIVER_NAME, /* name */
- NULL, /* preempt */
- NULL, /* wakeup */
- snd_portman_interrupt, /* ISR */
- PARPORT_DEV_EXCL, /* flags */
- (void *)card); /* private */
- if (pardev == NULL) {
- snd_printd("Cannot register pardevice\n");
- err = -EIO;
- goto __err;
- }
-
- if ((err = portman_create(card, pardev, &pm)) < 0) {
- snd_printd("Cannot create main component\n");
- parport_unregister_device(pardev);
- goto __err;
- }
- card->private_data = pm;
- card->private_free = snd_portman_card_private_free;
-
- if ((err = snd_portman_rawmidi_create(card)) < 0) {
- snd_printd("Creating Rawmidi component failed\n");
- goto __err;
- }
-
- /* claim parport */
- if (parport_claim(pardev)) {
- snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
- err = -EIO;
- goto __err;
- }
- pm->pardev_claimed = 1;
-
- /* init device */
- if ((err = portman_device_init(pm)) < 0)
- goto __err;
-
- platform_set_drvdata(pdev, card);
-
- snd_card_set_dev(card, &pdev->dev);
-
- /* At this point card will be usable */
- if ((err = snd_card_register(card)) < 0) {
- snd_printd("Cannot register card\n");
- goto __err;
- }
-
- snd_printk(KERN_INFO "Portman 2x4 on 0x%lx\n", p->base);
- return 0;
-
-__err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_portman_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- if (card)
- snd_card_free(card);
-
- return 0;
-}
-
-
-static struct platform_driver snd_portman_driver = {
- .probe = snd_portman_probe,
- .remove = __devexit_p(snd_portman_remove),
- .driver = {
- .name = PLATFORM_DRIVER
- }
-};
-
-/*********************************************************************
- * module init stuff
- *********************************************************************/
-static void snd_portman_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < SNDRV_CARDS; ++i) {
- if (platform_devices[i]) {
- platform_device_unregister(platform_devices[i]);
- platform_devices[i] = NULL;
- }
- }
- platform_driver_unregister(&snd_portman_driver);
- parport_unregister_driver(&portman_parport_driver);
-}
-
-static int __init snd_portman_module_init(void)
-{
- int err;
-
- if ((err = platform_driver_register(&snd_portman_driver)) < 0)
- return err;
-
- if (parport_register_driver(&portman_parport_driver) != 0) {
- platform_driver_unregister(&snd_portman_driver);
- return -EIO;
- }
-
- if (device_count == 0) {
- snd_portman_unregister_all();
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit snd_portman_module_exit(void)
-{
- snd_portman_unregister_all();
-}
-
-module_init(snd_portman_module_init);
-module_exit(snd_portman_module_exit);
diff --git a/ANDROID_3.4.5/sound/drivers/serial-u16550.c b/ANDROID_3.4.5/sound/drivers/serial-u16550.c
deleted file mode 100644
index b2d0e8e4..00000000
--- a/ANDROID_3.4.5/sound/drivers/serial-u16550.c
+++ /dev/null
@@ -1,1050 +0,0 @@
-/*
- * serial.c
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
- * Isaku Yamahata <yamahata@private.email.ne.jp>,
- * George Hansper <ghansper@apana.org.au>,
- * Hannu Savolainen
- *
- * This code is based on the code from ALSA 0.5.9, but heavily rewritten.
- *
- * 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
- *
- * Sat Mar 31 17:27:57 PST 2001 tim.mann@compaq.com
- * Added support for the Midiator MS-124T and for the MS-124W in
- * Single Addressed (S/A) or Multiple Burst (M/B) mode, with
- * power derived either parasitically from the serial port or
- * from a separate power supply.
- *
- * More documentation can be found in serial-u16550.txt.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/rawmidi.h>
-#include <sound/initval.h>
-
-#include <linux/serial_reg.h>
-#include <linux/jiffies.h>
-
-#include <asm/io.h>
-
-MODULE_DESCRIPTION("MIDI serial u16550");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA, MIDI serial u16550}}");
-
-#define SNDRV_SERIAL_SOUNDCANVAS 0 /* Roland Soundcanvas; F5 NN selects part */
-#define SNDRV_SERIAL_MS124T 1 /* Midiator MS-124T */
-#define SNDRV_SERIAL_MS124W_SA 2 /* Midiator MS-124W in S/A mode */
-#define SNDRV_SERIAL_MS124W_MB 3 /* Midiator MS-124W in M/B mode */
-#define SNDRV_SERIAL_GENERIC 4 /* Generic Interface */
-#define SNDRV_SERIAL_MAX_ADAPTOR SNDRV_SERIAL_GENERIC
-static char *adaptor_names[] = {
- "Soundcanvas",
- "MS-124T",
- "MS-124W S/A",
- "MS-124W M/B",
- "Generic"
-};
-
-#define SNDRV_SERIAL_NORMALBUFF 0 /* Normal blocking buffer operation */
-#define SNDRV_SERIAL_DROPBUFF 1 /* Non-blocking discard operation */
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,4,5,7,9,10,11,14,15 */
-static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */
-static int base[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 115200}; /* baud base */
-static int outs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */
-static int ins[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */
-static int adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS};
-static bool droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF };
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Serial MIDI.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Serial MIDI.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable UART16550A chip.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for UART16550A chip.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for UART16550A chip.");
-module_param_array(speed, int, NULL, 0444);
-MODULE_PARM_DESC(speed, "Speed in bauds.");
-module_param_array(base, int, NULL, 0444);
-MODULE_PARM_DESC(base, "Base for divisor in bauds.");
-module_param_array(outs, int, NULL, 0444);
-MODULE_PARM_DESC(outs, "Number of MIDI outputs.");
-module_param_array(ins, int, NULL, 0444);
-MODULE_PARM_DESC(ins, "Number of MIDI inputs.");
-module_param_array(droponfull, bool, NULL, 0444);
-MODULE_PARM_DESC(droponfull, "Flag to enable drop-on-full buffer mode");
-
-module_param_array(adaptor, int, NULL, 0444);
-MODULE_PARM_DESC(adaptor, "Type of adaptor.");
-
-/*#define SNDRV_SERIAL_MS124W_MB_NOCOMBO 1*/ /* Address outs as 0-3 instead of bitmap */
-
-#define SNDRV_SERIAL_MAX_OUTS 16 /* max 64, min 16 */
-#define SNDRV_SERIAL_MAX_INS 16 /* max 64, min 16 */
-
-#define TX_BUFF_SIZE (1<<15) /* Must be 2^n */
-#define TX_BUFF_MASK (TX_BUFF_SIZE - 1)
-
-#define SERIAL_MODE_NOT_OPENED (0)
-#define SERIAL_MODE_INPUT_OPEN (1 << 0)
-#define SERIAL_MODE_OUTPUT_OPEN (1 << 1)
-#define SERIAL_MODE_INPUT_TRIGGERED (1 << 2)
-#define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3)
-
-struct snd_uart16550 {
- struct snd_card *card;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *midi_output[SNDRV_SERIAL_MAX_OUTS];
- struct snd_rawmidi_substream *midi_input[SNDRV_SERIAL_MAX_INS];
-
- int filemode; /* open status of file */
-
- spinlock_t open_lock;
-
- int irq;
-
- unsigned long base;
- struct resource *res_base;
-
- unsigned int speed;
- unsigned int speed_base;
- unsigned char divisor;
-
- unsigned char old_divisor_lsb;
- unsigned char old_divisor_msb;
- unsigned char old_line_ctrl_reg;
-
- /* parameter for using of write loop */
- short int fifo_limit; /* used in uart16550 */
- short int fifo_count; /* used in uart16550 */
-
- /* type of adaptor */
- int adaptor;
-
- /* inputs */
- int prev_in;
- unsigned char rstatus;
-
- /* outputs */
- int prev_out;
- unsigned char prev_status[SNDRV_SERIAL_MAX_OUTS];
-
- /* write buffer and its writing/reading position */
- unsigned char tx_buff[TX_BUFF_SIZE];
- int buff_in_count;
- int buff_in;
- int buff_out;
- int drop_on_full;
-
- /* wait timer */
- unsigned int timer_running:1;
- struct timer_list buffer_timer;
-
-};
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart)
-{
- if (!uart->timer_running) {
- /* timer 38600bps * 10bit * 16byte */
- uart->buffer_timer.expires = jiffies + (HZ+255)/256;
- uart->timer_running = 1;
- add_timer(&uart->buffer_timer);
- }
-}
-
-static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart)
-{
- if (uart->timer_running) {
- del_timer(&uart->buffer_timer);
- uart->timer_running = 0;
- }
-}
-
-/* This macro is only used in snd_uart16550_io_loop */
-static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart)
-{
- unsigned short buff_out = uart->buff_out;
- if (uart->buff_in_count > 0) {
- outb(uart->tx_buff[buff_out], uart->base + UART_TX);
- uart->fifo_count++;
- buff_out++;
- buff_out &= TX_BUFF_MASK;
- uart->buff_out = buff_out;
- uart->buff_in_count--;
- }
-}
-
-/* This loop should be called with interrupts disabled
- * We don't want to interrupt this,
- * as we're already handling an interrupt
- */
-static void snd_uart16550_io_loop(struct snd_uart16550 * uart)
-{
- unsigned char c, status;
- int substream;
-
- /* recall previous stream */
- substream = uart->prev_in;
-
- /* Read Loop */
- while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) {
- /* while receive data ready */
- c = inb(uart->base + UART_RX);
-
- /* keep track of last status byte */
- if (c & 0x80)
- uart->rstatus = c;
-
- /* handle stream switch */
- if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
- if (uart->rstatus == 0xf5) {
- if (c <= SNDRV_SERIAL_MAX_INS && c > 0)
- substream = c - 1;
- if (c != 0xf5)
- /* prevent future bytes from being
- interpreted as streams */
- uart->rstatus = 0;
- } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN)
- && uart->midi_input[substream])
- snd_rawmidi_receive(uart->midi_input[substream],
- &c, 1);
- } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) &&
- uart->midi_input[substream])
- snd_rawmidi_receive(uart->midi_input[substream], &c, 1);
-
- if (status & UART_LSR_OE)
- snd_printk(KERN_WARNING
- "%s: Overrun on device at 0x%lx\n",
- uart->rmidi->name, uart->base);
- }
-
- /* remember the last stream */
- uart->prev_in = substream;
-
- /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not,
- buffer is never filled. */
- /* Check write status */
- if (status & UART_LSR_THRE)
- uart->fifo_count = 0;
- if (uart->adaptor == SNDRV_SERIAL_MS124W_SA
- || uart->adaptor == SNDRV_SERIAL_GENERIC) {
- /* Can't use FIFO, must send only when CTS is true */
- status = inb(uart->base + UART_MSR);
- while (uart->fifo_count == 0 && (status & UART_MSR_CTS) &&
- uart->buff_in_count > 0) {
- snd_uart16550_buffer_output(uart);
- status = inb(uart->base + UART_MSR);
- }
- } else {
- /* Write loop */
- while (uart->fifo_count < uart->fifo_limit /* Can we write ? */
- && uart->buff_in_count > 0) /* Do we want to? */
- snd_uart16550_buffer_output(uart);
- }
- if (uart->irq < 0 && uart->buff_in_count > 0)
- snd_uart16550_add_timer(uart);
-}
-
-/* NOTES ON SERVICING INTERUPTS
- * ---------------------------
- * After receiving a interrupt, it is important to indicate to the UART that
- * this has been done.
- * For a Rx interrupt, this is done by reading the received byte.
- * For a Tx interrupt this is done by either:
- * a) Writing a byte
- * b) Reading the IIR
- * It is particularly important to read the IIR if a Tx interrupt is received
- * when there is no data in tx_buff[], as in this case there no other
- * indication that the interrupt has been serviced, and it remains outstanding
- * indefinitely. This has the curious side effect that and no further interrupts
- * will be generated from this device AT ALL!!.
- * It is also desirable to clear outstanding interrupts when the device is
- * opened/closed.
- *
- *
- * Note that some devices need OUT2 to be set before they will generate
- * interrupts at all. (Possibly tied to an internal pull-up on CTS?)
- */
-static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
-{
- struct snd_uart16550 *uart;
-
- uart = dev_id;
- spin_lock(&uart->open_lock);
- if (uart->filemode == SERIAL_MODE_NOT_OPENED) {
- spin_unlock(&uart->open_lock);
- return IRQ_NONE;
- }
- /* indicate to the UART that the interrupt has been serviced */
- inb(uart->base + UART_IIR);
- snd_uart16550_io_loop(uart);
- spin_unlock(&uart->open_lock);
- return IRQ_HANDLED;
-}
-
-/* When the polling mode, this function calls snd_uart16550_io_loop. */
-static void snd_uart16550_buffer_timer(unsigned long data)
-{
- unsigned long flags;
- struct snd_uart16550 *uart;
-
- uart = (struct snd_uart16550 *)data;
- spin_lock_irqsave(&uart->open_lock, flags);
- snd_uart16550_del_timer(uart);
- snd_uart16550_io_loop(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
-}
-
-/*
- * this method probes, if an uart sits on given port
- * return 0 if found
- * return negative error if not found
- */
-static int __devinit snd_uart16550_detect(struct snd_uart16550 *uart)
-{
- unsigned long io_base = uart->base;
- int ok;
- unsigned char c;
-
- /* Do some vague tests for the presence of the uart */
- if (io_base == 0 || io_base == SNDRV_AUTO_PORT) {
- return -ENODEV; /* Not configured */
- }
-
- uart->res_base = request_region(io_base, 8, "Serial MIDI");
- if (uart->res_base == NULL) {
- snd_printk(KERN_ERR "u16550: can't grab port 0x%lx\n", io_base);
- return -EBUSY;
- }
-
- /* uart detected unless one of the following tests should fail */
- ok = 1;
- /* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */
- outb(UART_LCR_WLEN8, io_base + UART_LCR); /* Line Control Register */
- c = inb(io_base + UART_IER);
- /* The top four bits of the IER should always == 0 */
- if ((c & 0xf0) != 0)
- ok = 0; /* failed */
-
- outb(0xaa, io_base + UART_SCR);
- /* Write arbitrary data into the scratch reg */
- c = inb(io_base + UART_SCR);
- /* If it comes back, it's OK */
- if (c != 0xaa)
- ok = 0; /* failed */
-
- outb(0x55, io_base + UART_SCR);
- /* Write arbitrary data into the scratch reg */
- c = inb(io_base + UART_SCR);
- /* If it comes back, it's OK */
- if (c != 0x55)
- ok = 0; /* failed */
-
- return ok;
-}
-
-static void snd_uart16550_do_open(struct snd_uart16550 * uart)
-{
- char byte;
-
- /* Initialize basic variables */
- uart->buff_in_count = 0;
- uart->buff_in = 0;
- uart->buff_out = 0;
- uart->fifo_limit = 1;
- uart->fifo_count = 0;
- uart->timer_running = 0;
-
- outb(UART_FCR_ENABLE_FIFO /* Enable FIFO's (if available) */
- | UART_FCR_CLEAR_RCVR /* Clear receiver FIFO */
- | UART_FCR_CLEAR_XMIT /* Clear transmitter FIFO */
- | UART_FCR_TRIGGER_4 /* Set FIFO trigger at 4-bytes */
- /* NOTE: interrupt generated after T=(time)4-bytes
- * if less than UART_FCR_TRIGGER bytes received
- */
- ,uart->base + UART_FCR); /* FIFO Control Register */
-
- if ((inb(uart->base + UART_IIR) & 0xf0) == 0xc0)
- uart->fifo_limit = 16;
- if (uart->divisor != 0) {
- uart->old_line_ctrl_reg = inb(uart->base + UART_LCR);
- outb(UART_LCR_DLAB /* Divisor latch access bit */
- ,uart->base + UART_LCR); /* Line Control Register */
- uart->old_divisor_lsb = inb(uart->base + UART_DLL);
- uart->old_divisor_msb = inb(uart->base + UART_DLM);
-
- outb(uart->divisor
- ,uart->base + UART_DLL); /* Divisor Latch Low */
- outb(0
- ,uart->base + UART_DLM); /* Divisor Latch High */
- /* DLAB is reset to 0 in next outb() */
- }
- /* Set serial parameters (parity off, etc) */
- outb(UART_LCR_WLEN8 /* 8 data-bits */
- | 0 /* 1 stop-bit */
- | 0 /* parity off */
- | 0 /* DLAB = 0 */
- ,uart->base + UART_LCR); /* Line Control Register */
-
- switch (uart->adaptor) {
- default:
- outb(UART_MCR_RTS /* Set Request-To-Send line active */
- | UART_MCR_DTR /* Set Data-Terminal-Ready line active */
- | UART_MCR_OUT2 /* Set OUT2 - not always required, but when
- * it is, it is ESSENTIAL for enabling interrupts
- */
- ,uart->base + UART_MCR); /* Modem Control Register */
- break;
- case SNDRV_SERIAL_MS124W_SA:
- case SNDRV_SERIAL_MS124W_MB:
- /* MS-124W can draw power from RTS and DTR if they
- are in opposite states. */
- outb(UART_MCR_RTS | (0&UART_MCR_DTR) | UART_MCR_OUT2,
- uart->base + UART_MCR);
- break;
- case SNDRV_SERIAL_MS124T:
- /* MS-124T can draw power from RTS and/or DTR (preferably
- both) if they are both asserted. */
- outb(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2,
- uart->base + UART_MCR);
- break;
- }
-
- if (uart->irq < 0) {
- byte = (0 & UART_IER_RDI) /* Disable Receiver data interrupt */
- |(0 & UART_IER_THRI) /* Disable Transmitter holding register empty interrupt */
- ;
- } else if (uart->adaptor == SNDRV_SERIAL_MS124W_SA) {
- byte = UART_IER_RDI /* Enable Receiver data interrupt */
- | UART_IER_MSI /* Enable Modem status interrupt */
- ;
- } else if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
- byte = UART_IER_RDI /* Enable Receiver data interrupt */
- | UART_IER_MSI /* Enable Modem status interrupt */
- | UART_IER_THRI /* Enable Transmitter holding register empty interrupt */
- ;
- } else {
- byte = UART_IER_RDI /* Enable Receiver data interrupt */
- | UART_IER_THRI /* Enable Transmitter holding register empty interrupt */
- ;
- }
- outb(byte, uart->base + UART_IER); /* Interrupt enable Register */
-
- inb(uart->base + UART_LSR); /* Clear any pre-existing overrun indication */
- inb(uart->base + UART_IIR); /* Clear any pre-existing transmit interrupt */
- inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */
-}
-
-static void snd_uart16550_do_close(struct snd_uart16550 * uart)
-{
- if (uart->irq < 0)
- snd_uart16550_del_timer(uart);
-
- /* NOTE: may need to disable interrupts before de-registering out handler.
- * For now, the consequences are harmless.
- */
-
- outb((0 & UART_IER_RDI) /* Disable Receiver data interrupt */
- |(0 & UART_IER_THRI) /* Disable Transmitter holding register empty interrupt */
- ,uart->base + UART_IER); /* Interrupt enable Register */
-
- switch (uart->adaptor) {
- default:
- outb((0 & UART_MCR_RTS) /* Deactivate Request-To-Send line */
- |(0 & UART_MCR_DTR) /* Deactivate Data-Terminal-Ready line */
- |(0 & UART_MCR_OUT2) /* Deactivate OUT2 */
- ,uart->base + UART_MCR); /* Modem Control Register */
- break;
- case SNDRV_SERIAL_MS124W_SA:
- case SNDRV_SERIAL_MS124W_MB:
- /* MS-124W can draw power from RTS and DTR if they
- are in opposite states; leave it powered. */
- outb(UART_MCR_RTS | (0&UART_MCR_DTR) | (0&UART_MCR_OUT2),
- uart->base + UART_MCR);
- break;
- case SNDRV_SERIAL_MS124T:
- /* MS-124T can draw power from RTS and/or DTR (preferably
- both) if they are both asserted; leave it powered. */
- outb(UART_MCR_RTS | UART_MCR_DTR | (0&UART_MCR_OUT2),
- uart->base + UART_MCR);
- break;
- }
-
- inb(uart->base + UART_IIR); /* Clear any outstanding interrupts */
-
- /* Restore old divisor */
- if (uart->divisor != 0) {
- outb(UART_LCR_DLAB /* Divisor latch access bit */
- ,uart->base + UART_LCR); /* Line Control Register */
- outb(uart->old_divisor_lsb
- ,uart->base + UART_DLL); /* Divisor Latch Low */
- outb(uart->old_divisor_msb
- ,uart->base + UART_DLM); /* Divisor Latch High */
- /* Restore old LCR (data bits, stop bits, parity, DLAB) */
- outb(uart->old_line_ctrl_reg
- ,uart->base + UART_LCR); /* Line Control Register */
- }
-}
-
-static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_open(uart);
- uart->filemode |= SERIAL_MODE_INPUT_OPEN;
- uart->midi_input[substream->number] = substream;
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-}
-
-static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- uart->filemode &= ~SERIAL_MODE_INPUT_OPEN;
- uart->midi_input[substream->number] = NULL;
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_close(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-}
-
-static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (up)
- uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED;
- else
- uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&uart->open_lock, flags);
-}
-
-static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_open(uart);
- uart->filemode |= SERIAL_MODE_OUTPUT_OPEN;
- uart->midi_output[substream->number] = substream;
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-};
-
-static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN;
- uart->midi_output[substream->number] = NULL;
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_close(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-};
-
-static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart,
- int Num)
-{
- if (uart->buff_in_count + Num < TX_BUFF_SIZE)
- return 1;
- else
- return 0;
-}
-
-static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart,
- unsigned char byte)
-{
- unsigned short buff_in = uart->buff_in;
- if (uart->buff_in_count < TX_BUFF_SIZE) {
- uart->tx_buff[buff_in] = byte;
- buff_in++;
- buff_in &= TX_BUFF_MASK;
- uart->buff_in = buff_in;
- uart->buff_in_count++;
- if (uart->irq < 0) /* polling mode */
- snd_uart16550_add_timer(uart);
- return 1;
- } else
- return 0;
-}
-
-static int snd_uart16550_output_byte(struct snd_uart16550 *uart,
- struct snd_rawmidi_substream *substream,
- unsigned char midi_byte)
-{
- if (uart->buff_in_count == 0 /* Buffer empty? */
- && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA &&
- uart->adaptor != SNDRV_SERIAL_GENERIC) ||
- (uart->fifo_count == 0 /* FIFO empty? */
- && (inb(uart->base + UART_MSR) & UART_MSR_CTS)))) { /* CTS? */
-
- /* Tx Buffer Empty - try to write immediately */
- if ((inb(uart->base + UART_LSR) & UART_LSR_THRE) != 0) {
- /* Transmitter holding register (and Tx FIFO) empty */
- uart->fifo_count = 1;
- outb(midi_byte, uart->base + UART_TX);
- } else {
- if (uart->fifo_count < uart->fifo_limit) {
- uart->fifo_count++;
- outb(midi_byte, uart->base + UART_TX);
- } else {
- /* Cannot write (buffer empty) -
- * put char in buffer */
- snd_uart16550_write_buffer(uart, midi_byte);
- }
- }
- } else {
- if (!snd_uart16550_write_buffer(uart, midi_byte)) {
- snd_printk(KERN_WARNING
- "%s: Buffer overrun on device at 0x%lx\n",
- uart->rmidi->name, uart->base);
- return 0;
- }
- }
-
- return 1;
-}
-
-static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- unsigned char midi_byte, addr_byte;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
- char first;
- static unsigned long lasttime = 0;
-
- /* Interrupts are disabled during the updating of the tx_buff,
- * since it is 'bad' to have two processes updating the same
- * variables (ie buff_in & buff_out)
- */
-
- spin_lock_irqsave(&uart->open_lock, flags);
-
- if (uart->irq < 0) /* polling */
- snd_uart16550_io_loop(uart);
-
- if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) {
- while (1) {
- /* buffer full? */
- /* in this mode we need two bytes of space */
- if (uart->buff_in_count > TX_BUFF_SIZE - 2)
- break;
- if (snd_rawmidi_transmit(substream, &midi_byte, 1) != 1)
- break;
-#ifdef SNDRV_SERIAL_MS124W_MB_NOCOMBO
- /* select exactly one of the four ports */
- addr_byte = (1 << (substream->number + 4)) | 0x08;
-#else
- /* select any combination of the four ports */
- addr_byte = (substream->number << 4) | 0x08;
- /* ...except none */
- if (addr_byte == 0x08)
- addr_byte = 0xf8;
-#endif
- snd_uart16550_output_byte(uart, substream, addr_byte);
- /* send midi byte */
- snd_uart16550_output_byte(uart, substream, midi_byte);
- }
- } else {
- first = 0;
- while (snd_rawmidi_transmit_peek(substream, &midi_byte, 1) == 1) {
- /* Also send F5 after 3 seconds with no data
- * to handle device disconnect */
- if (first == 0 &&
- (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS ||
- uart->adaptor == SNDRV_SERIAL_GENERIC) &&
- (uart->prev_out != substream->number ||
- time_after(jiffies, lasttime + 3*HZ))) {
-
- if (snd_uart16550_buffer_can_write(uart, 3)) {
- /* Roland Soundcanvas part selection */
- /* If this substream of the data is
- * different previous substream
- * in this uart, send the change part
- * event
- */
- uart->prev_out = substream->number;
- /* change part */
- snd_uart16550_output_byte(uart, substream,
- 0xf5);
- /* data */
- snd_uart16550_output_byte(uart, substream,
- uart->prev_out + 1);
- /* If midi_byte is a data byte,
- * send the previous status byte */
- if (midi_byte < 0x80 &&
- uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)
- snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]);
- } else if (!uart->drop_on_full)
- break;
-
- }
-
- /* send midi byte */
- if (!snd_uart16550_output_byte(uart, substream, midi_byte) &&
- !uart->drop_on_full )
- break;
-
- if (midi_byte >= 0x80 && midi_byte < 0xf0)
- uart->prev_status[uart->prev_out] = midi_byte;
- first = 1;
-
- snd_rawmidi_transmit_ack( substream, 1 );
- }
- lasttime = jiffies;
- }
- spin_unlock_irqrestore(&uart->open_lock, flags);
-}
-
-static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (up)
- uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED;
- else
- uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED;
- spin_unlock_irqrestore(&uart->open_lock, flags);
- if (up)
- snd_uart16550_output_write(substream);
-}
-
-static struct snd_rawmidi_ops snd_uart16550_output =
-{
- .open = snd_uart16550_output_open,
- .close = snd_uart16550_output_close,
- .trigger = snd_uart16550_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_uart16550_input =
-{
- .open = snd_uart16550_input_open,
- .close = snd_uart16550_input_close,
- .trigger = snd_uart16550_input_trigger,
-};
-
-static int snd_uart16550_free(struct snd_uart16550 *uart)
-{
- if (uart->irq >= 0)
- free_irq(uart->irq, uart);
- release_and_free_resource(uart->res_base);
- kfree(uart);
- return 0;
-};
-
-static int snd_uart16550_dev_free(struct snd_device *device)
-{
- struct snd_uart16550 *uart = device->device_data;
- return snd_uart16550_free(uart);
-}
-
-static int __devinit snd_uart16550_create(struct snd_card *card,
- unsigned long iobase,
- int irq,
- unsigned int speed,
- unsigned int base,
- int adaptor,
- int droponfull,
- struct snd_uart16550 **ruart)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_uart16550_dev_free,
- };
- struct snd_uart16550 *uart;
- int err;
-
-
- if ((uart = kzalloc(sizeof(*uart), GFP_KERNEL)) == NULL)
- return -ENOMEM;
- uart->adaptor = adaptor;
- uart->card = card;
- spin_lock_init(&uart->open_lock);
- uart->irq = -1;
- uart->base = iobase;
- uart->drop_on_full = droponfull;
-
- if ((err = snd_uart16550_detect(uart)) <= 0) {
- printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
- snd_uart16550_free(uart);
- return -ENODEV;
- }
-
- if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
- if (request_irq(irq, snd_uart16550_interrupt,
- 0, "Serial MIDI", uart)) {
- snd_printk(KERN_WARNING
- "irq %d busy. Using Polling.\n", irq);
- } else {
- uart->irq = irq;
- }
- }
- uart->divisor = base / speed;
- uart->speed = base / (unsigned int)uart->divisor;
- uart->speed_base = base;
- uart->prev_out = -1;
- uart->prev_in = 0;
- uart->rstatus = 0;
- memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS);
- init_timer(&uart->buffer_timer);
- uart->buffer_timer.function = snd_uart16550_buffer_timer;
- uart->buffer_timer.data = (unsigned long)uart;
- uart->timer_running = 0;
-
- /* Register device */
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops)) < 0) {
- snd_uart16550_free(uart);
- return err;
- }
-
- switch (uart->adaptor) {
- case SNDRV_SERIAL_MS124W_SA:
- case SNDRV_SERIAL_MS124W_MB:
- /* MS-124W can draw power from RTS and DTR if they
- are in opposite states. */
- outb(UART_MCR_RTS | (0&UART_MCR_DTR), uart->base + UART_MCR);
- break;
- case SNDRV_SERIAL_MS124T:
- /* MS-124T can draw power from RTS and/or DTR (preferably
- both) if they are asserted. */
- outb(UART_MCR_RTS | UART_MCR_DTR, uart->base + UART_MCR);
- break;
- default:
- break;
- }
-
- if (ruart)
- *ruart = uart;
-
- return 0;
-}
-
-static void __devinit snd_uart16550_substreams(struct snd_rawmidi_str *stream)
-{
- struct snd_rawmidi_substream *substream;
-
- list_for_each_entry(substream, &stream->substreams, list) {
- sprintf(substream->name, "Serial MIDI %d", substream->number + 1);
- }
-}
-
-static int __devinit snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
- int outs, int ins,
- struct snd_rawmidi **rmidi)
-{
- struct snd_rawmidi *rrawmidi;
- int err;
-
- err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device,
- outs, ins, &rrawmidi);
- if (err < 0)
- return err;
- snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_uart16550_input);
- snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_uart16550_output);
- strcpy(rrawmidi->name, "Serial MIDI");
- snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
- snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
- rrawmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rrawmidi->private_data = uart;
- if (rmidi)
- *rmidi = rrawmidi;
- return 0;
-}
-
-static int __devinit snd_serial_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct snd_uart16550 *uart;
- int err;
- int dev = devptr->id;
-
- switch (adaptor[dev]) {
- case SNDRV_SERIAL_SOUNDCANVAS:
- ins[dev] = 1;
- break;
- case SNDRV_SERIAL_MS124T:
- case SNDRV_SERIAL_MS124W_SA:
- outs[dev] = 1;
- ins[dev] = 1;
- break;
- case SNDRV_SERIAL_MS124W_MB:
- outs[dev] = 16;
- ins[dev] = 1;
- break;
- case SNDRV_SERIAL_GENERIC:
- break;
- default:
- snd_printk(KERN_ERR
- "Adaptor type is out of range 0-%d (%d)\n",
- SNDRV_SERIAL_MAX_ADAPTOR, adaptor[dev]);
- return -ENODEV;
- }
-
- if (outs[dev] < 1 || outs[dev] > SNDRV_SERIAL_MAX_OUTS) {
- snd_printk(KERN_ERR
- "Count of outputs is out of range 1-%d (%d)\n",
- SNDRV_SERIAL_MAX_OUTS, outs[dev]);
- return -ENODEV;
- }
-
- if (ins[dev] < 1 || ins[dev] > SNDRV_SERIAL_MAX_INS) {
- snd_printk(KERN_ERR
- "Count of inputs is out of range 1-%d (%d)\n",
- SNDRV_SERIAL_MAX_INS, ins[dev]);
- return -ENODEV;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "Serial");
- strcpy(card->shortname, "Serial MIDI (UART16550A)");
-
- if ((err = snd_uart16550_create(card,
- port[dev],
- irq[dev],
- speed[dev],
- base[dev],
- adaptor[dev],
- droponfull[dev],
- &uart)) < 0)
- goto _err;
-
- err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
- if (err < 0)
- goto _err;
-
- sprintf(card->longname, "%s [%s] at %#lx, irq %d",
- card->shortname,
- adaptor_names[uart->adaptor],
- uart->base,
- uart->irq);
-
- snd_card_set_dev(card, &devptr->dev);
-
- if ((err = snd_card_register(card)) < 0)
- goto _err;
-
- platform_set_drvdata(devptr, card);
- return 0;
-
- _err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_serial_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_SERIAL_DRIVER "snd_serial_u16550"
-
-static struct platform_driver snd_serial_driver = {
- .probe = snd_serial_probe,
- .remove = __devexit_p( snd_serial_remove),
- .driver = {
- .name = SND_SERIAL_DRIVER
- },
-};
-
-static void snd_serial_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_serial_driver);
-}
-
-static int __init alsa_card_serial_init(void)
-{
- int i, cards, err;
-
- if ((err = platform_driver_register(&snd_serial_driver)) < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_SERIAL_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (! cards) {
-#ifdef MODULE
- printk(KERN_ERR "serial midi soundcard not found or device busy\n");
-#endif
- snd_serial_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_serial_exit(void)
-{
- snd_serial_unregister_all();
-}
-
-module_init(alsa_card_serial_init)
-module_exit(alsa_card_serial_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/virmidi.c b/ANDROID_3.4.5/sound/drivers/virmidi.c
deleted file mode 100644
index 9d97478a..00000000
--- a/ANDROID_3.4.5/sound/drivers/virmidi.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Dummy soundcard for virtual rawmidi devices
- *
- * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>
- *
- * 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
- *
- */
-
-/*
- * VIRTUAL RAW MIDI DEVICE CARDS
- *
- * This dummy card contains up to 4 virtual rawmidi devices.
- * They are not real rawmidi devices but just associated with sequencer
- * clients, so that any input/output sources can be connected as a raw
- * MIDI device arbitrary.
- * Also, multiple access is allowed to a single rawmidi device.
- *
- * Typical usage is like following:
- * - Load snd-virmidi module.
- * # modprobe snd-virmidi index=2
- * Then, sequencer clients 72:0 to 75:0 will be created, which are
- * mapped from /dev/snd/midiC1D0 to /dev/snd/midiC1D3, respectively.
- *
- * - Connect input/output via aconnect.
- * % aconnect 64:0 72:0 # keyboard input redirection 64:0 -> 72:0
- * % aconnect 72:0 65:0 # output device redirection 72:0 -> 65:0
- *
- * - Run application using a midi device (eg. /dev/snd/midiC1D0)
- */
-
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/seq_kernel.h>
-#include <sound/seq_virmidi.h>
-#include <sound/initval.h>
-
-/* hack: OSS defines midi_devs, so undefine it (versioned symbols) */
-#undef midi_devs
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Dummy soundcard for virtual rawmidi devices");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual rawmidi device}}");
-
-#define MAX_MIDI_DEVICES 4
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
-static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for virmidi soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for virmidi soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this soundcard.");
-module_param_array(midi_devs, int, NULL, 0444);
-MODULE_PARM_DESC(midi_devs, "MIDI devices # (1-4)");
-
-struct snd_card_virmidi {
- struct snd_card *card;
- struct snd_rawmidi *midi[MAX_MIDI_DEVICES];
-};
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-
-static int __devinit snd_virmidi_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct snd_card_virmidi *vmidi;
- int idx, err;
- int dev = devptr->id;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_virmidi), &card);
- if (err < 0)
- return err;
- vmidi = card->private_data;
- vmidi->card = card;
-
- if (midi_devs[dev] > MAX_MIDI_DEVICES) {
- snd_printk(KERN_WARNING
- "too much midi devices for virmidi %d: "
- "force to use %d\n", dev, MAX_MIDI_DEVICES);
- midi_devs[dev] = MAX_MIDI_DEVICES;
- }
- for (idx = 0; idx < midi_devs[dev]; idx++) {
- struct snd_rawmidi *rmidi;
- struct snd_virmidi_dev *rdev;
- if ((err = snd_virmidi_new(card, idx, &rmidi)) < 0)
- goto __nodev;
- rdev = rmidi->private_data;
- vmidi->midi[idx] = rmidi;
- strcpy(rmidi->name, "Virtual Raw MIDI");
- rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH;
- }
-
- strcpy(card->driver, "VirMIDI");
- strcpy(card->shortname, "VirMIDI");
- sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
-
- snd_card_set_dev(card, &devptr->dev);
-
- if ((err = snd_card_register(card)) == 0) {
- platform_set_drvdata(devptr, card);
- return 0;
- }
- __nodev:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_virmidi_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_VIRMIDI_DRIVER "snd_virmidi"
-
-static struct platform_driver snd_virmidi_driver = {
- .probe = snd_virmidi_probe,
- .remove = __devexit_p(snd_virmidi_remove),
- .driver = {
- .name = SND_VIRMIDI_DRIVER
- },
-};
-
-static void snd_virmidi_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_virmidi_driver);
-}
-
-static int __init alsa_card_virmidi_init(void)
-{
- int i, cards, err;
-
- if ((err = platform_driver_register(&snd_virmidi_driver)) < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_VIRMIDI_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "Card-VirMIDI soundcard not found or device busy\n");
-#endif
- snd_virmidi_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_virmidi_exit(void)
-{
- snd_virmidi_unregister_all();
-}
-
-module_init(alsa_card_virmidi_init)
-module_exit(alsa_card_virmidi_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/vx/Makefile b/ANDROID_3.4.5/sound/drivers/vx/Makefile
deleted file mode 100644
index 9a168a3c..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-vx-lib-objs := vx_core.o vx_hwdep.o vx_pcm.o vx_mixer.o vx_cmd.o vx_uer.o
-
-obj-$(CONFIG_SND_VX_LIB) += snd-vx-lib.o
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c b/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c
deleted file mode 100644
index 23f4857f..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * DSP commands
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * 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/core.h>
-#include <sound/pcm.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-/*
- * Array of DSP commands
- */
-static struct vx_cmd_info vx_dsp_cmds[] = {
-[CMD_VERSION] = { 0x010000, 2, RMH_SSIZE_FIXED, 1 },
-[CMD_SUPPORTED] = { 0x020000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_TEST_IT] = { 0x040000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_SEND_IRQA] = { 0x070001, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_IBL] = { 0x080000, 1, RMH_SSIZE_FIXED, 4 },
-[CMD_ASYNC] = { 0x0A0000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_RES_PIPE] = { 0x400000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_FREE_PIPE] = { 0x410000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_CONF_PIPE] = { 0x42A101, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_ABORT_CONF_PIPE] = { 0x42A100, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_PARAM_OUTPUT_PIPE] = { 0x43A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_STOP_PIPE] = { 0x470004, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_PIPE_STATE] = { 0x480000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_PIPE_SPL_COUNT] = { 0x49A000, 2, RMH_SSIZE_FIXED, 2 },
-[CMD_CAN_START_PIPE] = { 0x4b0000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_SIZE_HBUFFER] = { 0x4C0000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_START_STREAM] = { 0x80A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_START_ONE_STREAM] = { 0x800000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_PAUSE_STREAM] = { 0x81A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_PAUSE_ONE_STREAM] = { 0x810000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM_OUT_LEVEL_ADJUST] = { 0x828000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_STOP_STREAM] = { 0x830000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_FORMAT_STREAM_OUT] = { 0x868000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_FORMAT_STREAM_IN] = { 0x878800, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_STREAM_STATE] = { 0x890001, 2, RMH_SSIZE_FIXED, 1 },
-[CMD_DROP_BYTES_AWAY] = { 0x8A8000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_REMAINING_BYTES] = { 0x8D0800, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_CONNECT_AUDIO] = { 0xC10000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_AUDIO_LEVEL_ADJUST] = { 0xC2A000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_AUDIO_VU_PIC_METER] = { 0xC3A003, 2, RMH_SSIZE_FIXED, 1 },
-[CMD_GET_AUDIO_LEVELS] = { 0xC4A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_NOTIFY_EVENT] = { 0x4D0000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_INFO_NOTIFIED] = { 0x0B0000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_ACCESS_IO_FCT] = { 0x098000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_STATUS_R_BUFFERS] = { 0x440000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_UPDATE_R_BUFFERS] = { 0x848000, 4, RMH_SSIZE_FIXED, 0 },
-[CMD_LOAD_EFFECT_CONTEXT] = { 0x0c8000, 3, RMH_SSIZE_FIXED, 1 },
-[CMD_EFFECT_ONE_PIPE] = { 0x458000, 0, RMH_SSIZE_FIXED, 0 },
-[CMD_MODIFY_CLOCK] = { 0x0d0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM1_OUT_SET_N_LEVELS] ={ 0x858000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_PURGE_STREAM_DCMDS] = { 0x8b8000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_NOTIFY_PIPE_TIME] = { 0x4e0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_LOAD_EFFECT_CONTEXT_PACKET] = { 0x0c8000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_RELIC_R_BUFFER] = { 0x8e0800, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_RESYNC_AUDIO_INPUTS] = { 0x0e0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_NOTIFY_STREAM_TIME] = { 0x8f0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM_SAMPLE_COUNT] = { 0x900000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_CONFIG_TIME_CODE] = { 0x050000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_TIME_CODE] = { 0x060000, 1, RMH_SSIZE_FIXED, 5 },
-[CMD_MANAGE_SIGNAL] = { 0x0f0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_PARAMETER_STREAM_OUT] = { 0x91A000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_READ_BOARD_FREQ] = { 0x030000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_GET_STREAM_LEVELS] = { 0x8c0000, 1, RMH_SSIZE_FIXED, 3 },
-[CMD_PURGE_PIPE_DCMDS] = { 0x4f8000, 3, RMH_SSIZE_FIXED, 0 },
-// [CMD_SET_STREAM_OUT_EFFECTS] = { 0x888000, 34, RMH_SSIZE_FIXED, 0 },
-// [CMD_GET_STREAM_OUT_EFFECTS] = { 0x928000, 2, RMH_SSIZE_FIXED, 32 },
-[CMD_CONNECT_MONITORING] = { 0xC00000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM2_OUT_SET_N_LEVELS] = { 0x938000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_CANCEL_R_BUFFERS] = { 0x948000, 4, RMH_SSIZE_FIXED, 0 },
-[CMD_NOTIFY_END_OF_BUFFER] = { 0x950000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_STREAM_VU_METER] = { 0x95A000, 2, RMH_SSIZE_ARG, 0 },
-};
-
-/**
- * vx_init_rmh - initialize the RMH instance
- * @rmh: the rmh pointer to be initialized
- * @cmd: the rmh command to be set
- */
-void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd)
-{
- if (snd_BUG_ON(cmd >= CMD_LAST_INDEX))
- return;
- rmh->LgCmd = vx_dsp_cmds[cmd].length;
- rmh->LgStat = vx_dsp_cmds[cmd].st_length;
- rmh->DspStat = vx_dsp_cmds[cmd].st_type;
- rmh->Cmd[0] = vx_dsp_cmds[cmd].opcode;
-}
-
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h b/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h
deleted file mode 100644
index a85248ba..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * Definitions of DSP commands
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * 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
- */
-
-#ifndef __VX_CMD_H
-#define __VX_CMD_H
-
-enum {
- CMD_VERSION,
- CMD_SUPPORTED,
- CMD_TEST_IT,
- CMD_SEND_IRQA,
- CMD_IBL,
- CMD_ASYNC,
- CMD_RES_PIPE,
- CMD_FREE_PIPE,
- CMD_CONF_PIPE,
- CMD_ABORT_CONF_PIPE,
- CMD_PARAM_OUTPUT_PIPE,
- CMD_STOP_PIPE,
- CMD_PIPE_STATE,
- CMD_PIPE_SPL_COUNT,
- CMD_CAN_START_PIPE,
- CMD_SIZE_HBUFFER,
- CMD_START_STREAM,
- CMD_START_ONE_STREAM,
- CMD_PAUSE_STREAM,
- CMD_PAUSE_ONE_STREAM,
- CMD_STREAM_OUT_LEVEL_ADJUST,
- CMD_STOP_STREAM,
- CMD_FORMAT_STREAM_OUT,
- CMD_FORMAT_STREAM_IN,
- CMD_GET_STREAM_STATE,
- CMD_DROP_BYTES_AWAY,
- CMD_GET_REMAINING_BYTES,
- CMD_CONNECT_AUDIO,
- CMD_AUDIO_LEVEL_ADJUST,
- CMD_AUDIO_VU_PIC_METER,
- CMD_GET_AUDIO_LEVELS,
- CMD_GET_NOTIFY_EVENT,
- CMD_INFO_NOTIFIED,
- CMD_ACCESS_IO_FCT,
- CMD_STATUS_R_BUFFERS,
- CMD_UPDATE_R_BUFFERS,
- CMD_LOAD_EFFECT_CONTEXT,
- CMD_EFFECT_ONE_PIPE,
- CMD_MODIFY_CLOCK,
- CMD_STREAM1_OUT_SET_N_LEVELS,
- CMD_PURGE_STREAM_DCMDS,
- CMD_NOTIFY_PIPE_TIME,
- CMD_LOAD_EFFECT_CONTEXT_PACKET,
- CMD_RELIC_R_BUFFER,
- CMD_RESYNC_AUDIO_INPUTS,
- CMD_NOTIFY_STREAM_TIME,
- CMD_STREAM_SAMPLE_COUNT,
- CMD_CONFIG_TIME_CODE,
- CMD_GET_TIME_CODE,
- CMD_MANAGE_SIGNAL,
- CMD_PARAMETER_STREAM_OUT,
- CMD_READ_BOARD_FREQ,
- CMD_GET_STREAM_LEVELS,
- CMD_PURGE_PIPE_DCMDS,
- // CMD_SET_STREAM_OUT_EFFECTS,
- // CMD_GET_STREAM_OUT_EFFECTS,
- CMD_CONNECT_MONITORING,
- CMD_STREAM2_OUT_SET_N_LEVELS,
- CMD_CANCEL_R_BUFFERS,
- CMD_NOTIFY_END_OF_BUFFER,
- CMD_GET_STREAM_VU_METER,
- CMD_LAST_INDEX
-};
-
-struct vx_cmd_info {
- unsigned int opcode; /* command word */
- int length; /* command length (in words) */
- int st_type; /* status type (RMH_SSIZE_XXX) */
- int st_length; /* fixed length */
-};
-
-/* Family and code op of some DSP requests. */
-#define CODE_OP_PIPE_TIME 0x004e0000
-#define CODE_OP_START_STREAM 0x00800000
-#define CODE_OP_PAUSE_STREAM 0x00810000
-#define CODE_OP_OUT_STREAM_LEVEL 0x00820000
-#define CODE_OP_UPDATE_R_BUFFERS 0x00840000
-#define CODE_OP_OUT_STREAM1_LEVEL_CURVE 0x00850000
-#define CODE_OP_OUT_STREAM2_LEVEL_CURVE 0x00930000
-#define CODE_OP_OUT_STREAM_FORMAT 0x00860000
-#define CODE_OP_STREAM_TIME 0x008f0000
-#define CODE_OP_OUT_STREAM_EXTRAPARAMETER 0x00910000
-#define CODE_OP_OUT_AUDIO_LEVEL 0x00c20000
-
-#define NOTIFY_LAST_COMMAND 0x00400000
-
-/* Values for a user delay */
-#define DC_DIFFERED_DELAY (1<<BIT_DIFFERED_COMMAND)
-#define DC_NOTIFY_DELAY (1<<BIT_NOTIFIED_COMMAND)
-#define DC_HBUFFER_DELAY (1<<BIT_TIME_RELATIVE_TO_BUFFER)
-#define DC_MULTIPLE_DELAY (1<<BIT_RESERVED)
-#define DC_STREAM_TIME_DELAY (1<<BIT_STREAM_TIME)
-#define DC_CANCELLED_DELAY (1<<BIT_CANCELLED_COMMAND)
-
-/* Values for tiDelayed field in TIME_INFO structure,
- * and for pbPause field in PLAY_BUFFER_INFO structure
- */
-#define BIT_DIFFERED_COMMAND 0
-#define BIT_NOTIFIED_COMMAND 1
-#define BIT_TIME_RELATIVE_TO_BUFFER 2
-#define BIT_RESERVED 3
-#define BIT_STREAM_TIME 4
-#define BIT_CANCELLED_COMMAND 5
-
-/* Access to the "Size" field of the response of the CMD_GET_NOTIFY_EVENT request. */
-#define GET_NOTIFY_EVENT_SIZE_FIELD_MASK 0x000000ff
-
-/* DSP commands general masks */
-#define OPCODE_MASK 0x00ff0000
-#define DSP_DIFFERED_COMMAND_MASK 0x0000C000
-
-/* Notifications (NOTIFY_INFO) */
-#define ALL_CMDS_NOTIFIED 0x0000 // reserved
-#define START_STREAM_NOTIFIED 0x0001
-#define PAUSE_STREAM_NOTIFIED 0x0002
-#define OUT_STREAM_LEVEL_NOTIFIED 0x0003
-#define OUT_STREAM_PARAMETER_NOTIFIED 0x0004 // left for backward compatibility
-#define OUT_STREAM_FORMAT_NOTIFIED 0x0004
-#define PIPE_TIME_NOTIFIED 0x0005
-#define OUT_AUDIO_LEVEL_NOTIFIED 0x0006
-#define OUT_STREAM_LEVEL_CURVE_NOTIFIED 0x0007
-#define STREAM_TIME_NOTIFIED 0x0008
-#define OUT_STREAM_EXTRAPARAMETER_NOTIFIED 0x0009
-#define UNKNOWN_COMMAND_NOTIFIED 0xffff
-
-/* Output pipe parameters setting */
-#define MASK_VALID_PIPE_MPEG_PARAM 0x000040
-#define MASK_VALID_PIPE_BACKWARD_PARAM 0x000020
-#define MASK_SET_PIPE_MPEG_PARAM 0x000002
-#define MASK_SET_PIPE_BACKWARD_PARAM 0x000001
-
-#define MASK_DSP_WORD 0x00FFFFFF
-#define MASK_ALL_STREAM 0x00FFFFFF
-#define MASK_DSP_WORD_LEVEL 0x000001FF
-#define MASK_FIRST_FIELD 0x0000001F
-#define FIELD_SIZE 5
-
-#define COMMAND_RECORD_MASK 0x000800
-
-/* PipeManagement definition bits (PIPE_DECL_INFO) */
-#define P_UNDERRUN_SKIP_SOUND_MASK 0x01
-#define P_PREPARE_FOR_MPEG3_MASK 0x02
-#define P_DO_NOT_RESET_ANALOG_LEVELS 0x04
-#define P_ALLOW_UNDER_ALLOCATION_MASK 0x08
-#define P_DATA_MODE_MASK 0x10
-#define P_ASIO_BUFFER_MANAGEMENT_MASK 0x20
-
-#define BIT_SKIP_SOUND 0x08 // bit 3
-#define BIT_DATA_MODE 0x10 // bit 4
-
-/* Bits in the CMD_MODIFY_CLOCK request. */
-#define CMD_MODIFY_CLOCK_FD_BIT 0x00000001
-#define CMD_MODIFY_CLOCK_T_BIT 0x00000002
-#define CMD_MODIFY_CLOCK_S_BIT 0x00000004
-
-/* Access to the results of the CMD_GET_TIME_CODE RMH. */
-#define TIME_CODE_V_MASK 0x00800000
-#define TIME_CODE_N_MASK 0x00400000
-#define TIME_CODE_B_MASK 0x00200000
-#define TIME_CODE_W_MASK 0x00100000
-
-/* Values for the CMD_MANAGE_SIGNAL RMH. */
-#define MANAGE_SIGNAL_TIME_CODE 0x01
-#define MANAGE_SIGNAL_MIDI 0x02
-
-/* Values for the CMD_CONFIG_TIME_CODE RMH. */
-#define CONFIG_TIME_CODE_CANCEL 0x00001000
-
-/* Mask to get only the effective time from the
- * high word out of the 2 returned by the DSP
- */
-#define PCX_TIME_HI_MASK 0x000fffff
-
-/* Values for setting a H-Buffer time */
-#define HBUFFER_TIME_HIGH 0x00200000
-#define HBUFFER_TIME_LOW 0x00000000
-
-#define NOTIFY_MASK_TIME_HIGH 0x00400000
-#define MULTIPLE_MASK_TIME_HIGH 0x00100000
-#define STREAM_MASK_TIME_HIGH 0x00800000
-
-
-/*
- *
- */
-void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd);
-
-/**
- * vx_send_pipe_cmd_params - fill first command word for pipe commands
- * @rmh: the rmh to be modified
- * @is_capture: 0 = playback, 1 = capture operation
- * @param1: first pipe-parameter
- * @param2: second pipe-parameter
- */
-static inline void vx_set_pipe_cmd_params(struct vx_rmh *rmh, int is_capture,
- int param1, int param2)
-{
- if (is_capture)
- rmh->Cmd[0] |= COMMAND_RECORD_MASK;
- rmh->Cmd[0] |= (((u32)param1 & MASK_FIRST_FIELD) << FIELD_SIZE) & MASK_DSP_WORD;
-
- if (param2)
- rmh->Cmd[0] |= ((u32)param2 & MASK_FIRST_FIELD) & MASK_DSP_WORD;
-
-}
-
-/**
- * vx_set_stream_cmd_params - fill first command word for stream commands
- * @rmh: the rmh to be modified
- * @is_capture: 0 = playback, 1 = capture operation
- * @pipe: the pipe index (zero-based)
- */
-static inline void vx_set_stream_cmd_params(struct vx_rmh *rmh, int is_capture, int pipe)
-{
- if (is_capture)
- rmh->Cmd[0] |= COMMAND_RECORD_MASK;
- rmh->Cmd[0] |= (((u32)pipe & MASK_FIRST_FIELD) << FIELD_SIZE) & MASK_DSP_WORD;
-}
-
-#endif /* __VX_CMD_H */
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_core.c b/ANDROID_3.4.5/sound/drivers/vx/vx_core.c
deleted file mode 100644
index b8e51599..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_core.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * Hardware core part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * 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 <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/asoundef.h>
-#include <sound/info.h>
-#include <asm/io.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Common routines for Digigram VX drivers");
-MODULE_LICENSE("GPL");
-
-
-/*
- * vx_check_reg_bit - wait for the specified bit is set/reset on a register
- * @reg: register to check
- * @mask: bit mask
- * @bit: resultant bit to be checked
- * @time: time-out of loop in msec
- *
- * returns zero if a bit matches, or a negative error code.
- */
-int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time)
-{
- unsigned long end_time = jiffies + (time * HZ + 999) / 1000;
-#ifdef CONFIG_SND_DEBUG
- static char *reg_names[VX_REG_MAX] = {
- "ICR", "CVR", "ISR", "IVR", "RXH", "RXM", "RXL",
- "DMA", "CDSP", "RFREQ", "RUER/V2", "DATA", "MEMIRQ",
- "ACQ", "BIT0", "BIT1", "MIC0", "MIC1", "MIC2",
- "MIC3", "INTCSR", "CNTRL", "GPIOC",
- "LOFREQ", "HIFREQ", "CSUER", "RUER"
- };
-#endif
- do {
- if ((snd_vx_inb(chip, reg) & mask) == bit)
- return 0;
- //msleep(10);
- } while (time_after_eq(end_time, jiffies));
- snd_printd(KERN_DEBUG "vx_check_reg_bit: timeout, reg=%s, mask=0x%x, val=0x%x\n", reg_names[reg], mask, snd_vx_inb(chip, reg));
- return -EIO;
-}
-
-EXPORT_SYMBOL(snd_vx_check_reg_bit);
-
-/*
- * vx_send_irq_dsp - set command irq bit
- * @num: the requested IRQ type, IRQ_XXX
- *
- * this triggers the specified IRQ request
- * returns 0 if successful, or a negative error code.
- *
- */
-static int vx_send_irq_dsp(struct vx_core *chip, int num)
-{
- int nirq;
-
- /* wait for Hc = 0 */
- if (snd_vx_check_reg_bit(chip, VX_CVR, CVR_HC, 0, 200) < 0)
- return -EIO;
-
- nirq = num;
- if (vx_has_new_dsp(chip))
- nirq += VXP_IRQ_OFFSET;
- vx_outb(chip, CVR, (nirq >> 1) | CVR_HC);
- return 0;
-}
-
-
-/*
- * vx_reset_chk - reset CHK bit on ISR
- *
- * returns 0 if successful, or a negative error code.
- */
-static int vx_reset_chk(struct vx_core *chip)
-{
- /* Reset irq CHK */
- if (vx_send_irq_dsp(chip, IRQ_RESET_CHK) < 0)
- return -EIO;
- /* Wait until CHK = 0 */
- if (vx_check_isr(chip, ISR_CHK, 0, 200) < 0)
- return -EIO;
- return 0;
-}
-
-/*
- * vx_transfer_end - terminate message transfer
- * @cmd: IRQ message to send (IRQ_MESS_XXX_END)
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- * NB: call with spinlock held!
- */
-static int vx_transfer_end(struct vx_core *chip, int cmd)
-{
- int err;
-
- if ((err = vx_reset_chk(chip)) < 0)
- return err;
-
- /* irq MESS_READ/WRITE_END */
- if ((err = vx_send_irq_dsp(chip, cmd)) < 0)
- return err;
-
- /* Wait CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
-
- /* If error, Read RX */
- if ((err = vx_inb(chip, ISR)) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0) {
- snd_printd(KERN_DEBUG "transfer_end: error in rx_full\n");
- return err;
- }
- err = vx_inb(chip, RXH) << 16;
- err |= vx_inb(chip, RXM) << 8;
- err |= vx_inb(chip, RXL);
- snd_printd(KERN_DEBUG "transfer_end: error = 0x%x\n", err);
- return -(VX_ERR_MASK | err);
- }
- return 0;
-}
-
-/*
- * vx_read_status - return the status rmh
- * @rmh: rmh record to store the status
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- * NB: call with spinlock held!
- */
-static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
-{
- int i, err, val, size;
-
- /* no read necessary? */
- if (rmh->DspStat == RMH_SSIZE_FIXED && rmh->LgStat == 0)
- return 0;
-
- /* Wait for RX full (with timeout protection)
- * The first word of status is in RX
- */
- err = vx_wait_for_rx_full(chip);
- if (err < 0)
- return err;
-
- /* Read RX */
- val = vx_inb(chip, RXH) << 16;
- val |= vx_inb(chip, RXM) << 8;
- val |= vx_inb(chip, RXL);
-
- /* If status given by DSP, let's decode its size */
- switch (rmh->DspStat) {
- case RMH_SSIZE_ARG:
- size = val & 0xff;
- rmh->Stat[0] = val & 0xffff00;
- rmh->LgStat = size + 1;
- break;
- case RMH_SSIZE_MASK:
- /* Let's count the arg numbers from a mask */
- rmh->Stat[0] = val;
- size = 0;
- while (val) {
- if (val & 0x01)
- size++;
- val >>= 1;
- }
- rmh->LgStat = size + 1;
- break;
- default:
- /* else retrieve the status length given by the driver */
- size = rmh->LgStat;
- rmh->Stat[0] = val; /* Val is the status 1st word */
- size--; /* hence adjust remaining length */
- break;
- }
-
- if (size < 1)
- return 0;
- if (snd_BUG_ON(size > SIZE_MAX_STATUS))
- return -EINVAL;
-
- for (i = 1; i <= size; i++) {
- /* trigger an irq MESS_WRITE_NEXT */
- err = vx_send_irq_dsp(chip, IRQ_MESS_WRITE_NEXT);
- if (err < 0)
- return err;
- /* Wait for RX full (with timeout protection) */
- err = vx_wait_for_rx_full(chip);
- if (err < 0)
- return err;
- rmh->Stat[i] = vx_inb(chip, RXH) << 16;
- rmh->Stat[i] |= vx_inb(chip, RXM) << 8;
- rmh->Stat[i] |= vx_inb(chip, RXL);
- }
-
- return vx_transfer_end(chip, IRQ_MESS_WRITE_END);
-}
-
-
-#define MASK_MORE_THAN_1_WORD_COMMAND 0x00008000
-#define MASK_1_WORD_COMMAND 0x00ff7fff
-
-/*
- * vx_send_msg_nolock - send a DSP message and read back the status
- * @rmh: the rmh record to send and receive
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- *
- * this function doesn't call spinlock at all.
- */
-int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
-{
- int i, err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- if ((err = vx_reset_chk(chip)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: vx_reset_chk error\n");
- return err;
- }
-
-#if 0
- printk(KERN_DEBUG "rmh: cmd = 0x%06x, length = %d, stype = %d\n",
- rmh->Cmd[0], rmh->LgCmd, rmh->DspStat);
- if (rmh->LgCmd > 1) {
- printk(KERN_DEBUG " ");
- for (i = 1; i < rmh->LgCmd; i++)
- printk("0x%06x ", rmh->Cmd[i]);
- printk("\n");
- }
-#endif
- /* Check bit M is set according to length of the command */
- if (rmh->LgCmd > 1)
- rmh->Cmd[0] |= MASK_MORE_THAN_1_WORD_COMMAND;
- else
- rmh->Cmd[0] &= MASK_1_WORD_COMMAND;
-
- /* Wait for TX empty */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: wait tx empty error\n");
- return err;
- }
-
- /* Write Cmd[0] */
- vx_outb(chip, TXH, (rmh->Cmd[0] >> 16) & 0xff);
- vx_outb(chip, TXM, (rmh->Cmd[0] >> 8) & 0xff);
- vx_outb(chip, TXL, rmh->Cmd[0] & 0xff);
-
- /* Trigger irq MESSAGE */
- if ((err = vx_send_irq_dsp(chip, IRQ_MESSAGE)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: send IRQ_MESSAGE error\n");
- return err;
- }
-
- /* Wait for CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
-
- /* If error, get error value from RX */
- if (vx_inb(chip, ISR) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: rx_full read error\n");
- return err;
- }
- err = vx_inb(chip, RXH) << 16;
- err |= vx_inb(chip, RXM) << 8;
- err |= vx_inb(chip, RXL);
- snd_printd(KERN_DEBUG "msg got error = 0x%x at cmd[0]\n", err);
- err = -(VX_ERR_MASK | err);
- return err;
- }
-
- /* Send the other words */
- if (rmh->LgCmd > 1) {
- for (i = 1; i < rmh->LgCmd; i++) {
- /* Wait for TX ready */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: tx_ready error\n");
- return err;
- }
-
- /* Write Cmd[i] */
- vx_outb(chip, TXH, (rmh->Cmd[i] >> 16) & 0xff);
- vx_outb(chip, TXM, (rmh->Cmd[i] >> 8) & 0xff);
- vx_outb(chip, TXL, rmh->Cmd[i] & 0xff);
-
- /* Trigger irq MESS_READ_NEXT */
- if ((err = vx_send_irq_dsp(chip, IRQ_MESS_READ_NEXT)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: IRQ_READ_NEXT error\n");
- return err;
- }
- }
- /* Wait for TX empty */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: TX_READY error\n");
- return err;
- }
- /* End of transfer */
- err = vx_transfer_end(chip, IRQ_MESS_READ_END);
- if (err < 0)
- return err;
- }
-
- return vx_read_status(chip, rmh);
-}
-
-
-/*
- * vx_send_msg - send a DSP message with spinlock
- * @rmh: the rmh record to send and receive
- *
- * returns 0 if successful, or a negative error code.
- * see vx_send_msg_nolock().
- */
-int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&chip->lock, flags);
- err = vx_send_msg_nolock(chip, rmh);
- spin_unlock_irqrestore(&chip->lock, flags);
- return err;
-}
-
-
-/*
- * vx_send_rih_nolock - send an RIH to xilinx
- * @cmd: the command to send
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- *
- * this function doesn't call spinlock at all.
- *
- * unlike RMH, no command is sent to DSP.
- */
-int vx_send_rih_nolock(struct vx_core *chip, int cmd)
-{
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
-#if 0
- printk(KERN_DEBUG "send_rih: cmd = 0x%x\n", cmd);
-#endif
- if ((err = vx_reset_chk(chip)) < 0)
- return err;
- /* send the IRQ */
- if ((err = vx_send_irq_dsp(chip, cmd)) < 0)
- return err;
- /* Wait CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
- /* If error, read RX */
- if (vx_inb(chip, ISR) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0)
- return err;
- err = vx_inb(chip, RXH) << 16;
- err |= vx_inb(chip, RXM) << 8;
- err |= vx_inb(chip, RXL);
- return -(VX_ERR_MASK | err);
- }
- return 0;
-}
-
-
-/*
- * vx_send_rih - send an RIH with spinlock
- * @cmd: the command to send
- *
- * see vx_send_rih_nolock().
- */
-int vx_send_rih(struct vx_core *chip, int cmd)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&chip->lock, flags);
- err = vx_send_rih_nolock(chip, cmd);
- spin_unlock_irqrestore(&chip->lock, flags);
- return err;
-}
-
-#define END_OF_RESET_WAIT_TIME 500 /* us */
-
-/**
- * snd_vx_boot_xilinx - boot up the xilinx interface
- * @boot: the boot record to load
- */
-int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
-{
- unsigned int i;
- int no_fillup = vx_has_new_dsp(chip);
-
- /* check the length of boot image */
- if (boot->size <= 0)
- return -EINVAL;
- if (boot->size % 3)
- return -EINVAL;
-#if 0
- {
- /* more strict check */
- unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2];
- if (boot->size != (c + 2) * 3)
- return -EINVAL;
- }
-#endif
-
- /* reset dsp */
- vx_reset_dsp(chip);
-
- udelay(END_OF_RESET_WAIT_TIME); /* another wait? */
-
- /* download boot strap */
- for (i = 0; i < 0x600; i += 3) {
- if (i >= boot->size) {
- if (no_fillup)
- break;
- if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
- snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
- return -EIO;
- }
- vx_outb(chip, TXH, 0);
- vx_outb(chip, TXM, 0);
- vx_outb(chip, TXL, 0);
- } else {
- const unsigned char *image = boot->data + i;
- if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
- snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
- return -EIO;
- }
- vx_outb(chip, TXH, image[0]);
- vx_outb(chip, TXM, image[1]);
- vx_outb(chip, TXL, image[2]);
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_load_boot_image);
-
-/*
- * vx_test_irq_src - query the source of interrupts
- *
- * called from irq handler only
- */
-static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret)
-{
- int err;
-
- vx_init_rmh(&chip->irq_rmh, CMD_TEST_IT);
- spin_lock(&chip->lock);
- err = vx_send_msg_nolock(chip, &chip->irq_rmh);
- if (err < 0)
- *ret = 0;
- else
- *ret = chip->irq_rmh.Stat[0];
- spin_unlock(&chip->lock);
- return err;
-}
-
-
-/*
- * vx_interrupt - soft irq handler
- */
-static void vx_interrupt(unsigned long private_data)
-{
- struct vx_core *chip = (struct vx_core *) private_data;
- unsigned int events;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- if (vx_test_irq_src(chip, &events) < 0)
- return;
-
-#if 0
- if (events & 0x000800)
- printk(KERN_ERR "DSP Stream underrun ! IRQ events = 0x%x\n", events);
-#endif
- // printk(KERN_DEBUG "IRQ events = 0x%x\n", events);
-
- /* We must prevent any application using this DSP
- * and block any further request until the application
- * either unregisters or reloads the DSP
- */
- if (events & FATAL_DSP_ERROR) {
- snd_printk(KERN_ERR "vx_core: fatal DSP error!!\n");
- return;
- }
-
- /* The start on time code conditions are filled (ie the time code
- * received by the board is equal to one of those given to it).
- */
- if (events & TIME_CODE_EVENT_PENDING)
- ; /* so far, nothing to do yet */
-
- /* The frequency has changed on the board (UER mode). */
- if (events & FREQUENCY_CHANGE_EVENT_PENDING)
- vx_change_frequency(chip);
-
- /* update the pcm streams */
- vx_pcm_update_intr(chip, events);
-}
-
-
-/**
- * snd_vx_irq_handler - interrupt handler
- */
-irqreturn_t snd_vx_irq_handler(int irq, void *dev)
-{
- struct vx_core *chip = dev;
-
- if (! (chip->chip_status & VX_STAT_CHIP_INIT) ||
- (chip->chip_status & VX_STAT_IS_STALE))
- return IRQ_NONE;
- if (! vx_test_and_ack(chip))
- tasklet_schedule(&chip->tq);
- return IRQ_HANDLED;
-}
-
-EXPORT_SYMBOL(snd_vx_irq_handler);
-
-/*
- */
-static void vx_reset_board(struct vx_core *chip, int cold_reset)
-{
- if (snd_BUG_ON(!chip->ops->reset_board))
- return;
-
- /* current source, later sync'ed with target */
- chip->audio_source = VX_AUDIO_SRC_LINE;
- if (cold_reset) {
- chip->audio_source_target = chip->audio_source;
- chip->clock_source = INTERNAL_QUARTZ;
- chip->clock_mode = VX_CLOCK_MODE_AUTO;
- chip->freq = 48000;
- chip->uer_detected = VX_UER_MODE_NOT_PRESENT;
- chip->uer_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
- }
-
- chip->ops->reset_board(chip, cold_reset);
-
- vx_reset_codec(chip, cold_reset);
-
- vx_set_internal_clock(chip, chip->freq);
-
- /* Reset the DSP */
- vx_reset_dsp(chip);
-
- if (vx_is_pcmcia(chip)) {
- /* Acknowledge any pending IRQ and reset the MEMIRQ flag. */
- vx_test_and_ack(chip);
- vx_validate_irq(chip, 1);
- }
-
- /* init CBits */
- vx_set_iec958_status(chip, chip->uer_bits);
-}
-
-
-/*
- * proc interface
- */
-
-static void vx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct vx_core *chip = entry->private_data;
- static char *audio_src_vxp[] = { "Line", "Mic", "Digital" };
- static char *audio_src_vx2[] = { "Analog", "Analog", "Digital" };
- static char *clock_mode[] = { "Auto", "Internal", "External" };
- static char *clock_src[] = { "Internal", "External" };
- static char *uer_type[] = { "Consumer", "Professional", "Not Present" };
-
- snd_iprintf(buffer, "%s\n", chip->card->longname);
- snd_iprintf(buffer, "Xilinx Firmware: %s\n",
- chip->chip_status & VX_STAT_XILINX_LOADED ? "Loaded" : "No");
- snd_iprintf(buffer, "Device Initialized: %s\n",
- chip->chip_status & VX_STAT_DEVICE_INIT ? "Yes" : "No");
- snd_iprintf(buffer, "DSP audio info:");
- if (chip->audio_info & VX_AUDIO_INFO_REAL_TIME)
- snd_iprintf(buffer, " realtime");
- if (chip->audio_info & VX_AUDIO_INFO_OFFLINE)
- snd_iprintf(buffer, " offline");
- if (chip->audio_info & VX_AUDIO_INFO_MPEG1)
- snd_iprintf(buffer, " mpeg1");
- if (chip->audio_info & VX_AUDIO_INFO_MPEG2)
- snd_iprintf(buffer, " mpeg2");
- if (chip->audio_info & VX_AUDIO_INFO_LINEAR_8)
- snd_iprintf(buffer, " linear8");
- if (chip->audio_info & VX_AUDIO_INFO_LINEAR_16)
- snd_iprintf(buffer, " linear16");
- if (chip->audio_info & VX_AUDIO_INFO_LINEAR_24)
- snd_iprintf(buffer, " linear24");
- snd_iprintf(buffer, "\n");
- snd_iprintf(buffer, "Input Source: %s\n", vx_is_pcmcia(chip) ?
- audio_src_vxp[chip->audio_source] :
- audio_src_vx2[chip->audio_source]);
- snd_iprintf(buffer, "Clock Mode: %s\n", clock_mode[chip->clock_mode]);
- snd_iprintf(buffer, "Clock Source: %s\n", clock_src[chip->clock_source]);
- snd_iprintf(buffer, "Frequency: %d\n", chip->freq);
- snd_iprintf(buffer, "Detected Frequency: %d\n", chip->freq_detected);
- snd_iprintf(buffer, "Detected UER type: %s\n", uer_type[chip->uer_detected]);
- snd_iprintf(buffer, "Min/Max/Cur IBL: %d/%d/%d (granularity=%d)\n",
- chip->ibl.min_size, chip->ibl.max_size, chip->ibl.size,
- chip->ibl.granularity);
-}
-
-static void vx_proc_init(struct vx_core *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "vx-status", &entry))
- snd_info_set_text_ops(entry, chip, vx_proc_read);
-}
-
-
-/**
- * snd_vx_dsp_boot - load the DSP boot
- */
-int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot)
-{
- int err;
- int cold_reset = !(chip->chip_status & VX_STAT_DEVICE_INIT);
-
- vx_reset_board(chip, cold_reset);
- vx_validate_irq(chip, 0);
-
- if ((err = snd_vx_load_boot_image(chip, boot)) < 0)
- return err;
- msleep(10);
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_dsp_boot);
-
-/**
- * snd_vx_dsp_load - load the DSP image
- */
-int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
-{
- unsigned int i;
- int err;
- unsigned int csum = 0;
- const unsigned char *image, *cptr;
-
- if (dsp->size % 3)
- return -EINVAL;
-
- vx_toggle_dac_mute(chip, 1);
-
- /* Transfert data buffer from PC to DSP */
- for (i = 0; i < dsp->size; i += 3) {
- image = dsp->data + i;
- /* Wait DSP ready for a new read */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
- printk(KERN_ERR
- "dsp loading error at position %d\n", i);
- return err;
- }
- cptr = image;
- csum ^= *cptr;
- csum = (csum >> 24) | (csum << 8);
- vx_outb(chip, TXH, *cptr++);
- csum ^= *cptr;
- csum = (csum >> 24) | (csum << 8);
- vx_outb(chip, TXM, *cptr++);
- csum ^= *cptr;
- csum = (csum >> 24) | (csum << 8);
- vx_outb(chip, TXL, *cptr++);
- }
- snd_printdd(KERN_DEBUG "checksum = 0x%08x\n", csum);
-
- msleep(200);
-
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
-
- vx_toggle_dac_mute(chip, 0);
-
- vx_test_and_ack(chip);
- vx_validate_irq(chip, 1);
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_dsp_load);
-
-#ifdef CONFIG_PM
-/*
- * suspend
- */
-int snd_vx_suspend(struct vx_core *chip, pm_message_t state)
-{
- unsigned int i;
-
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
- chip->chip_status |= VX_STAT_IN_SUSPEND;
- for (i = 0; i < chip->hw->num_codecs; i++)
- snd_pcm_suspend_all(chip->pcm[i]);
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_suspend);
-
-/*
- * resume
- */
-int snd_vx_resume(struct vx_core *chip)
-{
- int i, err;
-
- chip->chip_status &= ~VX_STAT_CHIP_INIT;
-
- for (i = 0; i < 4; i++) {
- if (! chip->firmware[i])
- continue;
- err = chip->ops->load_dsp(chip, i, chip->firmware[i]);
- if (err < 0) {
- snd_printk(KERN_ERR "vx: firmware resume error at DSP %d\n", i);
- return -EIO;
- }
- }
-
- chip->chip_status |= VX_STAT_CHIP_INIT;
- chip->chip_status &= ~VX_STAT_IN_SUSPEND;
-
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_resume);
-#endif
-
-/**
- * snd_vx_create - constructor for struct vx_core
- * @hw: hardware specific record
- *
- * this function allocates the instance and prepare for the hardware
- * initialization.
- *
- * return the instance pointer if successful, NULL in error.
- */
-struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
- struct snd_vx_ops *ops,
- int extra_size)
-{
- struct vx_core *chip;
-
- if (snd_BUG_ON(!card || !hw || !ops))
- return NULL;
-
- chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
- if (! chip) {
- snd_printk(KERN_ERR "vx_core: no memory\n");
- return NULL;
- }
- spin_lock_init(&chip->lock);
- spin_lock_init(&chip->irq_lock);
- chip->irq = -1;
- chip->hw = hw;
- chip->type = hw->type;
- chip->ops = ops;
- tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip);
- mutex_init(&chip->mixer_mutex);
-
- chip->card = card;
- card->private_data = chip;
- strcpy(card->driver, hw->name);
- sprintf(card->shortname, "Digigram %s", hw->name);
-
- vx_proc_init(chip);
-
- return chip;
-}
-
-EXPORT_SYMBOL(snd_vx_create);
-
-/*
- * module entries
- */
-static int __init alsa_vx_core_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_vx_core_exit(void)
-{
-}
-
-module_init(alsa_vx_core_init)
-module_exit(alsa_vx_core_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c b/ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c
deleted file mode 100644
index 4a1fae99..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * DSP firmware management
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * 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 <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/hwdep.h>
-#include <sound/vx_core.h>
-
-#ifdef SND_VX_FW_LOADER
-
-MODULE_FIRMWARE("vx/bx_1_vxp.b56");
-MODULE_FIRMWARE("vx/bx_1_vp4.b56");
-MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
-MODULE_FIRMWARE("vx/x1_2_v22.xlx");
-MODULE_FIRMWARE("vx/x1_1_vxp.xlx");
-MODULE_FIRMWARE("vx/x1_1_vp4.xlx");
-MODULE_FIRMWARE("vx/bd56002.boot");
-MODULE_FIRMWARE("vx/bd563v2.boot");
-MODULE_FIRMWARE("vx/bd563s3.boot");
-MODULE_FIRMWARE("vx/l_1_vx2.d56");
-MODULE_FIRMWARE("vx/l_1_v22.d56");
-MODULE_FIRMWARE("vx/l_1_vxp.d56");
-MODULE_FIRMWARE("vx/l_1_vp4.d56");
-
-int snd_vx_setup_firmware(struct vx_core *chip)
-{
- static char *fw_files[VX_TYPE_NUMS][4] = {
- [VX_TYPE_BOARD] = {
- NULL, "x1_1_vx2.xlx", "bd56002.boot", "l_1_vx2.d56",
- },
- [VX_TYPE_V2] = {
- NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
- },
- [VX_TYPE_MIC] = {
- NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
- },
- [VX_TYPE_VXPOCKET] = {
- "bx_1_vxp.b56", "x1_1_vxp.xlx", "bd563s3.boot", "l_1_vxp.d56"
- },
- [VX_TYPE_VXP440] = {
- "bx_1_vp4.b56", "x1_1_vp4.xlx", "bd563s3.boot", "l_1_vp4.d56"
- },
- };
-
- int i, err;
-
- for (i = 0; i < 4; i++) {
- char path[32];
- const struct firmware *fw;
- if (! fw_files[chip->type][i])
- continue;
- sprintf(path, "vx/%s", fw_files[chip->type][i]);
- if (request_firmware(&fw, path, chip->dev)) {
- snd_printk(KERN_ERR "vx: can't load firmware %s\n", path);
- return -ENOENT;
- }
- err = chip->ops->load_dsp(chip, i, fw);
- if (err < 0) {
- release_firmware(fw);
- return err;
- }
- if (i == 1)
- chip->chip_status |= VX_STAT_XILINX_LOADED;
-#ifdef CONFIG_PM
- chip->firmware[i] = fw;
-#else
- release_firmware(fw);
-#endif
- }
-
- /* ok, we reached to the last one */
- /* create the devices if not built yet */
- if ((err = snd_vx_pcm_new(chip)) < 0)
- return err;
-
- if ((err = snd_vx_mixer_new(chip)) < 0)
- return err;
-
- if (chip->ops->add_controls)
- if ((err = chip->ops->add_controls(chip)) < 0)
- return err;
-
- chip->chip_status |= VX_STAT_DEVICE_INIT;
- chip->chip_status |= VX_STAT_CHIP_INIT;
-
- return snd_card_register(chip->card);
-}
-
-/* exported */
-void snd_vx_free_firmware(struct vx_core *chip)
-{
-#ifdef CONFIG_PM
- int i;
- for (i = 0; i < 4; i++)
- release_firmware(chip->firmware[i]);
-#endif
-}
-
-#else /* old style firmware loading */
-
-static int vx_hwdep_dsp_status(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_status *info)
-{
- static char *type_ids[VX_TYPE_NUMS] = {
- [VX_TYPE_BOARD] = "vxboard",
- [VX_TYPE_V2] = "vx222",
- [VX_TYPE_MIC] = "vx222",
- [VX_TYPE_VXPOCKET] = "vxpocket",
- [VX_TYPE_VXP440] = "vxp440",
- };
- struct vx_core *vx = hw->private_data;
-
- if (snd_BUG_ON(!type_ids[vx->type]))
- return -EINVAL;
- strcpy(info->id, type_ids[vx->type]);
- if (vx_is_pcmcia(vx))
- info->num_dsps = 4;
- else
- info->num_dsps = 3;
- if (vx->chip_status & VX_STAT_CHIP_INIT)
- info->chip_ready = 1;
- info->version = VX_DRIVER_VERSION;
- return 0;
-}
-
-static void free_fw(const struct firmware *fw)
-{
- if (fw) {
- vfree(fw->data);
- kfree(fw);
- }
-}
-
-static int vx_hwdep_dsp_load(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image *dsp)
-{
- struct vx_core *vx = hw->private_data;
- int index, err;
- struct firmware *fw;
-
- if (snd_BUG_ON(!vx->ops->load_dsp))
- return -ENXIO;
-
- fw = kmalloc(sizeof(*fw), GFP_KERNEL);
- if (! fw) {
- snd_printk(KERN_ERR "cannot allocate firmware\n");
- return -ENOMEM;
- }
- fw->size = dsp->length;
- fw->data = vmalloc(fw->size);
- if (! fw->data) {
- snd_printk(KERN_ERR "cannot allocate firmware image (length=%d)\n",
- (int)fw->size);
- kfree(fw);
- return -ENOMEM;
- }
- if (copy_from_user((void *)fw->data, dsp->image, dsp->length)) {
- free_fw(fw);
- return -EFAULT;
- }
-
- index = dsp->index;
- if (! vx_is_pcmcia(vx))
- index++;
- err = vx->ops->load_dsp(vx, index, fw);
- if (err < 0) {
- free_fw(fw);
- return err;
- }
-#ifdef CONFIG_PM
- vx->firmware[index] = fw;
-#else
- free_fw(fw);
-#endif
-
- if (index == 1)
- vx->chip_status |= VX_STAT_XILINX_LOADED;
- if (index < 3)
- return 0;
-
- /* ok, we reached to the last one */
- /* create the devices if not built yet */
- if (! (vx->chip_status & VX_STAT_DEVICE_INIT)) {
- if ((err = snd_vx_pcm_new(vx)) < 0)
- return err;
-
- if ((err = snd_vx_mixer_new(vx)) < 0)
- return err;
-
- if (vx->ops->add_controls)
- if ((err = vx->ops->add_controls(vx)) < 0)
- return err;
-
- if ((err = snd_card_register(vx->card)) < 0)
- return err;
-
- vx->chip_status |= VX_STAT_DEVICE_INIT;
- }
- vx->chip_status |= VX_STAT_CHIP_INIT;
- return 0;
-}
-
-
-/* exported */
-int snd_vx_setup_firmware(struct vx_core *chip)
-{
- int err;
- struct snd_hwdep *hw;
-
- if ((err = snd_hwdep_new(chip->card, SND_VX_HWDEP_ID, 0, &hw)) < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_VX;
- hw->private_data = chip;
- hw->ops.dsp_status = vx_hwdep_dsp_status;
- hw->ops.dsp_load = vx_hwdep_dsp_load;
- hw->exclusive = 1;
- sprintf(hw->name, "VX Loader (%s)", chip->card->driver);
- chip->hwdep = hw;
-
- return snd_card_register(chip->card);
-}
-
-/* exported */
-void snd_vx_free_firmware(struct vx_core *chip)
-{
-#ifdef CONFIG_PM
- int i;
- for (i = 0; i < 4; i++)
- free_fw(chip->firmware[i]);
-#endif
-}
-
-#endif /* SND_VX_FW_LOADER */
-
-EXPORT_SYMBOL(snd_vx_setup_firmware);
-EXPORT_SYMBOL(snd_vx_free_firmware);
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c b/ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c
deleted file mode 100644
index c71b8d14..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * Common mixer part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * 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/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-
-/*
- * write a codec data (24bit)
- */
-static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int data)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!chip->ops->write_codec))
- return;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- spin_lock_irqsave(&chip->lock, flags);
- chip->ops->write_codec(chip, codec, data);
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-/*
- * Data type used to access the Codec
- */
-union vx_codec_data {
- u32 l;
-#ifdef SNDRV_BIG_ENDIAN
- struct w {
- u16 h;
- u16 l;
- } w;
- struct b {
- u8 hh;
- u8 mh;
- u8 ml;
- u8 ll;
- } b;
-#else /* LITTLE_ENDIAN */
- struct w {
- u16 l;
- u16 h;
- } w;
- struct b {
- u8 ll;
- u8 ml;
- u8 mh;
- u8 hh;
- } b;
-#endif
-};
-
-#define SET_CDC_DATA_SEL(di,s) ((di).b.mh = (u8) (s))
-#define SET_CDC_DATA_REG(di,r) ((di).b.ml = (u8) (r))
-#define SET_CDC_DATA_VAL(di,d) ((di).b.ll = (u8) (d))
-#define SET_CDC_DATA_INIT(di) ((di).l = 0L, SET_CDC_DATA_SEL(di,XX_CODEC_SELECTOR))
-
-/*
- * set up codec register and write the value
- * @codec: the codec id, 0 or 1
- * @reg: register index
- * @val: data value
- */
-static void vx_set_codec_reg(struct vx_core *chip, int codec, int reg, int val)
-{
- union vx_codec_data data;
- /* DAC control register */
- SET_CDC_DATA_INIT(data);
- SET_CDC_DATA_REG(data, reg);
- SET_CDC_DATA_VAL(data, val);
- vx_write_codec_reg(chip, codec, data.l);
-}
-
-
-/*
- * vx_set_analog_output_level - set the output attenuation level
- * @codec: the output codec, 0 or 1. (1 for VXP440 only)
- * @left: left output level, 0 = mute
- * @right: right output level
- */
-static void vx_set_analog_output_level(struct vx_core *chip, int codec, int left, int right)
-{
- left = chip->hw->output_level_max - left;
- right = chip->hw->output_level_max - right;
-
- if (chip->ops->akm_write) {
- chip->ops->akm_write(chip, XX_CODEC_LEVEL_LEFT_REGISTER, left);
- chip->ops->akm_write(chip, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
- } else {
- /* convert to attenuation level: 0 = 0dB (max), 0xe3 = -113.5 dB (min) */
- vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_LEFT_REGISTER, left);
- vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
- }
-}
-
-
-/*
- * vx_toggle_dac_mute - mute/unmute DAC
- * @mute: 0 = unmute, 1 = mute
- */
-
-#define DAC_ATTEN_MIN 0x08
-#define DAC_ATTEN_MAX 0x38
-
-void vx_toggle_dac_mute(struct vx_core *chip, int mute)
-{
- unsigned int i;
- for (i = 0; i < chip->hw->num_codecs; i++) {
- if (chip->ops->akm_write)
- chip->ops->akm_write(chip, XX_CODEC_DAC_CONTROL_REGISTER, mute); /* XXX */
- else
- vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER,
- mute ? DAC_ATTEN_MAX : DAC_ATTEN_MIN);
- }
-}
-
-/*
- * vx_reset_codec - reset and initialize the codecs
- */
-void vx_reset_codec(struct vx_core *chip, int cold_reset)
-{
- unsigned int i;
- int port = chip->type >= VX_TYPE_VXPOCKET ? 0x75 : 0x65;
-
- chip->ops->reset_codec(chip);
-
- /* AKM codecs should be initialized in reset_codec callback */
- if (! chip->ops->akm_write) {
- /* initialize old codecs */
- for (i = 0; i < chip->hw->num_codecs; i++) {
- /* DAC control register (change level when zero crossing + mute) */
- vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER, DAC_ATTEN_MAX);
- /* ADC control register */
- vx_set_codec_reg(chip, i, XX_CODEC_ADC_CONTROL_REGISTER, 0x00);
- /* Port mode register */
- vx_set_codec_reg(chip, i, XX_CODEC_PORT_MODE_REGISTER, port);
- /* Clock control register */
- vx_set_codec_reg(chip, i, XX_CODEC_CLOCK_CONTROL_REGISTER, 0x00);
- }
- }
-
- /* mute analog output */
- for (i = 0; i < chip->hw->num_codecs; i++) {
- chip->output_level[i][0] = 0;
- chip->output_level[i][1] = 0;
- vx_set_analog_output_level(chip, i, 0, 0);
- }
-}
-
-/*
- * change the audio input source
- * @src: the target source (VX_AUDIO_SRC_XXX)
- */
-static void vx_change_audio_source(struct vx_core *chip, int src)
-{
- unsigned long flags;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- spin_lock_irqsave(&chip->lock, flags);
- chip->ops->change_audio_source(chip, src);
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-/*
- * change the audio source if necessary and possible
- * returns 1 if the source is actually changed.
- */
-int vx_sync_audio_source(struct vx_core *chip)
-{
- if (chip->audio_source_target == chip->audio_source ||
- chip->pcm_running)
- return 0;
- vx_change_audio_source(chip, chip->audio_source_target);
- chip->audio_source = chip->audio_source_target;
- return 1;
-}
-
-
-/*
- * audio level, mute, monitoring
- */
-struct vx_audio_level {
- unsigned int has_level: 1;
- unsigned int has_monitor_level: 1;
- unsigned int has_mute: 1;
- unsigned int has_monitor_mute: 1;
- unsigned int mute;
- unsigned int monitor_mute;
- short level;
- short monitor_level;
-};
-
-static int vx_adjust_audio_level(struct vx_core *chip, int audio, int capture,
- struct vx_audio_level *info)
-{
- struct vx_rmh rmh;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- vx_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
- if (capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
- /* Add Audio IO mask */
- rmh.Cmd[1] = 1 << audio;
- rmh.Cmd[2] = 0;
- if (info->has_level) {
- rmh.Cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
- rmh.Cmd[2] |= info->level;
- }
- if (info->has_monitor_level) {
- rmh.Cmd[0] |= VALID_AUDIO_IO_MONITORING_LEVEL;
- rmh.Cmd[2] |= ((unsigned int)info->monitor_level << 10);
- }
- if (info->has_mute) {
- rmh.Cmd[0] |= VALID_AUDIO_IO_MUTE_LEVEL;
- if (info->mute)
- rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_LEVEL;
- }
- if (info->has_monitor_mute) {
- /* validate flag for M2 at least to unmute it */
- rmh.Cmd[0] |= VALID_AUDIO_IO_MUTE_MONITORING_1 | VALID_AUDIO_IO_MUTE_MONITORING_2;
- if (info->monitor_mute)
- rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_MONITORING_1;
- }
-
- return vx_send_msg(chip, &rmh);
-}
-
-
-#if 0 // not used
-static int vx_read_audio_level(struct vx_core *chip, int audio, int capture,
- struct vx_audio_level *info)
-{
- int err;
- struct vx_rmh rmh;
-
- memset(info, 0, sizeof(*info));
- vx_init_rmh(&rmh, CMD_GET_AUDIO_LEVELS);
- if (capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
- /* Add Audio IO mask */
- rmh.Cmd[1] = 1 << audio;
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
- info.level = rmh.Stat[0] & MASK_DSP_WORD_LEVEL;
- info.monitor_level = (rmh.Stat[0] >> 10) & MASK_DSP_WORD_LEVEL;
- info.mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_LEVEL) ? 1 : 0;
- info.monitor_mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_MONITORING_1) ? 1 : 0;
- return 0;
-}
-#endif // not used
-
-/*
- * set the monitoring level and mute state of the given audio
- * no more static, because must be called from vx_pcm to demute monitoring
- */
-int vx_set_monitor_level(struct vx_core *chip, int audio, int level, int active)
-{
- struct vx_audio_level info;
-
- memset(&info, 0, sizeof(info));
- info.has_monitor_level = 1;
- info.monitor_level = level;
- info.has_monitor_mute = 1;
- info.monitor_mute = !active;
- chip->audio_monitor[audio] = level;
- chip->audio_monitor_active[audio] = active;
- return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
-}
-
-
-/*
- * set the mute status of the given audio
- */
-static int vx_set_audio_switch(struct vx_core *chip, int audio, int active)
-{
- struct vx_audio_level info;
-
- memset(&info, 0, sizeof(info));
- info.has_mute = 1;
- info.mute = !active;
- chip->audio_active[audio] = active;
- return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
-}
-
-/*
- * set the mute status of the given audio
- */
-static int vx_set_audio_gain(struct vx_core *chip, int audio, int capture, int level)
-{
- struct vx_audio_level info;
-
- memset(&info, 0, sizeof(info));
- info.has_level = 1;
- info.level = level;
- chip->audio_gain[capture][audio] = level;
- return vx_adjust_audio_level(chip, audio, capture, &info);
-}
-
-/*
- * reset all audio levels
- */
-static void vx_reset_audio_levels(struct vx_core *chip)
-{
- unsigned int i, c;
- struct vx_audio_level info;
-
- memset(chip->audio_gain, 0, sizeof(chip->audio_gain));
- memset(chip->audio_active, 0, sizeof(chip->audio_active));
- memset(chip->audio_monitor, 0, sizeof(chip->audio_monitor));
- memset(chip->audio_monitor_active, 0, sizeof(chip->audio_monitor_active));
-
- for (c = 0; c < 2; c++) {
- for (i = 0; i < chip->hw->num_ins * 2; i++) {
- memset(&info, 0, sizeof(info));
- if (c == 0) {
- info.has_monitor_level = 1;
- info.has_mute = 1;
- info.has_monitor_mute = 1;
- }
- info.has_level = 1;
- info.level = CVAL_0DB; /* default: 0dB */
- vx_adjust_audio_level(chip, i, c, &info);
- chip->audio_gain[c][i] = CVAL_0DB;
- chip->audio_monitor[i] = CVAL_0DB;
- }
- }
-}
-
-
-/*
- * VU, peak meter record
- */
-
-#define VU_METER_CHANNELS 2
-
-struct vx_vu_meter {
- int saturated;
- int vu_level;
- int peak_level;
-};
-
-/*
- * get the VU and peak meter values
- * @audio: the audio index
- * @capture: 0 = playback, 1 = capture operation
- * @info: the array of vx_vu_meter records (size = 2).
- */
-static int vx_get_audio_vu_meter(struct vx_core *chip, int audio, int capture, struct vx_vu_meter *info)
-{
- struct vx_rmh rmh;
- int i, err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- vx_init_rmh(&rmh, CMD_AUDIO_VU_PIC_METER);
- rmh.LgStat += 2 * VU_METER_CHANNELS;
- if (capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
-
- /* Add Audio IO mask */
- rmh.Cmd[1] = 0;
- for (i = 0; i < VU_METER_CHANNELS; i++)
- rmh.Cmd[1] |= 1 << (audio + i);
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
- /* Read response */
- for (i = 0; i < 2 * VU_METER_CHANNELS; i +=2) {
- info->saturated = (rmh.Stat[0] & (1 << (audio + i))) ? 1 : 0;
- info->vu_level = rmh.Stat[i + 1];
- info->peak_level = rmh.Stat[i + 2];
- info++;
- }
- return 0;
-}
-
-
-/*
- * control API entries
- */
-
-/*
- * output level control
- */
-static int vx_output_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = chip->hw->output_level_max;
- return 0;
-}
-
-static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->id.index;
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->output_level[codec][0];
- ucontrol->value.integer.value[1] = chip->output_level[codec][1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->id.index;
- unsigned int val[2], vmax;
-
- vmax = chip->hw->output_level_max;
- val[0] = ucontrol->value.integer.value[0];
- val[1] = ucontrol->value.integer.value[1];
- if (val[0] > vmax || val[1] > vmax)
- return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
- if (val[0] != chip->output_level[codec][0] ||
- val[1] != chip->output_level[codec][1]) {
- vx_set_analog_output_level(chip, codec, val[0], val[1]);
- chip->output_level[codec][0] = val[0];
- chip->output_level[codec][1] = val[1];
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_output_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Master Playback Volume",
- .info = vx_output_level_info,
- .get = vx_output_level_get,
- .put = vx_output_level_put,
- /* tlv will be filled later */
-};
-
-/*
- * audio source select
- */
-static int vx_audio_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts_mic[3] = {
- "Digital", "Line", "Mic"
- };
- static char *texts_vx2[2] = {
- "Digital", "Analog"
- };
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- if (chip->type >= VX_TYPE_VXPOCKET) {
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name,
- texts_mic[uinfo->value.enumerated.item]);
- } else {
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- texts_vx2[uinfo->value.enumerated.item]);
- }
- return 0;
-}
-
-static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = chip->audio_source_target;
- return 0;
-}
-
-static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- if (chip->type >= VX_TYPE_VXPOCKET) {
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- } else {
- if (ucontrol->value.enumerated.item[0] > 1)
- return -EINVAL;
- }
- mutex_lock(&chip->mixer_mutex);
- if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
- chip->audio_source_target = ucontrol->value.enumerated.item[0];
- vx_sync_audio_source(chip);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_audio_src = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = vx_audio_src_info,
- .get = vx_audio_src_get,
- .put = vx_audio_src_put,
-};
-
-/*
- * clock mode selection
- */
-static int vx_clock_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {
- "Auto", "Internal", "External"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = chip->clock_mode;
- return 0;
-}
-
-static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
- if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
- chip->clock_mode = ucontrol->value.enumerated.item[0];
- vx_set_clock(chip, chip->freq);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_clock_mode = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Clock Mode",
- .info = vx_clock_mode_info,
- .get = vx_clock_mode_get,
- .put = vx_clock_mode_put,
-};
-
-/*
- * Audio Gain
- */
-static int vx_audio_gain_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = CVAL_MAX;
- return 0;
-}
-
-static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio];
- ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
- unsigned int val[2];
-
- val[0] = ucontrol->value.integer.value[0];
- val[1] = ucontrol->value.integer.value[1];
- if (val[0] > CVAL_MAX || val[1] > CVAL_MAX)
- return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
- if (val[0] != chip->audio_gain[capture][audio] ||
- val[1] != chip->audio_gain[capture][audio+1]) {
- vx_set_audio_gain(chip, audio, capture, val[0]);
- vx_set_audio_gain(chip, audio+1, capture, val[1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_monitor[audio];
- ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
- unsigned int val[2];
-
- val[0] = ucontrol->value.integer.value[0];
- val[1] = ucontrol->value.integer.value[1];
- if (val[0] > CVAL_MAX || val[1] > CVAL_MAX)
- return -EINVAL;
-
- mutex_lock(&chip->mixer_mutex);
- if (val[0] != chip->audio_monitor[audio] ||
- val[1] != chip->audio_monitor[audio+1]) {
- vx_set_monitor_level(chip, audio, val[0],
- chip->audio_monitor_active[audio]);
- vx_set_monitor_level(chip, audio+1, val[1],
- chip->audio_monitor_active[audio+1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-#define vx_audio_sw_info snd_ctl_boolean_stereo_info
-
-static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_active[audio];
- ucontrol->value.integer.value[1] = chip->audio_active[audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- if (ucontrol->value.integer.value[0] != chip->audio_active[audio] ||
- ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) {
- vx_set_audio_switch(chip, audio,
- !!ucontrol->value.integer.value[0]);
- vx_set_audio_switch(chip, audio+1,
- !!ucontrol->value.integer.value[1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio];
- ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] ||
- ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) {
- vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
- !!ucontrol->value.integer.value[0]);
- vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
- !!ucontrol->value.integer.value[1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_audio_gain, -10975, 25, 0);
-
-static struct snd_kcontrol_new vx_control_audio_gain = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- /* name will be filled later */
- .info = vx_audio_gain_info,
- .get = vx_audio_gain_get,
- .put = vx_audio_gain_put,
- .tlv = { .p = db_scale_audio_gain },
-};
-static struct snd_kcontrol_new vx_control_output_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .info = vx_audio_sw_info,
- .get = vx_audio_sw_get,
- .put = vx_audio_sw_put
-};
-static struct snd_kcontrol_new vx_control_monitor_gain = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitoring Volume",
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .info = vx_audio_gain_info, /* shared */
- .get = vx_audio_monitor_get,
- .put = vx_audio_monitor_put,
- .tlv = { .p = db_scale_audio_gain },
-};
-static struct snd_kcontrol_new vx_control_monitor_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitoring Switch",
- .info = vx_audio_sw_info, /* shared */
- .get = vx_monitor_sw_get,
- .put = vx_monitor_sw_put
-};
-
-
-/*
- * IEC958 status bits
- */
-static int vx_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff;
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_iec958_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- unsigned int val;
-
- val = (ucontrol->value.iec958.status[0] << 0) |
- (ucontrol->value.iec958.status[1] << 8) |
- (ucontrol->value.iec958.status[2] << 16) |
- (ucontrol->value.iec958.status[3] << 24);
- mutex_lock(&chip->mixer_mutex);
- if (chip->uer_bits != val) {
- chip->uer_bits = val;
- vx_set_iec958_status(chip, val);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_iec958_mask = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .info = vx_iec958_info, /* shared */
- .get = vx_iec958_mask_get,
-};
-
-static struct snd_kcontrol_new vx_control_iec958 = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = vx_iec958_info,
- .get = vx_iec958_get,
- .put = vx_iec958_put
-};
-
-
-/*
- * VU meter
- */
-
-#define METER_MAX 0xff
-#define METER_SHIFT 16
-
-static int vx_vu_meter_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = METER_MAX;
- return 0;
-}
-
-static int vx_vu_meter_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- struct vx_vu_meter meter[2];
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
-
- vx_get_audio_vu_meter(chip, audio, capture, meter);
- ucontrol->value.integer.value[0] = meter[0].vu_level >> METER_SHIFT;
- ucontrol->value.integer.value[1] = meter[1].vu_level >> METER_SHIFT;
- return 0;
-}
-
-static int vx_peak_meter_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- struct vx_vu_meter meter[2];
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
-
- vx_get_audio_vu_meter(chip, audio, capture, meter);
- ucontrol->value.integer.value[0] = meter[0].peak_level >> METER_SHIFT;
- ucontrol->value.integer.value[1] = meter[1].peak_level >> METER_SHIFT;
- return 0;
-}
-
-#define vx_saturation_info snd_ctl_boolean_stereo_info
-
-static int vx_saturation_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- struct vx_vu_meter meter[2];
- int audio = kcontrol->private_value & 0xff;
-
- vx_get_audio_vu_meter(chip, audio, 1, meter); /* capture only */
- ucontrol->value.integer.value[0] = meter[0].saturated;
- ucontrol->value.integer.value[1] = meter[1].saturated;
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_vu_meter = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- /* name will be filled later */
- .info = vx_vu_meter_info,
- .get = vx_vu_meter_get,
-};
-
-static struct snd_kcontrol_new vx_control_peak_meter = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- /* name will be filled later */
- .info = vx_vu_meter_info, /* shared */
- .get = vx_peak_meter_get,
-};
-
-static struct snd_kcontrol_new vx_control_saturation = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Saturation",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = vx_saturation_info,
- .get = vx_saturation_get,
-};
-
-
-
-/*
- *
- */
-
-int snd_vx_mixer_new(struct vx_core *chip)
-{
- unsigned int i, c;
- int err;
- struct snd_kcontrol_new temp;
- struct snd_card *card = chip->card;
- char name[32];
-
- strcpy(card->mixername, card->driver);
-
- /* output level controls */
- for (i = 0; i < chip->hw->num_outs; i++) {
- temp = vx_control_output_level;
- temp.index = i;
- temp.tlv.p = chip->hw->output_level_db_scale;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
-
- /* PCM volumes, switches, monitoring */
- for (i = 0; i < chip->hw->num_outs; i++) {
- int val = i * 2;
- temp = vx_control_audio_gain;
- temp.index = i;
- temp.name = "PCM Playback Volume";
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- temp = vx_control_output_switch;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- temp = vx_control_monitor_gain;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- temp = vx_control_monitor_switch;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
- for (i = 0; i < chip->hw->num_outs; i++) {
- temp = vx_control_audio_gain;
- temp.index = i;
- temp.name = "PCM Capture Volume";
- temp.private_value = (i * 2) | (1 << 8);
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
-
- /* Audio source */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_audio_src, chip))) < 0)
- return err;
- /* clock mode */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_clock_mode, chip))) < 0)
- return err;
- /* IEC958 controls */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958_mask, chip))) < 0)
- return err;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958, chip))) < 0)
- return err;
- /* VU, peak, saturation meters */
- for (c = 0; c < 2; c++) {
- static char *dir[2] = { "Output", "Input" };
- for (i = 0; i < chip->hw->num_ins; i++) {
- int val = (i * 2) | (c << 8);
- if (c == 1) {
- temp = vx_control_saturation;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
- sprintf(name, "%s VU Meter", dir[c]);
- temp = vx_control_vu_meter;
- temp.index = i;
- temp.name = name;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- sprintf(name, "%s Peak Meter", dir[c]);
- temp = vx_control_peak_meter;
- temp.index = i;
- temp.name = name;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
- }
- vx_reset_audio_levels(chip);
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c b/ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c
deleted file mode 100644
index 5e897b23..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c
+++ /dev/null
@@ -1,1283 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * PCM part
- *
- * Copyright (c) 2002,2003 by Takashi Iwai <tiwai@suse.de>
- *
- * 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
- *
- *
- * STRATEGY
- * for playback, we send series of "chunks", which size is equal with the
- * IBL size, typically 126 samples. at each end of chunk, the end-of-buffer
- * interrupt is notified, and the interrupt handler will feed the next chunk.
- *
- * the current position is calculated from the sample count RMH.
- * pipe->transferred is the counter of data which has been already transferred.
- * if this counter reaches to the period size, snd_pcm_period_elapsed() will
- * be issued.
- *
- * for capture, the situation is much easier.
- * to get a low latency response, we'll check the capture streams at each
- * interrupt (capture stream has no EOB notification). if the pending
- * data is accumulated to the period size, snd_pcm_period_elapsed() is
- * called and the pointer is updated.
- *
- * the current point of read buffer is kept in pipe->hw_ptr. note that
- * this is in bytes.
- *
- *
- * TODO
- * - linked trigger for full-duplex mode.
- * - scheduled action on the stream.
- */
-
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/asoundef.h>
-#include <sound/pcm.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-
-/*
- * read three pending pcm bytes via inb()
- */
-static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe)
-{
- int offset = pipe->hw_ptr;
- unsigned char *buf = (unsigned char *)(runtime->dma_area + offset);
- *buf++ = vx_inb(chip, RXH);
- if (++offset >= pipe->buffer_bytes) {
- offset = 0;
- buf = (unsigned char *)runtime->dma_area;
- }
- *buf++ = vx_inb(chip, RXM);
- if (++offset >= pipe->buffer_bytes) {
- offset = 0;
- buf = (unsigned char *)runtime->dma_area;
- }
- *buf++ = vx_inb(chip, RXL);
- if (++offset >= pipe->buffer_bytes) {
- offset = 0;
- buf = (unsigned char *)runtime->dma_area;
- }
- pipe->hw_ptr = offset;
-}
-
-/*
- * vx_set_pcx_time - convert from the PC time to the RMH status time.
- * @pc_time: the pointer for the PC-time to set
- * @dsp_time: the pointer for RMH status time array
- */
-static void vx_set_pcx_time(struct vx_core *chip, pcx_time_t *pc_time,
- unsigned int *dsp_time)
-{
- dsp_time[0] = (unsigned int)((*pc_time) >> 24) & PCX_TIME_HI_MASK;
- dsp_time[1] = (unsigned int)(*pc_time) & MASK_DSP_WORD;
-}
-
-/*
- * vx_set_differed_time - set the differed time if specified
- * @rmh: the rmh record to modify
- * @pipe: the pipe to be checked
- *
- * if the pipe is programmed with the differed time, set the DSP time
- * on the rmh and changes its command length.
- *
- * returns the increase of the command length.
- */
-static int vx_set_differed_time(struct vx_core *chip, struct vx_rmh *rmh,
- struct vx_pipe *pipe)
-{
- /* Update The length added to the RMH command by the timestamp */
- if (! (pipe->differed_type & DC_DIFFERED_DELAY))
- return 0;
-
- /* Set the T bit */
- rmh->Cmd[0] |= DSP_DIFFERED_COMMAND_MASK;
-
- /* Time stamp is the 1st following parameter */
- vx_set_pcx_time(chip, &pipe->pcx_time, &rmh->Cmd[1]);
-
- /* Add the flags to a notified differed command */
- if (pipe->differed_type & DC_NOTIFY_DELAY)
- rmh->Cmd[1] |= NOTIFY_MASK_TIME_HIGH ;
-
- /* Add the flags to a multiple differed command */
- if (pipe->differed_type & DC_MULTIPLE_DELAY)
- rmh->Cmd[1] |= MULTIPLE_MASK_TIME_HIGH;
-
- /* Add the flags to a stream-time differed command */
- if (pipe->differed_type & DC_STREAM_TIME_DELAY)
- rmh->Cmd[1] |= STREAM_MASK_TIME_HIGH;
-
- rmh->LgCmd += 2;
- return 2;
-}
-
-/*
- * vx_set_stream_format - send the stream format command
- * @pipe: the affected pipe
- * @data: format bitmask
- */
-static int vx_set_stream_format(struct vx_core *chip, struct vx_pipe *pipe,
- unsigned int data)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, pipe->is_capture ?
- CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
- rmh.Cmd[0] |= pipe->number << FIELD_SIZE;
-
- /* Command might be longer since we may have to add a timestamp */
- vx_set_differed_time(chip, &rmh, pipe);
-
- rmh.Cmd[rmh.LgCmd] = (data & 0xFFFFFF00) >> 8;
- rmh.Cmd[rmh.LgCmd + 1] = (data & 0xFF) << 16 /*| (datal & 0xFFFF00) >> 8*/;
- rmh.LgCmd += 2;
-
- return vx_send_msg(chip, &rmh);
-}
-
-
-/*
- * vx_set_format - set the format of a pipe
- * @pipe: the affected pipe
- * @runtime: pcm runtime instance to be referred
- *
- * returns 0 if successful, or a negative error code.
- */
-static int vx_set_format(struct vx_core *chip, struct vx_pipe *pipe,
- struct snd_pcm_runtime *runtime)
-{
- unsigned int header = HEADER_FMT_BASE;
-
- if (runtime->channels == 1)
- header |= HEADER_FMT_MONO;
- if (snd_pcm_format_little_endian(runtime->format))
- header |= HEADER_FMT_INTEL;
- if (runtime->rate < 32000 && runtime->rate > 11025)
- header |= HEADER_FMT_UPTO32;
- else if (runtime->rate <= 11025)
- header |= HEADER_FMT_UPTO11;
-
- switch (snd_pcm_format_physical_width(runtime->format)) {
- // case 8: break;
- case 16: header |= HEADER_FMT_16BITS; break;
- case 24: header |= HEADER_FMT_24BITS; break;
- default :
- snd_BUG();
- return -EINVAL;
- };
-
- return vx_set_stream_format(chip, pipe, header);
-}
-
-/*
- * set / query the IBL size
- */
-static int vx_set_ibl(struct vx_core *chip, struct vx_ibl_info *info)
-{
- int err;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_IBL);
- rmh.Cmd[0] |= info->size & 0x03ffff;
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
- info->size = rmh.Stat[0];
- info->max_size = rmh.Stat[1];
- info->min_size = rmh.Stat[2];
- info->granularity = rmh.Stat[3];
- snd_printdd(KERN_DEBUG "vx_set_ibl: size = %d, max = %d, min = %d, gran = %d\n",
- info->size, info->max_size, info->min_size, info->granularity);
- return 0;
-}
-
-
-/*
- * vx_get_pipe_state - get the state of a pipe
- * @pipe: the pipe to be checked
- * @state: the pointer for the returned state
- *
- * checks the state of a given pipe, and stores the state (1 = running,
- * 0 = paused) on the given pointer.
- *
- * called from trigger callback only
- */
-static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *state)
-{
- int err;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_PIPE_STATE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
- if (! err)
- *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
- return err;
-}
-
-
-/*
- * vx_query_hbuffer_size - query available h-buffer size in bytes
- * @pipe: the pipe to be checked
- *
- * return the available size on h-buffer in bytes,
- * or a negative error code.
- *
- * NOTE: calling this function always switches to the stream mode.
- * you'll need to disconnect the host to get back to the
- * normal mode.
- */
-static int vx_query_hbuffer_size(struct vx_core *chip, struct vx_pipe *pipe)
-{
- int result;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_SIZE_HBUFFER);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- if (pipe->is_capture)
- rmh.Cmd[0] |= 0x00000001;
- result = vx_send_msg(chip, &rmh);
- if (! result)
- result = rmh.Stat[0] & 0xffff;
- return result;
-}
-
-
-/*
- * vx_pipe_can_start - query whether a pipe is ready for start
- * @pipe: the pipe to be checked
- *
- * return 1 if ready, 0 if not ready, and negative value on error.
- *
- * called from trigger callback only
- */
-static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe)
-{
- int err;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_CAN_START_PIPE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- rmh.Cmd[0] |= 1;
-
- err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
- if (! err) {
- if (rmh.Stat[0])
- err = 1;
- }
- return err;
-}
-
-/*
- * vx_conf_pipe - tell the pipe to stand by and wait for IRQA.
- * @pipe: the pipe to be configured
- */
-static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_CONF_PIPE);
- if (pipe->is_capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
- rmh.Cmd[1] = 1 << pipe->number;
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-/*
- * vx_send_irqa - trigger IRQA
- */
-static int vx_send_irqa(struct vx_core *chip)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_SEND_IRQA);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-#define MAX_WAIT_FOR_DSP 250
-/*
- * vx boards do not support inter-card sync, besides
- * only 126 samples require to be prepared before a pipe can start
- */
-#define CAN_START_DELAY 2 /* wait 2ms only before asking if the pipe is ready*/
-#define WAIT_STATE_DELAY 2 /* wait 2ms after irqA was requested and check if the pipe state toggled*/
-
-/*
- * vx_toggle_pipe - start / pause a pipe
- * @pipe: the pipe to be triggered
- * @state: start = 1, pause = 0
- *
- * called from trigger callback only
- *
- */
-static int vx_toggle_pipe(struct vx_core *chip, struct vx_pipe *pipe, int state)
-{
- int err, i, cur_state;
-
- /* Check the pipe is not already in the requested state */
- if (vx_get_pipe_state(chip, pipe, &cur_state) < 0)
- return -EBADFD;
- if (state == cur_state)
- return 0;
-
- /* If a start is requested, ask the DSP to get prepared
- * and wait for a positive acknowledge (when there are
- * enough sound buffer for this pipe)
- */
- if (state) {
- for (i = 0 ; i < MAX_WAIT_FOR_DSP; i++) {
- err = vx_pipe_can_start(chip, pipe);
- if (err > 0)
- break;
- /* Wait for a few, before asking again
- * to avoid flooding the DSP with our requests
- */
- mdelay(1);
- }
- }
-
- if ((err = vx_conf_pipe(chip, pipe)) < 0)
- return err;
-
- if ((err = vx_send_irqa(chip)) < 0)
- return err;
-
- /* If it completes successfully, wait for the pipes
- * reaching the expected state before returning
- * Check one pipe only (since they are synchronous)
- */
- for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
- err = vx_get_pipe_state(chip, pipe, &cur_state);
- if (err < 0 || cur_state == state)
- break;
- err = -EIO;
- mdelay(1);
- }
- return err < 0 ? -EIO : 0;
-}
-
-
-/*
- * vx_stop_pipe - stop a pipe
- * @pipe: the pipe to be stopped
- *
- * called from trigger callback only
- */
-static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
- vx_init_rmh(&rmh, CMD_STOP_PIPE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-/*
- * vx_alloc_pipe - allocate a pipe and initialize the pipe instance
- * @capture: 0 = playback, 1 = capture operation
- * @audioid: the audio id to be assigned
- * @num_audio: number of audio channels
- * @pipep: the returned pipe instance
- *
- * return 0 on success, or a negative error code.
- */
-static int vx_alloc_pipe(struct vx_core *chip, int capture,
- int audioid, int num_audio,
- struct vx_pipe **pipep)
-{
- int err;
- struct vx_pipe *pipe;
- struct vx_rmh rmh;
- int data_mode;
-
- *pipep = NULL;
- vx_init_rmh(&rmh, CMD_RES_PIPE);
- vx_set_pipe_cmd_params(&rmh, capture, audioid, num_audio);
-#if 0 // NYI
- if (underrun_skip_sound)
- rmh.Cmd[0] |= BIT_SKIP_SOUND;
-#endif // NYI
- data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
- if (! capture && data_mode)
- rmh.Cmd[0] |= BIT_DATA_MODE;
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
-
- /* initialize the pipe record */
- pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
- if (! pipe) {
- /* release the pipe */
- vx_init_rmh(&rmh, CMD_FREE_PIPE);
- vx_set_pipe_cmd_params(&rmh, capture, audioid, 0);
- vx_send_msg(chip, &rmh);
- return -ENOMEM;
- }
-
- /* the pipe index should be identical with the audio index */
- pipe->number = audioid;
- pipe->is_capture = capture;
- pipe->channels = num_audio;
- pipe->differed_type = 0;
- pipe->pcx_time = 0;
- pipe->data_mode = data_mode;
- *pipep = pipe;
-
- return 0;
-}
-
-
-/*
- * vx_free_pipe - release a pipe
- * @pipe: pipe to be released
- */
-static int vx_free_pipe(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_FREE_PIPE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- vx_send_msg(chip, &rmh);
-
- kfree(pipe);
- return 0;
-}
-
-
-/*
- * vx_start_stream - start the stream
- *
- * called from trigger callback only
- */
-static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_START_ONE_STREAM);
- vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
- vx_set_differed_time(chip, &rmh, pipe);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-/*
- * vx_stop_stream - stop the stream
- *
- * called from trigger callback only
- */
-static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_STOP_STREAM);
- vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-/*
- * playback hw information
- */
-
-static struct snd_pcm_hardware vx_pcm_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
- /*SNDRV_PCM_INFO_RESUME*/),
- .formats = (/*SNDRV_PCM_FMTBIT_U8 |*/
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 126,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = VX_MAX_PERIODS,
- .fifo_size = 126,
-};
-
-
-static void vx_pcm_delayed_start(unsigned long arg);
-
-/*
- * vx_pcm_playback_open - open callback for playback
- */
-static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe = NULL;
- unsigned int audio;
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- audio = subs->pcm->device * 2;
- if (snd_BUG_ON(audio >= chip->audio_outs))
- return -EINVAL;
-
- /* playback pipe may have been already allocated for monitoring */
- pipe = chip->playback_pipes[audio];
- if (! pipe) {
- /* not allocated yet */
- err = vx_alloc_pipe(chip, 0, audio, 2, &pipe); /* stereo playback */
- if (err < 0)
- return err;
- chip->playback_pipes[audio] = pipe;
- }
- /* open for playback */
- pipe->references++;
-
- pipe->substream = subs;
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
- chip->playback_pipes[audio] = pipe;
-
- runtime->hw = vx_pcm_playback_hw;
- runtime->hw.period_bytes_min = chip->ibl.size;
- runtime->private_data = pipe;
-
- /* align to 4 bytes (otherwise will be problematic when 24bit is used) */
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
-
- return 0;
-}
-
-/*
- * vx_pcm_playback_close - close callback for playback
- */
-static int vx_pcm_playback_close(struct snd_pcm_substream *subs)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe;
-
- if (! subs->runtime->private_data)
- return -EINVAL;
-
- pipe = subs->runtime->private_data;
-
- if (--pipe->references == 0) {
- chip->playback_pipes[pipe->number] = NULL;
- vx_free_pipe(chip, pipe);
- }
-
- return 0;
-
-}
-
-
-/*
- * vx_notify_end_of_buffer - send "end-of-buffer" notifier at the given pipe
- * @pipe: the pipe to notify
- *
- * NB: call with a certain lock.
- */
-static int vx_notify_end_of_buffer(struct vx_core *chip, struct vx_pipe *pipe)
-{
- int err;
- struct vx_rmh rmh; /* use a temporary rmh here */
-
- /* Toggle Dsp Host Interface into Message mode */
- vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
- vx_init_rmh(&rmh, CMD_NOTIFY_END_OF_BUFFER);
- vx_set_stream_cmd_params(&rmh, 0, pipe->number);
- err = vx_send_msg_nolock(chip, &rmh);
- if (err < 0)
- return err;
- /* Toggle Dsp Host Interface back to sound transfer mode */
- vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
- return 0;
-}
-
-/*
- * vx_pcm_playback_transfer_chunk - transfer a single chunk
- * @subs: substream
- * @pipe: the pipe to transfer
- * @size: chunk size in bytes
- *
- * transfer a single buffer chunk. EOB notificaton is added after that.
- * called from the interrupt handler, too.
- *
- * return 0 if ok.
- */
-static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
- struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe, int size)
-{
- int space, err = 0;
-
- space = vx_query_hbuffer_size(chip, pipe);
- if (space < 0) {
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
- snd_printd("error hbuffer\n");
- return space;
- }
- if (space < size) {
- vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
- snd_printd("no enough hbuffer space %d\n", space);
- return -EIO; /* XRUN */
- }
-
- /* we don't need irqsave here, because this function
- * is called from either trigger callback or irq handler
- */
- spin_lock(&chip->lock);
- vx_pseudo_dma_write(chip, runtime, pipe, size);
- err = vx_notify_end_of_buffer(chip, pipe);
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- spin_unlock(&chip->lock);
- return err;
-}
-
-/*
- * update the position of the given pipe.
- * pipe->position is updated and wrapped within the buffer size.
- * pipe->transferred is updated, too, but the size is not wrapped,
- * so that the caller can check the total transferred size later
- * (to call snd_pcm_period_elapsed).
- */
-static int vx_update_pipe_position(struct vx_core *chip,
- struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
- int err, update;
- u64 count;
-
- vx_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
-
- count = ((u64)(rmh.Stat[0] & 0xfffff) << 24) | (u64)rmh.Stat[1];
- update = (int)(count - pipe->cur_count);
- pipe->cur_count = count;
- pipe->position += update;
- if (pipe->position >= (int)runtime->buffer_size)
- pipe->position %= runtime->buffer_size;
- pipe->transferred += update;
- return 0;
-}
-
-/*
- * transfer the pending playback buffer data to DSP
- * called from interrupt handler
- */
-static void vx_pcm_playback_transfer(struct vx_core *chip,
- struct snd_pcm_substream *subs,
- struct vx_pipe *pipe, int nchunks)
-{
- int i, err;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
- return;
- for (i = 0; i < nchunks; i++) {
- if ((err = vx_pcm_playback_transfer_chunk(chip, runtime, pipe,
- chip->ibl.size)) < 0)
- return;
- }
-}
-
-/*
- * update the playback position and call snd_pcm_period_elapsed() if necessary
- * called from interrupt handler
- */
-static void vx_pcm_playback_update(struct vx_core *chip,
- struct snd_pcm_substream *subs,
- struct vx_pipe *pipe)
-{
- int err;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- if (pipe->running && ! (chip->chip_status & VX_STAT_IS_STALE)) {
- if ((err = vx_update_pipe_position(chip, runtime, pipe)) < 0)
- return;
- if (pipe->transferred >= (int)runtime->period_size) {
- pipe->transferred %= runtime->period_size;
- snd_pcm_period_elapsed(subs);
- }
- }
-}
-
-/*
- * start the stream and pipe.
- * this function is called from tasklet, which is invoked by the trigger
- * START callback.
- */
-static void vx_pcm_delayed_start(unsigned long arg)
-{
- struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg;
- struct vx_core *chip = subs->pcm->private_data;
- struct vx_pipe *pipe = subs->runtime->private_data;
- int err;
-
- /* printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/
-
- if ((err = vx_start_stream(chip, pipe)) < 0) {
- snd_printk(KERN_ERR "vx: cannot start stream\n");
- return;
- }
- if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) {
- snd_printk(KERN_ERR "vx: cannot start pipe\n");
- return;
- }
- /* printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/
-}
-
-/*
- * vx_pcm_playback_trigger - trigger callback for playback
- */
-static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe = subs->runtime->private_data;
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (! pipe->is_capture)
- vx_pcm_playback_transfer(chip, subs, pipe, 2);
- /* FIXME:
- * we trigger the pipe using tasklet, so that the interrupts are
- * issued surely after the trigger is completed.
- */
- tasklet_schedule(&pipe->start_tq);
- chip->pcm_running++;
- pipe->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- vx_toggle_pipe(chip, pipe, 0);
- vx_stop_pipe(chip, pipe);
- vx_stop_stream(chip, pipe);
- chip->pcm_running--;
- pipe->running = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if ((err = vx_toggle_pipe(chip, pipe, 0)) < 0)
- return err;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0)
- return err;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * vx_pcm_playback_pointer - pointer callback for playback
- */
-static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_pipe *pipe = runtime->private_data;
- return pipe->position;
-}
-
-/*
- * vx_pcm_hw_params - hw_params callback for playback and capture
- */
-static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_alloc_vmalloc_32_buffer
- (subs, params_buffer_bytes(hw_params));
-}
-
-/*
- * vx_pcm_hw_free - hw_free callback for playback and capture
- */
-static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
-{
- return snd_pcm_lib_free_vmalloc_buffer(subs);
-}
-
-/*
- * vx_pcm_prepare - prepare callback for playback and capture
- */
-static int vx_pcm_prepare(struct snd_pcm_substream *subs)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_pipe *pipe = runtime->private_data;
- int err, data_mode;
- // int max_size, nchunks;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
- if (data_mode != pipe->data_mode && ! pipe->is_capture) {
- /* IEC958 status (raw-mode) was changed */
- /* we reopen the pipe */
- struct vx_rmh rmh;
- snd_printdd(KERN_DEBUG "reopen the pipe with data_mode = %d\n", data_mode);
- vx_init_rmh(&rmh, CMD_FREE_PIPE);
- vx_set_pipe_cmd_params(&rmh, 0, pipe->number, 0);
- if ((err = vx_send_msg(chip, &rmh)) < 0)
- return err;
- vx_init_rmh(&rmh, CMD_RES_PIPE);
- vx_set_pipe_cmd_params(&rmh, 0, pipe->number, pipe->channels);
- if (data_mode)
- rmh.Cmd[0] |= BIT_DATA_MODE;
- if ((err = vx_send_msg(chip, &rmh)) < 0)
- return err;
- pipe->data_mode = data_mode;
- }
-
- if (chip->pcm_running && chip->freq != runtime->rate) {
- snd_printk(KERN_ERR "vx: cannot set different clock %d "
- "from the current %d\n", runtime->rate, chip->freq);
- return -EINVAL;
- }
- vx_set_clock(chip, runtime->rate);
-
- if ((err = vx_set_format(chip, pipe, runtime)) < 0)
- return err;
-
- if (vx_is_pcmcia(chip)) {
- pipe->align = 2; /* 16bit word */
- } else {
- pipe->align = 4; /* 32bit word */
- }
-
- pipe->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
- pipe->period_bytes = frames_to_bytes(runtime, runtime->period_size);
- pipe->hw_ptr = 0;
-
- /* set the timestamp */
- vx_update_pipe_position(chip, runtime, pipe);
- /* clear again */
- pipe->transferred = 0;
- pipe->position = 0;
-
- pipe->prepared = 1;
-
- return 0;
-}
-
-
-/*
- * operators for PCM playback
- */
-static struct snd_pcm_ops vx_pcm_playback_ops = {
- .open = vx_pcm_playback_open,
- .close = vx_pcm_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = vx_pcm_hw_params,
- .hw_free = vx_pcm_hw_free,
- .prepare = vx_pcm_prepare,
- .trigger = vx_pcm_trigger,
- .pointer = vx_pcm_playback_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-
-/*
- * playback hw information
- */
-
-static struct snd_pcm_hardware vx_pcm_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
- /*SNDRV_PCM_INFO_RESUME*/),
- .formats = (/*SNDRV_PCM_FMTBIT_U8 |*/
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 126,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = VX_MAX_PERIODS,
- .fifo_size = 126,
-};
-
-
-/*
- * vx_pcm_capture_open - open callback for capture
- */
-static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe;
- struct vx_pipe *pipe_out_monitoring = NULL;
- unsigned int audio;
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- audio = subs->pcm->device * 2;
- if (snd_BUG_ON(audio >= chip->audio_ins))
- return -EINVAL;
- err = vx_alloc_pipe(chip, 1, audio, 2, &pipe);
- if (err < 0)
- return err;
- pipe->substream = subs;
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
- chip->capture_pipes[audio] = pipe;
-
- /* check if monitoring is needed */
- if (chip->audio_monitor_active[audio]) {
- pipe_out_monitoring = chip->playback_pipes[audio];
- if (! pipe_out_monitoring) {
- /* allocate a pipe */
- err = vx_alloc_pipe(chip, 0, audio, 2, &pipe_out_monitoring);
- if (err < 0)
- return err;
- chip->playback_pipes[audio] = pipe_out_monitoring;
- }
- pipe_out_monitoring->references++;
- /*
- if an output pipe is available, it's audios still may need to be
- unmuted. hence we'll have to call a mixer entry point.
- */
- vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
- chip->audio_monitor_active[audio]);
- /* assuming stereo */
- vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
- chip->audio_monitor_active[audio+1]);
- }
-
- pipe->monitoring_pipe = pipe_out_monitoring; /* default value NULL */
-
- runtime->hw = vx_pcm_capture_hw;
- runtime->hw.period_bytes_min = chip->ibl.size;
- runtime->private_data = pipe;
-
- /* align to 4 bytes (otherwise will be problematic when 24bit is used) */
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
-
- return 0;
-}
-
-/*
- * vx_pcm_capture_close - close callback for capture
- */
-static int vx_pcm_capture_close(struct snd_pcm_substream *subs)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe;
- struct vx_pipe *pipe_out_monitoring;
-
- if (! subs->runtime->private_data)
- return -EINVAL;
- pipe = subs->runtime->private_data;
- chip->capture_pipes[pipe->number] = NULL;
-
- pipe_out_monitoring = pipe->monitoring_pipe;
-
- /*
- if an output pipe is attached to this input,
- check if it needs to be released.
- */
- if (pipe_out_monitoring) {
- if (--pipe_out_monitoring->references == 0) {
- vx_free_pipe(chip, pipe_out_monitoring);
- chip->playback_pipes[pipe->number] = NULL;
- pipe->monitoring_pipe = NULL;
- }
- }
-
- vx_free_pipe(chip, pipe);
- return 0;
-}
-
-
-
-#define DMA_READ_ALIGN 6 /* hardware alignment for read */
-
-/*
- * vx_pcm_capture_update - update the capture buffer
- */
-static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream *subs,
- struct vx_pipe *pipe)
-{
- int size, space, count;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
- return;
-
- size = runtime->buffer_size - snd_pcm_capture_avail(runtime);
- if (! size)
- return;
- size = frames_to_bytes(runtime, size);
- space = vx_query_hbuffer_size(chip, pipe);
- if (space < 0)
- goto _error;
- if (size > space)
- size = space;
- size = (size / 3) * 3; /* align to 3 bytes */
- if (size < DMA_READ_ALIGN)
- goto _error;
-
- /* keep the last 6 bytes, they will be read after disconnection */
- count = size - DMA_READ_ALIGN;
- /* read bytes until the current pointer reaches to the aligned position
- * for word-transfer
- */
- while (count > 0) {
- if ((pipe->hw_ptr % pipe->align) == 0)
- break;
- if (vx_wait_for_rx_full(chip) < 0)
- goto _error;
- vx_pcm_read_per_bytes(chip, runtime, pipe);
- count -= 3;
- }
- if (count > 0) {
- /* ok, let's accelerate! */
- int align = pipe->align * 3;
- space = (count / align) * align;
- vx_pseudo_dma_read(chip, runtime, pipe, space);
- count -= space;
- }
- /* read the rest of bytes */
- while (count > 0) {
- if (vx_wait_for_rx_full(chip) < 0)
- goto _error;
- vx_pcm_read_per_bytes(chip, runtime, pipe);
- count -= 3;
- }
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- /* read the last pending 6 bytes */
- count = DMA_READ_ALIGN;
- while (count > 0) {
- vx_pcm_read_per_bytes(chip, runtime, pipe);
- count -= 3;
- }
- /* update the position */
- pipe->transferred += size;
- if (pipe->transferred >= pipe->period_bytes) {
- pipe->transferred %= pipe->period_bytes;
- snd_pcm_period_elapsed(subs);
- }
- return;
-
- _error:
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- return;
-}
-
-/*
- * vx_pcm_capture_pointer - pointer callback for capture
- */
-static snd_pcm_uframes_t vx_pcm_capture_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_pipe *pipe = runtime->private_data;
- return bytes_to_frames(runtime, pipe->hw_ptr);
-}
-
-/*
- * operators for PCM capture
- */
-static struct snd_pcm_ops vx_pcm_capture_ops = {
- .open = vx_pcm_capture_open,
- .close = vx_pcm_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = vx_pcm_hw_params,
- .hw_free = vx_pcm_hw_free,
- .prepare = vx_pcm_prepare,
- .trigger = vx_pcm_trigger,
- .pointer = vx_pcm_capture_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-
-/*
- * interrupt handler for pcm streams
- */
-void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
-{
- unsigned int i;
- struct vx_pipe *pipe;
-
-#define EVENT_MASK (END_OF_BUFFER_EVENTS_PENDING|ASYNC_EVENTS_PENDING)
-
- if (events & EVENT_MASK) {
- vx_init_rmh(&chip->irq_rmh, CMD_ASYNC);
- if (events & ASYNC_EVENTS_PENDING)
- chip->irq_rmh.Cmd[0] |= 0x00000001; /* SEL_ASYNC_EVENTS */
- if (events & END_OF_BUFFER_EVENTS_PENDING)
- chip->irq_rmh.Cmd[0] |= 0x00000002; /* SEL_END_OF_BUF_EVENTS */
-
- if (vx_send_msg(chip, &chip->irq_rmh) < 0) {
- snd_printdd(KERN_ERR "msg send error!!\n");
- return;
- }
-
- i = 1;
- while (i < chip->irq_rmh.LgStat) {
- int p, buf, capture, eob;
- p = chip->irq_rmh.Stat[i] & MASK_FIRST_FIELD;
- capture = (chip->irq_rmh.Stat[i] & 0x400000) ? 1 : 0;
- eob = (chip->irq_rmh.Stat[i] & 0x800000) ? 1 : 0;
- i++;
- if (events & ASYNC_EVENTS_PENDING)
- i++;
- buf = 1; /* force to transfer */
- if (events & END_OF_BUFFER_EVENTS_PENDING) {
- if (eob)
- buf = chip->irq_rmh.Stat[i];
- i++;
- }
- if (capture)
- continue;
- if (snd_BUG_ON(p < 0 || p >= chip->audio_outs))
- continue;
- pipe = chip->playback_pipes[p];
- if (pipe && pipe->substream) {
- vx_pcm_playback_update(chip, pipe->substream, pipe);
- vx_pcm_playback_transfer(chip, pipe->substream, pipe, buf);
- }
- }
- }
-
- /* update the capture pcm pointers as frequently as possible */
- for (i = 0; i < chip->audio_ins; i++) {
- pipe = chip->capture_pipes[i];
- if (pipe && pipe->substream)
- vx_pcm_capture_update(chip, pipe->substream, pipe);
- }
-}
-
-
-/*
- * vx_init_audio_io - check the available audio i/o and allocate pipe arrays
- */
-static int vx_init_audio_io(struct vx_core *chip)
-{
- struct vx_rmh rmh;
- int preferred;
-
- vx_init_rmh(&rmh, CMD_SUPPORTED);
- if (vx_send_msg(chip, &rmh) < 0) {
- snd_printk(KERN_ERR "vx: cannot get the supported audio data\n");
- return -ENXIO;
- }
-
- chip->audio_outs = rmh.Stat[0] & MASK_FIRST_FIELD;
- chip->audio_ins = (rmh.Stat[0] >> (FIELD_SIZE*2)) & MASK_FIRST_FIELD;
- chip->audio_info = rmh.Stat[1];
-
- /* allocate pipes */
- chip->playback_pipes = kcalloc(chip->audio_outs, sizeof(struct vx_pipe *), GFP_KERNEL);
- if (!chip->playback_pipes)
- return -ENOMEM;
- chip->capture_pipes = kcalloc(chip->audio_ins, sizeof(struct vx_pipe *), GFP_KERNEL);
- if (!chip->capture_pipes) {
- kfree(chip->playback_pipes);
- return -ENOMEM;
- }
-
- preferred = chip->ibl.size;
- chip->ibl.size = 0;
- vx_set_ibl(chip, &chip->ibl); /* query the info */
- if (preferred > 0) {
- chip->ibl.size = ((preferred + chip->ibl.granularity - 1) /
- chip->ibl.granularity) * chip->ibl.granularity;
- if (chip->ibl.size > chip->ibl.max_size)
- chip->ibl.size = chip->ibl.max_size;
- } else
- chip->ibl.size = chip->ibl.min_size; /* set to the minimum */
- vx_set_ibl(chip, &chip->ibl);
-
- return 0;
-}
-
-
-/*
- * free callback for pcm
- */
-static void snd_vx_pcm_free(struct snd_pcm *pcm)
-{
- struct vx_core *chip = pcm->private_data;
- chip->pcm[pcm->device] = NULL;
- kfree(chip->playback_pipes);
- chip->playback_pipes = NULL;
- kfree(chip->capture_pipes);
- chip->capture_pipes = NULL;
-}
-
-/*
- * snd_vx_pcm_new - create and initialize a pcm
- */
-int snd_vx_pcm_new(struct vx_core *chip)
-{
- struct snd_pcm *pcm;
- unsigned int i;
- int err;
-
- if ((err = vx_init_audio_io(chip)) < 0)
- return err;
-
- for (i = 0; i < chip->hw->num_codecs; i++) {
- unsigned int outs, ins;
- outs = chip->audio_outs > i * 2 ? 1 : 0;
- ins = chip->audio_ins > i * 2 ? 1 : 0;
- if (! outs && ! ins)
- break;
- err = snd_pcm_new(chip->card, "VX PCM", i,
- outs, ins, &pcm);
- if (err < 0)
- return err;
- if (outs)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &vx_pcm_playback_ops);
- if (ins)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &vx_pcm_capture_ops);
-
- pcm->private_data = chip;
- pcm->private_free = snd_vx_pcm_free;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm[i] = pcm;
- }
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_uer.c b/ANDROID_3.4.5/sound/drivers/vx/vx_uer.c
deleted file mode 100644
index b0560fec..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_uer.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * IEC958 stuff
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * 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 <linux/delay.h>
-#include <sound/core.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-
-/*
- * vx_modify_board_clock - tell the board that its clock has been modified
- * @sync: DSP needs to resynchronize its FIFO
- */
-static int vx_modify_board_clock(struct vx_core *chip, int sync)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_MODIFY_CLOCK);
- /* Ask the DSP to resynchronize its FIFO. */
- if (sync)
- rmh.Cmd[0] |= CMD_MODIFY_CLOCK_S_BIT;
- return vx_send_msg(chip, &rmh);
-}
-
-/*
- * vx_modify_board_inputs - resync audio inputs
- */
-static int vx_modify_board_inputs(struct vx_core *chip)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
- rmh.Cmd[0] |= 1 << 0; /* reference: AUDIO 0 */
- return vx_send_msg(chip, &rmh);
-}
-
-/*
- * vx_read_one_cbit - read one bit from UER config
- * @index: the bit index
- * returns 0 or 1.
- */
-static int vx_read_one_cbit(struct vx_core *chip, int index)
-{
- unsigned long flags;
- int val;
- spin_lock_irqsave(&chip->lock, flags);
- if (chip->type >= VX_TYPE_VXPOCKET) {
- vx_outb(chip, CSUER, 1); /* read */
- vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
- val = (vx_inb(chip, RUER) >> 7) & 0x01;
- } else {
- vx_outl(chip, CSUER, 1); /* read */
- vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
- val = (vx_inl(chip, RUER) >> 7) & 0x01;
- }
- spin_unlock_irqrestore(&chip->lock, flags);
- return val;
-}
-
-/*
- * vx_write_one_cbit - write one bit to UER config
- * @index: the bit index
- * @val: bit value, 0 or 1
- */
-static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
-{
- unsigned long flags;
- val = !!val; /* 0 or 1 */
- spin_lock_irqsave(&chip->lock, flags);
- if (vx_is_pcmcia(chip)) {
- vx_outb(chip, CSUER, 0); /* write */
- vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
- } else {
- vx_outl(chip, CSUER, 0); /* write */
- vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-/*
- * vx_read_uer_status - read the current UER status
- * @mode: pointer to store the UER mode, VX_UER_MODE_XXX
- *
- * returns the frequency of UER, or 0 if not sync,
- * or a negative error code.
- */
-static int vx_read_uer_status(struct vx_core *chip, unsigned int *mode)
-{
- int val, freq;
-
- /* Default values */
- freq = 0;
-
- /* Read UER status */
- if (vx_is_pcmcia(chip))
- val = vx_inb(chip, CSUER);
- else
- val = vx_inl(chip, CSUER);
- if (val < 0)
- return val;
- /* If clock is present, read frequency */
- if (val & VX_SUER_CLOCK_PRESENT_MASK) {
- switch (val & VX_SUER_FREQ_MASK) {
- case VX_SUER_FREQ_32KHz_MASK:
- freq = 32000;
- break;
- case VX_SUER_FREQ_44KHz_MASK:
- freq = 44100;
- break;
- case VX_SUER_FREQ_48KHz_MASK:
- freq = 48000;
- break;
- }
- }
- if (val & VX_SUER_DATA_PRESENT_MASK)
- /* bit 0 corresponds to consumer/professional bit */
- *mode = vx_read_one_cbit(chip, 0) ?
- VX_UER_MODE_PROFESSIONAL : VX_UER_MODE_CONSUMER;
- else
- *mode = VX_UER_MODE_NOT_PRESENT;
-
- return freq;
-}
-
-
-/*
- * compute the sample clock value from frequency
- *
- * The formula is as follows:
- *
- * HexFreq = (dword) ((double) ((double) 28224000 / (double) Frequency))
- * switch ( HexFreq & 0x00000F00 )
- * case 0x00000100: ;
- * case 0x00000200:
- * case 0x00000300: HexFreq -= 0x00000201 ;
- * case 0x00000400:
- * case 0x00000500:
- * case 0x00000600:
- * case 0x00000700: HexFreq = (dword) (((double) 28224000 / (double) (Frequency*2)) - 1)
- * default : HexFreq = (dword) ((double) 28224000 / (double) (Frequency*4)) - 0x000001FF
- */
-
-static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
-{
- int hexfreq;
-
- if (snd_BUG_ON(freq <= 0))
- return 0;
-
- hexfreq = (28224000 * 10) / freq;
- hexfreq = (hexfreq + 5) / 10;
-
- /* max freq = 55125 Hz */
- if (snd_BUG_ON(hexfreq <= 0x00000200))
- return 0;
-
- if (hexfreq <= 0x03ff)
- return hexfreq - 0x00000201;
- if (hexfreq <= 0x07ff)
- return (hexfreq / 2) - 1;
- if (hexfreq <= 0x0fff)
- return (hexfreq / 4) + 0x000001ff;
-
- return 0x5fe; /* min freq = 6893 Hz */
-}
-
-
-/*
- * vx_change_clock_source - change the clock source
- * @source: the new source
- */
-static void vx_change_clock_source(struct vx_core *chip, int source)
-{
- unsigned long flags;
-
- /* we mute DAC to prevent clicks */
- vx_toggle_dac_mute(chip, 1);
- spin_lock_irqsave(&chip->lock, flags);
- chip->ops->set_clock_source(chip, source);
- chip->clock_source = source;
- spin_unlock_irqrestore(&chip->lock, flags);
- /* unmute */
- vx_toggle_dac_mute(chip, 0);
-}
-
-
-/*
- * set the internal clock
- */
-void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
-{
- int clock;
- unsigned long flags;
- /* Get real clock value */
- clock = vx_calc_clock_from_freq(chip, freq);
- snd_printdd(KERN_DEBUG "set internal clock to 0x%x from freq %d\n", clock, freq);
- spin_lock_irqsave(&chip->lock, flags);
- if (vx_is_pcmcia(chip)) {
- vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f);
- vx_outb(chip, LOFREQ, clock & 0xff);
- } else {
- vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f);
- vx_outl(chip, LOFREQ, clock & 0xff);
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-/*
- * set the iec958 status bits
- * @bits: 32-bit status bits
- */
-void vx_set_iec958_status(struct vx_core *chip, unsigned int bits)
-{
- int i;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- for (i = 0; i < 32; i++)
- vx_write_one_cbit(chip, i, bits & (1 << i));
-}
-
-
-/*
- * vx_set_clock - change the clock and audio source if necessary
- */
-int vx_set_clock(struct vx_core *chip, unsigned int freq)
-{
- int src_changed = 0;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return 0;
-
- /* change the audio source if possible */
- vx_sync_audio_source(chip);
-
- if (chip->clock_mode == VX_CLOCK_MODE_EXTERNAL ||
- (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
- chip->audio_source == VX_AUDIO_SRC_DIGITAL)) {
- if (chip->clock_source != UER_SYNC) {
- vx_change_clock_source(chip, UER_SYNC);
- mdelay(6);
- src_changed = 1;
- }
- } else if (chip->clock_mode == VX_CLOCK_MODE_INTERNAL ||
- (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
- chip->audio_source != VX_AUDIO_SRC_DIGITAL)) {
- if (chip->clock_source != INTERNAL_QUARTZ) {
- vx_change_clock_source(chip, INTERNAL_QUARTZ);
- src_changed = 1;
- }
- if (chip->freq == freq)
- return 0;
- vx_set_internal_clock(chip, freq);
- if (src_changed)
- vx_modify_board_inputs(chip);
- }
- if (chip->freq == freq)
- return 0;
- chip->freq = freq;
- vx_modify_board_clock(chip, 1);
- return 0;
-}
-
-
-/*
- * vx_change_frequency - called from interrupt handler
- */
-int vx_change_frequency(struct vx_core *chip)
-{
- int freq;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return 0;
-
- if (chip->clock_source == INTERNAL_QUARTZ)
- return 0;
- /*
- * Read the real UER board frequency
- */
- freq = vx_read_uer_status(chip, &chip->uer_detected);
- if (freq < 0)
- return freq;
- /*
- * The frequency computed by the DSP is good and
- * is different from the previous computed.
- */
- if (freq == 48000 || freq == 44100 || freq == 32000)
- chip->freq_detected = freq;
-
- return 0;
-}