diff options
Diffstat (limited to 'sound/pci/rme9652/hdsp.c')
-rw-r--r-- | sound/pci/rme9652/hdsp.c | 462 |
1 files changed, 117 insertions, 345 deletions
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 4fae81f21efb..94084cdb130c 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -154,10 +154,13 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); | |||
154 | #define HDSP_BIGENDIAN_MODE 0x200 | 154 | #define HDSP_BIGENDIAN_MODE 0x200 |
155 | #define HDSP_RD_MULTIPLE 0x400 | 155 | #define HDSP_RD_MULTIPLE 0x400 |
156 | #define HDSP_9652_ENABLE_MIXER 0x800 | 156 | #define HDSP_9652_ENABLE_MIXER 0x800 |
157 | #define HDSP_S200 0x800 | ||
158 | #define HDSP_S300 (0x100 | HDSP_S200) /* dummy, purpose of 0x100 unknown */ | ||
159 | #define HDSP_CYCLIC_MODE 0x1000 | ||
157 | #define HDSP_TDO 0x10000000 | 160 | #define HDSP_TDO 0x10000000 |
158 | 161 | ||
159 | #define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0) | 162 | #define HDSP_S_PROGRAM (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0) |
160 | #define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1) | 163 | #define HDSP_S_LOAD (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1) |
161 | 164 | ||
162 | /* Control Register bits */ | 165 | /* Control Register bits */ |
163 | 166 | ||
@@ -671,13 +674,23 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg) | |||
671 | 674 | ||
672 | static int hdsp_check_for_iobox (struct hdsp *hdsp) | 675 | static int hdsp_check_for_iobox (struct hdsp *hdsp) |
673 | { | 676 | { |
677 | int i; | ||
678 | |||
674 | if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; | 679 | if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; |
675 | if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { | 680 | for (i = 0; i < 500; i++) { |
676 | snd_printk("Hammerfall-DSP: no IO box connected!\n"); | 681 | if (0 == (hdsp_read(hdsp, HDSP_statusRegister) & |
677 | hdsp->state &= ~HDSP_FirmwareLoaded; | 682 | HDSP_ConfigError)) { |
678 | return -EIO; | 683 | if (i) { |
684 | snd_printd("Hammerfall-DSP: IO box found after %d ms\n", | ||
685 | (20 * i)); | ||
686 | } | ||
687 | return 0; | ||
688 | } | ||
689 | msleep(20); | ||
679 | } | 690 | } |
680 | return 0; | 691 | snd_printk(KERN_ERR "Hammerfall-DSP: no IO box connected!\n"); |
692 | hdsp->state &= ~HDSP_FirmwareLoaded; | ||
693 | return -EIO; | ||
681 | } | 694 | } |
682 | 695 | ||
683 | static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, | 696 | static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, |
@@ -728,6 +741,7 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { | |||
728 | 741 | ||
729 | if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { | 742 | if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { |
730 | snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n"); | 743 | snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n"); |
744 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); | ||
731 | return -EIO; | 745 | return -EIO; |
732 | } | 746 | } |
733 | 747 | ||
@@ -737,17 +751,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { | |||
737 | hdsp_write(hdsp, HDSP_fifoData, cache[i]); | 751 | hdsp_write(hdsp, HDSP_fifoData, cache[i]); |
738 | if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { | 752 | if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { |
739 | snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); | 753 | snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); |
754 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); | ||
740 | return -EIO; | 755 | return -EIO; |
741 | } | 756 | } |
742 | } | 757 | } |
743 | 758 | ||
744 | ssleep(3); | 759 | hdsp_fifo_wait(hdsp, 3, HDSP_LONG_WAIT); |
745 | 760 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); | |
746 | if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { | ||
747 | snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n"); | ||
748 | return -EIO; | ||
749 | } | ||
750 | 761 | ||
762 | ssleep(3); | ||
751 | #ifdef SNDRV_BIG_ENDIAN | 763 | #ifdef SNDRV_BIG_ENDIAN |
752 | hdsp->control2_register = HDSP_BIGENDIAN_MODE; | 764 | hdsp->control2_register = HDSP_BIGENDIAN_MODE; |
753 | #else | 765 | #else |
@@ -773,24 +785,51 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) | |||
773 | { | 785 | { |
774 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { | 786 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { |
775 | 787 | ||
776 | hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM); | 788 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); |
777 | hdsp_write (hdsp, HDSP_fifoData, 0); | 789 | hdsp_write(hdsp, HDSP_fifoData, 0); |
778 | if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) | ||
779 | return -EIO; | ||
780 | 790 | ||
781 | hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); | 791 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { |
792 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); | ||
793 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | ||
794 | } | ||
795 | |||
796 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM); | ||
782 | hdsp_write (hdsp, HDSP_fifoData, 0); | 797 | hdsp_write (hdsp, HDSP_fifoData, 0); |
798 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { | ||
799 | hdsp->io_type = Multiface; | ||
800 | snd_printk("Hammerfall-DSP: Multiface found\n"); | ||
801 | return 0; | ||
802 | } | ||
783 | 803 | ||
784 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) { | 804 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); |
785 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); | 805 | hdsp_write(hdsp, HDSP_fifoData, 0); |
786 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | 806 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { |
787 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) | ||
788 | hdsp->io_type = RPM; | ||
789 | else | ||
790 | hdsp->io_type = Multiface; | ||
791 | } else { | ||
792 | hdsp->io_type = Digiface; | 807 | hdsp->io_type = Digiface; |
808 | snd_printk("Hammerfall-DSP: Digiface found\n"); | ||
809 | return 0; | ||
793 | } | 810 | } |
811 | |||
812 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); | ||
813 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | ||
814 | hdsp_write(hdsp, HDSP_fifoData, 0); | ||
815 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { | ||
816 | hdsp->io_type = Multiface; | ||
817 | snd_printk("Hammerfall-DSP: Multiface found\n"); | ||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); | ||
822 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | ||
823 | hdsp_write(hdsp, HDSP_fifoData, 0); | ||
824 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { | ||
825 | hdsp->io_type = Multiface; | ||
826 | snd_printk("Hammerfall-DSP: Multiface found\n"); | ||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | hdsp->io_type = RPM; | ||
831 | snd_printk("Hammerfall-DSP: RPM found\n"); | ||
832 | return 0; | ||
794 | } else { | 833 | } else { |
795 | /* firmware was already loaded, get iobox type */ | 834 | /* firmware was already loaded, get iobox type */ |
796 | if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) | 835 | if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) |
@@ -1674,171 +1713,50 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1674 | return change; | 1713 | return change; |
1675 | } | 1714 | } |
1676 | 1715 | ||
1677 | #define HDSP_SPDIF_OUT(xname, xindex) \ | 1716 | #define HDSP_TOGGLE_SETTING(xname, xindex) \ |
1678 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | 1717 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1679 | .info = snd_hdsp_info_spdif_bits, \ | 1718 | .name = xname, \ |
1680 | .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out } | 1719 | .private_value = xindex, \ |
1681 | 1720 | .info = snd_hdsp_info_toggle_setting, \ | |
1682 | static int hdsp_spdif_out(struct hdsp *hdsp) | 1721 | .get = snd_hdsp_get_toggle_setting, \ |
1683 | { | 1722 | .put = snd_hdsp_put_toggle_setting \ |
1684 | return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0; | ||
1685 | } | ||
1686 | |||
1687 | static int hdsp_set_spdif_output(struct hdsp *hdsp, int out) | ||
1688 | { | ||
1689 | if (out) | ||
1690 | hdsp->control_register |= HDSP_SPDIFOpticalOut; | ||
1691 | else | ||
1692 | hdsp->control_register &= ~HDSP_SPDIFOpticalOut; | ||
1693 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
1694 | return 0; | ||
1695 | } | ||
1696 | |||
1697 | #define snd_hdsp_info_spdif_bits snd_ctl_boolean_mono_info | ||
1698 | |||
1699 | static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1700 | { | ||
1701 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1702 | |||
1703 | ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp); | ||
1704 | return 0; | ||
1705 | } | ||
1706 | |||
1707 | static int snd_hdsp_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1708 | { | ||
1709 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1710 | int change; | ||
1711 | unsigned int val; | ||
1712 | |||
1713 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
1714 | return -EBUSY; | ||
1715 | val = ucontrol->value.integer.value[0] & 1; | ||
1716 | spin_lock_irq(&hdsp->lock); | ||
1717 | change = (int)val != hdsp_spdif_out(hdsp); | ||
1718 | hdsp_set_spdif_output(hdsp, val); | ||
1719 | spin_unlock_irq(&hdsp->lock); | ||
1720 | return change; | ||
1721 | } | 1723 | } |
1722 | 1724 | ||
1723 | #define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \ | 1725 | static int hdsp_toggle_setting(struct hdsp *hdsp, u32 regmask) |
1724 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
1725 | .info = snd_hdsp_info_spdif_bits, \ | ||
1726 | .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional } | ||
1727 | |||
1728 | static int hdsp_spdif_professional(struct hdsp *hdsp) | ||
1729 | { | 1726 | { |
1730 | return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0; | 1727 | return (hdsp->control_register & regmask) ? 1 : 0; |
1731 | } | 1728 | } |
1732 | 1729 | ||
1733 | static int hdsp_set_spdif_professional(struct hdsp *hdsp, int val) | 1730 | static int hdsp_set_toggle_setting(struct hdsp *hdsp, u32 regmask, int out) |
1734 | { | 1731 | { |
1735 | if (val) | 1732 | if (out) |
1736 | hdsp->control_register |= HDSP_SPDIFProfessional; | 1733 | hdsp->control_register |= regmask; |
1737 | else | 1734 | else |
1738 | hdsp->control_register &= ~HDSP_SPDIFProfessional; | 1735 | hdsp->control_register &= ~regmask; |
1739 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | 1736 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); |
1740 | return 0; | ||
1741 | } | ||
1742 | |||
1743 | static int snd_hdsp_get_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1744 | { | ||
1745 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1746 | 1737 | ||
1747 | ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp); | ||
1748 | return 0; | 1738 | return 0; |
1749 | } | 1739 | } |
1750 | 1740 | ||
1751 | static int snd_hdsp_put_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1741 | #define snd_hdsp_info_toggle_setting snd_ctl_boolean_mono_info |
1752 | { | ||
1753 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1754 | int change; | ||
1755 | unsigned int val; | ||
1756 | |||
1757 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
1758 | return -EBUSY; | ||
1759 | val = ucontrol->value.integer.value[0] & 1; | ||
1760 | spin_lock_irq(&hdsp->lock); | ||
1761 | change = (int)val != hdsp_spdif_professional(hdsp); | ||
1762 | hdsp_set_spdif_professional(hdsp, val); | ||
1763 | spin_unlock_irq(&hdsp->lock); | ||
1764 | return change; | ||
1765 | } | ||
1766 | |||
1767 | #define HDSP_SPDIF_EMPHASIS(xname, xindex) \ | ||
1768 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
1769 | .info = snd_hdsp_info_spdif_bits, \ | ||
1770 | .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis } | ||
1771 | 1742 | ||
1772 | static int hdsp_spdif_emphasis(struct hdsp *hdsp) | 1743 | static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol, |
1773 | { | 1744 | struct snd_ctl_elem_value *ucontrol) |
1774 | return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0; | ||
1775 | } | ||
1776 | |||
1777 | static int hdsp_set_spdif_emphasis(struct hdsp *hdsp, int val) | ||
1778 | { | ||
1779 | if (val) | ||
1780 | hdsp->control_register |= HDSP_SPDIFEmphasis; | ||
1781 | else | ||
1782 | hdsp->control_register &= ~HDSP_SPDIFEmphasis; | ||
1783 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
1784 | return 0; | ||
1785 | } | ||
1786 | |||
1787 | static int snd_hdsp_get_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1788 | { | 1745 | { |
1789 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 1746 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
1747 | u32 regmask = kcontrol->private_value; | ||
1790 | 1748 | ||
1791 | ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp); | ||
1792 | return 0; | ||
1793 | } | ||
1794 | |||
1795 | static int snd_hdsp_put_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1796 | { | ||
1797 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1798 | int change; | ||
1799 | unsigned int val; | ||
1800 | |||
1801 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
1802 | return -EBUSY; | ||
1803 | val = ucontrol->value.integer.value[0] & 1; | ||
1804 | spin_lock_irq(&hdsp->lock); | 1749 | spin_lock_irq(&hdsp->lock); |
1805 | change = (int)val != hdsp_spdif_emphasis(hdsp); | 1750 | ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask); |
1806 | hdsp_set_spdif_emphasis(hdsp, val); | ||
1807 | spin_unlock_irq(&hdsp->lock); | 1751 | spin_unlock_irq(&hdsp->lock); |
1808 | return change; | ||
1809 | } | ||
1810 | |||
1811 | #define HDSP_SPDIF_NON_AUDIO(xname, xindex) \ | ||
1812 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
1813 | .info = snd_hdsp_info_spdif_bits, \ | ||
1814 | .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio } | ||
1815 | |||
1816 | static int hdsp_spdif_nonaudio(struct hdsp *hdsp) | ||
1817 | { | ||
1818 | return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0; | ||
1819 | } | ||
1820 | |||
1821 | static int hdsp_set_spdif_nonaudio(struct hdsp *hdsp, int val) | ||
1822 | { | ||
1823 | if (val) | ||
1824 | hdsp->control_register |= HDSP_SPDIFNonAudio; | ||
1825 | else | ||
1826 | hdsp->control_register &= ~HDSP_SPDIFNonAudio; | ||
1827 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
1828 | return 0; | ||
1829 | } | ||
1830 | |||
1831 | static int snd_hdsp_get_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1832 | { | ||
1833 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1834 | |||
1835 | ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp); | ||
1836 | return 0; | 1752 | return 0; |
1837 | } | 1753 | } |
1838 | 1754 | ||
1839 | static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1755 | static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol, |
1756 | struct snd_ctl_elem_value *ucontrol) | ||
1840 | { | 1757 | { |
1841 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 1758 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
1759 | u32 regmask = kcontrol->private_value; | ||
1842 | int change; | 1760 | int change; |
1843 | unsigned int val; | 1761 | unsigned int val; |
1844 | 1762 | ||
@@ -1846,8 +1764,9 @@ static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd | |||
1846 | return -EBUSY; | 1764 | return -EBUSY; |
1847 | val = ucontrol->value.integer.value[0] & 1; | 1765 | val = ucontrol->value.integer.value[0] & 1; |
1848 | spin_lock_irq(&hdsp->lock); | 1766 | spin_lock_irq(&hdsp->lock); |
1849 | change = (int)val != hdsp_spdif_nonaudio(hdsp); | 1767 | change = (int) val != hdsp_toggle_setting(hdsp, regmask); |
1850 | hdsp_set_spdif_nonaudio(hdsp, val); | 1768 | if (change) |
1769 | hdsp_set_toggle_setting(hdsp, regmask, val); | ||
1851 | spin_unlock_irq(&hdsp->lock); | 1770 | spin_unlock_irq(&hdsp->lock); |
1852 | return change; | 1771 | return change; |
1853 | } | 1772 | } |
@@ -2451,114 +2370,6 @@ static int snd_hdsp_put_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
2451 | return change; | 2370 | return change; |
2452 | } | 2371 | } |
2453 | 2372 | ||
2454 | #define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \ | ||
2455 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2456 | .name = xname, \ | ||
2457 | .index = xindex, \ | ||
2458 | .info = snd_hdsp_info_xlr_breakout_cable, \ | ||
2459 | .get = snd_hdsp_get_xlr_breakout_cable, \ | ||
2460 | .put = snd_hdsp_put_xlr_breakout_cable \ | ||
2461 | } | ||
2462 | |||
2463 | static int hdsp_xlr_breakout_cable(struct hdsp *hdsp) | ||
2464 | { | ||
2465 | if (hdsp->control_register & HDSP_XLRBreakoutCable) | ||
2466 | return 1; | ||
2467 | return 0; | ||
2468 | } | ||
2469 | |||
2470 | static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode) | ||
2471 | { | ||
2472 | if (mode) | ||
2473 | hdsp->control_register |= HDSP_XLRBreakoutCable; | ||
2474 | else | ||
2475 | hdsp->control_register &= ~HDSP_XLRBreakoutCable; | ||
2476 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
2477 | return 0; | ||
2478 | } | ||
2479 | |||
2480 | #define snd_hdsp_info_xlr_breakout_cable snd_ctl_boolean_mono_info | ||
2481 | |||
2482 | static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2483 | { | ||
2484 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2485 | |||
2486 | ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp); | ||
2487 | return 0; | ||
2488 | } | ||
2489 | |||
2490 | static int snd_hdsp_put_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2491 | { | ||
2492 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2493 | int change; | ||
2494 | int val; | ||
2495 | |||
2496 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
2497 | return -EBUSY; | ||
2498 | val = ucontrol->value.integer.value[0] & 1; | ||
2499 | spin_lock_irq(&hdsp->lock); | ||
2500 | change = (int)val != hdsp_xlr_breakout_cable(hdsp); | ||
2501 | hdsp_set_xlr_breakout_cable(hdsp, val); | ||
2502 | spin_unlock_irq(&hdsp->lock); | ||
2503 | return change; | ||
2504 | } | ||
2505 | |||
2506 | /* (De)activates old RME Analog Extension Board | ||
2507 | These are connected to the internal ADAT connector | ||
2508 | Switching this on desactivates external ADAT | ||
2509 | */ | ||
2510 | #define HDSP_AEB(xname, xindex) \ | ||
2511 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2512 | .name = xname, \ | ||
2513 | .index = xindex, \ | ||
2514 | .info = snd_hdsp_info_aeb, \ | ||
2515 | .get = snd_hdsp_get_aeb, \ | ||
2516 | .put = snd_hdsp_put_aeb \ | ||
2517 | } | ||
2518 | |||
2519 | static int hdsp_aeb(struct hdsp *hdsp) | ||
2520 | { | ||
2521 | if (hdsp->control_register & HDSP_AnalogExtensionBoard) | ||
2522 | return 1; | ||
2523 | return 0; | ||
2524 | } | ||
2525 | |||
2526 | static int hdsp_set_aeb(struct hdsp *hdsp, int mode) | ||
2527 | { | ||
2528 | if (mode) | ||
2529 | hdsp->control_register |= HDSP_AnalogExtensionBoard; | ||
2530 | else | ||
2531 | hdsp->control_register &= ~HDSP_AnalogExtensionBoard; | ||
2532 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
2533 | return 0; | ||
2534 | } | ||
2535 | |||
2536 | #define snd_hdsp_info_aeb snd_ctl_boolean_mono_info | ||
2537 | |||
2538 | static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2539 | { | ||
2540 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2541 | |||
2542 | ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp); | ||
2543 | return 0; | ||
2544 | } | ||
2545 | |||
2546 | static int snd_hdsp_put_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2547 | { | ||
2548 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2549 | int change; | ||
2550 | int val; | ||
2551 | |||
2552 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
2553 | return -EBUSY; | ||
2554 | val = ucontrol->value.integer.value[0] & 1; | ||
2555 | spin_lock_irq(&hdsp->lock); | ||
2556 | change = (int)val != hdsp_aeb(hdsp); | ||
2557 | hdsp_set_aeb(hdsp, val); | ||
2558 | spin_unlock_irq(&hdsp->lock); | ||
2559 | return change; | ||
2560 | } | ||
2561 | |||
2562 | #define HDSP_PREF_SYNC_REF(xname, xindex) \ | 2373 | #define HDSP_PREF_SYNC_REF(xname, xindex) \ |
2563 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2374 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2564 | .name = xname, \ | 2375 | .name = xname, \ |
@@ -2747,58 +2558,6 @@ static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_c | |||
2747 | return 0; | 2558 | return 0; |
2748 | } | 2559 | } |
2749 | 2560 | ||
2750 | #define HDSP_LINE_OUT(xname, xindex) \ | ||
2751 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2752 | .name = xname, \ | ||
2753 | .index = xindex, \ | ||
2754 | .info = snd_hdsp_info_line_out, \ | ||
2755 | .get = snd_hdsp_get_line_out, \ | ||
2756 | .put = snd_hdsp_put_line_out \ | ||
2757 | } | ||
2758 | |||
2759 | static int hdsp_line_out(struct hdsp *hdsp) | ||
2760 | { | ||
2761 | return (hdsp->control_register & HDSP_LineOut) ? 1 : 0; | ||
2762 | } | ||
2763 | |||
2764 | static int hdsp_set_line_output(struct hdsp *hdsp, int out) | ||
2765 | { | ||
2766 | if (out) | ||
2767 | hdsp->control_register |= HDSP_LineOut; | ||
2768 | else | ||
2769 | hdsp->control_register &= ~HDSP_LineOut; | ||
2770 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
2771 | return 0; | ||
2772 | } | ||
2773 | |||
2774 | #define snd_hdsp_info_line_out snd_ctl_boolean_mono_info | ||
2775 | |||
2776 | static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2777 | { | ||
2778 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2779 | |||
2780 | spin_lock_irq(&hdsp->lock); | ||
2781 | ucontrol->value.integer.value[0] = hdsp_line_out(hdsp); | ||
2782 | spin_unlock_irq(&hdsp->lock); | ||
2783 | return 0; | ||
2784 | } | ||
2785 | |||
2786 | static int snd_hdsp_put_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2787 | { | ||
2788 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2789 | int change; | ||
2790 | unsigned int val; | ||
2791 | |||
2792 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
2793 | return -EBUSY; | ||
2794 | val = ucontrol->value.integer.value[0] & 1; | ||
2795 | spin_lock_irq(&hdsp->lock); | ||
2796 | change = (int)val != hdsp_line_out(hdsp); | ||
2797 | hdsp_set_line_output(hdsp, val); | ||
2798 | spin_unlock_irq(&hdsp->lock); | ||
2799 | return change; | ||
2800 | } | ||
2801 | |||
2802 | #define HDSP_PRECISE_POINTER(xname, xindex) \ | 2561 | #define HDSP_PRECISE_POINTER(xname, xindex) \ |
2803 | { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ | 2562 | { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ |
2804 | .name = xname, \ | 2563 | .name = xname, \ |
@@ -3190,7 +2949,7 @@ static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { | |||
3190 | HDSP_DA_GAIN("DA Gain", 0), | 2949 | HDSP_DA_GAIN("DA Gain", 0), |
3191 | HDSP_AD_GAIN("AD Gain", 0), | 2950 | HDSP_AD_GAIN("AD Gain", 0), |
3192 | HDSP_PHONE_GAIN("Phones Gain", 0), | 2951 | HDSP_PHONE_GAIN("Phones Gain", 0), |
3193 | HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), | 2952 | HDSP_TOGGLE_SETTING("XLR Breakout Cable", HDSP_XLRBreakoutCable), |
3194 | HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) | 2953 | HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) |
3195 | }; | 2954 | }; |
3196 | 2955 | ||
@@ -3232,10 +2991,10 @@ static struct snd_kcontrol_new snd_hdsp_controls[] = { | |||
3232 | }, | 2991 | }, |
3233 | HDSP_MIXER("Mixer", 0), | 2992 | HDSP_MIXER("Mixer", 0), |
3234 | HDSP_SPDIF_IN("IEC958 Input Connector", 0), | 2993 | HDSP_SPDIF_IN("IEC958 Input Connector", 0), |
3235 | HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0), | 2994 | HDSP_TOGGLE_SETTING("IEC958 Output also on ADAT1", HDSP_SPDIFOpticalOut), |
3236 | HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0), | 2995 | HDSP_TOGGLE_SETTING("IEC958 Professional Bit", HDSP_SPDIFProfessional), |
3237 | HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), | 2996 | HDSP_TOGGLE_SETTING("IEC958 Emphasis Bit", HDSP_SPDIFEmphasis), |
3238 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), | 2997 | HDSP_TOGGLE_SETTING("IEC958 Non-audio Bit", HDSP_SPDIFNonAudio), |
3239 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | 2998 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ |
3240 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), | 2999 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), |
3241 | { | 3000 | { |
@@ -3255,7 +3014,7 @@ HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0), | |||
3255 | HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0), | 3014 | HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0), |
3256 | HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0), | 3015 | HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0), |
3257 | HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), | 3016 | HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), |
3258 | HDSP_LINE_OUT("Line Out", 0), | 3017 | HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut), |
3259 | HDSP_PRECISE_POINTER("Precise Pointer", 0), | 3018 | HDSP_PRECISE_POINTER("Precise Pointer", 0), |
3260 | HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), | 3019 | HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), |
3261 | }; | 3020 | }; |
@@ -3572,7 +3331,9 @@ static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { | |||
3572 | HDSP_MIXER("Mixer", 0) | 3331 | HDSP_MIXER("Mixer", 0) |
3573 | }; | 3332 | }; |
3574 | 3333 | ||
3575 | static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); | 3334 | static struct snd_kcontrol_new snd_hdsp_96xx_aeb = |
3335 | HDSP_TOGGLE_SETTING("Analog Extension Board", | ||
3336 | HDSP_AnalogExtensionBoard); | ||
3576 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; | 3337 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; |
3577 | 3338 | ||
3578 | static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) | 3339 | static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) |
@@ -3995,7 +3756,9 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | |||
3995 | } | 3756 | } |
3996 | snd_iprintf(buffer, "Phones Gain : %s\n", tmp); | 3757 | snd_iprintf(buffer, "Phones Gain : %s\n", tmp); |
3997 | 3758 | ||
3998 | snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no"); | 3759 | snd_iprintf(buffer, "XLR Breakout Cable : %s\n", |
3760 | hdsp_toggle_setting(hdsp, HDSP_XLRBreakoutCable) ? | ||
3761 | "yes" : "no"); | ||
3999 | 3762 | ||
4000 | if (hdsp->control_register & HDSP_AnalogExtensionBoard) | 3763 | if (hdsp->control_register & HDSP_AnalogExtensionBoard) |
4001 | snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n"); | 3764 | snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n"); |
@@ -5026,29 +4789,38 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne | |||
5026 | for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) | 4789 | for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) |
5027 | info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); | 4790 | info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); |
5028 | info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); | 4791 | info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); |
5029 | info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); | 4792 | info.spdif_out = (unsigned char)hdsp_toggle_setting(hdsp, |
5030 | info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp); | 4793 | HDSP_SPDIFOpticalOut); |
5031 | info.spdif_emphasis = (unsigned char)hdsp_spdif_emphasis(hdsp); | 4794 | info.spdif_professional = (unsigned char) |
5032 | info.spdif_nonaudio = (unsigned char)hdsp_spdif_nonaudio(hdsp); | 4795 | hdsp_toggle_setting(hdsp, HDSP_SPDIFProfessional); |
4796 | info.spdif_emphasis = (unsigned char) | ||
4797 | hdsp_toggle_setting(hdsp, HDSP_SPDIFEmphasis); | ||
4798 | info.spdif_nonaudio = (unsigned char) | ||
4799 | hdsp_toggle_setting(hdsp, HDSP_SPDIFNonAudio); | ||
5033 | info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp); | 4800 | info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp); |
5034 | info.system_sample_rate = hdsp->system_sample_rate; | 4801 | info.system_sample_rate = hdsp->system_sample_rate; |
5035 | info.autosync_sample_rate = hdsp_external_sample_rate(hdsp); | 4802 | info.autosync_sample_rate = hdsp_external_sample_rate(hdsp); |
5036 | info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp); | 4803 | info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp); |
5037 | info.clock_source = (unsigned char)hdsp_clock_source(hdsp); | 4804 | info.clock_source = (unsigned char)hdsp_clock_source(hdsp); |
5038 | info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp); | 4805 | info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp); |
5039 | info.line_out = (unsigned char)hdsp_line_out(hdsp); | 4806 | info.line_out = (unsigned char) |
4807 | hdsp_toggle_setting(hdsp, HDSP_LineOut); | ||
5040 | if (hdsp->io_type == H9632) { | 4808 | if (hdsp->io_type == H9632) { |
5041 | info.da_gain = (unsigned char)hdsp_da_gain(hdsp); | 4809 | info.da_gain = (unsigned char)hdsp_da_gain(hdsp); |
5042 | info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp); | 4810 | info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp); |
5043 | info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); | 4811 | info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); |
5044 | info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); | 4812 | info.xlr_breakout_cable = |
4813 | (unsigned char)hdsp_toggle_setting(hdsp, | ||
4814 | HDSP_XLRBreakoutCable); | ||
5045 | 4815 | ||
5046 | } else if (hdsp->io_type == RPM) { | 4816 | } else if (hdsp->io_type == RPM) { |
5047 | info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); | 4817 | info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); |
5048 | info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); | 4818 | info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); |
5049 | } | 4819 | } |
5050 | if (hdsp->io_type == H9632 || hdsp->io_type == H9652) | 4820 | if (hdsp->io_type == H9632 || hdsp->io_type == H9652) |
5051 | info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); | 4821 | info.analog_extension_board = |
4822 | (unsigned char)hdsp_toggle_setting(hdsp, | ||
4823 | HDSP_AnalogExtensionBoard); | ||
5052 | spin_unlock_irqrestore(&hdsp->lock, flags); | 4824 | spin_unlock_irqrestore(&hdsp->lock, flags); |
5053 | if (copy_to_user(argp, &info, sizeof(info))) | 4825 | if (copy_to_user(argp, &info, sizeof(info))) |
5054 | return -EFAULT; | 4826 | return -EFAULT; |