aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/rme9652/hdsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/rme9652/hdsp.c')
-rw-r--r--sound/pci/rme9652/hdsp.c462
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
672static int hdsp_check_for_iobox (struct hdsp *hdsp) 675static 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
683static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, 696static 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, \
1682static 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
1687static 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
1699static 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
1707static 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) \ 1725static 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
1728static 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
1733static int hdsp_set_spdif_professional(struct hdsp *hdsp, int val) 1730static 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
1743static 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
1751static 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
1772static int hdsp_spdif_emphasis(struct hdsp *hdsp) 1743static 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
1777static 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
1787static 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
1795static 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
1816static int hdsp_spdif_nonaudio(struct hdsp *hdsp)
1817{
1818 return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0;
1819}
1820
1821static 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
1831static 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
1839static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1755static 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
2463static int hdsp_xlr_breakout_cable(struct hdsp *hdsp)
2464{
2465 if (hdsp->control_register & HDSP_XLRBreakoutCable)
2466 return 1;
2467 return 0;
2468}
2469
2470static 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
2482static 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
2490static 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
2519static int hdsp_aeb(struct hdsp *hdsp)
2520{
2521 if (hdsp->control_register & HDSP_AnalogExtensionBoard)
2522 return 1;
2523 return 0;
2524}
2525
2526static 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
2538static 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
2546static 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
2759static int hdsp_line_out(struct hdsp *hdsp)
2760{
2761 return (hdsp->control_register & HDSP_LineOut) ? 1 : 0;
2762}
2763
2764static 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
2776static 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
2786static 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[] = {
3190HDSP_DA_GAIN("DA Gain", 0), 2949HDSP_DA_GAIN("DA Gain", 0),
3191HDSP_AD_GAIN("AD Gain", 0), 2950HDSP_AD_GAIN("AD Gain", 0),
3192HDSP_PHONE_GAIN("Phones Gain", 0), 2951HDSP_PHONE_GAIN("Phones Gain", 0),
3193HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), 2952HDSP_TOGGLE_SETTING("XLR Breakout Cable", HDSP_XLRBreakoutCable),
3194HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) 2953HDSP_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},
3233HDSP_MIXER("Mixer", 0), 2992HDSP_MIXER("Mixer", 0),
3234HDSP_SPDIF_IN("IEC958 Input Connector", 0), 2993HDSP_SPDIF_IN("IEC958 Input Connector", 0),
3235HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0), 2994HDSP_TOGGLE_SETTING("IEC958 Output also on ADAT1", HDSP_SPDIFOpticalOut),
3236HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0), 2995HDSP_TOGGLE_SETTING("IEC958 Professional Bit", HDSP_SPDIFProfessional),
3237HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), 2996HDSP_TOGGLE_SETTING("IEC958 Emphasis Bit", HDSP_SPDIFEmphasis),
3238HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), 2997HDSP_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 */
3240HDSP_CLOCK_SOURCE("Sample Clock Source", 0), 2999HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
3241{ 3000{
@@ -3255,7 +3014,7 @@ HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
3255HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0), 3014HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0),
3256HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0), 3015HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0),
3257HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), 3016HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0),
3258HDSP_LINE_OUT("Line Out", 0), 3017HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut),
3259HDSP_PRECISE_POINTER("Precise Pointer", 0), 3018HDSP_PRECISE_POINTER("Precise Pointer", 0),
3260HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), 3019HDSP_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
3575static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); 3334static struct snd_kcontrol_new snd_hdsp_96xx_aeb =
3335 HDSP_TOGGLE_SETTING("Analog Extension Board",
3336 HDSP_AnalogExtensionBoard);
3576static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; 3337static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
3577 3338
3578static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) 3339static 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;