diff options
Diffstat (limited to 'sound/pci/maestro3.c')
-rw-r--r-- | sound/pci/maestro3.c | 139 |
1 files changed, 133 insertions, 6 deletions
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index b56e33676780..3c40d726b46e 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 |
@@ -1598,18 +1605,32 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s) | |||
1598 | } | 1605 | } |
1599 | } | 1606 | } |
1600 | 1607 | ||
1608 | /* The m3's hardware volume works by incrementing / decrementing 2 counters | ||
1609 | (without wrap around) in response to volume button presses and then | ||
1610 | generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7 | ||
1611 | of a byte wide register. The meaning of bits 0 and 4 is unknown. */ | ||
1601 | static void snd_m3_update_hw_volume(unsigned long private_data) | 1612 | static void snd_m3_update_hw_volume(unsigned long private_data) |
1602 | { | 1613 | { |
1603 | struct snd_m3 *chip = (struct snd_m3 *) private_data; | 1614 | struct snd_m3 *chip = (struct snd_m3 *) private_data; |
1604 | int x, val; | 1615 | int x, val; |
1616 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1605 | unsigned long flags; | 1617 | unsigned long flags; |
1618 | #endif | ||
1606 | 1619 | ||
1607 | /* Figure out which volume control button was pushed, | 1620 | /* Figure out which volume control button was pushed, |
1608 | based on differences from the default register | 1621 | based on differences from the default register |
1609 | values. */ | 1622 | values. */ |
1610 | x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee; | 1623 | x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee; |
1611 | 1624 | ||
1612 | /* Reset the volume control registers. */ | 1625 | /* Reset the volume counters to 4. Tests on the allegro integrated |
1626 | into a Compaq N600C laptop, have revealed that: | ||
1627 | 1) Writing any value will result in the 2 counters being reset to | ||
1628 | 4 so writing 0x88 is not strictly necessary | ||
1629 | 2) Writing to any of the 4 involved registers will reset all 4 | ||
1630 | of them (and reading them always returns the same value for all | ||
1631 | of them) | ||
1632 | It could be that a maestro deviates from this, so leave the code | ||
1633 | as is. */ | ||
1613 | outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE); | 1634 | outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE); |
1614 | outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE); | 1635 | outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE); |
1615 | outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); | 1636 | outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); |
@@ -1620,6 +1641,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1620 | if (chip->in_suspend) | 1641 | if (chip->in_suspend) |
1621 | return; | 1642 | return; |
1622 | 1643 | ||
1644 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1623 | if (!chip->master_switch || !chip->master_volume) | 1645 | if (!chip->master_switch || !chip->master_volume) |
1624 | return; | 1646 | return; |
1625 | 1647 | ||
@@ -1629,7 +1651,9 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1629 | val = chip->ac97->regs[AC97_MASTER_VOL]; | 1651 | val = chip->ac97->regs[AC97_MASTER_VOL]; |
1630 | switch (x) { | 1652 | switch (x) { |
1631 | case 0x88: | 1653 | case 0x88: |
1632 | /* mute */ | 1654 | /* The counters have not changed, yet we've received a HV |
1655 | interrupt. According to tests run by various people this | ||
1656 | happens when pressing the mute button. */ | ||
1633 | val ^= 0x8000; | 1657 | val ^= 0x8000; |
1634 | chip->ac97->regs[AC97_MASTER_VOL] = val; | 1658 | chip->ac97->regs[AC97_MASTER_VOL] = val; |
1635 | outw(val, chip->iobase + CODEC_DATA); | 1659 | outw(val, chip->iobase + CODEC_DATA); |
@@ -1638,7 +1662,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1638 | &chip->master_switch->id); | 1662 | &chip->master_switch->id); |
1639 | break; | 1663 | break; |
1640 | case 0xaa: | 1664 | case 0xaa: |
1641 | /* volume up */ | 1665 | /* counters increased by 1 -> volume up */ |
1642 | if ((val & 0x7f) > 0) | 1666 | if ((val & 0x7f) > 0) |
1643 | val--; | 1667 | val--; |
1644 | if ((val & 0x7f00) > 0) | 1668 | if ((val & 0x7f00) > 0) |
@@ -1650,7 +1674,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1650 | &chip->master_volume->id); | 1674 | &chip->master_volume->id); |
1651 | break; | 1675 | break; |
1652 | case 0x66: | 1676 | case 0x66: |
1653 | /* volume down */ | 1677 | /* counters decreased by 1 -> volume down */ |
1654 | if ((val & 0x7f) < 0x1f) | 1678 | if ((val & 0x7f) < 0x1f) |
1655 | val++; | 1679 | val++; |
1656 | if ((val & 0x7f00) < 0x1f00) | 1680 | if ((val & 0x7f00) < 0x1f00) |
@@ -1663,6 +1687,35 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1663 | break; | 1687 | break; |
1664 | } | 1688 | } |
1665 | 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 | ||
1666 | } | 1719 | } |
1667 | 1720 | ||
1668 | static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) | 1721 | static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) |
@@ -1677,7 +1730,11 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) | |||
1677 | return IRQ_NONE; | 1730 | return IRQ_NONE; |
1678 | 1731 | ||
1679 | 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 | ||
1680 | tasklet_schedule(&chip->hwvol_tq); | 1736 | tasklet_schedule(&chip->hwvol_tq); |
1737 | #endif | ||
1681 | 1738 | ||
1682 | /* | 1739 | /* |
1683 | * ack an assp int if its running | 1740 | * ack an assp int if its running |
@@ -1943,18 +2000,24 @@ static unsigned short | |||
1943 | snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | 2000 | snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) |
1944 | { | 2001 | { |
1945 | struct snd_m3 *chip = ac97->private_data; | 2002 | struct snd_m3 *chip = ac97->private_data; |
2003 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1946 | unsigned long flags; | 2004 | unsigned long flags; |
2005 | #endif | ||
1947 | unsigned short data = 0xffff; | 2006 | unsigned short data = 0xffff; |
1948 | 2007 | ||
1949 | if (snd_m3_ac97_wait(chip)) | 2008 | if (snd_m3_ac97_wait(chip)) |
1950 | goto fail; | 2009 | goto fail; |
2010 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1951 | spin_lock_irqsave(&chip->ac97_lock, flags); | 2011 | spin_lock_irqsave(&chip->ac97_lock, flags); |
2012 | #endif | ||
1952 | snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); | 2013 | snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); |
1953 | if (snd_m3_ac97_wait(chip)) | 2014 | if (snd_m3_ac97_wait(chip)) |
1954 | goto fail_unlock; | 2015 | goto fail_unlock; |
1955 | data = snd_m3_inw(chip, CODEC_DATA); | 2016 | data = snd_m3_inw(chip, CODEC_DATA); |
1956 | fail_unlock: | 2017 | fail_unlock: |
2018 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1957 | spin_unlock_irqrestore(&chip->ac97_lock, flags); | 2019 | spin_unlock_irqrestore(&chip->ac97_lock, flags); |
2020 | #endif | ||
1958 | fail: | 2021 | fail: |
1959 | return data; | 2022 | return data; |
1960 | } | 2023 | } |
@@ -1963,14 +2026,20 @@ static void | |||
1963 | 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) |
1964 | { | 2027 | { |
1965 | struct snd_m3 *chip = ac97->private_data; | 2028 | struct snd_m3 *chip = ac97->private_data; |
2029 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1966 | unsigned long flags; | 2030 | unsigned long flags; |
2031 | #endif | ||
1967 | 2032 | ||
1968 | if (snd_m3_ac97_wait(chip)) | 2033 | if (snd_m3_ac97_wait(chip)) |
1969 | return; | 2034 | return; |
2035 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1970 | spin_lock_irqsave(&chip->ac97_lock, flags); | 2036 | spin_lock_irqsave(&chip->ac97_lock, flags); |
2037 | #endif | ||
1971 | snd_m3_outw(chip, val, CODEC_DATA); | 2038 | snd_m3_outw(chip, val, CODEC_DATA); |
1972 | snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); | 2039 | snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); |
2040 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
1973 | spin_unlock_irqrestore(&chip->ac97_lock, flags); | 2041 | spin_unlock_irqrestore(&chip->ac97_lock, flags); |
2042 | #endif | ||
1974 | } | 2043 | } |
1975 | 2044 | ||
1976 | 2045 | ||
@@ -2077,7 +2146,9 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2077 | { | 2146 | { |
2078 | struct snd_ac97_bus *pbus; | 2147 | struct snd_ac97_bus *pbus; |
2079 | struct snd_ac97_template ac97; | 2148 | struct snd_ac97_template ac97; |
2149 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2080 | struct snd_ctl_elem_id elem_id; | 2150 | struct snd_ctl_elem_id elem_id; |
2151 | #endif | ||
2081 | int err; | 2152 | int err; |
2082 | static struct snd_ac97_bus_ops ops = { | 2153 | static struct snd_ac97_bus_ops ops = { |
2083 | .write = snd_m3_ac97_write, | 2154 | .write = snd_m3_ac97_write, |
@@ -2097,6 +2168,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2097 | schedule_timeout_uninterruptible(msecs_to_jiffies(100)); | 2168 | schedule_timeout_uninterruptible(msecs_to_jiffies(100)); |
2098 | snd_ac97_write(chip->ac97, AC97_PCM, 0); | 2169 | snd_ac97_write(chip->ac97, AC97_PCM, 0); |
2099 | 2170 | ||
2171 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2100 | memset(&elem_id, 0, sizeof(elem_id)); | 2172 | memset(&elem_id, 0, sizeof(elem_id)); |
2101 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2173 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
2102 | strcpy(elem_id.name, "Master Playback Switch"); | 2174 | strcpy(elem_id.name, "Master Playback Switch"); |
@@ -2105,6 +2177,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2105 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2177 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
2106 | strcpy(elem_id.name, "Master Playback Volume"); | 2178 | strcpy(elem_id.name, "Master Playback Volume"); |
2107 | 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 | ||
2108 | 2181 | ||
2109 | return 0; | 2182 | return 0; |
2110 | } | 2183 | } |
@@ -2370,6 +2443,7 @@ snd_m3_enable_ints(struct snd_m3 *chip) | |||
2370 | val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; | 2443 | val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; |
2371 | if (chip->hv_config & HV_CTRL_ENABLE) | 2444 | if (chip->hv_config & HV_CTRL_ENABLE) |
2372 | val |= HV_INT_ENABLE; | 2445 | val |= HV_INT_ENABLE; |
2446 | outb(val, chip->iobase + HOST_INT_STATUS); | ||
2373 | outw(val, io + HOST_INT_CTRL); | 2447 | outw(val, io + HOST_INT_CTRL); |
2374 | outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, | 2448 | outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, |
2375 | io + ASSP_CONTROL_C); | 2449 | io + ASSP_CONTROL_C); |
@@ -2384,6 +2458,11 @@ static int snd_m3_free(struct snd_m3 *chip) | |||
2384 | struct m3_dma *s; | 2458 | struct m3_dma *s; |
2385 | int i; | 2459 | int i; |
2386 | 2460 | ||
2461 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
2462 | if (chip->input_dev) | ||
2463 | input_unregister_device(chip->input_dev); | ||
2464 | #endif | ||
2465 | |||
2387 | if (chip->substreams) { | 2466 | if (chip->substreams) { |
2388 | spin_lock_irq(&chip->reg_lock); | 2467 | spin_lock_irq(&chip->reg_lock); |
2389 | for (i = 0; i < chip->num_substreams; i++) { | 2468 | for (i = 0; i < chip->num_substreams; i++) { |
@@ -2510,6 +2589,41 @@ static int m3_resume(struct pci_dev *pci) | |||
2510 | } | 2589 | } |
2511 | #endif /* CONFIG_PM */ | 2590 | #endif /* CONFIG_PM */ |
2512 | 2591 | ||
2592 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
2593 | static int __devinit snd_m3_input_register(struct snd_m3 *chip) | ||
2594 | { | ||
2595 | struct input_dev *input_dev; | ||
2596 | int err; | ||
2597 | |||
2598 | input_dev = input_allocate_device(); | ||
2599 | if (!input_dev) | ||
2600 | return -ENOMEM; | ||
2601 | |||
2602 | snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0", | ||
2603 | pci_name(chip->pci)); | ||
2604 | |||
2605 | input_dev->name = chip->card->driver; | ||
2606 | input_dev->phys = chip->phys; | ||
2607 | input_dev->id.bustype = BUS_PCI; | ||
2608 | input_dev->id.vendor = chip->pci->vendor; | ||
2609 | input_dev->id.product = chip->pci->device; | ||
2610 | input_dev->dev.parent = &chip->pci->dev; | ||
2611 | |||
2612 | __set_bit(EV_KEY, input_dev->evbit); | ||
2613 | __set_bit(KEY_MUTE, input_dev->keybit); | ||
2614 | __set_bit(KEY_VOLUMEDOWN, input_dev->keybit); | ||
2615 | __set_bit(KEY_VOLUMEUP, input_dev->keybit); | ||
2616 | |||
2617 | err = input_register_device(input_dev); | ||
2618 | if (err) { | ||
2619 | input_free_device(input_dev); | ||
2620 | return err; | ||
2621 | } | ||
2622 | |||
2623 | chip->input_dev = input_dev; | ||
2624 | return 0; | ||
2625 | } | ||
2626 | #endif /* CONFIG_INPUT */ | ||
2513 | 2627 | ||
2514 | /* | 2628 | /* |
2515 | */ | 2629 | */ |
@@ -2553,7 +2667,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2553 | } | 2667 | } |
2554 | 2668 | ||
2555 | spin_lock_init(&chip->reg_lock); | 2669 | spin_lock_init(&chip->reg_lock); |
2670 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2556 | spin_lock_init(&chip->ac97_lock); | 2671 | spin_lock_init(&chip->ac97_lock); |
2672 | #endif | ||
2557 | 2673 | ||
2558 | switch (pci->device) { | 2674 | switch (pci->device) { |
2559 | case PCI_DEVICE_ID_ESS_ALLEGRO: | 2675 | case PCI_DEVICE_ID_ESS_ALLEGRO: |
@@ -2636,7 +2752,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2636 | 2752 | ||
2637 | snd_m3_hv_init(chip); | 2753 | snd_m3_hv_init(chip); |
2638 | 2754 | ||
2755 | #ifndef CONFIG_SND_MAESTRO3_INPUT | ||
2639 | tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); | 2756 | tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); |
2757 | #endif | ||
2640 | 2758 | ||
2641 | if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, | 2759 | if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, |
2642 | card->driver, chip)) { | 2760 | card->driver, chip)) { |
@@ -2668,7 +2786,16 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2668 | 2786 | ||
2669 | if ((err = snd_m3_pcm(chip, 0)) < 0) | 2787 | if ((err = snd_m3_pcm(chip, 0)) < 0) |
2670 | return err; | 2788 | return err; |
2671 | 2789 | ||
2790 | #ifdef CONFIG_SND_MAESTRO3_INPUT | ||
2791 | if (chip->hv_config & HV_CTRL_ENABLE) { | ||
2792 | err = snd_m3_input_register(chip); | ||
2793 | if (err) | ||
2794 | snd_printk(KERN_WARNING "Input device registration " | ||
2795 | "failed with error %i", err); | ||
2796 | } | ||
2797 | #endif | ||
2798 | |||
2672 | snd_m3_enable_ints(chip); | 2799 | snd_m3_enable_ints(chip); |
2673 | snd_m3_assp_continue(chip); | 2800 | snd_m3_assp_continue(chip); |
2674 | 2801 | ||