diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 4f0eac9bff1e..523aec188ccf 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig @@ -48,7 +48,10 @@ config SND_USB_CAIAQ * Native Instruments Kore Controller * Native Instruments Kore Controller 2 * Native Instruments Audio Kontrol 1 + * Native Instruments Audio 4 DJ * Native Instruments Audio 8 DJ + * Native Instruments Guitar Rig Session I/O + * Native Instruments Guitar Rig mobile To compile this driver as a module, choose M here: the module will be called snd-usb-caiaq. diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c index b3a603325835..08d51e0c9fea 100644 --- a/sound/usb/caiaq/caiaq-audio.c +++ b/sound/usb/caiaq/caiaq-audio.c @@ -114,6 +114,7 @@ static int stream_start(struct snd_usb_caiaqdev *dev) dev->output_panic = 0; dev->first_packet = 1; dev->streaming = 1; + dev->warned = 0; for (i = 0; i < N_URBS; i++) { ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC); @@ -376,6 +377,9 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, for (stream = 0; stream < dev->n_streams; stream++, i++) { sub = dev->sub_capture[stream]; + if (dev->input_panic) + usb_buf[i] = 0; + if (sub) { struct snd_pcm_runtime *rt = sub->runtime; char *audio_buf = rt->dma_area; @@ -397,6 +401,9 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev, if (!dev->streaming) return; + if (iso->actual_length < dev->bpp) + return; + switch (dev->spec.data_alignment) { case 0: read_in_urb_mode0(dev, urb, iso); @@ -406,10 +413,11 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev, break; } - if (dev->input_panic || dev->output_panic) { + if ((dev->input_panic || dev->output_panic) && !dev->warned) { debug("streaming error detected %s %s\n", dev->input_panic ? "(input)" : "", dev->output_panic ? "(output)" : ""); + dev->warned = 1; } } @@ -638,9 +646,10 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO): - dev->samplerates |= SNDRV_PCM_RATE_88200; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE): dev->samplerates |= SNDRV_PCM_RATE_192000; - break; + /* fall thru */ + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): dev->samplerates |= SNDRV_PCM_RATE_88200; break; diff --git a/sound/usb/caiaq/caiaq-control.c b/sound/usb/caiaq/caiaq-control.c index ccd763dd7167..e92c2bbf4fe9 100644 --- a/sound/usb/caiaq/caiaq-control.c +++ b/sound/usb/caiaq/caiaq-control.c @@ -39,12 +39,12 @@ static int control_info(struct snd_kcontrol *kcontrol, struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); int pos = kcontrol->private_value; int is_intval = pos & CNT_INTVAL; + unsigned int id = dev->chip.usb_id; uinfo->count = 1; pos &= ~CNT_INTVAL; - if (dev->chip.usb_id == - USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ) + if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ) && (pos == 0)) { /* current input mode of A8DJ */ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -53,6 +53,15 @@ static int control_info(struct snd_kcontrol *kcontrol, return 0; } + if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ) + && (pos == 0)) { + /* current input mode of A4DJ */ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; + } + if (is_intval) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->value.integer.min = 0; @@ -73,6 +82,14 @@ static int control_get(struct snd_kcontrol *kcontrol, struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); int pos = kcontrol->private_value; + if (dev->chip.usb_id == + USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { + /* A4DJ has only one control */ + /* do not expose hardware input mode 0 */ + ucontrol->value.integer.value[0] = dev->control_state[0] - 1; + return 0; + } + if (pos & CNT_INTVAL) ucontrol->value.integer.value[0] = dev->control_state[pos & ~CNT_INTVAL]; @@ -90,10 +107,20 @@ static int control_put(struct snd_kcontrol *kcontrol, struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); int pos = kcontrol->private_value; + if (dev->chip.usb_id == + USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { + /* A4DJ has only one control */ + /* do not expose hardware input mode 0 */ + dev->control_state[0] = ucontrol->value.integer.value[0] + 1; + snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, + dev->control_state, sizeof(dev->control_state)); + return 1; + } + if (pos & CNT_INTVAL) { dev->control_state[pos & ~CNT_INTVAL] = ucontrol->value.integer.value[0]; - snd_usb_caiaq_send_command(dev, EP1_CMD_DIMM_LEDS, + snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, dev->control_state, sizeof(dev->control_state)); } else { if (ucontrol->value.integer.value[0]) @@ -243,10 +270,13 @@ static struct caiaq_controller a8dj_controller[] = { { "GND lift for TC Vinyl mode", 24 + 0 }, { "GND lift for TC CD/Line mode", 24 + 1 }, { "GND lift for phono mode", 24 + 2 }, - { "GND lift for TC Vinyl mode", 24 + 3 }, { "Software lock", 40 } }; +static struct caiaq_controller a4dj_controller[] = { + { "Current input mode", 0 | CNT_INTVAL } +}; + static int __devinit add_controls(struct caiaq_controller *c, int num, struct snd_usb_caiaqdev *dev) { @@ -295,6 +325,10 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) ret = add_controls(a8dj_controller, ARRAY_SIZE(a8dj_controller), dev); break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): + ret = add_controls(a4dj_controller, + ARRAY_SIZE(a4dj_controller), dev); + break; } return ret; diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c index 09aed2363cc9..cf573a982fdc 100644 --- a/sound/usb/caiaq/caiaq-device.c +++ b/sound/usb/caiaq/caiaq-device.c @@ -42,15 +42,17 @@ #endif MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("caiaq USB audio, version 1.3.10"); +MODULE_DESCRIPTION("caiaq USB audio, version 1.3.13"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," "{Native Instruments, RigKontrol3}," "{Native Instruments, Kore Controller}," "{Native Instruments, Kore Controller 2}," "{Native Instruments, Audio Kontrol 1}," + "{Native Instruments, Audio 4 DJ}," "{Native Instruments, Audio 8 DJ}," - "{Native Instruments, Session I/O}}"); + "{Native Instruments, Session I/O}," + "{Native Instruments, GuitarRig mobile}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ @@ -116,6 +118,16 @@ static struct usb_device_id snd_usb_id_table[] = { .idVendor = USB_VID_NATIVEINSTRUMENTS, .idProduct = USB_PID_SESSIONIO }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_GUITARRIGMOBILE + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_AUDIO4DJ + }, { /* terminator */ } }; @@ -239,6 +251,8 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, if (dev->audio_parm_answer != 1) debug("unable to set the device's audio params\n"); + else + dev->bpp = bpp; return dev->audio_parm_answer == 1 ? 0 : -EINVAL; } @@ -300,6 +314,12 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) } break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): + /* Audio 4 DJ - default input mode to phono */ + dev->control_state[0] = 2; + snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, + dev->control_state, 1); + break; } if (dev->spec.num_analog_audio_out + diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h index ab56e738c5fc..4cce1ad7493d 100644 --- a/sound/usb/caiaq/caiaq-device.h +++ b/sound/usb/caiaq/caiaq-device.h @@ -10,8 +10,10 @@ #define USB_PID_KORECONTROLLER 0x4711 #define USB_PID_KORECONTROLLER2 0x4712 #define USB_PID_AK1 0x0815 +#define USB_PID_AUDIO4DJ 0x0839 #define USB_PID_AUDIO8DJ 0x1978 #define USB_PID_SESSIONIO 0x1915 +#define USB_PID_GUITARRIGMOBILE 0x0d8d #define EP1_BUFSIZE 64 #define CAIAQ_USB_STR_LEN 0xff @@ -87,9 +89,9 @@ struct snd_usb_caiaqdev { int audio_out_buf_pos[MAX_STREAMS]; int period_in_count[MAX_STREAMS]; int period_out_count[MAX_STREAMS]; - int input_panic, output_panic; + int input_panic, output_panic, warned; char *audio_in_buf, *audio_out_buf; - unsigned int samplerates; + unsigned int samplerates, bpp; struct snd_pcm_substream *sub_playback[MAX_STREAMS]; struct snd_pcm_substream *sub_capture[MAX_STREAMS];