Commit e2fa3083 authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Linus Torvalds

[PATCH] ALSA update [8/10] - 2002/07/31

  - AC'97 codec
    - added reset callback to do reset and skip the standard procedure
    - added limited_regs flag to avoid to touch unexpected registers
    - Fixes for AD1981A and added a special patch for an intel motherboard
  - sequencer
    - check the possible infinite loop in priority queues
    - reset the timer at continue if not initialized yet
  - changed synchronize_irq() for new api with an argument
  - NM256 driver - fixes the lock up on NM256 ZX
  - VIA8233 - implementation of SG buffer
parent b21fd933
...@@ -152,6 +152,7 @@ ...@@ -152,6 +152,7 @@
typedef struct _snd_ac97 ac97_t; typedef struct _snd_ac97 ac97_t;
struct _snd_ac97 { struct _snd_ac97 {
void (*reset) (ac97_t *ac97);
void (*write) (ac97_t *ac97, unsigned short reg, unsigned short val); void (*write) (ac97_t *ac97, unsigned short reg, unsigned short val);
unsigned short (*read) (ac97_t *ac97, unsigned short reg); unsigned short (*read) (ac97_t *ac97, unsigned short reg);
void (*wait) (ac97_t *ac97); void (*wait) (ac97_t *ac97);
...@@ -178,6 +179,7 @@ struct _snd_ac97 { ...@@ -178,6 +179,7 @@ struct _snd_ac97 {
unsigned int rates_mic_adc; unsigned int rates_mic_adc;
unsigned int spdif_status; unsigned int spdif_status;
unsigned short regs[0x80]; /* register cache */ unsigned short regs[0x80]; /* register cache */
unsigned int limited_regs; /* allow limited registers only */
bitmap_member(reg_accessed,0x80); /* bit flags */ bitmap_member(reg_accessed,0x80); /* bit flags */
union { /* vendor specific code */ union { /* vendor specific code */
struct { struct {
......
/* include/version.h. Generated automatically by configure. */ /* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc2" #define CONFIG_SND_VERSION "0.9.0rc2"
#define CONFIG_SND_DATE " (Wed Jul 24 10:42:45 2002 UTC)" #define CONFIG_SND_DATE " (Wed Jul 31 15:28:28 2002 UTC)"
...@@ -146,20 +146,15 @@ static inline int compare_timestamp_rel(snd_seq_event_t *a, snd_seq_event_t *b) ...@@ -146,20 +146,15 @@ static inline int compare_timestamp_rel(snd_seq_event_t *a, snd_seq_event_t *b)
} }
/* enqueue cell to prioq */ /* enqueue cell to prioq */
void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell) int snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell)
{ {
snd_seq_event_cell_t *cur, *prev; snd_seq_event_cell_t *cur, *prev;
unsigned long flags; unsigned long flags;
int count;
int prior; int prior;
if (f == NULL) { snd_assert(f, return -EINVAL);
snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n"); snd_assert(cell, return -EINVAL);
return;
}
if (cell == NULL) {
snd_printd("oops: snd_seq_prioq_cell_in() called with NULL cell\n");
return;
}
/* check flags */ /* check flags */
prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK); prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK);
...@@ -177,7 +172,7 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell) ...@@ -177,7 +172,7 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell)
cell->next = NULL; cell->next = NULL;
f->cells++; f->cells++;
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
return; return 0;
} }
} }
/* traverse list of elements to find the place where the new cell is /* traverse list of elements to find the place where the new cell is
...@@ -186,6 +181,7 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell) ...@@ -186,6 +181,7 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell)
prev = NULL; /* previous cell */ prev = NULL; /* previous cell */
cur = f->head; /* cursor */ cur = f->head; /* cursor */
count = 10000; /* FIXME: enough big, isn't it? */
while (cur != NULL) { while (cur != NULL) {
/* compare timestamps */ /* compare timestamps */
int rel = compare_timestamp_rel(&cell->event, &cur->event); int rel = compare_timestamp_rel(&cell->event, &cur->event);
...@@ -199,6 +195,11 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell) ...@@ -199,6 +195,11 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell)
/* move cursor to next cell */ /* move cursor to next cell */
prev = cur; prev = cur;
cur = cur->next; cur = cur->next;
if (! --count) {
spin_unlock_irqrestore(&f->lock, flags);
snd_printk(KERN_ERR "cannot find a pointer.. infinite loop?\n");
return -EINVAL;
}
} }
/* insert it before cursor */ /* insert it before cursor */
...@@ -212,6 +213,7 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell) ...@@ -212,6 +213,7 @@ void snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell)
f->tail = cell; f->tail = cell;
f->cells++; f->cells++;
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
return 0;
} }
/* dequeue cell from prioq */ /* dequeue cell from prioq */
......
...@@ -41,7 +41,7 @@ extern prioq_t *snd_seq_prioq_new(void); ...@@ -41,7 +41,7 @@ extern prioq_t *snd_seq_prioq_new(void);
extern void snd_seq_prioq_delete(prioq_t **fifo); extern void snd_seq_prioq_delete(prioq_t **fifo);
/* enqueue cell to prioq */ /* enqueue cell to prioq */
extern void snd_seq_prioq_cell_in(prioq_t *f, snd_seq_event_cell_t *cell); extern int snd_seq_prioq_cell_in(prioq_t *f, snd_seq_event_cell_t *cell);
/* dequeue cell from prioq */ /* dequeue cell from prioq */
extern snd_seq_event_cell_t *snd_seq_prioq_cell_out(prioq_t *f); extern snd_seq_event_cell_t *snd_seq_prioq_cell_out(prioq_t *f);
......
...@@ -365,9 +365,11 @@ void snd_seq_timer_continue(seq_timer_t * tmr) ...@@ -365,9 +365,11 @@ void snd_seq_timer_continue(seq_timer_t * tmr)
return; return;
if (tmr->running) if (tmr->running)
return; return;
if (! tmr->initialized) if (! tmr->initialized) {
snd_seq_timer_reset(tmr);
if (initialize_timer(tmr) < 0) if (initialize_timer(tmr) < 0)
return; return;
}
snd_timer_start(tmr->timeri, tmr->ticks); snd_timer_start(tmr->timeri, tmr->ticks);
tmr->running = 1; tmr->running = 1;
do_gettimeofday(&tmr->last_update); do_gettimeofday(&tmr->last_update);
......
...@@ -168,7 +168,7 @@ static int __init snd_card_dt019x_isapnp(int dev, struct snd_card_dt019x *acard) ...@@ -168,7 +168,7 @@ static int __init snd_card_dt019x_isapnp(int dev, struct snd_card_dt019x *acard)
snd_dma8[dev] = pdev->dma_resource[0].start; snd_dma8[dev] = pdev->dma_resource[0].start;
snd_irq[dev] = pdev->irq_resource[0].start; snd_irq[dev] = pdev->irq_resource[0].start;
snd_printdd("dt019x: found audio interface: port=0x%lx, irq=0x%lx, dma=0x%lx\n", snd_printdd("dt019x: found audio interface: port=0x%lx, irq=0x%lx, dma=0x%lx\n",
snd_port[dev],snd_irq[dev],smd_dma8[dev]); snd_port[dev],snd_irq[dev],snd_dma8[dev]);
pdev = acard->devmpu; pdev = acard->devmpu;
if (!pdev || pdev->prepare(pdev)<0) if (!pdev || pdev->prepare(pdev)<0)
......
...@@ -91,10 +91,10 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { ...@@ -91,10 +91,10 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819 }, { 0x41445303, 0xffffffff, "AD1819", patch_ad1819 },
{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881 }, { 0x41445340, 0xffffffff, "AD1881", patch_ad1881 },
{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881 }, { 0x41445348, 0xffffffff, "AD1881A", patch_ad1881 },
{ 0x41445360, 0xffffffff, "AD1885", patch_ad1881 }, { 0x41445360, 0xffffffff, "AD1885", patch_ad1885 },
{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886 }, { 0x41445361, 0xffffffff, "AD1886", patch_ad1886 },
{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881 }, { 0x41445362, 0xffffffff, "AD1887", patch_ad1881 },
{ 0x41445372, 0xffffffff, "AD1981A", NULL }, { 0x41445372, 0xffffffff, "AD1981A", patch_ad1881 },
{ 0x414c4300, 0xfffffff0, "RL5306", NULL }, { 0x414c4300, 0xfffffff0, "RL5306", NULL },
{ 0x414c4310, 0xfffffff0, "RL5382", NULL }, { 0x414c4310, 0xfffffff0, "RL5382", NULL },
{ 0x414c4320, 0xfffffff0, "RL5383", NULL }, { 0x414c4320, 0xfffffff0, "RL5383", NULL },
...@@ -240,12 +240,11 @@ void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value ...@@ -240,12 +240,11 @@ void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value
set_bit(reg, ac97->reg_accessed); set_bit(reg, ac97->reg_accessed);
} }
#ifndef CONFIG_SND_DEBUG
#define snd_ac97_write_cache_test snd_ac97_write_cache
#else
static void snd_ac97_write_cache_test(ac97_t *ac97, unsigned short reg, unsigned short value) static void snd_ac97_write_cache_test(ac97_t *ac97, unsigned short reg, unsigned short value)
{ {
return snd_ac97_write_cache(ac97, reg, value); if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed))
return;
#if 0
if (!snd_ac97_valid_reg(ac97, reg)) if (!snd_ac97_valid_reg(ac97, reg))
return; return;
spin_lock(&ac97->reg_lock); spin_lock(&ac97->reg_lock);
...@@ -254,8 +253,9 @@ static void snd_ac97_write_cache_test(ac97_t *ac97, unsigned short reg, unsigned ...@@ -254,8 +253,9 @@ static void snd_ac97_write_cache_test(ac97_t *ac97, unsigned short reg, unsigned
if (value != ac97->regs[reg]) if (value != ac97->regs[reg])
snd_printk("AC97 reg=%02x val=%04x real=%04x\n", reg, value, ac97->regs[reg]); snd_printk("AC97 reg=%02x val=%04x real=%04x\n", reg, value, ac97->regs[reg]);
spin_unlock(&ac97->reg_lock); spin_unlock(&ac97->reg_lock);
}
#endif #endif
snd_ac97_write_cache(ac97, reg, value);
}
int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value) int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
{ {
...@@ -911,6 +911,9 @@ static int snd_ac97_try_volume_mix(ac97_t * ac97, int reg) ...@@ -911,6 +911,9 @@ static int snd_ac97_try_volume_mix(ac97_t * ac97, int reg)
{ {
unsigned short val, mask = 0x8000; unsigned short val, mask = 0x8000;
if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed))
return 0;
switch (reg) { switch (reg) {
case AC97_MASTER_TONE: case AC97_MASTER_TONE:
return ac97->caps & 0x04 ? 1 : 0; return ac97->caps & 0x04 ? 1 : 0;
...@@ -1461,6 +1464,12 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97) ...@@ -1461,6 +1464,12 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
*ac97 = *_ac97; *ac97 = *_ac97;
ac97->card = card; ac97->card = card;
spin_lock_init(&ac97->reg_lock); spin_lock_init(&ac97->reg_lock);
if (ac97->reset) {
ac97->reset(ac97);
goto __access_ok;
}
snd_ac97_write(ac97, AC97_RESET, 0); /* reset to defaults */ snd_ac97_write(ac97, AC97_RESET, 0); /* reset to defaults */
if (ac97->wait) if (ac97->wait)
ac97->wait(ac97); ac97->wait(ac97);
...@@ -1499,6 +1508,10 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97) ...@@ -1499,6 +1508,10 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
snd_ac97_free(ac97); snd_ac97_free(ac97);
return -EIO; return -EIO;
} }
if (ac97->reset) // FIXME: always skipping?
goto __ready_ok;
/* FIXME: add powerdown control */ /* FIXME: add powerdown control */
/* nothing should be in powerdown mode */ /* nothing should be in powerdown mode */
snd_ac97_write_cache_test(ac97, AC97_POWERDOWN, 0); snd_ac97_write_cache_test(ac97, AC97_POWERDOWN, 0);
...@@ -1540,6 +1553,7 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97) ...@@ -1540,6 +1553,7 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
snd_ac97_determine_rates(ac97, AC97_PCM_LFE_DAC_RATE, &ac97->rates_lfe_dac); snd_ac97_determine_rates(ac97, AC97_PCM_LFE_DAC_RATE, &ac97->rates_lfe_dac);
ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC; ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
} }
/* additional initializations */
if (ac97->init) if (ac97->init)
ac97->init(ac97); ac97->init(ac97);
snd_ac97_get_name(ac97, ac97->id, name); snd_ac97_get_name(ac97, ac97->id, name);
...@@ -1738,6 +1752,9 @@ static void snd_ac97_proc_regs_read_main(ac97_t *ac97, snd_info_buffer_t * buffe ...@@ -1738,6 +1752,9 @@ static void snd_ac97_proc_regs_read_main(ac97_t *ac97, snd_info_buffer_t * buffe
int reg, val; int reg, val;
for (reg = 0; reg < 0x80; reg += 2) { for (reg = 0; reg < 0x80; reg += 2) {
if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed))
val = 0xffff;
else
val = snd_ac97_read(ac97, reg); val = snd_ac97_read(ac97, reg);
snd_iprintf(buffer, "%i:%02x = %04x\n", subidx, reg, val); snd_iprintf(buffer, "%i:%02x = %04x\n", subidx, reg, val);
} }
...@@ -1903,6 +1920,11 @@ void snd_ac97_resume(ac97_t *ac97) ...@@ -1903,6 +1920,11 @@ void snd_ac97_resume(ac97_t *ac97)
{ {
int i; int i;
if (ac97->reset) {
ac97->reset(ac97);
goto __reset_ready;
}
snd_ac97_write(ac97, AC97_POWERDOWN, 0); snd_ac97_write(ac97, AC97_POWERDOWN, 0);
snd_ac97_write(ac97, AC97_RESET, 0); snd_ac97_write(ac97, AC97_RESET, 0);
udelay(100); udelay(100);
...@@ -1916,6 +1938,7 @@ void snd_ac97_resume(ac97_t *ac97) ...@@ -1916,6 +1938,7 @@ void snd_ac97_resume(ac97_t *ac97)
break; break;
mdelay(1); mdelay(1);
} }
__reset_ready:
if (ac97->init) if (ac97->init)
ac97->init(ac97); ac97->init(ac97);
......
...@@ -300,6 +300,20 @@ int patch_ad1881(ac97_t * ac97) ...@@ -300,6 +300,20 @@ int patch_ad1881(ac97_t * ac97)
return 0; return 0;
} }
int patch_ad1885(ac97_t * ac97)
{
unsigned short jack;
patch_ad1881(ac97);
/* This is required to deal with the Intel D815EEAL2 */
/* i.e. Line out is actually headphone out from codec */
/* turn off jack sense bits D8 & D9 */
jack = snd_ac97_read(ac97, AC97_AD_JACK_SPDIF);
snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, jack | 0x0300);
return 0;
}
int patch_ad1886(ac97_t * ac97) int patch_ad1886(ac97_t * ac97)
{ {
patch_ad1881(ac97); patch_ad1881(ac97);
......
...@@ -35,4 +35,5 @@ int patch_cirrus_spdif(ac97_t * ac97); ...@@ -35,4 +35,5 @@ int patch_cirrus_spdif(ac97_t * ac97);
int patch_conexant(ac97_t * ac97); int patch_conexant(ac97_t * ac97);
int patch_ad1819(ac97_t * ac97); int patch_ad1819(ac97_t * ac97);
int patch_ad1881(ac97_t * ac97); int patch_ad1881(ac97_t * ac97);
int patch_ad1885(ac97_t * ac97);
int patch_ad1886(ac97_t * ac97); int patch_ad1886(ac97_t * ac97);
...@@ -1970,9 +1970,10 @@ static void snd_ali_resume(struct pci_dev *dev) ...@@ -1970,9 +1970,10 @@ static void snd_ali_resume(struct pci_dev *dev)
static int snd_ali_free(ali_t * codec) static int snd_ali_free(ali_t * codec)
{ {
snd_ali_disable_address_interrupt(codec); snd_ali_disable_address_interrupt(codec);
if (codec->irq >= 0) {
synchronize_irq(codec->irq); synchronize_irq(codec->irq);
if (codec->irq >=0)
free_irq(codec->irq, (void *)codec); free_irq(codec->irq, (void *)codec);
}
if (codec->res_port) { if (codec->res_port) {
release_resource(codec->res_port); release_resource(codec->res_port);
kfree_nocheck(codec->res_port); kfree_nocheck(codec->res_port);
......
...@@ -1300,7 +1300,7 @@ static int snd_cs4281_free(cs4281_t *chip) ...@@ -1300,7 +1300,7 @@ static int snd_cs4281_free(cs4281_t *chip)
} }
#endif #endif
snd_cs4281_proc_done(chip); snd_cs4281_proc_done(chip);
if(chip->irq >= 0) if (chip->irq >= 0)
synchronize_irq(chip->irq); synchronize_irq(chip->irq);
/* Mask interrupts */ /* Mask interrupts */
......
...@@ -64,7 +64,7 @@ static void mpu401_clear_rx(emu10k1_t *emu, emu10k1_midi_t *mpu) ...@@ -64,7 +64,7 @@ static void mpu401_clear_rx(emu10k1_t *emu, emu10k1_midi_t *mpu)
mpu401_read_data(emu, mpu); mpu401_read_data(emu, mpu);
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (timeout <= 0) if (timeout <= 0)
snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu)); snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
#endif #endif
} }
...@@ -143,7 +143,7 @@ static void snd_emu10k1_midi_cmd(emu10k1_t * emu, emu10k1_midi_t *midi, unsigned ...@@ -143,7 +143,7 @@ static void snd_emu10k1_midi_cmd(emu10k1_t * emu, emu10k1_midi_t *midi, unsigned
} }
spin_unlock_irqrestore(&midi->input_lock, flags); spin_unlock_irqrestore(&midi->input_lock, flags);
if (!ok) if (!ok)
snd_printk("midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n", snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
cmd, emu->port, cmd, emu->port,
mpu401_read_stat(emu, midi), mpu401_read_stat(emu, midi),
mpu401_read_data(emu, midi)); mpu401_read_data(emu, midi));
......
...@@ -968,11 +968,13 @@ static void snd_emu10k1_pcm_free(snd_pcm_t *pcm) ...@@ -968,11 +968,13 @@ static void snd_emu10k1_pcm_free(snd_pcm_t *pcm)
{ {
emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return); emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return);
emu->pcm = NULL; emu->pcm = NULL;
snd_pcm_lib_preallocate_free_for_all(pcm);
} }
int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
{ {
snd_pcm_t *pcm; snd_pcm_t *pcm;
snd_pcm_substream_t *substream;
int err; int err;
if (rpcm) if (rpcm)
...@@ -992,6 +994,10 @@ int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) ...@@ -992,6 +994,10 @@ int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
strcpy(pcm->name, "EMU10K1"); strcpy(pcm->name, "EMU10K1");
emu->pcm = pcm; emu->pcm = pcm;
for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next)
snd_pcm_lib_preallocate_pci_pages(emu->pci, substream, 64*1024, 64*1024);
return err;
if (rpcm) if (rpcm)
*rpcm = pcm; *rpcm = pcm;
......
...@@ -1532,7 +1532,6 @@ static int snd_ensoniq_free(ensoniq_t *ensoniq) ...@@ -1532,7 +1532,6 @@ static int snd_ensoniq_free(ensoniq_t *ensoniq)
outl(0, ES_REG(ensoniq, CONTROL)); /* switch everything off */ outl(0, ES_REG(ensoniq, CONTROL)); /* switch everything off */
outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */ outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */
#endif #endif
if(ensoniq->irq >= 0)
synchronize_irq(ensoniq->irq); synchronize_irq(ensoniq->irq);
pci_set_power_state(ensoniq->pci, 3); pci_set_power_state(ensoniq->pci, 3);
__hw_end: __hw_end:
......
...@@ -4072,7 +4072,7 @@ static int snd_ice1712_free(ice1712_t *ice) ...@@ -4072,7 +4072,7 @@ static int snd_ice1712_free(ice1712_t *ice)
/* --- */ /* --- */
__hw_end: __hw_end:
snd_ice1712_proc_done(ice); snd_ice1712_proc_done(ice);
if (ice->irq) { if (ice->irq >= 0) {
synchronize_irq(ice->irq); synchronize_irq(ice->irq);
free_irq(ice->irq, (void *) ice); free_irq(ice->irq, (void *) ice);
} }
...@@ -4146,7 +4146,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card, ...@@ -4146,7 +4146,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
pci_write_config_word(ice->pci, 0x40, 0x807f); pci_write_config_word(ice->pci, 0x40, 0x807f);
pci_write_config_word(ice->pci, 0x42, 0x0006); pci_write_config_word(ice->pci, 0x42, 0x0006);
snd_ice1712_proc_init(ice); snd_ice1712_proc_init(ice);
synchronize_irq(ice->irq); synchronize_irq(pci->irq);
if ((ice->res_port = request_region(ice->port, 32, "ICE1712 - Controller")) == NULL) { if ((ice->res_port = request_region(ice->port, 32, "ICE1712 - Controller")) == NULL) {
snd_ice1712_free(ice); snd_ice1712_free(ice);
......
...@@ -1104,7 +1104,6 @@ static int snd_intel8x0_free(intel8x0_t *chip) ...@@ -1104,7 +1104,6 @@ static int snd_intel8x0_free(intel8x0_t *chip)
outb(ICH_RESETREGS, ICHREG(chip, PO_CR)); outb(ICH_RESETREGS, ICHREG(chip, PO_CR));
outb(ICH_RESETREGS, ICHREG(chip, MC_CR)); outb(ICH_RESETREGS, ICHREG(chip, MC_CR));
/* --- */ /* --- */
if(chip->irq >= 0)
synchronize_irq(chip->irq); synchronize_irq(chip->irq);
__hw_end: __hw_end:
if (chip->bdbars) if (chip->bdbars)
......
...@@ -2310,7 +2310,7 @@ static int snd_m3_free(m3_t *chip) ...@@ -2310,7 +2310,7 @@ static int snd_m3_free(m3_t *chip)
vfree(chip->suspend_mem); vfree(chip->suspend_mem);
#endif #endif
if(chip->irq >= 0) if (chip->irq >= 0)
synchronize_irq(chip->irq); synchronize_irq(chip->irq);
if (chip->iobase_res) { if (chip->iobase_res) {
......
...@@ -892,7 +892,7 @@ static snd_pcm_ops_t snd_nm256_capture_ops = { ...@@ -892,7 +892,7 @@ static snd_pcm_ops_t snd_nm256_capture_ops = {
#endif #endif
}; };
static int __init static int __devinit
snd_nm256_pcm(nm256_t *chip, int device) snd_nm256_pcm(nm256_t *chip, int device)
{ {
snd_pcm_t *pcm; snd_pcm_t *pcm;
...@@ -1188,21 +1188,31 @@ snd_nm256_ac97_reset(ac97_t *ac97) ...@@ -1188,21 +1188,31 @@ snd_nm256_ac97_reset(ac97_t *ac97)
} }
/* create an ac97 mixer interface */ /* create an ac97 mixer interface */
static int __init static int __devinit
snd_nm256_mixer(nm256_t *chip) snd_nm256_mixer(nm256_t *chip)
{ {
ac97_t ac97; ac97_t ac97;
int err; int i;
/* looks like nm256 hangs up when unexpected registers are touched... */
static int mixer_regs[] = {
AC97_MASTER, AC97_HEADPHONE, AC97_MASTER_MONO,
AC97_PC_BEEP, AC97_PHONE, AC97_MIC, AC97_LINE,
AC97_VIDEO, AC97_AUX, AC97_PCM, AC97_REC_SEL,
AC97_REC_GAIN, AC97_GENERAL_PURPOSE, AC97_3D_CONTROL,
AC97_EXTENDED_ID, AC97_EXTENDED_STATUS,
AC97_VENDOR_ID1, AC97_VENDOR_ID2,
-1
};
memset(&ac97, 0, sizeof(ac97)); memset(&ac97, 0, sizeof(ac97));
ac97.init = snd_nm256_ac97_reset; ac97.reset = snd_nm256_ac97_reset;
ac97.write = snd_nm256_ac97_write; ac97.write = snd_nm256_ac97_write;
ac97.read = snd_nm256_ac97_read; ac97.read = snd_nm256_ac97_read;
ac97.limited_regs = 1;
for (i = 0; mixer_regs[i] >= 0; i++)
set_bit(mixer_regs[i], ac97.reg_accessed);
ac97.private_data = chip; ac97.private_data = chip;
if ((err = snd_ac97_mixer(chip->card, &ac97, &chip->ac97)) < 0) return snd_ac97_mixer(chip->card, &ac97, &chip->ac97);
return err;
return 0;
} }
/* /*
...@@ -1211,7 +1221,7 @@ snd_nm256_mixer(nm256_t *chip) ...@@ -1211,7 +1221,7 @@ snd_nm256_mixer(nm256_t *chip)
* RAM. * RAM.
*/ */
static int __init static int __devinit
snd_nm256_peek_for_sig(nm256_t *chip) snd_nm256_peek_for_sig(nm256_t *chip)
{ {
/* The signature is located 1K below the end of video RAM. */ /* The signature is located 1K below the end of video RAM. */
...@@ -1346,7 +1356,7 @@ static int snd_nm256_free(nm256_t *chip) ...@@ -1346,7 +1356,7 @@ static int snd_nm256_free(nm256_t *chip)
if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running) if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running)
snd_nm256_capture_stop(chip); snd_nm256_capture_stop(chip);
if(chip->irq >= 0) if (chip->irq >= 0)
synchronize_irq(chip->irq); synchronize_irq(chip->irq);
if (chip->cport) if (chip->cport)
...@@ -1374,7 +1384,7 @@ static int snd_nm256_dev_free(snd_device_t *device) ...@@ -1374,7 +1384,7 @@ static int snd_nm256_dev_free(snd_device_t *device)
return snd_nm256_free(chip); return snd_nm256_free(chip);
} }
static int __init static int __devinit
snd_nm256_create(snd_card_t *card, struct pci_dev *pci, snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
int play_bufsize, int capt_bufsize, int play_bufsize, int capt_bufsize,
int force_load, int force_load,
......
...@@ -238,7 +238,7 @@ struct _snd_via686a { ...@@ -238,7 +238,7 @@ struct _snd_via686a {
snd_card_t *card; snd_card_t *card;
snd_pcm_t *pcm; snd_pcm_t *pcm;
snd_pcm_t *pcm_fm; /*snd_pcm_t *pcm_fm;*/
viadev_t playback; viadev_t playback;
viadev_t capture; viadev_t capture;
/*viadev_t playback_fm;*/ /*viadev_t playback_fm;*/
...@@ -564,8 +564,13 @@ static inline unsigned int snd_via686a_cur_ptr(via686a_t *chip, viadev_t *viadev ...@@ -564,8 +564,13 @@ static inline unsigned int snd_via686a_cur_ptr(via686a_t *chip, viadev_t *viadev
val = 0; val = 0;
else else
val = ((ptr - (unsigned int)viadev->table_addr) / 8 - 1) % viadev->tbl_entries; val = ((ptr - (unsigned int)viadev->table_addr) / 8 - 1) % viadev->tbl_entries;
if (val < viadev->tbl_entries - 1) {
val *= viadev->tbl_size; val *= viadev->tbl_size;
val += viadev->tbl_size - count; val += viadev->tbl_size - count;
} else {
val *= viadev->tbl_size;
val += (viadev->size % viadev->tbl_size) + 1 - count;
}
viadev->lastptr = ptr; viadev->lastptr = ptr;
viadev->lastcount = count; viadev->lastcount = count;
// printk("pointer: ptr = 0x%x (%i), count = 0x%x, val = 0x%x\n", ptr, count, val); // printk("pointer: ptr = 0x%x (%i), count = 0x%x, val = 0x%x\n", ptr, count, val);
...@@ -632,10 +637,10 @@ static int snd_via686a_playback_open(snd_pcm_substream_t * substream) ...@@ -632,10 +637,10 @@ static int snd_via686a_playback_open(snd_pcm_substream_t * substream)
chip->playback.substream = substream; chip->playback.substream = substream;
runtime->hw = snd_via686a_playback; runtime->hw = snd_via686a_playback;
runtime->hw.rates = chip->ac97->rates_front_dac; runtime->hw.rates = chip->ac97->rates_front_dac;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err;
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
runtime->hw.rate_min = 48000; runtime->hw.rate_min = 48000;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err;
if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
return err; return err;
#if 0 #if 0
...@@ -658,10 +663,10 @@ static int snd_via686a_capture_open(snd_pcm_substream_t * substream) ...@@ -658,10 +663,10 @@ static int snd_via686a_capture_open(snd_pcm_substream_t * substream)
chip->capture.substream = substream; chip->capture.substream = substream;
runtime->hw = snd_via686a_capture; runtime->hw = snd_via686a_capture;
runtime->hw.rates = chip->ac97->rates_adc; runtime->hw.rates = chip->ac97->rates_adc;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err;
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
runtime->hw.rate_min = 48000; runtime->hw.rate_min = 48000;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err;
if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
return err; return err;
#if 0 #if 0
...@@ -1020,7 +1025,7 @@ static int __devinit snd_via686a_create(snd_card_t * card, ...@@ -1020,7 +1025,7 @@ static int __devinit snd_via686a_create(snd_card_t * card,
if (ac97_clock >= 8000 && ac97_clock <= 48000) if (ac97_clock >= 8000 && ac97_clock <= 48000)
chip->ac97_clock = ac97_clock; chip->ac97_clock = ac97_clock;
pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision); pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
synchronize_irq(pci->irq); synchronize_irq(chip->irq);
/* initialize offsets */ /* initialize offsets */
chip->playback.reg_offset = VIA_REG_PLAYBACK_STATUS; chip->playback.reg_offset = VIA_REG_PLAYBACK_STATUS;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment