15455Sdg// SPDX-License-Identifier: GPL-2.0-or-later 21541Srgrimes/* 31541Srgrimes * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 41549Srgrimes * Driver EMU10K1X chips 51549Srgrimes * 61549Srgrimes * Parts of this code were adapted from audigyls.c driver which is 71549Srgrimes * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> 81541Srgrimes * 91549Srgrimes * BUGS: 101541Srgrimes * -- 111541Srgrimes * 121541Srgrimes * TODO: 131541Srgrimes * 141541Srgrimes * Chips (SB0200 model): 151541Srgrimes * - EMU10K1X-DBQ 161541Srgrimes * - STAC 9708T 171541Srgrimes */ 181541Srgrimes#include <linux/init.h> 191541Srgrimes#include <linux/interrupt.h> 201541Srgrimes#include <linux/pci.h> 211541Srgrimes#include <linux/dma-mapping.h> 2258705Scharnier#include <linux/slab.h> 231541Srgrimes#include <linux/module.h> 241541Srgrimes#include <sound/core.h> 251541Srgrimes#include <sound/initval.h> 261541Srgrimes#include <sound/pcm.h> 271541Srgrimes#include <sound/ac97_codec.h> 281541Srgrimes#include <sound/info.h> 291541Srgrimes#include <sound/rawmidi.h> 301541Srgrimes 311541SrgrimesMODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>"); 321541SrgrimesMODULE_DESCRIPTION("EMU10K1X"); 331541SrgrimesMODULE_LICENSE("GPL"); 341541Srgrimes 351541Srgrimes// module parameters (see "Module Parameters") 361541Srgrimesstatic int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 371541Srgrimesstatic char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 381541Srgrimesstatic bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 391541Srgrimes 401541Srgrimesmodule_param_array(index, int, NULL, 0444); 411817SdgMODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard."); 421541Srgrimesmodule_param_array(id, charp, NULL, 0444); 431541SrgrimesMODULE_PARM_DESC(id, "ID string for the EMU10K1X soundcard."); 441541Srgrimesmodule_param_array(enable, bool, NULL, 0444); 451541SrgrimesMODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard."); 461541Srgrimes 471541Srgrimes 485455Sdg// some definitions were borrowed from emu10k1 driver as they seem to be the same 491541Srgrimes/************************************************************************************************/ 501541Srgrimes/* PCI function 0 registers, address = <val> + PCIBASE0 */ 511541Srgrimes/************************************************************************************************/ 521541Srgrimes 531541Srgrimes#define PTR 0x00 /* Indexed register set pointer register */ 545455Sdg /* NOTE: The CHANNELNUM and ADDRESS words can */ 555455Sdg /* be modified independently of each other. */ 565455Sdg 571541Srgrimes#define DATA 0x04 /* Indexed register set data register */ 585455Sdg 591541Srgrimes#define IPR 0x08 /* Global interrupt pending register */ 601541Srgrimes /* Clear pending interrupts by writing a 1 to */ 611541Srgrimes /* the relevant bits and zero to the other bits */ 621541Srgrimes#define IPR_MIDITRANSBUFEMPTY 0x00000001 /* MIDI UART transmit buffer empty */ 631541Srgrimes#define IPR_MIDIRECVBUFEMPTY 0x00000002 /* MIDI UART receive buffer empty */ 641541Srgrimes#define IPR_CH_0_LOOP 0x00000800 /* Channel 0 loop */ 651541Srgrimes#define IPR_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */ 661541Srgrimes#define IPR_CAP_0_LOOP 0x00080000 /* Channel capture loop */ 671541Srgrimes#define IPR_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */ 681541Srgrimes 691541Srgrimes#define INTE 0x0c /* Interrupt enable register */ 701541Srgrimes#define INTE_MIDITXENABLE 0x00000001 /* Enable MIDI transmit-buffer-empty interrupts */ 711541Srgrimes#define INTE_MIDIRXENABLE 0x00000002 /* Enable MIDI receive-buffer-empty interrupts */ 721541Srgrimes#define INTE_CH_0_LOOP 0x00000800 /* Channel 0 loop */ 73116226Sobrien#define INTE_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */ 74116226Sobrien#define INTE_CAP_0_LOOP 0x00080000 /* Channel capture loop */ 75116226Sobrien#define INTE_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */ 76116226Sobrien 771541Srgrimes#define HCFG 0x14 /* Hardware config register */ 781541Srgrimes 7976949Sjhb#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */ 8076166Smarkm /* NOTE: This should generally never be used. */ 8176166Smarkm#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */ 821549Srgrimes /* Should be set to 1 when the EMU10K1 is */ 831549Srgrimes /* completely initialized. */ 8476949Sjhb#define GPIO 0x18 /* Defaults: 00001080-Analog, 00001000-SPDIF. */ 8512662Sdg 8676949Sjhb 871541Srgrimes#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */ 881541Srgrimes 8912662Sdg#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */ 9012662Sdg 9112662Sdg/********************************************************************************************************/ 9212662Sdg/* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers */ 931541Srgrimes/********************************************************************************************************/ 941541Srgrimes#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */ 954207Sdg /* One list entry: 4 bytes for DMA address, 969507Sdg * 4 bytes for period_size << 16. 979507Sdg * One list entry is 8 bytes long. 9812662Sdg * One list entry for each period in the buffer. 991541Srgrimes */ 100120722Salc#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ 101120722Salc#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ 102120722Salc#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ 103120722Salc#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */ 104120722Salc#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */ 105120722Salc#define PLAYBACK_UNKNOWN1 0x07 106120722Salc#define PLAYBACK_UNKNOWN2 0x08 107120722Salc 108120722Salc/* Only one capture channel supported */ 109120722Salc#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */ 110120722Salc#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */ 11192727Salfred#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */ 112120722Salc#define CAPTURE_UNKNOWN 0x13 1131549Srgrimes 11432585Sdyson/* From 0x20 - 0x3f, last samples played on each channel */ 11532585Sdyson 1161549Srgrimes#define TRIGGER_CHANNEL 0x40 /* Trigger channel playback */ 1171549Srgrimes#define TRIGGER_CHANNEL_0 0x00000001 /* Trigger channel 0 */ 11834202Sdyson#define TRIGGER_CHANNEL_1 0x00000002 /* Trigger channel 1 */ 11934202Sdyson#define TRIGGER_CHANNEL_2 0x00000004 /* Trigger channel 2 */ 12034202Sdyson#define TRIGGER_CAPTURE 0x00000100 /* Trigger capture channel */ 12134202Sdyson 12234202Sdyson#define ROUTING 0x41 /* Setup sound routing ? */ 12334202Sdyson#define ROUTING_FRONT_LEFT 0x00000001 12434202Sdyson#define ROUTING_FRONT_RIGHT 0x00000002 12534202Sdyson#define ROUTING_REAR_LEFT 0x00000004 12634202Sdyson#define ROUTING_REAR_RIGHT 0x00000008 12792588Sgreen#define ROUTING_CENTER_LFE 0x00010000 12834202Sdyson 12934202Sdyson#define SPCS0 0x42 /* SPDIF output Channel Status 0 register */ 13034202Sdyson 13142957Sdillon#define SPCS1 0x43 /* SPDIF output Channel Status 1 register */ 13234202Sdyson 13334202Sdyson#define SPCS2 0x44 /* SPDIF output Channel Status 2 register */ 134100456Salc 13538799Sdfr#define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */ 13634202Sdyson#define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */ 137100456Salc#define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */ 13834202Sdyson#define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */ 13934202Sdyson#define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */ 14034202Sdyson#define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */ 14142957Sdillon#define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */ 14234202Sdyson#define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */ 14334202Sdyson#define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */ 14492588Sgreen#define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */ 14534202Sdyson#define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */ 14692588Sgreen#define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */ 14734202Sdyson#define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */ 14834202Sdyson#define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */ 14934202Sdyson#define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */ 15034202Sdyson#define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */ 15134202Sdyson#define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */ 15234202Sdyson#define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */ 153116695Salc#define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */ 15434202Sdyson#define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */ 155113761Salc#define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */ 15634202Sdyson#define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */ 157113761Salc#define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */ 158100456Salc 15934202Sdyson#define SPDIF_SELECT 0x45 /* Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF */ 160100456Salc 16134202Sdyson/* This is the MPU port on the card */ 162113761Salc#define MUDATA 0x47 16334202Sdyson#define MUCMD 0x48 16434202Sdyson#define MUSTAT MUCMD 16534202Sdyson 16634202Sdyson/* From 0x50 - 0x5f, last samples captured */ 16734202Sdyson 16834202Sdyson/* 16934202Sdyson * The hardware has 3 channels for playback and 1 for capture. 17079224Sdillon * - channel 0 is the front channel 17134202Sdyson * - channel 1 is the rear channel 17234202Sdyson * - channel 2 is the center/lfe channel 173123879Salc * Volume is controlled by the AC97 for the front and rear channels by 174123879Salc * the PCM Playback Volume, Sigmatel Surround Playback Volume and 17534202Sdyson * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects 17634202Sdyson * the front/rear channel mixing in the REAR OUT jack. When using the 17734202Sdyson * 4-Speaker Stereo, both front and rear channels will be mixed in the 17834202Sdyson * REAR OUT. 17934202Sdyson * The center/lfe channel has no volume control and cannot be muted during 1801541Srgrimes * playback. 18151488Sdillon */ 18251488Sdillon 18351488Sdillonstruct emu10k1x_voice { 18451488Sdillon struct emu10k1x *emu; 18551488Sdillon int number; 18651488Sdillon int use; 18751488Sdillon 18851488Sdillon struct emu10k1x_pcm *epcm; 18951488Sdillon}; 1901541Srgrimes 1911541Srgrimesstruct emu10k1x_pcm { 19258634Scharnier struct emu10k1x *emu; 1931541Srgrimes struct snd_pcm_substream *substream; 1941541Srgrimes struct emu10k1x_voice *voice; 1951541Srgrimes unsigned short running; 1961541Srgrimes}; 1971541Srgrimes 1981541Srgrimesstruct emu10k1x_midi { 1991541Srgrimes struct emu10k1x *emu; 2001541Srgrimes struct snd_rawmidi *rmidi; 2011541Srgrimes struct snd_rawmidi_substream *substream_input; 2021541Srgrimes struct snd_rawmidi_substream *substream_output; 2031541Srgrimes unsigned int midi_mode; 2041541Srgrimes spinlock_t input_lock; 20579224Sdillon spinlock_t output_lock; 2061541Srgrimes spinlock_t open_lock; 2071541Srgrimes int tx_enable, rx_enable; 20876827Salfred int port; 20976827Salfred int ipr_tx, ipr_rx; 2101541Srgrimes void (*interrupt)(struct emu10k1x *emu, unsigned int status); 2115455Sdg}; 212116650Salc 21394977Salc// definition of the chip-specific record 21432702Sdysonstruct emu10k1x { 2155455Sdg struct snd_card *card; 2165455Sdg struct pci_dev *pci; 21734202Sdyson 21832702Sdyson unsigned long port; 21934202Sdyson int irq; 2201541Srgrimes 22134202Sdyson unsigned char revision; /* chip revision */ 22294977Salc unsigned int serial; /* serial number */ 22395021Salc unsigned short model; /* subsystem id */ 2241541Srgrimes 2255455Sdg spinlock_t emu_lock; 2261541Srgrimes spinlock_t voice_lock; 2271541Srgrimes 2285455Sdg struct snd_ac97 *ac97; 2295455Sdg struct snd_pcm *pcm; 2301541Srgrimes 23151488Sdillon struct emu10k1x_voice voices[3]; 23295021Salc struct emu10k1x_voice capture_voice; 23395021Salc u32 spdif_bits[3]; // SPDIF out setup 23495021Salc 23595021Salc struct snd_dma_buffer *dma_buffer; 23695021Salc 23794977Salc struct emu10k1x_midi midi; 23894977Salc}; 23994977Salc 240123879Salc/* hardware definition */ 24194977Salcstatic const struct snd_pcm_hardware snd_emu10k1x_playback_hw = { 24294977Salc .info = (SNDRV_PCM_INFO_MMAP | 24394977Salc SNDRV_PCM_INFO_INTERLEAVED | 24494977Salc SNDRV_PCM_INFO_BLOCK_TRANSFER | 24595021Salc SNDRV_PCM_INFO_MMAP_VALID), 24632585Sdyson .formats = SNDRV_PCM_FMTBIT_S16_LE, 24732585Sdyson .rates = SNDRV_PCM_RATE_48000, 24832585Sdyson .rate_min = 48000, 24932585Sdyson .rate_max = 48000, 25032585Sdyson .channels_min = 2, 25132585Sdyson .channels_max = 2, 25232585Sdyson .buffer_bytes_max = (32*1024), 25332585Sdyson .period_bytes_min = 64, 25432585Sdyson .period_bytes_max = (16*1024), 25534202Sdyson .periods_min = 2, 25632585Sdyson .periods_max = 8, 25734202Sdyson .fifo_size = 0, 258123879Salc}; 25995764Salc 26032585Sdysonstatic const struct snd_pcm_hardware snd_emu10k1x_capture_hw = { 26132585Sdyson .info = (SNDRV_PCM_INFO_MMAP | 26232585Sdyson SNDRV_PCM_INFO_INTERLEAVED | 26332585Sdyson SNDRV_PCM_INFO_BLOCK_TRANSFER | 26432585Sdyson SNDRV_PCM_INFO_MMAP_VALID), 26594981Salc .formats = SNDRV_PCM_FMTBIT_S16_LE, 26694981Salc .rates = SNDRV_PCM_RATE_48000, 26794981Salc .rate_min = 48000, 26832585Sdyson .rate_max = 48000, 26934202Sdyson .channels_min = 2, 27034202Sdyson .channels_max = 2, 2711541Srgrimes .buffer_bytes_max = (32*1024), 2727695Sdg .period_bytes_min = 64, 27334202Sdyson .period_bytes_max = (16*1024), 27432702Sdyson .periods_min = 2, 27534202Sdyson .periods_max = 2, 27620054Sdyson .fifo_size = 0, 27737563Sbde}; 27820054Sdyson 27920054Sdysonstatic unsigned int snd_emu10k1x_ptr_read(struct emu10k1x * emu, 28020449Sdyson unsigned int reg, 28132286Sdyson unsigned int chn) 28232286Sdyson{ 28332286Sdyson unsigned long flags; 28432286Sdyson unsigned int regptr, val; 28586236Sdillon 28686236Sdillon regptr = (reg << 16) | chn; 28786236Sdillon 28886236Sdillon spin_lock_irqsave(&emu->emu_lock, flags); 28995701Salc outl(regptr, emu->port + PTR); 29095701Salc val = inl(emu->port + DATA); 29132286Sdyson spin_unlock_irqrestore(&emu->emu_lock, flags); 292123879Salc return val; 293120183Salc} 294123879Salc 29586236Sdillonstatic void snd_emu10k1x_ptr_write(struct emu10k1x *emu, 29638135Sdfr unsigned int reg, 29732286Sdyson unsigned int chn, 29892588Sgreen unsigned int data) 2991541Srgrimes{ 3001541Srgrimes unsigned int regptr; 3011541Srgrimes unsigned long flags; 3021541Srgrimes 30334202Sdyson regptr = (reg << 16) | chn; 3041541Srgrimes 3055455Sdg spin_lock_irqsave(&emu->emu_lock, flags); 3065455Sdg outl(regptr, emu->port + PTR); 3071541Srgrimes outl(data, emu->port + DATA); 30834202Sdyson spin_unlock_irqrestore(&emu->emu_lock, flags); 30934202Sdyson} 3101541Srgrimes 31142957Sdillonstatic void snd_emu10k1x_intr_enable(struct emu10k1x *emu, unsigned int intrenb) 31242957Sdillon{ 31342957Sdillon unsigned long flags; 31434202Sdyson unsigned int intr_enable; 31534202Sdyson 31632585Sdyson spin_lock_irqsave(&emu->emu_lock, flags); 31732585Sdyson intr_enable = inl(emu->port + INTE) | intrenb; 31842957Sdillon outl(intr_enable, emu->port + INTE); 31942957Sdillon spin_unlock_irqrestore(&emu->emu_lock, flags); 32042957Sdillon} 32142957Sdillon 32234202Sdysonstatic void snd_emu10k1x_intr_disable(struct emu10k1x *emu, unsigned int intrenb) 32334202Sdyson{ 32441322Sdg unsigned long flags; 32598849Sken unsigned int intr_enable; 32698849Sken 327111977Sken spin_lock_irqsave(&emu->emu_lock, flags); 328111977Sken intr_enable = inl(emu->port + INTE) & ~intrenb; 329111977Sken outl(intr_enable, emu->port + INTE); 330111977Sken spin_unlock_irqrestore(&emu->emu_lock, flags); 331111977Sken} 332111977Sken 333111977Skenstatic void snd_emu10k1x_gpio_write(struct emu10k1x *emu, unsigned int value) 33498849Sken{ 335105466Salc unsigned long flags; 33698849Sken 337111977Sken spin_lock_irqsave(&emu->emu_lock, flags); 338111977Sken outl(value, emu->port + GPIO); 33998849Sken spin_unlock_irqrestore(&emu->emu_lock, flags); 34098849Sken} 34198849Sken 342105466Salcstatic void snd_emu10k1x_pcm_free_substream(struct snd_pcm_runtime *runtime) 343116552Salc{ 34498849Sken kfree(runtime->private_data); 34598849Sken} 34698849Sken 3471541Srgrimesstatic void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voice *voice) 34842957Sdillon{ 34942957Sdillon struct emu10k1x_pcm *epcm; 35042957Sdillon 35142957Sdillon epcm = voice->epcm; 35242957Sdillon if (!epcm) 35358634Scharnier return; 35442957Sdillon if (epcm->substream == NULL) 35542957Sdillon return; 35642957Sdillon#if 0 35742957Sdillon dev_info(emu->card->dev, 35842957Sdillon "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n", 35942957Sdillon epcm->substream->ops->pointer(epcm->substream), 36042957Sdillon snd_pcm_lib_period_bytes(epcm->substream), 36142957Sdillon snd_pcm_lib_buffer_bytes(epcm->substream)); 3621541Srgrimes#endif 36342957Sdillon snd_pcm_period_elapsed(epcm->substream); 364100742Salc} 36534202Sdyson 366108068Salc/* open callback */ 367108068Salcstatic int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream) 368108068Salc{ 36942957Sdillon struct emu10k1x *chip = snd_pcm_substream_chip(substream); 370123879Salc struct emu10k1x_pcm *epcm; 37134202Sdyson struct snd_pcm_runtime *runtime = substream->runtime; 3721541Srgrimes int err; 3731541Srgrimes 37492029Seivind err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 3757695Sdg if (err < 0) 37641322Sdg return err; 37779263Sdillon err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64); 37841322Sdg if (err < 0) 37916268Sdyson return err; 38051488Sdillon 38134202Sdyson epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); 382100742Salc if (epcm == NULL) 38334202Sdyson return -ENOMEM; 38490935Ssilby epcm->emu = chip; 3855455Sdg epcm->substream = substream; 3865455Sdg 38743086Sdillon runtime->private_data = epcm; 38842957Sdillon runtime->private_free = snd_emu10k1x_pcm_free_substream; 38942957Sdillon 39042957Sdillon runtime->hw = snd_emu10k1x_playback_hw; 39142957Sdillon 39242957Sdillon return 0; 39342957Sdillon} 39438799Sdfr 395100742Salc/* close callback */ 39634202Sdysonstatic int snd_emu10k1x_playback_close(struct snd_pcm_substream *substream) 39734202Sdyson{ 3985455Sdg return 0; 3995455Sdg} 40033936Sdyson 4011541Srgrimes/* hw_params callback */ 4021541Srgrimesstatic int snd_emu10k1x_pcm_hw_params(struct snd_pcm_substream *substream, 40342957Sdillon struct snd_pcm_hw_params *hw_params) 40442957Sdillon{ 40551488Sdillon struct snd_pcm_runtime *runtime = substream->runtime; 40651488Sdillon struct emu10k1x_pcm *epcm = runtime->private_data; 40742957Sdillon 40851488Sdillon if (! epcm->voice) { 40934202Sdyson epcm->voice = &epcm->emu->voices[substream->pcm->device]; 41034202Sdyson epcm->voice->use = 1; 4118585Sdg epcm->voice->epcm = epcm; 4128585Sdg } 41310988Sdyson 4141541Srgrimes return 0; 4155455Sdg} 4161541Srgrimes 41751488Sdillon/* hw_free callback */ 41851488Sdillonstatic int snd_emu10k1x_pcm_hw_free(struct snd_pcm_substream *substream) 41951488Sdillon{ 42051488Sdillon struct snd_pcm_runtime *runtime = substream->runtime; 42151488Sdillon struct emu10k1x_pcm *epcm; 42234202Sdyson 42334202Sdyson if (runtime->private_data == NULL) 42490935Ssilby return 0; 4251541Srgrimes 4261541Srgrimes epcm = runtime->private_data; 4271541Srgrimes 42832585Sdyson if (epcm->voice) { 4295455Sdg epcm->voice->use = 0; 43042957Sdillon epcm->voice->epcm = NULL; 43151488Sdillon epcm->voice = NULL; 43251488Sdillon } 43351488Sdillon 43451488Sdillon return 0; 43551488Sdillon} 43651488Sdillon 43751488Sdillon/* prepare callback */ 43842957Sdillonstatic int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream) 43951488Sdillon{ 4401541Srgrimes struct emu10k1x *emu = snd_pcm_substream_chip(substream); 4411549Srgrimes struct snd_pcm_runtime *runtime = substream->runtime; 44215819Sdyson struct emu10k1x_pcm *epcm = runtime->private_data; 44349338Salc int voice = epcm->voice->number; 4441541Srgrimes u32 *table_base = (u32 *)(emu->dma_buffer->area+1024*voice); 44549338Salc u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); 44615819Sdyson int i; 44715819Sdyson 44832702Sdyson for(i = 0; i < runtime->periods; i++) { 44934202Sdyson *table_base++=runtime->dma_addr+(i*period_size_bytes); 45032702Sdyson *table_base++=period_size_bytes<<16; 45132702Sdyson } 45232702Sdyson 45334202Sdyson snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer->addr+1024*voice); 45432702Sdyson snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19); 45532702Sdyson snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0); 45615819Sdyson snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0); 457119357Salc snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN1, voice, 0); 458119357Salc snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN2, voice, 0); 459119357Salc snd_emu10k1x_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr); 460119357Salc 461119357Salc snd_emu10k1x_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16); 462119357Salc 463119357Salc return 0; 464119357Salc} 46515819Sdyson 46651488Sdillon/* trigger callback */ 46751488Sdillonstatic int snd_emu10k1x_pcm_trigger(struct snd_pcm_substream *substream, 46815819Sdyson int cmd) 46915819Sdyson{ 47051488Sdillon struct emu10k1x *emu = snd_pcm_substream_chip(substream); 47115819Sdyson struct snd_pcm_runtime *runtime = substream->runtime; 472100413Salc struct emu10k1x_pcm *epcm = runtime->private_data; 47346349Salc int channel = epcm->voice->number; 47446349Salc int result = 0; 47546349Salc 47646349Salc /* 47746349Salc dev_dbg(emu->card->dev, 47892029Seivind "trigger - emu10k1x = 0x%x, cmd = %i, pointer = %d\n", 47924678Speter (int)emu, cmd, (int)substream->ops->pointer(substream)); 48015819Sdyson */ 48115819Sdyson 48292029Seivind switch (cmd) { 48392029Seivind case SNDRV_PCM_TRIGGER_START: 48415819Sdyson if(runtime->periods == 2) 48515819Sdyson snd_emu10k1x_intr_enable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel); 48616058Sdyson else 48761081Sdillon snd_emu10k1x_intr_enable(emu, INTE_CH_0_LOOP << channel); 48816058Sdyson epcm->running = 1; 48915819Sdyson snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|(TRIGGER_CHANNEL_0<<channel)); 49015819Sdyson break; 491125838Salc case SNDRV_PCM_TRIGGER_STOP: 49215819Sdyson epcm->running = 0; 49315819Sdyson snd_emu10k1x_intr_disable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel); 49415819Sdyson snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CHANNEL_0<<channel)); 49515819Sdyson break; 49615819Sdyson default: 49715819Sdyson result = -EINVAL; 498100413Salc break; 49915819Sdyson } 50015819Sdyson return result; 50115819Sdyson} 502119357Salc 503119357Salc/* pointer callback */ 5041541Srgrimesstatic snd_pcm_uframes_t 5055455Sdgsnd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream) 5065455Sdg{ 5075455Sdg struct emu10k1x *emu = snd_pcm_substream_chip(substream); 5085455Sdg struct snd_pcm_runtime *runtime = substream->runtime; 5095455Sdg struct emu10k1x_pcm *epcm = runtime->private_data; 5105455Sdg int channel = epcm->voice->number; 5115455Sdg snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0; 5125455Sdg 5135455Sdg if (!epcm->running) 5145455Sdg return 0; 51542957Sdillon 51642957Sdillon ptr3 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 51795701Salc ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel); 51895701Salc ptr4 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 51995701Salc 5201549Srgrimes if(ptr4 == 0 && ptr1 == frames_to_bytes(runtime, runtime->buffer_size)) 5213449Sphk return 0; 52234202Sdyson 5231541Srgrimes if (ptr3 != ptr4) 5241541Srgrimes ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel); 52551488Sdillon ptr2 = bytes_to_frames(runtime, ptr1); 52651488Sdillon ptr2 += (ptr4 >> 3) * runtime->period_size; 52795701Salc ptr = ptr2; 52895701Salc 52995701Salc if (ptr >= runtime->buffer_size) 53051488Sdillon ptr -= runtime->buffer_size; 53151488Sdillon 53251488Sdillon return ptr; 53351488Sdillon} 5345455Sdg 53542957Sdillon/* operators */ 53642957Sdillonstatic const struct snd_pcm_ops snd_emu10k1x_playback_ops = { 5371541Srgrimes .open = snd_emu10k1x_playback_open, 53834202Sdyson .close = snd_emu10k1x_playback_close, 5391541Srgrimes .hw_params = snd_emu10k1x_pcm_hw_params, 5401549Srgrimes .hw_free = snd_emu10k1x_pcm_hw_free, 54134202Sdyson .prepare = snd_emu10k1x_pcm_prepare, 5429507Sdg .trigger = snd_emu10k1x_pcm_trigger, 54310988Sdyson .pointer = snd_emu10k1x_pcm_pointer, 5441541Srgrimes}; 5451541Srgrimes 54617312Sdyson/* open_capture callback */ 54717312Sdysonstatic int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream) 54817312Sdyson{ 54917312Sdyson struct emu10k1x *chip = snd_pcm_substream_chip(substream); 55017312Sdyson struct emu10k1x_pcm *epcm; 5515455Sdg struct snd_pcm_runtime *runtime = substream->runtime; 5525455Sdg int err; 5535455Sdg 5541541Srgrimes err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 55534202Sdyson if (err < 0) 55692029Seivind return err; 55734202Sdyson err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64); 55817312Sdyson if (err < 0) 5597695Sdg return err; 5608876Srgrimes 5611549Srgrimes epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); 56242957Sdillon if (epcm == NULL) 5631541Srgrimes return -ENOMEM; 5641541Srgrimes 5655455Sdg epcm->emu = chip; 5665455Sdg epcm->substream = substream; 5675455Sdg 5688876Srgrimes runtime->private_data = epcm; 5699507Sdg runtime->private_free = snd_emu10k1x_pcm_free_substream; 5705455Sdg 5718876Srgrimes runtime->hw = snd_emu10k1x_capture_hw; 5725455Sdg 5739507Sdg return 0; 5745455Sdg} 5755455Sdg 5761541Srgrimes/* close callback */ 5774207Sdgstatic int snd_emu10k1x_pcm_close_capture(struct snd_pcm_substream *substream) 57837843Sdg{ 57937843Sdg return 0; 5801549Srgrimes} 5814207Sdg 5821549Srgrimes/* hw_params callback */ 5834207Sdgstatic int snd_emu10k1x_pcm_hw_params_capture(struct snd_pcm_substream *substream, 5845455Sdg struct snd_pcm_hw_params *hw_params) 5855455Sdg{ 5865455Sdg struct snd_pcm_runtime *runtime = substream->runtime; 5874207Sdg struct emu10k1x_pcm *epcm = runtime->private_data; 58834202Sdyson 58932585Sdyson if (! epcm->voice) { 590100456Salc if (epcm->emu->capture_voice.use) 59134202Sdyson return -EBUSY; 592100456Salc epcm->voice = &epcm->emu->capture_voice; 59334202Sdyson epcm->voice->epcm = epcm; 59434202Sdyson epcm->voice->use = 1; 5954207Sdg } 5961541Srgrimes 59734202Sdyson return 0; 598100456Salc} 59934202Sdyson 600100456Salc/* hw_free callback */ 60134202Sdysonstatic int snd_emu10k1x_pcm_hw_free_capture(struct snd_pcm_substream *substream) 6021549Srgrimes{ 6031549Srgrimes struct snd_pcm_runtime *runtime = substream->runtime; 6041549Srgrimes 6051549Srgrimes struct emu10k1x_pcm *epcm; 6061541Srgrimes 6071541Srgrimes if (runtime->private_data == NULL) 60851488Sdillon return 0; 6091541Srgrimes epcm = runtime->private_data; 61042957Sdillon 61142957Sdillon if (epcm->voice) { 6121541Srgrimes epcm->voice->use = 0; 61334202Sdyson epcm->voice->epcm = NULL; 61434202Sdyson epcm->voice = NULL; 6151541Srgrimes } 6161541Srgrimes 6175455Sdg return 0; 6185455Sdg} 6191541Srgrimes 62034202Sdyson/* prepare capture callback */ 62134202Sdysonstatic int snd_emu10k1x_pcm_prepare_capture(struct snd_pcm_substream *substream) 6221541Srgrimes{ 6231541Srgrimes struct emu10k1x *emu = snd_pcm_substream_chip(substream); 6245455Sdg struct snd_pcm_runtime *runtime = substream->runtime; 6255455Sdg 6261541Srgrimes snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr); 62734202Sdyson snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes 62834202Sdyson snd_emu10k1x_ptr_write(emu, CAPTURE_POINTER, 0, 0); 629113761Salc snd_emu10k1x_ptr_write(emu, CAPTURE_UNKNOWN, 0, 0); 6301541Srgrimes 63134202Sdyson return 0; 63234202Sdyson} 63334202Sdyson 634116695Salc/* trigger_capture callback */ 6351541Srgrimesstatic int snd_emu10k1x_pcm_trigger_capture(struct snd_pcm_substream *substream, 63634202Sdyson int cmd) 6371541Srgrimes{ 63846349Salc struct emu10k1x *emu = snd_pcm_substream_chip(substream); 63946349Salc struct snd_pcm_runtime *runtime = substream->runtime; 64046349Salc struct emu10k1x_pcm *epcm = runtime->private_data; 64134202Sdyson int result = 0; 642102382Salc 64346349Salc switch (cmd) { 64446349Salc case SNDRV_PCM_TRIGGER_START: 64544250Salc snd_emu10k1x_intr_enable(emu, INTE_CAP_0_LOOP | 64617312Sdyson INTE_CAP_0_HALF_LOOP); 64746349Salc snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|TRIGGER_CAPTURE); 64842957Sdillon epcm->running = 1; 6495455Sdg break; 650116667Salc case SNDRV_PCM_TRIGGER_STOP: 651116667Salc epcm->running = 0; 652116667Salc snd_emu10k1x_intr_disable(emu, INTE_CAP_0_LOOP | 653116667Salc INTE_CAP_0_HALF_LOOP); 654116667Salc snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CAPTURE)); 65534202Sdyson break; 656116667Salc default: 65734202Sdyson result = -EINVAL; 6581541Srgrimes break; 6591541Srgrimes } 66042957Sdillon return result; 66142408Seivind} 66242408Seivind 6631541Srgrimes/* pointer_capture callback */ 6641541Srgrimesstatic snd_pcm_uframes_t 6655455Sdgsnd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream) 6665455Sdg{ 6671541Srgrimes struct emu10k1x *emu = snd_pcm_substream_chip(substream); 6681541Srgrimes struct snd_pcm_runtime *runtime = substream->runtime; 6691541Srgrimes struct emu10k1x_pcm *epcm = runtime->private_data; 6705455Sdg snd_pcm_uframes_t ptr; 6715455Sdg 6725455Sdg if (!epcm->running) 6731541Srgrimes return 0; 67434202Sdyson 6755455Sdg ptr = bytes_to_frames(runtime, snd_emu10k1x_ptr_read(emu, CAPTURE_POINTER, 0)); 6765455Sdg if (ptr >= runtime->buffer_size) 6771541Srgrimes ptr -= runtime->buffer_size; 6785455Sdg 6791541Srgrimes return ptr; 68042957Sdillon} 68142957Sdillon 68242957Sdillonstatic const struct snd_pcm_ops snd_emu10k1x_capture_ops = { 68342957Sdillon .open = snd_emu10k1x_pcm_open_capture, 68442957Sdillon .close = snd_emu10k1x_pcm_close_capture, 68542957Sdillon .hw_params = snd_emu10k1x_pcm_hw_params_capture, 68642957Sdillon .hw_free = snd_emu10k1x_pcm_hw_free_capture, 68742957Sdillon .prepare = snd_emu10k1x_pcm_prepare_capture, 6881541Srgrimes .trigger = snd_emu10k1x_pcm_trigger_capture, 689116650Salc .pointer = snd_emu10k1x_pcm_pointer_capture, 690116596Salc}; 69114316Sdyson 69214316Sdysonstatic unsigned short snd_emu10k1x_ac97_read(struct snd_ac97 *ac97, 69314316Sdyson unsigned short reg) 69434202Sdyson{ 69514316Sdyson struct emu10k1x *emu = ac97->private_data; 69614316Sdyson unsigned long flags; 69714316Sdyson unsigned short val; 69834202Sdyson 69914316Sdyson spin_lock_irqsave(&emu->emu_lock, flags); 70058705Scharnier outb(reg, emu->port + AC97ADDRESS); 70114316Sdyson val = inw(emu->port + AC97DATA); 70234202Sdyson spin_unlock_irqrestore(&emu->emu_lock, flags); 70314316Sdyson return val; 70414316Sdyson} 70514316Sdyson 70634202Sdysonstatic void snd_emu10k1x_ac97_write(struct snd_ac97 *ac97, 70734202Sdyson unsigned short reg, unsigned short val) 708116650Salc{ 70914316Sdyson struct emu10k1x *emu = ac97->private_data; 71014316Sdyson unsigned long flags; 71114316Sdyson 712116596Salc spin_lock_irqsave(&emu->emu_lock, flags); 713116658Salc outb(reg, emu->port + AC97ADDRESS); 71414316Sdyson outw(val, emu->port + AC97DATA); 71514316Sdyson spin_unlock_irqrestore(&emu->emu_lock, flags); 71614316Sdyson} 717106981Salc 71834202Sdysonstatic int snd_emu10k1x_ac97(struct emu10k1x *chip) 71914316Sdyson{ 72042957Sdillon struct snd_ac97_bus *pbus; 72142957Sdillon struct snd_ac97_template ac97; 72242957Sdillon int err; 72314316Sdyson static const struct snd_ac97_bus_ops ops = { 72434202Sdyson .write = snd_emu10k1x_ac97_write, 725116658Salc .read = snd_emu10k1x_ac97_read, 726116658Salc }; 72734202Sdyson 72834202Sdyson err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus); 72934202Sdyson if (err < 0) 73014316Sdyson return err; 73114316Sdyson pbus->no_vra = 1; /* we don't need VRA */ 73214316Sdyson 73314316Sdyson memset(&ac97, 0, sizeof(ac97)); 734120903Salc ac97.private_data = chip; 735120903Salc ac97.scaps = AC97_SCAP_NO_SPDIF; 73614316Sdyson return snd_ac97_mixer(pbus, &ac97, &chip->ac97); 73734202Sdyson} 73834202Sdyson 73934202Sdysonstatic void snd_emu10k1x_free(struct snd_card *card) 74034202Sdyson{ 74134202Sdyson struct emu10k1x *chip = card->private_data; 74214316Sdyson 74342957Sdillon snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0); 74442957Sdillon // disable interrupts 74542957Sdillon outl(0, chip->port + INTE); 74642957Sdillon // disable audio 74734202Sdyson outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); 748113761Salc} 7491541Srgrimes 7505455Sdgstatic irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id) 7511541Srgrimes{ 75234202Sdyson unsigned int status; 75334202Sdyson 754116658Salc struct emu10k1x *chip = dev_id; 755116695Salc struct emu10k1x_voice *pvoice = chip->voices; 756116695Salc int i; 757116658Salc int mask; 7585455Sdg 7595455Sdg status = inl(chip->port + IPR); 7601541Srgrimes 7611541Srgrimes if (! status) 7621541Srgrimes return IRQ_NONE; 7631541Srgrimes 7645455Sdg // capture interrupt 7655455Sdg if (status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) { 7661541Srgrimes struct emu10k1x_voice *cap_voice = &chip->capture_voice; 76792588Sgreen if (cap_voice->use) 76834202Sdyson snd_emu10k1x_pcm_interrupt(chip, cap_voice); 7695455Sdg else 77012767Sdyson snd_emu10k1x_intr_disable(chip, 7715455Sdg INTE_CAP_0_LOOP | 7721541Srgrimes INTE_CAP_0_HALF_LOOP); 7731541Srgrimes } 7745455Sdg 7755455Sdg mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP; 7761541Srgrimes for (i = 0; i < 3; i++) { 7771541Srgrimes if (status & mask) { 7781541Srgrimes if (pvoice->use) 77944098Sdillon snd_emu10k1x_pcm_interrupt(chip, pvoice); 78044098Sdillon else 78144098Sdillon snd_emu10k1x_intr_disable(chip, mask); 78244098Sdillon } 78344098Sdillon pvoice++; 78444098Sdillon mask <<= 1; 78544098Sdillon } 78644098Sdillon 78774237Sdillon if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) { 78874237Sdillon if (chip->midi.interrupt) 78974237Sdillon chip->midi.interrupt(chip, status); 79074237Sdillon else 79174237Sdillon snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE); 79274237Sdillon } 793116695Salc 79444098Sdillon // acknowledge the interrupt if necessary 79544098Sdillon outl(status, chip->port + IPR); 7969507Sdg 797122383Smini /* dev_dbg(chip->card->dev, "interrupt %08x\n", status); */ 7985455Sdg return IRQ_HANDLED; 7995455Sdg} 8005455Sdg 8015455Sdgstatic const struct snd_pcm_chmap_elem surround_map[] = { 8021541Srgrimes { .channels = 2, 80334202Sdyson .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, 80434202Sdyson { } 80534202Sdyson}; 8061541Srgrimes 807116695Salcstatic const struct snd_pcm_chmap_elem clfe_map[] = { 8081541Srgrimes { .channels = 2, 8095455Sdg .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } }, 8105455Sdg { } 8115455Sdg}; 8121541Srgrimes 8131541Srgrimesstatic int snd_emu10k1x_pcm(struct emu10k1x *emu, int device) 81434202Sdyson{ 81534202Sdyson struct snd_pcm *pcm; 8165455Sdg const struct snd_pcm_chmap_elem *map = NULL; 8171541Srgrimes int err; 81892588Sgreen int capture = 0; 8191541Srgrimes 82034202Sdyson if (device == 0) 82134202Sdyson capture = 1; 82234202Sdyson 82334202Sdyson err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm); 8241541Srgrimes if (err < 0) 8251541Srgrimes return err; 8261541Srgrimes 8275455Sdg pcm->private_data = emu; 8285455Sdg 8295455Sdg switch(device) { 8305455Sdg case 0: 8315455Sdg snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops); 8325455Sdg snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1x_capture_ops); 8331541Srgrimes break; 8341541Srgrimes case 1: 8351541Srgrimes case 2: 8361541Srgrimes snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops); 8371541Srgrimes break; 8385455Sdg } 8395455Sdg 8405455Sdg pcm->info_flags = 0; 8415455Sdg switch(device) { 8421541Srgrimes case 0: 8431541Srgrimes strcpy(pcm->name, "EMU10K1X Front"); 8447411Sdg map = snd_pcm_std_chmaps; 845108068Salc break; 84638799Sdfr case 1: 84785517Sdillon strcpy(pcm->name, "EMU10K1X Rear"); 84854467Sdillon map = surround_map; 8497411Sdg break; 8507411Sdg case 2: 85154467Sdillon strcpy(pcm->name, "EMU10K1X Center/LFE"); 85254467Sdillon map = clfe_map; 85342957Sdillon break; 85454467Sdillon } 85554467Sdillon emu->pcm = pcm; 85654467Sdillon 85754467Sdillon snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, 85854467Sdillon &emu->pci->dev, 32*1024, 32*1024); 85954467Sdillon 86054467Sdillon return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2, 86142957Sdillon 1 << 2, NULL); 86242957Sdillon} 8637411Sdg 86473212Sdillonstatic int snd_emu10k1x_create(struct snd_card *card, 86573212Sdillon struct pci_dev *pci) 86673212Sdillon{ 86773212Sdillon struct emu10k1x *chip = card->private_data; 86873212Sdillon int err; 86973212Sdillon int ch; 870108068Salc 87124666Sdyson err = pcim_enable_device(pci); 87268884Sdillon if (err < 0) 87343138Sdillon return err; 87468884Sdillon 87542957Sdillon if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28)) < 0) { 87668884Sdillon dev_err(card->dev, "error to set 28bit mask DMA\n"); 8777411Sdg return -ENXIO; 8787411Sdg } 8797695Sdg 88043119Sdillon chip->card = card; 88143119Sdillon chip->pci = pci; 88243119Sdillon chip->irq = -1; 88348922Salc 88448922Salc spin_lock_init(&chip->emu_lock); 88546349Salc spin_lock_init(&chip->voice_lock); 88646349Salc 88746349Salc err = pci_request_regions(pci, "EMU10K1X"); 88846349Salc if (err < 0) 88946349Salc return err; 89046349Salc chip->port = pci_resource_start(pci, 0); 89146349Salc 89246349Salc if (devm_request_irq(&pci->dev, pci->irq, snd_emu10k1x_interrupt, 893120764Salc IRQF_SHARED, KBUILD_MODNAME, chip)) { 894120764Salc dev_err(card->dev, "cannot grab irq %d\n", pci->irq); 89560755Speter return -EBUSY; 89632702Sdyson } 897120722Salc chip->irq = pci->irq; 89832702Sdyson card->sync_irq = chip->irq; 899123879Salc card->private_free = snd_emu10k1x_free; 90099920Salc 90146349Salc chip->dma_buffer = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV, 902101634Salc 4 * 1024); 90316058Sdyson if (!chip->dma_buffer) 9041541Srgrimes return -ENOMEM; 9055455Sdg 9065455Sdg pci_set_master(pci); 9071541Srgrimes /* read revision & serial */ 90824666Sdyson chip->revision = pci->revision; 9091541Srgrimes pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial); 91034202Sdyson pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model); 9111541Srgrimes dev_info(card->dev, "Model %04x Rev %08x Serial %08x\n", chip->model, 91240700Sdg chip->revision, chip->serial); 9135455Sdg 91434202Sdyson outl(0, chip->port + INTE); 9151549Srgrimes 916101654Salc for(ch = 0; ch < 3; ch++) { 91799920Salc chip->voices[ch].emu = chip; 918113868Sjhb chip->voices[ch].number = ch; 919113868Sjhb } 920113868Sjhb 9211549Srgrimes /* 9221549Srgrimes * Init to 0x02109204 : 9231549Srgrimes * Clock accuracy = 0 (1000ppm) 9241549Srgrimes * Sample Rate = 2 (48kHz) 9251549Srgrimes * Audio Channel = 1 (Left of 2) 9261549Srgrimes * Source Number = 0 (Unspecified) 927113868Sjhb * Generation Status = 1 (Original for Cat Code 12) 9281541Srgrimes * Cat Code = 12 (Digital Signal Mixer) 9291541Srgrimes * Mode = 0 (Mode 0) 9305455Sdg * Emphasis = 0 (None) 9311541Srgrimes * CP = 1 (Copyright unasserted) 93234202Sdyson * AN = 0 (Audio data) 9335455Sdg * P = 0 (Consumer) 9341541Srgrimes */ 9351541Srgrimes snd_emu10k1x_ptr_write(chip, SPCS0, 0, 9361541Srgrimes chip->spdif_bits[0] = 937120722Salc SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 938120722Salc SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 939120722Salc SPCS_GENERATIONSTATUS | 0x00001200 | 940120722Salc 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); 941120722Salc snd_emu10k1x_ptr_write(chip, SPCS1, 0, 942120722Salc chip->spdif_bits[1] = 943120722Salc SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 944120722Salc SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 945120722Salc SPCS_GENERATIONSTATUS | 0x00001200 | 946120722Salc 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); 947120722Salc snd_emu10k1x_ptr_write(chip, SPCS2, 0, 948120722Salc chip->spdif_bits[2] = 949120722Salc SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 950120722Salc SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 951120722Salc SPCS_GENERATIONSTATUS | 0x00001200 | 952120722Salc 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); 953120722Salc 954120722Salc snd_emu10k1x_ptr_write(chip, SPDIF_SELECT, 0, 0x700); // disable SPDIF 955120722Salc snd_emu10k1x_ptr_write(chip, ROUTING, 0, 0x1003F); // routing 956120722Salc snd_emu10k1x_gpio_write(chip, 0x1080); // analog mode 957120722Salc 958120722Salc outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); 959120722Salc 960120722Salc return 0; 961120722Salc} 962120722Salc 963120722Salcstatic void snd_emu10k1x_proc_reg_read(struct snd_info_entry *entry, 964120722Salc struct snd_info_buffer *buffer) 965120722Salc{ 966120722Salc struct emu10k1x *emu = entry->private_data; 967120722Salc unsigned long value,value1,value2; 968120722Salc unsigned long flags; 969120722Salc int i; 970120722Salc 971120722Salc snd_iprintf(buffer, "Registers:\n\n"); 972120722Salc for(i = 0; i < 0x20; i+=4) { 973120722Salc spin_lock_irqsave(&emu->emu_lock, flags); 974120722Salc value = inl(emu->port + i); 975120722Salc spin_unlock_irqrestore(&emu->emu_lock, flags); 976120722Salc snd_iprintf(buffer, "Register %02X: %08lX\n", i, value); 977120722Salc } 978120722Salc snd_iprintf(buffer, "\nRegisters\n\n"); 979120722Salc for(i = 0; i <= 0x48; i++) { 980120722Salc value = snd_emu10k1x_ptr_read(emu, i, 0); 981120722Salc if(i < 0x10 || (i >= 0x20 && i < 0x40)) { 982120722Salc value1 = snd_emu10k1x_ptr_read(emu, i, 1); 983120722Salc value2 = snd_emu10k1x_ptr_read(emu, i, 2); 984120722Salc snd_iprintf(buffer, "%02X: %08lX %08lX %08lX\n", i, value, value1, value2); 985120722Salc } else { 986120722Salc snd_iprintf(buffer, "%02X: %08lX\n", i, value); 987120722Salc } 988120722Salc } 989120722Salc} 990120722Salc 991120722Salcstatic void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry, 992120722Salc struct snd_info_buffer *buffer) 993120764Salc{ 994120764Salc struct emu10k1x *emu = entry->private_data; 995120722Salc char line[64]; 996120764Salc unsigned int reg, channel_id , val; 997120722Salc 998120722Salc while (!snd_info_get_line(buffer, line, sizeof(line))) { 999120722Salc if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) 1000120722Salc continue; 1001120722Salc 1002120722Salc if (reg < 0x49 && channel_id <= 2) 1003120722Salc snd_emu10k1x_ptr_write(emu, reg, channel_id, val); 1004120722Salc } 1005120722Salc} 1006120722Salc 1007120764Salcstatic int snd_emu10k1x_proc_init(struct emu10k1x *emu) 1008120722Salc{ 1009120764Salc snd_card_rw_proc_new(emu->card, "emu10k1x_regs", emu, 1010120722Salc snd_emu10k1x_proc_reg_read, 1011120722Salc snd_emu10k1x_proc_reg_write); 1012120722Salc return 0; 1013120722Salc} 1014120764Salc 1015120722Salc#define snd_emu10k1x_shared_spdif_info snd_ctl_boolean_mono_info 1016120722Salc 1017120722Salcstatic int snd_emu10k1x_shared_spdif_get(struct snd_kcontrol *kcontrol, 1018120722Salc struct snd_ctl_elem_value *ucontrol) 1019109342Sdillon{ 1020109342Sdillon struct emu10k1x *emu = snd_kcontrol_chip(kcontrol); 1021109342Sdillon 1022109342Sdillon ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1; 1023109342Sdillon 1024109342Sdillon return 0; 1025109342Sdillon} 1026109342Sdillon 1027109342Sdillonstatic int snd_emu10k1x_shared_spdif_put(struct snd_kcontrol *kcontrol, 1028109342Sdillon struct snd_ctl_elem_value *ucontrol) 1029109342Sdillon{ 1030109342Sdillon struct emu10k1x *emu = snd_kcontrol_chip(kcontrol); 1031109342Sdillon unsigned int val; 1032109342Sdillon 1033109342Sdillon val = ucontrol->value.integer.value[0] ; 1034109342Sdillon 1035109342Sdillon if (val) { 1036109342Sdillon // enable spdif output 10371541Srgrimes snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x000); 10381541Srgrimes snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x700); 10391541Srgrimes snd_emu10k1x_gpio_write(emu, 0x1000); 10401541Srgrimes } else { 10411541Srgrimes // disable spdif output 1042100630Salc snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x700); 10435455Sdg snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x1003F); 10445455Sdg snd_emu10k1x_gpio_write(emu, 0x1080); 1045100630Salc } 10461541Srgrimes return 0; 104779242Sdillon} 10481549Srgrimes 10491541Srgrimesstatic const struct snd_kcontrol_new snd_emu10k1x_shared_spdif = 10501541Srgrimes{ 10515455Sdg .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1052100630Salc .name = "Analog/Digital Output Jack", 1053100630Salc .info = snd_emu10k1x_shared_spdif_info, 10541541Srgrimes .get = snd_emu10k1x_shared_spdif_get, 10551541Srgrimes .put = snd_emu10k1x_shared_spdif_put 1056100630Salc}; 1057100630Salc 1058100630Salcstatic int snd_emu10k1x_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 10591541Srgrimes{ 10601541Srgrimes uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 10611541Srgrimes uinfo->count = 1; 10625455Sdg return 0; 10631541Srgrimes} 10641541Srgrimes 10655455Sdgstatic int snd_emu10k1x_spdif_get(struct snd_kcontrol *kcontrol, 10661541Srgrimes struct snd_ctl_elem_value *ucontrol) 10671541Srgrimes{ 106820449Sdyson struct emu10k1x *emu = snd_kcontrol_chip(kcontrol); 10691541Srgrimes unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 10701541Srgrimes 10711541Srgrimes ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; 10721541Srgrimes ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; 10731549Srgrimes ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff; 10741549Srgrimes ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff; 10755455Sdg return 0; 10765455Sdg} 10771541Srgrimes 1078112569Sjakestatic int snd_emu10k1x_spdif_get_mask(struct snd_kcontrol *kcontrol, 1079112569Sjake struct snd_ctl_elem_value *ucontrol) 108079242Sdillon{ 10811541Srgrimes ucontrol->value.iec958.status[0] = 0xff; 10821541Srgrimes ucontrol->value.iec958.status[1] = 0xff; 10831541Srgrimes ucontrol->value.iec958.status[2] = 0xff; 1084126793Salc ucontrol->value.iec958.status[3] = 0xff; 1085126793Salc return 0; 10861541Srgrimes} 10875455Sdg 10885455Sdgstatic int snd_emu10k1x_spdif_put(struct snd_kcontrol *kcontrol, 10891541Srgrimes struct snd_ctl_elem_value *ucontrol) 10901541Srgrimes{ 10911541Srgrimes struct emu10k1x *emu = snd_kcontrol_chip(kcontrol); 1092112569Sjake unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 109315809Sdyson int change; 109499920Salc unsigned int val; 109540700Sdg 109699920Salc val = (ucontrol->value.iec958.status[0] << 0) | 10971541Srgrimes (ucontrol->value.iec958.status[1] << 8) | 10981541Srgrimes (ucontrol->value.iec958.status[2] << 16) | 1099126793Salc (ucontrol->value.iec958.status[3] << 24); 1100126793Salc change = val != emu->spdif_bits[idx]; 11011541Srgrimes if (change) { 11021541Srgrimes snd_emu10k1x_ptr_write(emu, SPCS0 + idx, 0, val); 11031541Srgrimes emu->spdif_bits[idx] = val; 11041541Srgrimes } 11051541Srgrimes return change; 11061541Srgrimes} 11071541Srgrimes 11081541Srgrimesstatic const struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control = 11091541Srgrimes{ 11101541Srgrimes .access = SNDRV_CTL_ELEM_ACCESS_READ, 11111541Srgrimes .iface = SNDRV_CTL_ELEM_IFACE_PCM, 11121541Srgrimes .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 11131541Srgrimes .count = 3, 11141549Srgrimes .info = snd_emu10k1x_spdif_info, 11151549Srgrimes .get = snd_emu10k1x_spdif_get_mask 11165455Sdg}; 11175455Sdg 11185455Sdgstatic const struct snd_kcontrol_new snd_emu10k1x_spdif_control = 11195455Sdg{ 11201541Srgrimes .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1121121108Salc .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 11225455Sdg .count = 3, 112312767Sdyson .info = snd_emu10k1x_spdif_info, 112412767Sdyson .get = snd_emu10k1x_spdif_get, 1125121108Salc .put = snd_emu10k1x_spdif_put 11265455Sdg}; 11275455Sdg 11285455Sdgstatic int snd_emu10k1x_mixer(struct emu10k1x *emu) 11295455Sdg{ 11301541Srgrimes int err; 11311541Srgrimes struct snd_kcontrol *kctl; 11321541Srgrimes struct snd_card *card = emu->card; 11335455Sdg 11341541Srgrimes kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu); 11351541Srgrimes if (!kctl) 11361541Srgrimes return -ENOMEM; 11371541Srgrimes err = snd_ctl_add(card, kctl); 11381541Srgrimes if (err) 11395455Sdg return err; 11405455Sdg kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu); 11411541Srgrimes if (!kctl) 11429507Sdg return -ENOMEM; 114312767Sdyson err = snd_ctl_add(card, kctl); 11441541Srgrimes if (err) 1145120905Salc return err; 11461541Srgrimes kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu); 11471541Srgrimes if (!kctl) 11481541Srgrimes return -ENOMEM; 11495455Sdg err = snd_ctl_add(card, kctl); 11501541Srgrimes if (err) 11511541Srgrimes return err; 11525455Sdg 11535455Sdg return 0; 11545455Sdg} 11551541Srgrimes 11561541Srgrimes#define EMU10K1X_MIDI_MODE_INPUT (1<<0) 11575455Sdg#define EMU10K1X_MIDI_MODE_OUTPUT (1<<1) 11585455Sdg 11591541Srgrimesstatic inline unsigned char mpu401_read(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int idx) 11601541Srgrimes{ 11615455Sdg return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0); 11621541Srgrimes} 11631541Srgrimes 116412767Sdysonstatic inline void mpu401_write(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int data, int idx) 116512767Sdyson{ 11661541Srgrimes snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data); 1167120905Salc} 11681541Srgrimes 1169120905Salc#define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0) 11701541Srgrimes#define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1) 11711541Srgrimes#define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0) 11721541Srgrimes#define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1) 11731541Srgrimes 11745455Sdg#define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80)) 11755455Sdg#define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40)) 11765455Sdg 11771541Srgrimes#define MPU401_RESET 0xff 1178116695Salc#define MPU401_ENTER_UART 0x3f 1179121108Salc#define MPU401_ACK 0xfe 1180121108Salc 1181121108Salcstatic void mpu401_clear_rx(struct emu10k1x *emu, struct emu10k1x_midi *mpu) 1182121108Salc{ 1183121108Salc int timeout = 100000; 1184121108Salc for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--) 1185121108Salc mpu401_read_data(emu, mpu); 1186121108Salc#ifdef CONFIG_SND_DEBUG 1187121108Salc if (timeout <= 0) 1188121108Salc dev_err(emu->card->dev, 1189121108Salc "cmd: clear rx timeout (status = 0x%x)\n", 1190121108Salc mpu401_read_stat(emu, mpu)); 1191121108Salc#endif 1192121108Salc} 11931541Srgrimes 11941541Srgrimes/* 1195120903Salc 1196121108Salc */ 1197120903Salc 1198120905Salcstatic void do_emu10k1x_midi_interrupt(struct emu10k1x *emu, 11991541Srgrimes struct emu10k1x_midi *midi, unsigned int status) 12001541Srgrimes{ 12015455Sdg unsigned char byte; 12021541Srgrimes 120360755Speter if (midi->rmidi == NULL) { 1204120905Salc snd_emu10k1x_intr_disable(emu, midi->tx_enable | midi->rx_enable); 1205100742Salc return; 1206121108Salc } 1207121108Salc 12081541Srgrimes spin_lock(&midi->input_lock); 12091541Srgrimes if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) { 12105455Sdg if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) { 12111541Srgrimes mpu401_clear_rx(emu, midi); 12121541Srgrimes } else { 121338799Sdfr byte = mpu401_read_data(emu, midi); 1214100742Salc if (midi->substream_input) 12151541Srgrimes snd_rawmidi_receive(midi->substream_input, &byte, 1); 1216120905Salc } 12171549Srgrimes } 12181541Srgrimes spin_unlock(&midi->input_lock); 12191549Srgrimes 12201549Srgrimes spin_lock(&midi->output_lock); 12211549Srgrimes if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) { 122210988Sdyson if (midi->substream_output && 122310988Sdyson snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) { 12241549Srgrimes mpu401_write_data(emu, midi, byte); 12251549Srgrimes } else { 122610988Sdyson snd_emu10k1x_intr_disable(emu, midi->tx_enable); 12271549Srgrimes } 12281549Srgrimes } 12291549Srgrimes spin_unlock(&midi->output_lock); 12301549Srgrimes} 12311549Srgrimes 12321549Srgrimesstatic void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int status) 123376827Salfred{ 123476827Salfred do_emu10k1x_midi_interrupt(emu, &emu->midi, status); 12351549Srgrimes} 123633181Seivind 123710988Sdysonstatic int snd_emu10k1x_midi_cmd(struct emu10k1x * emu, 12381549Srgrimes struct emu10k1x_midi *midi, unsigned char cmd, int ack) 12391549Srgrimes{ 124010988Sdyson unsigned long flags; 12411549Srgrimes int timeout, ok; 12421549Srgrimes 12431549Srgrimes spin_lock_irqsave(&midi->input_lock, flags); 124432702Sdyson mpu401_write_data(emu, midi, 0x00); 12451549Srgrimes /* mpu401_clear_rx(emu, midi); */ 124612767Sdyson 12471549Srgrimes mpu401_write_cmd(emu, midi, cmd); 124810556Sdyson if (ack) { 12491549Srgrimes ok = 0; 1250116695Salc timeout = 10000; 125176827Salfred while (!ok && timeout-- > 0) { 12521549Srgrimes if (mpu401_input_avail(emu, midi)) { 125312767Sdyson if (mpu401_read_data(emu, midi) == MPU401_ACK) 12541549Srgrimes ok = 1; 12551549Srgrimes } 125616026Sdyson } 125716026Sdyson if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK) 125816026Sdyson ok = 1; 125916026Sdyson } else { 126016026Sdyson ok = 1; 126116026Sdyson } 126216026Sdyson spin_unlock_irqrestore(&midi->input_lock, flags); 126316026Sdyson if (!ok) { 126416026Sdyson dev_err(emu->card->dev, 12651549Srgrimes "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n", 12661549Srgrimes cmd, emu->port, 126742957Sdillon mpu401_read_stat(emu, midi), 12681549Srgrimes mpu401_read_data(emu, midi)); 126932702Sdyson return 1; 12701549Srgrimes } 127110988Sdyson return 0; 127210988Sdyson} 127310988Sdyson 127410988Sdysonstatic int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream) 127510556Sdyson{ 127610556Sdyson struct emu10k1x *emu; 127710988Sdyson struct emu10k1x_midi *midi = substream->rmidi->private_data; 127810988Sdyson unsigned long flags; 127910988Sdyson 128010988Sdyson emu = midi->emu; 128110988Sdyson if (snd_BUG_ON(!emu)) 128210988Sdyson return -ENXIO; 128310988Sdyson spin_lock_irqsave(&midi->open_lock, flags); 128410988Sdyson midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT; 12851549Srgrimes midi->substream_input = substream; 12861549Srgrimes if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) { 12871549Srgrimes spin_unlock_irqrestore(&midi->open_lock, flags); 128810668Sdyson if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1)) 128910988Sdyson goto error_out; 129010988Sdyson if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1)) 129132702Sdyson goto error_out; 12921549Srgrimes } else { 12931549Srgrimes spin_unlock_irqrestore(&midi->open_lock, flags); 12941549Srgrimes } 129510988Sdyson return 0; 12961549Srgrimes 129732702Sdysonerror_out: 12981549Srgrimes return -EIO; 129932702Sdyson} 130032702Sdyson 130112767Sdysonstatic int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream) 130232702Sdyson{ 130332702Sdyson struct emu10k1x *emu; 130432702Sdyson struct emu10k1x_midi *midi = substream->rmidi->private_data; 130532702Sdyson unsigned long flags; 130632702Sdyson 130792029Seivind emu = midi->emu; 130892029Seivind if (snd_BUG_ON(!emu)) 130912767Sdyson return -ENXIO; 13104446Sdg spin_lock_irqsave(&midi->open_lock, flags); 13114446Sdg midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT; 131212767Sdyson midi->substream_output = substream; 13134446Sdg if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) { 13141549Srgrimes spin_unlock_irqrestore(&midi->open_lock, flags); 131532702Sdyson if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1)) 131692029Seivind goto error_out; 131732702Sdyson if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1)) 131832702Sdyson goto error_out; 131932702Sdyson } else { 1320100456Salc spin_unlock_irqrestore(&midi->open_lock, flags); 132132702Sdyson } 132234202Sdyson return 0; 132332702Sdyson 1324100456Salcerror_out: 132532702Sdyson return -EIO; 132632702Sdyson} 132732702Sdyson 132832702Sdysonstatic int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream) 132932702Sdyson{ 133032702Sdyson struct emu10k1x *emu; 133132702Sdyson struct emu10k1x_midi *midi = substream->rmidi->private_data; 13324446Sdg unsigned long flags; 133332702Sdyson int err = 0; 133432702Sdyson 13351549Srgrimes emu = midi->emu; 13361549Srgrimes if (snd_BUG_ON(!emu)) 133732702Sdyson return -ENXIO; 133832702Sdyson spin_lock_irqsave(&midi->open_lock, flags); 133932702Sdyson snd_emu10k1x_intr_disable(emu, midi->rx_enable); 134032702Sdyson midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT; 134132702Sdyson midi->substream_input = NULL; 134232702Sdyson if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) { 134332702Sdyson spin_unlock_irqrestore(&midi->open_lock, flags); 13441549Srgrimes err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0); 134532702Sdyson } else { 13461549Srgrimes spin_unlock_irqrestore(&midi->open_lock, flags); 134732702Sdyson } 134812767Sdyson return err; 134912767Sdyson} 13501549Srgrimes 135192029Seivindstatic int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream) 13521549Srgrimes{ 135332702Sdyson struct emu10k1x *emu; 135432702Sdyson struct emu10k1x_midi *midi = substream->rmidi->private_data; 135532702Sdyson unsigned long flags; 13565455Sdg int err = 0; 135732702Sdyson 135832702Sdyson emu = midi->emu; 135932702Sdyson if (snd_BUG_ON(!emu)) 13601549Srgrimes return -ENXIO; 13611549Srgrimes spin_lock_irqsave(&midi->open_lock, flags); 136232702Sdyson snd_emu10k1x_intr_disable(emu, midi->tx_enable); 13631549Srgrimes midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT; 136432702Sdyson midi->substream_output = NULL; 136532702Sdyson if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) { 136632702Sdyson spin_unlock_irqrestore(&midi->open_lock, flags); 13671549Srgrimes err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0); 1368 } else { 1369 spin_unlock_irqrestore(&midi->open_lock, flags); 1370 } 1371 return err; 1372} 1373 1374static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) 1375{ 1376 struct emu10k1x *emu; 1377 struct emu10k1x_midi *midi = substream->rmidi->private_data; 1378 emu = midi->emu; 1379 if (snd_BUG_ON(!emu)) 1380 return; 1381 1382 if (up) 1383 snd_emu10k1x_intr_enable(emu, midi->rx_enable); 1384 else 1385 snd_emu10k1x_intr_disable(emu, midi->rx_enable); 1386} 1387 1388static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) 1389{ 1390 struct emu10k1x *emu; 1391 struct emu10k1x_midi *midi = substream->rmidi->private_data; 1392 unsigned long flags; 1393 1394 emu = midi->emu; 1395 if (snd_BUG_ON(!emu)) 1396 return; 1397 1398 if (up) { 1399 int max = 4; 1400 unsigned char byte; 1401 1402 /* try to send some amount of bytes here before interrupts */ 1403 spin_lock_irqsave(&midi->output_lock, flags); 1404 while (max > 0) { 1405 if (mpu401_output_ready(emu, midi)) { 1406 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) || 1407 snd_rawmidi_transmit(substream, &byte, 1) != 1) { 1408 /* no more data */ 1409 spin_unlock_irqrestore(&midi->output_lock, flags); 1410 return; 1411 } 1412 mpu401_write_data(emu, midi, byte); 1413 max--; 1414 } else { 1415 break; 1416 } 1417 } 1418 spin_unlock_irqrestore(&midi->output_lock, flags); 1419 snd_emu10k1x_intr_enable(emu, midi->tx_enable); 1420 } else { 1421 snd_emu10k1x_intr_disable(emu, midi->tx_enable); 1422 } 1423} 1424 1425/* 1426 1427 */ 1428 1429static const struct snd_rawmidi_ops snd_emu10k1x_midi_output = 1430{ 1431 .open = snd_emu10k1x_midi_output_open, 1432 .close = snd_emu10k1x_midi_output_close, 1433 .trigger = snd_emu10k1x_midi_output_trigger, 1434}; 1435 1436static const struct snd_rawmidi_ops snd_emu10k1x_midi_input = 1437{ 1438 .open = snd_emu10k1x_midi_input_open, 1439 .close = snd_emu10k1x_midi_input_close, 1440 .trigger = snd_emu10k1x_midi_input_trigger, 1441}; 1442 1443static void snd_emu10k1x_midi_free(struct snd_rawmidi *rmidi) 1444{ 1445 struct emu10k1x_midi *midi = rmidi->private_data; 1446 midi->interrupt = NULL; 1447 midi->rmidi = NULL; 1448} 1449 1450static int emu10k1x_midi_init(struct emu10k1x *emu, 1451 struct emu10k1x_midi *midi, int device, 1452 char *name) 1453{ 1454 struct snd_rawmidi *rmidi; 1455 int err; 1456 1457 err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi); 1458 if (err < 0) 1459 return err; 1460 midi->emu = emu; 1461 spin_lock_init(&midi->open_lock); 1462 spin_lock_init(&midi->input_lock); 1463 spin_lock_init(&midi->output_lock); 1464 strcpy(rmidi->name, name); 1465 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1x_midi_output); 1466 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1x_midi_input); 1467 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 1468 SNDRV_RAWMIDI_INFO_INPUT | 1469 SNDRV_RAWMIDI_INFO_DUPLEX; 1470 rmidi->private_data = midi; 1471 rmidi->private_free = snd_emu10k1x_midi_free; 1472 midi->rmidi = rmidi; 1473 return 0; 1474} 1475 1476static int snd_emu10k1x_midi(struct emu10k1x *emu) 1477{ 1478 struct emu10k1x_midi *midi = &emu->midi; 1479 int err; 1480 1481 err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)"); 1482 if (err < 0) 1483 return err; 1484 1485 midi->tx_enable = INTE_MIDITXENABLE; 1486 midi->rx_enable = INTE_MIDIRXENABLE; 1487 midi->port = MUDATA; 1488 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY; 1489 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY; 1490 midi->interrupt = snd_emu10k1x_midi_interrupt; 1491 return 0; 1492} 1493 1494static int __snd_emu10k1x_probe(struct pci_dev *pci, 1495 const struct pci_device_id *pci_id) 1496{ 1497 static int dev; 1498 struct snd_card *card; 1499 struct emu10k1x *chip; 1500 int err; 1501 1502 if (dev >= SNDRV_CARDS) 1503 return -ENODEV; 1504 if (!enable[dev]) { 1505 dev++; 1506 return -ENOENT; 1507 } 1508 1509 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 1510 sizeof(*chip), &card); 1511 if (err < 0) 1512 return err; 1513 chip = card->private_data; 1514 1515 err = snd_emu10k1x_create(card, pci); 1516 if (err < 0) 1517 return err; 1518 1519 err = snd_emu10k1x_pcm(chip, 0); 1520 if (err < 0) 1521 return err; 1522 err = snd_emu10k1x_pcm(chip, 1); 1523 if (err < 0) 1524 return err; 1525 err = snd_emu10k1x_pcm(chip, 2); 1526 if (err < 0) 1527 return err; 1528 1529 err = snd_emu10k1x_ac97(chip); 1530 if (err < 0) 1531 return err; 1532 1533 err = snd_emu10k1x_mixer(chip); 1534 if (err < 0) 1535 return err; 1536 1537 err = snd_emu10k1x_midi(chip); 1538 if (err < 0) 1539 return err; 1540 1541 snd_emu10k1x_proc_init(chip); 1542 1543 strcpy(card->driver, "EMU10K1X"); 1544 strcpy(card->shortname, "Dell Sound Blaster Live!"); 1545 sprintf(card->longname, "%s at 0x%lx irq %i", 1546 card->shortname, chip->port, chip->irq); 1547 1548 err = snd_card_register(card); 1549 if (err < 0) 1550 return err; 1551 1552 pci_set_drvdata(pci, card); 1553 dev++; 1554 return 0; 1555} 1556 1557static int snd_emu10k1x_probe(struct pci_dev *pci, 1558 const struct pci_device_id *pci_id) 1559{ 1560 return snd_card_free_on_error(&pci->dev, __snd_emu10k1x_probe(pci, pci_id)); 1561} 1562 1563// PCI IDs 1564static const struct pci_device_id snd_emu10k1x_ids[] = { 1565 { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */ 1566 { 0, } 1567}; 1568MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids); 1569 1570// pci_driver definition 1571static struct pci_driver emu10k1x_driver = { 1572 .name = KBUILD_MODNAME, 1573 .id_table = snd_emu10k1x_ids, 1574 .probe = snd_emu10k1x_probe, 1575}; 1576 1577module_pci_driver(emu10k1x_driver); 1578