* [PATCH] audigyls.c updated to version 0.0.14
@ 2004-07-22 13:41 James Courtier-Dutton
0 siblings, 0 replies; only message in thread
From: James Courtier-Dutton @ 2004-07-22 13:41 UTC (permalink / raw)
To: ALSA development
[-- Attachment #1: Type: text/plain, Size: 567 bytes --]
Here is a patch against the alsa-driver cvs for the AudigyLS.
There is also a patch for alsa-lib AudigyLS.conf file.
Changelog:
0.0.12
Correct interrupt timing. interrupt at end of period,
instead of in the middle of a playback period.
Remove redundent "voice" handling.
0.0.13
Single trigger call for multi channels.
0.0.14
Set limits based on what the sound card hardware can do.
playback periods_min=2, periods_max=8
capture hw constraints require period_size = n * 64 bytes.
playback hw constraints require period_size = n * 64 bytes.
[-- Attachment #2: alsa-lib.audigyls.diff.txt --]
[-- Type: text/plain, Size: 751 bytes --]
Index: alsa-lib/src/conf/cards/AudigyLS.conf
===================================================================
RCS file: /cvsroot/alsa/alsa-lib/src/conf/cards/AudigyLS.conf,v
retrieving revision 1.3
diff -u -r1.3 AudigyLS.conf
--- alsa-lib/src/conf/cards/AudigyLS.conf 28 Jun 2004 10:26:45 -0000 1.3
+++ alsa-lib/src/conf/cards/AudigyLS.conf 22 Jul 2004 13:36:38 -0000
@@ -152,14 +152,14 @@
type ctl_elems
hook_args [
{
- name "PCM Front Volume"
+ name "SPDIF Front Volume"
index 0
lock true
preserve true
value [ 207 207 ] # Puts 0x30303030 in the Volume register. 0xff - 0x30 = 0xcf = 207
}
{
- name "Analog/Digital Output Jack"
+ name "SPDIF Out"
lock true
preserve true
value 0
[-- Attachment #3: alsa-driver.audigyls.c.0.0.14.diff.txt --]
[-- Type: text/plain, Size: 22686 bytes --]
Index: alsa-driver/pci/emu10k1/audigyls.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pci/emu10k1/audigyls.c,v
retrieving revision 1.9
diff -u -r1.9 audigyls.c
--- alsa-driver/pci/emu10k1/audigyls.c 12 Jul 2004 14:27:12 -0000 1.9
+++ alsa-driver/pci/emu10k1/audigyls.c 22 Jul 2004 13:23:06 -0000
@@ -1,7 +1,7 @@
/*
* Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
* Driver AUDIGYLS chips
- * Version: 0.0.11
+ * Version: 0.0.14
*
* FEATURES currently supported:
* Front, Rear and Center/LFE.
@@ -50,9 +50,19 @@
* Fix AC3 output.
* Enable S32_LE format support.
* 0.0.10
- * Enable 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
+ * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
* 0.0.11
* Add Model name recognition.
+ * 0.0.12
+ * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
+ * Remove redundent "voice" handling.
+ * 0.0.13
+ * Single trigger call for multi channels.
+ * 0.0.14
+ * Set limits based on what the sound card hardware can do.
+ * playback periods_min=2, periods_max=8
+ * capture hw constraints require period_size = n * 64 bytes.
+ * playback hw constraints require period_size = n * 64 bytes.
*
* BUGS:
* Some stability problems when unloading the snd-audigyls kernel module.
@@ -60,7 +70,7 @@
*
* TODO:
* 4 Capture channels, only one implemented so far.
- * Other rates apart from 48khz not implemented.
+ * Other capture rates apart from 48khz not implemented.
* MIDI
* --
* GENERAL INFO:
@@ -145,8 +155,11 @@
#define HCFG 0x14 /* Hardware config register */
/* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
-#define HCFG_8_CHANNEL 0x00000200 /* 1 = 8 channels, 0 = 2 channels per substream. */
-#define HCFG_S32_LE 0x00000800 /* 1 = S32_LE, 0 = S16_LE */
+#define HCFG_24KHZ_CAPTURE 0x10000000 /* Set 24khz capture rate. */
+#define HCFG_8_CHANNEL_CAPTURE 0x00000100 /* 1 = 8 channels, 0 = 2 channels per substream.*/
+#define HCFG_8_CHANNEL_PLAY 0x00000200 /* 1 = 8 channels, 0 = 2 channels per substream.*/
+#define HCFG_CAPTURE_MUTE 0x00000400 /* 1 = Mute caputre, 0 = capture normal. */
+#define HCFG_S32_LE 0x00000800 /* 1 = S32_LE, 0 = S16_LE */
#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
/* NOTE: This should generally never be used. */
#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
@@ -186,6 +199,7 @@
#define BASIC_INTERRUPT 0x40 /* Used by both playback and capture interrupt handler */
/* Playback (0x1<<channel_id) */
/* Capture (0x100<<channel_id) */
+ /* Playback sample rate 96000 = 0x20000 */
/* The Digital out jack is shared with the Center/LFE Analogue output.
* The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3
* For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground
@@ -247,8 +261,8 @@
#define CAPTURE_SOURCE_CHANNEL3 0x000f0000 /* 3 - Mic in, Line in, TAD in, Aux in. */
#define CAPTURE_SOURCE_LOOPBACK 0x0000ffff /* Default 0x00e4 */
-#define CAPTURE_VOLUME1 0x61 /* Capture volume per voice */
-#define CAPTURE_VOLUME2 0x62 /* Capture volume per voice */
+#define CAPTURE_VOLUME1 0x61 /* Capture volume per channel */
+#define CAPTURE_VOLUME2 0x62 /* Capture volume per channel */
#define PLAYBACK_ROUTING1 0x63 /* Playback routing. Effects AC3 output. Default 0x32765410 */
#define ROUTING1_REAR 0x77000000 /* Channel_id 0 sends to 10, Channel_id 1 sends to 32 */
@@ -258,12 +272,12 @@
#define PLAYBACK_ROUTING2 0x64 /* Unknown Routing. Effects AC3 output. Default 0x76767676 */
#define PLAYBACK_MUTE 0x65 /* Unknown. While playing 0x0, while silent 0x00fc0000 */
-#define PLAYBACK_VOLUME1 0x66 /* Playback volume per voice. Set to the same PLAYBACK_VOLUME(0x6a) */
+#define PLAYBACK_VOLUME1 0x66 /* Playback volume per channel. Set to the same PLAYBACK_VOLUME(0x6a) */
/* PLAYBACK_VOLUME1 must be set to 30303030 for SPDIF AC3 Playback */
#define CAPTURE_ROUTING1 0x67 /* Playback Routing. Default 0x32765410 */
#define CAPTURE_ROUTING2 0x68 /* Unknown Routing. Default 0x76767676 */
#define CAPTURE_MUTE 0x69 /* Unknown. While capturing 0x0, while silent 0x00fc0000 */
-#define PLAYBACK_VOLUME2 0x6a /* Playback volume per voice. Does not effect AC3 output */
+#define PLAYBACK_VOLUME2 0x6a /* Playback volume per channel. Does not effect AC3 output */
#define UNKNOWN6b 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
#define UART1 0x6c /* Uart, used in setting sample rates, bits per sample etc. */
#define UART2 0x6d /* Uart, used in setting sample rates, bits per sample etc. */
@@ -281,8 +295,20 @@
#define CHIP_VERSION 0x74 /* P17 Chip version. Channel_id 0 only. Default 00000071 */
#define EXTENDED_INT_MASK 0x75 /* Used by both playback and capture interrupt handler */
/* Sets which Interrupts are enabled. */
+ /* 0x00000001 = Half period. Playback.
+ * 0x00000010 = Full period. Playback.
+ * 0x00010000 = Half buffer. Capture.
+ * 0x00100000 = Full buffer. Capture.
+ * Capture can only do 2 periods.
+ */
#define EXTENDED_INT 0x76 /* Used by both playback and capture interrupt handler */
/* Shows which interrupts are active at the moment. */
+ /* 0x00000001 = Half period. Playback.
+ * 0x00000010 = Full period. Playback.
+ * 0x00010000 = Half buffer. Capture.
+ * 0x00100000 = Full buffer. Capture.
+ * Capture can only do 2 periods.
+ */
#define COUNTER77 0x77 /* Counter range 0 to 0x3fffff, 192000 counts per second. */
#define COUNTER78 0x78 /* Counter range 0 to 0x3fffff, 44100 counts per second. */
#define EXTENDED_INT_TIMER 0x79 /* Channel_id 0 only. Used by both playback and capture interrupt handler */
@@ -297,20 +323,10 @@
#define CONTROL_CENTER_LFE_CHANNEL 1
#define CONTROL_UNKNOWN_CHANNEL 2
-typedef struct snd_audigyls_voice audigyls_voice_t;
typedef struct snd_audigyls_channel audigyls_channel_t;
typedef struct snd_audigyls audigyls_t;
typedef struct snd_audigyls_pcm audigyls_pcm_t;
-struct snd_audigyls_voice {
- audigyls_t *emu;
- int number;
- int use;
- void (*interrupt)(audigyls_t *emu, audigyls_voice_t *pvoice);
-
- audigyls_pcm_t *epcm;
-};
-
struct snd_audigyls_channel {
audigyls_t *emu;
int number;
@@ -323,7 +339,6 @@
struct snd_audigyls_pcm {
audigyls_t *emu;
snd_pcm_substream_t *substream;
- audigyls_voice_t *voice;
int channel_id;
unsigned short running;
};
@@ -352,12 +367,10 @@
unsigned short model; /* subsystem id */
spinlock_t emu_lock;
- spinlock_t voice_lock;
ac97_t *ac97;
snd_pcm_t *pcm;
- audigyls_voice_t voices[4];
audigyls_channel_t channels[4];
audigyls_channel_t capture_channel;
u32 spdif_bits[4]; /* s/pdif out setup */
@@ -384,7 +397,7 @@
.period_bytes_min = 64,
.period_bytes_max = (16*1024),
.periods_min = 2,
- .periods_max = 16,
+ .periods_max = 8,
.fifo_size = 0,
};
@@ -450,54 +463,6 @@
spin_unlock_irqrestore(&emu->emu_lock, flags);
}
-static int voice_alloc(audigyls_t *emu, audigyls_voice_t **rvoice)
-{
- audigyls_voice_t *voice;
- int idx;
-
- *rvoice = NULL;
- for (idx = 0; idx < 4; idx ++) {
- voice = &emu->voices[idx];
- if (voice->use)
- continue;
- voice->use = 1;
- *rvoice = voice;
- return 0;
- }
- return -ENOMEM;
-}
-
-static int snd_audigyls_voice_alloc(audigyls_t *emu, audigyls_voice_t **rvoice)
-{
- unsigned long flags;
- int result;
-
- snd_assert(rvoice != NULL, return -EINVAL);
-
- spin_lock_irqsave(&emu->voice_lock, flags);
-
- result = voice_alloc(emu, rvoice);
-
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-
- return result;
-}
-
-static int snd_audigyls_voice_free(audigyls_t *emu, audigyls_voice_t *pvoice)
-{
- unsigned long flags;
-
- snd_assert(pvoice != NULL, return -EINVAL);
- spin_lock_irqsave(&emu->voice_lock, flags);
-
- pvoice->interrupt = NULL;
- pvoice->use = 0;
- pvoice->epcm = NULL;
-
- spin_unlock_irqrestore(&emu->voice_lock, flags);
- return 0;
-}
-
static void snd_audigyls_pcm_free_substream(snd_pcm_runtime_t *runtime)
{
audigyls_pcm_t *epcm = runtime->private_data;
@@ -507,30 +472,6 @@
}
}
-static void snd_audigyls_pcm_interrupt(audigyls_t *emu, audigyls_voice_t *voice)
-{
- audigyls_pcm_t *epcm;
-
- if ((epcm = voice->epcm) == NULL)
- return;
- if (epcm->substream == NULL)
- return;
- snd_pcm_period_elapsed(epcm->substream);
-}
-
-#if 0 /* not used */
-static void snd_audigyls_pcm_channel_interrupt(audigyls_t *emu, audigyls_voice_t *voice)
-{
- audigyls_pcm_t *epcm;
- if ((epcm = voice->epcm) == NULL)
- return;
- if (epcm->substream == NULL)
- return;
- snd_pcm_period_elapsed(epcm->substream);
-}
-#endif
-
-
/* open_playback callback */
static int snd_audigyls_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
{
@@ -538,6 +479,7 @@
audigyls_channel_t *channel = &(chip->channels[channel_id]);
audigyls_pcm_t *epcm;
snd_pcm_runtime_t *runtime = substream->runtime;
+ int err;
epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
@@ -559,6 +501,10 @@
//printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
//channel->interrupt = snd_audigyls_pcm_channel_interrupt;
channel->epcm=epcm;
+ if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ return err;
+ if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+ return err;
return 0;
}
@@ -600,6 +546,7 @@
audigyls_channel_t *channel = &(chip->capture_channel);
audigyls_pcm_t *epcm;
snd_pcm_runtime_t *runtime = substream->runtime;
+ int err;
epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL) {
@@ -622,6 +569,11 @@
//printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
//channel->interrupt = snd_audigyls_pcm_channel_interrupt;
channel->epcm=epcm;
+ if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ return err;
+ //snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes);
+ if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+ return err;
return 0;
}
@@ -645,17 +597,6 @@
static int snd_audigyls_pcm_hw_params_playback(snd_pcm_substream_t *substream,
snd_pcm_hw_params_t * hw_params)
{
- int err;
- snd_pcm_runtime_t *runtime = substream->runtime;
- audigyls_pcm_t *epcm = runtime->private_data;
-
- if (! epcm->voice) {
- if ((err = snd_audigyls_voice_alloc(epcm->emu, &epcm->voice)) < 0)
- return err;
- epcm->voice->epcm = epcm;
- epcm->voice->interrupt = snd_audigyls_pcm_interrupt;
- }
-
return snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params));
}
@@ -663,18 +604,6 @@
/* hw_free callback */
static int snd_audigyls_pcm_hw_free_playback(snd_pcm_substream_t *substream)
{
- snd_pcm_runtime_t *runtime = substream->runtime;
- audigyls_pcm_t *epcm;
-
- if (runtime->private_data == NULL)
- return 0;
- epcm = runtime->private_data;
-
- if (epcm->voice) {
- snd_audigyls_voice_free(epcm->emu, epcm->voice);
- epcm->voice = NULL;
- }
-
return snd_pcm_lib_free_pages(substream);
}
@@ -689,11 +618,6 @@
/* hw_free callback */
static int snd_audigyls_pcm_hw_free_capture(snd_pcm_substream_t *substream)
{
- snd_pcm_runtime_t *runtime = substream->runtime;
-
- if (runtime->private_data == NULL)
- return 0;
-
return snd_pcm_lib_free_pages(substream);
}
@@ -703,8 +627,8 @@
audigyls_t *emu = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
audigyls_pcm_t *epcm = runtime->private_data;
- int voice = voice=epcm->channel_id;
- u32 *table_base = (u32 *)(emu->buffer.area+(8*16*voice));
+ int channel = epcm->channel_id;
+ u32 *table_base = (u32 *)(emu->buffer.area+(8*16*channel));
u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
u32 hcfg_mask = 0x00000800; /* We only know what bits 17 and 19 do. */
u32 hcfg_set = 0x00000000;
@@ -714,7 +638,7 @@
u32 reg40;
int i;
- snd_printk("prepare:voice_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",voice, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
+ //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
//snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
//snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
switch (runtime->rate) {
@@ -752,14 +676,14 @@
table_base[(i*2)+1]=period_size_bytes<<16;
}
- snd_audigyls_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->buffer.addr+(8*16*voice));
- snd_audigyls_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
- snd_audigyls_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
- snd_audigyls_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr);
- snd_audigyls_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
- snd_audigyls_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
- snd_audigyls_ptr_write(emu, 0x07, voice, 0x0);
- snd_audigyls_ptr_write(emu, 0x08, voice, 0);
+ snd_audigyls_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel));
+ snd_audigyls_ptr_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
+ snd_audigyls_ptr_write(emu, PLAYBACK_LIST_PTR, channel, 0);
+ snd_audigyls_ptr_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
+ snd_audigyls_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
+ snd_audigyls_ptr_write(emu, PLAYBACK_POINTER, channel, 0);
+ snd_audigyls_ptr_write(emu, 0x07, channel, 0x0);
+ snd_audigyls_ptr_write(emu, 0x08, channel, 0);
snd_audigyls_ptr_write(emu, PLAYBACK_MUTE, 0x0, 0x0); /* Unmute output */
#if 0
snd_audigyls_ptr_write(emu, SPCS0, 0,
@@ -769,10 +693,6 @@
0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
}
#endif
- //snd_audigyls_ptr_write(emu, SPCS0, 0, 0x2108006);
- //snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, 0x33); /* Routing of some sort */
- //snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, 0x11 << voice); /* Routing of some sort */
- snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_audigyls_ptr_read(emu, EXTENDED_INT_MASK, 0) | (0x11<<voice));
return 0;
}
@@ -783,14 +703,12 @@
audigyls_t *emu = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
audigyls_pcm_t *epcm = runtime->private_data;
- int voice = epcm->voice->number;
- voice=epcm->channel_id;
- //printk("prepare:voice_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",voice, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1));
- snd_audigyls_ptr_write(emu, 0x13, voice, 0);
- snd_audigyls_ptr_write(emu, CAPTURE_DMA_ADDR, voice, runtime->dma_addr);
- snd_audigyls_ptr_write(emu, CAPTURE_BUFFER_SIZE, voice, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
- snd_audigyls_ptr_write(emu, CAPTURE_POINTER, voice, 0);
- snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_audigyls_ptr_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<voice));
+ int channel = epcm->channel_id;
+ //printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1));
+ snd_audigyls_ptr_write(emu, 0x13, channel, 0);
+ snd_audigyls_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
+ snd_audigyls_ptr_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
+ snd_audigyls_ptr_write(emu, CAPTURE_POINTER, channel, 0);
return 0;
}
@@ -800,21 +718,46 @@
int cmd)
{
audigyls_t *emu = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
- audigyls_pcm_t *epcm = runtime->private_data;
- int channel = epcm->voice->number;
+ snd_pcm_runtime_t *runtime;
+ audigyls_pcm_t *epcm;
+ int channel;
int result = 0;
- channel=epcm->channel_id;
+ struct list_head *pos;
+ snd_pcm_substream_t *s;
+ u32 basic = 0;
+ u32 extended = 0;
+ int running=0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- snd_audigyls_ptr_write(emu, BASIC_INTERRUPT, 0, snd_audigyls_ptr_read(emu, BASIC_INTERRUPT, 0)|(0x1<<channel));
- epcm->running = 1;
+ running=1;
break;
case SNDRV_PCM_TRIGGER_STOP:
- snd_audigyls_ptr_write(emu, BASIC_INTERRUPT, 0, snd_audigyls_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(0x1<<channel));
- snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_audigyls_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(0x11<<channel));
- epcm->running = 0;
+ default:
+ running=0;
+ break;
+ }
+ snd_pcm_group_for_each(pos, substream) {
+ s = snd_pcm_group_substream_entry(pos);
+ runtime = s->runtime;
+ epcm = runtime->private_data;
+ channel = epcm->channel_id;
+ //snd_printk("channel=%d\n",channel);
+ epcm->running = running;
+ basic |= (0x1<<channel);
+ extended |= (0x10<<channel);
+ snd_pcm_trigger_done(s, substream);
+ }
+ //snd_printk("basic=0x%x, extended=0x%x\n",basic, extended);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_audigyls_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended));
+ snd_audigyls_ptr_write(emu, BASIC_INTERRUPT, 0, snd_audigyls_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic));
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ snd_audigyls_ptr_write(emu, BASIC_INTERRUPT, 0, snd_audigyls_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
+ snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_audigyls_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended));
break;
default:
result = -EINVAL;
@@ -830,12 +773,12 @@
audigyls_t *emu = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
audigyls_pcm_t *epcm = runtime->private_data;
- int channel = epcm->voice->number;
+ int channel = epcm->channel_id;
int result = 0;
- channel=epcm->channel_id;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ snd_audigyls_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_audigyls_ptr_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
snd_audigyls_ptr_write(emu, BASIC_INTERRUPT, 0, snd_audigyls_ptr_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
epcm->running = 1;
break;
@@ -859,8 +802,7 @@
snd_pcm_runtime_t *runtime = substream->runtime;
audigyls_pcm_t *epcm = runtime->private_data;
snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
- int channel = epcm->voice->number;
- channel=epcm->channel_id;
+ int channel = epcm->channel_id;
if (!epcm->running)
return 0;
@@ -887,8 +829,7 @@
snd_pcm_runtime_t *runtime = substream->runtime;
audigyls_pcm_t *epcm = runtime->private_data;
snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
- int channel = epcm->voice->number;
- channel=epcm->channel_id;
+ int channel = channel=epcm->channel_id;
if (!epcm->running)
return 0;
@@ -1064,8 +1005,9 @@
if (! status)
return IRQ_NONE;
- //printk(KERN_INFO "interrupt status = %08x, chip=%p, channel=%p\n", status,chip, chip->channels);
stat76 = snd_audigyls_ptr_read(chip, EXTENDED_INT, 0);
+ //snd_printk("interrupt status = 0x%08x, stat76=0x%08x\n", status, stat76);
+ //snd_printk("ptr=0x%08x\n",snd_audigyls_ptr_read(chip, PLAYBACK_POINTER, 0));
//mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */
for(i = 0; i < 4; i++) {
@@ -1076,8 +1018,6 @@
snd_pcm_period_elapsed(pchannel->epcm->substream);
//printk(KERN_INFO "interrupt [%d] used\n", i);
}
- //if(pvoice->use && pvoice->interrupt)
- // pvoice->interrupt(chip, pvoice);
}
//printk(KERN_INFO "channel=%p\n",pchannel);
//printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
@@ -1199,7 +1139,6 @@
chip->irq = -1;
spin_lock_init(&chip->emu_lock);
- spin_lock_init(&chip->voice_lock);
chip->port = pci_resource_start(pci, 0);
if ((chip->res_port = request_region(chip->port, 0x20,
@@ -1239,11 +1178,6 @@
outl(0, chip->port + INTE);
- for(ch = 0; ch < 4; ch++) {
- chip->voices[ch].emu = chip;
- chip->voices[ch].number = ch;
- }
-
/*
* Init to 0x02109204 :
* Clock accuracy = 0 (1000ppm)
@@ -1317,6 +1251,8 @@
for(ch = 0; ch < 4; ch++) {
snd_audigyls_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */
snd_audigyls_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
+ //snd_audigyls_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */
+ //snd_audigyls_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */
snd_audigyls_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */
snd_audigyls_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-07-22 13:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-22 13:41 [PATCH] audigyls.c updated to version 0.0.14 James Courtier-Dutton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.