|
@@ -133,6 +133,10 @@
|
|
#include <asm/page.h>
|
|
#include <asm/page.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
|
|
|
|
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
|
|
|
|
+#define SUPPORT_JOYSTICK
|
|
|
|
+#endif
|
|
|
|
+
|
|
/* --------------------------------------------------------------------- */
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
#undef OSS_DOCUMENTED_MIXER_SEMANTICS
|
|
#undef OSS_DOCUMENTED_MIXER_SEMANTICS
|
|
@@ -453,7 +457,10 @@ struct es1371_state {
|
|
unsigned char obuf[MIDIOUTBUF];
|
|
unsigned char obuf[MIDIOUTBUF];
|
|
} midi;
|
|
} midi;
|
|
|
|
|
|
|
|
+#ifdef SUPPORT_JOYSTICK
|
|
struct gameport *gameport;
|
|
struct gameport *gameport;
|
|
|
|
+#endif
|
|
|
|
+
|
|
struct semaphore sem;
|
|
struct semaphore sem;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -2786,12 +2793,63 @@ static struct
|
|
{ PCI_ANY_ID, PCI_ANY_ID }
|
|
{ PCI_ANY_ID, PCI_ANY_ID }
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+#ifdef SUPPORT_JOYSTICK
|
|
|
|
+
|
|
|
|
+static int __devinit es1371_register_gameport(struct es1371_state *s)
|
|
|
|
+{
|
|
|
|
+ struct gameport *gp;
|
|
|
|
+ int gpio;
|
|
|
|
+
|
|
|
|
+ for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
|
|
|
|
+ if (request_region(gpio, JOY_EXTENT, "es1371"))
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ if (gpio < 0x200) {
|
|
|
|
+ printk(KERN_ERR PFX "no free joystick address found\n");
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ s->gameport = gp = gameport_allocate_port();
|
|
|
|
+ if (!gp) {
|
|
|
|
+ printk(KERN_ERR PFX "can not allocate memory for gameport\n");
|
|
|
|
+ release_region(gpio, JOY_EXTENT);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ gameport_set_name(gp, "ESS1371 Gameport");
|
|
|
|
+ gameport_set_phys(gp, "isa%04x/gameport0", gpio);
|
|
|
|
+ gp->dev.parent = &s->dev->dev;
|
|
|
|
+ gp->io = gpio;
|
|
|
|
+
|
|
|
|
+ s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
|
|
|
|
+ outl(s->ctrl, s->io + ES1371_REG_CONTROL);
|
|
|
|
+
|
|
|
|
+ gameport_register_port(gp);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void es1371_unregister_gameport(struct es1371_state *s)
|
|
|
|
+{
|
|
|
|
+ if (s->gameport) {
|
|
|
|
+ int gpio = s->gameport->io;
|
|
|
|
+ gameport_unregister_port(s->gameport);
|
|
|
|
+ release_region(gpio, JOY_EXTENT);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#else
|
|
|
|
+static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; }
|
|
|
|
+static inline void es1371_unregister_gameport(struct es1371_state *s) { }
|
|
|
|
+#endif /* SUPPORT_JOYSTICK */
|
|
|
|
+
|
|
|
|
+
|
|
static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
|
|
static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
|
|
{
|
|
{
|
|
struct es1371_state *s;
|
|
struct es1371_state *s;
|
|
- struct gameport *gp;
|
|
|
|
mm_segment_t fs;
|
|
mm_segment_t fs;
|
|
- int i, gpio, val, res = -1;
|
|
|
|
|
|
+ int i, val, res = -1;
|
|
int idx;
|
|
int idx;
|
|
unsigned long tmo;
|
|
unsigned long tmo;
|
|
signed long tmo2;
|
|
signed long tmo2;
|
|
@@ -2882,23 +2940,6 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
|
|
|
|
- if (request_region(gpio, JOY_EXTENT, "es1371"))
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- if (gpio < 0x200) {
|
|
|
|
- printk(KERN_ERR PFX "no free joystick address found\n");
|
|
|
|
- } else if (!(s->gameport = gp = gameport_allocate_port())) {
|
|
|
|
- printk(KERN_ERR PFX "can not allocate memory for gameport\n");
|
|
|
|
- release_region(gpio, JOY_EXTENT);
|
|
|
|
- } else {
|
|
|
|
- gameport_set_name(gp, "ESS1371 Gameport");
|
|
|
|
- gameport_set_phys(gp, "isa%04x/gameport0", gpio);
|
|
|
|
- gp->dev.parent = &s->dev->dev;
|
|
|
|
- gp->io = gpio;
|
|
|
|
- s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
s->sctrl = 0;
|
|
s->sctrl = 0;
|
|
cssr = 0;
|
|
cssr = 0;
|
|
s->spdif_volume = -1;
|
|
s->spdif_volume = -1;
|
|
@@ -2968,9 +3009,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
|
|
/* turn on S/PDIF output driver if requested */
|
|
/* turn on S/PDIF output driver if requested */
|
|
outl(cssr, s->io+ES1371_REG_STATUS);
|
|
outl(cssr, s->io+ES1371_REG_STATUS);
|
|
|
|
|
|
- /* register gameport */
|
|
|
|
- if (s->gameport)
|
|
|
|
- gameport_register_port(s->gameport);
|
|
|
|
|
|
+ es1371_register_gameport(s);
|
|
|
|
|
|
/* store it in the driver field */
|
|
/* store it in the driver field */
|
|
pci_set_drvdata(pcidev, s);
|
|
pci_set_drvdata(pcidev, s);
|
|
@@ -2979,13 +3018,9 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
|
|
/* increment devindex */
|
|
/* increment devindex */
|
|
if (devindex < NR_DEVICE-1)
|
|
if (devindex < NR_DEVICE-1)
|
|
devindex++;
|
|
devindex++;
|
|
- return 0;
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
err_gp:
|
|
err_gp:
|
|
- if (s->gameport) {
|
|
|
|
- release_region(s->gameport->io, JOY_EXTENT);
|
|
|
|
- gameport_free_port(s->gameport);
|
|
|
|
- }
|
|
|
|
#ifdef ES1371_DEBUG
|
|
#ifdef ES1371_DEBUG
|
|
if (s->ps)
|
|
if (s->ps)
|
|
remove_proc_entry("es1371", NULL);
|
|
remove_proc_entry("es1371", NULL);
|
|
@@ -3024,11 +3059,7 @@ static void __devexit es1371_remove(struct pci_dev *dev)
|
|
outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
|
|
outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
|
|
synchronize_irq(s->irq);
|
|
synchronize_irq(s->irq);
|
|
free_irq(s->irq, s);
|
|
free_irq(s->irq, s);
|
|
- if (s->gameport) {
|
|
|
|
- int gpio = s->gameport->io;
|
|
|
|
- gameport_unregister_port(s->gameport);
|
|
|
|
- release_region(gpio, JOY_EXTENT);
|
|
|
|
- }
|
|
|
|
|
|
+ es1371_unregister_gameport(s);
|
|
release_region(s->io, ES1371_EXTENT);
|
|
release_region(s->io, ES1371_EXTENT);
|
|
unregister_sound_dsp(s->dev_audio);
|
|
unregister_sound_dsp(s->dev_audio);
|
|
unregister_sound_mixer(s->codec->dev_mixer);
|
|
unregister_sound_mixer(s->codec->dev_mixer);
|