diff options
Diffstat (limited to 'sound/oss/es1370.c')
-rw-r--r-- | sound/oss/es1370.c | 88 |
1 files changed, 58 insertions, 30 deletions
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c index 886f61c1c34a..8538085086e7 100644 --- a/sound/oss/es1370.c +++ b/sound/oss/es1370.c | |||
@@ -162,6 +162,10 @@ | |||
162 | #include <asm/page.h> | 162 | #include <asm/page.h> |
163 | #include <asm/uaccess.h> | 163 | #include <asm/uaccess.h> |
164 | 164 | ||
165 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
166 | #define SUPPORT_JOYSTICK | ||
167 | #endif | ||
168 | |||
165 | /* --------------------------------------------------------------------- */ | 169 | /* --------------------------------------------------------------------- */ |
166 | 170 | ||
167 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | 171 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS |
@@ -385,7 +389,10 @@ struct es1370_state { | |||
385 | unsigned char obuf[MIDIOUTBUF]; | 389 | unsigned char obuf[MIDIOUTBUF]; |
386 | } midi; | 390 | } midi; |
387 | 391 | ||
392 | #ifdef SUPPORT_JOYSTICK | ||
388 | struct gameport *gameport; | 393 | struct gameport *gameport; |
394 | #endif | ||
395 | |||
389 | struct semaphore sem; | 396 | struct semaphore sem; |
390 | }; | 397 | }; |
391 | 398 | ||
@@ -2554,10 +2561,55 @@ static struct initvol { | |||
2554 | { SOUND_MIXER_WRITE_OGAIN, 0x4040 } | 2561 | { SOUND_MIXER_WRITE_OGAIN, 0x4040 } |
2555 | }; | 2562 | }; |
2556 | 2563 | ||
2564 | #ifdef SUPPORT_JOYSTICK | ||
2565 | |||
2566 | static int __devinit es1370_register_gameport(struct es1370_state *s) | ||
2567 | { | ||
2568 | struct gameport *gp; | ||
2569 | |||
2570 | if (!request_region(0x200, JOY_EXTENT, "es1370")) { | ||
2571 | printk(KERN_ERR "es1370: joystick io port 0x200 in use\n"); | ||
2572 | return -EBUSY; | ||
2573 | } | ||
2574 | |||
2575 | s->gameport = gp = gameport_allocate_port(); | ||
2576 | if (!gp) { | ||
2577 | printk(KERN_ERR "es1370: can not allocate memory for gameport\n"); | ||
2578 | release_region(0x200, JOY_EXTENT); | ||
2579 | return -ENOMEM; | ||
2580 | } | ||
2581 | |||
2582 | gameport_set_name(gp, "ESS1370"); | ||
2583 | gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev)); | ||
2584 | gp->dev.parent = &s->dev->dev; | ||
2585 | gp->io = 0x200; | ||
2586 | |||
2587 | s->ctrl |= CTRL_JYSTK_EN; | ||
2588 | outl(s->ctrl, s->io + ES1370_REG_CONTROL); | ||
2589 | |||
2590 | gameport_register_port(gp); | ||
2591 | |||
2592 | return 0; | ||
2593 | } | ||
2594 | |||
2595 | static inline void es1370_unregister_gameport(struct es1370_state *s) | ||
2596 | { | ||
2597 | if (s->gameport) { | ||
2598 | int gpio = s->gameport->io; | ||
2599 | gameport_unregister_port(s->gameport); | ||
2600 | release_region(gpio, JOY_EXTENT); | ||
2601 | |||
2602 | } | ||
2603 | } | ||
2604 | |||
2605 | #else | ||
2606 | static inline int es1370_register_gameport(struct es1370_state *s) { return -ENOSYS; } | ||
2607 | static inline void es1370_unregister_gameport(struct es1370_state *s) { } | ||
2608 | #endif /* SUPPORT_JOYSTICK */ | ||
2609 | |||
2557 | static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | 2610 | static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) |
2558 | { | 2611 | { |
2559 | struct es1370_state *s; | 2612 | struct es1370_state *s; |
2560 | struct gameport *gp = NULL; | ||
2561 | mm_segment_t fs; | 2613 | mm_segment_t fs; |
2562 | int i, val, ret; | 2614 | int i, val, ret; |
2563 | 2615 | ||
@@ -2606,28 +2658,14 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic | |||
2606 | /* note: setting CTRL_SERR_DIS is reported to break | 2658 | /* note: setting CTRL_SERR_DIS is reported to break |
2607 | * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */ | 2659 | * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */ |
2608 | s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL); | 2660 | s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL); |
2609 | if (!request_region(0x200, JOY_EXTENT, "es1370")) { | ||
2610 | printk(KERN_ERR "es1370: joystick io port 0x200 in use\n"); | ||
2611 | } else if (!(s->gameport = gp = gameport_allocate_port())) { | ||
2612 | printk(KERN_ERR "es1370: can not allocate memory for gameport\n"); | ||
2613 | release_region(0x200, JOY_EXTENT); | ||
2614 | } else { | ||
2615 | gameport_set_name(gp, "ESS1370"); | ||
2616 | gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev)); | ||
2617 | gp->dev.parent = &s->dev->dev; | ||
2618 | gp->io = 0x200; | ||
2619 | s->ctrl |= CTRL_JYSTK_EN; | ||
2620 | } | ||
2621 | if (lineout[devindex]) | 2661 | if (lineout[devindex]) |
2622 | s->ctrl |= CTRL_XCTL0; | 2662 | s->ctrl |= CTRL_XCTL0; |
2623 | if (micbias[devindex]) | 2663 | if (micbias[devindex]) |
2624 | s->ctrl |= CTRL_XCTL1; | 2664 | s->ctrl |= CTRL_XCTL1; |
2625 | s->sctrl = 0; | 2665 | s->sctrl = 0; |
2626 | printk(KERN_INFO "es1370: found adapter at io %#lx irq %u\n" | 2666 | printk(KERN_INFO "es1370: adapter at io %#lx irq %u, line %s, mic impedance %s\n", |
2627 | KERN_INFO "es1370: features: joystick %s, line %s, mic impedance %s\n", | 2667 | s->io, s->irq, (s->ctrl & CTRL_XCTL0) ? "out" : "in", |
2628 | s->io, s->irq, (s->ctrl & CTRL_JYSTK_EN) ? "on" : "off", | 2668 | (s->ctrl & CTRL_XCTL1) ? "1" : "0"); |
2629 | (s->ctrl & CTRL_XCTL0) ? "out" : "in", | ||
2630 | (s->ctrl & CTRL_XCTL1) ? "1" : "0"); | ||
2631 | /* register devices */ | 2669 | /* register devices */ |
2632 | if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0) { | 2670 | if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0) { |
2633 | ret = s->dev_audio; | 2671 | ret = s->dev_audio; |
@@ -2673,9 +2711,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic | |||
2673 | } | 2711 | } |
2674 | set_fs(fs); | 2712 | set_fs(fs); |
2675 | 2713 | ||
2676 | /* register gameport */ | 2714 | es1370_register_gameport(s); |
2677 | if (gp) | ||
2678 | gameport_register_port(gp); | ||
2679 | 2715 | ||
2680 | /* store it in the driver field */ | 2716 | /* store it in the driver field */ |
2681 | pci_set_drvdata(pcidev, s); | 2717 | pci_set_drvdata(pcidev, s); |
@@ -2697,10 +2733,6 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic | |||
2697 | err_dev1: | 2733 | err_dev1: |
2698 | printk(KERN_ERR "es1370: cannot register misc device\n"); | 2734 | printk(KERN_ERR "es1370: cannot register misc device\n"); |
2699 | free_irq(s->irq, s); | 2735 | free_irq(s->irq, s); |
2700 | if (s->gameport) { | ||
2701 | release_region(s->gameport->io, JOY_EXTENT); | ||
2702 | gameport_free_port(s->gameport); | ||
2703 | } | ||
2704 | err_irq: | 2736 | err_irq: |
2705 | release_region(s->io, ES1370_EXTENT); | 2737 | release_region(s->io, ES1370_EXTENT); |
2706 | err_region: | 2738 | err_region: |
@@ -2719,11 +2751,7 @@ static void __devexit es1370_remove(struct pci_dev *dev) | |||
2719 | outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */ | 2751 | outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */ |
2720 | synchronize_irq(s->irq); | 2752 | synchronize_irq(s->irq); |
2721 | free_irq(s->irq, s); | 2753 | free_irq(s->irq, s); |
2722 | if (s->gameport) { | 2754 | es1370_unregister_gameport(s); |
2723 | int gpio = s->gameport->io; | ||
2724 | gameport_unregister_port(s->gameport); | ||
2725 | release_region(gpio, JOY_EXTENT); | ||
2726 | } | ||
2727 | release_region(s->io, ES1370_EXTENT); | 2755 | release_region(s->io, ES1370_EXTENT); |
2728 | unregister_sound_dsp(s->dev_audio); | 2756 | unregister_sound_dsp(s->dev_audio); |
2729 | unregister_sound_mixer(s->dev_mixer); | 2757 | unregister_sound_mixer(s->dev_mixer); |