Commit 2f2fc324 authored by Jaroslav Kysela's avatar Jaroslav Kysela

Merge http://linux.bkbits.net/linux-2.5

into suse.cz:/home/perex/bk/linux-sound/linux-sound
parents 7f9f9f51 bf734625
...@@ -63,7 +63,6 @@ ...@@ -63,7 +63,6 @@
#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1 #define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
#define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2 #define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2
#define DSP_SPDIF_STATUS_HW_ENABLED 4 #define DSP_SPDIF_STATUS_HW_ENABLED 4
#define DSP_SPDIF_STATUS_AC3_MODE 8
struct _dsp_module_desc_t; struct _dsp_module_desc_t;
...@@ -196,6 +195,10 @@ typedef struct _dsp_spos_instance_t { ...@@ -196,6 +195,10 @@ typedef struct _dsp_spos_instance_t {
int spdif_status_in; int spdif_status_in;
u16 spdif_input_volume_right; u16 spdif_input_volume_right;
u16 spdif_input_volume_left; u16 spdif_input_volume_left;
/* spdif channel status,
left right and user validity bits */
int spdif_csuv_default;
int spdif_csuv_stream;
/* SPDIF input sample rate converter */ /* SPDIF input sample rate converter */
dsp_scb_descriptor_t * spdif_in_src; dsp_scb_descriptor_t * spdif_in_src;
......
...@@ -101,10 +101,18 @@ ...@@ -101,10 +101,18 @@
/* Global registers */ /* Global registers */
enum global_control_bits { enum global_control_bits {
CHANNEL_IDX = 0x0000003f, OVERRUN_IE = 0x00000400, CHANNEL_IDX = 0x0000003f,
UNDERRUN_IE = 0x00000800, ENDLP_IE = 0x00001000, OVERRUN_IE = 0x00000400, /* interrupt enable: capture overrun */
MIDLP_IE = 0x00002000, ETOG_IE = 0x00004000, UNDERRUN_IE = 0x00000800, /* interrupt enable: playback underrun */
EDROP_IE = 0x00008000, BANK_B_EN = 0x00010000 ENDLP_IE = 0x00001000, /* interrupt enable: end of buffer */
MIDLP_IE = 0x00002000, /* interrupt enable: middle buffer */
ETOG_IE = 0x00004000, /* interrupt enable: envelope toggling */
EDROP_IE = 0x00008000, /* interrupt enable: envelope drop */
BANK_B_EN = 0x00010000, /* SiS: enable bank B (64 channels) */
PCMIN_B_MIX = 0x00020000, /* SiS: PCM IN B mixing enable */
I2S_OUT_ASSIGN = 0x00040000, /* SiS: I2S Out contains surround PCM */
SPDIF_OUT_ASSIGN= 0x00080000, /* SiS: 0=S/PDIF L/R | 1=PCM Out FIFO */
MAIN_OUT_ASSIGN = 0x00100000, /* SiS: 0=PCM Out FIFO | 1=MMC Out buffer */
}; };
enum miscint_bits { enum miscint_bits {
...@@ -423,6 +431,8 @@ struct _snd_trident { ...@@ -423,6 +431,8 @@ struct _snd_trident {
int ChanPCM; /* max number of PCM channels */ int ChanPCM; /* max number of PCM channels */
int ChanPCMcnt; /* actual number of PCM channels */ int ChanPCMcnt; /* actual number of PCM channels */
int ac97_detect; /* 1 = AC97 in detection phase */
struct _snd_4dwave synth; /* synth specific variables */ struct _snd_4dwave synth; /* synth specific variables */
spinlock_t event_lock; spinlock_t event_lock;
......
/* include/version.h. Generated automatically by configure. */ /* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc5" #define CONFIG_SND_VERSION "0.9.0rc5"
#define CONFIG_SND_DATE " (Sun Nov 10 19:48:18 2002 UTC)" #define CONFIG_SND_DATE " (Sat Nov 23 10:12:47 2002 UTC)"
...@@ -266,7 +266,6 @@ static int snd_opl3_seq_new_device(snd_seq_device_t *dev) ...@@ -266,7 +266,6 @@ static int snd_opl3_seq_new_device(snd_seq_device_t *dev)
snd_seq_fm_init(&opl3->fm_ops, NULL); snd_seq_fm_init(&opl3->fm_ops, NULL);
/* setup system timer */ /* setup system timer */
memset(&opl3->tlist, 0, sizeof(opl3->tlist));
init_timer(&opl3->tlist); init_timer(&opl3->tlist);
opl3->tlist.function = snd_opl3_timer_func; opl3->tlist.function = snd_opl3_timer_func;
opl3->tlist.data = (unsigned long) opl3; opl3->tlist.data = (unsigned long) opl3;
......
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
#define SNDRV_GET_ID #define SNDRV_GET_ID
#include <sound/initval.h> #include <sound/initval.h>
/* hack: OSS defines midi_devs, so undefine it (versioned symbols) */
#undef midi_devs
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("Dummy soundcard for virtual rawmidi devices"); MODULE_DESCRIPTION("Dummy soundcard for virtual rawmidi devices");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -10,6 +10,12 @@ ...@@ -10,6 +10,12 @@
* Note: 16-bit wide is assigned to first direction which made request. * Note: 16-bit wide is assigned to first direction which made request.
* With full duplex - playback is preferred with abstract layer. * With full duplex - playback is preferred with abstract layer.
* *
* Note: Some chip revisions have hardware bug. Changing capture
* channel from full-duplex 8bit DMA to 16bit DMA will block
* 16bit DMA transfers from DSP chip (capture) until 8bit transfer
* to DSP chip (playback) starts. This bug can be avoided with
* "16bit DMA Allocation" setting set to Playback or Capture.
*
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
......
...@@ -950,15 +950,15 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, ...@@ -950,15 +950,15 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
/* magic value to unmute PCM stream playback volume */
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
SCBVolumeCtrl) << 2, 0x80007fff);
if (cpcm->pcm_channel->unlinked) if (cpcm->pcm_channel->unlinked)
cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel); cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
if (substream->runtime->periods != CS46XX_FRAGS) if (substream->runtime->periods != CS46XX_FRAGS)
snd_cs46xx_playback_transfer(substream, 0); snd_cs46xx_playback_transfer(substream, 0);
/* raise playback volume */
cs46xx_dsp_scb_set_volume (chip,cpcm->pcm_channel->pcm_reader_scb,
chip->dsp_spos_instance->dac_volume_right,
chip->dsp_spos_instance->dac_volume_left);
#else #else
if (substream->runtime->periods != CS46XX_FRAGS) if (substream->runtime->periods != CS46XX_FRAGS)
snd_cs46xx_playback_transfer(substream, 0); snd_cs46xx_playback_transfer(substream, 0);
...@@ -972,8 +972,9 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, ...@@ -972,8 +972,9 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
/* mute channel */ /* magic mute channel */
cs46xx_dsp_scb_set_volume (chip,cpcm->pcm_channel->pcm_reader_scb,0,0); snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
SCBVolumeCtrl) << 2, 0xffffffff);
if (!cpcm->pcm_channel->unlinked) if (!cpcm->pcm_channel->unlinked)
cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel); cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
...@@ -1067,6 +1068,7 @@ static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm, ...@@ -1067,6 +1068,7 @@ static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
} }
#endif #endif
static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream, static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params) snd_pcm_hw_params_t * hw_params)
{ {
...@@ -1083,15 +1085,10 @@ static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream, ...@@ -1083,15 +1085,10 @@ static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
down (&chip->spos_mutex); down (&chip->spos_mutex);
snd_assert (cpcm->pcm_channel != NULL); snd_assert (cpcm->pcm_channel != NULL);
/* if IEC958 is opened in AC3 mode dont adjust SRCTask is not if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
used so dont adjust sample rate */ up (&chip->spos_mutex);
if (cpcm->pcm_channel->pcm_channel_id != DSP_IEC958_CHANNEL || return -ENXIO;
!(chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE)) {
if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
up (&chip->spos_mutex);
return -ENXIO;
}
} }
if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size * 4)) { if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size * 4)) {
...@@ -2042,34 +2039,6 @@ static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol, ...@@ -2042,34 +2039,6 @@ static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol,
return 0; return 0;
} }
static int snd_cs46xx_iec958_ac3_mode_get(snd_kcontrol_t *kcontrol,
snd_ctl_elem_value_t *ucontrol)
{
cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
if (!ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE)
ucontrol->value.integer.value[0] = 1;
else
ucontrol->value.integer.value[0] = 0;
return 0;
}
static int snd_cs46xx_iec958_ac3_mode_put(snd_kcontrol_t *kcontrol,
snd_ctl_elem_value_t *ucontrol)
{
cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
int old = ins->spdif_status_out;
if (ucontrol->value.integer.value[0])
ins->spdif_status_out |= DSP_SPDIF_STATUS_AC3_MODE;
else
ins->spdif_status_out &= ~DSP_SPDIF_STATUS_AC3_MODE;
return (old != ins->spdif_status_out);
}
static int snd_cs46xx_pcm_capture_put(snd_kcontrol_t *kcontrol, static int snd_cs46xx_pcm_capture_put(snd_kcontrol_t *kcontrol,
snd_ctl_elem_value_t *ucontrol) snd_ctl_elem_value_t *ucontrol)
...@@ -2131,6 +2100,110 @@ static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol, ...@@ -2131,6 +2100,110 @@ static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol,
return (val1 != snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); return (val1 != snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
} }
static int snd_cs46xx_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
return 0;
}
static int snd_cs46xx_spdif_default_get(snd_kcontrol_t * kcontrol,
snd_ctl_elem_value_t * ucontrol)
{
cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
down (&chip->spos_mutex);
ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
ucontrol->value.iec958.status[2] = 0;
ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
up (&chip->spos_mutex);
return 0;
}
static int snd_cs46xx_spdif_default_put(snd_kcontrol_t * kcontrol,
snd_ctl_elem_value_t * ucontrol)
{
cs46xx_t * chip = snd_kcontrol_chip(kcontrol);
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
unsigned int val;
int change;
down (&chip->spos_mutex);
val = _wrap_all_bits(((u32)ucontrol->value.iec958.status[0] << 24)) |
_wrap_all_bits(((u32)ucontrol->value.iec958.status[2] << 16)) |
_wrap_all_bits( (u32)ucontrol->value.iec958.status[3]) |
/* left and right validity bit */
(1 << 13) | (1 << 12);
change = ins->spdif_csuv_default != val;
ins->spdif_csuv_default = val;
if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
up (&chip->spos_mutex);
return change;
}
static int snd_cs46xx_spdif_mask_get(snd_kcontrol_t * kcontrol,
snd_ctl_elem_value_t * ucontrol)
{
ucontrol->value.iec958.status[0] = 0xff;
ucontrol->value.iec958.status[1] = 0xff;
ucontrol->value.iec958.status[2] = 0x00;
ucontrol->value.iec958.status[3] = 0xff;
return 0;
}
static int snd_cs46xx_spdif_stream_get(snd_kcontrol_t * kcontrol,
snd_ctl_elem_value_t * ucontrol)
{
cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
down (&chip->spos_mutex);
ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
ucontrol->value.iec958.status[2] = 0;
ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
up (&chip->spos_mutex);
return 0;
}
static int snd_cs46xx_spdif_stream_put(snd_kcontrol_t * kcontrol,
snd_ctl_elem_value_t * ucontrol)
{
cs46xx_t * chip = snd_kcontrol_chip(kcontrol);
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
unsigned int val;
int change;
down (&chip->spos_mutex);
val = _wrap_all_bits(((u32)ucontrol->value.iec958.status[0] << 24)) |
_wrap_all_bits(((u32)ucontrol->value.iec958.status[1] << 16)) |
_wrap_all_bits( (u32)ucontrol->value.iec958.status[3]) |
/* left and right validity bit */
(1 << 13) | (1 << 12);
change = ins->spdif_csuv_stream != val;
ins->spdif_csuv_stream = val;
if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
up (&chip->spos_mutex);
return change;
}
#endif /* CONFIG_SND_CS46XX_NEW_DSP */ #endif /* CONFIG_SND_CS46XX_NEW_DSP */
#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
...@@ -2242,7 +2315,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { ...@@ -2242,7 +2315,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
}, },
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC 958 Output Switch", .name = "IEC958 Output Switch",
.info = snd_mixer_boolean_info, .info = snd_mixer_boolean_info,
.get = snd_cs46xx_iec958_get, .get = snd_cs46xx_iec958_get,
.put = snd_cs46xx_iec958_put, .put = snd_cs46xx_iec958_put,
...@@ -2250,14 +2323,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { ...@@ -2250,14 +2323,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
}, },
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC 958 AC3 Mode Switch", .name = "IEC958 Input Switch",
.info = snd_mixer_boolean_info,
.get = snd_cs46xx_iec958_ac3_mode_get,
.put = snd_cs46xx_iec958_ac3_mode_put,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC 958 Input Switch",
.info = snd_mixer_boolean_info, .info = snd_mixer_boolean_info,
.get = snd_cs46xx_iec958_get, .get = snd_cs46xx_iec958_get,
.put = snd_cs46xx_iec958_put, .put = snd_cs46xx_iec958_put,
...@@ -2265,12 +2331,34 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { ...@@ -2265,12 +2331,34 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
}, },
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC 958 Input Volume", .name = "IEC958 Input Volume",
.info = snd_cs46xx_vol_info, .info = snd_cs46xx_vol_info,
.get = snd_cs46xx_vol_iec958_get, .get = snd_cs46xx_vol_iec958_get,
.put = snd_cs46xx_vol_iec958_put, .put = snd_cs46xx_vol_iec958_put,
.private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2, .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
}, },
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
.info = snd_cs46xx_spdif_info,
.get = snd_cs46xx_spdif_default_get,
.put = snd_cs46xx_spdif_default_put,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
.info = snd_cs46xx_spdif_info,
.get = snd_cs46xx_spdif_mask_get,
.access = SNDRV_CTL_ELEM_ACCESS_READ
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
.info = snd_cs46xx_spdif_info,
.get = snd_cs46xx_spdif_stream_get,
.put = snd_cs46xx_spdif_stream_put
},
#endif #endif
#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
{ {
......
...@@ -217,6 +217,6 @@ int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip, ...@@ -217,6 +217,6 @@ int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
int period_size); int period_size);
int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip, int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
int period_size); int period_size);
int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 right,u16 left); int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 left,u16 right);
int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 right,u16 left); int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 left,u16 right);
#endif /* __CS46XX_LIB_H__ */ #endif /* __CS46XX_LIB_H__ */
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <sound/core.h> #include <sound/core.h>
#include <sound/control.h> #include <sound/control.h>
#include <sound/info.h> #include <sound/info.h>
#include <sound/asoundef.h>
#include <sound/cs46xx.h> #include <sound/cs46xx.h>
#include "cs46xx_lib.h" #include "cs46xx_lib.h"
...@@ -262,6 +263,15 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip) ...@@ -262,6 +263,15 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
ins->spdif_input_volume_right = 0x8000; ins->spdif_input_volume_right = 0x8000;
ins->spdif_input_volume_left = 0x8000; ins->spdif_input_volume_left = 0x8000;
/* set left and right validity bits and
default channel status */
ins->spdif_csuv_default =
ins->spdif_csuv_stream =
/* byte 0 */ (_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) |
/* byte 1 */ (_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 16) & 0xff)) << 16) |
/* byte 3 */ _wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) |
/* left and right validity bits */ (1 << 13) | (1 << 12);
return ins; return ins;
} }
...@@ -1549,7 +1559,7 @@ int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip) ...@@ -1549,7 +1559,7 @@ int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip)
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0x80000000); cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0x80000000);
/* right and left validate bit */ /* right and left validate bit */
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12)); cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);
/* monitor state */ /* monitor state */
ins->spdif_status_out |= DSP_SPDIF_STATUS_HW_ENABLED; ins->spdif_status_out |= DSP_SPDIF_STATUS_HW_ENABLED;
...@@ -1587,11 +1597,6 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip) ...@@ -1587,11 +1597,6 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0); cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);
cs46xx_src_link(chip,ins->spdif_in_src); cs46xx_src_link(chip,ins->spdif_in_src);
/* restore SPDIF input volume */
cs46xx_dsp_scb_set_volume (chip,ins->spdif_in_src,
ins->spdif_input_volume_right,
ins->spdif_input_volume_left);
spin_unlock_irq(&chip->reg_lock); spin_unlock_irq(&chip->reg_lock);
/* set SPDIF input sample rate and unmute /* set SPDIF input sample rate and unmute
...@@ -1725,39 +1730,47 @@ int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data) ...@@ -1725,39 +1730,47 @@ int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data)
return 0; return 0;
} }
int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 right,u16 left) int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 left,u16 right)
{ {
int i;
dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_spos_instance_t * ins = chip->dsp_spos_instance;
dsp_scb_descriptor_t * scb;
down(&chip->spos_mutex); down(&chip->spos_mutex);
/* main output */
scb = ins->master_mix_scb->sub_list_ptr;
while (scb != ins->the_null_scb) {
cs46xx_dsp_scb_set_volume (chip,scb,left,right);
scb = scb->next_scb_ptr;
}
ins->dac_volume_right = right; /* rear output */
ins->dac_volume_left = left; scb = ins->rear_mix_scb->sub_list_ptr;
while (scb != ins->the_null_scb) {
for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) { cs46xx_dsp_scb_set_volume (chip,scb,left,right);
if (ins->pcm_channels[i].active && scb = scb->next_scb_ptr;
!ins->pcm_channels[i].unlinked) {
cs46xx_dsp_scb_set_volume (chip,ins->pcm_channels[i].pcm_reader_scb,
right,left);
}
} }
ins->dac_volume_left = left;
ins->dac_volume_right = right;
up(&chip->spos_mutex); up(&chip->spos_mutex);
return 0; return 0;
} }
int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 right,u16 left) { int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 left,u16 right) {
dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_spos_instance_t * ins = chip->dsp_spos_instance;
down(&chip->spos_mutex); down(&chip->spos_mutex);
cs46xx_dsp_scb_set_volume (chip,ins->spdif_in_src,
right,left);
ins->spdif_input_volume_right = right; if (ins->asynch_rx_scb != NULL)
cs46xx_dsp_scb_set_volume (chip,ins->asynch_rx_scb,
left,right);
ins->spdif_input_volume_left = left; ins->spdif_input_volume_left = left;
ins->spdif_input_volume_right = right;
up(&chip->spos_mutex); up(&chip->spos_mutex);
return 0; return 0;
......
...@@ -185,6 +185,25 @@ typedef enum { ...@@ -185,6 +185,25 @@ typedef enum {
#define SP_SPDOUT_CONTROL 0x804D #define SP_SPDOUT_CONTROL 0x804D
#define SP_SPDOUT_CSUV 0x808E #define SP_SPDOUT_CSUV 0x808E
static inline u8 _wrap_all_bits (u8 val) {
u8 wrapped;
/* wrap all 8 bits */
wrapped =
((val & 0x1 ) << 7) |
((val & 0x2 ) << 5) |
((val & 0x4 ) << 3) |
((val & 0x8 ) << 1) |
((val & 0x10) >> 1) |
((val & 0x20) >> 3) |
((val & 0x40) >> 5) |
((val & 0x80) >> 6);
return wrapped;
}
static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t * scb) static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t * scb)
{ {
/* update nextSCB and subListPtr in SCB */ /* update nextSCB and subListPtr in SCB */
...@@ -195,12 +214,11 @@ static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descripto ...@@ -195,12 +214,11 @@ static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descripto
} }
static inline void cs46xx_dsp_scb_set_volume (cs46xx_t * chip,dsp_scb_descriptor_t * scb, static inline void cs46xx_dsp_scb_set_volume (cs46xx_t * chip,dsp_scb_descriptor_t * scb,
u16 right,u16 left) { u16 left,u16 right) {
unsigned int val = ((0xffff - right) << 16 | (0xffff - left)); unsigned int val = ((0xffff - left) << 16 | (0xffff - right));
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
} }
#endif /* __DSP_SPOS_H__ */ #endif /* __DSP_SPOS_H__ */
#endif /* CONFIG_SND_CS46XX_NEW_DSP */ #endif /* CONFIG_SND_CS46XX_NEW_DSP */
...@@ -603,8 +603,8 @@ cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name, ...@@ -603,8 +603,8 @@ cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
src_buffer_addr << 0x10, src_buffer_addr << 0x10,
0x04000000, 0x04000000,
{ {
0x8000,0x8000, 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left,
0xffff,0xffff 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left
} }
}; };
...@@ -658,7 +658,7 @@ cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name, ...@@ -658,7 +658,7 @@ cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
/* D */ 0, /* D */ 0,
{ {
/* E */ 0x8000,0x8000, /* E */ 0x8000,0x8000,
/* F */ 0xffff,0xffff /* F */ 0x8000,0x8000
} }
}; };
...@@ -830,7 +830,7 @@ cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest, ...@@ -830,7 +830,7 @@ cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
0,0x2aab, /* Const 1/3 */ 0,0x2aab, /* Const 1/3 */
{ {
0, /* Define the unused elements */ 0, /* Define the unused elements */
0, 0,
0 0
}, },
...@@ -846,7 +846,7 @@ cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest, ...@@ -846,7 +846,7 @@ cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
rate etc */ rate etc */
0x18000000, /* Phi increment for approx 32k operation */ 0x18000000, /* Phi increment for approx 32k operation */
0x8000,0x8000, /* Volume controls are unused at this time */ 0x8000,0x8000, /* Volume controls are unused at this time */
0xffff,0xffff 0x8000,0x8000
}; };
scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_tx_scb, scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_tx_scb,
...@@ -864,7 +864,7 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest, ...@@ -864,7 +864,7 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
dsp_scb_descriptor_t * parent_scb, dsp_scb_descriptor_t * parent_scb,
int scb_child_type) int scb_child_type)
{ {
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
dsp_scb_descriptor_t * scb; dsp_scb_descriptor_t * scb;
asynch_fg_rx_scb_t asynch_fg_rx_scb = { asynch_fg_rx_scb_t asynch_fg_rx_scb = {
...@@ -893,9 +893,9 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest, ...@@ -893,9 +893,9 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
rate etc */ rate etc */
0x18000000, 0x18000000,
/* Mute stream */ /* Set IEC958 input volume */
0x8000,0x8000, 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left,
0xffff,0xffff 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left,
}; };
scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_rx_scb, scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_rx_scb,
...@@ -1116,11 +1116,13 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip, ...@@ -1116,11 +1116,13 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
case DSP_IEC958_CHANNEL: case DSP_IEC958_CHANNEL:
snd_assert (ins->asynch_tx_scb != NULL, return NULL); snd_assert (ins->asynch_tx_scb != NULL, return NULL);
mixer_scb = ins->asynch_tx_scb; mixer_scb = ins->asynch_tx_scb;
#if 0
if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) { if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) {
snd_printdd ("IEC958 opened in AC3 mode\n"); snd_printdd ("IEC958 opened in AC3 mode\n");
/*src_scb = ins->asynch_tx_scb; /*src_scb = ins->asynch_tx_scb;
ins->asynch_tx_scb->ref_count ++;*/ ins->asynch_tx_scb->ref_count ++;*/
} }
#endif
break; break;
default: default:
snd_assert (0); snd_assert (0);
...@@ -1198,9 +1200,7 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip, ...@@ -1198,9 +1200,7 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
return NULL; return NULL;
} }
if (pcm_channel_id != DSP_IEC958_CHANNEL || cs46xx_dsp_set_src_sample_rate(chip,src_scb,sample_rate);
!(ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE))
cs46xx_dsp_set_src_sample_rate(chip,src_scb,sample_rate);
ins->nsrc_scb ++; ins->nsrc_scb ++;
} }
...@@ -1461,17 +1461,11 @@ void cs46xx_dsp_set_src_sample_rate(cs46xx_t *chip,dsp_scb_descriptor_t * src, u ...@@ -1461,17 +1461,11 @@ void cs46xx_dsp_set_src_sample_rate(cs46xx_t *chip,dsp_scb_descriptor_t * src, u
*/ */
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
/* mute SCB */
/* cs46xx_dsp_scb_set_volume (chip,src,0,0); */
snd_cs46xx_poke(chip, (src->address + SRCCorPerGof) << 2, snd_cs46xx_poke(chip, (src->address + SRCCorPerGof) << 2,
((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF)); ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
snd_cs46xx_poke(chip, (src->address + SRCPhiIncr6Int26Frac) << 2, phiIncr); snd_cs46xx_poke(chip, (src->address + SRCPhiIncr6Int26Frac) << 2, phiIncr);
/* raise volume */
/* cs46xx_dsp_scb_set_volume (chip,src,0x7fff,0x7fff); */
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
} }
...@@ -1641,9 +1635,8 @@ int cs46xx_iec958_pre_open (cs46xx_t *chip) ...@@ -1641,9 +1635,8 @@ int cs46xx_iec958_pre_open (cs46xx_t *chip)
SCB_ON_PARENT_NEXT_SCB); SCB_ON_PARENT_NEXT_SCB);
if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) /* set spdif channel status value for streaming */
/* set left (13), right validity bit (12) , and non-audio(1) and profsional bit (0) */ cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_stream);
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12) | (1 << 1) | 1);
ins->spdif_status_out |= DSP_SPDIF_STATUS_PLAYBACK_OPEN; ins->spdif_status_out |= DSP_SPDIF_STATUS_PLAYBACK_OPEN;
...@@ -1659,7 +1652,7 @@ int cs46xx_iec958_post_close (cs46xx_t *chip) ...@@ -1659,7 +1652,7 @@ int cs46xx_iec958_post_close (cs46xx_t *chip)
ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN; ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN;
/* restore settings */ /* restore settings */
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12)); cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);
/* deallocate stuff */ /* deallocate stuff */
cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb); cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
......
...@@ -1355,6 +1355,7 @@ static snd_kcontrol_new_t snd_ens1373_spdif_default __devinitdata = ...@@ -1355,6 +1355,7 @@ static snd_kcontrol_new_t snd_ens1373_spdif_default __devinitdata =
static snd_kcontrol_new_t snd_ens1373_spdif_mask __devinitdata = static snd_kcontrol_new_t snd_ens1373_spdif_mask __devinitdata =
{ {
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM, .iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
.info = snd_ens1373_spdif_info, .info = snd_ens1373_spdif_info,
...@@ -2181,10 +2182,10 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci, ...@@ -2181,10 +2182,10 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci,
return err; return err;
} }
#ifdef CHIP1370 #ifdef CHIP1370
strcpy(card->driver, "ES1370"); strcpy(card->driver, "ENS1370");
#endif #endif
#ifdef CHIP1371 #ifdef CHIP1371
strcpy(card->driver, "ES1371"); strcpy(card->driver, "ENS1371");
#endif #endif
strcpy(card->shortname, "Ensoniq AudioPCI"); strcpy(card->shortname, "Ensoniq AudioPCI");
sprintf(card->longname, "%s %s at 0x%lx, irq %i", sprintf(card->longname, "%s %s at 0x%lx, irq %i",
......
...@@ -257,17 +257,20 @@ static int delta1010lt_ak4524_start(ice1712_t *ice, unsigned char *saved, int ch ...@@ -257,17 +257,20 @@ static int delta1010lt_ak4524_start(ice1712_t *ice, unsigned char *saved, int ch
/* /*
* change the rate of AK4524 on Delta 44/66, AP, 1010LT * change the rate of AK4524 on Delta 44/66, AP, 1010LT
*/ */
static void delta_ak4524_set_rate_val(ice1712_t *ice, unsigned char val) static void delta_ak4524_set_rate_val(ice1712_t *ice, unsigned int rate)
{ {
unsigned char tmp, tmp2; unsigned char tmp, tmp2;
if (rate == 0) /* no hint - S/PDIF input is master, simply return */
return;
/* check before reset ak4524 to avoid unnecessary clicks */ /* check before reset ak4524 to avoid unnecessary clicks */
down(&ice->gpio_mutex); down(&ice->gpio_mutex);
tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
up(&ice->gpio_mutex); up(&ice->gpio_mutex);
tmp2 = tmp; tmp2 = tmp;
tmp2 &= ~ICE1712_DELTA_DFS; tmp2 &= ~ICE1712_DELTA_DFS;
if (val == 15 || val == 11 || val == 7) if (rate > 48000)
tmp2 |= ICE1712_DELTA_DFS; tmp2 |= ICE1712_DELTA_DFS;
if (tmp == tmp2) if (tmp == tmp2)
return; return;
...@@ -275,12 +278,9 @@ static void delta_ak4524_set_rate_val(ice1712_t *ice, unsigned char val) ...@@ -275,12 +278,9 @@ static void delta_ak4524_set_rate_val(ice1712_t *ice, unsigned char val)
/* do it again */ /* do it again */
snd_ice1712_ak4524_reset(ice, 1); snd_ice1712_ak4524_reset(ice, 1);
down(&ice->gpio_mutex); down(&ice->gpio_mutex);
tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
if (val == 15 || val == 11 || val == 7) { if (rate > 48000)
tmp |= ICE1712_DELTA_DFS; tmp |= ICE1712_DELTA_DFS;
} else {
tmp &= ~ICE1712_DELTA_DFS;
}
snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
up(&ice->gpio_mutex); up(&ice->gpio_mutex);
snd_ice1712_ak4524_reset(ice, 0); snd_ice1712_ak4524_reset(ice, 0);
......
This diff is collapsed.
...@@ -256,7 +256,7 @@ struct snd_ak4524 { ...@@ -256,7 +256,7 @@ struct snd_ak4524 {
struct snd_ak4524_ops { struct snd_ak4524_ops {
int (*start)(ice1712_t *, unsigned char *, int); int (*start)(ice1712_t *, unsigned char *, int);
void (*stop)(ice1712_t *, unsigned char *); void (*stop)(ice1712_t *, unsigned char *);
void (*set_rate_val)(ice1712_t *, unsigned char); void (*set_rate_val)(ice1712_t *, unsigned int);
} ops; } ops;
}; };
......
...@@ -178,7 +178,7 @@ void snd_hammerfall_free_buffer (struct pci_dev *pcidev, void *addr) ...@@ -178,7 +178,7 @@ void snd_hammerfall_free_buffer (struct pci_dev *pcidev, void *addr)
printk ("Hammerfall memory allocator: unknown buffer address or PCI device ID"); printk ("Hammerfall memory allocator: unknown buffer address or PCI device ID");
} }
static void hammerfall_free_buffers (void) static void __exit hammerfall_free_buffers (void)
{ {
int i; int i;
......
...@@ -85,7 +85,7 @@ static int __devinit snd_trident_probe(struct pci_dev *pci, ...@@ -85,7 +85,7 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
snd_card_t *card; snd_card_t *card;
trident_t *trident; trident_t *trident;
const char *str; const char *str;
int err; int err, pcm_dev = 0;
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
...@@ -106,21 +106,21 @@ static int __devinit snd_trident_probe(struct pci_dev *pci, ...@@ -106,21 +106,21 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
if ((err = snd_trident_pcm(trident, 0, NULL)) < 0) { if ((err = snd_trident_pcm(trident, pcm_dev++, NULL)) < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
switch (trident->device) { switch (trident->device) {
case TRIDENT_DEVICE_ID_DX: case TRIDENT_DEVICE_ID_DX:
case TRIDENT_DEVICE_ID_NX: case TRIDENT_DEVICE_ID_NX:
if ((err = snd_trident_foldback_pcm(trident, 1, NULL)) < 0) { if ((err = snd_trident_foldback_pcm(trident, pcm_dev++, NULL)) < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
break; break;
} }
if (trident->device == TRIDENT_DEVICE_ID_NX) { if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
if ((err = snd_trident_spdif_pcm(trident, 2, NULL)) < 0) { if ((err = snd_trident_spdif_pcm(trident, pcm_dev++, NULL)) < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
......
This diff is collapsed.
...@@ -202,4 +202,8 @@ int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *i ...@@ -202,4 +202,8 @@ int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *i
#define get_cfg_desc(cfg) (&(cfg)->desc) #define get_cfg_desc(cfg) (&(cfg)->desc)
#endif #endif
#ifndef usb_pipe_needs_resubmit
#define usb_pipe_needs_resubmit(pipe) 1
#endif
#endif /* __USBAUDIO_H */ #endif /* __USBAUDIO_H */
...@@ -114,7 +114,6 @@ struct snd_usb_midi_in_endpoint { ...@@ -114,7 +114,6 @@ struct snd_usb_midi_in_endpoint {
struct urb* urb; struct urb* urb;
struct usbmidi_in_port { struct usbmidi_in_port {
snd_rawmidi_substream_t* substream; snd_rawmidi_substream_t* substream;
int active;
} ports[0x10]; } ports[0x10];
}; };
...@@ -159,7 +158,12 @@ static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep, ...@@ -159,7 +158,12 @@ static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep,
int cable = packet[0] >> 4; int cable = packet[0] >> 4;
usbmidi_in_port_t* port = &ep->ports[cable]; usbmidi_in_port_t* port = &ep->ports[cable];
if (!port->active) if (!port->substream) {
snd_printd("unexpected port %d!\n", cable);
return;
}
if (!port->substream->runtime ||
!port->substream->runtime->trigger)
return; return;
snd_rawmidi_receive(port->substream, &packet[1], snd_rawmidi_receive(port->substream, &packet[1],
snd_usbmidi_cin_length[packet[0] & 0x0f]); snd_usbmidi_cin_length[packet[0] & 0x0f]);
...@@ -184,8 +188,10 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb) ...@@ -184,8 +188,10 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)
return; return;
} }
urb->dev = ep->umidi->chip->dev; if (usb_pipe_needs_resubmit(urb->pipe)) {
snd_usbmidi_submit_urb(urb, GFP_ATOMIC); urb->dev = ep->umidi->chip->dev;
snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
}
} }
/* /*
...@@ -451,20 +457,6 @@ static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int u ...@@ -451,20 +457,6 @@ static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int u
static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream) static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream)
{ {
snd_usb_midi_t* umidi = snd_magic_cast(snd_usb_midi_t, substream->rmidi->private_data, return -ENXIO);
usbmidi_in_port_t* port = NULL;
int i, j;
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
if (umidi->endpoints[i].in)
for (j = 0; j < 0x10; ++j)
if (umidi->endpoints[i].in->ports[j].substream == substream) {
port = &umidi->endpoints[i].in->ports[j];
break;
}
if (!port)
return -ENXIO;
substream->runtime->private_data = port;
return 0; return 0;
} }
...@@ -475,9 +467,6 @@ static int snd_usbmidi_input_close(snd_rawmidi_substream_t* substream) ...@@ -475,9 +467,6 @@ static int snd_usbmidi_input_close(snd_rawmidi_substream_t* substream)
static void snd_usbmidi_input_trigger(snd_rawmidi_substream_t* substream, int up) static void snd_usbmidi_input_trigger(snd_rawmidi_substream_t* substream, int up)
{ {
usbmidi_in_port_t* port = (usbmidi_in_port_t*)substream->runtime->private_data;
port->active = up;
} }
static snd_rawmidi_ops_t snd_usbmidi_output_ops = { static snd_rawmidi_ops_t snd_usbmidi_output_ops = {
......
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