size implementation. Everything got an explication, well and
now jackd behaves correctly, no more infinite amount of xruns.
I hope that should work OK now ...
/Benny
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx.h
../cvs/alsa-kernel/include/cs46xx.h
--- alsa-kernel/include/cs46xx.h Sat Nov 2 00:00:15 2002
+++ ../cvs/alsa-kernel/include/cs46xx.h Sun Nov 3 21:03:28 2002
@@ -1766,6 +1766,7 @@
int snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
int snd_cs46xx_mixer(cs46xx_t *chip);
int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi);
+int snd_cs46xx_start_dsp(cs46xx_t *chip);
void snd_cs46xx_gameport(cs46xx_t *chip);
#ifdef CONFIG_PM
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx_dsp_spos.h
../cvs/alsa-kernel/include/cs46xx_dsp_spos.h
--- alsa-kernel/include/cs46xx_dsp_spos.h Sat Nov 2 00:00:15 2002
+++ ../cvs/alsa-kernel/include/cs46xx_dsp_spos.h Sun Nov 3 20:12:31 2002
@@ -36,20 +36,20 @@
#define SEGTYPE_SP_COEFFICIENT 0x00000004
#define DSP_SPOS_UU 0x0deadul /* unused */
-#define DSP_SPOS_DC 0x0badul /* dont care */
-#define DSP_SPOS_DC_DC 0x0bad0badul /* dont care */
+#define DSP_SPOS_DC 0x0badul /* dont care */
+#define DSP_SPOS_DC_DC 0x0bad0badul /* dont care */
#define DSP_SPOS_UUUU 0xdeadc0edul /* unused */
#define DSP_SPOS_UUHI 0xdeadul
#define DSP_SPOS_UULO 0xc0edul
-#define DSP_SPOS_DCDC 0x0badf1d0ul /* dont care */
+#define DSP_SPOS_DCDC 0x0badf1d0ul /* dont care */
#define DSP_SPOS_DCDCHI 0x0badul
#define DSP_SPOS_DCDCLO 0xf1d0ul
-#define DSP_MAX_TASK_NAME 60
+#define DSP_MAX_TASK_NAME 60
#define DSP_MAX_SYMBOL_NAME 100
-#define DSP_MAX_SCB_NAME 60
-#define DSP_MAX_SCB_DESC 200
-#define DSP_MAX_TASK_DESC 50
+#define DSP_MAX_SCB_NAME 60
+#define DSP_MAX_SCB_DESC 200
+#define DSP_MAX_TASK_DESC 50
#define DSP_MAX_PCM_CHANNELS 32
#define DSP_MAX_SRC_NR 6
@@ -59,6 +59,10 @@
#define DSP_PCM_CENTER_CHANNEL 3
#define DSP_PCM_LFE_CHANNEL 4
#define DSP_IEC958_CHANNEL 5
+
+#define DSP_SDPIF_STATUS_OUTPUT_ENABLED 1
+#define DSP_SDPIF_STATUS_PLAYBACK_OPEN 2
+#define DSP_SDPIF_STATUS_HW_ENABLED 4
struct _dsp_module_desc_t;
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx.c
../cvs/alsa-kernel/pci/cs46xx/cs46xx.c
--- alsa-kernel/pci/cs46xx/cs46xx.c Sat Nov 2 00:00:21 2002
+++ ../cvs/alsa-kernel/pci/cs46xx/cs46xx.c Sun Nov 3 21:09:14 2002
@@ -110,14 +110,16 @@
snd_card_free(card);
return err;
}
- if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+ if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
+ snd_card_free(card);
+ return err;
+ }
+#endif
if ((err = snd_cs46xx_mixer(chip)) < 0) {
snd_card_free(card);
return err;
@@ -126,6 +128,12 @@
snd_card_free(card);
return err;
}
+ if ((err = snd_cs46xx_start_dsp(chip)) < 0) {
+ snd_card_free(card);
+ return err;
+ }
+
+
snd_cs46xx_gameport(chip);
strcpy(card->driver, "CS46xx");
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx_lib.c
../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.c
--- alsa-kernel/pci/cs46xx/cs46xx_lib.c Sat Nov 2 00:00:23 2002
+++ ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.c Mon Nov 4 02:04:58 2002
@@ -445,19 +445,19 @@
snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
}
-static int cs46xx_wait_for_fifo(cs46xx_t * chip)
+static int cs46xx_wait_for_fifo(cs46xx_t * chip,int retry_timeout)
{
u32 i, status;
/*
* Make sure the previous FIFO write operation has completed.
*/
- for(i = 0; i < 20; i++){
+ for(i = 0; i < 50; i++){
status = snd_cs46xx_peekBA0(chip, BA0_SERBST);
if( !(status & SERBST_WBSY) )
break;
- udelay(50);
+ mdelay(retry_timeout);
}
if(status & SERBST_WBSY) {
@@ -498,7 +498,7 @@
/*
* Make sure the previous FIFO write operation has completed.
*/
- if (cs46xx_wait_for_fifo(chip)) {
+ if (cs46xx_wait_for_fifo(chip,1)) {
snd_printdd ("failed waiting for FIFO at addr (%02X)\n",idx);
if (powerdown)
@@ -728,6 +728,8 @@
snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_sframes_t diff;
cs46xx_pcm_t * cpcm;
+ int buffer_size = runtime->period_size * CS46XX_FRAGS * 4;
+
cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return
-ENXIO);
diff = runtime->control->appl_ptr - cpcm->appl_ptr;
@@ -738,11 +740,11 @@
}
cpcm->sw_ready += frames << cpcm->shift;
cpcm->appl_ptr = runtime->control->appl_ptr + frames;
- while (cpcm->hw_ready < CS46XX_BUFFER_SIZE &&
+ while (cpcm->hw_ready < buffer_size &&
cpcm->sw_ready > 0) {
- size_t hw_to_end = CS46XX_BUFFER_SIZE - cpcm->hw_data;
+ size_t hw_to_end = buffer_size - cpcm->hw_data;
size_t sw_to_end = cpcm->sw_bufsize - cpcm->sw_data;
- size_t bytes = CS46XX_BUFFER_SIZE - cpcm->hw_ready;
+ size_t bytes = buffer_size - cpcm->hw_ready;
if (cpcm->sw_ready < bytes)
bytes = cpcm->sw_ready;
if (hw_to_end < bytes)
@@ -753,7 +755,7 @@
runtime->dma_area + cpcm->sw_data,
bytes);
cpcm->hw_data += bytes;
- if (cpcm->hw_data == CS46XX_BUFFER_SIZE)
+ if (cpcm->hw_data == buffer_size)
cpcm->hw_data = 0;
cpcm->sw_data += bytes;
if (cpcm->sw_data == cpcm->sw_bufsize)
@@ -770,6 +772,7 @@
cs46xx_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_sframes_t diff = runtime->control->appl_ptr - chip->capt.appl_ptr;
+ int buffer_size = runtime->period_size * CS46XX_FRAGS * 4;
if (diff) {
if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
diff += runtime->boundary;
@@ -779,7 +782,7 @@
chip->capt.appl_ptr = runtime->control->appl_ptr + frames;
while (chip->capt.hw_ready > 0 &&
chip->capt.sw_ready < chip->capt.sw_bufsize) {
- size_t hw_to_end = CS46XX_BUFFER_SIZE - chip->capt.hw_data;
+ size_t hw_to_end = buffer_size - chip->capt.hw_data;
size_t sw_to_end = chip->capt.sw_bufsize - chip->capt.sw_data;
size_t bytes = chip->capt.sw_bufsize - chip->capt.sw_ready;
if (chip->capt.hw_ready < bytes)
@@ -792,7 +795,7 @@
chip->capt.hw_area + chip->capt.hw_data,
bytes);
chip->capt.hw_data += bytes;
- if (chip->capt.hw_data == CS46XX_BUFFER_SIZE)
+ if (chip->capt.hw_data == buffer_size)
chip->capt.hw_data = 0;
chip->capt.sw_data += bytes;
if (chip->capt.sw_data == chip->capt.sw_bufsize)
@@ -825,6 +828,7 @@
size_t ptr;
cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t,
substream->runtime->private_data, return -ENXIO);
ssize_t bytes;
+ int buffer_size = substream->runtime->period_size * CS46XX_FRAGS * 4;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
snd_assert (cpcm->pcm_channel,return -ENXIO);
@@ -837,7 +841,7 @@
bytes = ptr - cpcm->hw_io;
if (bytes < 0)
- bytes += CS46XX_BUFFER_SIZE;
+ bytes += buffer_size;
cpcm->hw_io = ptr;
cpcm->hw_ready -= bytes;
cpcm->sw_io += bytes;
@@ -859,8 +863,10 @@
cs46xx_t *chip = snd_pcm_substream_chip(substream);
size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_addr;
ssize_t bytes = ptr - chip->capt.hw_io;
+ int buffer_size = substream->runtime->period_size * CS46XX_FRAGS * 4;
+
if (bytes < 0)
- bytes += CS46XX_BUFFER_SIZE;
+ bytes += buffer_size;
chip->capt.hw_io = ptr;
chip->capt.hw_ready += bytes;
chip->capt.sw_io += bytes;
@@ -1023,6 +1029,7 @@
int err;
cs46xx_t *chip = snd_pcm_substream_chip(substream);
int sample_rate = params_rate(hw_params);
+ int period_size = params_period_size(hw_params);
cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO);
#ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -1047,8 +1054,8 @@
cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip,
sample_rate, cpcm,
- cpcm->hw_addr,
-
cpcm->pcm_channel->pcm_channel_id)) == NULL) {
+ cpcm->hw_addr,
+
+cpcm->pcm_channel->pcm_channel_id)) == NULL) {
snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM
channel\n");
up (&chip->spos_mutex);
return -ENXIO;
@@ -1058,6 +1065,12 @@
cpcm->pcm_channel->sample_rate = sample_rate;
}
+ if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size *
+4)) {
+ up (&chip->spos_mutex);
+ return -EINVAL;
+ }
+ snd_printdd ("period_size (%d), periods (%d)\n",
+ period_size, params_periods(hw_params));
#endif
if (params_periods(hw_params) == CS46XX_FRAGS) {
@@ -1089,7 +1102,9 @@
runtime->dma_bytes = 0;
}
if ((err = snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params))) < 0) {
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
up (&chip->spos_mutex);
+#endif
return err;
}
@@ -1211,7 +1226,13 @@
cs46xx_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
+ int period_size = params_period_size(hw_params);
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+ snd_printdd ("capture period size (%d)\n",period_size);
+
+ cs46xx_dsp_pcm_ostream_set_period (chip,period_size * 4);
+#endif
if (runtime->periods == CS46XX_FRAGS) {
if (runtime->dma_area != chip->capt.hw_area)
snd_pcm_lib_free_pages(substream);
@@ -1368,8 +1389,8 @@
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = (256 * 1024),
- .period_bytes_min = CS46XX_PERIOD_SIZE,
- .period_bytes_max = CS46XX_PERIOD_SIZE,
+ .period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
+ .period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
.periods_min = CS46XX_FRAGS,
.periods_max = 1024,
.fifo_size = 0,
@@ -1388,13 +1409,23 @@
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = (256 * 1024),
- .period_bytes_min = CS46XX_PERIOD_SIZE,
- .period_bytes_max = CS46XX_PERIOD_SIZE,
+ .period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
+ .period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
.periods_min = CS46XX_FRAGS,
.periods_max = 1024,
.fifo_size = 0,
};
+static unsigned int period_sizes[] = { 8, 16, 32, 64, 128, 256, 512 };
+
+#define PERIOD_SIZES sizeof(period_sizes) / sizeof(period_sizes[0])
+
+static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
+ .count = PERIOD_SIZES,
+ .list = period_sizes,
+ .mask = 0
+};
+
static void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime)
{
cs46xx_pcm_t * cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data,
return);
@@ -1435,6 +1466,8 @@
return -ENOMEM;
}
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ &hw_constraints_period_sizes);
up (&chip->spos_mutex);
#else
chip->playback_pcm = cpcm; /* HACK */
@@ -1467,7 +1500,10 @@
cs46xx_t *chip = snd_pcm_substream_chip(substream);
snd_printdd("open raw iec958 channel\n");
+
+ down (&chip->spos_mutex);
cs46xx_iec958_pre_open (chip);
+ up (&chip->spos_mutex);
return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
}
@@ -1479,8 +1515,13 @@
int err;
cs46xx_t *chip = snd_pcm_substream_chip(substream);
+ snd_printdd("close raw iec958 channel\n");
+
err = snd_cs46xx_playback_close(substream);
+
+ down (&chip->spos_mutex);
cs46xx_iec958_post_close (chip);
+ up (&chip->spos_mutex);
return err;
}
@@ -1501,6 +1542,10 @@
chip->active_ctrl(chip, 1);
chip->amplifier_ctrl(chip, 1);
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ &hw_constraints_period_sizes);
+#endif
return 0;
}
@@ -1645,6 +1690,7 @@
snd_pcm_lib_preallocate_free_for_all(pcm);
}
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
static void snd_cs46xx_pcm_rear_free(snd_pcm_t *pcm)
{
cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return);
@@ -1659,7 +1705,6 @@
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
#define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
#else
#define MAX_PLAYBACK_CHANNELS 1
@@ -1846,7 +1891,7 @@
int reg = kcontrol->private_value;
if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
- ucontrol->value.integer.value[0] =
chip->dsp_spos_instance->spdif_status_out;
+ ucontrol->value.integer.value[0] =
+(chip->dsp_spos_instance->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED);
else
ucontrol->value.integer.value[0] =
chip->dsp_spos_instance->spdif_status_in;
@@ -1861,13 +1906,15 @@
switch (kcontrol->private_value) {
case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
- change = chip->dsp_spos_instance->spdif_status_out;
+ down (&chip->spos_mutex);
+ change = (chip->dsp_spos_instance->spdif_status_out &
+DSP_SDPIF_STATUS_OUTPUT_ENABLED);
if (ucontrol->value.integer.value[0] && !change)
cs46xx_dsp_enable_spdif_out(chip);
else if (change && !ucontrol->value.integer.value[0])
cs46xx_dsp_disable_spdif_out(chip);
- res = (change != chip->dsp_spos_instance->spdif_status_out);
+ res = (change != (chip->dsp_spos_instance->spdif_status_out &
+DSP_SDPIF_STATUS_OUTPUT_ENABLED));
+ up (&chip->spos_mutex);
break;
case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
change = chip->dsp_spos_instance->spdif_status_in;
@@ -2785,10 +2832,8 @@
/*
* initialize chip
*/
-
static int snd_cs46xx_chip_init(cs46xx_t *chip, int busywait)
{
- unsigned int tmp;
int timeout;
/*
@@ -2897,6 +2942,7 @@
snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
+
#ifdef CONFIG_SND_CS46XX_NEW_DSP
snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN);
snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0);
@@ -2907,6 +2953,7 @@
mdelay(5);
+
/*
* Wait for the codec ready signal from the AC97 codec.
*/
@@ -2959,6 +3006,7 @@
snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
#endif
+
/*
* Wait until we've sampled input slots 3 and 4 as valid, meaning that
* the codec is pumping ADC data across the AC-link.
@@ -2987,7 +3035,10 @@
* Now, assert valid frame and the slot 3 and 4 valid bits. This will
* commense the transfer of digital audio data to the AC97 codec.
*/
- snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4 | ACOSV_SLV7 |
ACOSV_SLV8);
+
+ snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4 |
+ ACOSV_SLV7 | ACOSV_SLV8);
+
/*
* Power down the DAC and ADC. We will power them up (if) when we need
@@ -3002,13 +3053,21 @@
/* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */
/* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */
+ return 0;
+}
+
+/*
+ * start and load DSP
+ */
+int __devinit snd_cs46xx_start_dsp(cs46xx_t *chip)
+{
+ unsigned int tmp;
/*
- * Reset the processor.
- */
+ * Reset the processor.
+ */
snd_cs46xx_reset(chip);
-
/*
- * Download the image to the processor.
+ * Download the image to the processor.
*/
#ifdef CONFIG_SND_CS46XX_NEW_DSP
#if 0
@@ -3040,7 +3099,6 @@
if (cs46xx_dsp_scb_and_task_init(chip) < 0)
return -EIO;
- snd_printdd("[get here]\n");
#else
/* old image */
if (snd_cs46xx_download_image(chip) < 0) {
@@ -3074,7 +3132,7 @@
* Enable interrupts on the part.
*/
snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
-
+
tmp = snd_cs46xx_peek(chip, BA1_PFIE);
tmp &= ~0x0000f03f;
snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
@@ -3084,19 +3142,24 @@
tmp |= 0x00000001;
snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* set the attenuation to 0dB */
- snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
- snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
+ snd_cs46xx_poke(chip, (MASTERMIX_SCB_ADDR + 0xE) << 2, 0x80008000);
+ snd_cs46xx_poke(chip, (VARIDECIMATE_SCB_ADDR + 0xE) << 2, 0x80008000);
+
+ /*
+ * Initialize cs46xx SPDIF controller
+ */
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* time countdown enable */
cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x80000000);
-
+
/* SPDIF input MASTER ENABLE */
cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x800003ff);
-
- /* mute spdif out */
- cs46xx_dsp_disable_spdif_out(chip);
+#else
+ /* set the attenuation to 0dB */
+ snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
+ snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
#endif
return 0;
@@ -3175,21 +3238,16 @@
valid_slots |= 0x200;
snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
- valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV2);
- valid_slots |= 0x200;
- snd_cs46xx_pokeBA0(chip, BA0_ACOSV2, valid_slots);
+ if ( cs46xx_wait_for_fifo(chip,1) ) {
+ snd_printdd("FIFO is busy\n");
+
+ return -EINVAL;
+ }
/*
* Fill slots 12 with the correct value for the GPIO pins.
*/
for(idx = 0x90; idx <= 0x9F; idx++) {
-
- if ( cs46xx_wait_for_fifo(chip) ) {
- snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx);
-
- return -EINVAL;
- }
-
/*
* Initialize the fifo so that bits 7 and 8 are on.
*
@@ -3197,6 +3255,15 @@
* the left. 0x1800 corresponds to bits 7 and 8.
*/
snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800);
+
+ /*
+ * Wait for command to complete
+ */
+ if ( cs46xx_wait_for_fifo(chip,200) ) {
+ snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx);
+
+ return -EINVAL;
+ }
/*
* Write the serial port FIFO index.
@@ -3207,14 +3274,10 @@
* Tell the serial port to load the new value into the FIFO location.
*/
snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
-
- /*
- * Wait for command to complete
- */
}
/* wait for last command to complete */
- cs46xx_wait_for_fifo(chip);
+ cs46xx_wait_for_fifo(chip,200);
/*
* Now, if we powered up the devices, then power them back down again.
@@ -3690,7 +3753,7 @@
snd_cs46xx_free(chip);
return err;
}
-
+
chip->active_ctrl(chip, -1);
*rchip = chip;
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx_lib.h
../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h
--- alsa-kernel/pci/cs46xx/cs46xx_lib.h Sat Nov 2 00:00:23 2002
+++ ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h Mon Nov 4 01:59:15 2002
@@ -35,9 +35,17 @@
#define CS46XX_BA1_REG_SIZE 0x0100
-#define CS46XX_PERIOD_SIZE 2048
+
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+#define CS46XX_MIN_PERIOD_SIZE 1
+#define CS46XX_MAX_PERIOD_SIZE 1024*1024
+#else
+#define CS46XX_MIN_PERIOD_SIZE 2048
+#define CS46XX_MAX_PERIOD_SIZE 2048
+#endif
+
#define CS46XX_FRAGS 2
-#define CS46XX_BUFFER_SIZE CS46XX_PERIOD_SIZE * CS46XX_FRAGS
+/* #define CS46XX_BUFFER_SIZE CS46XX_MAX_PERIOD_SIZE * CS46XX_FRAGS */
#define SCB_NO_PARENT 0
#define SCB_ON_PARENT_NEXT_SCB 1
@@ -100,6 +108,7 @@
unsigned long len);
int snd_cs46xx_clear_BA1(cs46xx_t *chip,unsigned long
offset,unsigned long len);
int cs46xx_dsp_enable_spdif_out (cs46xx_t *chip);
+int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip);
int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip);
int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip);
int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip);
@@ -199,8 +208,13 @@
int cs46xx_dsp_pcm_link (cs46xx_t *
chip,pcm_channel_descriptor_t * pcm_channel);
dsp_scb_descriptor_t * cs46xx_add_record_source (cs46xx_t
*chip,dsp_scb_descriptor_t * source,
u16 addr,char * scb_name);
-int cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t *
src);
-int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t *
src);
-int cs46xx_iec958_pre_open (cs46xx_t *chip);
-int cs46xx_iec958_post_close (cs46xx_t *chip);
+int cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t *
+src);
+int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src);
+int cs46xx_iec958_pre_open (cs46xx_t *chip);
+int cs46xx_iec958_post_close (cs46xx_t *chip);
+int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
+
+pcm_channel_descriptor_t * pcm_channel,
+ int period_size);
+int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
+ int period_size);
#endif /* __CS46XX_LIB_H__ */
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.c
../cvs/alsa-kernel/pci/cs46xx/dsp_spos.c
--- alsa-kernel/pci/cs46xx/dsp_spos.c Sat Nov 2 00:00:23 2002
+++ ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.c Sun Nov 3 21:10:49 2002
@@ -1021,8 +1021,6 @@
dsp_scb_descriptor_t * record_mix_scb;
dsp_scb_descriptor_t * write_back_scb;
dsp_scb_descriptor_t * vari_decimate_scb;
- dsp_scb_descriptor_t * pcm_serial_input_task;
- dsp_scb_descriptor_t * asynch_tx_scb;
dsp_scb_descriptor_t * sec_codec_out_scb;
dsp_scb_descriptor_t * magic_snoop_scb;
@@ -1096,6 +1094,7 @@
ins->the_null_scb->sub_list_ptr = ins->the_null_scb;
ins->the_null_scb->next_scb_ptr = ins->the_null_scb;
ins->the_null_scb->parent_scb_ptr = NULL;
+ cs46xx_dsp_proc_register_scb_desc (chip,ins->the_null_scb);
}
{
@@ -1265,9 +1264,9 @@
/* create codec in */
codec_in_scb = cs46xx_dsp_create_codec_in_scb(chip,"CodecInSCB",0x0010,0x00A0,
- CODEC_INPUT_BUF1,
- CODECIN_SCB_ADDR,codec_out_scb,
- SCB_ON_PARENT_NEXT_SCB);
+ CODEC_INPUT_BUF1,
+ CODECIN_SCB_ADDR,codec_out_scb,
+ SCB_ON_PARENT_NEXT_SCB);
if (!codec_in_scb) goto _fail_end;
ins->codec_in_scb = codec_in_scb;
@@ -1318,10 +1317,10 @@
/* create the rear PCM channel mixer SCB */
rear_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RearMixerSCB",
- MIX_SAMPLE_BUF3,
- REAR_MIXER_SCB_ADDR,
- sec_codec_out_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
+ MIX_SAMPLE_BUF3,
+ REAR_MIXER_SCB_ADDR,
+ sec_codec_out_scb,
+ SCB_ON_PARENT_SUBLIST_SCB);
ins->rear_mix_scb = rear_mix_scb;
if (!rear_mix_scb) goto _fail_end;
@@ -1336,29 +1335,9 @@
if (!magic_snoop_scb) goto _fail_end;
ins->ref_snoop_scb = magic_snoop_scb;
-
- /* The asynch. transfer task */
- asynch_tx_scb =
cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
- SPDIFO_SCB_INST,
- SPDIFO_IP_OUTPUT_BUFFER1,
- master_mix_scb,
- SCB_ON_PARENT_NEXT_SCB);
-
- if (!asynch_tx_scb) goto _fail_end;
- ins->asynch_tx_scb = asynch_tx_scb;
-
- /* pcm input */
- pcm_serial_input_task =
cs46xx_dsp_create_pcm_serial_input_scb(chip,"PCMSerialInput_II",
-
PCMSERIALINII_SCB_ADDR,
-
magic_snoop_scb,asynch_tx_scb,
-
SCB_ON_PARENT_SUBLIST_SCB);
-
- if (!pcm_serial_input_task) goto _fail_end;
- ins->spdif_pcm_input_scb = pcm_serial_input_task;
-
/* SP IO access */
if (!cs46xx_dsp_create_spio_write_scb(chip,"SPIOWriteSCB",SPIOWRITE_SCB_ADDR,
- asynch_tx_scb,
+ magic_snoop_scb,
SCB_ON_PARENT_NEXT_SCB))
goto _fail_end;
@@ -1518,6 +1497,7 @@
};
spdifo_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFOSCB",(u32
*)&spdifo_scb,SPDIFO_SCB_INST);
+
snd_assert(spdifo_scb_desc, return -EIO);
spdifi_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFISCB",(u32
*)&spdifi_scb,SPDIFI_SCB_INST);
snd_assert(spdifi_scb_desc, return -EIO);
@@ -1543,6 +1523,11 @@
is the FG task tree */
fg_entry->parent_scb_ptr = spdifo_scb_desc;
+ /* for proc fs */
+ cs46xx_dsp_proc_register_scb_desc (chip,spdifo_scb_desc);
+ cs46xx_dsp_proc_register_scb_desc (chip,spdifi_scb_desc);
+ cs46xx_dsp_proc_register_scb_desc (chip,async_codec_scb_desc);
+
/* Async MASTER ENABLE, affects both SPDIF input and output */
snd_cs46xx_pokeBA0(chip, BA0_ASER_MASTER, 0x1 );
}
@@ -1550,7 +1535,7 @@
return 0;
}
-int cs46xx_dsp_enable_spdif_out (cs46xx_t *chip)
+int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
@@ -1560,29 +1545,11 @@
/* SPDIF output MASTER ENABLE */
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0x80000000);
- /* right and left validate bit
- NOTE: 0x80000000 and enables the SCMC protection on stream
- */
+ /* right and left validate bit */
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12));
/* monitor state */
- ins->spdif_status_out = 1;
-
- return 0;
-}
-
-int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip)
-{
- dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-
- /* disable SPDIF output FIFO slot */
- snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, 0);
-
- /* SPDIF output MASTER DISABLE */
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0x0);
-
- /* monitor state */
- ins->spdif_status_out = 0;
+ ins->spdif_status_out |= DSP_SDPIF_STATUS_HW_ENABLED;
return 0;
}
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.h
../cvs/alsa-kernel/pci/cs46xx/dsp_spos.h
--- alsa-kernel/pci/cs46xx/dsp_spos.h Sat Nov 2 00:00:23 2002
+++ ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.h Sat Nov 2 19:27:36 2002
@@ -183,5 +183,14 @@
#define SP_SPDOUT_CONTROL 0x804D
#define SP_SPDOUT_CSUV 0x808E
+static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t *
+scb)
+{
+ /* update nextSCB and subListPtr in SCB */
+ snd_cs46xx_poke(chip,
+ (scb->address + SCBsubListPtr) << 2,
+ (scb->sub_list_ptr->address << 0x10) |
+ (scb->next_scb_ptr->address));
+}
+
#endif /* __DSP_SPOS_H__ */
#endif /* CONFIG_SND_CS46XX_NEW_DSP */
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c
../cvs/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c
--- alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c Sat Nov 2 00:00:23 2002
+++ ../cvs/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c Sun Nov 3 22:44:21 2002
@@ -150,17 +150,11 @@
spin_lock_irqsave(&chip->reg_lock, flags);
/* update parent first entry in DSP RAM */
- snd_cs46xx_poke(chip,
- (scb->parent_scb_ptr->address + SCBsubListPtr) << 2,
- (scb->parent_scb_ptr->sub_list_ptr->address << 0x10) |
- (scb->parent_scb_ptr->next_scb_ptr->address));
+ cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
/* then update entry in DSP RAM */
- snd_cs46xx_poke(chip,
- (scb->address + SCBsubListPtr) << 2,
- (scb->sub_list_ptr->address << 0x10) |
- (scb->next_scb_ptr->address));
-
+ cs46xx_dsp_spos_update_scb(chip,scb);
+
scb->parent_scb_ptr = NULL;
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
@@ -173,6 +167,7 @@
for (i = 0; i < dword_count ; ++i ) {
writel(0, dst);
+ dst += 4;
}
}
@@ -328,11 +323,9 @@
}
spin_lock_irqsave(&chip->reg_lock, flags);
+
/* update entry in DSP RAM */
- snd_cs46xx_poke(chip,
- (scb->parent_scb_ptr->address + SCBsubListPtr) << 2,
- (scb->parent_scb_ptr->sub_list_ptr->address << 0x10) |
- (scb->parent_scb_ptr->next_scb_ptr->address));
+ cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
@@ -1242,6 +1235,83 @@
return (ins->pcm_channels + pcm_index);
}
+int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
+ pcm_channel_descriptor_t * pcm_channel,
+ int period_size)
+{
+ u32 temp = snd_cs46xx_peek (chip,pcm_channel->pcm_reader_scb->address << 2);
+ temp &= ~DMA_RQ_C1_SOURCE_SIZE_MASK;
+
+ switch (period_size) {
+ case 2048:
+ temp |= DMA_RQ_C1_SOURCE_MOD1024;
+ break;
+ case 1024:
+ temp |= DMA_RQ_C1_SOURCE_MOD512;
+ break;
+ case 512:
+ temp |= DMA_RQ_C1_SOURCE_MOD256;
+ break;
+ case 256:
+ temp |= DMA_RQ_C1_SOURCE_MOD128;
+ break;
+ case 128:
+ temp |= DMA_RQ_C1_SOURCE_MOD64;
+ break;
+ case 64:
+ temp |= DMA_RQ_C1_SOURCE_MOD32;
+ break;
+ case 32:
+ temp |= DMA_RQ_C1_SOURCE_MOD16;
+ break;
+ default:
+ snd_printdd ("period size (%d) not supported by HW\n");
+ return -EINVAL;
+ }
+
+ snd_cs46xx_poke (chip,pcm_channel->pcm_reader_scb->address << 2,temp);
+
+ return 0;
+}
+
+int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
+ int period_size)
+{
+ u32 temp = snd_cs46xx_peek (chip,WRITEBACK_SCB_ADDR << 2);
+ temp &= ~DMA_RQ_C1_DEST_SIZE_MASK;
+
+ switch (period_size) {
+ case 2048:
+ temp |= DMA_RQ_C1_DEST_MOD1024;
+ break;
+ case 1024:
+ temp |= DMA_RQ_C1_DEST_MOD512;
+ break;
+ case 512:
+ temp |= DMA_RQ_C1_DEST_MOD256;
+ break;
+ case 256:
+ temp |= DMA_RQ_C1_DEST_MOD128;
+ break;
+ case 128:
+ temp |= DMA_RQ_C1_DEST_MOD64;
+ break;
+ case 64:
+ temp |= DMA_RQ_C1_DEST_MOD32;
+ break;
+ case 32:
+ temp |= DMA_RQ_C1_DEST_MOD16;
+ break;
+ default:
+ snd_printdd ("period size (%d) not supported by HW\n");
+ return -EINVAL;
+ }
+
+ snd_cs46xx_poke (chip,WRITEBACK_SCB_ADDR << 2,temp);
+
+ return 0;
+}
+
void cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,pcm_channel_descriptor_t *
pcm_channel)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
@@ -1323,17 +1393,13 @@
snd_assert (pcm_channel->pcm_reader_scb->parent_scb_ptr == NULL, ; );
pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
- /* update entry in DSP RAM */
spin_lock_irqsave(&chip->reg_lock, flags);
- snd_cs46xx_poke(chip,
- (pcm_channel->pcm_reader_scb->address + SCBsubListPtr) << 2,
- (pcm_channel->pcm_reader_scb->sub_list_ptr->address << 0x10) |
- (pcm_channel->pcm_reader_scb->next_scb_ptr->address));
-
- snd_cs46xx_poke(chip,
- (parent_scb->address + SCBsubListPtr) << 2,
- (parent_scb->sub_list_ptr->address << 0x10) |
- (parent_scb->next_scb_ptr->address));
+
+ /* update SCB entry in DSP RAM */
+ cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb);
+
+ /* update parent SCB entry */
+ cs46xx_dsp_spos_update_scb(chip,parent_scb);
pcm_channel->unlinked = 0;
spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -1455,47 +1521,136 @@
src->parent_scb_ptr = parent_scb;
/* update entry in DSP RAM */
- snd_cs46xx_poke(chip,
- (parent_scb->address + SCBsubListPtr) << 2,
- (parent_scb->sub_list_ptr->address << 0x10) |
- (parent_scb->next_scb_ptr->address));
+ cs46xx_dsp_spos_update_scb(chip,parent_scb);
return 0;
}
-int cs46xx_iec958_pre_open (cs46xx_t *chip)
+int cs46xx_dsp_enable_spdif_out (cs46xx_t *chip)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
- snd_assert (ins->spdif_pcm_input_scb != NULL);
- snd_assert (ins->asynch_tx_scb->sub_list_ptr == ins->spdif_pcm_input_scb);
+ if ( ! (ins->spdif_status_out & DSP_SDPIF_STATUS_PLAYBACK_OPEN) ) {
+ cs46xx_dsp_enable_spdif_hw (chip);
+ }
+
+ /* dont touch anything if SPDIF is open */
+ if ( ins->spdif_status_out & DSP_SDPIF_STATUS_PLAYBACK_OPEN) {
+ /* when cs46xx_iec958_post_close(...) is called it
+ will call this function if necesary depending on
+ this bit */
+ ins->spdif_status_out |= DSP_SDPIF_STATUS_OUTPUT_ENABLED;
+
+ return -EBUSY;
+ }
+
+ snd_assert (ins->asynch_tx_scb == NULL, return -EINVAL);
+ snd_assert (ins->master_mix_scb->next_scb_ptr == ins->the_null_scb, return
+-EINVAL);
+
+ /* reset output snooper sample buffer pointer */
+ snd_cs46xx_poke (chip, (ins->ref_snoop_scb->address + 2) << 2,
+ (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10 );
+
+ /* The asynch. transfer task */
+ ins->asynch_tx_scb =
+cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
+ SPDIFO_SCB_INST,
+
+SPDIFO_IP_OUTPUT_BUFFER1,
+ ins->master_mix_scb,
+
+SCB_ON_PARENT_NEXT_SCB);
+ if (!ins->asynch_tx_scb) return -ENOMEM;
+
+ ins->spdif_pcm_input_scb =
+cs46xx_dsp_create_pcm_serial_input_scb(chip,"PCMSerialInput_II",
+
+PCMSERIALINII_SCB_ADDR,
+
+ins->ref_snoop_scb,
+
+ins->asynch_tx_scb,
+
+SCB_ON_PARENT_SUBLIST_SCB);
+
+
+ if (!ins->spdif_pcm_input_scb) return -ENOMEM;
- /*cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12)
| (1 << 2)); */
+ /* monitor state */
+ ins->spdif_status_out |= DSP_SDPIF_STATUS_OUTPUT_ENABLED;
- _dsp_unlink_scb (chip,ins->spdif_pcm_input_scb);
return 0;
}
-int cs46xx_iec958_post_close (cs46xx_t *chip)
+int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
- snd_assert (ins->spdif_pcm_input_scb != NULL);
- snd_assert (ins->asynch_tx_scb->sub_list_ptr == ins->the_null_scb);
- snd_assert (ins->spdif_pcm_input_scb->parent_scb_ptr == NULL);
+ /* dont touch anything if SPDIF is open */
+ if ( ins->spdif_status_out & DSP_SDPIF_STATUS_PLAYBACK_OPEN) {
+ ins->spdif_status_out &= ~DSP_SDPIF_STATUS_OUTPUT_ENABLED;
+ return -EBUSY;
+ }
+
+ /* check integrety */
+ snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
+ snd_assert (ins->spdif_pcm_input_scb != NULL,return -EINVAL);
+ snd_assert (ins->master_mix_scb->next_scb_ptr == ins->asynch_tx_scb, return
+-EINVAL);
+ snd_assert (ins->asynch_tx_scb->parent_scb_ptr == ins->master_mix_scb, return
+-EINVAL);
+
+ cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb);
+ cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
- /* relink the SPDIF output PCM ref */
- ins->asynch_tx_scb->sub_list_ptr = ins->spdif_pcm_input_scb;
- ins->spdif_pcm_input_scb->parent_scb_ptr = ins->asynch_tx_scb;
+ ins->spdif_pcm_input_scb = NULL;
+ ins->asynch_tx_scb = NULL;
+ /* clear buffer to prevent any undesired noise */
+ _dsp_clear_sample_buffer(chip,SPDIFO_IP_OUTPUT_BUFFER1,256);
- /* cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 <<
12)); */
+ /* monitor state */
+ ins->spdif_status_out &= ~DSP_SDPIF_STATUS_OUTPUT_ENABLED;
- /* update entry in DSP RAM */
- snd_cs46xx_poke(chip,
- (ins->asynch_tx_scb->address + SCBsubListPtr) << 2,
- (ins->asynch_tx_scb->sub_list_ptr->address << 0x10) |
- (ins->asynch_tx_scb->next_scb_ptr->address));
+ return 0;
+}
+
+int cs46xx_iec958_pre_open (cs46xx_t *chip)
+{
+ dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+
+ if ( ins->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED ) {
+ /* remove AsynchFGTxSCB and and PCMSerialInput_II */
+ cs46xx_dsp_disable_spdif_out (chip);
+
+ /* save state */
+ ins->spdif_status_out |= DSP_SDPIF_STATUS_OUTPUT_ENABLED;
+ }
+
+ /* Create the asynch. transfer task for playback */
+ ins->asynch_tx_scb =
+cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
+ SPDIFO_SCB_INST,
+
+SPDIFO_IP_OUTPUT_BUFFER1,
+ ins->master_mix_scb,
+
+SCB_ON_PARENT_NEXT_SCB);
+
+ /* cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 15) |
+ (1 << 14) | (1 << 2) | (1 << 3)); */
+
+ ins->spdif_status_out |= DSP_SDPIF_STATUS_PLAYBACK_OPEN;
+
+ return 0;
+}
+
+int cs46xx_iec958_post_close (cs46xx_t *chip)
+{
+ dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+
+ snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
+
+ ins->spdif_status_out &= ~DSP_SDPIF_STATUS_PLAYBACK_OPEN;
+
+ /*cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 <<
+12));*/
+
+ /* deallocate stuff */
+ cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
+ ins->asynch_tx_scb = NULL;
+
+ /* restore state */
+ if ( ins->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED ) {
+ cs46xx_dsp_enable_spdif_out (chip);
+ }
+
return 0;
}
