Commit 5e2ece84 authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA CVS update - Takashi Iwai <tiwai@suse.de>

Documentation,SB drivers,YMFPCI driver,ALS4000 driver,AZT3328 driver
CMIPCI driver,ENS1370/1+ driver,ES1968 driver,Intel8x0 driver
VIA82xx driver
- removed joystick control from the card control API.
  added joystick (or joystick_port) module option instead.
- updated documents for this joystick fix.
- moved resource management for ALS4000 from sb-common header
  to the als4000 local code.
parent f1546fea
......@@ -173,8 +173,7 @@ Module parameters
Module for soundcards based on Avance Logic ALS4000 PCI chip.
joystick_port - port # for legacy joystick support.
default: 0x200 for the 1st card.
0 = disabled
0 = disabled (default)
Module supports up to 8 cards, autoprobe and PnP.
......@@ -225,6 +224,7 @@ Module parameters
fm_port - 0x388 (default), -1 (disable)
soft_ac3 - Sofware-conversion of raw SPDIF packets (model 033 only)
(default = 1)
joystick - Enable joystick (default off)
Module supports autoprobe and multiple chips (max 8).
......@@ -377,6 +377,8 @@ Module parameters
* SoundBlaster PCI 64
* SoundBlaster PCI 128
joystick - Enable joystick (default off)
Module supports up to 8 cards and autoprobe.
Module snd-ens1371
......@@ -387,6 +389,9 @@ Module parameters
* SoundBlaster PCI 128
* SoundBlaster Vibra PCI
joystick_port - port # for joystick (0x200,0x208,0x210,0x218),
0 = disable (default)
Module supports up to 8 cards and autoprobe.
Module snd-es968
......@@ -451,6 +456,7 @@ Module parameters
use_pm - support the power-management (0 = off, 1 = on,
2 = auto (default))
enable_mpu - enable MPU401 (0 = off, 1 = on, 2 = auto (default))
joystick - enable joystick (default off)
Module supports up to 8 cards and autoprobe.
......@@ -581,7 +587,7 @@ Module parameters
* ALi m5455
ac97_clock - AC'97 codec clock base (0 = auto-detect)
joystick_port - Joystick port # (0 = disabled, 0x200)
joystick - Enable joystick (default off)
mpu_port - MPU401 port # (0 = disabled, 0x330,0x300)
Module supports autoprobe and multiple bus-master chips (max 8).
......@@ -991,6 +997,7 @@ Module parameters
mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
[VIA686A/686B only]
joystick - Enable joystick (default off) [VIA686A/686B only]
ac97_clock - AC'97 codec clock base (default 48000Hz)
dxs_support - support DXS channels,
0 = auto (defalut), 1 = enable, 2 = disable,
......@@ -1117,11 +1124,15 @@ Module parameters
Module for Yamaha PCI chips (YMF72x, YMF74x & YMF75x).
mpu_port - 0x300,0x330,0x332,0x334, -1 (disable) by default
fm_port - 0x388,0x398,0x3a0,0x3a8, -1 (disable) by default
rear_switch - enable shared rear/line-in switch (bool)
mpu_port - 0x300,0x330,0x332,0x334, -1 (disable) by default
fm_port - 0x388,0x398,0x3a0,0x3a8, -1 (disable) by default
joystick_port - 0x201,0x202,0x204,0x205, -1 (disable) by default
rear_switch - enable shared rear/line-in switch (bool)
Module supports autoprobe and multiple chips (max 8).
With YMF744/754 chips, the MPU401/FM/joystick port addresses are
chosen automatically, and enabled by default.
The power-management is supported.
......
Analog Joystick Support on ALSA Drivers
=======================================
Oct. 14, 2003
Takashi Iwai <tiwai@suse.de>
General
-------
First of all, you need to enable GAMEPORT support on Linux kernel for
using a joystick with the ALSA driver. For the details of gameport
support, refer to Documentation/input/joystick.txt.
The joystick support of ALSA drivers is different between ISA and PCI
cards. In the case of ISA (PnP) cards, it's usually handled by the
independent module (ns558). Meanwhile, the ALSA PCI drivers have the
built-in gameport support. Hence, when the ALSA PCI driver is built
in the kernel, CONFIG_GAMEPORT must be 'y', too. Otherwise, the
gameport support on that card will be (silently) disabled.
Some adapter modules probe the physical connection of the device at
the load time. It'd be safer to plug in the joystick device before
loading the module.
PCI Cards
---------
For PCI cards, the joystick is enabled when the appropriate module
option is specified. Some drivers don't need options, and the
joystick support is always enabled. In the former ALSA version, there
was a dynamic control API for the joystick activation. It was
changed, however, to the static module options because of the system
stability and the resource management.
The following PCI drivers support the joystick natively.
Driver Module Option Available Values
---------------------------------------------------------------------------
als4000 joystick_port any address (e.g. 0x200), 0 = disable (default)
au88x0 N/A N/A
azf3328 joystick 0 = disable, 1 = enable, -1 = auto (default)
ens1370 joystick 0 = disable (default), 1 = enable
ens1371 joystick_port 0 = disable (default), 0x200,0x208,0x210,0x218
cmipci joystick 0 = disable (default), 1 = enable
cs4281 N/A N/A
cs46xx N/A N/A
es1938 N/A N/A
es1968 joystick 0 = disable (default), 1 = enable
intel8x0(*1)joystick 0 = disable (default), 1 = enable
sonicvibes N/A N/A
trident N/A N/A
via82xx(*2) joystick 0 = disable (default), 1 = enable
ymfpci(*3) joystick_port 0 = disable (default), 0x201,0x202,0x204,0x205
---------------------------------------------------------------------------
*1) not all chips support joystick
*2) VIA686A/B only
*3) With YMF744/754 chips, the port address is chosen automatically
and enabled by default
The following drivers don't support gameport natively, but there are
additional modules. Load the corresponding module to add the gameport
support.
Driver Additional Module
-----------------------------
emu10k1 emu10k1-gp
fm801 fm801-gp
-----------------------------
Note: the "pcigame" and "cs461x" modules are for the OSS drivers only.
These ALSA drivers (cs46xx, trident and au88x0) have the
built-in gameport support.
As mentioned above, ALSA PCI drivers have the built-in gameport
support, so you don't have to load ns558 module. Just load "joydev"
and the appropriate adapter module (e.g. "analog").
ISA Cards
---------
ALSA ISA drivers don't have the built-in gameport support.
Instead, you need to load "ns558" module in addition to "joydev" and
the adapter module (e.g. "analog").
......@@ -63,8 +63,6 @@ enum sb_hw_type {
struct _snd_sb {
unsigned long port; /* base port of DSP chip */
struct resource *res_port;
unsigned long alt_port; /* alternate port (ALS4000) */
struct resource *res_alt_port;
unsigned long mpu_port; /* MPU port for SB DSP 4.0+ */
int irq; /* IRQ number of DSP chip */
int dma8; /* 8-bit DMA */
......@@ -72,6 +70,7 @@ struct _snd_sb {
unsigned short version; /* version of DSP chip */
enum sb_hw_type hardware; /* see to SB_HW_XXXX */
unsigned long alt_port; /* alternate port (ALS4000) */
struct pci_dev *pci; /* ALS4000 */
unsigned int open; /* see to SB_OPEN_XXXX for sb8 */
......
......@@ -311,8 +311,6 @@ struct _snd_ymfpci {
unsigned short old_legacy_ctrl;
#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
unsigned int joystick_port;
struct semaphore joystick_mutex;
struct resource *joystick_res;
struct gameport gameport;
#endif
......@@ -389,9 +387,6 @@ int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch);
#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
int snd_ymfpci_joystick(ymfpci_t *chip);
#endif
int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice);
int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice);
......@@ -401,4 +396,8 @@ void snd_ymfpci_suspend(ymfpci_t *chip);
void snd_ymfpci_resume(ymfpci_t *chip);
#endif
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK
#endif
#endif /* __SOUND_YMFPCI_H */
......@@ -185,10 +185,6 @@ static int snd_sbdsp_free(sb_t *chip)
release_resource(chip->res_port);
kfree_nocheck(chip->res_port);
}
if (chip->res_alt_port) {
release_resource(chip->res_alt_port);
kfree_nocheck(chip->res_alt_port);
}
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
#ifdef CONFIG_ISA
......
......@@ -63,6 +63,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/rawmidi.h>
......@@ -78,14 +79,15 @@ MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{Avance Logic,ALS4000}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1
#endif
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_PNP; /* Enable this card */
static int joystick_port[SNDRV_CARDS] =
#ifdef CONFIG_ISA
{0x200}; /* enable as default */
#else
{0}; /* disabled */
#ifdef SUPPORT_JOYSTICK
static int joystick_port[SNDRV_CARDS];
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
......@@ -105,6 +107,11 @@ MODULE_PARM_SYNTAX(joystick_port, SNDRV_ENABLED);
typedef struct {
unsigned long gcr;
struct resource *res_gcr;
#ifdef SUPPORT_JOYSTICK
struct gameport gameport;
struct resource *res_joystick;
#endif
} snd_card_als4000_t;
static struct pci_device_id snd_als4000_ids[] = {
......@@ -523,7 +530,7 @@ static int __devinit snd_als4000_pcm(sb_t *chip, int device)
/******************************************************************/
static void __devinit snd_als4000_set_addr(unsigned long gcr,
static void snd_als4000_set_addr(unsigned long gcr,
unsigned int sb,
unsigned int mpu,
unsigned int opl,
......@@ -574,6 +581,18 @@ static void snd_card_als4000_free( snd_card_t *card )
snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data;
/* make sure that interrupts are disabled */
snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);
/* free resources */
#ifdef SUPPORT_JOYSTICK
if (acard->res_joystick) {
if (acard->gameport.io)
gameport_unregister_port(&acard->gameport);
snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
release_resource(acard->res_joystick);
kfree_nocheck(acard->res_joystick);
}
#endif
release_resource(acard->res_gcr);
kfree_nocheck(acard->res_gcr);
}
static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
......@@ -588,6 +607,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
opl3_t *opl3;
unsigned short word;
int err;
int joystick = 0;
if (dev >= SNDRV_CARDS)
return -ENODEV;
......@@ -617,9 +637,6 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
pci_set_master(pci);
/* disable all legacy ISA stuff except for joystick */
snd_als4000_set_addr(gcr, 0, 0, 0, joystick_port[dev]);
card = snd_card_new(index[dev], id[dev], THIS_MODULE,
sizeof( snd_card_als4000_t ) );
if (card == NULL) {
......@@ -630,8 +647,17 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
acard = (snd_card_als4000_t *)card->private_data;
acard->gcr = gcr;
acard->res_gcr = res_gcr_port;
card->private_free = snd_card_als4000_free;
/* disable all legacy ISA stuff except for joystick */
#ifdef SUPPORT_JOYSTICK
if (joystick_port[dev] > 0 &&
(acard->res_joystick = request_region(joystick_port[dev], 8, "ALS4000 gameport")) != NULL)
joystick = joystick_port[dev];
#endif
snd_als4000_set_addr(gcr, 0, 0, 0, joystick);
if ((err = snd_sbdsp_create(card,
gcr + 0x10,
pci->irq,
......@@ -640,15 +666,12 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
-1,
SB_HW_ALS4000,
&chip)) < 0) {
release_resource(res_gcr_port);
kfree_nocheck(res_gcr_port);
snd_card_free(card);
return err;
}
chip->pci = pci;
chip->alt_port = gcr;
chip->res_alt_port = res_gcr_port;
snd_als4000_configure(chip);
......@@ -680,6 +703,12 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
}
}
#ifdef SUPPORT_JOYSTICK
if (acard->res_joystick) {
acard->gameport.io = joystick;
gameport_register_port(&acard->gameport);
}
#endif
strcpy(card->driver, "ALS4000");
strcpy(card->shortname, "Avance Logic ALS4000");
sprintf(card->longname, "%s at 0x%lx, irq %i",
......@@ -730,7 +759,7 @@ module_exit(alsa_card_als4000_exit)
#ifndef MODULE
/* format is: snd-als4000=enable,index,id */
/* format is: snd-als4000=enable,index,id,joystick_port */
static int __init alsa_card_als4000_setup(char *str)
{
......@@ -740,7 +769,11 @@ static int __init alsa_card_als4000_setup(char *str)
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_id(&str,&id[nr_dev]) == 2
#ifdef SUPPORT_JOYSTICK
&& get_option(&str,&joystick_port[nr_dev]) == 2
#endif
);
nr_dev++;
return 1;
}
......
......@@ -97,6 +97,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
......@@ -113,6 +114,10 @@ MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{Aztech,AZF3328}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1
#endif
#define DEBUG_MISC 0
#define DEBUG_CALLS 0
#define DEBUG_MIXER 0
......@@ -158,8 +163,10 @@ MODULE_DEVICES("{{Aztech,AZF3328}}");
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_PNP; /* Enable this card */
#ifdef SUPPORT_JOYSTICK
static int joystick[SNDRV_CARDS] =
{-1}; /* "unset" as default */
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
......@@ -170,9 +177,11 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
MODULE_PARM_SYNTAX(enable, SNDRV_INDEX_DESC);
#ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick, "Forced joystick port enable for AZF3328 soundcard. (0 = force disable)");
MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED);
#endif
typedef struct _snd_azf3328 azf3328_t;
#define chip_t azf3328_t
......@@ -190,7 +199,11 @@ struct _snd_azf3328 {
struct resource *res_synth_port;
unsigned long mixer_port;
struct resource *res_mixer_port;
unsigned long game_port;
#ifdef SUPPORT_JOYSTICK
struct gameport gameport;
struct resource *res_joystick;
#endif
struct pci_dev *pci;
snd_card_t *card;
......@@ -1259,6 +1272,16 @@ static int snd_azf3328_free(azf3328_t *chip)
synchronize_irq(chip->irq);
__end_hw:
#ifdef SUPPORT_JOYSTICK
if (chip->res_joystick) {
gameport_unregister_port(&chip->gameport);
/* disable gameport */
snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
release_resource(chip->res_joystick);
kfree_nocheck(chip->res_joystick);
}
#endif
if (chip->res_codec_port) {
release_resource(chip->res_codec_port);
kfree_nocheck(chip->res_codec_port);
......@@ -1419,53 +1442,53 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
return 0;
}
#ifdef SUPPORT_JOYSTICK
static void __devinit snd_azf3328_config_joystick(azf3328_t *chip, int joystick)
{
int i, detected = 0, activate = 0;
int i, activate = 0;
char *msg = NULL;
unsigned char val;
if (joystick == -1) /* auto detection/activation */
{
activate = 1;
for (i=0x200; i <= 0x207; i++)
if (inb(i) != 0xff)
detected = 1; /* other joy found, don't activate */
if (inb(i) != 0xff) {
activate = 0;
break;
}
}
if ((joystick == -1) && (detected == 1))
{
activate = 0;
msg = "DISABLED (address occupied by another joystick port)";
}
else
if ((joystick == -1) && (detected == 0))
{
activate = 1;
msg = "ENABLED (via autodetect)";
if (activate || joystick == 1) {
if ((chip->res_joystick = request_region(0x200, 8, "AZF3328 gameport")) != NULL) {
chip->gameport.io = 0x200;
activate = 1;
} else
activate = 0;
}
else
if (joystick == 0)
{
activate = 0;
msg = "DISABLED (forced)";
}
else
if (joystick == 1)
{
activate = 1;
else if (joystick == 1 && activate)
msg = "ENABLED (Warning: forced!)";
}
else if (activate)
msg = "ENABLED (via autodetect)";
else
msg = "DISABLED (address occupied by another joystick port)";
val = inb(chip->io2_port + IDX_IO2_LEGACY_ADDR);
if (activate)
val |= LEGACY_JOY;
val |= LEGACY_JOY;
else
val &= ~LEGACY_JOY;
val &= ~LEGACY_JOY;
outb(val, chip->io2_port + IDX_IO2_LEGACY_ADDR);
#ifdef MODULE
printk("azt3328: Joystick port: %s.\n", msg);
#endif
if (activate)
gameport_register_port(&chip->gameport);
}
#endif
static int __devinit snd_azf3328_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
......@@ -1537,7 +1560,9 @@ static int __devinit snd_azf3328_probe(struct pci_dev *pci,
"azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");
#endif
#ifdef SUPPORT_JOYSTICK
snd_azf3328_config_joystick(chip, joystick[dev]);
#endif
pci_set_drvdata(pci, chip);
dev++;
......@@ -1598,7 +1623,7 @@ module_exit(alsa_card_azf3328_exit)
#ifndef MODULE
/* format is: snd-azf3328=enable,index,id */
/* format is: snd-azf3328=enable,index,id,joystick */
static int __init alsa_card_azf3328_setup(char *str)
{
......@@ -1610,12 +1635,16 @@ static int __init alsa_card_azf3328_setup(char *str)
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_id(&str,&id[nr_dev]) == 2
#ifdef SUPPORT_JOYSTICK
&& get_option(&str,&joystick[nr_dev]) == 2
#endif
);
nr_dev++;
snd_azf3328_dbgcallleave();
return 1;
}
__setup("snd-azf3328=", alsa_card_azf3328_setup);
__setup("snd-azt3328=", alsa_card_azf3328_setup);
#endif /* ifndef MODULE */
......@@ -31,6 +31,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
......@@ -52,6 +53,10 @@ MODULE_DEVICES("{{C-Media,CMI8738},"
"{C-Media,CMI8338A},"
"{C-Media,CMI8338B}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1
#endif
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_PNP; /* Enable switches */
......@@ -60,6 +65,9 @@ static long fm_port[SNDRV_CARDS] = {0x388, [1 ... (SNDRV_CARDS-1)]=-1};
#ifdef DO_SOFT_AC3
static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
#endif
#ifdef SUPPORT_JOYSTICK
static int joystick[SNDRV_CARDS];
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for C-Media PCI soundcard.");
......@@ -81,6 +89,11 @@ MODULE_PARM(soft_ac3, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only).");
MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
#endif
#ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick, "Enable joystick.");
MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
#endif
#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
......@@ -339,6 +352,10 @@ MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
#define CM_EXTENT_MIDI 0x2
#define CM_EXTENT_SYNTH 0x4
/* fixed legacy joystick address */
#define CM_JOYSTICK_ADDR 0x200
/*
* pci ids
*/
......@@ -480,6 +497,11 @@ struct snd_stru_cmipci {
/* external MIDI */
snd_rawmidi_t *rmidi;
#ifdef SUPPORT_JOYSTICK
struct gameport gameport;
struct resource *res_joystick;
#endif
spinlock_t reg_lock;
};
......@@ -2599,7 +2621,7 @@ DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0);
DEFINE_BIT_SWITCH_ARG(fourch, CM_REG_MISC_CTRL, CM_N4SPK3D, 0, 0);
DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0);
DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0);
DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0);
// DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0); /* now module option */
DEFINE_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0);
#define DEFINE_SWITCH(sname, stype, sarg) \
......@@ -2693,7 +2715,7 @@ static snd_kcontrol_new_t snd_cmipci_extra_mixer_switches[] __devinitdata = {
/* card control switches */
static snd_kcontrol_new_t snd_cmipci_control_switches[] __devinitdata = {
DEFINE_CARD_SWITCH("Joystick", joystick),
// DEFINE_CARD_SWITCH("Joystick", joystick), /* now module option */
DEFINE_CARD_SWITCH("Modem", modem),
};
......@@ -2905,6 +2927,14 @@ static int snd_cmipci_free(cmipci_t *cm)
free_irq(cm->irq, (void *)cm);
}
#ifdef SUPPORT_JOYSTICK
if (cm->res_joystick) {
gameport_unregister_port(&cm->gameport);
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
release_resource(cm->res_joystick);
kfree_nocheck(cm->res_joystick);
}
#endif
if (cm->res_iobase) {
release_resource(cm->res_iobase);
kfree_nocheck(cm->res_iobase);
......@@ -3110,6 +3140,15 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K|CM_SPDF_AC97);
#endif /* USE_VAR48KRATE */
#ifdef SUPPORT_JOYSTICK
if (joystick[dev] &&
(cm->res_joystick = request_region(CM_JOYSTICK_ADDR, 8, "CMIPCI gameport")) != NULL) {
cm->gameport.io = CM_JOYSTICK_ADDR;
snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
gameport_register_port(&cm->gameport);
} else
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
#endif
*rcmipci = cm;
return 0;
......@@ -3218,7 +3257,7 @@ module_exit(alsa_card_cmipci_exit)
#ifndef MODULE
/* format is: snd-cmipci=enable,index,id,
mpu_port,fm_port */
mpu_port,fm_port,soft_ac3,joystick */
static int __init alsa_card_cmipci_setup(char *str)
{
......@@ -3230,7 +3269,14 @@ static int __init alsa_card_cmipci_setup(char *str)
get_option(&str,&index[nr_dev]) == 2 &&
get_id(&str,&id[nr_dev]) == 2 &&
get_option_long(&str,&mpu_port[nr_dev]) == 2 &&
get_option_long(&str,&fm_port[nr_dev]) == 2);
get_option_long(&str,&fm_port[nr_dev]) == 2
#ifdef DO_SOFT_AC3
&& get_option(&str,&soft_ac3[nr_dev]) == 2
#endif
#ifdef SUPPORT_JOYSTICK
&& get_option(&str,&joystick[nr_dev]) == 2
#endif
);
nr_dev++;
return 1;
}
......
This diff is collapsed.
......@@ -101,6 +101,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/mpu401.h>
......@@ -121,6 +122,10 @@ MODULE_DEVICES("{{ESS,Maestro 2e},"
"{ESS,Maestro 1},"
"{TerraTec,DMX}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1
#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
......@@ -130,6 +135,9 @@ static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
static int clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
#ifdef SUPPORT_JOYSTICK
static int joystick[SNDRV_CARDS];
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
......@@ -158,6 +166,11 @@ MODULE_PARM_SYNTAX(use_pm, SNDRV_ENABLED ",allows:{{0,1,2}},skill:advanced");
MODULE_PARM(enable_mpu, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)");
MODULE_PARM_SYNTAX(enable_mpu, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
#ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick, "Enable joystick.");
MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
#endif
/* PCI Dev ID's */
......@@ -601,6 +614,11 @@ struct snd_es1968 {
#ifdef CONFIG_PM
u16 apu_map[NR_APUS][NR_APU_REGS];
#endif
#ifdef SUPPORT_JOYSTICK
struct gameport gameport;
struct resource *res_joystick;
#endif
};
static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs);
......@@ -2477,6 +2495,13 @@ static int snd_es1968_free(es1968_t *chip)
if (chip->res_io_port)
snd_es1968_reset(chip);
#ifdef SUPPORT_JOYSTICK
if (chip->res_joystick) {
gameport_unregister_port(&chip->gameport);
release_resource(chip->res_joystick);
kfree_nocheck(chip->res_joystick);
}
#endif
snd_es1968_set_acpi(chip, ACPI_D3);
chip->master_switch = NULL;
chip->master_volume = NULL;
......@@ -2622,57 +2647,6 @@ static int __devinit snd_es1968_create(snd_card_t * card,
}
/*
* joystick
*/
static int snd_es1968_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int snd_es1968_joystick_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
es1968_t *chip = snd_kcontrol_chip(kcontrol);
u16 val;
pci_read_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, &val);
ucontrol->value.integer.value[0] = (val & 0x04) ? 1 : 0;
return 0;
}
static int snd_es1968_joystick_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
es1968_t *chip = snd_kcontrol_chip(kcontrol);
u16 val, oval;
pci_read_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, &oval);
val = oval & ~0x04;
if (ucontrol->value.integer.value[0])
val |= 0x04;
if (val != oval) {
pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val);
return 1;
}
return 0;
}
#define num_controls(ary) (sizeof(ary) / sizeof(snd_kcontrol_new_t))
static snd_kcontrol_new_t snd_es1968_control_switches[] __devinitdata = {
{
.name = "Joystick",
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
.info = snd_es1968_joystick_info,
.get = snd_es1968_joystick_get,
.put = snd_es1968_joystick_put,
}
};
/*
*/
static int __devinit snd_es1968_probe(struct pci_dev *pci,
......@@ -2755,14 +2729,17 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
}
}
/* card switches */
for (i = 0; i < num_controls(snd_es1968_control_switches); i++) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_es1968_control_switches[i], chip));
if (err < 0) {
snd_card_free(card);
return err;
}
#ifdef SUPPORT_JOYSTICK
#define JOYSTICK_ADDR 0x200
if (joystick[dev] &&
(chip->res_joystick = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport")) != NULL) {
u16 val;
pci_read_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, &val);
pci_write_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04);
chip->gameport.io = JOYSTICK_ADDR;
gameport_register_port(&chip->gameport);
}
#endif
snd_es1968_start_irq(chip);
......@@ -2833,7 +2810,8 @@ module_exit(alsa_card_es1968_exit)
pcm_substreams_c,
clock,
use_pm,
enable_mpu
enable_mpu,
joystick
*/
static int __init alsa_card_es1968_setup(char *str)
......@@ -2850,7 +2828,11 @@ static int __init alsa_card_es1968_setup(char *str)
get_option(&str,&pcm_substreams_c[nr_dev]) == 2 &&
get_option(&str,&clock[nr_dev]) == 2 &&
get_option(&str,&use_pm[nr_dev]) == 2 &&
get_option(&str,&enable_mpu[nr_dev]) == 2);
get_option(&str,&enable_mpu[nr_dev]) == 2
#ifdef SUPPORT_JOYSTICK
&& get_option(&str,&joystick[nr_dev]) == 2
#endif
);
nr_dev++;
return 1;
}
......
......@@ -33,6 +33,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/ac97_codec.h>
......@@ -59,7 +60,9 @@ MODULE_DEVICES("{{Intel,82801AA-ICH},"
"{AMD,AMD8111},"
"{ALI,M5455}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1
#endif
#define SUPPORT_MIDI 1
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
......@@ -67,12 +70,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
#ifdef SUPPORT_JOYSTICK
static int joystick_port[SNDRV_CARDS] =
#ifdef CONFIG_ISA
{0x200}; /* enable as default */
#else
{0}; /* disabled */
#endif
static int joystick[SNDRV_CARDS];
#endif
#ifdef SUPPORT_MIDI
static int mpu_port[SNDRV_CARDS]; /* disabled */
......@@ -91,9 +89,9 @@ MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:0");
#ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick_port, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick_port, "Joystick port address for Intel i8x0 soundcard. (0 = disabled)");
MODULE_PARM_SYNTAX(joystick_port, SNDRV_ENABLED ",allows:{{0},{0x200}},dialog:list");
MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick, "Enable joystick for Intel i8x0 soundcard.");
MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
#endif
#ifdef SUPPORT_MIDI
MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
......@@ -2656,9 +2654,16 @@ static struct pci_driver driver = {
* initialize joystick/midi addresses
*/
#ifdef SUPPORT_JOYSTICK
/* there is only one available device, so we keep it here */
static struct pci_dev *ich_gameport_pci;
static struct gameport ich_gameport = { .io = 0x200 };
#endif
static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
const struct pci_device_id *id)
{
u16 val;
static int dev;
if (dev >= SNDRV_CARDS)
return -ENODEV;
......@@ -2667,17 +2672,24 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
return -ENOENT;
}
if (joystick_port[dev] > 0 || mpu_port[dev] > 0) {
u16 val;
pci_read_config_word(pci, 0xe6, &val);
if (joystick_port[dev] > 0)
pci_read_config_word(pci, 0xe6, &val);
#ifdef SUPPORT_JOYSTICK
if (joystick[dev]) {
if (! request_region(ich_gameport.io, 8, "ICH gameport")) {
printk(KERN_WARNING "intel8x0: cannot grab gameport 0x%x\n", ich_gameport.io);
joystick[dev] = 0;
} else {
ich_gameport_pci = pci;
gameport_register_port(&ich_gameport);
val |= 0x100;
if (mpu_port[dev] == 0x300 || mpu_port[dev] == 0x330)
val |= 0x20;
pci_write_config_word(pci, 0xe6, val | 0x100);
}
}
#endif
#ifdef SUPPORT_MIDI
if (mpu_port[dev] > 0) {
if (mpu_port[dev] == 0x300 || mpu_port[dev] == 0x330) {
u8 b;
val |= 0x20;
pci_read_config_byte(pci, 0xe2, &b);
if (mpu_port[dev] == 0x300)
b |= 0x08;
......@@ -2686,9 +2698,27 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
pci_write_config_byte(pci, 0xe2, b);
}
}
#endif
pci_write_config_word(pci, 0xe6, val);
return 0;
}
static void __devexit snd_intel8x0_joystick_remove(struct pci_dev *pci)
{
u16 val;
#ifdef SUPPORT_JOYSTICK
if (ich_gameport_pci == pci) {
gameport_unregister_port(&ich_gameport);
release_region(ich_gameport.io, 8);
ich_gameport_pci = NULL;
}
#endif
/* disable joystick and MIDI */
pci_read_config_word(pci, 0xe6, &val);
val &= ~0x120;
pci_write_config_word(pci, 0xe6, val);
}
static struct pci_device_id snd_intel8x0_joystick_ids[] = {
{ 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82801AA */
{ 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82901AB */
......@@ -2707,6 +2737,7 @@ static struct pci_driver joystick_driver = {
.name = "Intel ICH Joystick",
.id_table = snd_intel8x0_joystick_ids,
.probe = snd_intel8x0_joystick_probe,
.remove = __devexit_p(snd_intel8x0_joystick_remove),
};
static int have_joystick;
......@@ -2749,7 +2780,7 @@ module_exit(alsa_card_intel8x0_exit)
#ifndef MODULE
/* format is: snd-intel8x0=enable,index,id,ac97_clock,mpu_port */
/* format is: snd-intel8x0=enable,index,id,ac97_clock,mpu_port,joystick */
static int __init alsa_card_intel8x0_setup(char *str)
{
......@@ -2763,6 +2794,9 @@ static int __init alsa_card_intel8x0_setup(char *str)
get_option(&str,&ac97_clock[nr_dev]) == 2
#ifdef SUPPORT_MIDI
&& get_option(&str,&mpu_port[nr_dev]) == 2
#endif
#ifdef SUPPORT_JOYSTICK
&& get_option(&str,&joystick[nr_dev]) == 2
#endif
);
nr_dev++;
......
......@@ -50,6 +50,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
......@@ -69,10 +70,17 @@ MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1
#endif
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_PNP; /* Enable this card */
static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
#ifdef SUPPORT_JOYSTICK
static int joystick[SNDRV_CARDS];
#endif
static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
static int dxs_support[SNDRV_CARDS];
......@@ -86,8 +94,13 @@ MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable audio part of VIA 82xx bridge.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
MODULE_PARM_SYNTAX(mpu_port, SNDRV_PORT_DESC);
#ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick, "Enable joystick. (VT82C686x only)");
MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLE_DESC "," SNDRV_BOOLEAN_FALSE_DESC);
#endif
MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:48000");
......@@ -461,6 +474,11 @@ struct _snd_via82xx {
spinlock_t reg_lock;
spinlock_t ac97_lock;
snd_info_entry_t *proc_entry;
#ifdef SUPPORT_JOYSTICK
struct gameport gameport;
struct resource *res_joystick;
#endif
};
static struct pci_device_id snd_via82xx_ids[] = {
......@@ -1558,53 +1576,6 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
return 0;
}
/*
* joystick
*/
static int snd_via82xx_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int snd_via82xx_joystick_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
u16 val;
pci_read_config_word(chip->pci, VIA_FUNC_ENABLE, &val);
ucontrol->value.integer.value[0] = (val & VIA_FUNC_ENABLE_GAME) ? 1 : 0;
return 0;
}
static int snd_via82xx_joystick_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
u16 val, oval;
pci_read_config_word(chip->pci, VIA_FUNC_ENABLE, &oval);
val = oval & ~VIA_FUNC_ENABLE_GAME;
if (ucontrol->value.integer.value[0])
val |= VIA_FUNC_ENABLE_GAME;
if (val != oval) {
pci_write_config_word(chip->pci, VIA_FUNC_ENABLE, val);
return 1;
}
return 0;
}
static snd_kcontrol_new_t snd_via82xx_joystick_control __devinitdata = {
.name = "Joystick",
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
.info = snd_via82xx_joystick_info,
.get = snd_via82xx_joystick_get,
.put = snd_via82xx_joystick_put,
};
/*
*
*/
......@@ -1689,6 +1660,16 @@ static int snd_via686_init_misc(via82xx_t *chip, int dev)
legacy &= ~VIA_FUNC_ENABLE_MIDI;
mpu_port[dev] = -1;
}
#ifdef SUPPORT_JOYSTICK
#define JOYSTICK_ADDR 0x200
if (joystick[dev] &&
(chip->res_joystick = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport")) != NULL) {
legacy |= VIA_FUNC_ENABLE_GAME;
chip->gameport.io = JOYSTICK_ADDR;
}
#endif
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
if (chip->mpu_res) {
......@@ -1702,9 +1683,13 @@ static int snd_via686_init_misc(via82xx_t *chip, int dev)
}
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
}
/* card switches */
return snd_ctl_add(chip->card, snd_ctl_new1(&snd_via82xx_joystick_control, chip));
#ifdef SUPPORT_JOYSTICK
if (chip->res_joystick)
gameport_register_port(&chip->gameport);
#endif
return 0;
}
......@@ -1866,6 +1851,13 @@ static int snd_via82xx_free(via82xx_t *chip)
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
if (chip->chip_type == TYPE_VIA686) {
#ifdef SUPPORT_JOYSTICK
if (chip->res_joystick) {
gameport_unregister_port(&chip->gameport);
release_resource(chip->res_joystick);
kfree_nocheck(chip->res_joystick);
}
#endif
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->old_legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg);
}
......@@ -2155,7 +2147,7 @@ module_exit(alsa_card_via82xx_exit)
#ifndef MODULE
/* format is: snd-via82xx=enable,index,id,
mpu_port,ac97_clock,dxs_support */
mpu_port,joystick,ac97_clock,dxs_support */
static int __init alsa_card_via82xx_setup(char *str)
{
......@@ -2167,6 +2159,9 @@ static int __init alsa_card_via82xx_setup(char *str)
get_option(&str,&index[nr_dev]) == 2 &&
get_id(&str,&id[nr_dev]) == 2 &&
get_option_long(&str,&mpu_port[nr_dev]) == 2 &&
#ifdef SUPPORT_JOYSTICK
get_option(&str,&joystick[nr_dev]) == 2 &&
#endif
get_option(&str,&ac97_clock[nr_dev]) == 2 &&
get_option(&str,&dxs_support[nr_dev]) == 2);
nr_dev++;
......
......@@ -44,8 +44,11 @@ MODULE_DEVICES("{{Yamaha,YMF724},"
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_PNP; /* Enable this card */
static long fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
static long fm_port[SNDRV_CARDS];
static long mpu_port[SNDRV_CARDS];
#ifdef SUPPORT_JOYSTICK
static long joystick_port[SNDRV_CARDS];
#endif
static int rear_switch[SNDRV_CARDS];
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
......@@ -63,6 +66,11 @@ MODULE_PARM_SYNTAX(mpu_port, SNDRV_ENABLED);
MODULE_PARM(fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(fm_port, "FM OPL-3 Port.");
MODULE_PARM_SYNTAX(fm_port, SNDRV_ENABLED);
#ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(joystick_port, "Joystick port address");
MODULE_PARM_SYNTAX(joystick_port, SNDRV_ENABLED);
#endif
MODULE_PARM(rear_switch, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
MODULE_PARM_SYNTAX(rear_switch, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
......@@ -86,6 +94,9 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
snd_card_t *card;
struct resource *fm_res = NULL;
struct resource *mpu_res = NULL;
#ifdef SUPPORT_JOYSTICK
struct resource *joystick_res = NULL;
#endif
ymfpci_t *chip;
opl3_t *opl3;
char *str;
......@@ -117,22 +128,32 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */
if (pci_id->device >= 0x0010) { /* YMF 744/754 */
if (fm_port[dev] < 0) {
if (fm_port[dev] <= 0) {
fm_port[dev] = pci_resource_start(pci, 1);
}
if (fm_port[dev] >= 0 &&
if (fm_port[dev] > 0 &&
(fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
legacy_ctrl |= YMFPCI_LEGACY_FMEN;
pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]);
}
if (mpu_port[dev] < 0) {
if (mpu_port[dev] <= 0) {
mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
}
if (mpu_port[dev] >= 0 &&
if (mpu_port[dev] > 0 &&
(mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
legacy_ctrl |= YMFPCI_LEGACY_MEN;
pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]);
}
#ifdef SUPPORT_JOYSTICK
if (joystick_port[dev] < 0) {
joystick_port[dev] = pci_resource_start(pci, 2);
}
if (joystick_port[dev] >= 0 &&
(joystick_res = request_region(joystick_port[dev], 1, "YMFPCI gameport")) != NULL) {
legacy_ctrl |= YMFPCI_LEGACY_JPEN;
pci_write_config_word(pci, PCIR_DSXG_JOYBASE, joystick_port[dev]);
}
#endif
} else {
switch (fm_port[dev]) {
case 0x388: legacy_ctrl2 |= 0; break;
......@@ -162,6 +183,22 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
mpu_port[dev] = -1;
}
#ifdef SUPPORT_JOYSTICK
switch (joystick_port[dev]) {
case 0x201: legacy_ctrl2 |= 0 << 6; break;
case 0x202: legacy_ctrl2 |= 1 << 6; break;
case 0x204: legacy_ctrl2 |= 2 << 6; break;
case 0x205: legacy_ctrl2 |= 3 << 6; break;
default: joystick_port[dev] = -1; break;
}
if (joystick_port[dev] > 0 &&
(joystick_res = request_region(joystick_port[dev], 1, "YMFPCI gameport")) != NULL) {
legacy_ctrl |= YMFPCI_LEGACY_JPEN;
} else {
legacy_ctrl2 &= ~YMFPCI_LEGACY2_JSIO;
joystick_port[dev] = -1;
}
#endif
}
if (mpu_res) {
legacy_ctrl |= YMFPCI_LEGACY_MIEN;
......@@ -182,10 +219,19 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
release_resource(fm_res);
kfree_nocheck(fm_res);
}
#ifdef SUPPORT_JOYSTICK
if (joystick_res) {
release_resource(joystick_res);
kfree_nocheck(joystick_res);
}
#endif
return err;
}
chip->fm_res = fm_res;
chip->mpu_res = mpu_res;
#ifdef SUPPORT_JOYSTICK
chip->joystick_res = joystick_res;
#endif
if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
snd_card_free(card);
return err;
......@@ -229,9 +275,10 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
return err;
}
}
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
if ((err = snd_ymfpci_joystick(chip)) < 0) {
printk(KERN_WARNING "ymfpci: cannot initialize joystick, skipping...\n");
#ifdef SUPPORT_JOYSTICK
if (chip->joystick_res) {
chip->gameport.io = joystick_port[dev];
gameport_register_port(&chip->gameport);
}
#endif
strcpy(card->driver, str);
......
......@@ -1702,177 +1702,6 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch)
}
/*
* joystick support
*/
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
static int ymfpci_joystick_ports[4] = {
0x201, 0x202, 0x204, 0x205
};
static int snd_ymfpci_get_joystick_port(ymfpci_t *chip, int index)
{
if (index < 4)
return ymfpci_joystick_ports[index];
else
return pci_resource_start(chip->pci, 2);
}
static void setup_joystick_base(ymfpci_t *chip)
{
if (chip->device_id >= 0x0010) /* YMF 744/754 */
pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE,
snd_ymfpci_get_joystick_port(chip, chip->joystick_port));
else {
u16 legacy_ctrl2;
pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, &legacy_ctrl2);
legacy_ctrl2 &= ~YMFPCI_LEGACY2_JSIO;
legacy_ctrl2 |= chip->joystick_port << 6;
pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
}
}
static int snd_ymfpci_enable_joystick(ymfpci_t *chip)
{
u16 val;
chip->gameport.io = snd_ymfpci_get_joystick_port(chip, chip->joystick_port);
chip->joystick_res = request_region(chip->gameport.io, 1, "YMFPCI gameport");
if (!chip->joystick_res) {
snd_printk(KERN_WARNING "gameport port %#x in use\n", chip->gameport.io);
return 0;
}
setup_joystick_base(chip);
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &val);
val |= YMFPCI_LEGACY_JPEN;
pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, val);
gameport_register_port(&chip->gameport);
return 1;
}
static int snd_ymfpci_disable_joystick(ymfpci_t *chip)
{
u16 val;
gameport_unregister_port(&chip->gameport);
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &val);
val &= ~YMFPCI_LEGACY_JPEN;
pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, val);
release_resource(chip->joystick_res);
kfree_nocheck(chip->joystick_res);
chip->joystick_res = NULL;
return 1;
}
static int snd_ymfpci_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int snd_ymfpci_joystick_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
u16 val;
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &val);
ucontrol->value.integer.value[0] = (val & YMFPCI_LEGACY_JPEN) ? 1 : 0;
return 0;
}
static int snd_ymfpci_joystick_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
int enabled, change;
down(&chip->joystick_mutex);
enabled = chip->joystick_res != NULL;
change = enabled != !! ucontrol->value.integer.value[0];
if (change) {
if (!enabled)
change = snd_ymfpci_enable_joystick(chip);
else
change = snd_ymfpci_disable_joystick(chip);
}
up(&chip->joystick_mutex);
return change;
}
static int snd_ymfpci_joystick_addr_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
int ports = chip->device_id >= 0x0010 ? 5 : 4;
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = ports;
if (uinfo->value.enumerated.item >= ports)
uinfo->value.enumerated.item = ports - 1;
sprintf(uinfo->value.enumerated.name, "port 0x%x",
snd_ymfpci_get_joystick_port(chip, uinfo->value.enumerated.item));
return 0;
}
static int snd_ymfpci_joystick_addr_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
ucontrol->value.enumerated.item[0] = chip->joystick_port;
return 0;
}
static int snd_ymfpci_joystick_addr_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
int change, enabled;
down(&chip->joystick_mutex);
change = ucontrol->value.enumerated.item[0] != chip->joystick_port;
if (change) {
enabled = chip->joystick_res != NULL;
if (enabled)
snd_ymfpci_disable_joystick(chip);
chip->joystick_port = ucontrol->value.enumerated.item[0];
if (enabled)
snd_ymfpci_enable_joystick(chip);
}
up(&chip->joystick_mutex);
return change;
}
static snd_kcontrol_new_t snd_ymfpci_control_joystick __devinitdata = {
.name = "Joystick",
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
.info = snd_ymfpci_joystick_info,
.get = snd_ymfpci_joystick_get,
.put = snd_ymfpci_joystick_put,
};
static snd_kcontrol_new_t snd_ymfpci_control_joystick_addr __devinitdata = {
.name = "Joystick Address",
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
.info = snd_ymfpci_joystick_addr_info,
.get = snd_ymfpci_joystick_addr_get,
.put = snd_ymfpci_joystick_addr_put,
};
int __devinit snd_ymfpci_joystick(ymfpci_t *chip)
{
int err;
chip->joystick_port = 0; /* default */
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_control_joystick, chip))) < 0)
return err;
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_control_joystick_addr, chip))) < 0)
return err;
return 0;
}
#endif /* CONFIG_GAMEPORT */
/*
* proc interface
*/
......@@ -2122,9 +1951,13 @@ static int snd_ymfpci_free(ymfpci_t *chip)
release_resource(chip->fm_res);
kfree_nocheck(chip->fm_res);
}
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
if (chip->joystick_res)
snd_ymfpci_disable_joystick(chip);
#ifdef SUPPORT_JOYSTICK
if (chip->joystick_res) {
if (chip->gameport.io)
gameport_unregister_port(&chip->gameport);
release_resource(chip->joystick_res);
kfree_nocheck(chip->joystick_res);
}
#endif
if (chip->reg_area_virt)
iounmap((void *)chip->reg_area_virt);
......@@ -2275,9 +2108,6 @@ int __devinit snd_ymfpci_create(snd_card_t * card,
spin_lock_init(&chip->voice_lock);
init_waitqueue_head(&chip->interrupt_sleep);
atomic_set(&chip->interrupt_sleep_count, 0);
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
init_MUTEX(&chip->joystick_mutex);
#endif
chip->card = card;
chip->pci = pci;
chip->irq = -1;
......
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