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