Commit e1f8e356 authored by Jaroslav Kysela's avatar Jaroslav Kysela

Merge suse.cz:/home/perex/bk/linux-sound/linux-sound

into suse.cz:/home/perex/bk/linux-sound/work
parents 53b4c216 6a4dad1d
This diff is collapsed.
This document describes standard names of mixer controls.
Syntax: SOURCE [DIRECTION] FUNCTION
DIRECTION:
<nothing> (both directions)
Playback
Capture
Bypass Playback
Bypass Capture
FUNCTION:
Switch (on/off switch)
Volume
Route (route control, hardware specific)
SOURCE:
Master
Master Mono
Hardware Master
Headphone
PC Speaker
Phone
Phone Input
Phone Output
Synth
FM
Mic
Line
CD
Video
Zoom Video
Aux
PCM
PCM Front
PCM Rear
PCM Pan
Loopback
Analog Loopback (D/A -> A/D loopback)
Digital Loopback (playback -> capture loopback - without analog path)
Mono
Mono Output
Multi
ADC
Wave
Music
I2S
IEC958
Exceptions:
[Digital] Capture Source
[Digital] Capture Switch (aka input gain switch)
[Digital] Capture Volume (aka input gain volume)
[Digital] Playback Switch (aka output gain switch)
[Digital] Playback Volume (aka output gain volume)
Tone Control - Switch
Tone Control - Bass
Tone Control - Treble
3D Control - Switch
3D Control - Center
3D Control - Depth
3D Control - Wide
3D Control - Space
3D Control - Level
Mic Boost [(?dB)]
PCM interface:
Sample Clock Source { "Word", "Internal", "AutoSync" }
Clock Sync Status { "Lock", "Sync", "No Lock" }
External Rate /* external capture rate */
Capture Rate /* capture rate taken from external source */
IEC958 (S/PDIF) interface:
IEC958 [...] [Playback|Capture] Switch /* turn on/off the IEC958 interface */
IEC958 [...] [Playback|Capture] Volume /* digital volume control */
IEC958 [...] [Playback|Capture] Default /* default or global value - read/write */
IEC958 [...] [Playback|Capture] Mask /* consumer and professional mask */
IEC958 [...] [Playback|Capture] Con Mask /* consumer mask */
IEC958 [...] [Playback|Capture] Pro Mask /* professional mask */
IEC958 [...] [Playback|Capture] PCM Stream /* the settings assigned to a PCM stream */
...@@ -2091,6 +2091,9 @@ static void hp100_update_stats(struct net_device *dev) ...@@ -2091,6 +2091,9 @@ static void hp100_update_stats(struct net_device *dev)
static void hp100_misc_interrupt(struct net_device *dev) static void hp100_misc_interrupt(struct net_device *dev)
{ {
#ifdef HP100_DEBUG_B
int ioaddr = dev->base_addr;
#endif
struct hp100_private *lp = (struct hp100_private *) dev->priv; struct hp100_private *lp = (struct hp100_private *) dev->priv;
#ifdef HP100_DEBUG_B #ifdef HP100_DEBUG_B
......
/* include/version.h. Generated automatically by configure. */ /* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc6" #define CONFIG_SND_VERSION "0.9.0rc6"
#define CONFIG_SND_DATE " (Wed Dec 11 21:24:39 2002 UTC)" #define CONFIG_SND_DATE " (Tue Dec 17 19:01:13 2002 UTC)"
...@@ -92,6 +92,56 @@ int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream) ...@@ -92,6 +92,56 @@ int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream)
return 0; return 0;
} }
/*
* snd_pci_alloc_page - allocate a page in the valid pci dma mask
*
* returns the virtual address and stores the physical address on
* addrp. this function cannot be called from interrupt handlers or
* within spinlocks.
*/
#ifdef __i386__
/*
* on ix86, we allocate a page with GFP_KERNEL to assure the
* allocation. the code is almost same with kernel/i386/pci-dma.c but
* it allocates only a single page and checkes the validity of the
* page address with the given pci dma mask.
*/
inline static void *snd_pci_alloc_page(struct pci_dev *pci, dma_addr_t *addrp)
{
void *ptr;
dma_addr_t addr;
unsigned long rmask;
if (pci)
rmask = ~(unsigned long)pci->dma_mask;
else
rmask = 0;
ptr = (void *)__get_free_page(GFP_KERNEL);
if (ptr) {
addr = virt_to_phys(ptr);
if (((unsigned long)addr + PAGE_SIZE - 1) & rmask) {
/* try to reallocate with the GFP_DMA */
free_page((unsigned long)ptr);
ptr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
if (ptr) /* ok, the address must be within lower 16MB... */
addr = virt_to_phys(ptr);
else
addr = 0;
}
} else
addr = 0;
if (ptr)
memset(ptr, 0, PAGE_SIZE);
*addrp = addr;
return ptr;
}
#else
/* on other architectures, call snd_malloc_pci_pages() helper function
* which uses pci_alloc_consistent().
*/
#define snd_pci_alloc_page(pci, addrp) snd_malloc_pci_pages(pci, PAGE_SIZE, addrp)
#endif
/* /*
* allocate sg buffer table with the given byte size. * allocate sg buffer table with the given byte size.
* if the buffer table already exists, try to resize it. * if the buffer table already exists, try to resize it.
...@@ -128,7 +178,7 @@ int snd_pcm_sgbuf_alloc(snd_pcm_substream_t *substream, size_t size) ...@@ -128,7 +178,7 @@ int snd_pcm_sgbuf_alloc(snd_pcm_substream_t *substream, size_t size)
while (sgbuf->pages < pages) { while (sgbuf->pages < pages) {
void *ptr; void *ptr;
dma_addr_t addr; dma_addr_t addr;
ptr = snd_malloc_pci_pages(sgbuf->pci, PAGE_SIZE, &addr); ptr = snd_pci_alloc_page(sgbuf->pci, &addr);
if (! ptr) if (! ptr)
return -ENOMEM; return -ENOMEM;
sgbuf->table[sgbuf->pages].buf = ptr; sgbuf->table[sgbuf->pages].buf = ptr;
......
...@@ -205,19 +205,19 @@ static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev) ...@@ -205,19 +205,19 @@ static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev)
static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport) static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport)
{ {
int port; int p;
if (hwport <= 0x00) /* all ports */ if (hwport <= 0x00) /* all ports */
return chip->num_ports + MTPAV_PIDX_BROADCAST; return chip->num_ports + MTPAV_PIDX_BROADCAST;
else if (hwport <= 0x08) { /* single port */ else if (hwport <= 0x08) { /* single port */
port = hwport - 1; p = hwport - 1;
if (port >= chip->num_ports) if (p >= chip->num_ports)
port = 0; p = 0;
return port; return p;
} else if (hwport <= 0x10) { /* remote port */ } else if (hwport <= 0x10) { /* remote port */
port = hwport - 0x09 + chip->num_ports; p = hwport - 0x09 + chip->num_ports;
if (port >= chip->num_ports * 2) if (p >= chip->num_ports * 2)
port = chip->num_ports; p = chip->num_ports;
return port; return p;
} else if (hwport == 0x11) /* computer port */ } else if (hwport == 0x11) /* computer port */
return chip->num_ports + MTPAV_PIDX_COMPUTER; return chip->num_ports + MTPAV_PIDX_COMPUTER;
else /* ADAT */ else /* ADAT */
...@@ -335,11 +335,11 @@ static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream) ...@@ -335,11 +335,11 @@ static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream)
static void snd_mtpav_portscan(mtpav_t *chip) // put mtp into smart routing mode static void snd_mtpav_portscan(mtpav_t *chip) // put mtp into smart routing mode
{ {
u8 port; u8 p;
for (port = 0; port < 8; port++) { for (p = 0; p < 8; p++) {
snd_mtpav_send_byte(chip, 0xf5); snd_mtpav_send_byte(chip, 0xf5);
snd_mtpav_send_byte(chip, port); snd_mtpav_send_byte(chip, p);
snd_mtpav_send_byte(chip, 0xfe); snd_mtpav_send_byte(chip, 0xfe);
} }
} }
...@@ -350,12 +350,12 @@ static void snd_mtpav_portscan(mtpav_t *chip) // put mtp into smart routing mode ...@@ -350,12 +350,12 @@ static void snd_mtpav_portscan(mtpav_t *chip) // put mtp into smart routing mode
static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream) static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream)
{ {
unsigned long flags; unsigned long flags;
mtpav_port_t *port = &mtp_card->ports[substream->number]; mtpav_port_t *portp = &mtp_card->ports[substream->number];
//printk("mtpav port: %d opened\n", (int) substream->number); //printk("mtpav port: %d opened\n", (int) substream->number);
spin_lock_irqsave(&mtp_card->spinlock, flags); spin_lock_irqsave(&mtp_card->spinlock, flags);
port->mode |= MTPAV_MODE_INPUT_OPENED; portp->mode |= MTPAV_MODE_INPUT_OPENED;
port->input = substream; portp->input = substream;
if (mtp_card->share_irq++ == 0) if (mtp_card->share_irq++ == 0)
snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts
spin_unlock_irqrestore(&mtp_card->spinlock, flags); spin_unlock_irqrestore(&mtp_card->spinlock, flags);
...@@ -368,14 +368,14 @@ static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream) ...@@ -368,14 +368,14 @@ static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream)
static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream) static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream)
{ {
unsigned long flags; unsigned long flags;
mtpav_port_t *port = &mtp_card->ports[substream->number]; mtpav_port_t *portp = &mtp_card->ports[substream->number];
//printk("mtpav port: %d closed\n", (int) port); //printk("mtpav port: %d closed\n", (int) portp);
spin_lock_irqsave(&mtp_card->spinlock, flags); spin_lock_irqsave(&mtp_card->spinlock, flags);
port->mode &= (~MTPAV_MODE_INPUT_OPENED); portp->mode &= (~MTPAV_MODE_INPUT_OPENED);
port->input = NULL; portp->input = NULL;
if (--mtp_card->share_irq == 0) if (--mtp_card->share_irq == 0)
snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts
...@@ -389,13 +389,13 @@ static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream) ...@@ -389,13 +389,13 @@ static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream)
static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up) static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up)
{ {
unsigned long flags; unsigned long flags;
mtpav_port_t *port = &mtp_card->ports[substream->number]; mtpav_port_t *portp = &mtp_card->ports[substream->number];
spin_lock_irqsave(&mtp_card->spinlock, flags); spin_lock_irqsave(&mtp_card->spinlock, flags);
if (up) if (up)
port->mode |= MTPAV_MODE_INPUT_TRIGGERED; portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
else else
port->mode &= ~MTPAV_MODE_INPUT_TRIGGERED; portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
spin_unlock_irqrestore(&mtp_card->spinlock, flags); spin_unlock_irqrestore(&mtp_card->spinlock, flags);
} }
...@@ -416,9 +416,9 @@ static void snd_mtpav_output_timer(unsigned long data) ...@@ -416,9 +416,9 @@ static void snd_mtpav_output_timer(unsigned long data)
add_timer(&chip->timer); add_timer(&chip->timer);
/* process each port */ /* process each port */
for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) { for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
mtpav_port_t *port = &mtp_card->ports[p]; mtpav_port_t *portp = &mtp_card->ports[p];
if ((port->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && port->output) if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
snd_mtpav_output_port_write(port, port->output); snd_mtpav_output_port_write(portp, portp->output);
} }
spin_unlock(&chip->spinlock); spin_unlock(&chip->spinlock);
} }
...@@ -445,11 +445,11 @@ static void snd_mtpav_remove_output_timer(mtpav_t *chip) ...@@ -445,11 +445,11 @@ static void snd_mtpav_remove_output_timer(mtpav_t *chip)
static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream) static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream)
{ {
unsigned long flags; unsigned long flags;
mtpav_port_t *port = &mtp_card->ports[substream->number]; mtpav_port_t *portp = &mtp_card->ports[substream->number];
spin_lock_irqsave(&mtp_card->spinlock, flags); spin_lock_irqsave(&mtp_card->spinlock, flags);
port->mode |= MTPAV_MODE_OUTPUT_OPENED; portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
port->output = substream; portp->output = substream;
spin_unlock_irqrestore(&mtp_card->spinlock, flags); spin_unlock_irqrestore(&mtp_card->spinlock, flags);
return 0; return 0;
}; };
...@@ -460,11 +460,11 @@ static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream) ...@@ -460,11 +460,11 @@ static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream)
static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream) static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream)
{ {
unsigned long flags; unsigned long flags;
mtpav_port_t *port = &mtp_card->ports[substream->number]; mtpav_port_t *portp = &mtp_card->ports[substream->number];
spin_lock_irqsave(&mtp_card->spinlock, flags); spin_lock_irqsave(&mtp_card->spinlock, flags);
port->mode &= (~MTPAV_MODE_OUTPUT_OPENED); portp->mode &= (~MTPAV_MODE_OUTPUT_OPENED);
port->output = NULL; portp->output = NULL;
spin_unlock_irqrestore(&mtp_card->spinlock, flags); spin_unlock_irqrestore(&mtp_card->spinlock, flags);
return 0; return 0;
}; };
...@@ -475,17 +475,17 @@ static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream) ...@@ -475,17 +475,17 @@ static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream)
static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up) static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up)
{ {
unsigned long flags; unsigned long flags;
mtpav_port_t *port = &mtp_card->ports[substream->number]; mtpav_port_t *portp = &mtp_card->ports[substream->number];
spin_lock_irqsave(&mtp_card->spinlock, flags); spin_lock_irqsave(&mtp_card->spinlock, flags);
if (up) { if (up) {
if (! (port->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) { if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
if (mtp_card->istimer++ == 0) if (mtp_card->istimer++ == 0)
snd_mtpav_add_output_timer(mtp_card); snd_mtpav_add_output_timer(mtp_card);
port->mode |= MTPAV_MODE_OUTPUT_TRIGGERED; portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
} }
} else { } else {
port->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED; portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
if (--mtp_card->istimer == 0) if (--mtp_card->istimer == 0)
snd_mtpav_remove_output_timer(mtp_card); snd_mtpav_remove_output_timer(mtp_card);
} }
...@@ -501,15 +501,15 @@ static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up ...@@ -501,15 +501,15 @@ static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up
static void snd_mtpav_inmidi_process(mtpav_t *mcrd, u8 inbyte) static void snd_mtpav_inmidi_process(mtpav_t *mcrd, u8 inbyte)
{ {
mtpav_port_t *port; mtpav_port_t *portp;
if (mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST) if (mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
return; return;
port = &mcrd->ports[mcrd->inmidiport]; portp = &mcrd->ports[mcrd->inmidiport];
if (port->mode & MTPAV_MODE_INPUT_TRIGGERED) { if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED) {
spin_unlock(&mcrd->spinlock); spin_unlock(&mcrd->spinlock);
snd_rawmidi_receive(port->input, &inbyte, 1); snd_rawmidi_receive(portp->input, &inbyte, 1);
spin_lock(&mcrd->spinlock); spin_lock(&mcrd->spinlock);
} }
} }
......
...@@ -1831,9 +1831,10 @@ static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t ...@@ -1831,9 +1831,10 @@ static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
return change; return change;
} }
static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinit = { static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinitdata = {
/* spdif aplayback switch */ /* spdif aplayback switch */
ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, 0), /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */
ALI5451_SPDIF("IEC958 Output switch", 0, 0),
/* spdif out to spdif channel */ /* spdif out to spdif channel */
ALI5451_SPDIF("IEC958 Channel Output Switch", 0, 1), ALI5451_SPDIF("IEC958 Channel Output Switch", 0, 1),
/* spdif in from spdif channel */ /* spdif in from spdif channel */
...@@ -1861,7 +1862,7 @@ static int __devinit snd_ali_mixer(ali_t * codec) ...@@ -1861,7 +1862,7 @@ static int __devinit snd_ali_mixer(ali_t * codec)
return err; return err;
} }
if (codec->revision == ALI_5451_V02) { if (codec->revision == ALI_5451_V02) {
for(idx = 0; idx < 3; idx++) { for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
if (err < 0) return err; if (err < 0) return err;
} }
...@@ -2010,10 +2011,12 @@ static int snd_ali_chip_init(ali_t *codec) ...@@ -2010,10 +2011,12 @@ static int snd_ali_chip_init(ali_t *codec)
if (codec->revision == ALI_5451_V02) { if (codec->revision == ALI_5451_V02) {
pci_dev = codec->pci_m1533; pci_dev = codec->pci_m1533;
pci_read_config_byte(pci_dev, 0x59, &temp); pci_read_config_byte(pci_dev, 0x59, &temp);
temp |= 0x80;
pci_write_config_byte(pci_dev, 0x59, temp);
pci_dev = codec->pci_m7101; pci_dev = codec->pci_m7101;
pci_read_config_byte(pci_dev, 0xb8, &temp); pci_read_config_byte(pci_dev, 0xb8, &temp);
temp |= 1 << 6; temp |= 0x20;
pci_write_config_byte(pci_dev, 0xB8, temp); pci_write_config_byte(pci_dev, 0xB8, temp);
} }
......
...@@ -164,7 +164,7 @@ struct _snd_fm801 { ...@@ -164,7 +164,7 @@ struct _snd_fm801 {
}; };
static struct pci_device_id snd_fm801_ids[] __devinitdata = { static struct pci_device_id snd_fm801_ids[] __devinitdata = {
{ 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FM801 */ { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
{ 0, } { 0, }
}; };
......
...@@ -24,7 +24,10 @@ ...@@ -24,7 +24,10 @@
* *
*/ */
#define HOONTECH_DEVICE_DESC "{Hoontech SoundTrack DSP 24}," #define HOONTECH_DEVICE_DESC \
"{Hoontech SoundTrack DSP 24}," \
"{Hoontech SoundTrack DSP 24 Value}," \
"{Hoontech SoundTrack DSP 24 Media 7.1}," \
#define ICE1712_SUBDEVICE_STDSP24 0x12141217 /* Hoontech SoundTrack Audio DSP 24 */ #define ICE1712_SUBDEVICE_STDSP24 0x12141217 /* Hoontech SoundTrack Audio DSP 24 */
#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
......
...@@ -53,6 +53,7 @@ MODULE_DEVICES("{{Intel,82801AA-ICH}," ...@@ -53,6 +53,7 @@ MODULE_DEVICES("{{Intel,82801AA-ICH},"
"{Intel,MX440}," "{Intel,MX440},"
"{SiS,SI7012}," "{SiS,SI7012},"
"{NVidia,NForce Audio}," "{NVidia,NForce Audio},"
"{NVidia,NForce2 Audio},"
"{AMD,AMD768}," "{AMD,AMD768},"
"{AMD,AMD8111}," "{AMD,AMD8111},"
"{ALI,M5455}}"); "{ALI,M5455}}");
...@@ -127,6 +128,9 @@ MODULE_PARM_SYNTAX(mpu_port, SNDRV_ENABLED ",allows:{{0},{0x330},{0x300}},dialog ...@@ -127,6 +128,9 @@ MODULE_PARM_SYNTAX(mpu_port, SNDRV_ENABLED ",allows:{{0},{0x330},{0x300}},dialog
#ifndef PCI_DEVICE_ID_NVIDIA_MCP_AUDIO #ifndef PCI_DEVICE_ID_NVIDIA_MCP_AUDIO
#define PCI_DEVICE_ID_NVIDIA_MCP_AUDIO 0x01b1 #define PCI_DEVICE_ID_NVIDIA_MCP_AUDIO 0x01b1
#endif #endif
#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a
#endif
enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI }; enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI };
...@@ -383,6 +387,7 @@ static struct pci_device_id snd_intel8x0_ids[] __devinitdata = { ...@@ -383,6 +387,7 @@ static struct pci_device_id snd_intel8x0_ids[] __devinitdata = {
{ 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */ { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
{ 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */ { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */
{ 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE */ { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE */
{ 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE2 */
{ 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
{ 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
{ 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
...@@ -2298,6 +2303,7 @@ static struct shortname_table { ...@@ -2298,6 +2303,7 @@ static struct shortname_table {
{ PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" }, { PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" }, { PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" }, { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" },
{ PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia NForce2" },
{ 0x746d, "AMD AMD8111" }, { 0x746d, "AMD AMD8111" },
{ 0x7445, "AMD AMD768" }, { 0x7445, "AMD AMD768" },
{ 0x5455, "ALi M5455" }, { 0x5455, "ALi M5455" },
......
...@@ -526,7 +526,11 @@ static struct snd_urb_ops audio_urb_ops[2] = { ...@@ -526,7 +526,11 @@ static struct snd_urb_ops audio_urb_ops[2] = {
/* /*
* complete callback from data urb * complete callback from data urb
*/ */
#ifndef OLD_USB
static void snd_complete_urb(struct urb *urb, struct pt_regs *regs) static void snd_complete_urb(struct urb *urb, struct pt_regs *regs)
#else
static void snd_complete_urb(struct urb *urb)
#endif
{ {
snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
snd_usb_substream_t *subs = ctx->subs; snd_usb_substream_t *subs = ctx->subs;
...@@ -551,7 +555,11 @@ static void snd_complete_urb(struct urb *urb, struct pt_regs *regs) ...@@ -551,7 +555,11 @@ static void snd_complete_urb(struct urb *urb, struct pt_regs *regs)
/* /*
* complete callback from sync urb * complete callback from sync urb
*/ */
#ifndef OLD_USB
static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs) static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs)
#else
static void snd_complete_sync_urb(struct urb *urb)
#endif
{ {
snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
snd_usb_substream_t *subs = ctx->subs; snd_usb_substream_t *subs = ctx->subs;
...@@ -583,6 +591,9 @@ static int deactivate_urbs(snd_usb_substream_t *subs) ...@@ -583,6 +591,9 @@ static int deactivate_urbs(snd_usb_substream_t *subs)
subs->running = 0; subs->running = 0;
if (subs->stream->chip->shutdown) /* to be sure... */
return 0;
#ifndef SND_USB_ASYNC_UNLINK #ifndef SND_USB_ASYNC_UNLINK
if (in_interrupt()) if (in_interrupt())
return 0; return 0;
...@@ -870,7 +881,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run ...@@ -870,7 +881,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run
u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS; u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS;
u->urb->number_of_packets = u->packets; u->urb->number_of_packets = u->packets;
u->urb->context = u; u->urb->context = u;
u->urb->complete = snd_complete_urb; u->urb->complete = (usb_complete_t)snd_complete_urb;
} }
if (subs->syncpipe) { if (subs->syncpipe) {
...@@ -892,7 +903,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run ...@@ -892,7 +903,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run
u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS; u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS;
u->urb->number_of_packets = u->packets; u->urb->number_of_packets = u->packets;
u->urb->context = u; u->urb->context = u;
u->urb->complete = snd_complete_sync_urb; u->urb->complete = (usb_complete_t)snd_complete_sync_urb;
} }
} }
return 0; return 0;
...@@ -2253,9 +2264,6 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) ...@@ -2253,9 +2264,6 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
snd_usb_audio_t *chip; snd_usb_audio_t *chip;
snd_card_t *card; snd_card_t *card;
struct list_head *p; struct list_head *p;
snd_usb_stream_t *as;
snd_usb_substream_t *subs;
int idx;
if (ptr == (void *)-1) if (ptr == (void *)-1)
return; return;
...@@ -2265,22 +2273,21 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) ...@@ -2265,22 +2273,21 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
down(&register_mutex); down(&register_mutex);
chip->shutdown = 1; chip->shutdown = 1;
chip->num_interfaces--; chip->num_interfaces--;
if (chip->num_interfaces <= 0) if (chip->num_interfaces <= 0) {
snd_card_disconnect(card); snd_card_disconnect(card);
/* release the pcm resources */
list_for_each(p, &chip->pcm_list) { list_for_each(p, &chip->pcm_list) {
snd_usb_stream_t *as;
int idx;
as = list_entry(p, snd_usb_stream_t, list); as = list_entry(p, snd_usb_stream_t, list);
for (idx = 0; idx < 2; idx++) { for (idx = 0; idx < 2; idx++) {
snd_usb_substream_t *subs;
subs = &as->substream[idx]; subs = &as->substream[idx];
if (!subs->num_formats) if (!subs->num_formats)
continue; continue;
release_substream_urbs(subs); release_substream_urbs(subs);
if (subs->interface >= 0) {
usb_set_interface(subs->dev, subs->interface, 0);
subs->interface = -1;
} }
} }
}
if (chip->num_interfaces <= 0) {
up(&register_mutex); up(&register_mutex);
snd_card_free_in_thread(card); snd_card_free_in_thread(card);
} else { } else {
......
...@@ -172,7 +172,11 @@ static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep, ...@@ -172,7 +172,11 @@ static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep,
/* /*
* Processes the data read from the device. * Processes the data read from the device.
*/ */
#ifndef OLD_USB
static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs) static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
#else
static void snd_usbmidi_in_urb_complete(struct urb* urb)
#endif
{ {
snd_usb_midi_in_endpoint_t* ep = snd_magic_cast(snd_usb_midi_in_endpoint_t, urb->context, return); snd_usb_midi_in_endpoint_t* ep = snd_magic_cast(snd_usb_midi_in_endpoint_t, urb->context, return);
...@@ -197,7 +201,11 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs) ...@@ -197,7 +201,11 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
/* /*
* Converts the data read from a Midiman device to standard USB MIDI packets. * Converts the data read from a Midiman device to standard USB MIDI packets.
*/ */
#ifndef OLD_USB
static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *regs) static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *regs)
#else
static void snd_usbmidi_in_midiman_complete(struct urb* urb)
#endif
{ {
if (urb->status == 0) { if (urb->status == 0) {
uint8_t* buffer = (uint8_t*)urb->transfer_buffer; uint8_t* buffer = (uint8_t*)urb->transfer_buffer;
...@@ -223,10 +231,18 @@ static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *reg ...@@ -223,10 +231,18 @@ static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *reg
} }
} }
} }
#ifndef OLD_USB
snd_usbmidi_in_urb_complete(urb, regs); snd_usbmidi_in_urb_complete(urb, regs);
#else
snd_usbmidi_in_urb_complete(urb);
#endif
} }
#ifndef OLD_USB
static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs) static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
#else
static void snd_usbmidi_out_urb_complete(struct urb* urb)
#endif
{ {
snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, urb->context, return); snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, urb->context, return);
...@@ -451,8 +467,10 @@ static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int u ...@@ -451,8 +467,10 @@ static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int u
usbmidi_out_port_t* port = (usbmidi_out_port_t*)substream->runtime->private_data; usbmidi_out_port_t* port = (usbmidi_out_port_t*)substream->runtime->private_data;
port->active = up; port->active = up;
if (up) if (up) {
if (! port->ep->umidi->chip->shutdown) /* to be sure... */
tasklet_hi_schedule(&port->ep->tasklet); tasklet_hi_schedule(&port->ep->tasklet);
}
} }
static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream) static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream)
...@@ -489,6 +507,7 @@ static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) ...@@ -489,6 +507,7 @@ static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
{ {
if (ep->urb) { if (ep->urb) {
if (ep->urb->transfer_buffer) { if (ep->urb->transfer_buffer) {
if (! ep->umidi->chip->shutdown) /* to be sure */
usb_unlink_urb(ep->urb); usb_unlink_urb(ep->urb);
kfree(ep->urb->transfer_buffer); kfree(ep->urb->transfer_buffer);
} }
...@@ -587,10 +606,12 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, ...@@ -587,10 +606,12 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi,
} }
if (int_epd) if (int_epd)
usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
snd_usbmidi_in_urb_complete, ep, int_epd->bInterval); (usb_complete_t)snd_usbmidi_in_urb_complete,
ep, int_epd->bInterval);
else else
usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
snd_usbmidi_in_urb_complete, ep); (usb_complete_t)snd_usbmidi_in_urb_complete,
ep);
rep->in = ep; rep->in = ep;
return 0; return 0;
...@@ -615,6 +636,7 @@ static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep) ...@@ -615,6 +636,7 @@ static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep)
tasklet_kill(&ep->tasklet); tasklet_kill(&ep->tasklet);
if (ep->urb) { if (ep->urb) {
if (ep->urb->transfer_buffer) { if (ep->urb->transfer_buffer) {
if (! ep->umidi->chip->shutdown) /* to be sure */
usb_unlink_urb(ep->urb); usb_unlink_urb(ep->urb);
kfree(ep->urb->transfer_buffer); kfree(ep->urb->transfer_buffer);
} }
...@@ -654,7 +676,8 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, ...@@ -654,7 +676,8 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi,
return -ENOMEM; return -ENOMEM;
} }
usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
ep->max_transfer, snd_usbmidi_out_urb_complete, ep); ep->max_transfer,
(usb_complete_t)snd_usbmidi_out_urb_complete, ep);
spin_lock_init(&ep->buffer_lock); spin_lock_init(&ep->buffer_lock);
tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep);
...@@ -944,7 +967,7 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, ...@@ -944,7 +967,7 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi,
err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
if (err < 0) if (err < 0)
return err; return err;
umidi->endpoints[0].in->urb->complete = snd_usbmidi_in_midiman_complete; umidi->endpoints[0].in->urb->complete = (usb_complete_t)snd_usbmidi_in_midiman_complete;
if (endpoint->out_cables > 0x0001) { if (endpoint->out_cables > 0x0001) {
ep_info.epnum = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ep_info.epnum = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
......
...@@ -296,7 +296,7 @@ static int get_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, i ...@@ -296,7 +296,7 @@ static int get_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, i
return 0; return 0;
} }
} }
snd_printdd(KERN_ERR "cannot get ctl value: req = 0x%x, idx = 0x%x, val = 0x%x, type = %d\n", request, validx, cval->ctrlif | (cval->id << 8), cval->val_type); snd_printdd(KERN_ERR "cannot get ctl value: req = 0x%x, wValue = 0x%x, wIndex = 0x%x, type = %d\n", request, validx, cval->ctrlif | (cval->id << 8), cval->val_type);
return -EINVAL; return -EINVAL;
} }
...@@ -331,6 +331,7 @@ static int set_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, i ...@@ -331,6 +331,7 @@ static int set_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, i
validx, cval->ctrlif | (cval->id << 8), validx, cval->ctrlif | (cval->id << 8),
buf, val_len, HZ / 10) >= 0) buf, val_len, HZ / 10) >= 0)
return 0; return 0;
snd_printdd(KERN_ERR "cannot set ctl value: req = 0x%x, wValue = 0x%x, wIndex = 0x%x, type = %d, data = 0x%x/0x%x\n", request, validx, cval->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]);
return -EINVAL; return -EINVAL;
} }
...@@ -571,11 +572,11 @@ static void usb_mixer_elem_free(snd_kcontrol_t *kctl) ...@@ -571,11 +572,11 @@ static void usb_mixer_elem_free(snd_kcontrol_t *kctl)
/* /*
* retrieve the minimum and maximum values for the specified control * retrieve the minimum and maximum values for the specified control
*/ */
static int get_min_max(usb_mixer_elem_info_t *cval) static int get_min_max(usb_mixer_elem_info_t *cval, int default_min)
{ {
/* for failsafe */ /* for failsafe */
cval->min = 0; cval->min = default_min;
cval->max = 1; cval->max = cval->min + 1;
cval->res = 1; cval->res = 1;
if (cval->val_type == USB_MIXER_BOOLEAN || if (cval->val_type == USB_MIXER_BOOLEAN ||
...@@ -634,7 +635,7 @@ static int mixer_ctl_feature_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t ...@@ -634,7 +635,7 @@ static int mixer_ctl_feature_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
uinfo->value.integer.max = 1; uinfo->value.integer.max = 1;
} else { } else {
if (! cval->initialized) if (! cval->initialized)
get_min_max(cval); get_min_max(cval, 0);
uinfo->value.integer.min = 0; uinfo->value.integer.min = 0;
uinfo->value.integer.max = (cval->max - cval->min) / cval->res; uinfo->value.integer.max = (cval->max - cval->min) / cval->res;
} }
...@@ -784,7 +785,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc, ...@@ -784,7 +785,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
} }
/* get min/max values */ /* get min/max values */
get_min_max(cval); get_min_max(cval, 0);
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
if (! kctl) { if (! kctl) {
...@@ -952,7 +953,7 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc, ...@@ -952,7 +953,7 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
} }
/* get min/max values */ /* get min/max values */
get_min_max(cval); get_min_max(cval, 0);
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
if (! kctl) { if (! kctl) {
...@@ -1060,6 +1061,7 @@ struct procunit_value_info { ...@@ -1060,6 +1061,7 @@ struct procunit_value_info {
int control; int control;
char *suffix; char *suffix;
int val_type; int val_type;
int min_value;
}; };
struct procunit_info { struct procunit_info {
...@@ -1070,12 +1072,12 @@ struct procunit_info { ...@@ -1070,12 +1072,12 @@ struct procunit_info {
static struct procunit_value_info updown_proc_info[] = { static struct procunit_value_info updown_proc_info[] = {
{ USB_PROC_UPDOWN_SWITCH, "Switch", USB_MIXER_BOOLEAN }, { USB_PROC_UPDOWN_SWITCH, "Switch", USB_MIXER_BOOLEAN },
{ USB_PROC_UPDOWN_MODE_SEL, "Mode Select", USB_MIXER_U8 }, { USB_PROC_UPDOWN_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 },
{ 0 } { 0 }
}; };
static struct procunit_value_info prologic_proc_info[] = { static struct procunit_value_info prologic_proc_info[] = {
{ USB_PROC_PROLOGIC_SWITCH, "Switch", USB_MIXER_BOOLEAN }, { USB_PROC_PROLOGIC_SWITCH, "Switch", USB_MIXER_BOOLEAN },
{ USB_PROC_PROLOGIC_MODE_SEL, "Mode Select", USB_MIXER_U8 }, { USB_PROC_PROLOGIC_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 },
{ 0 } { 0 }
}; };
static struct procunit_value_info threed_enh_proc_info[] = { static struct procunit_value_info threed_enh_proc_info[] = {
...@@ -1173,7 +1175,7 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char ...@@ -1173,7 +1175,7 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char
cval->channels = 1; cval->channels = 1;
/* get min/max values */ /* get min/max values */
get_min_max(cval); get_min_max(cval, valinfo->min_value);
kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
if (! kctl) { if (! kctl) {
......
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