* [PATCH - Add mixer support for M-Audio FTU series 1/1]Add basic mixer support for M-Audio FTU (8R)
@ 2010-09-25 6:36 linuxaudio
2010-09-25 6:36 ` linuxaudio
0 siblings, 1 reply; 2+ messages in thread
From: linuxaudio @ 2010-09-25 6:36 UTC (permalink / raw)
To: patch; +Cc: alsa-devel
And again, next try (somehow my mail address has not been accepted despite registration)
This patch (against alsa-kmirror) adds mixer support for M-Audio Fast Track Ultra (8R) devices.
It should be suitable as a blueprint for adding mixer support to other devices with missing/wrong descriptors.
I needed to move some enums to header files, raise MAX_CHANNELS, and slightly modify snd_usb_audio_probe().
If this get accepted I will work on the effects unit in the FTU devices. It's straight forward work based on this.
Kind regards,
Felix
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH - Add mixer support for M-Audio FTU series 1/1]Add basic mixer support for M-Audio FTU (8R)
2010-09-25 6:36 [PATCH - Add mixer support for M-Audio FTU series 1/1]Add basic mixer support for M-Audio FTU (8R) linuxaudio
@ 2010-09-25 6:36 ` linuxaudio
0 siblings, 0 replies; 2+ messages in thread
From: linuxaudio @ 2010-09-25 6:36 UTC (permalink / raw)
To: patch; +Cc: alsa-devel, Felix Homann
From: Felix Homann <linuxaudio@showlabor.de>
Signed-off-by: Felix Homann <linuxaudio@showlabor.de>
diff --git a/usb/card.c b/usb/card.c
index 800f7cb..28efd7b 100644
--- a/usb/card.c
+++ b/usb/card.c
@@ -489,6 +489,11 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
if (!chip->ctrl_intf)
chip->ctrl_intf = alts;
+ /* try to create a mixer for quirked devices, too */
+ if (snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
+ goto __error;
+ }
+
if (err > 0) {
/* create normal USB audio interfaces */
if (snd_usb_create_streams(chip, ifnum) < 0 ||
diff --git a/usb/mixer.c b/usb/mixer.c
index 3ed3901..edb9893 100644
--- a/usb/mixer.c
+++ b/usb/mixer.c
@@ -85,16 +85,6 @@ struct mixer_build {
const struct usbmix_selector_map *selector_map;
};
-enum {
- USB_MIXER_BOOLEAN,
- USB_MIXER_INV_BOOLEAN,
- USB_MIXER_S8,
- USB_MIXER_U8,
- USB_MIXER_S16,
- USB_MIXER_U16,
-};
-
-
/*E-mu 0202(0404) eXtension Unit(XU) control*/
enum {
USB_XU_CLOCK_RATE = 0xe301,
@@ -2149,6 +2139,71 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
return 0;
}
+/* This is just the same as 'add_control_to_empty' but using a mixer instead of a mixer_build */
+int add_unique_control_to_empty_mixer(struct usb_mixer_interface *mixer, struct snd_kcontrol *kctl)
+{
+ struct usb_mixer_elem_info *cval = kctl->private_data;
+ int err;
+
+ /* No duplicates! */
+ if (snd_ctl_find_id(mixer->chip->card, &kctl->id))
+ return 0;
+
+ if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) {
+ snd_printd(KERN_ERR "cannot add control (err = %d)\n", err);
+ return err;
+ }
+
+ cval->elem_id = &kctl->id;
+ cval->next_id_elem = mixer->id_elems[cval->id];
+ mixer->id_elems[cval->id] = cval;
+
+ return 0;
+}
+
+int build_named_mixer_unit_ctl(struct usb_mixer_interface *mixer,
+ int in_pin, int in_ch, int unitid, int val_type, unsigned int cmask, char *ctrl_name, int channels)
+{
+ struct usb_mixer_elem_info *cval;
+ struct snd_kcontrol *kctl;
+ int err;
+
+ cval = kzalloc(sizeof(*cval), GFP_KERNEL);
+ if (!cval)
+ return -1;
+
+ cval->mixer = mixer;
+ cval->id = unitid;
+ cval->control = in_ch + 1; /* based on 1 */
+ cval->val_type = val_type; /* like USB_MIXER_S16 etc. */
+ if (!((0 < channels) && (channels <= MAX_CHANNELS)))
+ return -1;
+ cval->channels = 1;
+ cval->cmask = cmask;
+ /* get min/max values */
+ get_min_max(cval, 0);
+
+ kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
+ if (!kctl) {
+ snd_printk(KERN_ERR "cannot malloc kcontrol\n");
+ kfree(cval);
+ return -1;
+ }
+
+ kctl->tlv.c = mixer_vol_tlv;
+ kctl->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
+ kctl->private_free = usb_mixer_elem_free;
+
+ sprintf(kctl->id.name, ctrl_name);
+
+ if (err = add_unique_control_to_empty_mixer(mixer, kctl))
+ return err;
+
+ return 0;
+}
+
int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
int ignore_error)
{
diff --git a/usb/mixer.h b/usb/mixer.h
index 26c636c..f7378c5 100644
--- a/usb/mixer.h
+++ b/usb/mixer.h
@@ -24,7 +24,16 @@ struct usb_mixer_interface {
u8 xonar_u1_status;
};
-#define MAX_CHANNELS 10 /* max logical channels */
+#define MAX_CHANNELS 16 /* max logical channels */
+
+enum {
+ USB_MIXER_BOOLEAN,
+ USB_MIXER_INV_BOOLEAN,
+ USB_MIXER_S8,
+ USB_MIXER_U8,
+ USB_MIXER_S16,
+ USB_MIXER_U16,
+};
struct usb_mixer_elem_info {
struct usb_mixer_interface *mixer;
@@ -53,4 +62,7 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
int request, int validx, int value_set);
+int build_named_mixer_unit_ctl(struct usb_mixer_interface *mixer,
+ int in_pin, int in_ch, int unitid, int val_type, unsigned int cmask,
+ char* ctrl_name, int channels);
#endif /* __USBMIXER_H */
diff --git a/usb/mixer_quirks.c b/usb/mixer_quirks.c
index e7df1e5..7843451 100644
--- a/usb/mixer_quirks.c
+++ b/usb/mixer_quirks.c
@@ -354,6 +354,32 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
}
}
+int snd_ftu_controls_create(struct usb_mixer_interface *mixer)
+{
+ char name[44];
+ int out, in_ch, unitid, err;
+ unsigned int cmask;
+ int val_type = USB_MIXER_S16;
+ int channels = 1;
+ unitid = 5; // FTU's unit id
+
+ for (out = 0; out < 8; ++out) {
+ for (in_ch = 0; in_ch < 16; ++in_ch) {
+ cmask = (1 << in_ch);
+ if (in_ch < 8)
+ sprintf(name, "AIn%d - Out%d Capture Volume", in_ch + 1, out + 1);
+ else if (in_ch >= 8)
+ sprintf(name, "DIn%d - Out%d Playback Volume", in_ch - 7, out + 1);
+ if ((err = build_named_mixer_unit_ctl(mixer, in_ch, out, unitid,
+ val_type, cmask, name, channels))) {
+ return err;
+ }
+ }
+ }
+
+ return 0;
+}
+
int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
{
int err;
@@ -379,6 +405,14 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
return err;
}
+ /* M-Audio Fast Track Ultra (8R) */
+ if (mixer->chip->usb_id == USB_ID(0x0763, 0x2080) ||
+ mixer->chip->usb_id == USB_ID(0x0763, 0x2081)) {
+ err = snd_ftu_controls_create(mixer);
+ if (err < 0)
+ return err;
+ }
+
return 0;
}
diff --git a/usb/usbmixer.h b/usb/usbmixer.h
index 63101ae..0ddbeab 100644
--- a/usb/usbmixer.h
+++ b/usb/usbmixer.h
@@ -22,7 +22,7 @@ struct usb_mixer_interface {
u8 xonar_u1_status;
};
-#define MAX_CHANNELS 10 /* max logical channels */
+#define MAX_CHANNELS 16 /* max logical channels */
struct usb_mixer_elem_info {
struct usb_mixer_interface *mixer;
--
1.7.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-09-25 6:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-25 6:36 [PATCH - Add mixer support for M-Audio FTU series 1/1]Add basic mixer support for M-Audio FTU (8R) linuxaudio
2010-09-25 6:36 ` linuxaudio
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.