diff options
-rw-r--r-- | sound/pci/Kconfig | 10 | ||||
-rw-r--r-- | sound/pci/maestro3.c | 116 |
2 files changed, 124 insertions, 2 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 517ae65ffc8e..ebcf065ad2c2 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -667,6 +667,16 @@ config SND_MAESTRO3 | |||
667 | To compile this driver as a module, choose M here: the module | 667 | To compile this driver as a module, choose M here: the module |
668 | will be called snd-maestro3. | 668 | will be called snd-maestro3. |
669 | 669 | ||
670 | config SND_MAESTRO3_INPUT | ||
671 | bool "Enable input device for maestro3 volume buttons" | ||
672 | depends on SND_MAESTRO3 | ||
673 | depends on INPUT=y || INPUT=SND_MAESTRO3 | ||
674 | help | ||
675 | If you say Y here, you will get an input device which reports | ||
676 | keypresses for the volume buttons connected to the maestro3 chip. | ||
677 | If you say N the buttons will directly control the master volume. | ||
678 | It is recommended to say Y. | ||
679 | |||
670 | config SND_MIXART | 680 | config SND_MIXART |
671 | tristate "Digigram miXart" | 681 | tristate "Digigram miXart" |
672 | select SND_HWDEP | 682 | select SND_HWDEP |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 53d2a5d61baf..217a4dcb259e 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/vmalloc.h> | 41 | #include <linux/vmalloc.h> |
42 | #include <linux/moduleparam.h> | 42 | #include <linux/moduleparam.h> |
43 | #include <linux/firmware.h> | 43 | #include <linux/firmware.h> |
44 | #include <linux/input.h> | ||
44 | #include <sound/core.h> | 45 | #include <sound/core.h> |
45 | #include <sound/info.h> | 46 | #include <sound/info.h> |
46 | #include <sound/control.h> | 47 | #include <sound/control.h> |
@@ -844,11 +845,17 @@ struct snd_m3 { | |||
844 | struct m3_dma *substreams; | 845 | struct m3_dma *substreams; |
845 | 846 | ||
846 | spinlock_t reg_lock; | 847 | spinlock_t reg_lock; |
847 | spinlock_t ac97_lock; | ||
848 | 848 | ||
849 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
850 | struct input_dev *input_dev; | ||
851 | char phys[64]; /* physical device path */ | ||
852 | #else | ||
853 | spinlock_t ac97_lock; | ||
849 | struct snd_kcontrol *master_switch; | 854 | struct snd_kcontrol *master_switch; |
850 | struct snd_kcontrol *master_volume; | 855 | struct snd_kcontrol *master_volume; |
851 | struct tasklet_struct hwvol_tq; | 856 | struct tasklet_struct hwvol_tq; |
857 | #endif | ||
858 | |||
852 | unsigned int in_suspend; | 859 | unsigned int in_suspend; |
853 | 860 | ||
854 | #ifdef CONFIG_PM | 861 | #ifdef CONFIG_PM |
@@ -1606,7 +1613,9 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1606 | { | 1613 | { |
1607 | struct snd_m3 *chip = (struct snd_m3 *) private_data; | 1614 | struct snd_m3 *chip = (struct snd_m3 *) private_data; |
1608 | int x, val; | 1615 | int x, val; |
1616 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1609 | unsigned long flags; | 1617 | unsigned long flags; |
1618 | #endif | ||
1610 | 1619 | ||
1611 | /* Figure out which volume control button was pushed, | 1620 | /* Figure out which volume control button was pushed, |
1612 | based on differences from the default register | 1621 | based on differences from the default register |
@@ -1632,6 +1641,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1632 | if (chip->in_suspend) | 1641 | if (chip->in_suspend) |
1633 | return; | 1642 | return; |
1634 | 1643 | ||
1644 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1635 | if (!chip->master_switch || !chip->master_volume) | 1645 | if (!chip->master_switch || !chip->master_volume) |
1636 | return; | 1646 | return; |
1637 | 1647 | ||
@@ -1677,6 +1687,35 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1677 | break; | 1687 | break; |
1678 | } | 1688 | } |
1679 | spin_unlock_irqrestore(&chip->ac97_lock, flags); | 1689 | spin_unlock_irqrestore(&chip->ac97_lock, flags); |
1690 | #else | ||
1691 | if (!chip->input_dev) | ||
1692 | return; | ||
1693 | |||
1694 | val = 0; | ||
1695 | switch (x) { | ||
1696 | case 0x88: | ||
1697 | /* The counters have not changed, yet we've received a HV | ||
1698 | interrupt. According to tests run by various people this | ||
1699 | happens when pressing the mute button. */ | ||
1700 | val = KEY_MUTE; | ||
1701 | break; | ||
1702 | case 0xaa: | ||
1703 | /* counters increased by 1 -> volume up */ | ||
1704 | val = KEY_VOLUMEUP; | ||
1705 | break; | ||
1706 | case 0x66: | ||
1707 | /* counters decreased by 1 -> volume down */ | ||
1708 | val = KEY_VOLUMEDOWN; | ||
1709 | break; | ||
1710 | } | ||
1711 | |||
1712 | if (val) { | ||
1713 | input_report_key(chip->input_dev, val, 1); | ||
1714 | input_sync(chip->input_dev); | ||
1715 | input_report_key(chip->input_dev, val, 0); | ||
1716 | input_sync(chip->input_dev); | ||
1717 | } | ||
1718 | #endif | ||
1680 | } | 1719 | } |
1681 | 1720 | ||
1682 | static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) | 1721 | static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) |
@@ -1691,7 +1730,11 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) | |||
1691 | return IRQ_NONE; | 1730 | return IRQ_NONE; |
1692 | 1731 | ||
1693 | if (status & HV_INT_PENDING) | 1732 | if (status & HV_INT_PENDING) |
1733 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
1734 | snd_m3_update_hw_volume((unsigned long)chip); | ||
1735 | #else | ||
1694 | tasklet_schedule(&chip->hwvol_tq); | 1736 | tasklet_schedule(&chip->hwvol_tq); |
1737 | #endif | ||
1695 | 1738 | ||
1696 | /* | 1739 | /* |
1697 | * ack an assp int if its running | 1740 | * ack an assp int if its running |
@@ -1957,18 +2000,24 @@ static unsigned short | |||
1957 | snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | 2000 | snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) |
1958 | { | 2001 | { |
1959 | struct snd_m3 *chip = ac97->private_data; | 2002 | struct snd_m3 *chip = ac97->private_data; |
2003 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1960 | unsigned long flags; | 2004 | unsigned long flags; |
2005 | #endif | ||
1961 | unsigned short data = 0xffff; | 2006 | unsigned short data = 0xffff; |
1962 | 2007 | ||
1963 | if (snd_m3_ac97_wait(chip)) | 2008 | if (snd_m3_ac97_wait(chip)) |
1964 | goto fail; | 2009 | goto fail; |
2010 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1965 | spin_lock_irqsave(&chip->ac97_lock, flags); | 2011 | spin_lock_irqsave(&chip->ac97_lock, flags); |
2012 | #endif | ||
1966 | snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); | 2013 | snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); |
1967 | if (snd_m3_ac97_wait(chip)) | 2014 | if (snd_m3_ac97_wait(chip)) |
1968 | goto fail_unlock; | 2015 | goto fail_unlock; |
1969 | data = snd_m3_inw(chip, CODEC_DATA); | 2016 | data = snd_m3_inw(chip, CODEC_DATA); |
1970 | fail_unlock: | 2017 | fail_unlock: |
2018 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1971 | spin_unlock_irqrestore(&chip->ac97_lock, flags); | 2019 | spin_unlock_irqrestore(&chip->ac97_lock, flags); |
2020 | #endif | ||
1972 | fail: | 2021 | fail: |
1973 | return data; | 2022 | return data; |
1974 | } | 2023 | } |
@@ -1977,14 +2026,20 @@ static void | |||
1977 | snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) | 2026 | snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) |
1978 | { | 2027 | { |
1979 | struct snd_m3 *chip = ac97->private_data; | 2028 | struct snd_m3 *chip = ac97->private_data; |
2029 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1980 | unsigned long flags; | 2030 | unsigned long flags; |
2031 | #endif | ||
1981 | 2032 | ||
1982 | if (snd_m3_ac97_wait(chip)) | 2033 | if (snd_m3_ac97_wait(chip)) |
1983 | return; | 2034 | return; |
2035 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1984 | spin_lock_irqsave(&chip->ac97_lock, flags); | 2036 | spin_lock_irqsave(&chip->ac97_lock, flags); |
2037 | #endif | ||
1985 | snd_m3_outw(chip, val, CODEC_DATA); | 2038 | snd_m3_outw(chip, val, CODEC_DATA); |
1986 | snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); | 2039 | snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); |
2040 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1987 | spin_unlock_irqrestore(&chip->ac97_lock, flags); | 2041 | spin_unlock_irqrestore(&chip->ac97_lock, flags); |
2042 | #endif | ||
1988 | } | 2043 | } |
1989 | 2044 | ||
1990 | 2045 | ||
@@ -2091,7 +2146,9 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2091 | { | 2146 | { |
2092 | struct snd_ac97_bus *pbus; | 2147 | struct snd_ac97_bus *pbus; |
2093 | struct snd_ac97_template ac97; | 2148 | struct snd_ac97_template ac97; |
2149 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2094 | struct snd_ctl_elem_id elem_id; | 2150 | struct snd_ctl_elem_id elem_id; |
2151 | #endif | ||
2095 | int err; | 2152 | int err; |
2096 | static struct snd_ac97_bus_ops ops = { | 2153 | static struct snd_ac97_bus_ops ops = { |
2097 | .write = snd_m3_ac97_write, | 2154 | .write = snd_m3_ac97_write, |
@@ -2111,6 +2168,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2111 | schedule_timeout_uninterruptible(msecs_to_jiffies(100)); | 2168 | schedule_timeout_uninterruptible(msecs_to_jiffies(100)); |
2112 | snd_ac97_write(chip->ac97, AC97_PCM, 0); | 2169 | snd_ac97_write(chip->ac97, AC97_PCM, 0); |
2113 | 2170 | ||
2171 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2114 | memset(&elem_id, 0, sizeof(elem_id)); | 2172 | memset(&elem_id, 0, sizeof(elem_id)); |
2115 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2173 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
2116 | strcpy(elem_id.name, "Master Playback Switch"); | 2174 | strcpy(elem_id.name, "Master Playback Switch"); |
@@ -2119,6 +2177,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2119 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2177 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
2120 | strcpy(elem_id.name, "Master Playback Volume"); | 2178 | strcpy(elem_id.name, "Master Playback Volume"); |
2121 | chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); | 2179 | chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); |
2180 | #endif | ||
2122 | 2181 | ||
2123 | return 0; | 2182 | return 0; |
2124 | } | 2183 | } |
@@ -2398,6 +2457,11 @@ static int snd_m3_free(struct snd_m3 *chip) | |||
2398 | struct m3_dma *s; | 2457 | struct m3_dma *s; |
2399 | int i; | 2458 | int i; |
2400 | 2459 | ||
2460 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
2461 | if (chip->input_dev) | ||
2462 | input_unregister_device(chip->input_dev); | ||
2463 | #endif | ||
2464 | |||
2401 | if (chip->substreams) { | 2465 | if (chip->substreams) { |
2402 | spin_lock_irq(&chip->reg_lock); | 2466 | spin_lock_irq(&chip->reg_lock); |
2403 | for (i = 0; i < chip->num_substreams; i++) { | 2467 | for (i = 0; i < chip->num_substreams; i++) { |
@@ -2524,6 +2588,41 @@ static int m3_resume(struct pci_dev *pci) | |||
2524 | } | 2588 | } |
2525 | #endif /* CONFIG_PM */ | 2589 | #endif /* CONFIG_PM */ |
2526 | 2590 | ||
2591 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
2592 | static int __devinit snd_m3_input_register(struct snd_m3 *chip) | ||
2593 | { | ||
2594 | struct input_dev *input_dev; | ||
2595 | int err; | ||
2596 | |||
2597 | input_dev = input_allocate_device(); | ||
2598 | if (!input_dev) | ||
2599 | return -ENOMEM; | ||
2600 | |||
2601 | snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0", | ||
2602 | pci_name(chip->pci)); | ||
2603 | |||
2604 | input_dev->name = chip->card->driver; | ||
2605 | input_dev->phys = chip->phys; | ||
2606 | input_dev->id.bustype = BUS_PCI; | ||
2607 | input_dev->id.vendor = chip->pci->vendor; | ||
2608 | input_dev->id.product = chip->pci->device; | ||
2609 | input_dev->dev.parent = &chip->pci->dev; | ||
2610 | |||
2611 | __set_bit(EV_KEY, input_dev->evbit); | ||
2612 | __set_bit(KEY_MUTE, input_dev->keybit); | ||
2613 | __set_bit(KEY_VOLUMEDOWN, input_dev->keybit); | ||
2614 | __set_bit(KEY_VOLUMEUP, input_dev->keybit); | ||
2615 | |||
2616 | err = input_register_device(input_dev); | ||
2617 | if (err) { | ||
2618 | input_free_device(input_dev); | ||
2619 | return err; | ||
2620 | } | ||
2621 | |||
2622 | chip->input_dev = input_dev; | ||
2623 | return 0; | ||
2624 | } | ||
2625 | #endif /* CONFIG_INPUT */ | ||
2527 | 2626 | ||
2528 | /* | 2627 | /* |
2529 | */ | 2628 | */ |
@@ -2567,7 +2666,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2567 | } | 2666 | } |
2568 | 2667 | ||
2569 | spin_lock_init(&chip->reg_lock); | 2668 | spin_lock_init(&chip->reg_lock); |
2669 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2570 | spin_lock_init(&chip->ac97_lock); | 2670 | spin_lock_init(&chip->ac97_lock); |
2671 | #endif | ||
2571 | 2672 | ||
2572 | switch (pci->device) { | 2673 | switch (pci->device) { |
2573 | case PCI_DEVICE_ID_ESS_ALLEGRO: | 2674 | case PCI_DEVICE_ID_ESS_ALLEGRO: |
@@ -2650,7 +2751,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2650 | 2751 | ||
2651 | snd_m3_hv_init(chip); | 2752 | snd_m3_hv_init(chip); |
2652 | 2753 | ||
2754 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2653 | tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); | 2755 | tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); |
2756 | #endif | ||
2654 | 2757 | ||
2655 | if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, | 2758 | if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, |
2656 | card->driver, chip)) { | 2759 | card->driver, chip)) { |
@@ -2682,7 +2785,16 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2682 | 2785 | ||
2683 | if ((err = snd_m3_pcm(chip, 0)) < 0) | 2786 | if ((err = snd_m3_pcm(chip, 0)) < 0) |
2684 | return err; | 2787 | return err; |
2685 | 2788 | ||
2789 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
2790 | if (chip->hv_config & HV_CTRL_ENABLE) { | ||
2791 | err = snd_m3_input_register(chip); | ||
2792 | if (err) | ||
2793 | snd_printk(KERN_WARNING "Input device registration " | ||
2794 | "failed with error %i", err); | ||
2795 | } | ||
2796 | #endif | ||
2797 | |||
2686 | snd_m3_enable_ints(chip); | 2798 | snd_m3_enable_ints(chip); |
2687 | snd_m3_assp_continue(chip); | 2799 | snd_m3_assp_continue(chip); |
2688 | 2800 | ||