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 @@
#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
#define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2
#define DSP_SPDIF_STATUS_HW_ENABLED 4
#define DSP_SPDIF_STATUS_AC3_MODE 8
struct _dsp_module_desc_t;
......@@ -196,6 +195,10 @@ typedef struct _dsp_spos_instance_t {
int spdif_status_in;
u16 spdif_input_volume_right;
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 */
dsp_scb_descriptor_t * spdif_in_src;
......
......@@ -101,10 +101,18 @@
/* Global registers */
enum global_control_bits {
CHANNEL_IDX = 0x0000003f, OVERRUN_IE = 0x00000400,
UNDERRUN_IE = 0x00000800, ENDLP_IE = 0x00001000,
MIDLP_IE = 0x00002000, ETOG_IE = 0x00004000,
EDROP_IE = 0x00008000, BANK_B_EN = 0x00010000
CHANNEL_IDX = 0x0000003f,
OVERRUN_IE = 0x00000400, /* interrupt enable: capture overrun */
UNDERRUN_IE = 0x00000800, /* interrupt enable: playback underrun */
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 {
......@@ -423,6 +431,8 @@ struct _snd_trident {
int ChanPCM; /* max 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 */
spinlock_t event_lock;
......
/* include/version.h. Generated automatically by configure. */
#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)
snd_seq_fm_init(&opl3->fm_ops, NULL);
/* setup system timer */
memset(&opl3->tlist, 0, sizeof(opl3->tlist));
init_timer(&opl3->tlist);
opl3->tlist.function = snd_opl3_timer_func;
opl3->tlist.data = (unsigned long) opl3;
......
......@@ -51,6 +51,9 @@
#define SNDRV_GET_ID
#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_DESCRIPTION("Dummy soundcard for virtual rawmidi devices");
MODULE_LICENSE("GPL");
......
......@@ -10,6 +10,12 @@
* Note: 16-bit wide is assigned to first direction which made request.
* 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
* 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,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
#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)
cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
if (substream->runtime->periods != CS46XX_FRAGS)
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
if (substream->runtime->periods != CS46XX_FRAGS)
snd_cs46xx_playback_transfer(substream, 0);
......@@ -972,8 +972,9 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* mute channel */
cs46xx_dsp_scb_set_volume (chip,cpcm->pcm_channel->pcm_reader_scb,0,0);
/* magic mute channel */
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
SCBVolumeCtrl) << 2, 0xffffffff);
if (!cpcm->pcm_channel->unlinked)
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,
}
#endif
static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
{
......@@ -1084,15 +1086,10 @@ static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
snd_assert (cpcm->pcm_channel != NULL);
/* if IEC958 is opened in AC3 mode dont adjust SRCTask is not
used so dont adjust sample rate */
if (cpcm->pcm_channel->pcm_channel_id != DSP_IEC958_CHANNEL ||
!(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)) {
up (&chip->spos_mutex);
......@@ -2042,34 +2039,6 @@ static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol,
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,
snd_ctl_elem_value_t *ucontrol)
......@@ -2131,6 +2100,110 @@ static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol,
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 */
#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
......@@ -2242,7 +2315,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC 958 Output Switch",
.name = "IEC958 Output Switch",
.info = snd_mixer_boolean_info,
.get = snd_cs46xx_iec958_get,
.put = snd_cs46xx_iec958_put,
......@@ -2250,14 +2323,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC 958 AC3 Mode 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",
.name = "IEC958 Input Switch",
.info = snd_mixer_boolean_info,
.get = snd_cs46xx_iec958_get,
.put = snd_cs46xx_iec958_put,
......@@ -2265,12 +2331,34 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC 958 Input Volume",
.name = "IEC958 Input Volume",
.info = snd_cs46xx_vol_info,
.get = snd_cs46xx_vol_iec958_get,
.put = snd_cs46xx_vol_iec958_put,
.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
#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
{
......
......@@ -217,6 +217,6 @@ int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
int period_size);
int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
int period_size);
int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 right,u16 left);
int cs46xx_dsp_set_iec958_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 left,u16 right);
#endif /* __CS46XX_LIB_H__ */
......@@ -31,6 +31,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/info.h>
#include <sound/asoundef.h>
#include <sound/cs46xx.h>
#include "cs46xx_lib.h"
......@@ -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_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;
}
......@@ -1549,7 +1559,7 @@ int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip)
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0x80000000);
/* 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 */
ins->spdif_status_out |= DSP_SPDIF_STATUS_HW_ENABLED;
......@@ -1587,11 +1597,6 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);
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);
/* set SPDIF input sample rate and unmute
......@@ -1725,39 +1730,47 @@ int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data)
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_scb_descriptor_t * scb;
down(&chip->spos_mutex);
ins->dac_volume_right = right;
ins->dac_volume_left = left;
for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) {
if (ins->pcm_channels[i].active &&
!ins->pcm_channels[i].unlinked) {
cs46xx_dsp_scb_set_volume (chip,ins->pcm_channels[i].pcm_reader_scb,
right,left);
/* 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;
}
/* rear output */
scb = ins->rear_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_left = left;
ins->dac_volume_right = right;
up(&chip->spos_mutex);
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;
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_right = right;
up(&chip->spos_mutex);
return 0;
......
......@@ -185,6 +185,25 @@ typedef enum {
#define SP_SPDOUT_CONTROL 0x804D
#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)
{
/* update nextSCB and subListPtr in SCB */
......@@ -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,
u16 right,u16 left) {
unsigned int val = ((0xffff - right) << 16 | (0xffff - left));
u16 left,u16 right) {
unsigned int val = ((0xffff - left) << 16 | (0xffff - right));
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
}
#endif /* __DSP_SPOS_H__ */
#endif /* CONFIG_SND_CS46XX_NEW_DSP */
......@@ -603,8 +603,8 @@ cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
src_buffer_addr << 0x10,
0x04000000,
{
0x8000,0x8000,
0xffff,0xffff
0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left,
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,
/* D */ 0,
{
/* E */ 0x8000,0x8000,
/* F */ 0xffff,0xffff
/* F */ 0x8000,0x8000
}
};
......@@ -846,7 +846,7 @@ cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
rate etc */
0x18000000, /* Phi increment for approx 32k operation */
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,
......@@ -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,
int scb_child_type)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
dsp_scb_descriptor_t * 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,
rate etc */
0x18000000,
/* Mute stream */
0x8000,0x8000,
0xffff,0xffff
/* Set IEC958 input volume */
0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left,
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,
......@@ -1116,11 +1116,13 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
case DSP_IEC958_CHANNEL:
snd_assert (ins->asynch_tx_scb != NULL, return NULL);
mixer_scb = ins->asynch_tx_scb;
#if 0
if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) {
snd_printdd ("IEC958 opened in AC3 mode\n");
/*src_scb = ins->asynch_tx_scb;
ins->asynch_tx_scb->ref_count ++;*/
}
#endif
break;
default:
snd_assert (0);
......@@ -1198,8 +1200,6 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
return NULL;
}
if (pcm_channel_id != DSP_IEC958_CHANNEL ||
!(ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE))
cs46xx_dsp_set_src_sample_rate(chip,src_scb,sample_rate);
ins->nsrc_scb ++;
......@@ -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);
/* mute SCB */
/* cs46xx_dsp_scb_set_volume (chip,src,0,0); */
snd_cs46xx_poke(chip, (src->address + SRCCorPerGof) << 2,
((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
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);
}
......@@ -1641,9 +1635,8 @@ int cs46xx_iec958_pre_open (cs46xx_t *chip)
SCB_ON_PARENT_NEXT_SCB);
if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE)
/* set left (13), right validity bit (12) , and non-audio(1) and profsional bit (0) */
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12) | (1 << 1) | 1);
/* set spdif channel status value for streaming */
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_stream);
ins->spdif_status_out |= DSP_SPDIF_STATUS_PLAYBACK_OPEN;
......@@ -1659,7 +1652,7 @@ int cs46xx_iec958_post_close (cs46xx_t *chip)
ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN;
/* 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 */
cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
......
......@@ -1355,6 +1355,7 @@ static snd_kcontrol_new_t snd_ens1373_spdif_default __devinitdata =
static snd_kcontrol_new_t snd_ens1373_spdif_mask __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
.info = snd_ens1373_spdif_info,
......@@ -2181,10 +2182,10 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci,
return err;
}
#ifdef CHIP1370
strcpy(card->driver, "ES1370");
strcpy(card->driver, "ENS1370");
#endif
#ifdef CHIP1371
strcpy(card->driver, "ES1371");
strcpy(card->driver, "ENS1371");
#endif
strcpy(card->shortname, "Ensoniq AudioPCI");
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
/*
* 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;
if (rate == 0) /* no hint - S/PDIF input is master, simply return */
return;
/* check before reset ak4524 to avoid unnecessary clicks */
down(&ice->gpio_mutex);
tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
up(&ice->gpio_mutex);
tmp2 = tmp;
tmp2 &= ~ICE1712_DELTA_DFS;
if (val == 15 || val == 11 || val == 7)
if (rate > 48000)
tmp2 |= ICE1712_DELTA_DFS;
if (tmp == tmp2)
return;
......@@ -275,12 +278,9 @@ static void delta_ak4524_set_rate_val(ice1712_t *ice, unsigned char val)
/* do it again */
snd_ice1712_ak4524_reset(ice, 1);
down(&ice->gpio_mutex);
tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
if (val == 15 || val == 11 || val == 7) {
tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
if (rate > 48000)
tmp |= ICE1712_DELTA_DFS;
} else {
tmp &= ~ICE1712_DELTA_DFS;
}
snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
up(&ice->gpio_mutex);
snd_ice1712_ak4524_reset(ice, 0);
......
This diff is collapsed.
......@@ -256,7 +256,7 @@ struct snd_ak4524 {
struct snd_ak4524_ops {
int (*start)(ice1712_t *, unsigned char *, int);
void (*stop)(ice1712_t *, unsigned char *);
void (*set_rate_val)(ice1712_t *, unsigned char);
void (*set_rate_val)(ice1712_t *, unsigned int);
} ops;
};
......
......@@ -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");
}
static void hammerfall_free_buffers (void)
static void __exit hammerfall_free_buffers (void)
{
int i;
......
......@@ -85,7 +85,7 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
snd_card_t *card;
trident_t *trident;
const char *str;
int err;
int err, pcm_dev = 0;
if (dev >= SNDRV_CARDS)
return -ENODEV;
......@@ -106,21 +106,21 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
snd_card_free(card);
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);
return err;
}
switch (trident->device) {
case TRIDENT_DEVICE_ID_DX:
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);
return err;
}
break;
}
if (trident->device == TRIDENT_DEVICE_ID_NX) {
if ((err = snd_trident_spdif_pcm(trident, 2, NULL)) < 0) {
if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
if ((err = snd_trident_spdif_pcm(trident, pcm_dev++, NULL)) < 0) {
snd_card_free(card);
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
#define get_cfg_desc(cfg) (&(cfg)->desc)
#endif
#ifndef usb_pipe_needs_resubmit
#define usb_pipe_needs_resubmit(pipe) 1
#endif
#endif /* __USBAUDIO_H */
......@@ -114,7 +114,6 @@ struct snd_usb_midi_in_endpoint {
struct urb* urb;
struct usbmidi_in_port {
snd_rawmidi_substream_t* substream;
int active;
} ports[0x10];
};
......@@ -159,7 +158,12 @@ static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep,
int cable = packet[0] >> 4;
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;
snd_rawmidi_receive(port->substream, &packet[1],
snd_usbmidi_cin_length[packet[0] & 0x0f]);
......@@ -184,8 +188,10 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)
return;
}
if (usb_pipe_needs_resubmit(urb->pipe)) {
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
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;
}
......@@ -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)
{
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 = {
......
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