aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/trident
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/trident')
-rw-r--r--sound/pci/trident/Makefile12
-rw-r--r--sound/pci/trident/trident.c76
-rw-r--r--sound/pci/trident/trident.h444
-rw-r--r--sound/pci/trident/trident_main.c1061
-rw-r--r--sound/pci/trident/trident_memory.c295
-rw-r--r--sound/pci/trident/trident_synth.c1031
6 files changed, 1076 insertions, 1843 deletions
diff --git a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile
index 65bc5b70323..88676b50f38 100644
--- a/sound/pci/trident/Makefile
+++ b/sound/pci/trident/Makefile
@@ -1,19 +1,9 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-trident-objs := trident.o trident_main.o trident_memory.o
-snd-trident-synth-objs := trident_synth.o
-
-#
-# this function returns:
-# "m" - CONFIG_SND_SEQUENCER is m
-# <empty string> - CONFIG_SND_SEQUENCER is undefined
-# otherwise parameter #1 value
-#
-sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
# Toplevel Module Dependency
obj-$(CONFIG_SND_TRIDENT) += snd-trident.o
-obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-trident-synth.o
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 940d531575c..d852458caf3 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -21,16 +21,15 @@
*
*/
-#include <sound/driver.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/time.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
#include <sound/core.h>
-#include <sound/trident.h>
+#include "trident.h"
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, <audio@tridentmicro.com>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>");
MODULE_DESCRIPTION("Trident 4D-WaveDX/NX & SiS SI7018");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX},"
@@ -48,7 +47,7 @@ MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX},"
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
static int wavetable_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8192};
@@ -63,21 +62,23 @@ MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
module_param_array(wavetable_size, int, NULL, 0444);
MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
-static struct pci_device_id snd_trident_ids[] = {
- { 0x1023, 0x2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Trident 4DWave DX PCI Audio */
- { 0x1023, 0x2001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Trident 4DWave NX PCI Audio */
- { 0x1039, 0x7018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* SiS SI7018 PCI Audio */
+static DEFINE_PCI_DEVICE_TABLE(snd_trident_ids) = {
+ {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
+ PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
+ {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
+ 0, 0, 0},
+ {PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, 0},
{ 0, }
};
MODULE_DEVICE_TABLE(pci, snd_trident_ids);
-static int __devinit snd_trident_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
+static int snd_trident_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
{
static int dev;
- snd_card_t *card;
- trident_t *trident;
+ struct snd_card *card;
+ struct snd_trident *trident;
const char *str;
int err, pcm_dev = 0;
@@ -88,9 +89,10 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
return -ENOENT;
}
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+ 0, &card);
+ if (err < 0)
+ return err;
if ((err = snd_trident_create(card, pci,
pcm_channels[dev],
@@ -100,6 +102,7 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
snd_card_free(card);
return err;
}
+ card->private_data = trident;
switch (trident->device) {
case TRIDENT_DEVICE_ID_DX:
@@ -145,19 +148,14 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
}
if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
(err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
- trident->midi_port, 1,
- trident->irq, 0, &trident->rmidi)) < 0) {
+ trident->midi_port,
+ MPU401_INFO_INTEGRATED |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &trident->rmidi)) < 0) {
snd_card_free(card);
return err;
}
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- if ((err = snd_trident_attach_synthesizer(trident)) < 0) {
- snd_card_free(card);
- return err;
- }
-#endif
-
snd_trident_create_gameport(trident);
if ((err = snd_card_register(card)) < 0) {
@@ -169,29 +167,21 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
return 0;
}
-static void __devexit snd_trident_remove(struct pci_dev *pci)
+static void snd_trident_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
}
-static struct pci_driver driver = {
- .name = "Trident4DWaveAudio",
+static struct pci_driver trident_driver = {
+ .name = KBUILD_MODNAME,
.id_table = snd_trident_ids,
.probe = snd_trident_probe,
- .remove = __devexit_p(snd_trident_remove),
- SND_PCI_PM_CALLBACKS
+ .remove = snd_trident_remove,
+#ifdef CONFIG_PM_SLEEP
+ .driver = {
+ .pm = &snd_trident_pm,
+ },
+#endif
};
-static int __init alsa_card_trident_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_trident_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_trident_init)
-module_exit(alsa_card_trident_exit)
+module_pci_driver(trident_driver);
diff --git a/sound/pci/trident/trident.h b/sound/pci/trident/trident.h
new file mode 100644
index 00000000000..5f110eb56e4
--- /dev/null
+++ b/sound/pci/trident/trident.h
@@ -0,0 +1,444 @@
+#ifndef __SOUND_TRIDENT_H
+#define __SOUND_TRIDENT_H
+
+/*
+ * audio@tridentmicro.com
+ * Fri Feb 19 15:55:28 MST 1999
+ * Definitions for Trident 4DWave DX/NX chips
+ *
+ *
+ * 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/pcm.h>
+#include <sound/mpu401.h>
+#include <sound/ac97_codec.h>
+#include <sound/util_mem.h>
+
+#define TRIDENT_DEVICE_ID_DX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_DX)
+#define TRIDENT_DEVICE_ID_NX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_NX)
+#define TRIDENT_DEVICE_ID_SI7018 ((PCI_VENDOR_ID_SI<<16)|PCI_DEVICE_ID_SI_7018)
+
+#define SNDRV_TRIDENT_VOICE_TYPE_PCM 0
+#define SNDRV_TRIDENT_VOICE_TYPE_SYNTH 1
+#define SNDRV_TRIDENT_VOICE_TYPE_MIDI 2
+
+#define SNDRV_TRIDENT_VFLG_RUNNING (1<<0)
+
+/* TLB code constants */
+#define SNDRV_TRIDENT_PAGE_SIZE 4096
+#define SNDRV_TRIDENT_PAGE_SHIFT 12
+#define SNDRV_TRIDENT_PAGE_MASK ((1<<SNDRV_TRIDENT_PAGE_SHIFT)-1)
+#define SNDRV_TRIDENT_MAX_PAGES 4096
+
+/*
+ * Direct registers
+ */
+
+#define TRID_REG(trident, x) ((trident)->port + (x))
+
+#define ID_4DWAVE_DX 0x2000
+#define ID_4DWAVE_NX 0x2001
+
+/* Bank definitions */
+
+#define T4D_BANK_A 0
+#define T4D_BANK_B 1
+#define T4D_NUM_BANKS 2
+
+/* Register definitions */
+
+/* Global registers */
+
+enum global_control_bits {
+ CHANNEL_IDX = 0x0000003f,
+ OVERRUN_IE = 0x00000400, /* interrupt enable: capture overrun */
+ UNDERRUN_IE = 0x00000800, /* interrupt enable: playback underrun */
+ ENDLP_IE = 0x00001000, /* interrupt enable: end of buffer */
+ MIDLP_IE = 0x00002000, /* interrupt enable: middle buffer */
+ ETOG_IE = 0x00004000, /* interrupt enable: envelope toggling */
+ EDROP_IE = 0x00008000, /* interrupt enable: envelope drop */
+ BANK_B_EN = 0x00010000, /* SiS: enable bank B (64 channels) */
+ PCMIN_B_MIX = 0x00020000, /* SiS: PCM IN B mixing enable */
+ I2S_OUT_ASSIGN = 0x00040000, /* SiS: I2S Out contains surround PCM */
+ SPDIF_OUT_ASSIGN= 0x00080000, /* SiS: 0=S/PDIF L/R | 1=PCM Out FIFO */
+ MAIN_OUT_ASSIGN = 0x00100000, /* SiS: 0=PCM Out FIFO | 1=MMC Out buffer */
+};
+
+enum miscint_bits {
+ PB_UNDERRUN_IRQ = 0x00000001, REC_OVERRUN_IRQ = 0x00000002,
+ SB_IRQ = 0x00000004, MPU401_IRQ = 0x00000008,
+ OPL3_IRQ = 0x00000010, ADDRESS_IRQ = 0x00000020,
+ ENVELOPE_IRQ = 0x00000040, PB_UNDERRUN = 0x00000100,
+ REC_OVERRUN = 0x00000200, MIXER_UNDERFLOW = 0x00000400,
+ MIXER_OVERFLOW = 0x00000800, NX_SB_IRQ_DISABLE = 0x00001000,
+ ST_TARGET_REACHED = 0x00008000,
+ PB_24K_MODE = 0x00010000, ST_IRQ_EN = 0x00800000,
+ ACGPIO_IRQ = 0x01000000
+};
+
+/* T2 legacy dma control registers. */
+#define LEGACY_DMAR0 0x00 // ADR0
+#define LEGACY_DMAR4 0x04 // CNT0
+#define LEGACY_DMAR6 0x06 // CNT0 - High bits
+#define LEGACY_DMAR11 0x0b // MOD
+#define LEGACY_DMAR15 0x0f // MMR
+
+#define T4D_START_A 0x80
+#define T4D_STOP_A 0x84
+#define T4D_DLY_A 0x88
+#define T4D_SIGN_CSO_A 0x8c
+#define T4D_CSPF_A 0x90
+#define T4D_CSPF_B 0xbc
+#define T4D_CEBC_A 0x94
+#define T4D_AINT_A 0x98
+#define T4D_AINTEN_A 0x9c
+#define T4D_LFO_GC_CIR 0xa0
+#define T4D_MUSICVOL_WAVEVOL 0xa8
+#define T4D_SBDELTA_DELTA_R 0xac
+#define T4D_MISCINT 0xb0
+#define T4D_START_B 0xb4
+#define T4D_STOP_B 0xb8
+#define T4D_SBBL_SBCL 0xc0
+#define T4D_SBCTRL_SBE2R_SBDD 0xc4
+#define T4D_STIMER 0xc8
+#define T4D_AINT_B 0xd8
+#define T4D_AINTEN_B 0xdc
+#define T4D_RCI 0x70
+
+/* MPU-401 UART */
+#define T4D_MPU401_BASE 0x20
+#define T4D_MPUR0 0x20
+#define T4D_MPUR1 0x21
+#define T4D_MPUR2 0x22
+#define T4D_MPUR3 0x23
+
+/* S/PDIF Registers */
+#define NX_SPCTRL_SPCSO 0x24
+#define NX_SPLBA 0x28
+#define NX_SPESO 0x2c
+#define NX_SPCSTATUS 0x64
+
+/* Joystick */
+#define GAMEPORT_GCR 0x30
+#define GAMEPORT_MODE_ADC 0x80
+#define GAMEPORT_LEGACY 0x31
+#define GAMEPORT_AXES 0x34
+
+/* NX Specific Registers */
+#define NX_TLBC 0x6c
+
+/* Channel Registers */
+
+#define CH_START 0xe0
+
+#define CH_DX_CSO_ALPHA_FMS 0xe0
+#define CH_DX_ESO_DELTA 0xe8
+#define CH_DX_FMC_RVOL_CVOL 0xec
+
+#define CH_NX_DELTA_CSO 0xe0
+#define CH_NX_DELTA_ESO 0xe8
+#define CH_NX_ALPHA_FMS_FMC_RVOL_CVOL 0xec
+
+#define CH_LBA 0xe4
+#define CH_GVSEL_PAN_VOL_CTRL_EC 0xf0
+#define CH_EBUF1 0xf4
+#define CH_EBUF2 0xf8
+
+/* AC-97 Registers */
+
+#define DX_ACR0_AC97_W 0x40
+#define DX_ACR1_AC97_R 0x44
+#define DX_ACR2_AC97_COM_STAT 0x48
+
+#define NX_ACR0_AC97_COM_STAT 0x40
+#define NX_ACR1_AC97_W 0x44
+#define NX_ACR2_AC97_R_PRIMARY 0x48
+#define NX_ACR3_AC97_R_SECONDARY 0x4c
+
+#define SI_AC97_WRITE 0x40
+#define SI_AC97_READ 0x44
+#define SI_SERIAL_INTF_CTRL 0x48
+#define SI_AC97_GPIO 0x4c
+#define SI_ASR0 0x50
+#define SI_SPDIF_CS 0x70
+#define SI_GPIO 0x7c
+
+enum trident_nx_ac97_bits {
+ /* ACR1-3 */
+ NX_AC97_BUSY_WRITE = 0x0800,
+ NX_AC97_BUSY_READ = 0x0800,
+ NX_AC97_BUSY_DATA = 0x0400,
+ NX_AC97_WRITE_SECONDARY = 0x0100,
+ /* ACR0 */
+ NX_AC97_SECONDARY_READY = 0x0040,
+ NX_AC97_SECONDARY_RECORD = 0x0020,
+ NX_AC97_SURROUND_OUTPUT = 0x0010,
+ NX_AC97_PRIMARY_READY = 0x0008,
+ NX_AC97_PRIMARY_RECORD = 0x0004,
+ NX_AC97_PCM_OUTPUT = 0x0002,
+ NX_AC97_WARM_RESET = 0x0001
+};
+
+enum trident_dx_ac97_bits {
+ DX_AC97_BUSY_WRITE = 0x8000,
+ DX_AC97_BUSY_READ = 0x8000,
+ DX_AC97_READY = 0x0010,
+ DX_AC97_RECORD = 0x0008,
+ DX_AC97_PLAYBACK = 0x0002
+};
+
+enum sis7018_ac97_bits {
+ SI_AC97_BUSY_WRITE = 0x00008000,
+ SI_AC97_AUDIO_BUSY = 0x00004000,
+ SI_AC97_MODEM_BUSY = 0x00002000,
+ SI_AC97_BUSY_READ = 0x00008000,
+ SI_AC97_SECONDARY = 0x00000080,
+};
+
+enum serial_intf_ctrl_bits {
+ WARM_RESET = 0x00000001,
+ COLD_RESET = 0x00000002,
+ I2S_CLOCK = 0x00000004,
+ PCM_SEC_AC97 = 0x00000008,
+ AC97_DBL_RATE = 0x00000010,
+ SPDIF_EN = 0x00000020,
+ I2S_OUTPUT_EN = 0x00000040,
+ I2S_INPUT_EN = 0x00000080,
+ PCMIN = 0x00000100,
+ LINE1IN = 0x00000200,
+ MICIN = 0x00000400,
+ LINE2IN = 0x00000800,
+ HEAD_SET_IN = 0x00001000,
+ GPIOIN = 0x00002000,
+ /* 7018 spec says id = 01 but the demo board routed to 10
+ SECONDARY_ID= 0x00004000, */
+ SECONDARY_ID = 0x00004000,
+ PCMOUT = 0x00010000,
+ SURROUT = 0x00020000,
+ CENTEROUT = 0x00040000,
+ LFEOUT = 0x00080000,
+ LINE1OUT = 0x00100000,
+ LINE2OUT = 0x00200000,
+ GPIOOUT = 0x00400000,
+ SI_AC97_PRIMARY_READY = 0x01000000,
+ SI_AC97_SECONDARY_READY = 0x02000000,
+ SI_AC97_POWERDOWN = 0x04000000,
+};
+
+/* PCM defaults */
+
+#define T4D_DEFAULT_PCM_VOL 10 /* 0 - 255 */
+#define T4D_DEFAULT_PCM_PAN 0 /* 0 - 127 */
+#define T4D_DEFAULT_PCM_RVOL 127 /* 0 - 127 */
+#define T4D_DEFAULT_PCM_CVOL 127 /* 0 - 127 */
+
+struct snd_trident;
+struct snd_trident_voice;
+struct snd_trident_pcm_mixer;
+
+struct snd_trident_port {
+ struct snd_midi_channel_set * chset;
+ struct snd_trident * trident;
+ int mode; /* operation mode */
+ int client; /* sequencer client number */
+ int port; /* sequencer port number */
+ unsigned int midi_has_voices: 1;
+};
+
+struct snd_trident_memblk_arg {
+ short first_page, last_page;
+};
+
+struct snd_trident_tlb {
+ unsigned int * entries; /* 16k-aligned TLB table */
+ dma_addr_t entries_dmaaddr; /* 16k-aligned PCI address to TLB table */
+ unsigned long * shadow_entries; /* shadow entries with virtual addresses */
+ struct snd_dma_buffer buffer;
+ struct snd_util_memhdr * memhdr; /* page allocation list */
+ struct snd_dma_buffer silent_page;
+};
+
+struct snd_trident_voice {
+ unsigned int number;
+ unsigned int use: 1,
+ pcm: 1,
+ synth:1,
+ midi: 1;
+ unsigned int flags;
+ unsigned char client;
+ unsigned char port;
+ unsigned char index;
+
+ struct snd_trident_sample_ops *sample_ops;
+
+ /* channel parameters */
+ unsigned int CSO; /* 24 bits (16 on DX) */
+ unsigned int ESO; /* 24 bits (16 on DX) */
+ unsigned int LBA; /* 30 bits */
+ unsigned short EC; /* 12 bits */
+ unsigned short Alpha; /* 12 bits */
+ unsigned short Delta; /* 16 bits */
+ unsigned short Attribute; /* 16 bits - SiS 7018 */
+ unsigned short Vol; /* 12 bits (6.6) */
+ unsigned char Pan; /* 7 bits (1.4.2) */
+ unsigned char GVSel; /* 1 bit */
+ unsigned char RVol; /* 7 bits (5.2) */
+ unsigned char CVol; /* 7 bits (5.2) */
+ unsigned char FMC; /* 2 bits */
+ unsigned char CTRL; /* 4 bits */
+ unsigned char FMS; /* 4 bits */
+ unsigned char LFO; /* 8 bits */
+
+ unsigned int negCSO; /* nonzero - use negative CSO */
+
+ struct snd_util_memblk *memblk; /* memory block if TLB enabled */
+
+ /* PCM data */
+
+ struct snd_trident *trident;
+ struct snd_pcm_substream *substream;
+ struct snd_trident_voice *extra; /* extra PCM voice (acts as interrupt generator) */
+ unsigned int running: 1,
+ capture: 1,
+ spdif: 1,
+ foldback: 1,
+ isync: 1,
+ isync2: 1,
+ isync3: 1;
+ int foldback_chan; /* foldback subdevice number */
+ unsigned int stimer; /* global sample timer (to detect spurious interrupts) */
+ unsigned int spurious_threshold; /* spurious threshold */
+ unsigned int isync_mark;
+ unsigned int isync_max;
+ unsigned int isync_ESO;
+
+ /* --- */
+
+ void *private_data;
+ void (*private_free)(struct snd_trident_voice *voice);
+};
+
+struct snd_4dwave {
+ int seq_client;
+
+ struct snd_trident_port seq_ports[4];
+ struct snd_trident_voice voices[64];
+
+ int ChanSynthCount; /* number of allocated synth channels */
+ int max_size; /* maximum synth memory size in bytes */
+ int current_size; /* current allocated synth mem in bytes */
+};
+
+struct snd_trident_pcm_mixer {
+ struct snd_trident_voice *voice; /* active voice */
+ unsigned short vol; /* front volume */
+ unsigned char pan; /* pan control */
+ unsigned char rvol; /* rear volume */
+ unsigned char cvol; /* center volume */
+ unsigned char pad;
+};
+
+struct snd_trident {
+ int irq;
+
+ unsigned int device; /* device ID */
+
+ unsigned char bDMAStart;
+
+ unsigned long port;
+ unsigned long midi_port;
+
+ unsigned int spurious_irq_count;
+ unsigned int spurious_irq_max_delta;
+
+ struct snd_trident_tlb tlb; /* TLB entries for NX cards */
+
+ unsigned char spdif_ctrl;
+ unsigned char spdif_pcm_ctrl;
+ unsigned int spdif_bits;
+ unsigned int spdif_pcm_bits;
+ struct snd_kcontrol *spdif_pcm_ctl; /* S/PDIF settings */
+ unsigned int ac97_ctrl;
+
+ unsigned int ChanMap[2]; /* allocation map for hardware channels */
+
+ int ChanPCM; /* max number of PCM channels */
+ int ChanPCMcnt; /* actual number of PCM channels */
+
+ unsigned int ac97_detect: 1; /* 1 = AC97 in detection phase */
+ unsigned int in_suspend: 1; /* 1 during suspend/resume */
+
+ struct snd_4dwave synth; /* synth specific variables */
+
+ spinlock_t event_lock;
+ spinlock_t voice_alloc;
+
+ struct snd_dma_device dma_dev;
+
+ struct pci_dev *pci;
+ struct snd_card *card;
+ struct snd_pcm *pcm; /* ADC/DAC PCM */
+ struct snd_pcm *foldback; /* Foldback PCM */
+ struct snd_pcm *spdif; /* SPDIF PCM */
+ struct snd_rawmidi *rmidi;
+
+ struct snd_ac97_bus *ac97_bus;
+ struct snd_ac97 *ac97;
+ struct snd_ac97 *ac97_sec;
+
+ unsigned int musicvol_wavevol;
+ struct snd_trident_pcm_mixer pcm_mixer[32];
+ struct snd_kcontrol *ctl_vol; /* front volume */
+ struct snd_kcontrol *ctl_pan; /* pan */
+ struct snd_kcontrol *ctl_rvol; /* rear volume */
+ struct snd_kcontrol *ctl_cvol; /* center volume */
+
+ spinlock_t reg_lock;
+
+ struct gameport *gameport;
+};
+
+int snd_trident_create(struct snd_card *card,
+ struct pci_dev *pci,
+ int pcm_streams,
+ int pcm_spdif_device,
+ int max_wavetable_size,
+ struct snd_trident ** rtrident);
+int snd_trident_create_gameport(struct snd_trident *trident);
+
+int snd_trident_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
+int snd_trident_foldback_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
+int snd_trident_spdif_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
+int snd_trident_attach_synthesizer(struct snd_trident * trident);
+struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type,
+ int client, int port);
+void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice);
+void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice);
+void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice);
+void snd_trident_write_voice_regs(struct snd_trident * trident, struct snd_trident_voice *voice);
+extern const struct dev_pm_ops snd_trident_pm;
+
+/* TLB memory allocation */
+struct snd_util_memblk *snd_trident_alloc_pages(struct snd_trident *trident,
+ struct snd_pcm_substream *substream);
+int snd_trident_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk);
+struct snd_util_memblk *snd_trident_synth_alloc(struct snd_trident *trident, unsigned int size);
+int snd_trident_synth_free(struct snd_trident *trident, struct snd_util_memblk *blk);
+int snd_trident_synth_copy_from_user(struct snd_trident *trident, struct snd_util_memblk *blk,
+ int offset, const char __user *data, int size);
+
+#endif /* __SOUND_TRIDENT_H */
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 29d89bfba0a..1272c18a254 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -1,5 +1,5 @@
/*
- * Maintained by Jaroslav Kysela <perex@suse.cz>
+ * Maintained by Jaroslav Kysela <perex@perex.cz>
* Originated by audio@tridentmicro.com
* Fri Feb 19 15:55:28 MST 1999
* Routines for control of Trident 4DWave (DX and NX) chip
@@ -27,7 +27,6 @@
* SiS7018 S/PDIF support by Thomas Winischhofer <thomas@winischhofer.net>
*/
-#include <sound/driver.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -35,26 +34,30 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/gameport.h>
+#include <linux/dma-mapping.h>
+#include <linux/export.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
-#include <sound/trident.h>
+#include <sound/tlv.h>
+#include "trident.h"
#include <sound/asoundef.h>
#include <asm/io.h>
-static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
-static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
-static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-#ifdef CONFIG_PM
-static int snd_trident_suspend(snd_card_t *card, pm_message_t state);
-static int snd_trident_resume(snd_card_t *card);
-#endif
-static int snd_trident_sis_reset(trident_t *trident);
+static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
+ struct snd_trident_voice * voice,
+ struct snd_pcm_substream *substream);
+static int snd_trident_pcm_mixer_free(struct snd_trident *trident,
+ struct snd_trident_voice * voice,
+ struct snd_pcm_substream *substream);
+static irqreturn_t snd_trident_interrupt(int irq, void *dev_id);
+static int snd_trident_sis_reset(struct snd_trident *trident);
-static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
-static int snd_trident_free(trident_t *trident);
+static void snd_trident_clear_voices(struct snd_trident * trident,
+ unsigned short v_min, unsigned short v_max);
+static int snd_trident_free(struct snd_trident *trident);
/*
* common I/O routines
@@ -62,49 +65,49 @@ static int snd_trident_free(trident_t *trident);
#if 0
-static void snd_trident_print_voice_regs(trident_t *trident, int voice)
+static void snd_trident_print_voice_regs(struct snd_trident *trident, int voice)
{
unsigned int val, tmp;
- printk("Trident voice %i:\n", voice);
+ dev_dbg(trident->card->dev, "Trident voice %i:\n", voice);
outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR));
val = inl(TRID_REG(trident, CH_LBA));
- printk("LBA: 0x%x\n", val);
+ dev_dbg(trident->card->dev, "LBA: 0x%x\n", val);
val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
- printk("GVSel: %i\n", val >> 31);
- printk("Pan: 0x%x\n", (val >> 24) & 0x7f);
- printk("Vol: 0x%x\n", (val >> 16) & 0xff);
- printk("CTRL: 0x%x\n", (val >> 12) & 0x0f);
- printk("EC: 0x%x\n", val & 0x0fff);
+ dev_dbg(trident->card->dev, "GVSel: %i\n", val >> 31);
+ dev_dbg(trident->card->dev, "Pan: 0x%x\n", (val >> 24) & 0x7f);
+ dev_dbg(trident->card->dev, "Vol: 0x%x\n", (val >> 16) & 0xff);
+ dev_dbg(trident->card->dev, "CTRL: 0x%x\n", (val >> 12) & 0x0f);
+ dev_dbg(trident->card->dev, "EC: 0x%x\n", val & 0x0fff);
if (trident->device != TRIDENT_DEVICE_ID_NX) {
val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS));
- printk("CSO: 0x%x\n", val >> 16);
- printk("Alpha: 0x%x\n", (val >> 4) & 0x0fff);
- printk("FMS: 0x%x\n", val & 0x0f);
+ dev_dbg(trident->card->dev, "CSO: 0x%x\n", val >> 16);
+ dev_dbg(trident->card->dev, "Alpha: 0x%x\n", (val >> 4) & 0x0fff);
+ dev_dbg(trident->card->dev, "FMS: 0x%x\n", val & 0x0f);
val = inl(TRID_REG(trident, CH_DX_ESO_DELTA));
- printk("ESO: 0x%x\n", val >> 16);
- printk("Delta: 0x%x\n", val & 0xffff);
+ dev_dbg(trident->card->dev, "ESO: 0x%x\n", val >> 16);
+ dev_dbg(trident->card->dev, "Delta: 0x%x\n", val & 0xffff);
val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
} else { // TRIDENT_DEVICE_ID_NX
val = inl(TRID_REG(trident, CH_NX_DELTA_CSO));
tmp = (val >> 24) & 0xff;
- printk("CSO: 0x%x\n", val & 0x00ffffff);
+ dev_dbg(trident->card->dev, "CSO: 0x%x\n", val & 0x00ffffff);
val = inl(TRID_REG(trident, CH_NX_DELTA_ESO));
tmp |= (val >> 16) & 0xff00;
- printk("Delta: 0x%x\n", tmp);
- printk("ESO: 0x%x\n", val & 0x00ffffff);
+ dev_dbg(trident->card->dev, "Delta: 0x%x\n", tmp);
+ dev_dbg(trident->card->dev, "ESO: 0x%x\n", val & 0x00ffffff);
val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL));
- printk("Alpha: 0x%x\n", val >> 20);
- printk("FMS: 0x%x\n", (val >> 16) & 0x0f);
+ dev_dbg(trident->card->dev, "Alpha: 0x%x\n", val >> 20);
+ dev_dbg(trident->card->dev, "FMS: 0x%x\n", (val >> 16) & 0x0f);
}
- printk("FMC: 0x%x\n", (val >> 14) & 3);
- printk("RVol: 0x%x\n", (val >> 7) & 0x7f);
- printk("CVol: 0x%x\n", val & 0x7f);
+ dev_dbg(trident->card->dev, "FMC: 0x%x\n", (val >> 14) & 3);
+ dev_dbg(trident->card->dev, "RVol: 0x%x\n", (val >> 7) & 0x7f);
+ dev_dbg(trident->card->dev, "CVol: 0x%x\n", val & 0x7f);
}
#endif
/*---------------------------------------------------------------------------
- unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
+ unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
Description: This routine will do all of the reading from the external
CODEC (AC97).
@@ -115,12 +118,12 @@ static void snd_trident_print_voice_regs(trident_t *trident, int voice)
returns: 16 bit value read from the AC97.
---------------------------------------------------------------------------*/
-static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
{
unsigned int data = 0, treg;
unsigned short count = 0xffff;
unsigned long flags;
- trident_t *trident = ac97->private_data;
+ struct snd_trident *trident = ac97->private_data;
spin_lock_irqsave(&trident->reg_lock, flags);
if (trident->device == TRIDENT_DEVICE_ID_DX) {
@@ -153,7 +156,9 @@ static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
}
if (count == 0 && !trident->ac97_detect) {
- snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
+ dev_err(trident->card->dev,
+ "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n",
+ reg, data);
data = 0;
}
@@ -162,7 +167,8 @@ static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
}
/*---------------------------------------------------------------------------
- void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
+ void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
+ unsigned short wdata)
Description: This routine will do all of the writing to the external
CODEC (AC97).
@@ -174,12 +180,13 @@ static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
returns: TRUE if everything went ok, else FALSE.
---------------------------------------------------------------------------*/
-static void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
+static void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
+ unsigned short wdata)
{
unsigned int address, data;
unsigned short count = 0xffff;
unsigned long flags;
- trident_t *trident = ac97->private_data;
+ struct snd_trident *trident = ac97->private_data;
data = ((unsigned long) wdata) << 16;
@@ -230,7 +237,7 @@ static void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned s
}
/*---------------------------------------------------------------------------
- void snd_trident_enable_eso(trident_t *trident)
+ void snd_trident_enable_eso(struct snd_trident *trident)
Description: This routine will enable end of loop interrupts.
End of loop interrupts will occur when a running
@@ -241,7 +248,7 @@ static void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned s
---------------------------------------------------------------------------*/
-static void snd_trident_enable_eso(trident_t * trident)
+static void snd_trident_enable_eso(struct snd_trident * trident)
{
unsigned int val;
@@ -254,7 +261,7 @@ static void snd_trident_enable_eso(trident_t * trident)
}
/*---------------------------------------------------------------------------
- void snd_trident_disable_eso(trident_t *trident)
+ void snd_trident_disable_eso(struct snd_trident *trident)
Description: This routine will disable end of loop interrupts.
End of loop interrupts will occur when a running
@@ -268,7 +275,7 @@ static void snd_trident_enable_eso(trident_t * trident)
---------------------------------------------------------------------------*/
-static void snd_trident_disable_eso(trident_t * trident)
+static void snd_trident_disable_eso(struct snd_trident * trident)
{
unsigned int tmp;
@@ -279,7 +286,7 @@ static void snd_trident_disable_eso(trident_t * trident)
}
/*---------------------------------------------------------------------------
- void snd_trident_start_voice(trident_t * trident, unsigned int voice)
+ void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
Description: Start a voice, any channel 0 thru 63.
This routine automatically handles the fact that there are
@@ -292,7 +299,7 @@ static void snd_trident_disable_eso(trident_t * trident)
---------------------------------------------------------------------------*/
-void snd_trident_start_voice(trident_t * trident, unsigned int voice)
+void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
{
unsigned int mask = 1 << (voice & 0x1f);
unsigned int reg = (voice & 0x20) ? T4D_START_B : T4D_START_A;
@@ -300,8 +307,10 @@ void snd_trident_start_voice(trident_t * trident, unsigned int voice)
outl(mask, TRID_REG(trident, reg));
}
+EXPORT_SYMBOL(snd_trident_start_voice);
+
/*---------------------------------------------------------------------------
- void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
+ void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
Description: Stop a voice, any channel 0 thru 63.
This routine automatically handles the fact that there are
@@ -314,7 +323,7 @@ void snd_trident_start_voice(trident_t * trident, unsigned int voice)
---------------------------------------------------------------------------*/
-void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
+void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
{
unsigned int mask = 1 << (voice & 0x1f);
unsigned int reg = (voice & 0x20) ? T4D_STOP_B : T4D_STOP_A;
@@ -322,8 +331,10 @@ void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
outl(mask, TRID_REG(trident, reg));
}
+EXPORT_SYMBOL(snd_trident_stop_voice);
+
/*---------------------------------------------------------------------------
- int snd_trident_allocate_pcm_channel(trident_t *trident)
+ int snd_trident_allocate_pcm_channel(struct snd_trident *trident)
Description: Allocate hardware channel in Bank B (32-63).
@@ -333,7 +344,7 @@ void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
---------------------------------------------------------------------------*/
-static int snd_trident_allocate_pcm_channel(trident_t * trident)
+static int snd_trident_allocate_pcm_channel(struct snd_trident * trident)
{
int idx;
@@ -361,7 +372,7 @@ static int snd_trident_allocate_pcm_channel(trident_t * trident)
---------------------------------------------------------------------------*/
-static void snd_trident_free_pcm_channel(trident_t *trident, int channel)
+static void snd_trident_free_pcm_channel(struct snd_trident *trident, int channel)
{
if (channel < 32 || channel > 63)
return;
@@ -383,7 +394,7 @@ static void snd_trident_free_pcm_channel(trident_t *trident, int channel)
---------------------------------------------------------------------------*/
-static int snd_trident_allocate_synth_channel(trident_t * trident)
+static int snd_trident_allocate_synth_channel(struct snd_trident * trident)
{
int idx;
@@ -409,7 +420,7 @@ static int snd_trident_allocate_synth_channel(trident_t * trident)
---------------------------------------------------------------------------*/
-static void snd_trident_free_synth_channel(trident_t *trident, int channel)
+static void snd_trident_free_synth_channel(struct snd_trident *trident, int channel)
{
if (channel < 0 || channel > 31)
return;
@@ -426,14 +437,14 @@ static void snd_trident_free_synth_channel(trident_t *trident, int channel)
Description: This routine will complete and write the 5 hardware channel
registers to hardware.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
voice - synthesizer voice structure
Each register field.
---------------------------------------------------------------------------*/
-void snd_trident_write_voice_regs(trident_t * trident,
- snd_trident_voice_t * voice)
+void snd_trident_write_voice_regs(struct snd_trident * trident,
+ struct snd_trident_voice * voice)
{
unsigned int FmcRvolCvol;
unsigned int regs[5];
@@ -452,14 +463,16 @@ void snd_trident_write_voice_regs(trident_t * trident,
(voice->Vol & 0x000003ff) :
((voice->Vol & 0x00003fc) << (16-2)) |
(voice->EC & 0x00000fff);
- regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
+ regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
+ (voice->FMS & 0x0000000f);
regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
regs[3] = (voice->Attribute << 16) | FmcRvolCvol;
break;
case TRIDENT_DEVICE_ID_DX:
regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
(voice->EC & 0x00000fff);
- regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
+ regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
+ (voice->FMS & 0x0000000f);
regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
regs[3] = FmcRvolCvol;
break;
@@ -467,8 +480,10 @@ void snd_trident_write_voice_regs(trident_t * trident,
regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
(voice->EC & 0x00000fff);
regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff);
- regs[2] = ((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff);
- regs[3] = (voice->Alpha << 20) | ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
+ regs[2] = ((voice->Delta << 16) & 0xff000000) |
+ (voice->ESO & 0x00ffffff);
+ regs[3] = (voice->Alpha << 20) |
+ ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
break;
default:
snd_BUG();
@@ -483,35 +498,45 @@ void snd_trident_write_voice_regs(trident_t * trident,
outl(regs[4], TRID_REG(trident, CH_START + 16));
#if 0
- printk("written %i channel:\n", voice->number);
- printk(" regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0)));
- printk(" regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4)));
- printk(" regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8)));
- printk(" regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12)));
- printk(" regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16)));
+ dev_dbg(trident->card->dev, "written %i channel:\n", voice->number);
+ dev_dbg(trident->card->dev, " regs[0] = 0x%x/0x%x\n",
+ regs[0], inl(TRID_REG(trident, CH_START + 0)));
+ dev_dbg(trident->card->dev, " regs[1] = 0x%x/0x%x\n",
+ regs[1], inl(TRID_REG(trident, CH_START + 4)));
+ dev_dbg(trident->card->dev, " regs[2] = 0x%x/0x%x\n",
+ regs[2], inl(TRID_REG(trident, CH_START + 8)));
+ dev_dbg(trident->card->dev, " regs[3] = 0x%x/0x%x\n",
+ regs[3], inl(TRID_REG(trident, CH_START + 12)));
+ dev_dbg(trident->card->dev, " regs[4] = 0x%x/0x%x\n",
+ regs[4], inl(TRID_REG(trident, CH_START + 16)));
#endif
}
+EXPORT_SYMBOL(snd_trident_write_voice_regs);
+
/*---------------------------------------------------------------------------
snd_trident_write_cso_reg
Description: This routine will write the new CSO offset
register to hardware.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
voice - synthesizer voice structure
CSO - new CSO value
---------------------------------------------------------------------------*/
-static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CSO)
+static void snd_trident_write_cso_reg(struct snd_trident * trident,
+ struct snd_trident_voice * voice,
+ unsigned int CSO)
{
voice->CSO = CSO;
outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
if (trident->device != TRIDENT_DEVICE_ID_NX) {
outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
} else {
- outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
+ outl((voice->Delta << 24) |
+ (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
}
}
@@ -521,20 +546,23 @@ static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t *
Description: This routine will write the new ESO offset
register to hardware.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
voice - synthesizer voice structure
ESO - new ESO value
---------------------------------------------------------------------------*/
-static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO)
+static void snd_trident_write_eso_reg(struct snd_trident * trident,
+ struct snd_trident_voice * voice,
+ unsigned int ESO)
{
voice->ESO = ESO;
outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
if (trident->device != TRIDENT_DEVICE_ID_NX) {
outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
} else {
- outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO));
+ outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff),
+ TRID_REG(trident, CH_NX_DELTA_ESO));
}
}
@@ -544,13 +572,15 @@ static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t *
Description: This routine will write the new voice volume
register to hardware.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
voice - synthesizer voice structure
Vol - new voice volume
---------------------------------------------------------------------------*/
-static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Vol)
+static void snd_trident_write_vol_reg(struct snd_trident * trident,
+ struct snd_trident_voice * voice,
+ unsigned int Vol)
{
voice->Vol = Vol;
outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
@@ -560,8 +590,9 @@ static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t *
outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2));
break;
case TRIDENT_DEVICE_ID_SI7018:
- // printk("voice->Vol = 0x%x\n", voice->Vol);
- outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
+ /* dev_dbg(trident->card->dev, "voice->Vol = 0x%x\n", voice->Vol); */
+ outw((voice->CTRL << 12) | voice->Vol,
+ TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
break;
}
}
@@ -572,17 +603,20 @@ static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t *
Description: This routine will write the new voice pan
register to hardware.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
voice - synthesizer voice structure
Pan - new pan value
---------------------------------------------------------------------------*/
-static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Pan)
+static void snd_trident_write_pan_reg(struct snd_trident * trident,
+ struct snd_trident_voice * voice,
+ unsigned int Pan)
{
voice->Pan = Pan;
outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
+ outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f),
+ TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
}
/*---------------------------------------------------------------------------
@@ -591,18 +625,22 @@ static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t *
Description: This routine will write the new reverb volume
register to hardware.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
voice - synthesizer voice structure
RVol - new reverb volume
---------------------------------------------------------------------------*/
-static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int RVol)
+static void snd_trident_write_rvol_reg(struct snd_trident * trident,
+ struct snd_trident_voice * voice,
+ unsigned int RVol)
{
voice->RVol = RVol;
outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
- TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
+ outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
+ (voice->CVol & 0x007f),
+ TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
+ CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
}
/*---------------------------------------------------------------------------
@@ -611,18 +649,22 @@ static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t
Description: This routine will write the new chorus volume
register to hardware.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
voice - synthesizer voice structure
CVol - new chorus volume
---------------------------------------------------------------------------*/
-static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CVol)
+static void snd_trident_write_cvol_reg(struct snd_trident * trident,
+ struct snd_trident_voice * voice,
+ unsigned int CVol)
{
voice->CVol = CVol;
outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
- TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
+ outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
+ (voice->CVol & 0x007f),
+ TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
+ CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
}
/*---------------------------------------------------------------------------
@@ -630,7 +672,7 @@ static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t
Description: This routine converts rate in HZ to hardware delta value.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
rate - Real or Virtual channel number.
Returns: Delta value.
@@ -660,7 +702,7 @@ static unsigned int snd_trident_convert_rate(unsigned int rate)
Description: This routine converts rate in HZ to hardware delta value.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
rate - Real or Virtual channel number.
Returns: Delta value.
@@ -690,13 +732,14 @@ static unsigned int snd_trident_convert_adc_rate(unsigned int rate)
Description: This routine converts rate in HZ to spurious threshold.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
rate - Real or Virtual channel number.
Returns: Delta value.
---------------------------------------------------------------------------*/
-static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
+static unsigned int snd_trident_spurious_threshold(unsigned int rate,
+ unsigned int period_size)
{
unsigned int res = (rate * period_size) / 48000;
if (res < 64)
@@ -711,16 +754,16 @@ static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned i
Description: This routine returns a control mode for a PCM channel.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
substream - PCM substream
Returns: Control value.
---------------------------------------------------------------------------*/
-static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
+static unsigned int snd_trident_control_mode(struct snd_pcm_substream *substream)
{
unsigned int CTRL;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_pcm_runtime *runtime = substream->runtime;
/* set ctrl mode
CTRL default: 8-bit (unsigned) mono, loop mode enabled
@@ -744,7 +787,7 @@ static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
Description: Device I/O control handler for playback/capture parameters.
- Paramters: substream - PCM substream class
+ Parameters: substream - PCM substream class
cmd - what ioctl message to process
arg - additional message infoarg
@@ -752,7 +795,7 @@ static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
---------------------------------------------------------------------------*/
-static int snd_trident_ioctl(snd_pcm_substream_t * substream,
+static int snd_trident_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd,
void *arg)
{
@@ -774,12 +817,12 @@ static int snd_trident_ioctl(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_pcm_mem(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
int err;
if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
@@ -808,13 +851,13 @@ static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_evoice(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- snd_trident_voice_t *evoice = voice->extra;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident_voice *evoice = voice->extra;
/* voice management */
@@ -848,8 +891,8 @@ static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-static int snd_trident_hw_params(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
int err;
@@ -870,12 +913,12 @@ static int snd_trident_hw_params(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-static int snd_trident_hw_free(snd_pcm_substream_t * substream)
+static int snd_trident_hw_free(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
if (trident->tlb.entries) {
if (voice && voice->memblk) {
@@ -902,13 +945,13 @@ static int snd_trident_hw_free(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_playback_prepare(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- snd_trident_voice_t *evoice = voice->extra;
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident_voice *evoice = voice->extra;
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
spin_lock_irq(&trident->reg_lock);
@@ -988,8 +1031,8 @@ static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_capture_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
return snd_trident_allocate_pcm_mem(substream, hw_params);
}
@@ -1005,16 +1048,16 @@ static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_capture_prepare(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
unsigned int val, ESO_bytes;
spin_lock_irq(&trident->reg_lock);
- // Initilize the channel and set channel Mode
+ // Initialize the channel and set channel Mode
outb(0, TRID_REG(trident, LEGACY_DMAR15));
// Set DMA channel operation mode register
@@ -1097,8 +1140,8 @@ static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_si7018_capture_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
int err;
@@ -1119,12 +1162,12 @@ static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_trident_si7018_capture_hw_free(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
snd_pcm_lib_free_pages(substream);
if (evoice != NULL) {
@@ -1145,12 +1188,12 @@ static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- snd_trident_voice_t *evoice = voice->extra;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident_voice *evoice = voice->extra;
spin_lock_irq(&trident->reg_lock);
@@ -1216,12 +1259,12 @@ static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_foldback_prepare(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- snd_trident_voice_t *evoice = voice->extra;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident_voice *evoice = voice->extra;
spin_lock_irq(&trident->reg_lock);
@@ -1294,10 +1337,10 @@ static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_spdif_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
unsigned int old_bits = 0, change = 0;
int err;
@@ -1359,13 +1402,13 @@ static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_spdif_prepare(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- snd_trident_voice_t *evoice = voice->extra;
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident_voice *evoice = voice->extra;
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
unsigned int RESO, LBAO;
unsigned int temp;
@@ -1498,15 +1541,14 @@ static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_trigger(snd_pcm_substream_t *substream,
+static int snd_trident_trigger(struct snd_pcm_substream *substream,
int cmd)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- struct list_head *pos;
- snd_pcm_substream_t *s;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_substream *s;
unsigned int what, whati, capture_flag, spdif_flag;
- snd_trident_voice_t *voice, *evoice;
+ struct snd_trident_voice *voice, *evoice;
unsigned int val, go;
switch (cmd) {
@@ -1526,10 +1568,9 @@ static int snd_trident_trigger(snd_pcm_substream_t *substream,
what = whati = capture_flag = spdif_flag = 0;
spin_lock(&trident->reg_lock);
val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
- if ((trident_t *) snd_pcm_substream_chip(s) == trident) {
- voice = (snd_trident_voice_t *) s->runtime->private_data;
+ snd_pcm_group_for_each_entry(s, substream) {
+ if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) {
+ voice = s->runtime->private_data;
evoice = voice->extra;
what |= 1 << (voice->number & 0x1f);
if (evoice == NULL) {
@@ -1556,7 +1597,10 @@ static int snd_trident_trigger(snd_pcm_substream_t *substream,
if (spdif_flag) {
if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
- outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
+ val = trident->spdif_pcm_ctrl;
+ if (!go)
+ val &= ~(0x28);
+ outb(val, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
} else {
outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
@@ -1596,11 +1640,11 @@ static int snd_trident_trigger(snd_pcm_substream_t *substream,
---------------------------------------------------------------------------*/
-static snd_pcm_uframes_t snd_trident_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
unsigned int cso;
if (!voice->running)
@@ -1629,17 +1673,17 @@ static snd_pcm_uframes_t snd_trident_playback_pointer(snd_pcm_substream_t * subs
Description: This routine return the capture position
- Paramters: pcm1 - PCM device class
+ Parameters: pcm1 - PCM device class
Returns: position of buffer
---------------------------------------------------------------------------*/
-static snd_pcm_uframes_t snd_trident_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_trident_capture_pointer(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
unsigned int result;
if (!voice->running)
@@ -1665,11 +1709,11 @@ static snd_pcm_uframes_t snd_trident_capture_pointer(snd_pcm_substream_t * subst
---------------------------------------------------------------------------*/
-static snd_pcm_uframes_t snd_trident_spdif_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
unsigned int result;
if (!voice->running)
@@ -1684,12 +1728,12 @@ static snd_pcm_uframes_t snd_trident_spdif_pointer(snd_pcm_substream_t * substre
* Playback support device description
*/
-static snd_pcm_hardware_t snd_trident_playback =
+static struct snd_pcm_hardware snd_trident_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
.formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
@@ -1709,12 +1753,12 @@ static snd_pcm_hardware_t snd_trident_playback =
* Capture support device description
*/
-static snd_pcm_hardware_t snd_trident_capture =
+static struct snd_pcm_hardware snd_trident_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
.formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
@@ -1734,12 +1778,12 @@ static snd_pcm_hardware_t snd_trident_capture =
* Foldback capture support device description
*/
-static snd_pcm_hardware_t snd_trident_foldback =
+static struct snd_pcm_hardware snd_trident_foldback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
@@ -1758,12 +1802,12 @@ static snd_pcm_hardware_t snd_trident_foldback =
* SPDIF playback support device description
*/
-static snd_pcm_hardware_t snd_trident_spdif =
+static struct snd_pcm_hardware snd_trident_spdif =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000),
@@ -1779,12 +1823,12 @@ static snd_pcm_hardware_t snd_trident_spdif =
.fifo_size = 0,
};
-static snd_pcm_hardware_t snd_trident_spdif_7018 =
+static struct snd_pcm_hardware snd_trident_spdif_7018 =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
@@ -1799,10 +1843,10 @@ static snd_pcm_hardware_t snd_trident_spdif_7018 =
.fifo_size = 0,
};
-static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_trident_pcm_free_substream(struct snd_pcm_runtime *runtime)
{
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
- trident_t *trident;
+ struct snd_trident_voice *voice = runtime->private_data;
+ struct snd_trident *trident;
if (voice) {
trident = voice->trident;
@@ -1810,11 +1854,11 @@ static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime)
}
}
-static int snd_trident_playback_open(snd_pcm_substream_t * substream)
+static int snd_trident_playback_open(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice;
voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
if (voice == NULL)
@@ -1838,11 +1882,11 @@ static int snd_trident_playback_open(snd_pcm_substream_t * substream)
Parameters: substream - PCM substream class
---------------------------------------------------------------------------*/
-static int snd_trident_playback_close(snd_pcm_substream_t * substream)
+static int snd_trident_playback_close(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_trident_voice *voice = runtime->private_data;
snd_trident_pcm_mixer_free(trident, voice, substream);
return 0;
@@ -1859,11 +1903,11 @@ static int snd_trident_playback_close(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_open(snd_pcm_substream_t * substream)
+static int snd_trident_spdif_open(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_trident_voice_t *voice;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_trident_voice *voice;
+ struct snd_pcm_runtime *runtime = substream->runtime;
voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
if (voice == NULL)
@@ -1900,9 +1944,9 @@ static int snd_trident_spdif_open(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_close(snd_pcm_substream_t * substream)
+static int snd_trident_spdif_close(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
unsigned int temp;
spin_lock_irq(&trident->reg_lock);
@@ -1938,11 +1982,11 @@ static int snd_trident_spdif_close(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_capture_open(snd_pcm_substream_t * substream)
+static int snd_trident_capture_open(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_trident_voice_t *voice;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_trident_voice *voice;
+ struct snd_pcm_runtime *runtime = substream->runtime;
voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
if (voice == NULL)
@@ -1966,7 +2010,7 @@ static int snd_trident_capture_open(snd_pcm_substream_t * substream)
Parameters: substream - PCM substream class
---------------------------------------------------------------------------*/
-static int snd_trident_capture_close(snd_pcm_substream_t * substream)
+static int snd_trident_capture_close(struct snd_pcm_substream *substream)
{
return 0;
}
@@ -1982,11 +2026,11 @@ static int snd_trident_capture_close(snd_pcm_substream_t * substream)
---------------------------------------------------------------------------*/
-static int snd_trident_foldback_open(snd_pcm_substream_t * substream)
+static int snd_trident_foldback_open(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_trident_voice_t *voice;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_trident_voice *voice;
+ struct snd_pcm_runtime *runtime = substream->runtime;
voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
if (voice == NULL)
@@ -2009,12 +2053,12 @@ static int snd_trident_foldback_open(snd_pcm_substream_t * substream)
Parameters: substream - PCM substream class
---------------------------------------------------------------------------*/
-static int snd_trident_foldback_close(snd_pcm_substream_t * substream)
+static int snd_trident_foldback_close(struct snd_pcm_substream *substream)
{
- trident_t *trident = snd_pcm_substream_chip(substream);
- snd_trident_voice_t *voice;
- snd_pcm_runtime_t *runtime = substream->runtime;
- voice = (snd_trident_voice_t *) runtime->private_data;
+ struct snd_trident *trident = snd_pcm_substream_chip(substream);
+ struct snd_trident_voice *voice;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ voice = runtime->private_data;
/* stop capture channel */
spin_lock_irq(&trident->reg_lock);
@@ -2027,7 +2071,7 @@ static int snd_trident_foldback_close(snd_pcm_substream_t * substream)
PCM operations
---------------------------------------------------------------------------*/
-static snd_pcm_ops_t snd_trident_playback_ops = {
+static struct snd_pcm_ops snd_trident_playback_ops = {
.open = snd_trident_playback_open,
.close = snd_trident_playback_close,
.ioctl = snd_trident_ioctl,
@@ -2038,7 +2082,7 @@ static snd_pcm_ops_t snd_trident_playback_ops = {
.pointer = snd_trident_playback_pointer,
};
-static snd_pcm_ops_t snd_trident_nx_playback_ops = {
+static struct snd_pcm_ops snd_trident_nx_playback_ops = {
.open = snd_trident_playback_open,
.close = snd_trident_playback_close,
.ioctl = snd_trident_ioctl,
@@ -2050,7 +2094,7 @@ static snd_pcm_ops_t snd_trident_nx_playback_ops = {
.page = snd_pcm_sgbuf_ops_page,
};
-static snd_pcm_ops_t snd_trident_capture_ops = {
+static struct snd_pcm_ops snd_trident_capture_ops = {
.open = snd_trident_capture_open,
.close = snd_trident_capture_close,
.ioctl = snd_trident_ioctl,
@@ -2061,7 +2105,7 @@ static snd_pcm_ops_t snd_trident_capture_ops = {
.pointer = snd_trident_capture_pointer,
};
-static snd_pcm_ops_t snd_trident_si7018_capture_ops = {
+static struct snd_pcm_ops snd_trident_si7018_capture_ops = {
.open = snd_trident_capture_open,
.close = snd_trident_capture_close,
.ioctl = snd_trident_ioctl,
@@ -2072,7 +2116,7 @@ static snd_pcm_ops_t snd_trident_si7018_capture_ops = {
.pointer = snd_trident_playback_pointer,
};
-static snd_pcm_ops_t snd_trident_foldback_ops = {
+static struct snd_pcm_ops snd_trident_foldback_ops = {
.open = snd_trident_foldback_open,
.close = snd_trident_foldback_close,
.ioctl = snd_trident_ioctl,
@@ -2083,7 +2127,7 @@ static snd_pcm_ops_t snd_trident_foldback_ops = {
.pointer = snd_trident_playback_pointer,
};
-static snd_pcm_ops_t snd_trident_nx_foldback_ops = {
+static struct snd_pcm_ops snd_trident_nx_foldback_ops = {
.open = snd_trident_foldback_open,
.close = snd_trident_foldback_close,
.ioctl = snd_trident_ioctl,
@@ -2095,7 +2139,7 @@ static snd_pcm_ops_t snd_trident_nx_foldback_ops = {
.page = snd_pcm_sgbuf_ops_page,
};
-static snd_pcm_ops_t snd_trident_spdif_ops = {
+static struct snd_pcm_ops snd_trident_spdif_ops = {
.open = snd_trident_spdif_open,
.close = snd_trident_spdif_close,
.ioctl = snd_trident_ioctl,
@@ -2106,7 +2150,7 @@ static snd_pcm_ops_t snd_trident_spdif_ops = {
.pointer = snd_trident_spdif_pointer,
};
-static snd_pcm_ops_t snd_trident_spdif_7018_ops = {
+static struct snd_pcm_ops snd_trident_spdif_7018_ops = {
.open = snd_trident_spdif_open,
.close = snd_trident_spdif_close,
.ioctl = snd_trident_ioctl,
@@ -2118,50 +2162,20 @@ static snd_pcm_ops_t snd_trident_spdif_7018_ops = {
};
/*---------------------------------------------------------------------------
- snd_trident_pcm_free
-
- Description: This routine release the 4DWave private data.
-
- Paramters: private_data - pointer to 4DWave device info.
-
- Returns: None
-
- ---------------------------------------------------------------------------*/
-static void snd_trident_pcm_free(snd_pcm_t *pcm)
-{
- trident_t *trident = pcm->private_data;
- trident->pcm = NULL;
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static void snd_trident_foldback_pcm_free(snd_pcm_t *pcm)
-{
- trident_t *trident = pcm->private_data;
- trident->foldback = NULL;
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static void snd_trident_spdif_pcm_free(snd_pcm_t *pcm)
-{
- trident_t *trident = pcm->private_data;
- trident->spdif = NULL;
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-/*---------------------------------------------------------------------------
snd_trident_pcm
Description: This routine registers the 4DWave device for PCM support.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
Returns: None
---------------------------------------------------------------------------*/
-int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
+int snd_trident_pcm(struct snd_trident *trident,
+ int device, struct snd_pcm **rpcm)
{
- snd_pcm_t *pcm;
+ struct snd_pcm *pcm;
int err;
if (rpcm)
@@ -2170,7 +2184,6 @@ int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm
return err;
pcm->private_data = trident;
- pcm->private_free = snd_trident_pcm_free;
if (trident->tlb.entries) {
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
@@ -2188,7 +2201,7 @@ int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm
trident->pcm = pcm;
if (trident->tlb.entries) {
- snd_pcm_substream_t *substream;
+ struct snd_pcm_substream *substream;
for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(trident->pci),
@@ -2211,18 +2224,19 @@ int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm
Description: This routine registers the 4DWave device for foldback PCM support.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
Returns: None
---------------------------------------------------------------------------*/
-int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
+int snd_trident_foldback_pcm(struct snd_trident *trident,
+ int device, struct snd_pcm **rpcm)
{
- snd_pcm_t *foldback;
+ struct snd_pcm *foldback;
int err;
int num_chan = 3;
- snd_pcm_substream_t *substream;
+ struct snd_pcm_substream *substream;
if (rpcm)
*rpcm = NULL;
@@ -2232,7 +2246,6 @@ int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_
return err;
foldback->private_data = trident;
- foldback->private_free = snd_trident_foldback_pcm_free;
if (trident->tlb.entries)
snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
else
@@ -2268,15 +2281,16 @@ int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_
Description: This routine registers the 4DWave-NX device for SPDIF support.
- Paramters: trident - pointer to target device class for 4DWave-NX.
+ Parameters: trident - pointer to target device class for 4DWave-NX.
Returns: None
---------------------------------------------------------------------------*/
-int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
+int snd_trident_spdif_pcm(struct snd_trident *trident,
+ int device, struct snd_pcm **rpcm)
{
- snd_pcm_t *spdif;
+ struct snd_pcm *spdif;
int err;
if (rpcm)
@@ -2285,7 +2299,6 @@ int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t *
return err;
spdif->private_data = trident;
- spdif->private_free = snd_trident_spdif_pcm_free;
if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
} else {
@@ -2313,19 +2326,12 @@ int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t *
Description: enable/disable S/PDIF out from ac97 mixer
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_trident_spdif_control_info snd_ctl_boolean_mono_info
-static int snd_trident_spdif_control_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned char val;
spin_lock_irq(&trident->reg_lock);
@@ -2335,10 +2341,10 @@ static int snd_trident_spdif_control_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned char val;
int change;
@@ -2366,7 +2372,7 @@ static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_spdif_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
@@ -2382,17 +2388,18 @@ static snd_kcontrol_new_t snd_trident_spdif_control __devinitdata =
Description: put/get the S/PDIF default settings
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_spdif_default_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 snd_trident_spdif_default_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_default_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
spin_lock_irq(&trident->reg_lock);
ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
@@ -2403,10 +2410,10 @@ static int snd_trident_spdif_default_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned int val;
int change;
@@ -2428,7 +2435,7 @@ static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_default =
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -2443,15 +2450,16 @@ static snd_kcontrol_new_t snd_trident_spdif_default __devinitdata =
Description: put/get the S/PDIF mask
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_spdif_mask_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 snd_trident_spdif_mask_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.iec958.status[0] = 0xff;
ucontrol->value.iec958.status[1] = 0xff;
@@ -2460,7 +2468,7 @@ static int snd_trident_spdif_mask_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static snd_kcontrol_new_t snd_trident_spdif_mask __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_mask =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2475,17 +2483,18 @@ static snd_kcontrol_new_t snd_trident_spdif_mask __devinitdata =
Description: put/get the S/PDIF stream settings
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_spdif_stream_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 snd_trident_spdif_stream_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_stream_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
spin_lock_irq(&trident->reg_lock);
ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
@@ -2496,10 +2505,10 @@ static int snd_trident_spdif_stream_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned int val;
int change;
@@ -2521,7 +2530,7 @@ static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_stream =
{
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2537,19 +2546,12 @@ static snd_kcontrol_new_t snd_trident_spdif_stream __devinitdata =
Description: enable/disable rear path for ac97
---------------------------------------------------------------------------*/
-static int snd_trident_ac97_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_trident_ac97_control_info snd_ctl_boolean_mono_info
-static int snd_trident_ac97_control_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned char val;
spin_lock_irq(&trident->reg_lock);
@@ -2559,10 +2561,10 @@ static int snd_trident_ac97_control_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static int snd_trident_ac97_control_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned char val;
int change = 0;
@@ -2578,7 +2580,7 @@ static int snd_trident_ac97_control_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_ac97_rear_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_ac97_rear_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Rear Path",
@@ -2594,7 +2596,8 @@ static snd_kcontrol_new_t snd_trident_ac97_rear_control __devinitdata =
Description: wave & music volume control
---------------------------------------------------------------------------*/
-static int snd_trident_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_vol_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
@@ -2603,10 +2606,10 @@ static int snd_trident_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_i
return 0;
}
-static int snd_trident_vol_control_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned int val;
val = trident->musicvol_wavevol;
@@ -2615,10 +2618,12 @@ static int snd_trident_vol_control_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static int snd_trident_vol_control_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0);
+
+static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned int val;
int change = 0;
@@ -2633,7 +2638,7 @@ static int snd_trident_vol_control_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_vol_music_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_vol_music_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Music Playback Volume",
@@ -2641,9 +2646,10 @@ static snd_kcontrol_new_t snd_trident_vol_music_control __devinitdata =
.get = snd_trident_vol_control_get,
.put = snd_trident_vol_control_put,
.private_value = 16,
+ .tlv = { .p = db_scale_gvol },
};
-static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_vol_wave_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Wave Playback Volume",
@@ -2651,6 +2657,7 @@ static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata =
.get = snd_trident_vol_control_get,
.put = snd_trident_vol_control_put,
.private_value = 0,
+ .tlv = { .p = db_scale_gvol },
};
/*---------------------------------------------------------------------------
@@ -2659,9 +2666,10 @@ static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata =
Description: PCM front volume control
---------------------------------------------------------------------------*/
-static int snd_trident_pcm_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_vol_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -2672,11 +2680,11 @@ static int snd_trident_pcm_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_el
return 0;
}
-static int snd_trident_pcm_vol_control_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_vol_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
ucontrol->value.integer.value[0] = 1023 - mix->vol;
@@ -2686,11 +2694,11 @@ static int snd_trident_pcm_vol_control_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static int snd_trident_pcm_vol_control_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
unsigned int val;
int change = 0;
@@ -2708,7 +2716,7 @@ static int snd_trident_pcm_vol_control_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_vol_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Front Playback Volume",
@@ -2717,6 +2725,7 @@ static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata =
.info = snd_trident_pcm_vol_control_info,
.get = snd_trident_pcm_vol_control_get,
.put = snd_trident_pcm_vol_control_put,
+ /* FIXME: no tlv yet */
};
/*---------------------------------------------------------------------------
@@ -2725,7 +2734,8 @@ static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata =
Description: PCM front pan control
---------------------------------------------------------------------------*/
-static int snd_trident_pcm_pan_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_pan_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -2734,11 +2744,11 @@ static int snd_trident_pcm_pan_control_info(snd_kcontrol_t *kcontrol, snd_ctl_el
return 0;
}
-static int snd_trident_pcm_pan_control_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_pan_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
ucontrol->value.integer.value[0] = mix->pan;
if (ucontrol->value.integer.value[0] & 0x40) {
@@ -2749,11 +2759,11 @@ static int snd_trident_pcm_pan_control_get(snd_kcontrol_t * kcontrol,
return 0;
}
-static int snd_trident_pcm_pan_control_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
unsigned char val;
int change = 0;
@@ -2770,7 +2780,7 @@ static int snd_trident_pcm_pan_control_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_pcm_pan_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_pan_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Pan Playback Control",
@@ -2787,7 +2797,8 @@ static snd_kcontrol_new_t snd_trident_pcm_pan_control __devinitdata =
Description: PCM reverb volume control
---------------------------------------------------------------------------*/
-static int snd_trident_pcm_rvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_rvol_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -2796,21 +2807,21 @@ static int snd_trident_pcm_rvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_e
return 0;
}
-static int snd_trident_pcm_rvol_control_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_rvol_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
ucontrol->value.integer.value[0] = 127 - mix->rvol;
return 0;
}
-static int snd_trident_pcm_rvol_control_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
unsigned short val;
int change = 0;
@@ -2824,7 +2835,9 @@ static int snd_trident_pcm_rvol_control_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata =
+static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
+
+static struct snd_kcontrol_new snd_trident_pcm_rvol_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Reverb Playback Volume",
@@ -2833,6 +2846,7 @@ static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata =
.info = snd_trident_pcm_rvol_control_info,
.get = snd_trident_pcm_rvol_control_get,
.put = snd_trident_pcm_rvol_control_put,
+ .tlv = { .p = db_scale_crvol },
};
/*---------------------------------------------------------------------------
@@ -2841,7 +2855,8 @@ static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata =
Description: PCM chorus volume control
---------------------------------------------------------------------------*/
-static int snd_trident_pcm_cvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_cvol_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -2850,21 +2865,21 @@ static int snd_trident_pcm_cvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_e
return 0;
}
-static int snd_trident_pcm_cvol_control_get(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_cvol_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
ucontrol->value.integer.value[0] = 127 - mix->cvol;
return 0;
}
-static int snd_trident_pcm_cvol_control_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- trident_t *trident = snd_kcontrol_chip(kcontrol);
- snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+ struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+ struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
unsigned short val;
int change = 0;
@@ -2878,7 +2893,7 @@ static int snd_trident_pcm_cvol_control_put(snd_kcontrol_t * kcontrol,
return change;
}
-static snd_kcontrol_new_t snd_trident_pcm_cvol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_cvol_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Chorus Playback Volume",
@@ -2887,13 +2902,17 @@ static snd_kcontrol_new_t snd_trident_pcm_cvol_control __devinitdata =
.info = snd_trident_pcm_cvol_control_info,
.get = snd_trident_pcm_cvol_control_get,
.put = snd_trident_pcm_cvol_control_put,
+ .tlv = { .p = db_scale_crvol },
};
-static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kctl, int num, int activate)
+static void snd_trident_notify_pcm_change1(struct snd_card *card,
+ struct snd_kcontrol *kctl,
+ int num, int activate)
{
- snd_ctl_elem_id_t id;
+ struct snd_ctl_elem_id id;
- snd_runtime_check(kctl != NULL, return);
+ if (! kctl)
+ return;
if (activate)
kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
else
@@ -2903,7 +2922,9 @@ static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kc
snd_ctl_build_ioff(&id, kctl, num));
}
-static void snd_trident_notify_pcm_change(trident_t *trident, snd_trident_pcm_mixer_t *tmix, int num, int activate)
+static void snd_trident_notify_pcm_change(struct snd_trident *trident,
+ struct snd_trident_pcm_mixer *tmix,
+ int num, int activate)
{
snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate);
snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate);
@@ -2911,11 +2932,14 @@ static void snd_trident_notify_pcm_change(trident_t *trident, snd_trident_pcm_mi
snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate);
}
-static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
+static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
+ struct snd_trident_voice *voice,
+ struct snd_pcm_substream *substream)
{
- snd_trident_pcm_mixer_t *tmix;
+ struct snd_trident_pcm_mixer *tmix;
- snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL);
+ if (snd_BUG_ON(!trident || !voice || !substream))
+ return -EINVAL;
tmix = &trident->pcm_mixer[substream->number];
tmix->voice = voice;
tmix->vol = T4D_DEFAULT_PCM_VOL;
@@ -2926,11 +2950,12 @@ static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t *
return 0;
}
-static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
+static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice *voice, struct snd_pcm_substream *substream)
{
- snd_trident_pcm_mixer_t *tmix;
+ struct snd_trident_pcm_mixer *tmix;
- snd_assert(trident != NULL && substream != NULL, return -EINVAL);
+ if (snd_BUG_ON(!trident || !substream))
+ return -EINVAL;
tmix = &trident->pcm_mixer[substream->number];
tmix->voice = NULL;
snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
@@ -2942,25 +2967,25 @@ static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t *v
Description: This routine registers the 4DWave device for mixer support.
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
Returns: None
---------------------------------------------------------------------------*/
-static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device)
+static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
{
- ac97_template_t _ac97;
- snd_card_t * card = trident->card;
- snd_kcontrol_t *kctl;
- snd_ctl_elem_value_t *uctl;
+ struct snd_ac97_template _ac97;
+ struct snd_card *card = trident->card;
+ struct snd_kcontrol *kctl;
+ struct snd_ctl_elem_value *uctl;
int idx, err, retries = 2;
- static ac97_bus_ops_t ops = {
+ static struct snd_ac97_bus_ops ops = {
.write = snd_trident_codec_write,
.read = snd_trident_codec_read,
};
- uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+ uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (!uctl)
return -ENOMEM;
@@ -2989,13 +3014,15 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
_ac97.num = 1;
err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
if (err < 0)
- snd_printk("SI7018: the secondary codec - invalid access\n");
+ dev_err(trident->card->dev,
+ "SI7018: the secondary codec - invalid access\n");
#if 0 // only for my testing purpose --jk
{
- ac97_t *mc97;
+ struct snd_ac97 *mc97;
err = snd_ac97_modem(trident->card, &_ac97, &mc97);
if (err < 0)
- snd_printk("snd_ac97_modem returned error %i\n", err);
+ dev_err(trident->card->dev,
+ "snd_ac97_modem returned error %i\n", err);
}
#endif
}
@@ -3015,7 +3042,7 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
}
for (idx = 0; idx < 32; idx++) {
- snd_trident_pcm_mixer_t *tmix;
+ struct snd_trident_pcm_mixer *tmix;
tmix = &trident->pcm_mixer[idx];
tmix->voice = NULL;
@@ -3113,26 +3140,29 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
static unsigned char snd_trident_gameport_read(struct gameport *gameport)
{
- trident_t *chip = gameport_get_port_data(gameport);
+ struct snd_trident *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
return inb(TRID_REG(chip, GAMEPORT_LEGACY));
}
static void snd_trident_gameport_trigger(struct gameport *gameport)
{
- trident_t *chip = gameport_get_port_data(gameport);
+ struct snd_trident *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return);
+ if (snd_BUG_ON(!chip))
+ return;
outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
}
static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
{
- trident_t *chip = gameport_get_port_data(gameport);
+ struct snd_trident *chip = gameport_get_port_data(gameport);
int i;
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
*buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
@@ -3146,9 +3176,10 @@ static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes
static int snd_trident_gameport_open(struct gameport *gameport, int mode)
{
- trident_t *chip = gameport_get_port_data(gameport);
+ struct snd_trident *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
switch (mode) {
case GAMEPORT_MODE_COOKED:
@@ -3163,13 +3194,14 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode)
}
}
-int __devinit snd_trident_create_gameport(trident_t *chip)
+int snd_trident_create_gameport(struct snd_trident *chip)
{
struct gameport *gp;
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
- printk(KERN_ERR "trident: cannot allocate memory for gameport\n");
+ dev_err(chip->card->dev,
+ "cannot allocate memory for gameport\n");
return -ENOMEM;
}
@@ -3189,7 +3221,7 @@ int __devinit snd_trident_create_gameport(trident_t *chip)
return 0;
}
-static inline void snd_trident_free_gameport(trident_t *chip)
+static inline void snd_trident_free_gameport(struct snd_trident *chip)
{
if (chip->gameport) {
gameport_unregister_port(chip->gameport);
@@ -3197,24 +3229,23 @@ static inline void snd_trident_free_gameport(trident_t *chip)
}
}
#else
-int __devinit snd_trident_create_gameport(trident_t *chip) { return -ENOSYS; }
-static inline void snd_trident_free_gameport(trident_t *chip) { }
+int snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
+static inline void snd_trident_free_gameport(struct snd_trident *chip) { }
#endif /* CONFIG_GAMEPORT */
/*
* delay for 1 tick
*/
-static inline void do_delay(trident_t *chip)
+static inline void do_delay(struct snd_trident *chip)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
/*
* SiS reset routine
*/
-static int snd_trident_sis_reset(trident_t *trident)
+static int snd_trident_sis_reset(struct snd_trident *trident)
{
unsigned long end_time;
unsigned int i;
@@ -3243,7 +3274,8 @@ static int snd_trident_sis_reset(trident_t *trident)
goto __si7018_ok;
do_delay(trident);
} while (time_after_eq(end_time, jiffies));
- snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
+ dev_err(trident->card->dev, "AC'97 codec ready error [0x%x]\n",
+ inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
if (r-- > 0) {
end_time = jiffies + HZ;
do {
@@ -3267,10 +3299,10 @@ static int snd_trident_sis_reset(trident_t *trident)
* /proc interface
*/
-static void snd_trident_proc_read(snd_info_entry_t *entry,
- snd_info_buffer_t * buffer)
+static void snd_trident_proc_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- trident_t *trident = entry->private_data;
+ struct snd_trident *trident = entry->private_data;
char *s;
switch (trident->device) {
@@ -3300,28 +3332,22 @@ static void snd_trident_proc_read(snd_info_entry_t *entry,
snd_iprintf(buffer, "Memory Free : %d\n", snd_util_mem_avail(trident->tlb.memhdr));
}
}
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- snd_iprintf(buffer,"\nWavetable Synth\n");
- snd_iprintf(buffer, "Memory Maximum : %d\n", trident->synth.max_size);
- snd_iprintf(buffer, "Memory Used : %d\n", trident->synth.current_size);
- snd_iprintf(buffer, "Memory Free : %d\n", (trident->synth.max_size-trident->synth.current_size));
-#endif
}
-static void __devinit snd_trident_proc_init(trident_t * trident)
+static void snd_trident_proc_init(struct snd_trident *trident)
{
- snd_info_entry_t *entry;
+ struct snd_info_entry *entry;
const char *s = "trident";
if (trident->device == TRIDENT_DEVICE_ID_SI7018)
s = "sis7018";
if (! snd_card_proc_new(trident->card, s, &entry))
- snd_info_set_text_ops(entry, trident, 1024, snd_trident_proc_read);
+ snd_info_set_text_ops(entry, trident, snd_trident_proc_read);
}
-static int snd_trident_dev_free(snd_device_t *device)
+static int snd_trident_dev_free(struct snd_device *device)
{
- trident_t *trident = device->device_data;
+ struct snd_trident *trident = device->device_data;
return snd_trident_free(trident);
}
@@ -3331,13 +3357,13 @@ static int snd_trident_dev_free(snd_device_t *device)
Description: Allocate and set up the TLB page table on 4D NX.
Each entry has 4 bytes (physical PCI address).
- Paramters: trident - pointer to target device class for 4DWave.
+ Parameters: trident - pointer to target device class for 4DWave.
Returns: 0 or negative error code
---------------------------------------------------------------------------*/
-static int __devinit snd_trident_tlb_alloc(trident_t *trident)
+static int snd_trident_tlb_alloc(struct snd_trident *trident)
{
int i;
@@ -3346,21 +3372,22 @@ static int __devinit snd_trident_tlb_alloc(trident_t *trident)
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer) < 0) {
- snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n");
+ dev_err(trident->card->dev, "unable to allocate TLB buffer\n");
return -ENOMEM;
}
- trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer.area + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
- trident->tlb.entries_dmaaddr = (trident->tlb.buffer.addr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1);
+ trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
+ trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
/* allocate shadow TLB page table (virtual addresses) */
- trident->tlb.shadow_entries = (unsigned long *)vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
+ trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
if (trident->tlb.shadow_entries == NULL) {
- snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n");
+ dev_err(trident->card->dev,
+ "unable to allocate shadow TLB entries\n");
return -ENOMEM;
}
/* allocate and setup silent page and initialise TLB entries */
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) {
- snd_printk(KERN_ERR "trident: unable to allocate silent page\n");
+ dev_err(trident->card->dev, "unable to allocate silent page\n");
return -ENOMEM;
}
memset(trident->tlb.silent_page.area, 0, SNDRV_TRIDENT_PAGE_SIZE);
@@ -3374,7 +3401,7 @@ static int __devinit snd_trident_tlb_alloc(trident_t *trident)
if (trident->tlb.memhdr == NULL)
return -ENOMEM;
- trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t);
+ trident->tlb.memhdr->block_extra_size = sizeof(struct snd_trident_memblk_arg);
return 0;
}
@@ -3382,7 +3409,7 @@ static int __devinit snd_trident_tlb_alloc(trident_t *trident)
* initialize 4D DX chip
*/
-static void snd_trident_stop_all_voices(trident_t *trident)
+static void snd_trident_stop_all_voices(struct snd_trident *trident)
{
outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
@@ -3390,7 +3417,7 @@ static void snd_trident_stop_all_voices(trident_t *trident)
outl(0, TRID_REG(trident, T4D_AINTEN_B));
}
-static int snd_trident_4d_dx_init(trident_t *trident)
+static int snd_trident_4d_dx_init(struct snd_trident *trident)
{
struct pci_dev *pci = trident->pci;
unsigned long end_time;
@@ -3418,7 +3445,7 @@ static int snd_trident_4d_dx_init(trident_t *trident)
goto __dx_ok;
do_delay(trident);
} while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "AC'97 codec ready error\n");
+ dev_err(trident->card->dev, "AC'97 codec ready error\n");
return -EIO;
__dx_ok:
@@ -3430,7 +3457,7 @@ static int snd_trident_4d_dx_init(trident_t *trident)
/*
* initialize 4D NX chip
*/
-static int snd_trident_4d_nx_init(trident_t *trident)
+static int snd_trident_4d_nx_init(struct snd_trident *trident)
{
struct pci_dev *pci = trident->pci;
unsigned long end_time;
@@ -3456,7 +3483,8 @@ static int snd_trident_4d_nx_init(trident_t *trident)
goto __nx_ok;
do_delay(trident);
} while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
+ dev_err(trident->card->dev, "AC'97 codec ready error [0x%x]\n",
+ inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
return -EIO;
__nx_ok:
@@ -3487,7 +3515,7 @@ static int snd_trident_4d_nx_init(trident_t *trident)
/*
* initialize sis7018 chip
*/
-static int snd_trident_sis_init(trident_t *trident)
+static int snd_trident_sis_init(struct snd_trident *trident)
{
int err;
@@ -3508,7 +3536,7 @@ static int snd_trident_sis_init(trident_t *trident)
Description: This routine will create the device specific class for
the 4DWave card. It will also perform basic initialization.
- Paramters: card - which card to create
+ Parameters: card - which card to create
pci - interface to PCI bus resource info
dma1ptr - playback dma buffer
dma2ptr - capture dma buffer
@@ -3518,18 +3546,18 @@ static int snd_trident_sis_init(trident_t *trident)
---------------------------------------------------------------------------*/
-int __devinit snd_trident_create(snd_card_t * card,
+int snd_trident_create(struct snd_card *card,
struct pci_dev *pci,
int pcm_streams,
int pcm_spdif_device,
int max_wavetable_size,
- trident_t ** rtrident)
+ struct snd_trident ** rtrident)
{
- trident_t *trident;
+ struct snd_trident *trident;
int i, err;
- snd_trident_voice_t *voice;
- snd_trident_pcm_mixer_t *tmix;
- static snd_device_ops_t ops = {
+ struct snd_trident_voice *voice;
+ struct snd_trident_pcm_mixer *tmix;
+ static struct snd_device_ops ops = {
.dev_free = snd_trident_dev_free,
};
@@ -3539,14 +3567,15 @@ int __devinit snd_trident_create(snd_card_t * card,
if ((err = pci_enable_device(pci)) < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 30 bits */
- if (pci_set_dma_mask(pci, 0x3fffffff) < 0 ||
- pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) {
- snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
+ dev_err(card->dev,
+ "architecture does not support 30bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
- trident = kcalloc(1, sizeof(*trident), GFP_KERNEL);
+ trident = kzalloc(sizeof(*trident), GFP_KERNEL);
if (trident == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -3577,8 +3606,9 @@ int __devinit snd_trident_create(snd_card_t * card,
}
trident->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
+ KBUILD_MODNAME, trident)) {
+ dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_trident_free(trident);
return -EBUSY;
}
@@ -3641,10 +3671,7 @@ int __devinit snd_trident_create(snd_card_t * card,
snd_trident_enable_eso(trident);
-
- snd_card_set_pm_callback(card, snd_trident_suspend, snd_trident_resume, trident);
snd_trident_proc_init(trident);
- snd_card_set_dev(card, &pci->dev);
*rtrident = trident;
return 0;
}
@@ -3655,13 +3682,13 @@ int __devinit snd_trident_create(snd_card_t * card,
Description: This routine will free the device specific class for
the 4DWave card.
- Paramters: trident - device specific private data for 4DWave card
+ Parameters: trident - device specific private data for 4DWave card
Returns: None.
---------------------------------------------------------------------------*/
-static int snd_trident_free(trident_t *trident)
+static int snd_trident_free(struct snd_trident *trident)
{
snd_trident_free_gameport(trident);
snd_trident_disable_eso(trident);
@@ -3671,6 +3698,8 @@ static int snd_trident_free(trident_t *trident)
else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
}
+ if (trident->irq >= 0)
+ free_irq(trident->irq, trident);
if (trident->tlb.buffer.area) {
outl(0, TRID_REG(trident, NX_TLBC));
if (trident->tlb.memhdr)
@@ -3680,8 +3709,6 @@ static int snd_trident_free(trident_t *trident)
vfree(trident->tlb.shadow_entries);
snd_dma_free_pages(&trident->tlb.buffer);
}
- if (trident->irq >= 0)
- free_irq(trident->irq, (void *)trident);
pci_release_regions(trident->pci);
pci_disable_device(trident->pci);
kfree(trident);
@@ -3693,7 +3720,7 @@ static int snd_trident_free(trident_t *trident)
Description: ISR for Trident 4DWave device
- Paramters: trident - device specific private data for 4DWave card
+ Parameters: trident - device specific private data for 4DWave card
Problems: It seems that Trident chips generates interrupts more than
one time in special cases. The spurious interrupts are
@@ -3706,12 +3733,12 @@ static int snd_trident_free(trident_t *trident)
---------------------------------------------------------------------------*/
-static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_trident_interrupt(int irq, void *dev_id)
{
- trident_t *trident = dev_id;
+ struct snd_trident *trident = dev_id;
unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
int delta;
- snd_trident_voice_t *voice;
+ struct snd_trident_voice *voice;
audio_int = inl(TRID_REG(trident, T4D_MISCINT));
if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
@@ -3794,7 +3821,7 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *
}
if (audio_int & MPU401_IRQ) {
if (trident->rmidi) {
- snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data, regs);
+ snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data);
} else {
inb(TRID_REG(trident, T4D_MPUR0));
}
@@ -3803,31 +3830,9 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *
return IRQ_HANDLED;
}
-/*---------------------------------------------------------------------------
- snd_trident_attach_synthesizer
-
- Description: Attach synthesizer hooks
-
- Paramters: trident - device specific private data for 4DWave card
-
- Returns: None.
-
- ---------------------------------------------------------------------------*/
-int snd_trident_attach_synthesizer(trident_t *trident)
-{
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- if (snd_seq_device_new(trident->card, 1, SNDRV_SEQ_DEV_ID_TRIDENT,
- sizeof(trident_t*), &trident->seq_dev) >= 0) {
- strcpy(trident->seq_dev->name, "4DWave");
- *(trident_t**)SNDRV_SEQ_DEVICE_ARGPTR(trident->seq_dev) = trident;
- }
-#endif
- return 0;
-}
-
-snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port)
+struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port)
{
- snd_trident_voice_t *pvoice;
+ struct snd_trident_voice *pvoice;
unsigned long flags;
int idx;
@@ -3869,10 +3874,12 @@ snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int
return NULL;
}
-void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice)
+EXPORT_SYMBOL(snd_trident_alloc_voice);
+
+void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
{
unsigned long flags;
- void (*private_free)(snd_trident_voice_t *);
+ void (*private_free)(struct snd_trident_voice *);
void *private_data;
if (voice == NULL || !voice->use)
@@ -3897,12 +3904,14 @@ void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice)
private_free(voice);
}
-static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
+EXPORT_SYMBOL(snd_trident_free_voice);
+
+static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max)
{
unsigned int i, val, mask[2] = { 0, 0 };
- snd_assert(v_min <= 63, return);
- snd_assert(v_max <= 63, return);
+ if (snd_BUG_ON(v_min > 63 || v_max > 63))
+ return;
for (i = v_min; i <= v_max; i++)
mask[i >> 5] |= 1 << (i & 0x1f);
if (mask[0]) {
@@ -3917,42 +3926,42 @@ static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min,
}
}
-#ifdef CONFIG_PM
-static int snd_trident_suspend(snd_card_t *card, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int snd_trident_suspend(struct device *dev)
{
- trident_t *trident = card->pm_private_data;
+ struct pci_dev *pci = to_pci_dev(dev);
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct snd_trident *trident = card->private_data;
trident->in_suspend = 1;
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(trident->pcm);
- if (trident->foldback)
- snd_pcm_suspend_all(trident->foldback);
- if (trident->spdif)
- snd_pcm_suspend_all(trident->spdif);
+ snd_pcm_suspend_all(trident->foldback);
+ snd_pcm_suspend_all(trident->spdif);
snd_ac97_suspend(trident->ac97);
- if (trident->ac97_sec)
- snd_ac97_suspend(trident->ac97_sec);
+ snd_ac97_suspend(trident->ac97_sec);
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX:
- case TRIDENT_DEVICE_ID_NX:
- break; /* TODO */
- case TRIDENT_DEVICE_ID_SI7018:
- break;
- }
- pci_disable_device(trident->pci);
+ pci_disable_device(pci);
+ pci_save_state(pci);
+ pci_set_power_state(pci, PCI_D3hot);
return 0;
}
-static int snd_trident_resume(snd_card_t *card)
+static int snd_trident_resume(struct device *dev)
{
- trident_t *trident = card->pm_private_data;
+ struct pci_dev *pci = to_pci_dev(dev);
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct snd_trident *trident = card->private_data;
- pci_enable_device(trident->pci);
- if (pci_set_dma_mask(trident->pci, 0x3fffffff) < 0 ||
- pci_set_consistent_dma_mask(trident->pci, 0x3fffffff) < 0)
- snd_printk(KERN_WARNING "trident: can't set the proper DMA mask\n");
- pci_set_master(trident->pci); /* to be sure */
+ pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ dev_err(dev, "pci_enable_device failed, disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
+ pci_set_master(pci);
switch (trident->device) {
case TRIDENT_DEVICE_ID_DX:
@@ -3967,25 +3976,17 @@ static int snd_trident_resume(snd_card_t *card)
}
snd_ac97_resume(trident->ac97);
- if (trident->ac97_sec)
- snd_ac97_resume(trident->ac97_sec);
+ snd_ac97_resume(trident->ac97_sec);
/* restore some registers */
outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
snd_trident_enable_eso(trident);
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
trident->in_suspend = 0;
return 0;
}
-#endif /* CONFIG_PM */
-EXPORT_SYMBOL(snd_trident_alloc_voice);
-EXPORT_SYMBOL(snd_trident_free_voice);
-EXPORT_SYMBOL(snd_trident_start_voice);
-EXPORT_SYMBOL(snd_trident_stop_voice);
-EXPORT_SYMBOL(snd_trident_write_voice_regs);
-/* trident_memory.c symbols */
-EXPORT_SYMBOL(snd_trident_synth_alloc);
-EXPORT_SYMBOL(snd_trident_synth_free);
-EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
+SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume);
+#endif /* CONFIG_PM_SLEEP */
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 333d3790692..3102a579660 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
* Copyright (c) by Scott McNab <sdm@fractalgraphics.com.au>
*
@@ -23,12 +23,13 @@
*
*/
-#include <sound/driver.h>
#include <asm/io.h>
#include <linux/pci.h>
#include <linux/time.h>
+#include <linux/mutex.h>
+
#include <sound/core.h>
-#include <sound/trident.h>
+#include "trident.h"
/* page arguments of these two macros are Trident page (4096 bytes), not like
* aligned pages in others
@@ -68,13 +69,14 @@
#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) << 1)
/* fill TLB entries -- we need to fill two entries */
-static inline void set_tlb_bus(trident_t *trident, int page, unsigned long ptr, dma_addr_t addr)
+static inline void set_tlb_bus(struct snd_trident *trident, int page,
+ unsigned long ptr, dma_addr_t addr)
{
page <<= 1;
__set_tlb_bus(trident, page, ptr, addr);
__set_tlb_bus(trident, page+1, ptr + SNDRV_TRIDENT_PAGE_SIZE, addr + SNDRV_TRIDENT_PAGE_SIZE);
}
-static inline void set_silent_tlb(trident_t *trident, int page)
+static inline void set_silent_tlb(struct snd_trident *trident, int page)
{
page <<= 1;
__set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
@@ -97,7 +99,8 @@ static inline void set_silent_tlb(trident_t *trident, int page)
#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) * UNIT_PAGES)
/* fill TLB entries -- UNIT_PAGES entries must be filled */
-static inline void set_tlb_bus(trident_t *trident, int page, unsigned long ptr, dma_addr_t addr)
+static inline void set_tlb_bus(struct snd_trident *trident, int page,
+ unsigned long ptr, dma_addr_t addr)
{
int i;
page *= UNIT_PAGES;
@@ -107,7 +110,7 @@ static inline void set_tlb_bus(trident_t *trident, int page, unsigned long ptr,
addr += SNDRV_TRIDENT_PAGE_SIZE;
}
}
-static inline void set_silent_tlb(trident_t *trident, int page)
+static inline void set_silent_tlb(struct snd_trident *trident, int page)
{
int i;
page *= UNIT_PAGES;
@@ -118,7 +121,7 @@ static inline void set_silent_tlb(trident_t *trident, int page)
#endif /* PAGE_SIZE */
/* calculate buffer pointer from offset address */
-static inline void *offset_ptr(trident_t *trident, int offset)
+static inline void *offset_ptr(struct snd_trident *trident, int offset)
{
char *ptr;
ptr = page_to_ptr(trident, get_aligned_page(offset));
@@ -127,16 +130,16 @@ static inline void *offset_ptr(trident_t *trident, int offset)
}
/* first and last (aligned) pages of memory block */
-#define firstpg(blk) (((snd_trident_memblk_arg_t*)snd_util_memblk_argptr(blk))->first_page)
-#define lastpg(blk) (((snd_trident_memblk_arg_t*)snd_util_memblk_argptr(blk))->last_page)
+#define firstpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->first_page)
+#define lastpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->last_page)
/*
* search empty pages which may contain given size
*/
-static snd_util_memblk_t *
-search_empty(snd_util_memhdr_t *hdr, int size)
+static struct snd_util_memblk *
+search_empty(struct snd_util_memhdr *hdr, int size)
{
- snd_util_memblk_t *blk, *prev;
+ struct snd_util_memblk *blk, *prev;
int page, psize;
struct list_head *p;
@@ -144,7 +147,7 @@ search_empty(snd_util_memhdr_t *hdr, int size)
prev = NULL;
page = 0;
list_for_each(p, &hdr->block) {
- blk = list_entry(p, snd_util_memblk_t, list);
+ blk = list_entry(p, struct snd_util_memblk, list);
if (page + psize <= firstpg(blk))
goto __found_pages;
page = lastpg(blk) + 1;
@@ -170,11 +173,11 @@ __found_pages:
static int is_valid_page(unsigned long ptr)
{
if (ptr & ~0x3fffffffUL) {
- snd_printk("max memory size is 1GB!!\n");
+ snd_printk(KERN_ERR "max memory size is 1GB!!\n");
return 0;
}
if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
- snd_printk("page is not aligned\n");
+ snd_printk(KERN_ERR "page is not aligned\n");
return 0;
}
return 1;
@@ -183,71 +186,76 @@ static int is_valid_page(unsigned long ptr)
/*
* page allocation for DMA (Scatter-Gather version)
*/
-static snd_util_memblk_t *
-snd_trident_alloc_sg_pages(trident_t *trident, snd_pcm_substream_t *substream)
+static struct snd_util_memblk *
+snd_trident_alloc_sg_pages(struct snd_trident *trident,
+ struct snd_pcm_substream *substream)
{
- snd_util_memhdr_t *hdr;
- snd_util_memblk_t *blk;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_util_memhdr *hdr;
+ struct snd_util_memblk *blk;
+ struct snd_pcm_runtime *runtime = substream->runtime;
int idx, page;
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
- snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+ if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
+ runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
+ SNDRV_TRIDENT_PAGE_SIZE))
+ return NULL;
hdr = trident->tlb.memhdr;
- snd_assert(hdr != NULL, return NULL);
+ if (snd_BUG_ON(!hdr))
+ return NULL;
- down(&hdr->block_mutex);
+ mutex_lock(&hdr->block_mutex);
blk = search_empty(hdr, runtime->dma_bytes);
if (blk == NULL) {
- up(&hdr->block_mutex);
- return NULL;
- }
- if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) {
- snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk));
- __snd_util_mem_free(hdr, blk);
- up(&hdr->block_mutex);
+ mutex_unlock(&hdr->block_mutex);
return NULL;
}
/* set TLB entries */
idx = 0;
for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
- dma_addr_t addr = sgbuf->table[idx].addr;
- unsigned long ptr = (unsigned long)sgbuf->table[idx].buf;
+ unsigned long ofs = idx << PAGE_SHIFT;
+ dma_addr_t addr = snd_pcm_sgbuf_get_addr(substream, ofs);
+ unsigned long ptr = (unsigned long)
+ snd_pcm_sgbuf_get_ptr(substream, ofs);
if (! is_valid_page(addr)) {
__snd_util_mem_free(hdr, blk);
- up(&hdr->block_mutex);
+ mutex_unlock(&hdr->block_mutex);
return NULL;
}
set_tlb_bus(trident, page, ptr, addr);
}
- up(&hdr->block_mutex);
+ mutex_unlock(&hdr->block_mutex);
return blk;
}
/*
* page allocation for DMA (contiguous version)
*/
-static snd_util_memblk_t *
-snd_trident_alloc_cont_pages(trident_t *trident, snd_pcm_substream_t *substream)
+static struct snd_util_memblk *
+snd_trident_alloc_cont_pages(struct snd_trident *trident,
+ struct snd_pcm_substream *substream)
{
- snd_util_memhdr_t *hdr;
- snd_util_memblk_t *blk;
+ struct snd_util_memhdr *hdr;
+ struct snd_util_memblk *blk;
int page;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_pcm_runtime *runtime = substream->runtime;
dma_addr_t addr;
unsigned long ptr;
- snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+ if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
+ runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
+ SNDRV_TRIDENT_PAGE_SIZE))
+ return NULL;
hdr = trident->tlb.memhdr;
- snd_assert(hdr != NULL, return NULL);
+ if (snd_BUG_ON(!hdr))
+ return NULL;
- down(&hdr->block_mutex);
+ mutex_lock(&hdr->block_mutex);
blk = search_empty(hdr, runtime->dma_bytes);
if (blk == NULL) {
- up(&hdr->block_mutex);
+ mutex_unlock(&hdr->block_mutex);
return NULL;
}
@@ -258,23 +266,24 @@ snd_trident_alloc_cont_pages(trident_t *trident, snd_pcm_substream_t *substream)
ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) {
if (! is_valid_page(addr)) {
__snd_util_mem_free(hdr, blk);
- up(&hdr->block_mutex);
+ mutex_unlock(&hdr->block_mutex);
return NULL;
}
set_tlb_bus(trident, page, ptr, addr);
}
- up(&hdr->block_mutex);
+ mutex_unlock(&hdr->block_mutex);
return blk;
}
/*
* page allocation for DMA
*/
-snd_util_memblk_t *
-snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
+struct snd_util_memblk *
+snd_trident_alloc_pages(struct snd_trident *trident,
+ struct snd_pcm_substream *substream)
{
- snd_assert(trident != NULL, return NULL);
- snd_assert(substream != NULL, return NULL);
+ if (snd_BUG_ON(!trident || !substream))
+ return NULL;
if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG)
return snd_trident_alloc_sg_pages(trident, substream);
else
@@ -285,192 +294,22 @@ snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
/*
* release DMA buffer from page table
*/
-int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk)
+int snd_trident_free_pages(struct snd_trident *trident,
+ struct snd_util_memblk *blk)
{
- snd_util_memhdr_t *hdr;
+ struct snd_util_memhdr *hdr;
int page;
- snd_assert(trident != NULL, return -EINVAL);
- snd_assert(blk != NULL, return -EINVAL);
+ if (snd_BUG_ON(!trident || !blk))
+ return -EINVAL;
hdr = trident->tlb.memhdr;
- down(&hdr->block_mutex);
+ mutex_lock(&hdr->block_mutex);
/* reset TLB entries */
for (page = firstpg(blk); page <= lastpg(blk); page++)
set_silent_tlb(trident, page);
/* free memory block */
__snd_util_mem_free(hdr, blk);
- up(&hdr->block_mutex);
- return 0;
-}
-
-
-/*----------------------------------------------------------------
- * memory allocation using multiple pages (for synth)
- *----------------------------------------------------------------
- * Unlike the DMA allocation above, non-contiguous pages are
- * assigned to TLB.
- *----------------------------------------------------------------*/
-
-/*
- */
-static int synth_alloc_pages(trident_t *hw, snd_util_memblk_t *blk);
-static int synth_free_pages(trident_t *hw, snd_util_memblk_t *blk);
-
-/*
- * allocate a synth sample area
- */
-snd_util_memblk_t *
-snd_trident_synth_alloc(trident_t *hw, unsigned int size)
-{
- snd_util_memblk_t *blk;
- snd_util_memhdr_t *hdr = hw->tlb.memhdr;
-
- down(&hdr->block_mutex);
- blk = __snd_util_mem_alloc(hdr, size);
- if (blk == NULL) {
- up(&hdr->block_mutex);
- return NULL;
- }
- if (synth_alloc_pages(hw, blk)) {
- __snd_util_mem_free(hdr, blk);
- up(&hdr->block_mutex);
- return NULL;
- }
- up(&hdr->block_mutex);
- return blk;
-}
-
-
-/*
- * free a synth sample area
- */
-int
-snd_trident_synth_free(trident_t *hw, snd_util_memblk_t *blk)
-{
- snd_util_memhdr_t *hdr = hw->tlb.memhdr;
-
- down(&hdr->block_mutex);
- synth_free_pages(hw, blk);
- __snd_util_mem_free(hdr, blk);
- up(&hdr->block_mutex);
- return 0;
-}
-
-
-/*
- * reset TLB entry and free kernel page
- */
-static void clear_tlb(trident_t *trident, int page)
-{
- void *ptr = page_to_ptr(trident, page);
- dma_addr_t addr = page_to_addr(trident, page);
- set_silent_tlb(trident, page);
- if (ptr) {
- struct snd_dma_buffer dmab;
- dmab.dev.type = SNDRV_DMA_TYPE_DEV;
- dmab.dev.dev = snd_dma_pci_data(trident->pci);
- dmab.area = ptr;
- dmab.addr = addr;
- dmab.bytes = ALIGN_PAGE_SIZE;
- snd_dma_free_pages(&dmab);
- }
-}
-
-/* check new allocation range */
-static void get_single_page_range(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk, int *first_page_ret, int *last_page_ret)
-{
- struct list_head *p;
- snd_util_memblk_t *q;
- int first_page, last_page;
- first_page = firstpg(blk);
- if ((p = blk->list.prev) != &hdr->block) {
- q = list_entry(p, snd_util_memblk_t, list);
- if (lastpg(q) == first_page)
- first_page++; /* first page was already allocated */
- }
- last_page = lastpg(blk);
- if ((p = blk->list.next) != &hdr->block) {
- q = list_entry(p, snd_util_memblk_t, list);
- if (firstpg(q) == last_page)
- last_page--; /* last page was already allocated */
- }
- *first_page_ret = first_page;
- *last_page_ret = last_page;
-}
-
-/*
- * allocate kernel pages and assign them to TLB
- */
-static int synth_alloc_pages(trident_t *hw, snd_util_memblk_t *blk)
-{
- int page, first_page, last_page;
- struct snd_dma_buffer dmab;
-
- firstpg(blk) = get_aligned_page(blk->offset);
- lastpg(blk) = get_aligned_page(blk->offset + blk->size - 1);
- get_single_page_range(hw->tlb.memhdr, blk, &first_page, &last_page);
-
- /* allocate a kernel page for each Trident page -
- * fortunately Trident page size and kernel PAGE_SIZE is identical!
- */
- for (page = first_page; page <= last_page; page++) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(hw->pci),
- ALIGN_PAGE_SIZE, &dmab) < 0)
- goto __fail;
- if (! is_valid_page(dmab.addr)) {
- snd_dma_free_pages(&dmab);
- goto __fail;
- }
- set_tlb_bus(hw, page, (unsigned long)dmab.area, dmab.addr);
- }
- return 0;
-
-__fail:
- /* release allocated pages */
- last_page = page - 1;
- for (page = first_page; page <= last_page; page++)
- clear_tlb(hw, page);
-
- return -ENOMEM;
-}
-
-/*
- * free pages
- */
-static int synth_free_pages(trident_t *trident, snd_util_memblk_t *blk)
-{
- int page, first_page, last_page;
-
- get_single_page_range(trident->tlb.memhdr, blk, &first_page, &last_page);
- for (page = first_page; page <= last_page; page++)
- clear_tlb(trident, page);
-
+ mutex_unlock(&hdr->block_mutex);
return 0;
}
-
-/*
- * copy_from_user(blk + offset, data, size)
- */
-int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
-{
- int page, nextofs, end_offset, temp, temp1;
-
- offset += blk->offset;
- end_offset = offset + size;
- page = get_aligned_page(offset) + 1;
- do {
- nextofs = aligned_page_offset(page);
- temp = nextofs - offset;
- temp1 = end_offset - offset;
- if (temp1 < temp)
- temp = temp1;
- if (copy_from_user(offset_ptr(trident, offset), data, temp))
- return -EFAULT;
- offset = nextofs;
- data += temp;
- page++;
- } while (offset < end_offset);
- return 0;
-}
-
diff --git a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
deleted file mode 100644
index 5d5a719b058..00000000000
--- a/sound/pci/trident/trident_synth.c
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * Routines for Trident 4DWave NX/DX soundcards - Synthesizer
- * Copyright (c) by Scott McNab <jedi@tartarus.uwa.edu.au>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/driver.h>
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <sound/core.h>
-#include <sound/trident.h>
-#include <sound/seq_device.h>
-
-MODULE_AUTHOR("Scott McNab <jedi@tartarus.uwa.edu.au>");
-MODULE_DESCRIPTION("Routines for Trident 4DWave NX/DX soundcards - Synthesizer");
-MODULE_LICENSE("GPL");
-
-/* linear to log pan conversion table (4.2 channel attenuation format) */
-static unsigned int pan_table[63] = {
- 7959, 7733, 7514, 7301, 7093, 6892, 6697, 6507,
- 6322, 6143, 5968, 5799, 5634, 5475, 5319, 5168,
- 5022, 4879, 4741, 4606, 4475, 4349, 4225, 4105,
- 3989, 3876, 3766, 3659, 3555, 3454, 3356, 3261,
- 3168, 3078, 2991, 2906, 2824, 2744, 2666, 2590,
- 2517, 2445, 2376, 2308, 2243, 2179, 2117, 2057,
- 1999, 1942, 1887, 1833, 1781, 1731, 1682, 1634,
- 1588, 1543, 1499, 1456, 1415, 1375, 1336
-};
-
-#define LOG_TABLE_SIZE 386
-
-/* Linear half-attenuation to log conversion table in the format:
- * {linear volume, logarithmic attenuation equivalent}, ...
- *
- * Provides conversion from a linear half-volume value in the range
- * [0,8192] to a logarithmic attenuation value in the range 0 to 6.02dB.
- * Halving the linear volume is equivalent to an additional 6dB of
- * logarithmic attenuation. The algorithm used in log_from_linear()
- * therefore uses this table as follows:
- *
- * - loop and for every time the volume is less than half the maximum
- * volume (16384), add another 6dB and halve the maximum value used
- * for this comparison.
- * - when the volume is greater than half the maximum volume, take
- * the difference of the volume to half volume (in the range [0,8192])
- * and look up the log_table[] to find the nearest entry.
- * - take the logarithic component of this entry and add it to the
- * resulting attenuation.
- *
- * Thus this routine provides a linear->log conversion for a range of
- * [0,16384] using only 386 table entries
- *
- * Note: although this table stores log attenuation in 8.8 format, values
- * were only calculated for 6 bits fractional precision, since that is
- * the most precision offered by the trident hardware.
- */
-
-static unsigned short log_table[LOG_TABLE_SIZE*2] =
-{
- 4, 0x0604, 19, 0x0600, 34, 0x05fc,
- 49, 0x05f8, 63, 0x05f4, 78, 0x05f0, 93, 0x05ec, 108, 0x05e8,
- 123, 0x05e4, 138, 0x05e0, 153, 0x05dc, 168, 0x05d8, 183, 0x05d4,
- 198, 0x05d0, 213, 0x05cc, 228, 0x05c8, 244, 0x05c4, 259, 0x05c0,
- 274, 0x05bc, 289, 0x05b8, 304, 0x05b4, 320, 0x05b0, 335, 0x05ac,
- 350, 0x05a8, 366, 0x05a4, 381, 0x05a0, 397, 0x059c, 412, 0x0598,
- 428, 0x0594, 443, 0x0590, 459, 0x058c, 474, 0x0588, 490, 0x0584,
- 506, 0x0580, 521, 0x057c, 537, 0x0578, 553, 0x0574, 568, 0x0570,
- 584, 0x056c, 600, 0x0568, 616, 0x0564, 632, 0x0560, 647, 0x055c,
- 663, 0x0558, 679, 0x0554, 695, 0x0550, 711, 0x054c, 727, 0x0548,
- 743, 0x0544, 759, 0x0540, 776, 0x053c, 792, 0x0538, 808, 0x0534,
- 824, 0x0530, 840, 0x052c, 857, 0x0528, 873, 0x0524, 889, 0x0520,
- 906, 0x051c, 922, 0x0518, 938, 0x0514, 955, 0x0510, 971, 0x050c,
- 988, 0x0508, 1004, 0x0504, 1021, 0x0500, 1037, 0x04fc, 1054, 0x04f8,
- 1071, 0x04f4, 1087, 0x04f0, 1104, 0x04ec, 1121, 0x04e8, 1138, 0x04e4,
- 1154, 0x04e0, 1171, 0x04dc, 1188, 0x04d8, 1205, 0x04d4, 1222, 0x04d0,
- 1239, 0x04cc, 1256, 0x04c8, 1273, 0x04c4, 1290, 0x04c0, 1307, 0x04bc,
- 1324, 0x04b8, 1341, 0x04b4, 1358, 0x04b0, 1376, 0x04ac, 1393, 0x04a8,
- 1410, 0x04a4, 1427, 0x04a0, 1445, 0x049c, 1462, 0x0498, 1479, 0x0494,
- 1497, 0x0490, 1514, 0x048c, 1532, 0x0488, 1549, 0x0484, 1567, 0x0480,
- 1584, 0x047c, 1602, 0x0478, 1620, 0x0474, 1637, 0x0470, 1655, 0x046c,
- 1673, 0x0468, 1690, 0x0464, 1708, 0x0460, 1726, 0x045c, 1744, 0x0458,
- 1762, 0x0454, 1780, 0x0450, 1798, 0x044c, 1816, 0x0448, 1834, 0x0444,
- 1852, 0x0440, 1870, 0x043c, 1888, 0x0438, 1906, 0x0434, 1924, 0x0430,
- 1943, 0x042c, 1961, 0x0428, 1979, 0x0424, 1997, 0x0420, 2016, 0x041c,
- 2034, 0x0418, 2053, 0x0414, 2071, 0x0410, 2089, 0x040c, 2108, 0x0408,
- 2127, 0x0404, 2145, 0x0400, 2164, 0x03fc, 2182, 0x03f8, 2201, 0x03f4,
- 2220, 0x03f0, 2239, 0x03ec, 2257, 0x03e8, 2276, 0x03e4, 2295, 0x03e0,
- 2314, 0x03dc, 2333, 0x03d8, 2352, 0x03d4, 2371, 0x03d0, 2390, 0x03cc,
- 2409, 0x03c8, 2428, 0x03c4, 2447, 0x03c0, 2466, 0x03bc, 2485, 0x03b8,
- 2505, 0x03b4, 2524, 0x03b0, 2543, 0x03ac, 2562, 0x03a8, 2582, 0x03a4,
- 2601, 0x03a0, 2621, 0x039c, 2640, 0x0398, 2660, 0x0394, 2679, 0x0390,
- 2699, 0x038c, 2718, 0x0388, 2738, 0x0384, 2758, 0x0380, 2777, 0x037c,
- 2797, 0x0378, 2817, 0x0374, 2837, 0x0370, 2857, 0x036c, 2876, 0x0368,
- 2896, 0x0364, 2916, 0x0360, 2936, 0x035c, 2956, 0x0358, 2976, 0x0354,
- 2997, 0x0350, 3017, 0x034c, 3037, 0x0348, 3057, 0x0344, 3077, 0x0340,
- 3098, 0x033c, 3118, 0x0338, 3138, 0x0334, 3159, 0x0330, 3179, 0x032c,
- 3200, 0x0328, 3220, 0x0324, 3241, 0x0320, 3261, 0x031c, 3282, 0x0318,
- 3303, 0x0314, 3323, 0x0310, 3344, 0x030c, 3365, 0x0308, 3386, 0x0304,
- 3406, 0x0300, 3427, 0x02fc, 3448, 0x02f8, 3469, 0x02f4, 3490, 0x02f0,
- 3511, 0x02ec, 3532, 0x02e8, 3553, 0x02e4, 3575, 0x02e0, 3596, 0x02dc,
- 3617, 0x02d8, 3638, 0x02d4, 3660, 0x02d0, 3681, 0x02cc, 3702, 0x02c8,
- 3724, 0x02c4, 3745, 0x02c0, 3767, 0x02bc, 3788, 0x02b8, 3810, 0x02b4,
- 3831, 0x02b0, 3853, 0x02ac, 3875, 0x02a8, 3896, 0x02a4, 3918, 0x02a0,
- 3940, 0x029c, 3962, 0x0298, 3984, 0x0294, 4006, 0x0290, 4028, 0x028c,
- 4050, 0x0288, 4072, 0x0284, 4094, 0x0280, 4116, 0x027c, 4138, 0x0278,
- 4160, 0x0274, 4182, 0x0270, 4205, 0x026c, 4227, 0x0268, 4249, 0x0264,
- 4272, 0x0260, 4294, 0x025c, 4317, 0x0258, 4339, 0x0254, 4362, 0x0250,
- 4384, 0x024c, 4407, 0x0248, 4430, 0x0244, 4453, 0x0240, 4475, 0x023c,
- 4498, 0x0238, 4521, 0x0234, 4544, 0x0230, 4567, 0x022c, 4590, 0x0228,
- 4613, 0x0224, 4636, 0x0220, 4659, 0x021c, 4682, 0x0218, 4705, 0x0214,
- 4728, 0x0210, 4752, 0x020c, 4775, 0x0208, 4798, 0x0204, 4822, 0x0200,
- 4845, 0x01fc, 4869, 0x01f8, 4892, 0x01f4, 4916, 0x01f0, 4939, 0x01ec,
- 4963, 0x01e8, 4987, 0x01e4, 5010, 0x01e0, 5034, 0x01dc, 5058, 0x01d8,
- 5082, 0x01d4, 5106, 0x01d0, 5130, 0x01cc, 5154, 0x01c8, 5178, 0x01c4,
- 5202, 0x01c0, 5226, 0x01bc, 5250, 0x01b8, 5274, 0x01b4, 5299, 0x01b0,
- 5323, 0x01ac, 5347, 0x01a8, 5372, 0x01a4, 5396, 0x01a0, 5420, 0x019c,
- 5445, 0x0198, 5469, 0x0194, 5494, 0x0190, 5519, 0x018c, 5543, 0x0188,
- 5568, 0x0184, 5593, 0x0180, 5618, 0x017c, 5643, 0x0178, 5668, 0x0174,
- 5692, 0x0170, 5717, 0x016c, 5743, 0x0168, 5768, 0x0164, 5793, 0x0160,
- 5818, 0x015c, 5843, 0x0158, 5868, 0x0154, 5894, 0x0150, 5919, 0x014c,
- 5945, 0x0148, 5970, 0x0144, 5995, 0x0140, 6021, 0x013c, 6047, 0x0138,
- 6072, 0x0134, 6098, 0x0130, 6124, 0x012c, 6149, 0x0128, 6175, 0x0124,
- 6201, 0x0120, 6227, 0x011c, 6253, 0x0118, 6279, 0x0114, 6305, 0x0110,
- 6331, 0x010c, 6357, 0x0108, 6384, 0x0104, 6410, 0x0100, 6436, 0x00fc,
- 6462, 0x00f8, 6489, 0x00f4, 6515, 0x00f0, 6542, 0x00ec, 6568, 0x00e8,
- 6595, 0x00e4, 6621, 0x00e0, 6648, 0x00dc, 6675, 0x00d8, 6702, 0x00d4,
- 6728, 0x00d0, 6755, 0x00cc, 6782, 0x00c8, 6809, 0x00c4, 6836, 0x00c0,
- 6863, 0x00bc, 6890, 0x00b8, 6917, 0x00b4, 6945, 0x00b0, 6972, 0x00ac,
- 6999, 0x00a8, 7027, 0x00a4, 7054, 0x00a0, 7081, 0x009c, 7109, 0x0098,
- 7136, 0x0094, 7164, 0x0090, 7192, 0x008c, 7219, 0x0088, 7247, 0x0084,
- 7275, 0x0080, 7303, 0x007c, 7331, 0x0078, 7359, 0x0074, 7387, 0x0070,
- 7415, 0x006c, 7443, 0x0068, 7471, 0x0064, 7499, 0x0060, 7527, 0x005c,
- 7556, 0x0058, 7584, 0x0054, 7613, 0x0050, 7641, 0x004c, 7669, 0x0048,
- 7698, 0x0044, 7727, 0x0040, 7755, 0x003c, 7784, 0x0038, 7813, 0x0034,
- 7842, 0x0030, 7870, 0x002c, 7899, 0x0028, 7928, 0x0024, 7957, 0x0020,
- 7986, 0x001c, 8016, 0x0018, 8045, 0x0014, 8074, 0x0010, 8103, 0x000c,
- 8133, 0x0008, 8162, 0x0004, 8192, 0x0000
-};
-
-static unsigned short lookup_volume_table( unsigned short value )
-{
- /* This code is an optimised version of:
- * int i = 0;
- * while( volume_table[i*2] < value )
- * i++;
- * return volume_table[i*2+1];
- */
- unsigned short *ptr = log_table;
- while( *ptr < value )
- ptr += 2;
- return *(ptr+1);
-}
-
-/* this function calculates a 8.8 fixed point logarithmic attenuation
- * value from a linear volume value in the range 0 to 16384 */
-static unsigned short log_from_linear( unsigned short value )
-{
- if (value >= 16384)
- return 0x0000;
- if (value) {
- unsigned short result = 0;
- int v, c;
- for( c = 0, v = 8192; c < 14; c++, v >>= 1 ) {
- if( value >= v ) {
- result += lookup_volume_table( (value - v) << c );
- return result;
- }
- result += 0x0605; /* 6.0205 (result of -20*log10(0.5)) */
- }
- }
- return 0xffff;
-}
-
-/*
- * Sample handling operations
- */
-
-static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position);
-static void sample_stop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_stop_mode_t mode);
-static void sample_freq(trident_t * trident, snd_trident_voice_t * voice, snd_seq_frequency_t freq);
-static void sample_volume(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_volume_t * volume);
-static void sample_loop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_loop_t * loop);
-static void sample_pos(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position);
-static void sample_private1(trident_t * trident, snd_trident_voice_t * voice, unsigned char *data);
-
-static snd_trident_sample_ops_t sample_ops =
-{
- sample_start,
- sample_stop,
- sample_freq,
- sample_volume,
- sample_loop,
- sample_pos,
- sample_private1
-};
-
-static void snd_trident_simple_init(snd_trident_voice_t * voice)
-{
- //voice->handler_wave = interrupt_wave;
- //voice->handler_volume = interrupt_volume;
- //voice->handler_effect = interrupt_effect;
- //voice->volume_change = NULL;
- voice->sample_ops = &sample_ops;
-}
-
-static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position)
-{
- simple_instrument_t *simple;
- snd_seq_kinstr_t *instr;
- unsigned long flags;
- unsigned int loop_start, loop_end, sample_start, sample_end, start_offset;
- unsigned int value;
- unsigned int shift = 0;
-
- instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
- if (instr == NULL)
- return;
- voice->instr = instr->instr; /* copy ID to speedup aliases */
- simple = KINSTR_DATA(instr);
-
- spin_lock_irqsave(&trident->reg_lock, flags);
-
- if (trident->device == TRIDENT_DEVICE_ID_SI7018)
- voice->GVSel = 1; /* route to Wave volume */
-
- voice->CTRL = 0;
- voice->Alpha = 0;
- voice->FMS = 0;
-
- loop_start = simple->loop_start >> 4;
- loop_end = simple->loop_end >> 4;
- sample_start = (simple->start + position) >> 4;
- if( sample_start >= simple->size )
- sample_start = simple->start >> 4;
- sample_end = simple->size;
- start_offset = position >> 4;
-
- if (simple->format & SIMPLE_WAVE_16BIT) {
- voice->CTRL |= 8;
- shift++;
- }
- if (simple->format & SIMPLE_WAVE_STEREO) {
- voice->CTRL |= 4;
- shift++;
- }
- if (!(simple->format & SIMPLE_WAVE_UNSIGNED))
- voice->CTRL |= 2;
-
- voice->LBA = simple->address.memory;
-
- if (simple->format & SIMPLE_WAVE_LOOP) {
- voice->CTRL |= 1;
- voice->LBA += loop_start << shift;
- if( start_offset >= loop_start ) {
- voice->CSO = start_offset - loop_start;
- voice->negCSO = 0;
- } else {
- voice->CSO = loop_start - start_offset;
- voice->negCSO = 1;
- }
- voice->ESO = loop_end - loop_start - 1;
- } else {
- voice->LBA += start_offset << shift;
- voice->CSO = sample_start;
- voice->ESO = sample_end - 1;
- voice->negCSO = 0;
- }
-
- if (voice->flags & SNDRV_TRIDENT_VFLG_RUNNING) {
- snd_trident_stop_voice(trident, voice->number);
- voice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING;
- }
-
- /* set CSO sign */
- value = inl(TRID_REG(trident, T4D_SIGN_CSO_A));
- if( voice->negCSO ) {
- value |= 1 << (voice->number&31);
- } else {
- value &= ~(1 << (voice->number&31));
- }
- outl(value,TRID_REG(trident, T4D_SIGN_CSO_A));
-
- voice->Attribute = 0;
- snd_trident_write_voice_regs(trident, voice);
- snd_trident_start_voice(trident, voice->number);
- voice->flags |= SNDRV_TRIDENT_VFLG_RUNNING;
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- snd_seq_instr_free_use(trident->synth.ilist, instr);
-}
-
-static void sample_stop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_stop_mode_t mode)
-{
- unsigned long flags;
-
- if (!(voice->flags & SNDRV_TRIDENT_VFLG_RUNNING))
- return;
-
- switch (mode) {
- default:
- spin_lock_irqsave(&trident->reg_lock, flags);
- snd_trident_stop_voice(trident, voice->number);
- voice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING;
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- break;
- case SAMPLE_STOP_LOOP: /* disable loop only */
- voice->CTRL &= ~1;
- spin_lock_irqsave(&trident->reg_lock, flags);
- outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outw((((voice->CTRL << 12) | (voice->EC & 0x0fff)) & 0xffff), CH_GVSEL_PAN_VOL_CTRL_EC);
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- break;
- }
-}
-
-static void sample_freq(trident_t * trident, snd_trident_voice_t * voice, snd_seq_frequency_t freq)
-{
- unsigned long flags;
- freq >>= 4;
-
- spin_lock_irqsave(&trident->reg_lock, flags);
- if (freq == 44100)
- voice->Delta = 0xeb3;
- else if (freq == 8000)
- voice->Delta = 0x2ab;
- else if (freq == 48000)
- voice->Delta = 0x1000;
- else
- voice->Delta = (((freq << 12) + freq) / 48000) & 0x0000ffff;
-
- outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- if (trident->device == TRIDENT_DEVICE_ID_NX) {
- outb((unsigned char) voice->Delta, TRID_REG(trident, CH_NX_DELTA_CSO + 3));
- outb((unsigned char) (voice->Delta >> 8), TRID_REG(trident, CH_NX_DELTA_ESO + 3));
- } else {
- outw((unsigned short) voice->Delta, TRID_REG(trident, CH_DX_ESO_DELTA));
- }
-
- spin_unlock_irqrestore(&trident->reg_lock, flags);
-}
-
-static void sample_volume(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_volume_t * volume)
-{
- unsigned long flags;
- unsigned short value;
-
- spin_lock_irqsave(&trident->reg_lock, flags);
- voice->GVSel = 0; /* use global music volume */
- voice->FMC = 0x03; /* fixme: can we do something useful with FMC? */
- if (volume->volume >= 0) {
- volume->volume &= 0x3fff;
- /* linear volume -> logarithmic attenuation conversion
- * uses EC register for greater resolution (6.6 bits) than Vol register (5.3 bits)
- * Vol register used when additional attenuation is required */
- voice->RVol = 0;
- voice->CVol = 0;
- value = log_from_linear( volume->volume );
- voice->Vol = 0;
- voice->EC = (value & 0x3fff) >> 2;
- if (value > 0x3fff) {
- voice->EC |= 0xfc0;
- if (value < 0x5f00 )
- voice->Vol = ((value >> 8) - 0x3f) << 5;
- else {
- voice->Vol = 0x3ff;
- voice->EC = 0xfff;
- }
- }
- }
- if (volume->lr >= 0) {
- volume->lr &= 0x3fff;
- /* approximate linear pan by attenuating channels */
- if (volume->lr >= 0x2000) { /* attenuate left (pan right) */
- value = 0x3fff - volume->lr;
- for (voice->Pan = 0; voice->Pan < 63; voice->Pan++ )
- if (value >= pan_table[voice->Pan] )
- break;
- } else { /* attenuate right (pan left) */
- for (voice->Pan = 0; voice->Pan < 63; voice->Pan++ )
- if ((unsigned int)volume->lr >= pan_table[voice->Pan] )
- break;
- voice->Pan |= 0x40;
- }
- }
- outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outl((voice->GVSel << 31) | ((voice->Pan & 0x0000007f) << 24) |
- ((voice->Vol & 0x000000ff) << 16) | ((voice->CTRL & 0x0000000f) << 12) |
- (voice->EC & 0x00000fff), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
- value = ((voice->FMC & 0x03) << 14) | ((voice->RVol & 0x7f) << 7) | (voice->CVol & 0x7f);
- outw(value, TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
- spin_unlock_irqrestore(&trident->reg_lock, flags);
-}
-
-static void sample_loop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_loop_t * loop)
-{
- unsigned long flags;
- simple_instrument_t *simple;
- snd_seq_kinstr_t *instr;
- unsigned int loop_start, loop_end;
-
- instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
- if (instr == NULL)
- return;
- voice->instr = instr->instr; /* copy ID to speedup aliases */
- simple = KINSTR_DATA(instr);
-
- loop_start = loop->start >> 4;
- loop_end = loop->end >> 4;
-
- spin_lock_irqsave(&trident->reg_lock, flags);
-
- voice->LBA = simple->address.memory + loop_start;
- voice->CSO = 0;
- voice->ESO = loop_end - loop_start - 1;
-
- outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outb((voice->LBA >> 16), TRID_REG(trident, CH_LBA + 2));
- outw((voice->LBA & 0xffff), TRID_REG(trident, CH_LBA));
- if (trident->device == TRIDENT_DEVICE_ID_NX) {
- outb((voice->ESO >> 16), TRID_REG(trident, CH_NX_DELTA_ESO + 2));
- outw((voice->ESO & 0xffff), TRID_REG(trident, CH_NX_DELTA_ESO));
- outb((voice->CSO >> 16), TRID_REG(trident, CH_NX_DELTA_CSO + 2));
- outw((voice->CSO & 0xffff), TRID_REG(trident, CH_NX_DELTA_CSO));
- } else {
- outw((voice->ESO & 0xffff), TRID_REG(trident, CH_DX_ESO_DELTA + 2));
- outw((voice->CSO & 0xffff), TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2));
- }
-
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- snd_seq_instr_free_use(trident->synth.ilist, instr);
-}
-
-static void sample_pos(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position)
-{
- unsigned long flags;
- simple_instrument_t *simple;
- snd_seq_kinstr_t *instr;
- unsigned int value;
-
- instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
- if (instr == NULL)
- return;
- voice->instr = instr->instr; /* copy ID to speedup aliases */
- simple = KINSTR_DATA(instr);
-
- spin_lock_irqsave(&trident->reg_lock, flags);
-
- if (simple->format & SIMPLE_WAVE_LOOP) {
- if( position >= simple->loop_start ) {
- voice->CSO = (position - simple->loop_start) >> 4;
- voice->negCSO = 0;
- } else {
- voice->CSO = (simple->loop_start - position) >> 4;
- voice->negCSO = 1;
- }
- } else {
- voice->CSO = position >> 4;
- voice->negCSO = 0;
- }
-
- /* set CSO sign */
- value = inl(TRID_REG(trident, T4D_SIGN_CSO_A));
- if( voice->negCSO ) {
- value |= 1 << (voice->number&31);
- } else {
- value &= ~(1 << (voice->number&31));
- }
- outl(value,TRID_REG(trident, T4D_SIGN_CSO_A));
-
-
- outb((unsigned char) voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- if (trident->device == TRIDENT_DEVICE_ID_NX) {
- outw((voice->CSO & 0xffff), TRID_REG(trident, CH_NX_DELTA_CSO));
- outb((voice->CSO >> 16), TRID_REG(trident, CH_NX_DELTA_CSO + 2));
- } else {
- outw((voice->CSO & 0xffff), TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
- }
-
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- snd_seq_instr_free_use(trident->synth.ilist, instr);
-}
-
-static void sample_private1(trident_t * trident, snd_trident_voice_t * voice, unsigned char *data)
-{
-}
-
-/*
- * Memory management / sample loading
- */
-
-static int snd_trident_simple_put_sample(void *private_data, simple_instrument_t * instr,
- char __user *data, long len, int atomic)
-{
- trident_t *trident = private_data;
- int size = instr->size;
- int shift = 0;
-
- if (instr->format & SIMPLE_WAVE_BACKWARD ||
- instr->format & SIMPLE_WAVE_BIDIR ||
- instr->format & SIMPLE_WAVE_ULAW)
- return -EINVAL; /* not supported */
-
- if (instr->format & SIMPLE_WAVE_16BIT)
- shift++;
- if (instr->format & SIMPLE_WAVE_STEREO)
- shift++;
- size <<= shift;
-
- if (trident->synth.current_size + size > trident->synth.max_size)
- return -ENOMEM;
-
- if (!access_ok(VERIFY_READ, data, size))
- return -EFAULT;
-
- if (trident->tlb.entries) {
- snd_util_memblk_t *memblk;
- memblk = snd_trident_synth_alloc(trident, size);
- if (memblk == NULL)
- return -ENOMEM;
- if (snd_trident_synth_copy_from_user(trident, memblk, 0, data, size) ) {
- snd_trident_synth_free(trident, memblk);
- return -EFAULT;
- }
- instr->address.ptr = (unsigned char*)memblk;
- instr->address.memory = memblk->offset;
- } else {
- struct snd_dma_buffer dmab;
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
- size, &dmab) < 0)
- return -ENOMEM;
-
- if (copy_from_user(dmab.area, data, size)) {
- snd_dma_free_pages(&dmab);
- return -EFAULT;
- }
- instr->address.ptr = dmab.area;
- instr->address.memory = dmab.addr;
- }
-
- trident->synth.current_size += size;
- return 0;
-}
-
-static int snd_trident_simple_get_sample(void *private_data, simple_instrument_t * instr,
- char __user *data, long len, int atomic)
-{
- //trident_t *trident = private_data;
- int size = instr->size;
- int shift = 0;
-
- if (instr->format & SIMPLE_WAVE_16BIT)
- shift++;
- if (instr->format & SIMPLE_WAVE_STEREO)
- shift++;
- size <<= shift;
-
- if (!access_ok(VERIFY_WRITE, data, size))
- return -EFAULT;
-
- /* FIXME: not implemented yet */
-
- return -EBUSY;
-}
-
-static int snd_trident_simple_remove_sample(void *private_data, simple_instrument_t * instr,
- int atomic)
-{
- trident_t *trident = private_data;
- int size = instr->size;
-
- if (instr->format & SIMPLE_WAVE_16BIT)
- size <<= 1;
- if (instr->format & SIMPLE_WAVE_STEREO)
- size <<= 1;
-
- if (trident->tlb.entries) {
- snd_util_memblk_t *memblk = (snd_util_memblk_t*)instr->address.ptr;
- if (memblk)
- snd_trident_synth_free(trident, memblk);
- else
- return -EFAULT;
- } else {
- struct snd_dma_buffer dmab;
- dmab.dev.type = SNDRV_DMA_TYPE_DEV;
- dmab.dev.dev = snd_dma_pci_data(trident->pci);
- dmab.area = instr->address.ptr;
- dmab.addr = instr->address.memory;
- dmab.bytes = size;
- snd_dma_free_pages(&dmab);
- }
-
- trident->synth.current_size -= size;
- if (trident->synth.current_size < 0) /* shouldn't need this check... */
- trident->synth.current_size = 0;
-
- return 0;
-}
-
-static void select_instrument(trident_t * trident, snd_trident_voice_t * v)
-{
- snd_seq_kinstr_t *instr;
- instr = snd_seq_instr_find(trident->synth.ilist, &v->instr, 0, 1);
- if (instr != NULL) {
- if (instr->ops) {
- if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE))
- snd_trident_simple_init(v);
- }
- snd_seq_instr_free_use(trident->synth.ilist, instr);
- }
-}
-
-/*
-
- */
-
-static void event_sample(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_stop)
- v->sample_ops->sample_stop(p->trident, v, SAMPLE_STOP_IMMEDIATELY);
- v->instr.std = ev->data.sample.param.sample.std;
- if (v->instr.std & 0xff000000) { /* private instrument */
- v->instr.std &= 0x00ffffff;
- v->instr.std |= (unsigned int)ev->source.client << 24;
- }
- v->instr.bank = ev->data.sample.param.sample.bank;
- v->instr.prg = ev->data.sample.param.sample.prg;
- select_instrument(p->trident, v);
-}
-
-static void event_cluster(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_stop)
- v->sample_ops->sample_stop(p->trident, v, SAMPLE_STOP_IMMEDIATELY);
- v->instr.cluster = ev->data.sample.param.cluster.cluster;
- select_instrument(p->trident, v);
-}
-
-static void event_start(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_start)
- v->sample_ops->sample_start(p->trident, v, ev->data.sample.param.position);
-}
-
-static void event_stop(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_stop)
- v->sample_ops->sample_stop(p->trident, v, ev->data.sample.param.stop_mode);
-}
-
-static void event_freq(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_freq)
- v->sample_ops->sample_freq(p->trident, v, ev->data.sample.param.frequency);
-}
-
-static void event_volume(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_volume)
- v->sample_ops->sample_volume(p->trident, v, &ev->data.sample.param.volume);
-}
-
-static void event_loop(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_loop)
- v->sample_ops->sample_loop(p->trident, v, &ev->data.sample.param.loop);
-}
-
-static void event_position(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_pos)
- v->sample_ops->sample_pos(p->trident, v, ev->data.sample.param.position);
-}
-
-static void event_private1(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
-{
- if (v->sample_ops && v->sample_ops->sample_private1)
- v->sample_ops->sample_private1(p->trident, v, (unsigned char *) &ev->data.sample.param.raw8);
-}
-
-typedef void (trident_sample_event_handler_t) (snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v);
-
-static trident_sample_event_handler_t *trident_sample_event_handlers[9] =
-{
- event_sample,
- event_cluster,
- event_start,
- event_stop,
- event_freq,
- event_volume,
- event_loop,
- event_position,
- event_private1
-};
-
-static void snd_trident_sample_event(snd_seq_event_t * ev, snd_trident_port_t * p)
-{
- int idx, voice;
- trident_t *trident = p->trident;
- snd_trident_voice_t *v;
- unsigned long flags;
-
- idx = ev->type - SNDRV_SEQ_EVENT_SAMPLE;
- if (idx < 0 || idx > 8)
- return;
- for (voice = 0; voice < 64; voice++) {
- v = &trident->synth.voices[voice];
- if (v->use && v->client == ev->source.client &&
- v->port == ev->source.port &&
- v->index == ev->data.sample.channel) {
- spin_lock_irqsave(&trident->event_lock, flags);
- trident_sample_event_handlers[idx] (ev, p, v);
- spin_unlock_irqrestore(&trident->event_lock, flags);
- return;
- }
- }
-}
-
-/*
-
- */
-
-static void snd_trident_synth_free_voices(trident_t * trident, int client, int port)
-{
- int idx;
- snd_trident_voice_t *voice;
-
- for (idx = 0; idx < 32; idx++) {
- voice = &trident->synth.voices[idx];
- if (voice->use && voice->client == client && voice->port == port)
- snd_trident_free_voice(trident, voice);
- }
-}
-
-static int snd_trident_synth_use(void *private_data, snd_seq_port_subscribe_t * info)
-{
- snd_trident_port_t *port = (snd_trident_port_t *) private_data;
- trident_t *trident = port->trident;
- snd_trident_voice_t *voice;
- unsigned int idx;
- unsigned long flags;
-
- if (info->voices > 32)
- return -EINVAL;
- spin_lock_irqsave(&trident->reg_lock, flags);
- for (idx = 0; idx < info->voices; idx++) {
- voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_SYNTH, info->sender.client, info->sender.port);
- if (voice == NULL) {
- snd_trident_synth_free_voices(trident, info->sender.client, info->sender.port);
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- return -EBUSY;
- }
- voice->index = idx;
- voice->Vol = 0x3ff;
- voice->EC = 0x0fff;
- }
-#if 0
- for (idx = 0; idx < info->midi_voices; idx++) {
- port->midi_has_voices = 1;
- voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_MIDI, info->sender.client, info->sender.port);
- if (voice == NULL) {
- snd_trident_synth_free_voices(trident, info->sender.client, info->sender.port);
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- return -EBUSY;
- }
- voice->Vol = 0x3ff;
- voice->EC = 0x0fff;
- }
-#endif
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- return 0;
-}
-
-static int snd_trident_synth_unuse(void *private_data, snd_seq_port_subscribe_t * info)
-{
- snd_trident_port_t *port = (snd_trident_port_t *) private_data;
- trident_t *trident = port->trident;
- unsigned long flags;
-
- spin_lock_irqsave(&trident->reg_lock, flags);
- snd_trident_synth_free_voices(trident, info->sender.client, info->sender.port);
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- return 0;
-}
-
-/*
-
- */
-
-static void snd_trident_synth_free_private_instruments(snd_trident_port_t * p, int client)
-{
- snd_seq_instr_header_t ifree;
-
- memset(&ifree, 0, sizeof(ifree));
- ifree.cmd = SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE;
- snd_seq_instr_list_free_cond(p->trident->synth.ilist, &ifree, client, 0);
-}
-
-static int snd_trident_synth_event_input(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
-{
- snd_trident_port_t *p = (snd_trident_port_t *) private_data;
-
- if (p == NULL)
- return -EINVAL;
- if (ev->type >= SNDRV_SEQ_EVENT_SAMPLE &&
- ev->type <= SNDRV_SEQ_EVENT_SAMPLE_PRIVATE1) {
- snd_trident_sample_event(ev, p);
- return 0;
- }
- if (ev->source.client == SNDRV_SEQ_CLIENT_SYSTEM &&
- ev->source.port == SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE) {
- if (ev->type == SNDRV_SEQ_EVENT_CLIENT_EXIT) {
- snd_trident_synth_free_private_instruments(p, ev->data.addr.client);
- return 0;
- }
- }
- if (direct) {
- if (ev->type >= SNDRV_SEQ_EVENT_INSTR_BEGIN) {
- snd_seq_instr_event(&p->trident->synth.simple_ops.kops,
- p->trident->synth.ilist, ev,
- p->trident->synth.seq_client, atomic, hop);
- return 0;
- }
- }
- return 0;
-}
-
-static void snd_trident_synth_instr_notify(void *private_data,
- snd_seq_kinstr_t * instr,
- int what)
-{
- int idx;
- trident_t *trident = private_data;
- snd_trident_voice_t *pvoice;
- unsigned long flags;
-
- spin_lock_irqsave(&trident->event_lock, flags);
- for (idx = 0; idx < 64; idx++) {
- pvoice = &trident->synth.voices[idx];
- if (pvoice->use && !memcmp(&pvoice->instr, &instr->instr, sizeof(pvoice->instr))) {
- if (pvoice->sample_ops && pvoice->sample_ops->sample_stop) {
- pvoice->sample_ops->sample_stop(trident, pvoice, SAMPLE_STOP_IMMEDIATELY);
- } else {
- snd_trident_stop_voice(trident, pvoice->number);
- pvoice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING;
- }
- }
- }
- spin_unlock_irqrestore(&trident->event_lock, flags);
-}
-
-/*
-
- */
-
-static void snd_trident_synth_free_port(void *private_data)
-{
- snd_trident_port_t *p = (snd_trident_port_t *) private_data;
-
- if (p)
- snd_midi_channel_free_set(p->chset);
-}
-
-static int snd_trident_synth_create_port(trident_t * trident, int idx)
-{
- snd_trident_port_t *p;
- snd_seq_port_callback_t callbacks;
- char name[32];
- char *str;
- int result;
-
- p = &trident->synth.seq_ports[idx];
- p->chset = snd_midi_channel_alloc_set(16);
- if (p->chset == NULL)
- return -ENOMEM;
- p->chset->private_data = p;
- p->trident = trident;
- p->client = trident->synth.seq_client;
-
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.owner = THIS_MODULE;
- callbacks.use = snd_trident_synth_use;
- callbacks.unuse = snd_trident_synth_unuse;
- callbacks.event_input = snd_trident_synth_event_input;
- callbacks.private_free = snd_trident_synth_free_port;
- callbacks.private_data = p;
-
- str = "???";
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX: str = "Trident 4DWave-DX"; break;
- case TRIDENT_DEVICE_ID_NX: str = "Trident 4DWave-NX"; break;
- case TRIDENT_DEVICE_ID_SI7018: str = "SiS 7018"; break;
- }
- sprintf(name, "%s port %i", str, idx);
- p->chset->port = snd_seq_event_port_attach(trident->synth.seq_client,
- &callbacks,
- SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
- SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
- SNDRV_SEQ_PORT_TYPE_SYNTH,
- 16, 0,
- name);
- if (p->chset->port < 0) {
- result = p->chset->port;
- snd_trident_synth_free_port(p);
- return result;
- }
- p->port = p->chset->port;
- return 0;
-}
-
-/*
-
- */
-
-static int snd_trident_synth_new_device(snd_seq_device_t *dev)
-{
- trident_t *trident;
- int client, i;
- snd_seq_client_callback_t callbacks;
- snd_seq_client_info_t cinfo;
- snd_seq_port_subscribe_t sub;
- snd_simple_ops_t *simpleops;
- char *str;
-
- trident = *(trident_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (trident == NULL)
- return -EINVAL;
-
- trident->synth.seq_client = -1;
-
- /* allocate new client */
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.private_data = trident;
- callbacks.allow_output = callbacks.allow_input = 1;
- client = trident->synth.seq_client =
- snd_seq_create_kernel_client(trident->card, 1, &callbacks);
- if (client < 0)
- return client;
-
- /* change name of client */
- memset(&cinfo, 0, sizeof(cinfo));
- cinfo.client = client;
- cinfo.type = KERNEL_CLIENT;
- str = "???";
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX: str = "Trident 4DWave-DX"; break;
- case TRIDENT_DEVICE_ID_NX: str = "Trident 4DWave-NX"; break;
- case TRIDENT_DEVICE_ID_SI7018: str = "SiS 7018"; break;
- }
- sprintf(cinfo.name, str);
- snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
-
- for (i = 0; i < 4; i++)
- snd_trident_synth_create_port(trident, i);
-
- trident->synth.ilist = snd_seq_instr_list_new();
- if (trident->synth.ilist == NULL) {
- snd_seq_delete_kernel_client(client);
- trident->synth.seq_client = -1;
- return -ENOMEM;
- }
- trident->synth.ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT;
-
- simpleops = &trident->synth.simple_ops;
- snd_seq_simple_init(simpleops, trident, NULL);
- simpleops->put_sample = snd_trident_simple_put_sample;
- simpleops->get_sample = snd_trident_simple_get_sample;
- simpleops->remove_sample = snd_trident_simple_remove_sample;
- simpleops->notify = snd_trident_synth_instr_notify;
-
- memset(&sub, 0, sizeof(sub));
- sub.sender.client = SNDRV_SEQ_CLIENT_SYSTEM;
- sub.sender.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
- sub.dest.client = client;
- sub.dest.port = 0;
- snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &sub);
-
- return 0;
-}
-
-static int snd_trident_synth_delete_device(snd_seq_device_t *dev)
-{
- trident_t *trident;
-
- trident = *(trident_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (trident == NULL)
- return -EINVAL;
-
- if (trident->synth.seq_client >= 0) {
- snd_seq_delete_kernel_client(trident->synth.seq_client);
- trident->synth.seq_client = -1;
- }
- if (trident->synth.ilist)
- snd_seq_instr_list_free(&trident->synth.ilist);
- return 0;
-}
-
-static int __init alsa_trident_synth_init(void)
-{
- static snd_seq_dev_ops_t ops =
- {
- snd_trident_synth_new_device,
- snd_trident_synth_delete_device
- };
-
- return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_TRIDENT, &ops,
- sizeof(trident_t*));
-}
-
-static void __exit alsa_trident_synth_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_TRIDENT);
-}
-
-module_init(alsa_trident_synth_init)
-module_exit(alsa_trident_synth_exit)