Commit a2755d79 authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Jaroslav Kysela

[PATCH] ALSA update [6/12] - 2002/08/21

  - CS46xx
    - SPDIF input fixes
    - fixed missplaced #ifndef
    - amplifier fix for Game Theater XP
    - refine on the PCM multichannel functionality
  - EMU10K1
    - added the support for Audigy spdif controls
  - PCM midlevel
    - fixed hw_free (wrong state for drivers with no callback
    - fixed sw_params (runtime) lock
  - AC'97 codec
    - fixed spin deadlock
  - CS4281
    - fixed wrong mdelays and allowed scheduling in module_init
  - PPC drivers
    - added the missing inclusion of linux/slab.h
  - USB MIDI driver
    - replaced urb_t -> struct urb
parent 16a8f371
......@@ -177,6 +177,7 @@ typedef struct _dsp_spos_instance_t {
/* SPDIF status */
int spdif_status_out;
int spdif_status_in;
u32 spdif_input_volume;
/* SPDIF input sample rate converter */
dsp_scb_descriptor_t * spdif_in_src;
......
......@@ -1195,8 +1195,12 @@ int snd_emu10k1_proc_done(emu10k1_t * emu);
#define A_EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */
#define A_EXTIN_SPDIF_CD_L 0x02 /* digital CD left */
#define A_EXTIN_SPDIF_CD_R 0x03 /* digital CD left */
#define A_EXTIN_OPT_SPDIF_L 0x04 /* audigy drive Optical SPDIF - left */
#define A_EXTIN_OPT_SPDIF_R 0x05 /* right */
#define A_EXTIN_LINE2_L 0x08 /* audigy drive line2/mic2 - left */
#define A_EXTIN_LINE2_R 0x09 /* right */
#define A_EXTIN_RCA_SPDIF_L 0x0a /* audigy drive RCA SPDIF - left */
#define A_EXTIN_RCA_SPDIF_R 0x0b /* right */
#define A_EXTIN_AUX2_L 0x0c /* audigy drive aux2 - left */
#define A_EXTIN_AUX2_R 0x0d /* - right */
......
......@@ -137,6 +137,13 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define sa11xx_uda1341_t_magic 0xa15a3b00
#define uda1341_t_magic 0xa15a3c00
#define l3_client_t_magic 0xa15a3d00
#define snd_usb_audio_t_magic 0xa15a3e01
#define usb_mixer_elem_info_t_magic 0xa15a3e02
#define snd_usb_stream_t_magic 0xa15a3e03
#define usbmidi_t_magic 0xa15a3f01
#define usbmidi_out_endpoint_t_magic 0xa15a3f02
#define usbmidi_in_endpoint_t_magic 0xa15a3f03
#else
......
/* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc3"
#define CONFIG_SND_DATE " (Thu Aug 15 19:10:53 2002 UTC)"
#define CONFIG_SND_DATE " (Wed Aug 21 14:00:18 2002 UTC)"
......@@ -31,6 +31,11 @@ fi
if [ "$CONFIG_SND" != "n" -a "$CONFIG_ARM" = "y" ]; then
source sound/arm/Config.in
fi
# the following will depenend on the order of config.
# here assuming USB is defined before ALSA
if [ "$CONFIG_SND" != "n" -a "$CONFIG_USB" != "n" ]; then
source sound/usb/Config.in
fi
if [ "$CONFIG_SND" != "n" -a "$CONFIG_SPARC32" = "y" ]; then
source sound/sparc/Config.in
fi
......
......@@ -438,8 +438,10 @@ static int snd_pcm_hw_free(snd_pcm_substream_t * substream)
}
if (atomic_read(&runtime->mmap_count))
return -EBADFD;
if (substream->ops->hw_free == NULL)
if (substream->ops->hw_free == NULL) {
runtime->status->state = SNDRV_PCM_STATE_OPEN;
return 0;
}
result = substream->ops->hw_free(substream);
runtime->status->state = SNDRV_PCM_STATE_OPEN;
return result;
......@@ -463,6 +465,7 @@ static int snd_pcm_sw_params(snd_pcm_substream_t * substream, snd_pcm_sw_params_
return -EINVAL;
if (params->silence_threshold + params->silence_size > runtime->buffer_size)
return -EINVAL;
spin_lock_irq(&runtime->lock);
runtime->tstamp_mode = params->tstamp_mode;
runtime->sleep_min = params->sleep_min;
runtime->period_step = params->period_step;
......@@ -473,7 +476,6 @@ static int snd_pcm_sw_params(snd_pcm_substream_t * substream, snd_pcm_sw_params_
runtime->silence_size = params->silence_size;
runtime->xfer_align = params->xfer_align;
params->boundary = runtime->boundary;
spin_lock_irq(&runtime->lock);
if (snd_pcm_running(substream)) {
if (runtime->sleep_min)
snd_pcm_tick_prepare(substream);
......
......@@ -276,14 +276,13 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
return change;
}
int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
{
int change;
unsigned short old, new;
if (!snd_ac97_valid_reg(ac97, reg))
return -EINVAL;
spin_lock(&ac97->reg_lock);
old = ac97->regs[reg];
new = (old & ~mask) | value;
change = old != new;
......@@ -291,6 +290,14 @@ int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask,
ac97->write(ac97, reg, new);
ac97->regs[reg] = new;
}
return change;
}
int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
{
int change;
spin_lock(&ac97->reg_lock);
change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
spin_unlock(&ac97->reg_lock);
return change;
}
......@@ -740,16 +747,16 @@ static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
case 2: x = 0; break; // 48.0
default: x = 0; break; // illegal.
}
change = snd_ac97_update_bits(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
change = snd_ac97_update_bits_nolock(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
} else if (ac97->flags & AC97_CX_SPDIF) {
int v;
v = ucontrol->value.iec958.status[0] & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
v |= ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
change = snd_ac97_update_bits(ac97, AC97_CXR_AUDIO_MISC,
change = snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC,
AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
v);
} else {
change = snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val);
change = snd_ac97_update_bits_nolock(ac97, AC97_SPDIF, 0x3fff, val);
}
change |= ac97->spdif_status != new;
......
......@@ -549,8 +549,11 @@ static void snd_cs4281_delay(unsigned int delay, int can_schedule)
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (end_time - (signed long)jiffies >= 0);
} else
mdelay(delay);
} else {
delay += 999;
delay /= 1000;
mdelay(delay > 0 ? delay : 1);
}
} else {
udelay(delay);
}
......@@ -562,7 +565,7 @@ inline static void snd_cs4281_delay_long(int can_schedule)
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} else
mdelay(1999 / HZ);
mdelay(10);
}
static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val)
......@@ -1502,7 +1505,7 @@ static int __devinit snd_cs4281_create(snd_card_t * card,
return -ENOMEM;
}
tmp = snd_cs4281_chip_init(chip, 0);
tmp = snd_cs4281_chip_init(chip, 1);
if (tmp) {
snd_cs4281_free(chip);
return tmp;
......
......@@ -6,9 +6,9 @@
*
* KNOWN BUGS:
* - Sometimes the SPDIF input DSP tasks get's unsynchronized
* and the SPDIF get somewhat "distorcionated". To get around
* this problem when it happens, mute and unmute the SPDIF input
* mixer controll.
* and the SPDIF get somewhat "distorcionated", or/and left right channel
* are swapped. To get around this problem when it happens, mute and unmute
* the SPDIF input mixer controll.
* - On the Hercules Game Theater XP the amplifier are sometimes turned
* off on inadecuate moments which causes distorcions on sound.
*
......@@ -16,11 +16,19 @@
* - Secondary CODEC on some soundcards
* - SPDIF input support for other sample rates then 48khz
* - Independent PCM channels for rear output
* - Posibility to mix the SPDIF output with analog sources.
*
* NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which
* is default configuration), no SPDIF, no secondary codec, no
* multi channel PCM. But known to work.
*
* FINALLY: A credit to the developers Tom and Jordan
* at Cirrus for have helping me out with the DSP, however we
* still dont have sufficient documentation and technical
* references to be able to implement all fancy feutures
* supported by the cs46xx DPS's.
* Benny <benny@hostmobility.com>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
......@@ -839,6 +847,8 @@ static int snd_cs46xx_playback_copy(snd_pcm_substream_t *substream,
char *hwbuf;
cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO);
snd_assert(runtime->dma_area, return -EINVAL);
hwoffb = hwoff << cpcm->shift;
bytes = frames << cpcm->shift;
hwbuf = runtime->dma_area + hwoffb;
......@@ -895,6 +905,8 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
if (substream->runtime->periods != CS46XX_FRAGS)
snd_cs46xx_playback_transfer(substream, 0);
/* raise playback volume */
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 0xE) << 2, 0x80008000);
#else
if (substream->runtime->periods != CS46XX_FRAGS)
snd_cs46xx_playback_transfer(substream, 0);
......@@ -1028,7 +1040,7 @@ static int snd_cs46xx_playback_prepare(snd_pcm_substream_t * substream)
cpcm->pcm_channel->src_scb->ref_count != 1) {
cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip,runtime->rate,cpcm)) == NULL) {
if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, runtime->rate, cpcm, cpcm->hw_addr)) == NULL) {
snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n");
return -ENXIO;
}
......@@ -1073,9 +1085,6 @@ static int snd_cs46xx_playback_prepare(snd_pcm_substream_t * substream)
cpcm->appl_ptr = 0;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* playback address */
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2, cpcm->hw_addr);
tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2);
tmp &= ~0x000003ff;
tmp |= (4 << cpcm->shift) - 1;
......@@ -1315,7 +1324,7 @@ static int snd_cs46xx_playback_open(snd_pcm_substream_t * substream)
cpcm->substream = substream;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip,runtime->rate,cpcm);
cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, runtime->rate, cpcm, cpcm->hw_addr);
if (cpcm->pcm_channel == NULL) {
snd_printk(KERN_ERR "cs46xx: failed to create virtual PCM channel\n");
......@@ -1522,7 +1531,7 @@ static int snd_cs46xx_vol_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *
int change = (old != val);
if (change) {
snd_cs46xx_poke(chip, reg, val);
#ifndef CONFIG_SND_CS46XX_NEW_DSP
#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* NOTE: this updates the current left and right volume
that should be automatically updated by the DSP and
not touched by the host. But for some strange reason
......@@ -1531,6 +1540,14 @@ static int snd_cs46xx_vol_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *
channel volume.
*/
snd_cs46xx_poke(chip, reg + 4, val);
/* shadow the SPDIF input volume */
if (reg == (ASYNCRX_SCB_ADDR + 0xE) << 2) {
/* FIXME: I known this is uggly ...
any other suggestion ?
*/
chip->dsp_spos_instance->spdif_input_volume = val;
}
#endif
}
return change;
......@@ -1579,8 +1596,10 @@ static int snd_cs46xx_iec958_put(snd_kcontrol_t *kcontrol,
break;
case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
change = chip->dsp_spos_instance->spdif_status_in;
if (ucontrol->value.integer.value[0] && !change)
if (ucontrol->value.integer.value[0] && !change) {
cs46xx_dsp_enable_spdif_in(chip);
/* restore volume */
}
else if (change && !ucontrol->value.integer.value[0])
cs46xx_dsp_disable_spdif_in(chip);
......@@ -2742,12 +2761,14 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip, int busywait)
snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
#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);
/* mute spdif in */
cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x00000000);
cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x000003ff);
#endif
return 0;
......@@ -2943,6 +2964,9 @@ static void hercules_mixer_init (cs46xx_t *chip)
snd_printdd ("initializing Hercules mixer\n");
#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* turnon Amplifier and leave it on */
chip->amplifier_ctrl(chip, 1);
for (idx = 0 ; idx < sizeof(snd_hercules_controls) /
sizeof(snd_hercules_controls[0]) ; idx++) {
snd_kcontrol_t *kctl;
......
......@@ -185,7 +185,7 @@ dsp_scb_descriptor_t * cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char *
dsp_scb_descriptor_t * snoop_scb,
dsp_scb_descriptor_t * parent_scb,
int scb_child_type);
pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data);
pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data, u32 hw_dma_addr);
void cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,
pcm_channel_descriptor_t * pcm_channel);
void cs46xx_dsp_set_src_sample_rate(cs46xx_t * chip,dsp_scb_descriptor_t * src,
......@@ -194,4 +194,6 @@ int cs46xx_dsp_pcm_unlink (cs46xx_t * chip,pcm_channel_de
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);
#endif /* __CS46XX_LIB_H__ */
......@@ -36,74 +36,6 @@
#include "cs46xx_lib.h"
#include "dsp_spos.h"
#if 0
/* OBSOLETE NOW */
static void handle_goto (cs46xx_t * chip,u32 * hival,u32 * loval,char * format, u32 overlay_begin_address);
typedef struct _dsp_opcode_desc_t {
u32 hival,loval;
u32 himask,lomask;
void (*handler_func)(cs46xx_t * chip,u32 * hival,u32 * loval,char * format, u32 overlay_begin_address);
char * format;
} dsp_opcode_desc_t;
/* NOTE: theese opcodes are known needed to be reallocated,
there may be more. */
dsp_opcode_desc_t dsp_opcodes[] = {
{ 0x01000,0x02730, 0xFF000,0x07FFF,handle_goto,"goto %s" },
{ 0x01000,0x00730, 0xFF000,0x07FFF,handle_goto,"goto %s after" },
{ 0x01000,0x02630, 0xFF000,0x07FFF,handle_goto,"if (tb) goto %s" },
{ 0x01000,0x00630, 0xFF000,0x07FFF,handle_goto,"if (tb) goto %s after" },
{ 0x01000,0x00530, 0xFF000,0x07FFF,handle_goto,"if (lt) goto %s after" },
{ 0x01000,0x02530, 0xFF000,0x07FFF,handle_goto,"if (lt) goto %s" },
{ 0x01000,0x006B0, 0xFF000,0x07FFF,handle_goto,"if (!tb) goto %s after" },
{ 0x01000,0x026B0, 0xFF000,0x07FFF,handle_goto,"if (!tb) goto %s" },
{ 0x01000,0x00FB0, 0xFF000,0x07FFF,handle_goto,"if (gt) goto %s after" },
{ 0x01000,0x02FB0, 0xFF000,0x07FFF,handle_goto,"if (gt) goto %s" },
{ 0x01000,0x02734, 0xFF000,0x07FFF,NULL,"goto *ind" },
{ 0x01000,0x00734, 0xFF000,0x07FFF,NULL,"goto *ind after" },
{ 0x01000,0x02130, 0xFF000,0x07FFF,handle_goto,"if (N) goto %s" },
{ 0x01000,0x00130, 0xFF000,0x07FFF,handle_goto,"if (N) goto %s after" },
{ 0x01000,0x020F2, 0xFF000,0x07FFF,handle_goto,"tb = Z, if(!Z) goto %s" },
{ 0x01000,0x000F2, 0xFF000,0x07FFF,handle_goto,"tb = Z, if(!Z) goto %s after" },
{ 0x01000,0x04030, 0xFF000,0x07FFF,handle_goto,"if(Z) goto %s" },
{ 0x01000,0x00030, 0xFF000,0x07FFF,handle_goto,"if(Z) goto %s after" },
{ 0x01000,0x020B0, 0xFF000,0x07FFF,handle_goto,"if(!Z) goto %s" },
{ 0x01000,0x000B0, 0xFF000,0x07FFF,handle_goto,"if(!Z) goto %s after" },
{ 0x01000,0x02731, 0xFF000,0x07FFF,handle_goto,"%s();" },
};
static void handle_goto (cs46xx_t * chip,u32 * hival,u32 * loval,
char * format, u32 overlay_begin_address)
{
u32 address ;
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
address = (*hival & 0x00FFF) << 5;
address |= *loval >> 15;
snd_printdd("handle_goto[1]: %05x:%05x addr %04x\n",*hival,*loval,address);
if ( !(address & 0x8000) ) {
address += (ins->code.offset / 2) - overlay_begin_address;
} else {
snd_printdd("handle_goto[1]: ROM symbol not reallocated\n");
}
*hival &= 0xFF000;
*loval &= 0x07FFF;
*hival |= ( (address >> 5) & 0x00FFF);
*loval |= ( (address << 15) & 0xF8000);
address = (*hival & 0x00FFF) << 5;
address |= *loval >> 15;
snd_printdd("handle_goto:[2] %05x:%05x addr %04x\n",*hival,*loval,address);
}
#endif /* #if 0 */
static wide_opcode_t wide_opcodes[] = {
WIDE_FOR_BEGIN_LOOP,
WIDE_FOR_BEGIN_LOOP2,
......@@ -133,18 +65,6 @@ static int shadow_and_reallocate_code (cs46xx_t * chip,u32 * data,u32 size, u32
hival = data[i++];
if (ins->code.offset > 0) {
#if 0
/* OBSOLETE NOW */
for (j = 0;j < sizeof(dsp_opcodes) / sizeof(dsp_opcode_desc_t); ++j) {
if ( (hival & dsp_opcodes[j].himask) == dsp_opcodes[j].hival &&
(loval & dsp_opcodes[j].lomask) == dsp_opcodes[j].loval &&
dsp_opcodes[j].handler_func != NULL) {
dsp_opcodes[j].handler_func (chip,&hival,&loval,dsp_opcodes[j].format, overlay_begin_address);
nreallocated ++;
}
}
#endif
mop_operands = (hival >> 6) & 0x03fff;
mop_type = mop_operands >> 10;
......@@ -337,7 +257,10 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
/* default SPDIF input sample rate
to 48000 khz */
ins->spdif_in_sample_rate = 32000;
ins->spdif_in_sample_rate = 48000;
/* maximize volume */
ins->spdif_input_volume = 0x80008000;
return ins;
}
......@@ -655,7 +578,6 @@ static void cs46xx_dsp_proc_parameter_dump_read (snd_info_entry_t *entry, snd_in
static void cs46xx_dsp_proc_sample_dump_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
cs46xx_t *chip = snd_magic_cast(cs46xx_t, entry->private_data, return);
/*dsp_spos_instance_t * ins = chip->dsp_spos_instance; */
int i,col = 0;
unsigned long dst = chip->region.idx[2].remap_addr;
......@@ -1370,7 +1292,8 @@ int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip)
/* create the record mixer SCB */
record_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RecordMixerSCB",
MIX_SAMPLE_BUF2,0x170,
MIX_SAMPLE_BUF2,
RECORD_MIXER_SCB_ADDR,
vari_decimate_scb,
SCB_ON_PARENT_SUBLIST_SCB);
ins->record_mixer_scb = record_mix_scb;
......@@ -1417,8 +1340,7 @@ int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip)
goto _fail_end;
/* the magic snooper */
/* SPDIF input sampel rate converter */
src_task_scb = cs46xx_dsp_create_src_task_scb(chip,"SrcTaskSCB_SPDIFI",
SRC_OUTPUT_BUF1,
SRC_DELAY_BUF1,SRCTASK_SCB_ADDR,
......@@ -1427,6 +1349,8 @@ int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip)
if (!src_task_scb) goto _fail_end;
cs46xx_src_unlink(chip,src_task_scb);
/* NOTE: when we now how to detect the SPDIF input
sample rate we will use this SRC to adjust it */
ins->spdif_in_src = src_task_scb;
......@@ -1644,19 +1568,14 @@ int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip)
int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
unsigned int flags;
/* turn on amplifier */
chip->active_ctrl(chip, 1);
chip->amplifier_ctrl(chip, 1);
/* set SPDIF input sample rate
NOTE: only 48khz support for SPDIF input this time */
cs46xx_dsp_set_src_sample_rate(chip,ins->spdif_in_src,48000);
snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL);
snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
/* create and start the asynchronous receiver SCB */
ins->asynch_rx_scb = cs46xx_dsp_create_asynch_fg_rx_scb(chip,"AsynchFGRxSCB",
ASYNCRX_SCB_ADDR,
......@@ -1665,21 +1584,24 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
ins->spdif_in_src,
SCB_ON_PARENT_SUBLIST_SCB);
if (!ins->asynch_rx_scb)
return -EINVAL;
save_flags(flags);
cli();
/* reset SPDIF input sample buffer pointer */
snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2,
(SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC);
/* time countdown enable */
cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x80000000);
/* reset FIFO ptr */
cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);
cs46xx_src_link(chip,ins->spdif_in_src);
/* SPDIF input MASTER ENABLE */
cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x800003ff);
/* restore SPDIF input volume */
snd_cs46xx_poke(chip, (ASYNCRX_SCB_ADDR + 0xE) << 2, ins->spdif_input_volume);
snd_cs46xx_poke(chip, (ASYNCRX_SCB_ADDR + 0xF) << 2, ins->spdif_input_volume);
restore_flags(flags);
/* set SPDIF input sample rate and unmute
NOTE: only 48khz support for SPDIF input this time */
cs46xx_dsp_set_src_sample_rate(chip,ins->spdif_in_src,48000);
/* monitor state */
ins->spdif_status_in = 1;
......@@ -1692,17 +1614,14 @@ int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip)
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL);
/* Time countdown disable */
cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x00000000);
/* SPDIF input MASTER DISABLE */
cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x000003ff);
snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
/* Remove the asynchronous receiver SCB */
cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb);
ins->asynch_rx_scb = NULL;
cs46xx_src_unlink(chip,ins->spdif_in_src);
/* monitor state */
ins->spdif_status_in = 0;
......
......@@ -75,10 +75,6 @@ typedef enum {
#define MIX_SAMPLE_BUF1 0x1400
#define MIX_SAMPLE_BUF2 0x3000
// #define SPDIFI_IP_OUTPUT_BUFFER1 0x2800
// #define SRC_OUTPUT_BUF2 0x1280
// #define SRC_DELAY_BUF2 0x1288
/* Task stack address */
#define HFG_STACK 0x066A
#define FG_STACK 0x066E
......@@ -107,6 +103,7 @@ typedef enum {
#define SEC_CODECOUT_SCB_ADDR 0x140
#define OUTPUTSNOOPII_SCB_ADDR 0x150
#define PCMSERIALIN_PCM_SCB_ADDR 0x160
#define RECORD_MIXER_SCB_ADDR 0x170
/* hyperforground SCB's*/
#define HFG_TREE_SCB 0xBA0
......@@ -184,4 +181,3 @@ typedef enum {
#endif /* __DSP_SPOS_H__ */
#endif /* CONFIG_SND_CS46XX_NEW_DSP */
......@@ -137,7 +137,7 @@ static void _dsp_unlink_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb)
scb->next_scb_ptr = ins->the_null_scb;
}
} else {
snd_assert ( (scb->sub_list_ptr == ins->the_null_scb), return);
/* snd_assert ( (scb->sub_list_ptr == ins->the_null_scb), return); */
scb->parent_scb_ptr->next_scb_ptr = scb->next_scb_ptr;
if (scb->next_scb_ptr != ins->the_null_scb) {
......@@ -166,6 +166,16 @@ static void _dsp_unlink_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb)
}
}
static void _dsp_clear_sample_buffer (cs46xx_t *chip, u32 sample_buffer_addr, int dword_count)
{
u32 dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
int i;
for (i = 0; i < dword_count ; ++i ) {
writel(0, dst);
}
}
void cs46xx_dsp_remove_scb (cs46xx_t *chip, dsp_scb_descriptor_t * scb)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
......@@ -564,9 +574,10 @@ cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * scb_name,
/* Fractional increment per output sample in the input sample buffer */
0,
{
/* Standard stereo volume control */
0x8000,0x8000,
0x8000,0x8000
/* Standard stereo volume control
default muted */
0xffff,0xffff,
0xffff,0xffff
}
};
......@@ -614,8 +625,8 @@ cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
src_buffer_addr << 0x10,
0x04000000,
{
0x8000,0x8000,
0x8000,0x8000
0xffff,0xffff,
0xffff,0xffff
}
};
......@@ -629,6 +640,10 @@ cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
}
}
/* clear buffers */
_dsp_clear_sample_buffer (chip,src_buffer_addr,8);
_dsp_clear_sample_buffer (chip,src_delay_buffer_addr,32);
scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
dest,ins->s16_up,parent_scb,
scb_child_type);
......@@ -899,8 +914,9 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
/* There is no correct initial value, it will depend upon the detected
rate etc */
0x18000000,
/* Mute stream */
0x8000,0x8000,
0xFFFF,0xFFFF
0xffff,0xffff
};
scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_rx_scb,
......@@ -1091,7 +1107,7 @@ static u32 src_delay_buffer_addr[DSP_MAX_SRC_NR] = {
};
pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data)
pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data, u32 hw_dma_addr)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
dsp_scb_descriptor_t * src_scb = NULL,* pcm_scb;
......@@ -1206,7 +1222,7 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sa
/* 0x200 - 400 PCMreader SCBs */
(pcm_index * 0x10) + 0x200,
pcm_index, /* virtual channel 0-31 */
0, /* pcm hw addr */
hw_dma_addr, /* pcm hw addr */
pcm_parent_scb,
insert_point);
......@@ -1386,11 +1402,15 @@ 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 */
snd_cs46xx_poke(chip, (src->address + 0xE) << 2, 0xffffffff);
snd_cs46xx_poke(chip, (src->address + SRCCorPerGof) << 2,
((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
snd_cs46xx_poke(chip, (src->address + SRCPhiIncr6Int26Frac) << 2, phiIncr);
/* raise volume */
snd_cs46xx_poke(chip, (src->address + 0xE) << 2, 0x80008000);
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
......@@ -1419,3 +1439,72 @@ cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
return pcm_input;
}
int cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
down(&ins->pcm_mutex);
down(&ins->scb_mutex);
snd_assert (src->parent_scb_ptr != NULL,goto _fail_end);
/* mute SCB */
snd_cs46xx_poke(chip, (src->address + 0xE) << 2, 0xffffffff);
_dsp_unlink_scb (chip,src);
up(&ins->scb_mutex);
up(&ins->pcm_mutex);
return 0;
_fail_end:
up(&ins->scb_mutex);
up(&ins->pcm_mutex);
return -EINVAL;
}
int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
dsp_scb_descriptor_t * parent_scb;
unsigned int flags;
down(&ins->pcm_mutex);
down(&ins->scb_mutex);
snd_assert (src->parent_scb_ptr == NULL,goto _fail_end);
snd_assert(ins->master_mix_scb !=NULL,goto _fail_end);
if (ins->master_mix_scb->sub_list_ptr != ins->the_null_scb) {
parent_scb = find_next_free_scb (chip,ins->master_mix_scb->sub_list_ptr);
parent_scb->next_scb_ptr = src;
} else {
parent_scb = ins->master_mix_scb;
parent_scb->sub_list_ptr = src;
}
src->parent_scb_ptr = parent_scb;
/* update entry in DSP RAM */
spin_lock_irqsave(&chip->reg_lock, flags);
snd_cs46xx_poke(chip,
(parent_scb->address + SCBsubListPtr) << 2,
(parent_scb->sub_list_ptr->address << 0x10) |
(parent_scb->next_scb_ptr->address));
spin_unlock_irqrestore(&chip->reg_lock, flags);
up(&ins->scb_mutex);
up(&ins->pcm_mutex);
return 0;
_fail_end:
up(&ins->scb_mutex);
up(&ins->pcm_mutex);
return -EINVAL;
}
......@@ -91,14 +91,14 @@ static char *audigy_ins[16] = {
/* 0x01 */ "AC97 Right",
/* 0x02 */ "Audigy CD Left",
/* 0x03 */ "Audigy CD Right",
/* 0x04 */ NULL,
/* 0x05 */ NULL,
/* 0x04 */ "Optical IEC958 Left",
/* 0x05 */ "Optical IEC958 Right",
/* 0x06 */ NULL,
/* 0x07 */ NULL,
/* 0x08 */ "Line/Mic 2 Left",
/* 0x09 */ "Line/Mic 2 Right",
/* 0x0a */ NULL,
/* 0x0b */ NULL,
/* 0x0a */ "SPDIF Left",
/* 0x0b */ "SPDIF Right",
/* 0x0c */ "Aux2 Left",
/* 0x0d */ "Aux2 Right",
/* 0x0e */ NULL,
......@@ -1313,6 +1313,17 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
snd_emu10k1_init_stereo_control(&controls[nctl++], "Audigy CD Capture Volume", gpr, 0);
gpr += 2;
/* Optical SPDIF Playback Volume */
A_ADD_VOLUME_IN(playback, gpr, A_EXTIN_OPT_SPDIF_L);
A_ADD_VOLUME_IN(playback+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
snd_emu10k1_init_stereo_control(&controls[nctl++], "Optical IEC958 Playback Volume", gpr, 0);
gpr += 2;
/* Optical SPDIF Capture Volume */
A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
snd_emu10k1_init_stereo_control(&controls[nctl++], "Optical IEC958 Capture Volume", gpr, 0);
gpr += 2;
/* Line2 Playback Volume */
A_ADD_VOLUME_IN(playback, gpr, A_EXTIN_LINE2_L);
A_ADD_VOLUME_IN(playback+1, gpr+1, A_EXTIN_LINE2_R);
......@@ -1324,6 +1335,17 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
snd_emu10k1_init_stereo_control(&controls[nctl++], "Line2 Capture Volume", gpr, 0);
gpr += 2;
/* RCA SPDIF Playback Volume */
A_ADD_VOLUME_IN(playback, gpr, A_EXTIN_RCA_SPDIF_L);
A_ADD_VOLUME_IN(playback+1, gpr+1, A_EXTIN_RCA_SPDIF_R);
snd_emu10k1_init_stereo_control(&controls[nctl++], "RCA SPDIF Playback Volume", gpr, 0);
gpr += 2;
/* RCA SPDIF Capture Volume */
A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_RCA_SPDIF_L);
A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_RCA_SPDIF_R);
snd_emu10k1_init_stereo_control(&controls[nctl++], "RCA SPDIF Capture Volume", gpr, 0);
gpr += 2;
/* Aux2 Playback Volume */
A_ADD_VOLUME_IN(playback, gpr, A_EXTIN_AUX2_L);
A_ADD_VOLUME_IN(playback+1, gpr+1, A_EXTIN_AUX2_R);
......
......@@ -25,6 +25,7 @@
#include <asm/nvram.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "pmac.h"
......@@ -134,12 +135,20 @@ static int snd_pmac_awacs_get_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_valu
pmac_t *chip = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
int lshift = (kcontrol->private_value >> 8) & 0xff;
int inverted = (kcontrol->private_value >> 16) & 1;
unsigned long flags;
int vol[2];
spin_lock_irqsave(&chip->reg_lock, flags);
ucontrol->value.integer.value[0] = 0x0f - ((chip->awacs_reg[reg] >> lshift) & 0xf);
ucontrol->value.integer.value[1] = 0x0f - (chip->awacs_reg[reg] & 0xf);
vol[0] = (chip->awacs_reg[reg] >> lshift) & 0xf;
vol[1] = chip->awacs_reg[reg] & 0xf;
spin_unlock_irqrestore(&chip->reg_lock, flags);
if (inverted) {
vol[0] = 0x0f - vol[0];
vol[1] = 0x0f - vol[1];
}
ucontrol->value.integer.value[0] = vol[0];
ucontrol->value.integer.value[1] = vol[1];
return 0;
}
......@@ -148,14 +157,24 @@ static int snd_pmac_awacs_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_valu
pmac_t *chip = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
int lshift = (kcontrol->private_value >> 8) & 0xff;
int inverted = (kcontrol->private_value >> 16) & 1;
int val, oldval;
unsigned long flags;
int vol[2];
vol[0] = ucontrol->value.integer.value[0];
vol[1] = ucontrol->value.integer.value[1];
if (inverted) {
vol[0] = 0x0f - vol[0];
vol[1] = 0x0f - vol[1];
}
vol[0] &= 0x0f;
vol[1] &= 0x0f;
spin_lock_irqsave(&chip->reg_lock, flags);
oldval = chip->awacs_reg[reg];
val = oldval & ~(0xf | (0xf << lshift));
val |= ((0x0f - (ucontrol->value.integer.value[0] & 0xf)) << lshift);
val |= 0x0f - (ucontrol->value.integer.value[1] & 0xf);
val |= vol[0] << lshift;
val |= vol[1];
if (oldval != val)
snd_pmac_awacs_write_reg(chip, reg, val);
spin_unlock_irqrestore(&chip->reg_lock, flags);
......@@ -163,12 +182,12 @@ static int snd_pmac_awacs_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_valu
}
#define AWACS_VOLUME(xname, xreg, xshift) \
#define AWACS_VOLUME(xname, xreg, xshift, xinverted) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
.info = snd_pmac_awacs_info_volume, \
.get = snd_pmac_awacs_get_volume, \
.put = snd_pmac_awacs_put_volume, \
.private_value = (xreg) | ((xshift) << 8) }
.private_value = (xreg) | ((xshift) << 8) | ((xinverted) << 16) }
/*
* mute master/ogain for AWACS: mono
......@@ -539,9 +558,9 @@ static int snd_pmac_screamer_mic_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_ele
* lists of mixer elements
*/
static snd_kcontrol_new_t snd_pmac_awacs_mixers[] __initdata = {
AWACS_VOLUME("Master Playback Volume", 2, 6),
AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
AWACS_VOLUME("Capture Volume", 0, 4),
AWACS_VOLUME("Capture Volume", 0, 4, 0),
AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
......@@ -564,7 +583,7 @@ static snd_kcontrol_new_t snd_pmac_screamer_mic_boost[] __initdata = {
};
static snd_kcontrol_new_t snd_pmac_awacs_speaker_vol[] __initdata = {
AWACS_VOLUME("PC Speaker Playback Volume", 4, 6),
AWACS_VOLUME("PC Speaker Playback Volume", 4, 6, 1),
};
static snd_kcontrol_new_t snd_pmac_awacs_speaker_sw __initdata =
AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
......
......@@ -22,6 +22,7 @@
#include <sound/driver.h>
#include <asm/io.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "pmac.h"
#include "burgundy.h"
......@@ -196,9 +197,10 @@ static int snd_pmac_burgundy_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_v
#define BURGUNDY_VOLUME(xname, xindex, addr, shift) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
.info = snd_pmac_burgundy_info_volume,\ .get = snd_pmac_burgundy_get_volume,\
.put = snd_pmac_burgundy_put_volume,\ .private_value = ((ADDR2BASE(addr) &
0xff) | ((shift) << 8)) }
.info = snd_pmac_burgundy_info_volume,\
.get = snd_pmac_burgundy_get_volume,\
.put = snd_pmac_burgundy_put_volume,\
.private_value = ((ADDR2BASE(addr) & 0xff) | ((shift) << 8)) }
/* lineout/speaker */
......
......@@ -24,6 +24,7 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "pmac.h"
......
......@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "pmac.h"
......
......@@ -25,6 +25,7 @@
#include <asm/irq.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "pmac.h"
#include <sound/pcm_params.h>
......@@ -243,7 +244,10 @@ static int snd_pmac_pcm_prepare(pmac_t *chip, pmac_stream_t *rec, snd_pcm_substr
snd_pmac_dma_set_command(rec, &chip->extra_dma);
snd_pmac_dma_run(rec, RUN);
}
offset = runtime->dma_addr;
/* continuous DMA memory type doesn't provide the physical address,
* so we need to resolve the address here...
*/
offset = virt_to_bus(runtime->dma_area);
for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++) {
st_le32(&cp->phy_addr, offset);
st_le16(&cp->req_count, rec->period_size);
......@@ -650,9 +654,7 @@ static snd_pcm_ops_t snd_pmac_capture_ops = {
static void pmac_pcm_free(snd_pcm_t *pcm)
{
#if 0
snd_pcm_lib_preallocate_free_for_all(pcm);
#endif
}
int __init snd_pmac_pcm_new(pmac_t *chip)
......@@ -686,10 +688,8 @@ int __init snd_pmac_pcm_new(pmac_t *chip)
chip->playback.cur_freqs = chip->freqs_ok;
chip->capture.cur_freqs = chip->freqs_ok;
#if 0
/* preallocate 64k buffer */
snd_pcm_lib_preallocate_pages_for_all(pcm, 64 * 1024, 64 * 1024, GFP_KERNEL);
#endif
return 0;
}
......
......@@ -25,6 +25,7 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <asm/io.h>
#include <asm/irq.h>
......
......@@ -194,7 +194,7 @@ struct usbmidi {
struct usbmidi_out_endpoint {
usbmidi_t* umidi;
urb_t* urb;
struct urb* urb;
int max_transfer; /* size of urb buffer */
struct tasklet_struct tasklet;
......@@ -214,7 +214,7 @@ struct usbmidi_out_endpoint {
struct usbmidi_in_endpoint {
usbmidi_t* umidi;
usbmidi_endpoint_t* ep;
urb_t* urb;
struct urb* urb;
struct usbmidi_in_port {
int seq_port;
snd_midi_event_t* midi_event;
......@@ -229,7 +229,7 @@ static void snd_usbmidi_do_output(usbmidi_out_endpoint_t* ep);
/*
* Submits the URB, with error handling.
*/
static int snd_usbmidi_submit_urb(urb_t* urb, int flags)
static int snd_usbmidi_submit_urb(struct urb* urb, int flags)
{
int err = usb_submit_urb(urb, flags);
if (err < 0 && err != -ENODEV)
......@@ -283,7 +283,7 @@ static void snd_usbmidi_input_packet(usbmidi_in_endpoint_t* ep,
/*
* Processes the data read from the device.
*/
static void snd_usbmidi_in_urb_complete(urb_t* urb)
static void snd_usbmidi_in_urb_complete(struct urb* urb)
{
usbmidi_in_endpoint_t* ep = snd_magic_cast(usbmidi_in_endpoint_t, urb->context, return);
......@@ -305,7 +305,7 @@ static void snd_usbmidi_in_urb_complete(urb_t* urb)
}
}
static void snd_usbmidi_out_urb_complete(urb_t* urb)
static void snd_usbmidi_out_urb_complete(struct urb* urb)
{
usbmidi_out_endpoint_t* ep = snd_magic_cast(usbmidi_out_endpoint_t, urb->context, return);
unsigned long flags;
......
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