All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zerg Cannibal <cnb_zerg@yahoo.com>
To: alsa-devel@alsa-project.org
Subject: [PATCH 1/1] Added functionality for E-mu 0404USB/0202USB/TrackerPre
Date: Mon, 21 Dec 2009 12:39:27 -0800 (PST)	[thread overview]
Message-ID: <794724.87445.qm@web56107.mail.re3.yahoo.com> (raw)

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. 
  
Patch is based on Mac OS-X driver (http://sourceforge.net/projects/zaudiodrivermac/) and successfully tested by Ubuntu community users for 0404usb and 0202usb.

Signed-off-by: CannibalZerg <cnb_zerg@yahoo.com>
---
 sound/usb/usbaudio.c |   44 ++++++++++++++++++++++++++++++
 sound/usb/usbaudio.h |    2 +
 sound/usb/usbmixer.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 115 insertions(+), 4 deletions(-)

diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 31b63ea..d8eb029 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1271,6 +1271,42 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface,
 }
 
 /*
+ * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
+ * not for interface.
+*/
+static void set_format_emu_quirk(struct snd_usb_substream *subs, struct audioformat *fmt)
+{
+	unsigned char emu_samplerate_id = 0;
+
+	/* When capture is active sample rate shouldn't be changed by playback substream*/
+	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+		if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
+			return;
+	}
+
+	switch (fmt->rate_min) {
+	case 48000:
+		emu_samplerate_id = 1;
+		break;
+	case 88200:
+		emu_samplerate_id = 2;
+		break;
+	case 96000:
+		emu_samplerate_id = 3;
+		break;
+	case 176400:
+		emu_samplerate_id = 4;
+		break;
+	case 192000:
+		emu_samplerate_id = 5;
+		break;
+	default:
+		emu_samplerate_id = 0;
+	}
+	snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
+}
+
+/*
  * find a matching format and set up the interface
  */
 static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
@@ -1383,6 +1419,14 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 
 	subs->cur_audiofmt = fmt;
 
+	switch (subs->stream->chip->usb_id) {
+	case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
+	case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
+	case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
+		set_format_emu_quirk(subs, fmt);
+	break;
+	}
+
 #if 0
 	printk(KERN_DEBUG
 	       "setting done: format = %d, rate = %d..%d, channels = %d\n",
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 9826337..8558773 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -233,6 +233,8 @@ void snd_usbmidi_input_stop(struct list_head* p);
 void snd_usbmidi_input_start(struct list_head* p);
 void snd_usbmidi_disconnect(struct list_head *p);
 
+void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, unsigned char samplerate_id);
+
 /*
  * retrieve usb_interface descriptor from the host interface
  * (conditional for compatibility with the older API)
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index c998220..400208c 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -186,6 +186,21 @@ enum {
 	USB_PROC_DCR_RELEASE = 6,
 };
 
+/*E-mu 0202(0404) eXtension Unit(XU) control*/
+enum {
+  USB_XU_CLOCK_RATE 		= 0xe301,
+  USB_XU_CLOCK_SOURCE		= 0xe302,
+  USB_XU_DIGITAL_IO_STATUS	= 0xe303,
+  USB_XU_DEVICE_OPTIONS	= 0xe304,
+  USB_XU_DIRECT_MONITORING	= 0xe305,
+  USB_XU_METERING		= 0xe306
+};
+enum {
+	USB_XU_CLOCK_SOURCE_SELECTOR = 0x02,	/* clock source*/
+	USB_XU_CLOCK_RATE_SELECTOR = 0x03,	/* clock rate */
+	USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01,   /* the spdif format */
+	USB_XU_SOFT_LIMIT_SELECTOR = 0x03 /* soft limiter */
+};
 
 /*
  * manual mapping of mixer names
@@ -1330,7 +1345,32 @@ static struct procunit_info procunits[] = {
 	{ USB_PROC_DCR, "DCR", dcr_proc_info },
 	{ 0 },
 };
-
+/*
+ * predefined data for extension units
+ */
+static struct procunit_value_info clock_rate_xu_info[] = {
+       { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0},
+       { 0 }
+};
+static struct procunit_value_info clock_source_xu_info[] = {
+	{ USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN},
+	{ 0 }
+};
+static struct procunit_value_info spdif_format_xu_info[] = {
+	{ USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN},
+	{ 0 }
+};
+static struct procunit_value_info soft_limit_xu_info[] = {
+	{ USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN},
+	{ 0 }
+};
+static struct procunit_info extunits[] = {
+	{ USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
+	{ USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
+	{ USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
+	{ USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
+	{ 0 }
+};
 /*
  * build a processing/extension unit
  */
@@ -1391,8 +1431,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
 			cval->max = dsc[15];
 			cval->res = 1;
 			cval->initialized = 1;
-		} else
-			get_min_max(cval, valinfo->min_value);
+		} else {
+			if (type == USB_XU_CLOCK_RATE) {
+				/*E-Mu USB 0404/0202/TrackerPre samplerate control quirk*/
+						cval->min = 0;
+						cval->max = 5;
+						cval->res = 1;
+						cval->initialized = 1;
+			} else
+				get_min_max(cval, valinfo->min_value);
+		}
 
 		kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
 		if (! kctl) {
@@ -1433,7 +1481,7 @@ static int parse_audio_processing_unit(struct mixer_build *state, int unitid, un
 
 static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc)
 {
-	return build_audio_procunit(state, unitid, desc, NULL, "Extension Unit");
+	return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit");
 }
 
 
@@ -2109,6 +2157,23 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
 	return 0;
 }
 
+void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, unsigned char samplerate_id)
+{
+	 struct usb_mixer_interface *mixer;
+	 struct list_head *p;
+	 struct usb_mixer_elem_info *cval;
+	 int unitid = 12; /*SampleRate ExtensionUnit ID*/
+	 list_for_each(p, &chip->mixer_list) {
+		 mixer = list_entry(p, struct usb_mixer_interface, list);
+		 cval = mixer->id_elems[unitid];
+		 if (cval) {
+			 set_cur_ctl_value(cval, cval->control << 8, samplerate_id);
+			 snd_usb_mixer_notify_id(mixer, unitid);
+		 }
+		 break;
+	 }
+}
+
 int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
 			 int ignore_error)
 {
-- 
1.6.5.6

             reply	other threads:[~2009-12-21 20:39 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-21 20:39 Zerg Cannibal [this message]
2009-12-25 13:29 ` [PATCH 1/1] Added functionality for E-mu 0404USB/0202USB/TrackerPre Takashi Iwai
2009-12-27 16:50   ` Sergiy Kovalchuk
2009-12-27 17:13   ` Sergiy Kovalchuk
2009-12-28 11:33     ` Takashi Iwai
2009-12-27 12:04 ` James Courtier-Dutton
2009-12-27 15:05   ` Sergiy Kovalchuk
2009-12-28 10:47     ` James Courtier-Dutton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=794724.87445.qm@web56107.mail.re3.yahoo.com \
    --to=cnb_zerg@yahoo.com \
    --cc=alsa-devel@alsa-project.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.