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 ...@@ -173,8 +173,7 @@ Module parameters
Module for soundcards based on Avance Logic ALS4000 PCI chip. Module for soundcards based on Avance Logic ALS4000 PCI chip.
joystick_port - port # for legacy joystick support. joystick_port - port # for legacy joystick support.
default: 0x200 for the 1st card. 0 = disabled (default)
0 = disabled
Module supports up to 8 cards, autoprobe and PnP. Module supports up to 8 cards, autoprobe and PnP.
...@@ -225,6 +224,7 @@ Module parameters ...@@ -225,6 +224,7 @@ Module parameters
fm_port - 0x388 (default), -1 (disable) fm_port - 0x388 (default), -1 (disable)
soft_ac3 - Sofware-conversion of raw SPDIF packets (model 033 only) soft_ac3 - Sofware-conversion of raw SPDIF packets (model 033 only)
(default = 1) (default = 1)
joystick - Enable joystick (default off)
Module supports autoprobe and multiple chips (max 8). Module supports autoprobe and multiple chips (max 8).
...@@ -377,6 +377,8 @@ Module parameters ...@@ -377,6 +377,8 @@ Module parameters
* SoundBlaster PCI 64 * SoundBlaster PCI 64
* SoundBlaster PCI 128 * SoundBlaster PCI 128
joystick - Enable joystick (default off)
Module supports up to 8 cards and autoprobe. Module supports up to 8 cards and autoprobe.
Module snd-ens1371 Module snd-ens1371
...@@ -387,6 +389,9 @@ Module parameters ...@@ -387,6 +389,9 @@ Module parameters
* SoundBlaster PCI 128 * SoundBlaster PCI 128
* SoundBlaster Vibra PCI * SoundBlaster Vibra PCI
joystick_port - port # for joystick (0x200,0x208,0x210,0x218),
0 = disable (default)
Module supports up to 8 cards and autoprobe. Module supports up to 8 cards and autoprobe.
Module snd-es968 Module snd-es968
...@@ -451,6 +456,7 @@ Module parameters ...@@ -451,6 +456,7 @@ Module parameters
use_pm - support the power-management (0 = off, 1 = on, use_pm - support the power-management (0 = off, 1 = on,
2 = auto (default)) 2 = auto (default))
enable_mpu - enable MPU401 (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. Module supports up to 8 cards and autoprobe.
...@@ -581,7 +587,7 @@ Module parameters ...@@ -581,7 +587,7 @@ Module parameters
* ALi m5455 * ALi m5455
ac97_clock - AC'97 codec clock base (0 = auto-detect) 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) mpu_port - MPU401 port # (0 = disabled, 0x330,0x300)
Module supports autoprobe and multiple bus-master chips (max 8). Module supports autoprobe and multiple bus-master chips (max 8).
...@@ -991,6 +997,7 @@ Module parameters ...@@ -991,6 +997,7 @@ Module parameters
mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
[VIA686A/686B only] [VIA686A/686B only]
joystick - Enable joystick (default off) [VIA686A/686B only]
ac97_clock - AC'97 codec clock base (default 48000Hz) ac97_clock - AC'97 codec clock base (default 48000Hz)
dxs_support - support DXS channels, dxs_support - support DXS channels,
0 = auto (defalut), 1 = enable, 2 = disable, 0 = auto (defalut), 1 = enable, 2 = disable,
...@@ -1119,10 +1126,14 @@ Module parameters ...@@ -1119,10 +1126,14 @@ Module parameters
mpu_port - 0x300,0x330,0x332,0x334, -1 (disable) by default mpu_port - 0x300,0x330,0x332,0x334, -1 (disable) by default
fm_port - 0x388,0x398,0x3a0,0x3a8, -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) rear_switch - enable shared rear/line-in switch (bool)
Module supports autoprobe and multiple chips (max 8). 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. 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 { ...@@ -63,8 +63,6 @@ enum sb_hw_type {
struct _snd_sb { struct _snd_sb {
unsigned long port; /* base port of DSP chip */ unsigned long port; /* base port of DSP chip */
struct resource *res_port; 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+ */ unsigned long mpu_port; /* MPU port for SB DSP 4.0+ */
int irq; /* IRQ number of DSP chip */ int irq; /* IRQ number of DSP chip */
int dma8; /* 8-bit DMA */ int dma8; /* 8-bit DMA */
...@@ -72,6 +70,7 @@ struct _snd_sb { ...@@ -72,6 +70,7 @@ struct _snd_sb {
unsigned short version; /* version of DSP chip */ unsigned short version; /* version of DSP chip */
enum sb_hw_type hardware; /* see to SB_HW_XXXX */ enum sb_hw_type hardware; /* see to SB_HW_XXXX */
unsigned long alt_port; /* alternate port (ALS4000) */
struct pci_dev *pci; /* ALS4000 */ struct pci_dev *pci; /* ALS4000 */
unsigned int open; /* see to SB_OPEN_XXXX for sb8 */ unsigned int open; /* see to SB_OPEN_XXXX for sb8 */
......
...@@ -311,8 +311,6 @@ struct _snd_ymfpci { ...@@ -311,8 +311,6 @@ struct _snd_ymfpci {
unsigned short old_legacy_ctrl; unsigned short old_legacy_ctrl;
#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) #if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
unsigned int joystick_port;
struct semaphore joystick_mutex;
struct resource *joystick_res; struct resource *joystick_res;
struct gameport gameport; struct gameport gameport;
#endif #endif
...@@ -389,9 +387,6 @@ int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm); ...@@ -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_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_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch); 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_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); int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice);
...@@ -401,4 +396,8 @@ void snd_ymfpci_suspend(ymfpci_t *chip); ...@@ -401,4 +396,8 @@ void snd_ymfpci_suspend(ymfpci_t *chip);
void snd_ymfpci_resume(ymfpci_t *chip); void snd_ymfpci_resume(ymfpci_t *chip);
#endif #endif
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK
#endif
#endif /* __SOUND_YMFPCI_H */ #endif /* __SOUND_YMFPCI_H */
...@@ -185,10 +185,6 @@ static int snd_sbdsp_free(sb_t *chip) ...@@ -185,10 +185,6 @@ static int snd_sbdsp_free(sb_t *chip)
release_resource(chip->res_port); release_resource(chip->res_port);
kfree_nocheck(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) if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip); free_irq(chip->irq, (void *) chip);
#ifdef CONFIG_ISA #ifdef CONFIG_ISA
......
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/rawmidi.h> #include <sound/rawmidi.h>
...@@ -78,14 +79,15 @@ MODULE_LICENSE("GPL"); ...@@ -78,14 +79,15 @@ MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}"); MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{Avance Logic,ALS4000}}"); 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 int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 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 enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int joystick_port[SNDRV_CARDS] = #ifdef SUPPORT_JOYSTICK
#ifdef CONFIG_ISA static int joystick_port[SNDRV_CARDS];
{0x200}; /* enable as default */
#else
{0}; /* disabled */
#endif #endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
...@@ -105,6 +107,11 @@ MODULE_PARM_SYNTAX(joystick_port, SNDRV_ENABLED); ...@@ -105,6 +107,11 @@ MODULE_PARM_SYNTAX(joystick_port, SNDRV_ENABLED);
typedef struct { typedef struct {
unsigned long gcr; unsigned long gcr;
struct resource *res_gcr;
#ifdef SUPPORT_JOYSTICK
struct gameport gameport;
struct resource *res_joystick;
#endif
} snd_card_als4000_t; } snd_card_als4000_t;
static struct pci_device_id snd_als4000_ids[] = { static struct pci_device_id snd_als4000_ids[] = {
...@@ -523,7 +530,7 @@ static int __devinit snd_als4000_pcm(sb_t *chip, int device) ...@@ -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 sb,
unsigned int mpu, unsigned int mpu,
unsigned int opl, unsigned int opl,
...@@ -574,6 +581,18 @@ static void snd_card_als4000_free( snd_card_t *card ) ...@@ -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; snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data;
/* make sure that interrupts are disabled */ /* make sure that interrupts are disabled */
snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0); 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, 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, ...@@ -588,6 +607,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
opl3_t *opl3; opl3_t *opl3;
unsigned short word; unsigned short word;
int err; int err;
int joystick = 0;
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
...@@ -617,9 +637,6 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, ...@@ -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_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
pci_set_master(pci); 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, card = snd_card_new(index[dev], id[dev], THIS_MODULE,
sizeof( snd_card_als4000_t ) ); sizeof( snd_card_als4000_t ) );
if (card == NULL) { if (card == NULL) {
...@@ -630,8 +647,17 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, ...@@ -630,8 +647,17 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
acard = (snd_card_als4000_t *)card->private_data; acard = (snd_card_als4000_t *)card->private_data;
acard->gcr = gcr; acard->gcr = gcr;
acard->res_gcr = res_gcr_port;
card->private_free = snd_card_als4000_free; 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, if ((err = snd_sbdsp_create(card,
gcr + 0x10, gcr + 0x10,
pci->irq, pci->irq,
...@@ -640,15 +666,12 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, ...@@ -640,15 +666,12 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
-1, -1,
SB_HW_ALS4000, SB_HW_ALS4000,
&chip)) < 0) { &chip)) < 0) {
release_resource(res_gcr_port);
kfree_nocheck(res_gcr_port);
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
chip->pci = pci; chip->pci = pci;
chip->alt_port = gcr; chip->alt_port = gcr;
chip->res_alt_port = res_gcr_port;
snd_als4000_configure(chip); snd_als4000_configure(chip);
...@@ -680,6 +703,12 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, ...@@ -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->driver, "ALS4000");
strcpy(card->shortname, "Avance Logic ALS4000"); strcpy(card->shortname, "Avance Logic ALS4000");
sprintf(card->longname, "%s at 0x%lx, irq %i", sprintf(card->longname, "%s at 0x%lx, irq %i",
...@@ -730,7 +759,7 @@ module_exit(alsa_card_als4000_exit) ...@@ -730,7 +759,7 @@ module_exit(alsa_card_als4000_exit)
#ifndef MODULE #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) static int __init alsa_card_als4000_setup(char *str)
{ {
...@@ -740,7 +769,11 @@ static int __init alsa_card_als4000_setup(char *str) ...@@ -740,7 +769,11 @@ static int __init alsa_card_als4000_setup(char *str)
return 0; return 0;
(void)(get_option(&str,&enable[nr_dev]) == 2 && (void)(get_option(&str,&enable[nr_dev]) == 2 &&
get_option(&str,&index[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++; nr_dev++;
return 1; return 1;
} }
......
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/control.h> #include <sound/control.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -113,6 +114,10 @@ MODULE_LICENSE("GPL"); ...@@ -113,6 +114,10 @@ MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}"); MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{Aztech,AZF3328}}"); 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_MISC 0
#define DEBUG_CALLS 0 #define DEBUG_CALLS 0
#define DEBUG_MIXER 0 #define DEBUG_MIXER 0
...@@ -158,8 +163,10 @@ MODULE_DEVICES("{{Aztech,AZF3328}}"); ...@@ -158,8 +163,10 @@ MODULE_DEVICES("{{Aztech,AZF3328}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 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 enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
#ifdef SUPPORT_JOYSTICK
static int joystick[SNDRV_CARDS] = static int joystick[SNDRV_CARDS] =
{-1}; /* "unset" as default */ {-1}; /* "unset" as default */
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard."); MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
...@@ -170,9 +177,11 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC); ...@@ -170,9 +177,11 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard."); MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
MODULE_PARM_SYNTAX(enable, SNDRV_INDEX_DESC); MODULE_PARM_SYNTAX(enable, SNDRV_INDEX_DESC);
#ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); 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_DESC(joystick, "Forced joystick port enable for AZF3328 soundcard. (0 = force disable)");
MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED); MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED);
#endif
typedef struct _snd_azf3328 azf3328_t; typedef struct _snd_azf3328 azf3328_t;
#define chip_t azf3328_t #define chip_t azf3328_t
...@@ -190,7 +199,11 @@ struct _snd_azf3328 { ...@@ -190,7 +199,11 @@ struct _snd_azf3328 {
struct resource *res_synth_port; struct resource *res_synth_port;
unsigned long mixer_port; unsigned long mixer_port;
struct resource *res_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; struct pci_dev *pci;
snd_card_t *card; snd_card_t *card;
...@@ -1259,6 +1272,16 @@ static int snd_azf3328_free(azf3328_t *chip) ...@@ -1259,6 +1272,16 @@ static int snd_azf3328_free(azf3328_t *chip)
synchronize_irq(chip->irq); synchronize_irq(chip->irq);
__end_hw: __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) { if (chip->res_codec_port) {
release_resource(chip->res_codec_port); release_resource(chip->res_codec_port);
kfree_nocheck(chip->res_codec_port); kfree_nocheck(chip->res_codec_port);
...@@ -1419,42 +1442,39 @@ static int __devinit snd_azf3328_create(snd_card_t * card, ...@@ -1419,42 +1442,39 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
return 0; return 0;
} }
#ifdef SUPPORT_JOYSTICK
static void __devinit snd_azf3328_config_joystick(azf3328_t *chip, int 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; char *msg = NULL;
unsigned char val; unsigned char val;
if (joystick == -1) /* auto detection/activation */ if (joystick == -1) /* auto detection/activation */
{ {
activate = 1;
for (i=0x200; i <= 0x207; i++) for (i=0x200; i <= 0x207; i++)
if (inb(i) != 0xff) if (inb(i) != 0xff) {
detected = 1; /* other joy found, don't activate */
}
if ((joystick == -1) && (detected == 1))
{
activate = 0; activate = 0;
msg = "DISABLED (address occupied by another joystick port)"; break;
} }
else }
if ((joystick == -1) && (detected == 0))
{ if (activate || joystick == 1) {
if ((chip->res_joystick = request_region(0x200, 8, "AZF3328 gameport")) != NULL) {
chip->gameport.io = 0x200;
activate = 1; activate = 1;
msg = "ENABLED (via autodetect)"; } else
activate = 0;
} }
else
if (joystick == 0) if (joystick == 0)
{
activate = 0;
msg = "DISABLED (forced)"; msg = "DISABLED (forced)";
} else if (joystick == 1 && activate)
else
if (joystick == 1)
{
activate = 1;
msg = "ENABLED (Warning: forced!)"; 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); val = inb(chip->io2_port + IDX_IO2_LEGACY_ADDR);
if (activate) if (activate)
val |= LEGACY_JOY; val |= LEGACY_JOY;
...@@ -1465,7 +1485,10 @@ static void __devinit snd_azf3328_config_joystick(azf3328_t *chip, int joystick) ...@@ -1465,7 +1485,10 @@ static void __devinit snd_azf3328_config_joystick(azf3328_t *chip, int joystick)
#ifdef MODULE #ifdef MODULE
printk("azt3328: Joystick port: %s.\n", msg); printk("azt3328: Joystick port: %s.\n", msg);
#endif #endif
if (activate)
gameport_register_port(&chip->gameport);
} }
#endif
static int __devinit snd_azf3328_probe(struct pci_dev *pci, static int __devinit snd_azf3328_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id) const struct pci_device_id *pci_id)
...@@ -1537,7 +1560,9 @@ static int __devinit snd_azf3328_probe(struct pci_dev *pci, ...@@ -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"); "azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");
#endif #endif
#ifdef SUPPORT_JOYSTICK
snd_azf3328_config_joystick(chip, joystick[dev]); snd_azf3328_config_joystick(chip, joystick[dev]);
#endif
pci_set_drvdata(pci, chip); pci_set_drvdata(pci, chip);
dev++; dev++;
...@@ -1598,7 +1623,7 @@ module_exit(alsa_card_azf3328_exit) ...@@ -1598,7 +1623,7 @@ module_exit(alsa_card_azf3328_exit)
#ifndef MODULE #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) static int __init alsa_card_azf3328_setup(char *str)
{ {
...@@ -1610,12 +1635,16 @@ static int __init alsa_card_azf3328_setup(char *str) ...@@ -1610,12 +1635,16 @@ static int __init alsa_card_azf3328_setup(char *str)
return 0; return 0;
(void)(get_option(&str,&enable[nr_dev]) == 2 && (void)(get_option(&str,&enable[nr_dev]) == 2 &&
get_option(&str,&index[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++; nr_dev++;
snd_azf3328_dbgcallleave(); snd_azf3328_dbgcallleave();
return 1; return 1;
} }
__setup("snd-azf3328=", alsa_card_azf3328_setup); __setup("snd-azt3328=", alsa_card_azf3328_setup);
#endif /* ifndef MODULE */ #endif /* ifndef MODULE */
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/info.h> #include <sound/info.h>
#include <sound/control.h> #include <sound/control.h>
...@@ -52,6 +53,10 @@ MODULE_DEVICES("{{C-Media,CMI8738}," ...@@ -52,6 +53,10 @@ MODULE_DEVICES("{{C-Media,CMI8738},"
"{C-Media,CMI8338A}," "{C-Media,CMI8338A},"
"{C-Media,CMI8338B}}"); "{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 int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ 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}; ...@@ -60,6 +65,9 @@ static long fm_port[SNDRV_CARDS] = {0x388, [1 ... (SNDRV_CARDS-1)]=-1};
#ifdef DO_SOFT_AC3 #ifdef DO_SOFT_AC3
static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
#endif #endif
#ifdef SUPPORT_JOYSTICK
static int joystick[SNDRV_CARDS];
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for C-Media PCI soundcard."); 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"); ...@@ -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_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only).");
MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC); MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
#endif #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 #ifndef PCI_DEVICE_ID_CMEDIA_CM8738
#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111 #define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
...@@ -339,6 +352,10 @@ MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC); ...@@ -339,6 +352,10 @@ MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
#define CM_EXTENT_MIDI 0x2 #define CM_EXTENT_MIDI 0x2
#define CM_EXTENT_SYNTH 0x4 #define CM_EXTENT_SYNTH 0x4
/* fixed legacy joystick address */
#define CM_JOYSTICK_ADDR 0x200
/* /*
* pci ids * pci ids
*/ */
...@@ -480,6 +497,11 @@ struct snd_stru_cmipci { ...@@ -480,6 +497,11 @@ struct snd_stru_cmipci {
/* external MIDI */ /* external MIDI */
snd_rawmidi_t *rmidi; snd_rawmidi_t *rmidi;
#ifdef SUPPORT_JOYSTICK
struct gameport gameport;
struct resource *res_joystick;
#endif
spinlock_t reg_lock; spinlock_t reg_lock;
}; };
...@@ -2599,7 +2621,7 @@ DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0); ...@@ -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(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_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(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_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0);
#define DEFINE_SWITCH(sname, stype, sarg) \ #define DEFINE_SWITCH(sname, stype, sarg) \
...@@ -2693,7 +2715,7 @@ static snd_kcontrol_new_t snd_cmipci_extra_mixer_switches[] __devinitdata = { ...@@ -2693,7 +2715,7 @@ static snd_kcontrol_new_t snd_cmipci_extra_mixer_switches[] __devinitdata = {
/* card control switches */ /* card control switches */
static snd_kcontrol_new_t snd_cmipci_control_switches[] __devinitdata = { 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), DEFINE_CARD_SWITCH("Modem", modem),
}; };
...@@ -2905,6 +2927,14 @@ static int snd_cmipci_free(cmipci_t *cm) ...@@ -2905,6 +2927,14 @@ static int snd_cmipci_free(cmipci_t *cm)
free_irq(cm->irq, (void *)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) { if (cm->res_iobase) {
release_resource(cm->res_iobase); release_resource(cm->res_iobase);
kfree_nocheck(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, ...@@ -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); snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K|CM_SPDF_AC97);
#endif /* USE_VAR48KRATE */ #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; *rcmipci = cm;
return 0; return 0;
...@@ -3218,7 +3257,7 @@ module_exit(alsa_card_cmipci_exit) ...@@ -3218,7 +3257,7 @@ module_exit(alsa_card_cmipci_exit)
#ifndef MODULE #ifndef MODULE
/* format is: snd-cmipci=enable,index,id, /* 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) static int __init alsa_card_cmipci_setup(char *str)
{ {
...@@ -3230,7 +3269,14 @@ 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_option(&str,&index[nr_dev]) == 2 &&
get_id(&str,&id[nr_dev]) == 2 && get_id(&str,&id[nr_dev]) == 2 &&
get_option_long(&str,&mpu_port[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++; nr_dev++;
return 1; return 1;
} }
......
...@@ -72,9 +72,20 @@ MODULE_DEVICES("{{Ensoniq,AudioPCI ES1371/73}," ...@@ -72,9 +72,20 @@ MODULE_DEVICES("{{Ensoniq,AudioPCI ES1371/73},"
"{Ectiva,EV1938}}"); "{Ectiva,EV1938}}");
#endif #endif
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK
#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
#ifdef SUPPORT_JOYSTICK
#ifdef CHIP1371
static int joystick_port[SNDRV_CARDS];
#else
static int joystick[SNDRV_CARDS];
#endif
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for Ensoniq AudioPCI soundcard."); MODULE_PARM_DESC(index, "Index value for Ensoniq AudioPCI soundcard.");
...@@ -85,6 +96,17 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC); ...@@ -85,6 +96,17 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable Ensoniq AudioPCI soundcard."); MODULE_PARM_DESC(enable, "Enable Ensoniq AudioPCI soundcard.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
#ifdef SUPPORT_JOYSTICK
#ifdef CHIP1371
MODULE_PARM(joystick_port, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick_port, "Joystick port address.");
MODULE_PARM_SYNTAX(joystick_port, SNDRV_ENABLED ",allows:{{0},{0x200},{0x208},{0x210},{0x218}},dialog:list");
#else
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
#endif /* SUPPORT_JOYSTICK */
#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880 #ifndef PCI_DEVICE_ID_ENSONIQ_CT5880
#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 #define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
...@@ -416,9 +438,8 @@ struct _snd_ensoniq { ...@@ -416,9 +438,8 @@ struct _snd_ensoniq {
dma_addr_t bugbuf_addr; dma_addr_t bugbuf_addr;
#endif #endif
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) #ifdef SUPPORT_JOYSTICK
struct gameport gameport; struct gameport gameport;
struct semaphore joy_sem; // gameport configuration semaphore
#endif #endif
}; };
...@@ -1565,8 +1586,8 @@ static int snd_ensoniq_1371_mixer(ensoniq_t * ensoniq) ...@@ -1565,8 +1586,8 @@ static int snd_ensoniq_1371_mixer(ensoniq_t * ensoniq)
#endif /* CHIP1371 */ #endif /* CHIP1371 */
/* generic control callbacks for ens1370 and for joystick */ /* generic control callbacks for ens1370 */
#if defined(CHIP1370) || defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) #ifdef CHIP1370
#define ENSONIQ_CONTROL(xname, mask) \ #define ENSONIQ_CONTROL(xname, mask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \ { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
.get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \ .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \
...@@ -1593,7 +1614,6 @@ static int snd_ensoniq_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value ...@@ -1593,7 +1614,6 @@ static int snd_ensoniq_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
return 0; return 0;
} }
#ifdef CHIP1370
static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{ {
ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
...@@ -1611,14 +1631,11 @@ static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value ...@@ -1611,14 +1631,11 @@ static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
spin_unlock_irqrestore(&ensoniq->reg_lock, flags); spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
return change; return change;
} }
#endif /* CHIP1370 */
#endif /* CHIP1370 || GAMEPORT */
/* /*
* ENS1370 mixer * ENS1370 mixer
*/ */
#ifdef CHIP1370
static snd_kcontrol_new_t snd_es1370_controls[2] __devinitdata = { static snd_kcontrol_new_t snd_es1370_controls[2] __devinitdata = {
ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0), ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0),
ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1) ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1)
...@@ -1660,129 +1677,32 @@ static int __devinit snd_ensoniq_1370_mixer(ensoniq_t * ensoniq) ...@@ -1660,129 +1677,32 @@ static int __devinit snd_ensoniq_1370_mixer(ensoniq_t * ensoniq)
#endif /* CHIP1370 */ #endif /* CHIP1370 */
/* #ifdef SUPPORT_JOYSTICK
* General Switches... static int snd_ensoniq_joystick(ensoniq_t *ensoniq, long port)
*/
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
/* MQ: gameport driver connectivity */
#define ENSONIQ_JOY_CONTROL(xname, mask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
.get = snd_ensoniq_control_get, .put = snd_ensoniq_joy_control_put, \
.private_value = mask }
static int snd_ensoniq_joy_enable(ensoniq_t *ensoniq)
{ {
static unsigned long last_jiffies = 0; ensoniq->gameport.io = port;
unsigned long flags;
if (!request_region(ensoniq->gameport.io, 8, "ens137x: gameport")) { if (!request_region(ensoniq->gameport.io, 8, "ens137x: gameport")) {
#define ES___GAMEPORT_LOG_DELAY (30*HZ)
// avoid log pollution: limit to 2 infos per minute
if (time_after(jiffies, last_jiffies + ES___GAMEPORT_LOG_DELAY)) {
last_jiffies = jiffies;
snd_printk("gameport io port 0x%03x in use", ensoniq->gameport.io); snd_printk("gameport io port 0x%03x in use", ensoniq->gameport.io);
return -EBUSY;
} }
return 0;
}
spin_lock_irqsave(&ensoniq->reg_lock, flags);
ensoniq->ctrl |= ES_JYSTK_EN; ensoniq->ctrl |= ES_JYSTK_EN;
#ifdef CHIP1371
ensoniq->ctrl &= ~ES_1371_JOY_ASELM;
ensoniq->ctrl |= ES_1371_JOY_ASEL((ensoniq->gameport.io - 0x200) / 8);
#endif
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
gameport_register_port(&ensoniq->gameport); gameport_register_port(&ensoniq->gameport);
return 1; return 0;
} }
static int snd_ensoniq_joy_disable(ensoniq_t *ensoniq) static void snd_ensoniq_joystick_free(ensoniq_t *ensoniq)
{ {
unsigned long flags;
gameport_unregister_port(&ensoniq->gameport); gameport_unregister_port(&ensoniq->gameport);
spin_lock_irqsave(&ensoniq->reg_lock, flags);
ensoniq->ctrl &= ~ES_JYSTK_EN; ensoniq->ctrl &= ~ES_JYSTK_EN;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
release_region(ensoniq->gameport.io, 8); release_region(ensoniq->gameport.io, 8);
return 1;
}
static int snd_ensoniq_joy_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned int nval;
int change;
down(&ensoniq->joy_sem);
nval = ucontrol->value.integer.value[0] ? ES_JYSTK_EN : 0;
change = (ensoniq->ctrl & ES_JYSTK_EN) != nval; // spinlock shouldn't be needed because of joy_sem
if (change) {
if (nval) // enable
change = snd_ensoniq_joy_enable(ensoniq);
else change = snd_ensoniq_joy_disable(ensoniq);
}
up(&ensoniq->joy_sem);
return change;
} }
#endif /* SUPPORT_JOYSTICK */
static snd_kcontrol_new_t snd_ensoniq_control_joystick __devinitdata =
ENSONIQ_JOY_CONTROL("Joystick Enable", ES_JYSTK_EN);
#ifdef CHIP1371
#define ES1371_JOYSTICK_ADDR(xname) \
{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_es1371_joystick_addr_info, \
.get = snd_es1371_joystick_addr_get, .put = snd_es1371_joystick_addr_put }
static int snd_es1371_joystick_addr_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 4;
if (uinfo->value.enumerated.item >= 4)
uinfo->value.enumerated.item = 3;
sprintf(uinfo->value.enumerated.name, "port 0x%x", (uinfo->value.enumerated.item * 8) + 0x200);
return 0;
}
static int snd_es1371_joystick_addr_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned long flags;
spin_lock_irqsave(&ensoniq->reg_lock, flags);
ucontrol->value.enumerated.item[0] = ES_1371_JOY_ASELI(ensoniq->ctrl);
spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
return 0;
}
static int snd_es1371_joystick_addr_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned long flags;
unsigned int nval;
int change;
down(&ensoniq->joy_sem);
nval = ES_1371_JOY_ASEL(ucontrol->value.integer.value[0]);
spin_lock_irqsave(&ensoniq->reg_lock, flags);
if (!(change = !(ensoniq->ctrl & ES_JYSTK_EN)))
goto no_change; // FIXME: now we allow change only when joystick is disabled
change = (ensoniq->ctrl & ES_1371_JOY_ASELM) != nval;
ensoniq->ctrl &= ~ES_1371_JOY_ASELM;
ensoniq->ctrl |= nval;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
ensoniq->gameport.io = 0x200 + ES_1371_JOY_ASELI(nval) * 8;
no_change:
spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
up(&ensoniq->joy_sem);
return change;
}
static snd_kcontrol_new_t snd_es1371_joystick_addr __devinitdata =
ES1371_JOYSTICK_ADDR("Joystick Address");
#endif /* CHIP1371 */
#endif /* CONFIG_GAMEPORT */
/* /*
...@@ -1821,9 +1741,9 @@ static void __devinit snd_ensoniq_proc_init(ensoniq_t * ensoniq) ...@@ -1821,9 +1741,9 @@ static void __devinit snd_ensoniq_proc_init(ensoniq_t * ensoniq)
static int snd_ensoniq_free(ensoniq_t *ensoniq) static int snd_ensoniq_free(ensoniq_t *ensoniq)
{ {
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) #ifdef SUPPORT_JOYSTICK
if (ensoniq->ctrl & ES_JYSTK_EN) if (ensoniq->ctrl & ES_JYSTK_EN)
snd_ensoniq_joy_disable(ensoniq); snd_ensoniq_joystick_free(ensoniq);
#endif #endif
if (ensoniq->irq < 0) if (ensoniq->irq < 0)
goto __hw_end; goto __hw_end;
...@@ -2019,14 +1939,6 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, ...@@ -2019,14 +1939,6 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL));
outb(0x00, ES_REG(ensoniq, UART_RES)); outb(0x00, ES_REG(ensoniq, UART_RES));
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
init_MUTEX(&ensoniq->joy_sem);
#ifdef CHIP1371
snd_ctl_add(card, snd_ctl_new1(&snd_es1371_joystick_addr, ensoniq));
#endif
snd_ctl_add(card, snd_ctl_new1(&snd_ensoniq_control_joystick, ensoniq));
ensoniq->gameport.io = 0x200; // FIXME: is ES1371 configured like this above ?
#endif
synchronize_irq(ensoniq->irq); synchronize_irq(ensoniq->irq);
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
...@@ -2331,6 +2243,21 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci, ...@@ -2331,6 +2243,21 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci,
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
#ifdef SUPPORT_JOYSTICK
#ifdef CHIP1371
switch (joystick_port[dev]) {
case 0x200:
case 0x208:
case 0x210:
case 0x218:
snd_ensoniq_joystick(ensoniq, joystick_port[dev]);
break;
}
#else
if (joystick[dev])
snd_ensoniq_joystick(ensoniq, 0x200);
#endif
#endif /* SUPPORT_JOYSTICK */
strcpy(card->driver, DRIVER_NAME); strcpy(card->driver, DRIVER_NAME);
strcpy(card->shortname, "Ensoniq AudioPCI"); strcpy(card->shortname, "Ensoniq AudioPCI");
...@@ -2386,7 +2313,7 @@ module_exit(alsa_card_ens137x_exit) ...@@ -2386,7 +2313,7 @@ module_exit(alsa_card_ens137x_exit)
#ifndef MODULE #ifndef MODULE
/* format is: snd-ens1370=enable,index,id */ /* format is: snd-ens1370=enable,index,id,joystick */
static int __init alsa_card_ens137x_setup(char *str) static int __init alsa_card_ens137x_setup(char *str)
{ {
...@@ -2396,7 +2323,15 @@ static int __init alsa_card_ens137x_setup(char *str) ...@@ -2396,7 +2323,15 @@ static int __init alsa_card_ens137x_setup(char *str)
return 0; return 0;
(void)(get_option(&str,&enable[nr_dev]) == 2 && (void)(get_option(&str,&enable[nr_dev]) == 2 &&
get_option(&str,&index[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
#ifdef CHIP1371
&& get_option(&str,&joystick_port[nr_dev]) == 2
#else
&& get_option(&str,&joystick[nr_dev]) == 2
#endif
#endif
);
nr_dev++; nr_dev++;
return 1; return 1;
} }
......
...@@ -101,6 +101,7 @@ ...@@ -101,6 +101,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/mpu401.h> #include <sound/mpu401.h>
...@@ -121,6 +122,10 @@ MODULE_DEVICES("{{ESS,Maestro 2e}," ...@@ -121,6 +122,10 @@ MODULE_DEVICES("{{ESS,Maestro 2e},"
"{ESS,Maestro 1}," "{ESS,Maestro 1},"
"{TerraTec,DMX}}"); "{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 int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 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 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 }; ...@@ -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 clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
static int enable_mpu[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(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); 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"); ...@@ -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(enable_mpu, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)"); MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)");
MODULE_PARM_SYNTAX(enable_mpu, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC); 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 */ /* PCI Dev ID's */
...@@ -601,6 +614,11 @@ struct snd_es1968 { ...@@ -601,6 +614,11 @@ struct snd_es1968 {
#ifdef CONFIG_PM #ifdef CONFIG_PM
u16 apu_map[NR_APUS][NR_APU_REGS]; u16 apu_map[NR_APUS][NR_APU_REGS];
#endif #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); 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) ...@@ -2477,6 +2495,13 @@ static int snd_es1968_free(es1968_t *chip)
if (chip->res_io_port) if (chip->res_io_port)
snd_es1968_reset(chip); 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); snd_es1968_set_acpi(chip, ACPI_D3);
chip->master_switch = NULL; chip->master_switch = NULL;
chip->master_volume = NULL; chip->master_volume = NULL;
...@@ -2622,57 +2647,6 @@ static int __devinit snd_es1968_create(snd_card_t * card, ...@@ -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, static int __devinit snd_es1968_probe(struct pci_dev *pci,
...@@ -2755,14 +2729,17 @@ 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 */ #ifdef SUPPORT_JOYSTICK
for (i = 0; i < num_controls(snd_es1968_control_switches); i++) { #define JOYSTICK_ADDR 0x200
err = snd_ctl_add(card, snd_ctl_new1(&snd_es1968_control_switches[i], chip)); if (joystick[dev] &&
if (err < 0) { (chip->res_joystick = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport")) != NULL) {
snd_card_free(card); u16 val;
return err; 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); snd_es1968_start_irq(chip);
...@@ -2833,7 +2810,8 @@ module_exit(alsa_card_es1968_exit) ...@@ -2833,7 +2810,8 @@ module_exit(alsa_card_es1968_exit)
pcm_substreams_c, pcm_substreams_c,
clock, clock,
use_pm, use_pm,
enable_mpu enable_mpu,
joystick
*/ */
static int __init alsa_card_es1968_setup(char *str) static int __init alsa_card_es1968_setup(char *str)
...@@ -2850,7 +2828,11 @@ 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,&pcm_substreams_c[nr_dev]) == 2 &&
get_option(&str,&clock[nr_dev]) == 2 && get_option(&str,&clock[nr_dev]) == 2 &&
get_option(&str,&use_pm[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++; nr_dev++;
return 1; return 1;
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/ac97_codec.h> #include <sound/ac97_codec.h>
...@@ -59,7 +60,9 @@ MODULE_DEVICES("{{Intel,82801AA-ICH}," ...@@ -59,7 +60,9 @@ MODULE_DEVICES("{{Intel,82801AA-ICH},"
"{AMD,AMD8111}," "{AMD,AMD8111},"
"{ALI,M5455}}"); "{ALI,M5455}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1 #define SUPPORT_JOYSTICK 1
#endif
#define SUPPORT_MIDI 1 #define SUPPORT_MIDI 1
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 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 */ ...@@ -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 enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
static int joystick_port[SNDRV_CARDS] = static int joystick[SNDRV_CARDS];
#ifdef CONFIG_ISA
{0x200}; /* enable as default */
#else
{0}; /* disabled */
#endif
#endif #endif
#ifdef SUPPORT_MIDI #ifdef SUPPORT_MIDI
static int mpu_port[SNDRV_CARDS]; /* disabled */ static int mpu_port[SNDRV_CARDS]; /* disabled */
...@@ -91,9 +89,9 @@ MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); ...@@ -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_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:0"); MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:0");
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
MODULE_PARM(joystick_port, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(joystick_port, "Joystick port address for Intel i8x0 soundcard. (0 = disabled)"); MODULE_PARM_DESC(joystick, "Enable joystick for Intel i8x0 soundcard.");
MODULE_PARM_SYNTAX(joystick_port, SNDRV_ENABLED ",allows:{{0},{0x200}},dialog:list"); MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
#endif #endif
#ifdef SUPPORT_MIDI #ifdef SUPPORT_MIDI
MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
...@@ -2656,9 +2654,16 @@ static struct pci_driver driver = { ...@@ -2656,9 +2654,16 @@ static struct pci_driver driver = {
* initialize joystick/midi addresses * 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, static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
u16 val;
static int dev; static int dev;
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
...@@ -2667,17 +2672,24 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci, ...@@ -2667,17 +2672,24 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
return -ENOENT; return -ENOENT;
} }
if (joystick_port[dev] > 0 || mpu_port[dev] > 0) {
u16 val;
pci_read_config_word(pci, 0xe6, &val); pci_read_config_word(pci, 0xe6, &val);
if (joystick_port[dev] > 0) #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; 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) { if (mpu_port[dev] == 0x300 || mpu_port[dev] == 0x330) {
u8 b; u8 b;
val |= 0x20;
pci_read_config_byte(pci, 0xe2, &b); pci_read_config_byte(pci, 0xe2, &b);
if (mpu_port[dev] == 0x300) if (mpu_port[dev] == 0x300)
b |= 0x08; b |= 0x08;
...@@ -2686,9 +2698,27 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci, ...@@ -2686,9 +2698,27 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
pci_write_config_byte(pci, 0xe2, b); pci_write_config_byte(pci, 0xe2, b);
} }
} }
#endif
pci_write_config_word(pci, 0xe6, val);
return 0; 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[] = { static struct pci_device_id snd_intel8x0_joystick_ids[] = {
{ 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82801AA */ { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82801AA */
{ 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82901AB */ { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 82901AB */
...@@ -2707,6 +2737,7 @@ static struct pci_driver joystick_driver = { ...@@ -2707,6 +2737,7 @@ static struct pci_driver joystick_driver = {
.name = "Intel ICH Joystick", .name = "Intel ICH Joystick",
.id_table = snd_intel8x0_joystick_ids, .id_table = snd_intel8x0_joystick_ids,
.probe = snd_intel8x0_joystick_probe, .probe = snd_intel8x0_joystick_probe,
.remove = __devexit_p(snd_intel8x0_joystick_remove),
}; };
static int have_joystick; static int have_joystick;
...@@ -2749,7 +2780,7 @@ module_exit(alsa_card_intel8x0_exit) ...@@ -2749,7 +2780,7 @@ module_exit(alsa_card_intel8x0_exit)
#ifndef MODULE #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) static int __init alsa_card_intel8x0_setup(char *str)
{ {
...@@ -2763,6 +2794,9 @@ 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 get_option(&str,&ac97_clock[nr_dev]) == 2
#ifdef SUPPORT_MIDI #ifdef SUPPORT_MIDI
&& get_option(&str,&mpu_port[nr_dev]) == 2 && get_option(&str,&mpu_port[nr_dev]) == 2
#endif
#ifdef SUPPORT_JOYSTICK
&& get_option(&str,&joystick[nr_dev]) == 2
#endif #endif
); );
nr_dev++; nr_dev++;
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
...@@ -69,10 +70,17 @@ MODULE_LICENSE("GPL"); ...@@ -69,10 +70,17 @@ MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}"); MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}"); 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 int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 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 enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; 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 ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
static int dxs_support[SNDRV_CARDS]; static int dxs_support[SNDRV_CARDS];
...@@ -86,8 +94,13 @@ MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); ...@@ -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_DESC(enable, "Enable audio part of VIA 82xx bridge.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); 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); 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(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:48000"); MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:48000");
...@@ -461,6 +474,11 @@ struct _snd_via82xx { ...@@ -461,6 +474,11 @@ struct _snd_via82xx {
spinlock_t reg_lock; spinlock_t reg_lock;
spinlock_t ac97_lock; spinlock_t ac97_lock;
snd_info_entry_t *proc_entry; 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[] = { static struct pci_device_id snd_via82xx_ids[] = {
...@@ -1558,53 +1576,6 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip) ...@@ -1558,53 +1576,6 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
return 0; 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) ...@@ -1689,6 +1660,16 @@ static int snd_via686_init_misc(via82xx_t *chip, int dev)
legacy &= ~VIA_FUNC_ENABLE_MIDI; legacy &= ~VIA_FUNC_ENABLE_MIDI;
mpu_port[dev] = -1; 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_FUNC_ENABLE, legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
if (chip->mpu_res) { if (chip->mpu_res) {
...@@ -1703,8 +1684,12 @@ static int snd_via686_init_misc(via82xx_t *chip, int dev) ...@@ -1703,8 +1684,12 @@ static int snd_via686_init_misc(via82xx_t *chip, int dev)
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy); pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
} }
/* card switches */ #ifdef SUPPORT_JOYSTICK
return snd_ctl_add(chip->card, snd_ctl_new1(&snd_via82xx_joystick_control, chip)); if (chip->res_joystick)
gameport_register_port(&chip->gameport);
#endif
return 0;
} }
...@@ -1866,6 +1851,13 @@ static int snd_via82xx_free(via82xx_t *chip) ...@@ -1866,6 +1851,13 @@ static int snd_via82xx_free(via82xx_t *chip)
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip); free_irq(chip->irq, (void *)chip);
if (chip->chip_type == TYPE_VIA686) { 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_FUNC_ENABLE, chip->old_legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg); pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg);
} }
...@@ -2155,7 +2147,7 @@ module_exit(alsa_card_via82xx_exit) ...@@ -2155,7 +2147,7 @@ module_exit(alsa_card_via82xx_exit)
#ifndef MODULE #ifndef MODULE
/* format is: snd-via82xx=enable,index,id, /* 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) static int __init alsa_card_via82xx_setup(char *str)
{ {
...@@ -2167,6 +2159,9 @@ 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_option(&str,&index[nr_dev]) == 2 &&
get_id(&str,&id[nr_dev]) == 2 && get_id(&str,&id[nr_dev]) == 2 &&
get_option_long(&str,&mpu_port[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,&ac97_clock[nr_dev]) == 2 &&
get_option(&str,&dxs_support[nr_dev]) == 2); get_option(&str,&dxs_support[nr_dev]) == 2);
nr_dev++; nr_dev++;
......
...@@ -44,8 +44,11 @@ MODULE_DEVICES("{{Yamaha,YMF724}," ...@@ -44,8 +44,11 @@ MODULE_DEVICES("{{Yamaha,YMF724},"
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 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 enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static long fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; static long fm_port[SNDRV_CARDS];
static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; static long mpu_port[SNDRV_CARDS];
#ifdef SUPPORT_JOYSTICK
static long joystick_port[SNDRV_CARDS];
#endif
static int rear_switch[SNDRV_CARDS]; static int rear_switch[SNDRV_CARDS];
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
...@@ -63,6 +66,11 @@ MODULE_PARM_SYNTAX(mpu_port, SNDRV_ENABLED); ...@@ -63,6 +66,11 @@ MODULE_PARM_SYNTAX(mpu_port, SNDRV_ENABLED);
MODULE_PARM(fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); MODULE_PARM(fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(fm_port, "FM OPL-3 Port."); MODULE_PARM_DESC(fm_port, "FM OPL-3 Port.");
MODULE_PARM_SYNTAX(fm_port, SNDRV_ENABLED); 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(rear_switch, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
MODULE_PARM_SYNTAX(rear_switch, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); 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, ...@@ -86,6 +94,9 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
snd_card_t *card; snd_card_t *card;
struct resource *fm_res = NULL; struct resource *fm_res = NULL;
struct resource *mpu_res = NULL; struct resource *mpu_res = NULL;
#ifdef SUPPORT_JOYSTICK
struct resource *joystick_res = NULL;
#endif
ymfpci_t *chip; ymfpci_t *chip;
opl3_t *opl3; opl3_t *opl3;
char *str; char *str;
...@@ -117,22 +128,32 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, ...@@ -117,22 +128,32 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */ legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */
if (pci_id->device >= 0x0010) { /* YMF 744/754 */ 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); 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) { (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
legacy_ctrl |= YMFPCI_LEGACY_FMEN; legacy_ctrl |= YMFPCI_LEGACY_FMEN;
pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]); 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; 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) { (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
legacy_ctrl |= YMFPCI_LEGACY_MEN; legacy_ctrl |= YMFPCI_LEGACY_MEN;
pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]); 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 { } else {
switch (fm_port[dev]) { switch (fm_port[dev]) {
case 0x388: legacy_ctrl2 |= 0; break; case 0x388: legacy_ctrl2 |= 0; break;
...@@ -162,6 +183,22 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, ...@@ -162,6 +183,22 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO; legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
mpu_port[dev] = -1; 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) { if (mpu_res) {
legacy_ctrl |= YMFPCI_LEGACY_MIEN; legacy_ctrl |= YMFPCI_LEGACY_MIEN;
...@@ -182,10 +219,19 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, ...@@ -182,10 +219,19 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
release_resource(fm_res); release_resource(fm_res);
kfree_nocheck(fm_res); kfree_nocheck(fm_res);
} }
#ifdef SUPPORT_JOYSTICK
if (joystick_res) {
release_resource(joystick_res);
kfree_nocheck(joystick_res);
}
#endif
return err; return err;
} }
chip->fm_res = fm_res; chip->fm_res = fm_res;
chip->mpu_res = mpu_res; chip->mpu_res = mpu_res;
#ifdef SUPPORT_JOYSTICK
chip->joystick_res = joystick_res;
#endif
if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) { if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;
...@@ -229,9 +275,10 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, ...@@ -229,9 +275,10 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
return err; return err;
} }
} }
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) #ifdef SUPPORT_JOYSTICK
if ((err = snd_ymfpci_joystick(chip)) < 0) { if (chip->joystick_res) {
printk(KERN_WARNING "ymfpci: cannot initialize joystick, skipping...\n"); chip->gameport.io = joystick_port[dev];
gameport_register_port(&chip->gameport);
} }
#endif #endif
strcpy(card->driver, str); strcpy(card->driver, str);
......
...@@ -1702,177 +1702,6 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) ...@@ -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 * proc interface
*/ */
...@@ -2122,9 +1951,13 @@ static int snd_ymfpci_free(ymfpci_t *chip) ...@@ -2122,9 +1951,13 @@ static int snd_ymfpci_free(ymfpci_t *chip)
release_resource(chip->fm_res); release_resource(chip->fm_res);
kfree_nocheck(chip->fm_res); kfree_nocheck(chip->fm_res);
} }
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) #ifdef SUPPORT_JOYSTICK
if (chip->joystick_res) if (chip->joystick_res) {
snd_ymfpci_disable_joystick(chip); if (chip->gameport.io)
gameport_unregister_port(&chip->gameport);
release_resource(chip->joystick_res);
kfree_nocheck(chip->joystick_res);
}
#endif #endif
if (chip->reg_area_virt) if (chip->reg_area_virt)
iounmap((void *)chip->reg_area_virt); iounmap((void *)chip->reg_area_virt);
...@@ -2275,9 +2108,6 @@ int __devinit snd_ymfpci_create(snd_card_t * card, ...@@ -2275,9 +2108,6 @@ int __devinit snd_ymfpci_create(snd_card_t * card,
spin_lock_init(&chip->voice_lock); spin_lock_init(&chip->voice_lock);
init_waitqueue_head(&chip->interrupt_sleep); init_waitqueue_head(&chip->interrupt_sleep);
atomic_set(&chip->interrupt_sleep_count, 0); 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->card = card;
chip->pci = pci; chip->pci = pci;
chip->irq = -1; 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