Commit 2c4dcfb7 authored by Linus Torvalds's avatar Linus Torvalds

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

into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents 90ebbda4 909ab438
......@@ -755,8 +755,10 @@ Module parameters
port - port number or -1 (disable)
irq - IRQ number or -1 (disable)
acpipnp - ACPI PnP detection - 0 = disable, 1 = enable (default)
Module supports multiple devices (max 8).
Module supports multiple devices (max 8) and ACPI PnP. If PnP is not
used (or ACPI not enabled), port and irq must be specified.
Module snd-mtpav
----------------
......
......@@ -226,10 +226,14 @@
#define AC97_GPIO_LINE2_HL1R 0x8000 /* Opt./ Handset to Line2 relay control (out) */
/* specific - SigmaTel */
#define AC97_SIGMATEL_OUTSEL 0x64 /* Output Select, STAC9758 */
#define AC97_SIGMATEL_INSEL 0x66 /* Input Select, STAC9758 */
#define AC97_SIGMATEL_IOMISC 0x68 /* STAC9758 */
#define AC97_SIGMATEL_ANALOG 0x6c /* Analog Special */
#define AC97_SIGMATEL_DAC2INVERT 0x6e
#define AC97_SIGMATEL_BIAS1 0x70
#define AC97_SIGMATEL_BIAS2 0x72
#define AC97_SIGMATEL_VARIOUS 0x72 /* STAC9758 */
#define AC97_SIGMATEL_MULTICHN 0x74 /* Multi-Channel programming */
#define AC97_SIGMATEL_CIC1 0x76
#define AC97_SIGMATEL_CIC2 0x78
......
......@@ -2,6 +2,12 @@
* Driver for generic MPU-401 boards (UART mode only)
* Copyright (c) by Jaroslav Kysela <perex@suse.cz>
*
* ACPI PnP Copyright (c) 2004 by Clemens Ladisch <clemens@ladisch.de>
* based on 8250_acpi.c
* Copyright (c) 2002-2003 Matthew Wilcox for Hewlett-Packard
* Copyright (C) 2004 Hewlett-Packard Co
* Bjorn Helgaas <bjorn.helgaas@hp.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
......@@ -21,14 +27,17 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/slab.h>
#ifdef CONFIG_ACPI_BUS
#include <acpi/acpi_bus.h>
#endif
#include <sound/core.h>
#include <sound/mpu401.h>
#define SNDRV_GET_ID
#include <sound/initval.h>
#include <linux/delay.h>
#ifdef CONFIG_ACPI_BUS
#define USE_ACPI_PNP
#endif
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("MPU-401 UART");
......@@ -38,6 +47,9 @@ MODULE_CLASSES("{sound}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
#ifdef USE_ACPI_PNP
static int acpipnp[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
#ifdef CONFIG_X86_PC9800
......@@ -53,6 +65,11 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable MPU-401 device.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
#ifdef USE_ACPI_PNP
MODULE_PARM(acpipnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(acpipnp, "ACPI PnP detection for MPU-401 device.");
MODULE_PARM_SYNTAX(acpipnp, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
#endif
MODULE_PARM(port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
......@@ -65,25 +82,107 @@ MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
#endif
static snd_card_t *snd_mpu401_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
#ifndef CONFIG_ACPI_BUS
struct acpi_device;
#endif
static snd_card_t *snd_mpu401_legacy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
#ifdef USE_ACPI_PNP
struct mpu401_resources {
unsigned long port;
int irq;
};
static int __init snd_card_mpu401_probe(int dev)
static acpi_status __devinit snd_mpu401_acpi_resource(struct acpi_resource *res,
void *data)
{
struct mpu401_resources *resources = (struct mpu401_resources *)data;
if (res->id == ACPI_RSTYPE_IRQ) {
if (res->data.irq.number_of_interrupts > 0) {
#ifdef CONFIG_IA64
resources->irq = acpi_register_irq(res->data.irq.interrupts[0],
res->data.irq.active_high_low,
res->data.irq.edge_level);
#else
resources->irq = res->data.irq.interrupts[0];
#endif
}
} else if (res->id == ACPI_RSTYPE_IO) {
if (res->data.io.range_length >= 2) {
resources->port = res->data.io.min_base_address;
}
}
return AE_OK;
}
static int __devinit snd_mpu401_acpi_pnp(int dev, struct acpi_device *device)
{
struct mpu401_resources res;
acpi_status status;
res.port = SNDRV_AUTO_PORT;
res.irq = SNDRV_AUTO_IRQ;
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
snd_mpu401_acpi_resource, &res);
if (ACPI_FAILURE(status))
return -ENODEV;
if (res.port == SNDRV_AUTO_PORT || res.irq == SNDRV_AUTO_IRQ) {
snd_printk(KERN_ERR "no port or irq in %s _CRS\n",
acpi_device_bid(device));
return -ENODEV;
}
port[dev] = res.port;
irq[dev] = res.irq;
return 0;
}
#endif /* USE_ACPI_PNP */
static int __devinit snd_card_mpu401_probe(int dev, struct acpi_device *device)
{
snd_card_t *card;
int err;
if (port[dev] == SNDRV_AUTO_PORT) {
snd_printk("specify port\n");
return -EINVAL;
}
if (irq[dev] == SNDRV_AUTO_IRQ) {
snd_printk("specify or disable IRQ port\n");
return -EINVAL;
#ifdef USE_ACPI_PNP
if (!device) {
#endif
if (port[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR "specify port\n");
return -EINVAL;
}
if (irq[dev] == SNDRV_AUTO_IRQ) {
snd_printk(KERN_ERR "specify or disable IRQ port\n");
return -EINVAL;
}
#ifdef USE_ACPI_PNP
}
#endif
#ifdef USE_ACPI_PNP
if (device && (err = snd_mpu401_acpi_pnp(dev, device)) < 0)
return err;
#endif
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
strcpy(card->driver, "MPU-401 UART");
strcpy(card->shortname, card->driver);
sprintf(card->longname, "%s at 0x%lx, ", card->shortname, port[dev]);
if (irq[dev] >= 0) {
sprintf(card->longname + strlen(card->longname), "IRQ %d", irq[dev]);
} else {
strcat(card->longname, "polled");
}
#ifdef USE_ACPI_PNP
if (device) {
strcat(card->longname, ", bus id ");
strlcat(card->longname, acpi_device_bid(device), sizeof(card->longname));
}
#endif
if (snd_mpu401_uart_new(card, 0,
#ifdef CONFIG_X86_PC9800
pc98ii[dev] ? MPU401_HW_PC98II :
......@@ -95,22 +194,67 @@ static int __init snd_card_mpu401_probe(int dev)
snd_card_free(card);
return -ENODEV;
}
strcpy(card->driver, "MPU-401 UART");
strcpy(card->shortname, card->driver);
sprintf(card->longname, "%s at 0x%lx, ", card->shortname, port[dev]);
if (irq[dev] >= 0) {
sprintf(card->longname + strlen(card->longname), "IRQ %d", irq[dev]);
} else {
strcat(card->longname, "polled");
}
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
return err;
}
snd_mpu401_cards[dev] = card;
#ifdef USE_ACPI_PNP
if (device)
acpi_driver_data(device) = card;
else
#endif
snd_mpu401_legacy_cards[dev] = card;
return 0;
}
#ifdef USE_ACPI_PNP
static int __devinit snd_mpu401_acpi_add(struct acpi_device *device)
{
static int dev;
int err;
for ( ; dev < SNDRV_CARDS; ++dev) {
if (!enable[dev] || !acpipnp[dev])
continue;
err = snd_card_mpu401_probe(dev, device);
if (err < 0)
return err;
++dev;
return 0;
}
return -ENODEV;
}
static int __devexit snd_mpu401_acpi_remove(struct acpi_device *device,
int type)
{
snd_card_t *card;
if (!device)
return -EINVAL;
card = (snd_card_t *)acpi_driver_data(device);
if (!card)
return -EINVAL;
snd_card_disconnect(card);
snd_card_free_in_thread(card);
acpi_driver_data(device) = NULL;
return 0;
}
static struct acpi_driver snd_mpu401_acpi_driver = {
.name = "MPU-401 Driver",
.class = "mpu401",
.ids = "PNPB006",
.ops = {
.add = snd_mpu401_acpi_add,
.remove = __devexit_p(snd_mpu401_acpi_remove),
},
};
#endif /* USE_ACPI_PNP */
static int __init alsa_card_mpu401_init(void)
{
int dev, cards = 0;
......@@ -118,12 +262,24 @@ static int __init alsa_card_mpu401_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
continue;
if (snd_card_mpu401_probe(dev) >= 0)
#ifdef USE_ACPI_PNP
if (acpipnp[dev] && !acpi_disabled)
continue;
#endif
if (snd_card_mpu401_probe(dev, NULL) >= 0)
cards++;
}
#ifdef USE_ACPI_PNP
if (!acpi_disabled)
cards += acpi_bus_register_driver(&snd_mpu401_acpi_driver);
#endif
if (!cards) {
#ifdef MODULE
printk(KERN_ERR "MPU-401 device not found or device busy\n");
#endif
#ifdef USE_ACPI_PNP
if (!acpi_disabled)
acpi_bus_unregister_driver(&snd_mpu401_acpi_driver);
#endif
return -ENODEV;
}
......@@ -134,8 +290,12 @@ static void __exit alsa_card_mpu401_exit(void)
{
int idx;
#ifdef USE_ACPI_PNP
if (!acpi_disabled)
acpi_bus_unregister_driver(&snd_mpu401_acpi_driver);
#endif
for (idx = 0; idx < SNDRV_CARDS; idx++)
snd_card_free(snd_mpu401_cards[idx]);
snd_card_free(snd_mpu401_legacy_cards[idx]);
}
module_init(alsa_card_mpu401_init)
......@@ -143,22 +303,28 @@ module_exit(alsa_card_mpu401_exit)
#ifndef MODULE
/* format is: snd-mpu401=enable,index,id,port,irq */
/* format is: snd-mpu401=enable,index,id,acpipnp[,pc98ii],port,irq */
static int __init alsa_card_mpu401_setup(char *str)
{
static unsigned __initdata nr_dev = 0;
int __attribute__ ((__unused__)) pnp = INT_MAX;
if (nr_dev >= SNDRV_CARDS)
return 0;
(void)(get_option(&str,&enable[nr_dev]) == 2 &&
get_option(&str,&index[nr_dev]) == 2 &&
get_id(&str,&id[nr_dev]) == 2 &&
get_option(&str,&pnp) == 2 &&
#ifdef CONFIG_X86_PC9800
get_option(&str,&pc98ii[nr_dev]) == 2 &&
#endif
get_option_long(&str,&port[nr_dev]) == 2 &&
get_option(&str,&irq[nr_dev]) == 2);
#ifdef USE_ACPI_PNP
if (pnp != INT_MAX)
acpipnp[nr_dev] = pnp;
#endif
nr_dev++;
return 1;
}
......
......@@ -171,6 +171,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x83847650, 0xffffffff, "STAC9750/51", NULL, NULL }, // patch?
{ 0x83847652, 0xffffffff, "STAC9752/53", NULL, NULL }, // patch?
{ 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756, NULL },
{ 0x83847658, 0xffffffff, "STAC9758/59", patch_sigmatel_stac9758, NULL },
{ 0x83847666, 0xffffffff, "STAC9766/67", NULL, NULL }, // patch?
{ 0, 0, NULL, NULL, NULL }
};
......
......@@ -447,6 +447,21 @@ int patch_sigmatel_stac9756(ac97_t * ac97)
return 0;
}
int patch_sigmatel_stac9758(ac97_t * ac97)
{
// patch for SigmaTel
ac97->build_ops = &patch_sigmatel_stac9700_ops;
// turn on stereo speaker, headphone and line-out
snd_ac97_write_cache(ac97, AC97_SIGMATEL_OUTSEL, 0x9040);
// headphone select and boost
snd_ac97_write_cache(ac97, AC97_SIGMATEL_IOMISC, 0x2102);
// enable mic
snd_ac97_write_cache(ac97, AC97_SIGMATEL_INSEL, 0x0203);
// enable stereo mic
snd_ac97_write_cache(ac97, AC97_SIGMATEL_VARIOUS, 0x0001);
return 0;
}
/*
* Cirrus Logic CS42xx codecs
*/
......
......@@ -34,6 +34,7 @@ int patch_sigmatel_stac9708(ac97_t * ac97);
int patch_sigmatel_stac9721(ac97_t * ac97);
int patch_sigmatel_stac9744(ac97_t * ac97);
int patch_sigmatel_stac9756(ac97_t * ac97);
int patch_sigmatel_stac9758(ac97_t * ac97);
int patch_cirrus_cs4299(ac97_t * ac97);
int patch_cirrus_spdif(ac97_t * ac97);
int patch_conexant(ac97_t * ac97);
......
......@@ -71,6 +71,8 @@ MODULE_DEVICE_TABLE(pci, snd_vortex_ids);
static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
{
struct pci_dev *via = NULL;
int rc;
/* autodetect if workarounds are required */
while ((via = pci_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_8365_1, via))) {
......@@ -86,8 +88,6 @@ static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
if (fix == 255)
return;
int rc;
/* fix vortex latency */
if (fix & 0x01) {
if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) {
......
......@@ -562,7 +562,7 @@ static void vortex_A3dSourceHw_Initialize(vortex_t * v, int source, int slice)
a3dsrc_SetA3DSampleRate(a3dsrc, 0x11);
}
int Vort3DRend_Initialize(vortex_t * v, unsigned short mode)
static int Vort3DRend_Initialize(vortex_t * v, unsigned short mode)
{
v->xt_mode = mode; /* this_14 */
......
......@@ -82,8 +82,8 @@
/* MIXER (CAsp4Mix.s and CAsp4Mixer.s) */
// FIXME: get rid of this.
int mchannels[NR_MIXIN];
int rampchs[NR_MIXIN];
static int mchannels[NR_MIXIN];
static int rampchs[NR_MIXIN];
static void vortex_mixer_en_sr(vortex_t * vortex, int channel)
{
......
......@@ -37,6 +37,8 @@
#include "au88x0.h"
#include <linux/gameport.h>
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define VORTEX_GAME_DWAIT 20 /* 20 ms */
static struct gameport gameport;
......@@ -119,3 +121,10 @@ static int vortex_gameport_unregister(vortex_t * vortex)
gameport_unregister_port(vortex->gameport);
return 0;
}
#else
static inline int vortex_gameport_register(vortex_t * vortex) { return 0; }
static inline int vortex_gameport_unregister(vortex_t * vortex) { return 0; }
#endif
......@@ -55,6 +55,8 @@ MODULE_DEVICES("{{Intel,82801AA-ICH},"
"{Intel,82801CA-ICH3},"
"{Intel,82801DB-ICH4},"
"{Intel,ICH5},"
"{Intel,ICH6},"
"{Intel,6300ESB},"
"{Intel,MX440},"
"{SiS,SI7012},"
"{NVidia,nForce Audio},"
......@@ -131,6 +133,12 @@ MODULE_PARM_SYNTAX(mpu_port, SNDRV_ENABLED ",allows:{{0},{0x330},{0x300}},dialog
#ifndef PCI_DEVICE_ID_INTEL_ICH5
#define PCI_DEVICE_ID_INTEL_ICH5 0x24d5
#endif
#ifndef PCI_DEVICE_ID_INTEL_ESB_5
#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6
#endif
#ifndef PCI_DEVICE_ID_INTEL_ICH6_3
#define PCI_DEVICE_ID_INTEL_ICH6_3 0x266e
#endif
#ifndef PCI_DEVICE_ID_SI_7012
#define PCI_DEVICE_ID_SI_7012 0x7012
#endif
......@@ -198,6 +206,11 @@ DEFINE_REGSET(SP, 0x60); /* SPDIF out */
/* global block */
#define ICH_REG_GLOB_CNT 0x2c /* dword - global control */
#define ICH_PCM_SPDIF_MASK 0xc0000000 /* s/pdif pcm slot mask (ICH4) */
#define ICH_PCM_SPDIF_NONE 0x00000000 /* reserved - undefined */
#define ICH_PCM_SPDIF_78 0x40000000 /* s/pdif pcm on slots 7&8 */
#define ICH_PCM_SPDIF_69 0x80000000 /* s/pdif pcm on slots 6&9 */
#define ICH_PCM_SPDIF_1011 0xc0000000 /* s/pdif pcm on slots 10&11 */
#define ICH_PCM_20BIT 0x00400000 /* 20-bit samples (ICH4) */
#define ICH_PCM_246_MASK 0x00300000 /* 6 channels (not all chips) */
#define ICH_PCM_6 0x00200000 /* 6 channels (not all chips) */
......@@ -442,6 +455,8 @@ static struct pci_device_id snd_intel8x0_ids[] = {
{ 0x8086, 0x2485, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */
{ 0x8086, 0x24c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH4 */
{ 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH5 */
{ 0x8086, 0x25a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB */
{ 0x8086, 0x266e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH6 */
{ 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 */
{ 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */
......@@ -2590,6 +2605,8 @@ static struct shortname_table {
{ PCI_DEVICE_ID_INTEL_ICH3, "Intel 82801CA-ICH3" },
{ PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
{ PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" },
{ PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" },
{ PCI_DEVICE_ID_INTEL_ICH6_3, "Intel ICH6" },
{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" },
{ PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
......
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