aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbmixer.c
diff options
context:
space:
mode:
authorSergiy Kovalchuk <cnb_zerg@yahoo.com>2009-12-27 12:13:41 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-28 06:29:39 -0500
commit7d2b451e65d255427c108e990507964ac39c13ee (patch)
tree86e977405ae88b08fa74dff3202c9f88207dfacb /sound/usb/usbmixer.c
parent44eba3e82b35ae796826a65d8040001582adc10a (diff)
ALSA: usb-audio - Added functionality for E-mu 0404USB/0202USB/TrackerPre
Added functionality: 1) Extension Units support (all XU settings now available at alsamixer, kmix, etc): - "AnalogueIn soft limiter" switch; - "Sample rate" selector (values 0,1,2,3,4,5 corresponds to 44.1 48 ... 192 kHz); - "DigitalIn CLK source" selector (internal/external) (**); - "DigitalOut format SPDIF/AC3" switch (**); (**)E-mu-0404usb only. 2) Automatic device sample rate adjustment depending on substream samplerate for both capture and playback substream. [minor coding-style fixes by tiwai] Signed-off-by: Sergiy Kovalchuk <cnb_zerg@yahoo.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/usbmixer.c')
-rw-r--r--sound/usb/usbmixer.c75
1 files changed, 71 insertions, 4 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index c998220b99c6..f5596cfdbde1 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -186,6 +186,21 @@ enum {
186 USB_PROC_DCR_RELEASE = 6, 186 USB_PROC_DCR_RELEASE = 6,
187}; 187};
188 188
189/*E-mu 0202(0404) eXtension Unit(XU) control*/
190enum {
191 USB_XU_CLOCK_RATE = 0xe301,
192 USB_XU_CLOCK_SOURCE = 0xe302,
193 USB_XU_DIGITAL_IO_STATUS = 0xe303,
194 USB_XU_DEVICE_OPTIONS = 0xe304,
195 USB_XU_DIRECT_MONITORING = 0xe305,
196 USB_XU_METERING = 0xe306
197};
198enum {
199 USB_XU_CLOCK_SOURCE_SELECTOR = 0x02, /* clock source*/
200 USB_XU_CLOCK_RATE_SELECTOR = 0x03, /* clock rate */
201 USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01, /* the spdif format */
202 USB_XU_SOFT_LIMIT_SELECTOR = 0x03 /* soft limiter */
203};
189 204
190/* 205/*
191 * manual mapping of mixer names 206 * manual mapping of mixer names
@@ -1330,7 +1345,32 @@ static struct procunit_info procunits[] = {
1330 { USB_PROC_DCR, "DCR", dcr_proc_info }, 1345 { USB_PROC_DCR, "DCR", dcr_proc_info },
1331 { 0 }, 1346 { 0 },
1332}; 1347};
1333 1348/*
1349 * predefined data for extension units
1350 */
1351static struct procunit_value_info clock_rate_xu_info[] = {
1352 { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
1353 { 0 }
1354};
1355static struct procunit_value_info clock_source_xu_info[] = {
1356 { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
1357 { 0 }
1358};
1359static struct procunit_value_info spdif_format_xu_info[] = {
1360 { USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN },
1361 { 0 }
1362};
1363static struct procunit_value_info soft_limit_xu_info[] = {
1364 { USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN },
1365 { 0 }
1366};
1367static struct procunit_info extunits[] = {
1368 { USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
1369 { USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
1370 { USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
1371 { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
1372 { 0 }
1373};
1334/* 1374/*
1335 * build a processing/extension unit 1375 * build a processing/extension unit
1336 */ 1376 */
@@ -1391,8 +1431,18 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1391 cval->max = dsc[15]; 1431 cval->max = dsc[15];
1392 cval->res = 1; 1432 cval->res = 1;
1393 cval->initialized = 1; 1433 cval->initialized = 1;
1394 } else 1434 } else {
1395 get_min_max(cval, valinfo->min_value); 1435 if (type == USB_XU_CLOCK_RATE) {
1436 /* E-Mu USB 0404/0202/TrackerPre
1437 * samplerate control quirk
1438 */
1439 cval->min = 0;
1440 cval->max = 5;
1441 cval->res = 1;
1442 cval->initialized = 1;
1443 } else
1444 get_min_max(cval, valinfo->min_value);
1445 }
1396 1446
1397 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); 1447 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
1398 if (! kctl) { 1448 if (! kctl) {
@@ -1433,7 +1483,7 @@ static int parse_audio_processing_unit(struct mixer_build *state, int unitid, un
1433 1483
1434static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1484static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc)
1435{ 1485{
1436 return build_audio_procunit(state, unitid, desc, NULL, "Extension Unit"); 1486 return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit");
1437} 1487}
1438 1488
1439 1489
@@ -2109,6 +2159,23 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
2109 return 0; 2159 return 0;
2110} 2160}
2111 2161
2162void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
2163 unsigned char samplerate_id)
2164{
2165 struct usb_mixer_interface *mixer;
2166 struct usb_mixer_elem_info *cval;
2167 int unitid = 12; /* SamleRate ExtensionUnit ID */
2168
2169 list_for_each_entry(mixer, &chip->mixer_list, list) {
2170 cval = mixer->id_elems[unitid];
2171 if (cval) {
2172 set_cur_ctl_value(cval, cval->control << 8, samplerate_id);
2173 snd_usb_mixer_notify_id(mixer, unitid);
2174 }
2175 break;
2176 }
2177}
2178
2112int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 2179int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2113 int ignore_error) 2180 int ignore_error)
2114{ 2181{