aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/es1371.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/es1371.c')
-rw-r--r--sound/oss/es1371.c95
1 files changed, 63 insertions, 32 deletions
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
index a50fddaeea21..c38ae1eca25f 100644
--- a/sound/oss/es1371.c
+++ b/sound/oss/es1371.c
@@ -133,6 +133,10 @@
133#include <asm/page.h> 133#include <asm/page.h>
134#include <asm/uaccess.h> 134#include <asm/uaccess.h>
135 135
136#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
137#define SUPPORT_JOYSTICK
138#endif
139
136/* --------------------------------------------------------------------- */ 140/* --------------------------------------------------------------------- */
137 141
138#undef OSS_DOCUMENTED_MIXER_SEMANTICS 142#undef OSS_DOCUMENTED_MIXER_SEMANTICS
@@ -453,7 +457,10 @@ struct es1371_state {
453 unsigned char obuf[MIDIOUTBUF]; 457 unsigned char obuf[MIDIOUTBUF];
454 } midi; 458 } midi;
455 459
460#ifdef SUPPORT_JOYSTICK
456 struct gameport *gameport; 461 struct gameport *gameport;
462#endif
463
457 struct semaphore sem; 464 struct semaphore sem;
458}; 465};
459 466
@@ -2786,12 +2793,63 @@ static struct
2786 { PCI_ANY_ID, PCI_ANY_ID } 2793 { PCI_ANY_ID, PCI_ANY_ID }
2787}; 2794};
2788 2795
2796#ifdef SUPPORT_JOYSTICK
2797
2798static int __devinit es1371_register_gameport(struct es1371_state *s)
2799{
2800 struct gameport *gp;
2801 int gpio;
2802
2803 for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
2804 if (request_region(gpio, JOY_EXTENT, "es1371"))
2805 break;
2806
2807 if (gpio < 0x200) {
2808 printk(KERN_ERR PFX "no free joystick address found\n");
2809 return -EBUSY;
2810 }
2811
2812 s->gameport = gp = gameport_allocate_port();
2813 if (!gp) {
2814 printk(KERN_ERR PFX "can not allocate memory for gameport\n");
2815 release_region(gpio, JOY_EXTENT);
2816 return -ENOMEM;
2817 }
2818
2819 gameport_set_name(gp, "ESS1371 Gameport");
2820 gameport_set_phys(gp, "isa%04x/gameport0", gpio);
2821 gp->dev.parent = &s->dev->dev;
2822 gp->io = gpio;
2823
2824 s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
2825 outl(s->ctrl, s->io + ES1371_REG_CONTROL);
2826
2827 gameport_register_port(gp);
2828
2829 return 0;
2830}
2831
2832static inline void es1371_unregister_gameport(struct es1371_state *s)
2833{
2834 if (s->gameport) {
2835 int gpio = s->gameport->io;
2836 gameport_unregister_port(s->gameport);
2837 release_region(gpio, JOY_EXTENT);
2838
2839 }
2840}
2841
2842#else
2843static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; }
2844static inline void es1371_unregister_gameport(struct es1371_state *s) { }
2845#endif /* SUPPORT_JOYSTICK */
2846
2847
2789static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) 2848static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
2790{ 2849{
2791 struct es1371_state *s; 2850 struct es1371_state *s;
2792 struct gameport *gp;
2793 mm_segment_t fs; 2851 mm_segment_t fs;
2794 int i, gpio, val, res = -1; 2852 int i, val, res = -1;
2795 int idx; 2853 int idx;
2796 unsigned long tmo; 2854 unsigned long tmo;
2797 signed long tmo2; 2855 signed long tmo2;
@@ -2882,23 +2940,6 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
2882 } 2940 }
2883 } 2941 }
2884 2942
2885 for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
2886 if (request_region(gpio, JOY_EXTENT, "es1371"))
2887 break;
2888
2889 if (gpio < 0x200) {
2890 printk(KERN_ERR PFX "no free joystick address found\n");
2891 } else if (!(s->gameport = gp = gameport_allocate_port())) {
2892 printk(KERN_ERR PFX "can not allocate memory for gameport\n");
2893 release_region(gpio, JOY_EXTENT);
2894 } else {
2895 gameport_set_name(gp, "ESS1371 Gameport");
2896 gameport_set_phys(gp, "isa%04x/gameport0", gpio);
2897 gp->dev.parent = &s->dev->dev;
2898 gp->io = gpio;
2899 s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
2900 }
2901
2902 s->sctrl = 0; 2943 s->sctrl = 0;
2903 cssr = 0; 2944 cssr = 0;
2904 s->spdif_volume = -1; 2945 s->spdif_volume = -1;
@@ -2968,9 +3009,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
2968 /* turn on S/PDIF output driver if requested */ 3009 /* turn on S/PDIF output driver if requested */
2969 outl(cssr, s->io+ES1371_REG_STATUS); 3010 outl(cssr, s->io+ES1371_REG_STATUS);
2970 3011
2971 /* register gameport */ 3012 es1371_register_gameport(s);
2972 if (s->gameport)
2973 gameport_register_port(s->gameport);
2974 3013
2975 /* store it in the driver field */ 3014 /* store it in the driver field */
2976 pci_set_drvdata(pcidev, s); 3015 pci_set_drvdata(pcidev, s);
@@ -2979,13 +3018,9 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
2979 /* increment devindex */ 3018 /* increment devindex */
2980 if (devindex < NR_DEVICE-1) 3019 if (devindex < NR_DEVICE-1)
2981 devindex++; 3020 devindex++;
2982 return 0; 3021 return 0;
2983 3022
2984 err_gp: 3023 err_gp:
2985 if (s->gameport) {
2986 release_region(s->gameport->io, JOY_EXTENT);
2987 gameport_free_port(s->gameport);
2988 }
2989#ifdef ES1371_DEBUG 3024#ifdef ES1371_DEBUG
2990 if (s->ps) 3025 if (s->ps)
2991 remove_proc_entry("es1371", NULL); 3026 remove_proc_entry("es1371", NULL);
@@ -3024,11 +3059,7 @@ static void __devexit es1371_remove(struct pci_dev *dev)
3024 outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */ 3059 outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
3025 synchronize_irq(s->irq); 3060 synchronize_irq(s->irq);
3026 free_irq(s->irq, s); 3061 free_irq(s->irq, s);
3027 if (s->gameport) { 3062 es1371_unregister_gameport(s);
3028 int gpio = s->gameport->io;
3029 gameport_unregister_port(s->gameport);
3030 release_region(gpio, JOY_EXTENT);
3031 }
3032 release_region(s->io, ES1371_EXTENT); 3063 release_region(s->io, ES1371_EXTENT);
3033 unregister_sound_dsp(s->dev_audio); 3064 unregister_sound_dsp(s->dev_audio);
3034 unregister_sound_mixer(s->codec->dev_mixer); 3065 unregister_sound_mixer(s->codec->dev_mixer);