Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9a25e04 authored by Matt Gruskin's avatar Matt Gruskin Committed by Takashi Iwai
Browse files

ALSA: usb-audio: add support for M-Audio FT C600



Adds quirks and mixer support for the M-Audio Fast Track C600 USB
audio interface. This device is very similar to the C400 - the C600
simply has some more inputs and outputs, so the existing C400 support
is extended to support this device as well.

Signed-off-by: default avatarMatt Gruskin <matthew.gruskin@gmail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b3667bd7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -807,6 +807,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
{
	switch (cval->mixer->chip->usb_id) {
	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
		if (strcmp(kctl->id.name, "Effect Duration") == 0) {
			cval->min = 0x0000;
			cval->max = 0xffff;
+4 −0
Original line number Diff line number Diff line
@@ -379,6 +379,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
		.id = USB_ID(0x0763, 0x2030),
		.selector_map = c400_selectors,
	},
	{
		.id = USB_ID(0x0763, 0x2031),
		.selector_map = c400_selectors,
	},
	{
		.id = USB_ID(0x08bb, 0x2702),
		.map = linex_map,
+56 −16
Original line number Diff line number Diff line
@@ -637,7 +637,7 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
}

/* M-Audio FastTrack Ultra quirks */
/* FTU Effect switch (also used by C400) */
/* FTU Effect switch (also used by C400/C600) */
struct snd_ftu_eff_switch_priv_val {
	struct usb_mixer_interface *mixer;
	int cached_value;
@@ -1029,32 +1029,45 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
	}
}

/* M-Audio Fast Track C400 */
/* C400 volume controls, this control needs a volume quirk, see mixer.c */
/* M-Audio Fast Track C400/C600 */
/* C400/C600 volume controls, this control needs a volume quirk, see mixer.c */
static int snd_c400_create_vol_ctls(struct usb_mixer_interface *mixer)
{
	char name[64];
	unsigned int cmask, offset;
	int out, chan, err;
	int num_outs = 0;
	int num_ins = 0;

	const unsigned int id = 0x40;
	const int val_type = USB_MIXER_S16;
	const int control = 1;

	for (chan = 0; chan < 10; chan++) {
		for (out = 0; out < 6; out++) {
			if (chan < 6) {
	switch (mixer->chip->usb_id) {
	case USB_ID(0x0763, 0x2030):
		num_outs = 6;
		num_ins = 4;
		break;
	case USB_ID(0x0763, 0x2031):
		num_outs = 8;
		num_ins = 6;
		break;
	}

	for (chan = 0; chan < num_outs + num_ins; chan++) {
		for (out = 0; out < num_outs; out++) {
			if (chan < num_outs) {
				snprintf(name, sizeof(name),
					"PCM%d-Out%d Playback Volume",
					chan + 1, out + 1);
			} else {
				snprintf(name, sizeof(name),
					"In%d-Out%d Playback Volume",
					chan - 5, out + 1);
					chan - num_outs + 1, out + 1);
			}

			cmask = (out == 0) ? 0 : 1 << (out - 1);
			offset = chan * 6;
			offset = chan * num_outs;
			err = snd_create_std_mono_ctl_offset(mixer, id, control,
						cmask, val_type, offset, name,
						&snd_usb_mixer_vol_tlv);
@@ -1110,20 +1123,33 @@ static int snd_c400_create_effect_vol_ctls(struct usb_mixer_interface *mixer)
	char name[64];
	unsigned int cmask;
	int chan, err;
	int num_outs = 0;
	int num_ins = 0;

	const unsigned int id = 0x42;
	const int val_type = USB_MIXER_S16;
	const int control = 1;

	for (chan = 0; chan < 10; chan++) {
		if (chan < 6) {
	switch (mixer->chip->usb_id) {
	case USB_ID(0x0763, 0x2030):
		num_outs = 6;
		num_ins = 4;
		break;
	case USB_ID(0x0763, 0x2031):
		num_outs = 8;
		num_ins = 6;
		break;
	}

	for (chan = 0; chan < num_outs + num_ins; chan++) {
		if (chan < num_outs) {
			snprintf(name, sizeof(name),
				"Effect Send DOut%d",
				chan + 1);
		} else {
			snprintf(name, sizeof(name),
				"Effect Send AIn%d",
				chan - 5);
				chan - num_outs + 1);
		}

		cmask = (chan == 0) ? 0 : 1 << (chan - 1);
@@ -1142,20 +1168,33 @@ static int snd_c400_create_effect_ret_vol_ctls(struct usb_mixer_interface *mixer
	char name[64];
	unsigned int cmask;
	int chan, err;
	int num_outs = 0;
	int offset = 0;

	const unsigned int id = 0x40;
	const int val_type = USB_MIXER_S16;
	const int control = 1;
	const int chan_id[6] = { 0, 7, 2, 9, 4, 0xb };
	const unsigned int offset = 0x3c;

	switch (mixer->chip->usb_id) {
	case USB_ID(0x0763, 0x2030):
		num_outs = 6;
		offset = 0x3c;
		/* { 0x3c, 0x43, 0x3e, 0x45, 0x40, 0x47 } */
		break;
	case USB_ID(0x0763, 0x2031):
		num_outs = 8;
		offset = 0x70;
		/* { 0x70, 0x79, 0x72, 0x7b, 0x74, 0x7d, 0x76, 0x7f } */
		break;
	}

	for (chan = 0; chan < 6; chan++) {
	for (chan = 0; chan < num_outs; chan++) {
		snprintf(name, sizeof(name),
			"Effect Return %d",
			chan + 1);

		cmask = (chan_id[chan] == 0) ? 0 : 1 << (chan_id[chan] - 1);
		cmask = (chan == 0) ? 0 :
			1 << (chan + (chan % 2) * num_outs - 1);
		err = snd_create_std_mono_ctl_offset(mixer, id, control,
						cmask, val_type, offset, name,
						&snd_usb_mixer_vol_tlv);
@@ -1299,6 +1338,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
		break;

	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */
		err = snd_c400_create_mixer(mixer);
		break;

+1 −0
Original line number Diff line number Diff line
@@ -367,6 +367,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)

	switch (subs->stream->chip->usb_id) {
	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
		if (is_playback) {
			implicit_fb = 1;
			ep = 0x81;
+71 −0
Original line number Diff line number Diff line
@@ -2325,6 +2325,77 @@ YAMAHA_DEVICE(0x7010, "UB99"),
		}
	}
},
{
	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2031),
	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
		/* .vendor_name = "M-Audio", */
		/* .product_name = "Fast Track C600", */
		.ifnum = QUIRK_ANY_INTERFACE,
		.type = QUIRK_COMPOSITE,
		.data = &(const struct snd_usb_audio_quirk[]) {
			{
				.ifnum = 1,
				.type = QUIRK_AUDIO_STANDARD_MIXER,
			},
			/* Playback */
			{
				.ifnum = 2,
				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
				.data = &(const struct audioformat) {
					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
					.channels = 8,
					.iface = 2,
					.altsetting = 1,
					.altset_idx = 1,
					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
					.endpoint = 0x01,
					.ep_attr = 0x09,
					.rates = SNDRV_PCM_RATE_44100 |
						 SNDRV_PCM_RATE_48000 |
						 SNDRV_PCM_RATE_88200 |
						 SNDRV_PCM_RATE_96000,
					.rate_min = 44100,
					.rate_max = 96000,
					.nr_rates = 4,
					.rate_table = (unsigned int[]) {
							44100, 48000, 88200, 96000
					},
					.clock = 0x80,
				}
			},
			/* Capture */
			{
				.ifnum = 3,
				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
				.data = &(const struct audioformat) {
					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
					.channels = 6,
					.iface = 3,
					.altsetting = 1,
					.altset_idx = 1,
					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
					.endpoint = 0x81,
					.ep_attr = 0x05,
					.rates = SNDRV_PCM_RATE_44100 |
						 SNDRV_PCM_RATE_48000 |
						 SNDRV_PCM_RATE_88200 |
						 SNDRV_PCM_RATE_96000,
					.rate_min = 44100,
					.rate_max = 96000,
					.nr_rates = 4,
					.rate_table = (unsigned int[]) {
						44100, 48000, 88200, 96000
					},
					.clock = 0x80,
				}
			},
			/* MIDI */
			{
				.ifnum = -1 /* Interface = 4 */
			}
		}
	}
},
{
	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
Loading