diff options
-rw-r--r-- | sound/oss/es1371.c | 95 |
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 | |||
2798 | static 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 | |||
2832 | static 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 | ||
2843 | static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; } | ||
2844 | static inline void es1371_unregister_gameport(struct es1371_state *s) { } | ||
2845 | #endif /* SUPPORT_JOYSTICK */ | ||
2846 | |||
2847 | |||
2789 | static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | 2848 | static 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); |