Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/dtor/input.git manually
[pandora-kernel.git] / sound / oss / es1371.c
index 9266b77..12a56d5 100644 (file)
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK
+#endif
+
 /* --------------------------------------------------------------------- */
 
 #undef OSS_DOCUMENTED_MIXER_SEMANTICS
@@ -454,7 +458,10 @@ struct es1371_state {
                unsigned char obuf[MIDIOUTBUF];
        } midi;
 
+#ifdef SUPPORT_JOYSTICK
        struct gameport *gameport;
+#endif
+
        struct semaphore sem;
 };
 
@@ -2787,12 +2794,63 @@ static struct
        { 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)
 {
        struct es1371_state *s;
-       struct gameport *gp;
        mm_segment_t fs;
-       int i, gpio, val, res = -1;
+       int i, val, res = -1;
        int idx;
        unsigned long tmo;
        signed long tmo2;
@@ -2883,23 +2941,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;
        cssr = 0;
        s->spdif_volume = -1;
@@ -2969,9 +3010,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
        /* turn on S/PDIF output driver if requested */
        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 */
        pci_set_drvdata(pcidev, s);
@@ -2980,13 +3019,9 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
        /* increment devindex */
        if (devindex < NR_DEVICE-1)
                devindex++;
-               return 0;
+       return 0;
 
  err_gp:
-       if (s->gameport) {
-               release_region(s->gameport->io, JOY_EXTENT);
-               gameport_free_port(s->gameport);
-       }
 #ifdef ES1371_DEBUG
        if (s->ps)
                remove_proc_entry("es1371", NULL);
@@ -3025,11 +3060,7 @@ static void __devexit es1371_remove(struct pci_dev *dev)
        outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
        synchronize_irq(s->irq);
        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);
        unregister_sound_dsp(s->dev_audio);
        unregister_sound_mixer(s->codec->dev_mixer);