Merge branch 'topic/usb-caiaq' into for-linus
Takashi Iwai [Mon, 23 Mar 2009 23:36:23 +0000 (00:36 +0100)]
sound/usb/Kconfig
sound/usb/caiaq/caiaq-audio.c
sound/usb/caiaq/caiaq-control.c
sound/usb/caiaq/caiaq-device.c
sound/usb/caiaq/caiaq-device.h

index 4f0eac9..523aec1 100644 (file)
@@ -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.
index b3a6033..08d51e0 100644 (file)
@@ -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;
index ccd763d..e92c2bb 100644 (file)
@@ -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;
index 09aed23..cf573a9 100644 (file)
 #endif
 
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-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 +
index ab56e73..4cce1ad 100644 (file)
 #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];