diff options
Diffstat (limited to 'sound/pci/trident')
| -rw-r--r-- | sound/pci/trident/trident.c | 53 | ||||
| -rw-r--r-- | sound/pci/trident/trident.h | 444 | ||||
| -rw-r--r-- | sound/pci/trident/trident_main.c | 201 | ||||
| -rw-r--r-- | sound/pci/trident/trident_memory.c | 217 |
4 files changed, 600 insertions, 315 deletions
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index d94b16ffb38..d852458caf3 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -24,9 +24,9 @@ #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@perex.cz>, <audio@tridentmicro.com>"); @@ -47,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}; @@ -62,7 +62,7 @@ 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[] = { +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), @@ -73,8 +73,8 @@ static struct pci_device_id snd_trident_ids[] = { 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; struct snd_card *card; @@ -89,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], @@ -148,8 +149,9 @@ 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, - MPU401_INFO_INTEGRATED, - trident->irq, 0, &trident->rmidi)) < 0) { + MPU401_INFO_INTEGRATED | + MPU401_INFO_IRQ_HOOK, + -1, &trident->rmidi)) < 0) { snd_card_free(card); return err; } @@ -165,32 +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), -#ifdef CONFIG_PM - .suspend = snd_trident_suspend, - .resume = snd_trident_resume, + .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 71138ff9b31..1272c18a254 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -35,12 +35,13 @@ #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/tlv.h> -#include <sound/trident.h> +#include "trident.h" #include <sound/asoundef.h> #include <asm/io.h> @@ -68,40 +69,40 @@ 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 @@ -155,7 +156,8 @@ static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned sho } if (count == 0 && !trident->ac97_detect) { - snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", + dev_err(trident->card->dev, + "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data); data = 0; } @@ -496,12 +498,17 @@ void snd_trident_write_voice_regs(struct snd_trident * 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 } @@ -583,7 +590,7 @@ static void snd_trident_write_vol_reg(struct snd_trident * trident, 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); + /* 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; @@ -1050,7 +1057,7 @@ static int snd_trident_capture_prepare(struct snd_pcm_substream *substream) 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 @@ -1590,7 +1597,10 @@ static int snd_trident_trigger(struct snd_pcm_substream *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; @@ -2162,8 +2172,8 @@ static struct snd_pcm_ops snd_trident_spdif_7018_ops = { ---------------------------------------------------------------------------*/ -int __devinit snd_trident_pcm(struct snd_trident * trident, - int device, struct snd_pcm ** rpcm) +int snd_trident_pcm(struct snd_trident *trident, + int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; @@ -2220,8 +2230,8 @@ int __devinit snd_trident_pcm(struct snd_trident * trident, ---------------------------------------------------------------------------*/ -int __devinit snd_trident_foldback_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) { struct snd_pcm *foldback; int err; @@ -2277,8 +2287,8 @@ int __devinit snd_trident_foldback_pcm(struct snd_trident * trident, ---------------------------------------------------------------------------*/ -int __devinit snd_trident_spdif_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) { struct snd_pcm *spdif; int err; @@ -2362,7 +2372,7 @@ static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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), @@ -2425,7 +2435,7 @@ static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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), @@ -2458,7 +2468,7 @@ static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new 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, @@ -2520,7 +2530,7 @@ static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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, @@ -2570,7 +2580,7 @@ static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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", @@ -2628,7 +2638,7 @@ static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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", @@ -2639,7 +2649,7 @@ static struct snd_kcontrol_new snd_trident_vol_music_control __devinitdata = .tlv = { .p = db_scale_gvol }, }; -static struct snd_kcontrol_new 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", @@ -2706,7 +2716,7 @@ static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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", @@ -2770,7 +2780,7 @@ static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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", @@ -2827,7 +2837,7 @@ static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol, static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); -static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata = +static struct snd_kcontrol_new snd_trident_pcm_rvol_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Reverb Playback Volume", @@ -2883,7 +2893,7 @@ static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new 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", @@ -2928,7 +2938,8 @@ static int snd_trident_pcm_mixer_build(struct snd_trident *trident, { 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; @@ -2943,7 +2954,8 @@ static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_tr { 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); @@ -2961,7 +2973,7 @@ static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_tr ---------------------------------------------------------------------------*/ -static int __devinit snd_trident_mixer(struct snd_trident * trident, int pcm_spdif_device) +static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device) { struct snd_ac97_template _ac97; struct snd_card *card = trident->card; @@ -3002,13 +3014,15 @@ static int __devinit snd_trident_mixer(struct snd_trident * trident, int pcm_spd _ac97.num = 1; err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec); if (err < 0) - snd_printk(KERN_ERR "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 { struct snd_ac97 *mc97; err = snd_ac97_modem(trident->card, &_ac97, &mc97); if (err < 0) - snd_printk(KERN_ERR "snd_ac97_modem returned error %i\n", err); + dev_err(trident->card->dev, + "snd_ac97_modem returned error %i\n", err); } #endif } @@ -3128,7 +3142,8 @@ static unsigned char snd_trident_gameport_read(struct gameport *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)); } @@ -3136,7 +3151,8 @@ static void snd_trident_gameport_trigger(struct gameport *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)); } @@ -3145,7 +3161,8 @@ static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes 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; @@ -3161,7 +3178,8 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode) { 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: @@ -3176,13 +3194,14 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode) } } -int __devinit snd_trident_create_gameport(struct snd_trident *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; } @@ -3210,7 +3229,7 @@ static inline void snd_trident_free_gameport(struct snd_trident *chip) } } #else -int __devinit snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; } +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 */ @@ -3255,7 +3274,8 @@ static int snd_trident_sis_reset(struct snd_trident *trident) goto __si7018_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, 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 { @@ -3314,7 +3334,7 @@ static void snd_trident_proc_read(struct snd_info_entry *entry, } } -static void __devinit snd_trident_proc_init(struct snd_trident * trident) +static void snd_trident_proc_init(struct snd_trident *trident) { struct snd_info_entry *entry; const char *s = "trident"; @@ -3343,7 +3363,7 @@ static int snd_trident_dev_free(struct snd_device *device) ---------------------------------------------------------------------------*/ -static int __devinit snd_trident_tlb_alloc(struct snd_trident *trident) +static int snd_trident_tlb_alloc(struct snd_trident *trident) { int i; @@ -3352,7 +3372,7 @@ static int __devinit snd_trident_tlb_alloc(struct snd_trident *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*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4); @@ -3360,13 +3380,14 @@ static int __devinit snd_trident_tlb_alloc(struct snd_trident *trident) /* allocate shadow TLB page table (virtual addresses) */ 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); @@ -3424,7 +3445,7 @@ static int snd_trident_4d_dx_init(struct snd_trident *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: @@ -3462,7 +3483,8 @@ static int snd_trident_4d_nx_init(struct snd_trident *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: @@ -3524,7 +3546,7 @@ static int snd_trident_sis_init(struct snd_trident *trident) ---------------------------------------------------------------------------*/ -int __devinit snd_trident_create(struct snd_card *card, +int snd_trident_create(struct snd_card *card, struct pci_dev *pci, int pcm_streams, int pcm_spdif_device, @@ -3545,9 +3567,10 @@ int __devinit snd_trident_create(struct snd_card *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, DMA_30BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_30BIT_MASK) < 0) { - snd_printk(KERN_ERR "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; } @@ -3584,8 +3607,8 @@ int __devinit snd_trident_create(struct snd_card *card, trident->port = pci_resource_start(pci, 0); if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED, - "Trident Audio", trident)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + KBUILD_MODNAME, trident)) { + dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); snd_trident_free(trident); return -EBUSY; } @@ -3649,7 +3672,6 @@ int __devinit snd_trident_create(struct snd_card *card, snd_trident_enable_eso(trident); snd_trident_proc_init(trident); - snd_card_set_dev(card, &pci->dev); *rtrident = trident; return 0; } @@ -3676,6 +3698,8 @@ static int snd_trident_free(struct snd_trident *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) @@ -3685,8 +3709,6 @@ static int snd_trident_free(struct snd_trident *trident) vfree(trident->tlb.shadow_entries); snd_dma_free_pages(&trident->tlb.buffer); } - if (trident->irq >= 0) - free_irq(trident->irq, trident); pci_release_regions(trident->pci); pci_disable_device(trident->pci); kfree(trident); @@ -3888,8 +3910,8 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor { 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]) { @@ -3904,10 +3926,11 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor } } -#ifdef CONFIG_PM -int snd_trident_suspend(struct pci_dev *pci, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int snd_trident_suspend(struct device *dev) { - struct snd_card *card = pci_get_drvdata(pci); + 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; @@ -3921,20 +3944,20 @@ int snd_trident_suspend(struct pci_dev *pci, pm_message_t state) pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); + pci_set_power_state(pci, PCI_D3hot); return 0; } -int snd_trident_resume(struct pci_dev *pci) +static int snd_trident_resume(struct device *dev) { - struct snd_card *card = pci_get_drvdata(pci); + struct pci_dev *pci = to_pci_dev(dev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_trident *trident = card->private_data; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "trident: pci_enable_device failed, " - "disabling device\n"); + dev_err(dev, "pci_enable_device failed, disabling device\n"); snd_card_disconnect(card); return -EIO; } @@ -3964,4 +3987,6 @@ int snd_trident_resume(struct pci_dev *pci) trident->in_suspend = 0; return 0; } -#endif /* CONFIG_PM */ + +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 df9b487fa17..3102a579660 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c @@ -29,7 +29,7 @@ #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 @@ -194,11 +194,14 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, 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; @@ -208,18 +211,14 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, mutex_unlock(&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); - 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); mutex_unlock(&hdr->block_mutex); @@ -245,9 +244,13 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, 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; mutex_lock(&hdr->block_mutex); blk = search_empty(hdr, runtime->dma_bytes); @@ -279,8 +282,8 @@ 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 @@ -297,8 +300,8 @@ int snd_trident_free_pages(struct snd_trident *trident, 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; mutex_lock(&hdr->block_mutex); @@ -310,181 +313,3 @@ int snd_trident_free_pages(struct snd_trident *trident, mutex_unlock(&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(struct snd_trident *hw, struct snd_util_memblk *blk); -static int synth_free_pages(struct snd_trident *hw, struct snd_util_memblk *blk); - -/* - * allocate a synth sample area - */ -struct snd_util_memblk * -snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size) -{ - struct snd_util_memblk *blk; - struct snd_util_memhdr *hdr = hw->tlb.memhdr; - - mutex_lock(&hdr->block_mutex); - blk = __snd_util_mem_alloc(hdr, size); - if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); - return NULL; - } - if (synth_alloc_pages(hw, blk)) { - __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); - return NULL; - } - mutex_unlock(&hdr->block_mutex); - return blk; -} - -EXPORT_SYMBOL(snd_trident_synth_alloc); - -/* - * free a synth sample area - */ -int -snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk) -{ - struct snd_util_memhdr *hdr = hw->tlb.memhdr; - - mutex_lock(&hdr->block_mutex); - synth_free_pages(hw, blk); - __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); - return 0; -} - -EXPORT_SYMBOL(snd_trident_synth_free); - -/* - * reset TLB entry and free kernel page - */ -static void clear_tlb(struct snd_trident *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(struct snd_util_memhdr *hdr, - struct snd_util_memblk *blk, - int *first_page_ret, int *last_page_ret) -{ - struct list_head *p; - struct snd_util_memblk *q; - int first_page, last_page; - first_page = firstpg(blk); - if ((p = blk->list.prev) != &hdr->block) { - q = list_entry(p, struct snd_util_memblk, 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, struct snd_util_memblk, 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(struct snd_trident *hw, struct snd_util_memblk *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(struct snd_trident *trident, struct snd_util_memblk *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); - - return 0; -} - -/* - * copy_from_user(blk + offset, data, size) - */ -int snd_trident_synth_copy_from_user(struct snd_trident *trident, - struct snd_util_memblk *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; -} - -EXPORT_SYMBOL(snd_trident_synth_copy_from_user); |
