hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
kernel/sound/usb/mixer_quirks.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * USB Audio Driver for ALSA
34 *
....@@ -11,24 +12,11 @@
1112 *
1213 * Audio Advantage Micro II support added by:
1314 * Przemek Rudy (prudy1@o2.pl)
14
- *
15
- * This program is free software; you can redistribute it and/or modify
16
- * it under the terms of the GNU General Public License as published by
17
- * the Free Software Foundation; either version 2 of the License, or
18
- * (at your option) any later version.
19
- *
20
- * This program is distributed in the hope that it will be useful,
21
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- * GNU General Public License for more details.
24
- *
25
- * You should have received a copy of the GNU General Public License
26
- * along with this program; if not, write to the Free Software
27
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2815 */
2916
3017 #include <linux/hid.h>
3118 #include <linux/init.h>
19
+#include <linux/math64.h>
3220 #include <linux/slab.h>
3321 #include <linux/usb.h>
3422 #include <linux/usb/audio.h>
....@@ -44,7 +32,9 @@
4432 #include "mixer.h"
4533 #include "mixer_quirks.h"
4634 #include "mixer_scarlett.h"
35
+#include "mixer_scarlett_gen2.h"
4736 #include "mixer_us16x08.h"
37
+#include "mixer_s1810c.h"
4838 #include "helper.h"
4939
5040 struct std_mono_table {
....@@ -520,7 +510,7 @@
520510 list->kctl->private_value);
521511 }
522512
523
-static struct snd_kcontrol_new snd_emu0204_control = {
513
+static const struct snd_kcontrol_new snd_emu0204_control = {
524514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
525515 .name = "Front Jack Channels",
526516 .info = snd_emu0204_ch_switch_info,
....@@ -588,7 +578,7 @@
588578 list->kctl->private_value);
589579 }
590580
591
-static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
581
+static const struct snd_kcontrol_new snd_xonar_u1_output_switch = {
592582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
593583 .name = "Digital Playback Switch",
594584 .info = snd_ctl_boolean_mono_info,
....@@ -715,7 +705,7 @@
715705 return snd_mbox1_switch_update(list->mixer, list->kctl->private_value);
716706 }
717707
718
-static struct snd_kcontrol_new snd_mbox1_switch = {
708
+static const struct snd_kcontrol_new snd_mbox1_switch = {
719709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
720710 .name = "Clock Source",
721711 .index = 0,
....@@ -800,7 +790,7 @@
800790 return err < 0 ? err : 1;
801791 }
802792
803
-static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
793
+static const struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
804794 {
805795 .name = "Direct Thru Channel A",
806796 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
....@@ -819,7 +809,7 @@
819809 },
820810 };
821811
822
-static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
812
+static const struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
823813 {
824814 .name = "Direct Thru Channel A",
825815 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
....@@ -1679,7 +1669,7 @@
16791669 return err < 0 ? err : 1;
16801670 }
16811671
1682
-static struct snd_kcontrol_new snd_microii_mixer_spdif[] = {
1672
+static const struct snd_kcontrol_new snd_microii_mixer_spdif[] = {
16831673 {
16841674 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
16851675 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
....@@ -1786,7 +1776,7 @@
17861776 return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
17871777 }
17881778
1789
-static struct snd_kcontrol_new snd_soundblaster_e1_input_switch = {
1779
+static const struct snd_kcontrol_new snd_soundblaster_e1_input_switch = {
17901780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17911781 .name = "Input Source",
17921782 .info = snd_soundblaster_e1_switch_info,
....@@ -1823,10 +1813,1131 @@
18231813 return 0;
18241814 }
18251815
1816
+/* RME Class Compliant device quirks */
1817
+
1818
+#define SND_RME_GET_STATUS1 23
1819
+#define SND_RME_GET_CURRENT_FREQ 17
1820
+#define SND_RME_CLK_SYSTEM_SHIFT 16
1821
+#define SND_RME_CLK_SYSTEM_MASK 0x1f
1822
+#define SND_RME_CLK_AES_SHIFT 8
1823
+#define SND_RME_CLK_SPDIF_SHIFT 12
1824
+#define SND_RME_CLK_AES_SPDIF_MASK 0xf
1825
+#define SND_RME_CLK_SYNC_SHIFT 6
1826
+#define SND_RME_CLK_SYNC_MASK 0x3
1827
+#define SND_RME_CLK_FREQMUL_SHIFT 18
1828
+#define SND_RME_CLK_FREQMUL_MASK 0x7
1829
+#define SND_RME_CLK_SYSTEM(x) \
1830
+ ((x >> SND_RME_CLK_SYSTEM_SHIFT) & SND_RME_CLK_SYSTEM_MASK)
1831
+#define SND_RME_CLK_AES(x) \
1832
+ ((x >> SND_RME_CLK_AES_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK)
1833
+#define SND_RME_CLK_SPDIF(x) \
1834
+ ((x >> SND_RME_CLK_SPDIF_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK)
1835
+#define SND_RME_CLK_SYNC(x) \
1836
+ ((x >> SND_RME_CLK_SYNC_SHIFT) & SND_RME_CLK_SYNC_MASK)
1837
+#define SND_RME_CLK_FREQMUL(x) \
1838
+ ((x >> SND_RME_CLK_FREQMUL_SHIFT) & SND_RME_CLK_FREQMUL_MASK)
1839
+#define SND_RME_CLK_AES_LOCK 0x1
1840
+#define SND_RME_CLK_AES_SYNC 0x4
1841
+#define SND_RME_CLK_SPDIF_LOCK 0x2
1842
+#define SND_RME_CLK_SPDIF_SYNC 0x8
1843
+#define SND_RME_SPDIF_IF_SHIFT 4
1844
+#define SND_RME_SPDIF_FORMAT_SHIFT 5
1845
+#define SND_RME_BINARY_MASK 0x1
1846
+#define SND_RME_SPDIF_IF(x) \
1847
+ ((x >> SND_RME_SPDIF_IF_SHIFT) & SND_RME_BINARY_MASK)
1848
+#define SND_RME_SPDIF_FORMAT(x) \
1849
+ ((x >> SND_RME_SPDIF_FORMAT_SHIFT) & SND_RME_BINARY_MASK)
1850
+
1851
+static const u32 snd_rme_rate_table[] = {
1852
+ 32000, 44100, 48000, 50000,
1853
+ 64000, 88200, 96000, 100000,
1854
+ 128000, 176400, 192000, 200000,
1855
+ 256000, 352800, 384000, 400000,
1856
+ 512000, 705600, 768000, 800000
1857
+};
1858
+/* maximum number of items for AES and S/PDIF rates for above table */
1859
+#define SND_RME_RATE_IDX_AES_SPDIF_NUM 12
1860
+
1861
+enum snd_rme_domain {
1862
+ SND_RME_DOMAIN_SYSTEM,
1863
+ SND_RME_DOMAIN_AES,
1864
+ SND_RME_DOMAIN_SPDIF
1865
+};
1866
+
1867
+enum snd_rme_clock_status {
1868
+ SND_RME_CLOCK_NOLOCK,
1869
+ SND_RME_CLOCK_LOCK,
1870
+ SND_RME_CLOCK_SYNC
1871
+};
1872
+
1873
+static int snd_rme_read_value(struct snd_usb_audio *chip,
1874
+ unsigned int item,
1875
+ u32 *value)
1876
+{
1877
+ struct usb_device *dev = chip->dev;
1878
+ int err;
1879
+
1880
+ err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
1881
+ item,
1882
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1883
+ 0, 0,
1884
+ value, sizeof(*value));
1885
+ if (err < 0)
1886
+ dev_err(&dev->dev,
1887
+ "unable to issue vendor read request %d (ret = %d)",
1888
+ item, err);
1889
+ return err;
1890
+}
1891
+
1892
+static int snd_rme_get_status1(struct snd_kcontrol *kcontrol,
1893
+ u32 *status1)
1894
+{
1895
+ struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
1896
+ struct snd_usb_audio *chip = list->mixer->chip;
1897
+ int err;
1898
+
1899
+ err = snd_usb_lock_shutdown(chip);
1900
+ if (err < 0)
1901
+ return err;
1902
+ err = snd_rme_read_value(chip, SND_RME_GET_STATUS1, status1);
1903
+ snd_usb_unlock_shutdown(chip);
1904
+ return err;
1905
+}
1906
+
1907
+static int snd_rme_rate_get(struct snd_kcontrol *kcontrol,
1908
+ struct snd_ctl_elem_value *ucontrol)
1909
+{
1910
+ u32 status1;
1911
+ u32 rate = 0;
1912
+ int idx;
1913
+ int err;
1914
+
1915
+ err = snd_rme_get_status1(kcontrol, &status1);
1916
+ if (err < 0)
1917
+ return err;
1918
+ switch (kcontrol->private_value) {
1919
+ case SND_RME_DOMAIN_SYSTEM:
1920
+ idx = SND_RME_CLK_SYSTEM(status1);
1921
+ if (idx < ARRAY_SIZE(snd_rme_rate_table))
1922
+ rate = snd_rme_rate_table[idx];
1923
+ break;
1924
+ case SND_RME_DOMAIN_AES:
1925
+ idx = SND_RME_CLK_AES(status1);
1926
+ if (idx < SND_RME_RATE_IDX_AES_SPDIF_NUM)
1927
+ rate = snd_rme_rate_table[idx];
1928
+ break;
1929
+ case SND_RME_DOMAIN_SPDIF:
1930
+ idx = SND_RME_CLK_SPDIF(status1);
1931
+ if (idx < SND_RME_RATE_IDX_AES_SPDIF_NUM)
1932
+ rate = snd_rme_rate_table[idx];
1933
+ break;
1934
+ default:
1935
+ return -EINVAL;
1936
+ }
1937
+ ucontrol->value.integer.value[0] = rate;
1938
+ return 0;
1939
+}
1940
+
1941
+static int snd_rme_sync_state_get(struct snd_kcontrol *kcontrol,
1942
+ struct snd_ctl_elem_value *ucontrol)
1943
+{
1944
+ u32 status1;
1945
+ int idx = SND_RME_CLOCK_NOLOCK;
1946
+ int err;
1947
+
1948
+ err = snd_rme_get_status1(kcontrol, &status1);
1949
+ if (err < 0)
1950
+ return err;
1951
+ switch (kcontrol->private_value) {
1952
+ case SND_RME_DOMAIN_AES: /* AES */
1953
+ if (status1 & SND_RME_CLK_AES_SYNC)
1954
+ idx = SND_RME_CLOCK_SYNC;
1955
+ else if (status1 & SND_RME_CLK_AES_LOCK)
1956
+ idx = SND_RME_CLOCK_LOCK;
1957
+ break;
1958
+ case SND_RME_DOMAIN_SPDIF: /* SPDIF */
1959
+ if (status1 & SND_RME_CLK_SPDIF_SYNC)
1960
+ idx = SND_RME_CLOCK_SYNC;
1961
+ else if (status1 & SND_RME_CLK_SPDIF_LOCK)
1962
+ idx = SND_RME_CLOCK_LOCK;
1963
+ break;
1964
+ default:
1965
+ return -EINVAL;
1966
+ }
1967
+ ucontrol->value.enumerated.item[0] = idx;
1968
+ return 0;
1969
+}
1970
+
1971
+static int snd_rme_spdif_if_get(struct snd_kcontrol *kcontrol,
1972
+ struct snd_ctl_elem_value *ucontrol)
1973
+{
1974
+ u32 status1;
1975
+ int err;
1976
+
1977
+ err = snd_rme_get_status1(kcontrol, &status1);
1978
+ if (err < 0)
1979
+ return err;
1980
+ ucontrol->value.enumerated.item[0] = SND_RME_SPDIF_IF(status1);
1981
+ return 0;
1982
+}
1983
+
1984
+static int snd_rme_spdif_format_get(struct snd_kcontrol *kcontrol,
1985
+ struct snd_ctl_elem_value *ucontrol)
1986
+{
1987
+ u32 status1;
1988
+ int err;
1989
+
1990
+ err = snd_rme_get_status1(kcontrol, &status1);
1991
+ if (err < 0)
1992
+ return err;
1993
+ ucontrol->value.enumerated.item[0] = SND_RME_SPDIF_FORMAT(status1);
1994
+ return 0;
1995
+}
1996
+
1997
+static int snd_rme_sync_source_get(struct snd_kcontrol *kcontrol,
1998
+ struct snd_ctl_elem_value *ucontrol)
1999
+{
2000
+ u32 status1;
2001
+ int err;
2002
+
2003
+ err = snd_rme_get_status1(kcontrol, &status1);
2004
+ if (err < 0)
2005
+ return err;
2006
+ ucontrol->value.enumerated.item[0] = SND_RME_CLK_SYNC(status1);
2007
+ return 0;
2008
+}
2009
+
2010
+static int snd_rme_current_freq_get(struct snd_kcontrol *kcontrol,
2011
+ struct snd_ctl_elem_value *ucontrol)
2012
+{
2013
+ struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
2014
+ struct snd_usb_audio *chip = list->mixer->chip;
2015
+ u32 status1;
2016
+ const u64 num = 104857600000000ULL;
2017
+ u32 den;
2018
+ unsigned int freq;
2019
+ int err;
2020
+
2021
+ err = snd_usb_lock_shutdown(chip);
2022
+ if (err < 0)
2023
+ return err;
2024
+ err = snd_rme_read_value(chip, SND_RME_GET_STATUS1, &status1);
2025
+ if (err < 0)
2026
+ goto end;
2027
+ err = snd_rme_read_value(chip, SND_RME_GET_CURRENT_FREQ, &den);
2028
+ if (err < 0)
2029
+ goto end;
2030
+ freq = (den == 0) ? 0 : div64_u64(num, den);
2031
+ freq <<= SND_RME_CLK_FREQMUL(status1);
2032
+ ucontrol->value.integer.value[0] = freq;
2033
+
2034
+end:
2035
+ snd_usb_unlock_shutdown(chip);
2036
+ return err;
2037
+}
2038
+
2039
+static int snd_rme_rate_info(struct snd_kcontrol *kcontrol,
2040
+ struct snd_ctl_elem_info *uinfo)
2041
+{
2042
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2043
+ uinfo->count = 1;
2044
+ switch (kcontrol->private_value) {
2045
+ case SND_RME_DOMAIN_SYSTEM:
2046
+ uinfo->value.integer.min = 32000;
2047
+ uinfo->value.integer.max = 800000;
2048
+ break;
2049
+ case SND_RME_DOMAIN_AES:
2050
+ case SND_RME_DOMAIN_SPDIF:
2051
+ default:
2052
+ uinfo->value.integer.min = 0;
2053
+ uinfo->value.integer.max = 200000;
2054
+ }
2055
+ uinfo->value.integer.step = 0;
2056
+ return 0;
2057
+}
2058
+
2059
+static int snd_rme_sync_state_info(struct snd_kcontrol *kcontrol,
2060
+ struct snd_ctl_elem_info *uinfo)
2061
+{
2062
+ static const char *const sync_states[] = {
2063
+ "No Lock", "Lock", "Sync"
2064
+ };
2065
+
2066
+ return snd_ctl_enum_info(uinfo, 1,
2067
+ ARRAY_SIZE(sync_states), sync_states);
2068
+}
2069
+
2070
+static int snd_rme_spdif_if_info(struct snd_kcontrol *kcontrol,
2071
+ struct snd_ctl_elem_info *uinfo)
2072
+{
2073
+ static const char *const spdif_if[] = {
2074
+ "Coaxial", "Optical"
2075
+ };
2076
+
2077
+ return snd_ctl_enum_info(uinfo, 1,
2078
+ ARRAY_SIZE(spdif_if), spdif_if);
2079
+}
2080
+
2081
+static int snd_rme_spdif_format_info(struct snd_kcontrol *kcontrol,
2082
+ struct snd_ctl_elem_info *uinfo)
2083
+{
2084
+ static const char *const optical_type[] = {
2085
+ "Consumer", "Professional"
2086
+ };
2087
+
2088
+ return snd_ctl_enum_info(uinfo, 1,
2089
+ ARRAY_SIZE(optical_type), optical_type);
2090
+}
2091
+
2092
+static int snd_rme_sync_source_info(struct snd_kcontrol *kcontrol,
2093
+ struct snd_ctl_elem_info *uinfo)
2094
+{
2095
+ static const char *const sync_sources[] = {
2096
+ "Internal", "AES", "SPDIF", "Internal"
2097
+ };
2098
+
2099
+ return snd_ctl_enum_info(uinfo, 1,
2100
+ ARRAY_SIZE(sync_sources), sync_sources);
2101
+}
2102
+
2103
+static const struct snd_kcontrol_new snd_rme_controls[] = {
2104
+ {
2105
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2106
+ .name = "AES Rate",
2107
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2108
+ .info = snd_rme_rate_info,
2109
+ .get = snd_rme_rate_get,
2110
+ .private_value = SND_RME_DOMAIN_AES
2111
+ },
2112
+ {
2113
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2114
+ .name = "AES Sync",
2115
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2116
+ .info = snd_rme_sync_state_info,
2117
+ .get = snd_rme_sync_state_get,
2118
+ .private_value = SND_RME_DOMAIN_AES
2119
+ },
2120
+ {
2121
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2122
+ .name = "SPDIF Rate",
2123
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2124
+ .info = snd_rme_rate_info,
2125
+ .get = snd_rme_rate_get,
2126
+ .private_value = SND_RME_DOMAIN_SPDIF
2127
+ },
2128
+ {
2129
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2130
+ .name = "SPDIF Sync",
2131
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2132
+ .info = snd_rme_sync_state_info,
2133
+ .get = snd_rme_sync_state_get,
2134
+ .private_value = SND_RME_DOMAIN_SPDIF
2135
+ },
2136
+ {
2137
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2138
+ .name = "SPDIF Interface",
2139
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2140
+ .info = snd_rme_spdif_if_info,
2141
+ .get = snd_rme_spdif_if_get,
2142
+ },
2143
+ {
2144
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2145
+ .name = "SPDIF Format",
2146
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2147
+ .info = snd_rme_spdif_format_info,
2148
+ .get = snd_rme_spdif_format_get,
2149
+ },
2150
+ {
2151
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2152
+ .name = "Sync Source",
2153
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2154
+ .info = snd_rme_sync_source_info,
2155
+ .get = snd_rme_sync_source_get
2156
+ },
2157
+ {
2158
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2159
+ .name = "System Rate",
2160
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2161
+ .info = snd_rme_rate_info,
2162
+ .get = snd_rme_rate_get,
2163
+ .private_value = SND_RME_DOMAIN_SYSTEM
2164
+ },
2165
+ {
2166
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2167
+ .name = "Current Frequency",
2168
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2169
+ .info = snd_rme_rate_info,
2170
+ .get = snd_rme_current_freq_get
2171
+ }
2172
+};
2173
+
2174
+static int snd_rme_controls_create(struct usb_mixer_interface *mixer)
2175
+{
2176
+ int err, i;
2177
+
2178
+ for (i = 0; i < ARRAY_SIZE(snd_rme_controls); ++i) {
2179
+ err = add_single_ctl_with_resume(mixer, 0,
2180
+ NULL,
2181
+ &snd_rme_controls[i],
2182
+ NULL);
2183
+ if (err < 0)
2184
+ return err;
2185
+ }
2186
+
2187
+ return 0;
2188
+}
2189
+
2190
+/*
2191
+ * RME Babyface Pro (FS)
2192
+ *
2193
+ * These devices exposes a couple of DSP functions via request to EP0.
2194
+ * Switches are available via control registers, while routing is controlled
2195
+ * by controlling the volume on each possible crossing point.
2196
+ * Volume control is linear, from -inf (dec. 0) to +6dB (dec. 65536) with
2197
+ * 0dB being at dec. 32768.
2198
+ */
2199
+enum {
2200
+ SND_BBFPRO_CTL_REG1 = 0,
2201
+ SND_BBFPRO_CTL_REG2
2202
+};
2203
+
2204
+#define SND_BBFPRO_CTL_REG_MASK 1
2205
+#define SND_BBFPRO_CTL_IDX_MASK 0xff
2206
+#define SND_BBFPRO_CTL_IDX_SHIFT 1
2207
+#define SND_BBFPRO_CTL_VAL_MASK 1
2208
+#define SND_BBFPRO_CTL_VAL_SHIFT 9
2209
+#define SND_BBFPRO_CTL_REG1_CLK_MASTER 0
2210
+#define SND_BBFPRO_CTL_REG1_CLK_OPTICAL 1
2211
+#define SND_BBFPRO_CTL_REG1_SPDIF_PRO 7
2212
+#define SND_BBFPRO_CTL_REG1_SPDIF_EMPH 8
2213
+#define SND_BBFPRO_CTL_REG1_SPDIF_OPTICAL 10
2214
+#define SND_BBFPRO_CTL_REG2_48V_AN1 0
2215
+#define SND_BBFPRO_CTL_REG2_48V_AN2 1
2216
+#define SND_BBFPRO_CTL_REG2_SENS_IN3 2
2217
+#define SND_BBFPRO_CTL_REG2_SENS_IN4 3
2218
+#define SND_BBFPRO_CTL_REG2_PAD_AN1 4
2219
+#define SND_BBFPRO_CTL_REG2_PAD_AN2 5
2220
+
2221
+#define SND_BBFPRO_MIXER_IDX_MASK 0x1ff
2222
+#define SND_BBFPRO_MIXER_VAL_MASK 0x3ffff
2223
+#define SND_BBFPRO_MIXER_VAL_SHIFT 9
2224
+#define SND_BBFPRO_MIXER_VAL_MIN 0 // -inf
2225
+#define SND_BBFPRO_MIXER_VAL_MAX 65536 // +6dB
2226
+
2227
+#define SND_BBFPRO_USBREQ_CTL_REG1 0x10
2228
+#define SND_BBFPRO_USBREQ_CTL_REG2 0x17
2229
+#define SND_BBFPRO_USBREQ_MIXER 0x12
2230
+
2231
+static int snd_bbfpro_ctl_update(struct usb_mixer_interface *mixer, u8 reg,
2232
+ u8 index, u8 value)
2233
+{
2234
+ int err;
2235
+ u16 usb_req, usb_idx, usb_val;
2236
+ struct snd_usb_audio *chip = mixer->chip;
2237
+
2238
+ err = snd_usb_lock_shutdown(chip);
2239
+ if (err < 0)
2240
+ return err;
2241
+
2242
+ if (reg == SND_BBFPRO_CTL_REG1) {
2243
+ usb_req = SND_BBFPRO_USBREQ_CTL_REG1;
2244
+ if (index == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) {
2245
+ usb_idx = 3;
2246
+ usb_val = value ? 3 : 0;
2247
+ } else {
2248
+ usb_idx = 1 << index;
2249
+ usb_val = value ? usb_idx : 0;
2250
+ }
2251
+ } else {
2252
+ usb_req = SND_BBFPRO_USBREQ_CTL_REG2;
2253
+ usb_idx = 1 << index;
2254
+ usb_val = value ? usb_idx : 0;
2255
+ }
2256
+
2257
+ err = snd_usb_ctl_msg(chip->dev,
2258
+ usb_sndctrlpipe(chip->dev, 0), usb_req,
2259
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2260
+ usb_val, usb_idx, NULL, 0);
2261
+
2262
+ snd_usb_unlock_shutdown(chip);
2263
+ return err;
2264
+}
2265
+
2266
+static int snd_bbfpro_ctl_get(struct snd_kcontrol *kcontrol,
2267
+ struct snd_ctl_elem_value *ucontrol)
2268
+{
2269
+ u8 reg, idx, val;
2270
+ int pv;
2271
+
2272
+ pv = kcontrol->private_value;
2273
+ reg = pv & SND_BBFPRO_CTL_REG_MASK;
2274
+ idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
2275
+ val = kcontrol->private_value >> SND_BBFPRO_CTL_VAL_SHIFT;
2276
+
2277
+ if ((reg == SND_BBFPRO_CTL_REG1 &&
2278
+ idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) ||
2279
+ (reg == SND_BBFPRO_CTL_REG2 &&
2280
+ (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
2281
+ idx == SND_BBFPRO_CTL_REG2_SENS_IN4))) {
2282
+ ucontrol->value.enumerated.item[0] = val;
2283
+ } else {
2284
+ ucontrol->value.integer.value[0] = val;
2285
+ }
2286
+ return 0;
2287
+}
2288
+
2289
+static int snd_bbfpro_ctl_info(struct snd_kcontrol *kcontrol,
2290
+ struct snd_ctl_elem_info *uinfo)
2291
+{
2292
+ u8 reg, idx;
2293
+ int pv;
2294
+
2295
+ pv = kcontrol->private_value;
2296
+ reg = pv & SND_BBFPRO_CTL_REG_MASK;
2297
+ idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
2298
+
2299
+ if (reg == SND_BBFPRO_CTL_REG1 &&
2300
+ idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) {
2301
+ static const char * const texts[2] = {
2302
+ "AutoSync",
2303
+ "Internal"
2304
+ };
2305
+ return snd_ctl_enum_info(uinfo, 1, 2, texts);
2306
+ } else if (reg == SND_BBFPRO_CTL_REG2 &&
2307
+ (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
2308
+ idx == SND_BBFPRO_CTL_REG2_SENS_IN4)) {
2309
+ static const char * const texts[2] = {
2310
+ "-10dBV",
2311
+ "+4dBu"
2312
+ };
2313
+ return snd_ctl_enum_info(uinfo, 1, 2, texts);
2314
+ }
2315
+
2316
+ uinfo->count = 1;
2317
+ uinfo->value.integer.min = 0;
2318
+ uinfo->value.integer.max = 1;
2319
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2320
+ return 0;
2321
+}
2322
+
2323
+static int snd_bbfpro_ctl_put(struct snd_kcontrol *kcontrol,
2324
+ struct snd_ctl_elem_value *ucontrol)
2325
+{
2326
+ int err;
2327
+ u8 reg, idx;
2328
+ int old_value, pv, val;
2329
+
2330
+ struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
2331
+ struct usb_mixer_interface *mixer = list->mixer;
2332
+
2333
+ pv = kcontrol->private_value;
2334
+ reg = pv & SND_BBFPRO_CTL_REG_MASK;
2335
+ idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
2336
+ old_value = (pv >> SND_BBFPRO_CTL_VAL_SHIFT) & SND_BBFPRO_CTL_VAL_MASK;
2337
+
2338
+ if ((reg == SND_BBFPRO_CTL_REG1 &&
2339
+ idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) ||
2340
+ (reg == SND_BBFPRO_CTL_REG2 &&
2341
+ (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
2342
+ idx == SND_BBFPRO_CTL_REG2_SENS_IN4))) {
2343
+ val = ucontrol->value.enumerated.item[0];
2344
+ } else {
2345
+ val = ucontrol->value.integer.value[0];
2346
+ }
2347
+
2348
+ if (val > 1)
2349
+ return -EINVAL;
2350
+
2351
+ if (val == old_value)
2352
+ return 0;
2353
+
2354
+ kcontrol->private_value = reg
2355
+ | ((idx & SND_BBFPRO_CTL_IDX_MASK) << SND_BBFPRO_CTL_IDX_SHIFT)
2356
+ | ((val & SND_BBFPRO_CTL_VAL_MASK) << SND_BBFPRO_CTL_VAL_SHIFT);
2357
+
2358
+ err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
2359
+ return err < 0 ? err : 1;
2360
+}
2361
+
2362
+static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
2363
+{
2364
+ u8 reg, idx;
2365
+ int value, pv;
2366
+
2367
+ pv = list->kctl->private_value;
2368
+ reg = pv & SND_BBFPRO_CTL_REG_MASK;
2369
+ idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
2370
+ value = (pv >> SND_BBFPRO_CTL_VAL_SHIFT) & SND_BBFPRO_CTL_VAL_MASK;
2371
+
2372
+ return snd_bbfpro_ctl_update(list->mixer, reg, idx, value);
2373
+}
2374
+
2375
+static int snd_bbfpro_vol_update(struct usb_mixer_interface *mixer, u16 index,
2376
+ u32 value)
2377
+{
2378
+ struct snd_usb_audio *chip = mixer->chip;
2379
+ int err;
2380
+ u16 idx;
2381
+ u16 usb_idx, usb_val;
2382
+ u32 v;
2383
+
2384
+ err = snd_usb_lock_shutdown(chip);
2385
+ if (err < 0)
2386
+ return err;
2387
+
2388
+ idx = index & SND_BBFPRO_MIXER_IDX_MASK;
2389
+ // 18 bit linear volume, split so 2 bits end up in index.
2390
+ v = value & SND_BBFPRO_MIXER_VAL_MASK;
2391
+ usb_idx = idx | (v & 0x3) << 14;
2392
+ usb_val = (v >> 2) & 0xffff;
2393
+
2394
+ err = snd_usb_ctl_msg(chip->dev,
2395
+ usb_sndctrlpipe(chip->dev, 0),
2396
+ SND_BBFPRO_USBREQ_MIXER,
2397
+ USB_DIR_OUT | USB_TYPE_VENDOR |
2398
+ USB_RECIP_DEVICE,
2399
+ usb_val, usb_idx, NULL, 0);
2400
+
2401
+ snd_usb_unlock_shutdown(chip);
2402
+ return err;
2403
+}
2404
+
2405
+static int snd_bbfpro_vol_get(struct snd_kcontrol *kcontrol,
2406
+ struct snd_ctl_elem_value *ucontrol)
2407
+{
2408
+ ucontrol->value.integer.value[0] =
2409
+ kcontrol->private_value >> SND_BBFPRO_MIXER_VAL_SHIFT;
2410
+ return 0;
2411
+}
2412
+
2413
+static int snd_bbfpro_vol_info(struct snd_kcontrol *kcontrol,
2414
+ struct snd_ctl_elem_info *uinfo)
2415
+{
2416
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2417
+ uinfo->count = 1;
2418
+ uinfo->value.integer.min = SND_BBFPRO_MIXER_VAL_MIN;
2419
+ uinfo->value.integer.max = SND_BBFPRO_MIXER_VAL_MAX;
2420
+ return 0;
2421
+}
2422
+
2423
+static int snd_bbfpro_vol_put(struct snd_kcontrol *kcontrol,
2424
+ struct snd_ctl_elem_value *ucontrol)
2425
+{
2426
+ int err;
2427
+ u16 idx;
2428
+ u32 new_val, old_value, uvalue;
2429
+ struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
2430
+ struct usb_mixer_interface *mixer = list->mixer;
2431
+
2432
+ uvalue = ucontrol->value.integer.value[0];
2433
+ idx = kcontrol->private_value & SND_BBFPRO_MIXER_IDX_MASK;
2434
+ old_value = kcontrol->private_value >> SND_BBFPRO_MIXER_VAL_SHIFT;
2435
+
2436
+ if (uvalue > SND_BBFPRO_MIXER_VAL_MAX)
2437
+ return -EINVAL;
2438
+
2439
+ if (uvalue == old_value)
2440
+ return 0;
2441
+
2442
+ new_val = uvalue & SND_BBFPRO_MIXER_VAL_MASK;
2443
+
2444
+ kcontrol->private_value = idx
2445
+ | (new_val << SND_BBFPRO_MIXER_VAL_SHIFT);
2446
+
2447
+ err = snd_bbfpro_vol_update(mixer, idx, new_val);
2448
+ return err < 0 ? err : 1;
2449
+}
2450
+
2451
+static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list)
2452
+{
2453
+ int pv = list->kctl->private_value;
2454
+ u16 idx = pv & SND_BBFPRO_MIXER_IDX_MASK;
2455
+ u32 val = (pv >> SND_BBFPRO_MIXER_VAL_SHIFT)
2456
+ & SND_BBFPRO_MIXER_VAL_MASK;
2457
+ return snd_bbfpro_vol_update(list->mixer, idx, val);
2458
+}
2459
+
2460
+// Predfine elements
2461
+static const struct snd_kcontrol_new snd_bbfpro_ctl_control = {
2462
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2463
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2464
+ .index = 0,
2465
+ .info = snd_bbfpro_ctl_info,
2466
+ .get = snd_bbfpro_ctl_get,
2467
+ .put = snd_bbfpro_ctl_put
2468
+};
2469
+
2470
+static const struct snd_kcontrol_new snd_bbfpro_vol_control = {
2471
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2472
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2473
+ .index = 0,
2474
+ .info = snd_bbfpro_vol_info,
2475
+ .get = snd_bbfpro_vol_get,
2476
+ .put = snd_bbfpro_vol_put
2477
+};
2478
+
2479
+static int snd_bbfpro_ctl_add(struct usb_mixer_interface *mixer, u8 reg,
2480
+ u8 index, char *name)
2481
+{
2482
+ struct snd_kcontrol_new knew = snd_bbfpro_ctl_control;
2483
+
2484
+ knew.name = name;
2485
+ knew.private_value = (reg & SND_BBFPRO_CTL_REG_MASK)
2486
+ | ((index & SND_BBFPRO_CTL_IDX_MASK)
2487
+ << SND_BBFPRO_CTL_IDX_SHIFT);
2488
+
2489
+ return add_single_ctl_with_resume(mixer, 0, snd_bbfpro_ctl_resume,
2490
+ &knew, NULL);
2491
+}
2492
+
2493
+static int snd_bbfpro_vol_add(struct usb_mixer_interface *mixer, u16 index,
2494
+ char *name)
2495
+{
2496
+ struct snd_kcontrol_new knew = snd_bbfpro_vol_control;
2497
+
2498
+ knew.name = name;
2499
+ knew.private_value = index & SND_BBFPRO_MIXER_IDX_MASK;
2500
+
2501
+ return add_single_ctl_with_resume(mixer, 0, snd_bbfpro_vol_resume,
2502
+ &knew, NULL);
2503
+}
2504
+
2505
+static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
2506
+{
2507
+ int err, i, o;
2508
+ char name[48];
2509
+
2510
+ static const char * const input[] = {
2511
+ "AN1", "AN2", "IN3", "IN4", "AS1", "AS2", "ADAT3",
2512
+ "ADAT4", "ADAT5", "ADAT6", "ADAT7", "ADAT8"};
2513
+
2514
+ static const char * const output[] = {
2515
+ "AN1", "AN2", "PH3", "PH4", "AS1", "AS2", "ADAT3", "ADAT4",
2516
+ "ADAT5", "ADAT6", "ADAT7", "ADAT8"};
2517
+
2518
+ for (o = 0 ; o < 12 ; ++o) {
2519
+ for (i = 0 ; i < 12 ; ++i) {
2520
+ // Line routing
2521
+ snprintf(name, sizeof(name),
2522
+ "%s-%s-%s Playback Volume",
2523
+ (i < 2 ? "Mic" : "Line"),
2524
+ input[i], output[o]);
2525
+ err = snd_bbfpro_vol_add(mixer, (26 * o + i), name);
2526
+ if (err < 0)
2527
+ return err;
2528
+
2529
+ // PCM routing... yes, it is output remapping
2530
+ snprintf(name, sizeof(name),
2531
+ "PCM-%s-%s Playback Volume",
2532
+ output[i], output[o]);
2533
+ err = snd_bbfpro_vol_add(mixer, (26 * o + 12 + i),
2534
+ name);
2535
+ if (err < 0)
2536
+ return err;
2537
+ }
2538
+ }
2539
+
2540
+ // Control Reg 1
2541
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
2542
+ SND_BBFPRO_CTL_REG1_CLK_OPTICAL,
2543
+ "Sample Clock Source");
2544
+ if (err < 0)
2545
+ return err;
2546
+
2547
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
2548
+ SND_BBFPRO_CTL_REG1_SPDIF_PRO,
2549
+ "IEC958 Pro Mask");
2550
+ if (err < 0)
2551
+ return err;
2552
+
2553
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
2554
+ SND_BBFPRO_CTL_REG1_SPDIF_EMPH,
2555
+ "IEC958 Emphasis");
2556
+ if (err < 0)
2557
+ return err;
2558
+
2559
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
2560
+ SND_BBFPRO_CTL_REG1_SPDIF_OPTICAL,
2561
+ "IEC958 Switch");
2562
+ if (err < 0)
2563
+ return err;
2564
+
2565
+ // Control Reg 2
2566
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
2567
+ SND_BBFPRO_CTL_REG2_48V_AN1,
2568
+ "Mic-AN1 48V");
2569
+ if (err < 0)
2570
+ return err;
2571
+
2572
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
2573
+ SND_BBFPRO_CTL_REG2_48V_AN2,
2574
+ "Mic-AN2 48V");
2575
+ if (err < 0)
2576
+ return err;
2577
+
2578
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
2579
+ SND_BBFPRO_CTL_REG2_SENS_IN3,
2580
+ "Line-IN3 Sens.");
2581
+ if (err < 0)
2582
+ return err;
2583
+
2584
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
2585
+ SND_BBFPRO_CTL_REG2_SENS_IN4,
2586
+ "Line-IN4 Sens.");
2587
+ if (err < 0)
2588
+ return err;
2589
+
2590
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
2591
+ SND_BBFPRO_CTL_REG2_PAD_AN1,
2592
+ "Mic-AN1 PAD");
2593
+ if (err < 0)
2594
+ return err;
2595
+
2596
+ err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
2597
+ SND_BBFPRO_CTL_REG2_PAD_AN2,
2598
+ "Mic-AN2 PAD");
2599
+ if (err < 0)
2600
+ return err;
2601
+
2602
+ return 0;
2603
+}
2604
+
2605
+/*
2606
+ * Pioneer DJ DJM Mixers
2607
+ *
2608
+ * These devices generally have options for soft-switching the playback and
2609
+ * capture sources in addition to the recording level. Although different
2610
+ * devices have different configurations, there seems to be canonical values
2611
+ * for specific capture/playback types: See the definitions of these below.
2612
+ *
2613
+ * The wValue is masked with the stereo channel number. e.g. Setting Ch2 to
2614
+ * capture phono would be 0x0203. Capture, playback and capture level have
2615
+ * different wIndexes.
2616
+ */
2617
+
2618
+// Capture types
2619
+#define SND_DJM_CAP_LINE 0x00
2620
+#define SND_DJM_CAP_CDLINE 0x01
2621
+#define SND_DJM_CAP_DIGITAL 0x02
2622
+#define SND_DJM_CAP_PHONO 0x03
2623
+#define SND_DJM_CAP_PFADER 0x06
2624
+#define SND_DJM_CAP_XFADERA 0x07
2625
+#define SND_DJM_CAP_XFADERB 0x08
2626
+#define SND_DJM_CAP_MIC 0x09
2627
+#define SND_DJM_CAP_AUX 0x0d
2628
+#define SND_DJM_CAP_RECOUT 0x0a
2629
+#define SND_DJM_CAP_NONE 0x0f
2630
+#define SND_DJM_CAP_CH1PFADER 0x11
2631
+#define SND_DJM_CAP_CH2PFADER 0x12
2632
+#define SND_DJM_CAP_CH3PFADER 0x13
2633
+#define SND_DJM_CAP_CH4PFADER 0x14
2634
+
2635
+// Playback types
2636
+#define SND_DJM_PB_CH1 0x00
2637
+#define SND_DJM_PB_CH2 0x01
2638
+#define SND_DJM_PB_AUX 0x04
2639
+
2640
+#define SND_DJM_WINDEX_CAP 0x8002
2641
+#define SND_DJM_WINDEX_CAPLVL 0x8003
2642
+#define SND_DJM_WINDEX_PB 0x8016
2643
+
2644
+// kcontrol->private_value layout
2645
+#define SND_DJM_VALUE_MASK 0x0000ffff
2646
+#define SND_DJM_GROUP_MASK 0x00ff0000
2647
+#define SND_DJM_DEVICE_MASK 0xff000000
2648
+#define SND_DJM_GROUP_SHIFT 16
2649
+#define SND_DJM_DEVICE_SHIFT 24
2650
+
2651
+// device table index
2652
+#define SND_DJM_250MK2_IDX 0x0
2653
+#define SND_DJM_750_IDX 0x1
2654
+#define SND_DJM_900NXS2_IDX 0x2
2655
+
2656
+
2657
+#define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \
2658
+ .name = _name, \
2659
+ .options = snd_djm_opts_##suffix, \
2660
+ .noptions = ARRAY_SIZE(snd_djm_opts_##suffix), \
2661
+ .default_value = _default_value, \
2662
+ .wIndex = _windex }
2663
+
2664
+#define SND_DJM_DEVICE(suffix) { \
2665
+ .controls = snd_djm_ctls_##suffix, \
2666
+ .ncontrols = ARRAY_SIZE(snd_djm_ctls_##suffix) }
2667
+
2668
+
2669
+struct snd_djm_device {
2670
+ const char *name;
2671
+ const struct snd_djm_ctl *controls;
2672
+ size_t ncontrols;
2673
+};
2674
+
2675
+struct snd_djm_ctl {
2676
+ const char *name;
2677
+ const u16 *options;
2678
+ size_t noptions;
2679
+ u16 default_value;
2680
+ u16 wIndex;
2681
+};
2682
+
2683
+static const char *snd_djm_get_label_caplevel(u16 wvalue)
2684
+{
2685
+ switch (wvalue) {
2686
+ case 0x0000: return "-19dB";
2687
+ case 0x0100: return "-15dB";
2688
+ case 0x0200: return "-10dB";
2689
+ case 0x0300: return "-5dB";
2690
+ default: return NULL;
2691
+ }
2692
+};
2693
+
2694
+static const char *snd_djm_get_label_cap(u16 wvalue)
2695
+{
2696
+ switch (wvalue & 0x00ff) {
2697
+ case SND_DJM_CAP_LINE: return "Control Tone LINE";
2698
+ case SND_DJM_CAP_CDLINE: return "Control Tone CD/LINE";
2699
+ case SND_DJM_CAP_DIGITAL: return "Control Tone DIGITAL";
2700
+ case SND_DJM_CAP_PHONO: return "Control Tone PHONO";
2701
+ case SND_DJM_CAP_PFADER: return "Post Fader";
2702
+ case SND_DJM_CAP_XFADERA: return "Cross Fader A";
2703
+ case SND_DJM_CAP_XFADERB: return "Cross Fader B";
2704
+ case SND_DJM_CAP_MIC: return "Mic";
2705
+ case SND_DJM_CAP_RECOUT: return "Rec Out";
2706
+ case SND_DJM_CAP_AUX: return "Aux";
2707
+ case SND_DJM_CAP_NONE: return "None";
2708
+ case SND_DJM_CAP_CH1PFADER: return "Post Fader Ch1";
2709
+ case SND_DJM_CAP_CH2PFADER: return "Post Fader Ch2";
2710
+ case SND_DJM_CAP_CH3PFADER: return "Post Fader Ch3";
2711
+ case SND_DJM_CAP_CH4PFADER: return "Post Fader Ch4";
2712
+ default: return NULL;
2713
+ }
2714
+};
2715
+
2716
+static const char *snd_djm_get_label_pb(u16 wvalue)
2717
+{
2718
+ switch (wvalue & 0x00ff) {
2719
+ case SND_DJM_PB_CH1: return "Ch1";
2720
+ case SND_DJM_PB_CH2: return "Ch2";
2721
+ case SND_DJM_PB_AUX: return "Aux";
2722
+ default: return NULL;
2723
+ }
2724
+};
2725
+
2726
+static const char *snd_djm_get_label(u16 wvalue, u16 windex)
2727
+{
2728
+ switch (windex) {
2729
+ case SND_DJM_WINDEX_CAPLVL: return snd_djm_get_label_caplevel(wvalue);
2730
+ case SND_DJM_WINDEX_CAP: return snd_djm_get_label_cap(wvalue);
2731
+ case SND_DJM_WINDEX_PB: return snd_djm_get_label_pb(wvalue);
2732
+ default: return NULL;
2733
+ }
2734
+};
2735
+
2736
+
2737
+// DJM-250MK2
2738
+static const u16 snd_djm_opts_cap_level[] = {
2739
+ 0x0000, 0x0100, 0x0200, 0x0300 };
2740
+
2741
+static const u16 snd_djm_opts_250mk2_cap1[] = {
2742
+ 0x0103, 0x0100, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d, 0x010a };
2743
+
2744
+static const u16 snd_djm_opts_250mk2_cap2[] = {
2745
+ 0x0203, 0x0200, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d, 0x020a };
2746
+
2747
+static const u16 snd_djm_opts_250mk2_cap3[] = {
2748
+ 0x030a, 0x0311, 0x0312, 0x0307, 0x0308, 0x0309, 0x030d };
2749
+
2750
+static const u16 snd_djm_opts_250mk2_pb1[] = { 0x0100, 0x0101, 0x0104 };
2751
+static const u16 snd_djm_opts_250mk2_pb2[] = { 0x0200, 0x0201, 0x0204 };
2752
+static const u16 snd_djm_opts_250mk2_pb3[] = { 0x0300, 0x0301, 0x0304 };
2753
+
2754
+static const struct snd_djm_ctl snd_djm_ctls_250mk2[] = {
2755
+ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
2756
+ SND_DJM_CTL("Ch1 Input", 250mk2_cap1, 2, SND_DJM_WINDEX_CAP),
2757
+ SND_DJM_CTL("Ch2 Input", 250mk2_cap2, 2, SND_DJM_WINDEX_CAP),
2758
+ SND_DJM_CTL("Ch3 Input", 250mk2_cap3, 0, SND_DJM_WINDEX_CAP),
2759
+ SND_DJM_CTL("Ch1 Output", 250mk2_pb1, 0, SND_DJM_WINDEX_PB),
2760
+ SND_DJM_CTL("Ch2 Output", 250mk2_pb2, 1, SND_DJM_WINDEX_PB),
2761
+ SND_DJM_CTL("Ch3 Output", 250mk2_pb3, 2, SND_DJM_WINDEX_PB)
2762
+};
2763
+
2764
+
2765
+// DJM-750
2766
+static const u16 snd_djm_opts_750_cap1[] = {
2767
+ 0x0101, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010f };
2768
+static const u16 snd_djm_opts_750_cap2[] = {
2769
+ 0x0200, 0x0201, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020f };
2770
+static const u16 snd_djm_opts_750_cap3[] = {
2771
+ 0x0300, 0x0301, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a, 0x030f };
2772
+static const u16 snd_djm_opts_750_cap4[] = {
2773
+ 0x0401, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040f };
2774
+
2775
+static const struct snd_djm_ctl snd_djm_ctls_750[] = {
2776
+ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
2777
+ SND_DJM_CTL("Ch1 Input", 750_cap1, 2, SND_DJM_WINDEX_CAP),
2778
+ SND_DJM_CTL("Ch2 Input", 750_cap2, 2, SND_DJM_WINDEX_CAP),
2779
+ SND_DJM_CTL("Ch3 Input", 750_cap3, 0, SND_DJM_WINDEX_CAP),
2780
+ SND_DJM_CTL("Ch4 Input", 750_cap4, 0, SND_DJM_WINDEX_CAP)
2781
+};
2782
+
2783
+
2784
+// DJM-900NXS2
2785
+static const u16 snd_djm_opts_900nxs2_cap1[] = {
2786
+ 0x0100, 0x0102, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a };
2787
+static const u16 snd_djm_opts_900nxs2_cap2[] = {
2788
+ 0x0200, 0x0202, 0x0203, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a };
2789
+static const u16 snd_djm_opts_900nxs2_cap3[] = {
2790
+ 0x0300, 0x0302, 0x0303, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a };
2791
+static const u16 snd_djm_opts_900nxs2_cap4[] = {
2792
+ 0x0400, 0x0402, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a };
2793
+static const u16 snd_djm_opts_900nxs2_cap5[] = {
2794
+ 0x0507, 0x0508, 0x0509, 0x050a, 0x0511, 0x0512, 0x0513, 0x0514 };
2795
+
2796
+static const struct snd_djm_ctl snd_djm_ctls_900nxs2[] = {
2797
+ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
2798
+ SND_DJM_CTL("Ch1 Input", 900nxs2_cap1, 2, SND_DJM_WINDEX_CAP),
2799
+ SND_DJM_CTL("Ch2 Input", 900nxs2_cap2, 2, SND_DJM_WINDEX_CAP),
2800
+ SND_DJM_CTL("Ch3 Input", 900nxs2_cap3, 2, SND_DJM_WINDEX_CAP),
2801
+ SND_DJM_CTL("Ch4 Input", 900nxs2_cap4, 2, SND_DJM_WINDEX_CAP),
2802
+ SND_DJM_CTL("Ch5 Input", 900nxs2_cap5, 3, SND_DJM_WINDEX_CAP)
2803
+};
2804
+
2805
+
2806
+static const struct snd_djm_device snd_djm_devices[] = {
2807
+ SND_DJM_DEVICE(250mk2),
2808
+ SND_DJM_DEVICE(750),
2809
+ SND_DJM_DEVICE(900nxs2)
2810
+};
2811
+
2812
+
2813
+static int snd_djm_controls_info(struct snd_kcontrol *kctl,
2814
+ struct snd_ctl_elem_info *info)
2815
+{
2816
+ unsigned long private_value = kctl->private_value;
2817
+ u8 device_idx = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT;
2818
+ u8 ctl_idx = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT;
2819
+ const struct snd_djm_device *device = &snd_djm_devices[device_idx];
2820
+ const char *name;
2821
+ const struct snd_djm_ctl *ctl;
2822
+ size_t noptions;
2823
+
2824
+ if (ctl_idx >= device->ncontrols)
2825
+ return -EINVAL;
2826
+
2827
+ ctl = &device->controls[ctl_idx];
2828
+ noptions = ctl->noptions;
2829
+ if (info->value.enumerated.item >= noptions)
2830
+ info->value.enumerated.item = noptions - 1;
2831
+
2832
+ name = snd_djm_get_label(ctl->options[info->value.enumerated.item],
2833
+ ctl->wIndex);
2834
+ if (!name)
2835
+ return -EINVAL;
2836
+
2837
+ strlcpy(info->value.enumerated.name, name, sizeof(info->value.enumerated.name));
2838
+ info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2839
+ info->count = 1;
2840
+ info->value.enumerated.items = noptions;
2841
+ return 0;
2842
+}
2843
+
2844
+static int snd_djm_controls_update(struct usb_mixer_interface *mixer,
2845
+ u8 device_idx, u8 group, u16 value)
2846
+{
2847
+ int err;
2848
+ const struct snd_djm_device *device = &snd_djm_devices[device_idx];
2849
+
2850
+ if ((group >= device->ncontrols) || value >= device->controls[group].noptions)
2851
+ return -EINVAL;
2852
+
2853
+ err = snd_usb_lock_shutdown(mixer->chip);
2854
+ if (err)
2855
+ return err;
2856
+
2857
+ err = snd_usb_ctl_msg(
2858
+ mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0),
2859
+ USB_REQ_SET_FEATURE,
2860
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2861
+ device->controls[group].options[value],
2862
+ device->controls[group].wIndex,
2863
+ NULL, 0);
2864
+
2865
+ snd_usb_unlock_shutdown(mixer->chip);
2866
+ return err;
2867
+}
2868
+
2869
+static int snd_djm_controls_get(struct snd_kcontrol *kctl,
2870
+ struct snd_ctl_elem_value *elem)
2871
+{
2872
+ elem->value.enumerated.item[0] = kctl->private_value & SND_DJM_VALUE_MASK;
2873
+ return 0;
2874
+}
2875
+
2876
+static int snd_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem)
2877
+{
2878
+ struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
2879
+ struct usb_mixer_interface *mixer = list->mixer;
2880
+ unsigned long private_value = kctl->private_value;
2881
+
2882
+ u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT;
2883
+ u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT;
2884
+ u16 value = elem->value.enumerated.item[0];
2885
+
2886
+ kctl->private_value = (((unsigned long)device << SND_DJM_DEVICE_SHIFT) |
2887
+ (group << SND_DJM_GROUP_SHIFT) |
2888
+ value);
2889
+
2890
+ return snd_djm_controls_update(mixer, device, group, value);
2891
+}
2892
+
2893
+static int snd_djm_controls_resume(struct usb_mixer_elem_list *list)
2894
+{
2895
+ unsigned long private_value = list->kctl->private_value;
2896
+ u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT;
2897
+ u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT;
2898
+ u16 value = (private_value & SND_DJM_VALUE_MASK);
2899
+
2900
+ return snd_djm_controls_update(list->mixer, device, group, value);
2901
+}
2902
+
2903
+static int snd_djm_controls_create(struct usb_mixer_interface *mixer,
2904
+ const u8 device_idx)
2905
+{
2906
+ int err, i;
2907
+ u16 value;
2908
+
2909
+ const struct snd_djm_device *device = &snd_djm_devices[device_idx];
2910
+
2911
+ struct snd_kcontrol_new knew = {
2912
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2913
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2914
+ .index = 0,
2915
+ .info = snd_djm_controls_info,
2916
+ .get = snd_djm_controls_get,
2917
+ .put = snd_djm_controls_put
2918
+ };
2919
+
2920
+ for (i = 0; i < device->ncontrols; i++) {
2921
+ value = device->controls[i].default_value;
2922
+ knew.name = device->controls[i].name;
2923
+ knew.private_value = (
2924
+ ((unsigned long)device_idx << SND_DJM_DEVICE_SHIFT) |
2925
+ (i << SND_DJM_GROUP_SHIFT) |
2926
+ value);
2927
+ err = snd_djm_controls_update(mixer, device_idx, i, value);
2928
+ if (err)
2929
+ return err;
2930
+ err = add_single_ctl_with_resume(mixer, 0, snd_djm_controls_resume,
2931
+ &knew, NULL);
2932
+ if (err)
2933
+ return err;
2934
+ }
2935
+ return 0;
2936
+}
2937
+
18262938 int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
18272939 {
18282940 int err = 0;
1829
- struct snd_info_entry *entry;
18302941
18312942 err = snd_usb_soundblaster_remote_init(mixer);
18322943 if (err < 0)
....@@ -1845,9 +2956,8 @@
18452956 err = snd_audigy2nx_controls_create(mixer);
18462957 if (err < 0)
18472958 break;
1848
- if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
1849
- snd_info_set_text_ops(entry, mixer,
1850
- snd_audigy2nx_proc_read);
2959
+ snd_card_ro_proc_new(mixer->chip->card, "audigy2nx",
2960
+ mixer, snd_audigy2nx_proc_read);
18512961 break;
18522962
18532963 /* EMU0204 */
....@@ -1904,11 +3014,39 @@
19043014 err = snd_scarlett_controls_create(mixer);
19053015 break;
19063016
3017
+ case USB_ID(0x1235, 0x8203): /* Focusrite Scarlett 6i6 2nd Gen */
3018
+ case USB_ID(0x1235, 0x8204): /* Focusrite Scarlett 18i8 2nd Gen */
3019
+ case USB_ID(0x1235, 0x8201): /* Focusrite Scarlett 18i20 2nd Gen */
3020
+ err = snd_scarlett_gen2_init(mixer);
3021
+ break;
3022
+
19073023 case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */
19083024 err = snd_soundblaster_e1_switch_create(mixer);
19093025 break;
19103026 case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */
19113027 err = dell_dock_mixer_init(mixer);
3028
+ break;
3029
+
3030
+ case USB_ID(0x2a39, 0x3fd2): /* RME ADI-2 Pro */
3031
+ case USB_ID(0x2a39, 0x3fd3): /* RME ADI-2 DAC */
3032
+ case USB_ID(0x2a39, 0x3fd4): /* RME */
3033
+ err = snd_rme_controls_create(mixer);
3034
+ break;
3035
+
3036
+ case USB_ID(0x194f, 0x010c): /* Presonus Studio 1810c */
3037
+ err = snd_sc1810_init_mixer(mixer);
3038
+ break;
3039
+ case USB_ID(0x2a39, 0x3fb0): /* RME Babyface Pro FS */
3040
+ err = snd_bbfpro_controls_create(mixer);
3041
+ break;
3042
+ case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
3043
+ err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX);
3044
+ break;
3045
+ case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */
3046
+ err = snd_djm_controls_create(mixer, SND_DJM_750_IDX);
3047
+ break;
3048
+ case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
3049
+ err = snd_djm_controls_create(mixer, SND_DJM_900NXS2_IDX);
19123050 break;
19133051 }
19143052
....@@ -1997,9 +3135,10 @@
19973135 if (unitid == 7 && cval->control == UAC_FU_VOLUME)
19983136 snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
19993137 break;
2000
- /* lowest playback value is muted on C-Media devices */
2001
- case USB_ID(0x0d8c, 0x000c):
2002
- case USB_ID(0x0d8c, 0x0014):
3138
+ /* lowest playback value is muted on some devices */
3139
+ case USB_ID(0x0d8c, 0x000c): /* C-Media */
3140
+ case USB_ID(0x0d8c, 0x0014): /* C-Media */
3141
+ case USB_ID(0x19f7, 0x0003): /* RODE NT-USB */
20033142 if (strstr(kctl->id.name, "Playback"))
20043143 cval->min_mute = 1;
20053144 break;