]> Pileus Git - ~andy/linux/blobdiff - sound/usb/usbmixer.c
Pull remove-sn-bist-lock into release branch
[~andy/linux] / sound / usb / usbmixer.c
index ec880ff5262517c6f2c78ec96d2846b81bc8c4be..c3c08c9cb46edfceca5b018f9f5efe7897201aa0 100644 (file)
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/hwdep.h>
+#include <sound/info.h>
 
 #include "usbaudio.h"
 
-#if 0
-#include <linux/lirc.h>
-#else
-/* only those symbols from lirc.h we actually need: */
-#include <linux/ioctl.h>
-#define LIRC_MODE2REC(x)       ((x) << 16)
-#define LIRC_MODE_CODE         0x00000008
-#define LIRC_CAN_REC_CODE      LIRC_MODE2REC(LIRC_MODE_CODE)
-#define LIRC_GET_FEATURES      _IOR('i', 0x00000000, __u32)
-#define LIRC_GET_REC_MODE      _IOR('i', 0x00000002, __u32)
-#define LIRC_SET_REC_MODE      _IOW('i', 0x00000012, __u32)
-#endif
-
 /*
  */
 
@@ -375,7 +363,7 @@ static int get_cur_ctl_value(usb_mixer_elem_info_t *cval, int validx, int *value
 }
 
 /* channel = 0: master, 1 = first channel */
-inline static int get_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int *value)
+static inline int get_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int *value)
 {
        return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value);
 }
@@ -411,7 +399,7 @@ static int set_cur_ctl_value(usb_mixer_elem_info_t *cval, int validx, int value)
        return set_ctl_value(cval, SET_CUR, validx, value);
 }
 
-inline static int set_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int value)
+static inline int set_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int value)
 {
        return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value);
 }
@@ -635,10 +623,8 @@ static struct usb_feature_control_info audio_feature_info[] = {
 /* private_free callback */
 static void usb_mixer_elem_free(snd_kcontrol_t *kctl)
 {
-       if (kctl->private_data) {
-               kfree(kctl->private_data);
-               kctl->private_data = NULL;
-       }
+       kfree(kctl->private_data);
+       kctl->private_data = NULL;
 }
 
 
@@ -838,7 +824,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
        if (check_ignored_ctl(state, unitid, control))
                return;
 
-       cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+       cval = kzalloc(sizeof(*cval), GFP_KERNEL);
        if (! cval) {
                snd_printk(KERN_ERR "cannot malloc kcontrol\n");
                return;
@@ -1011,7 +997,7 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
        if (check_ignored_ctl(state, unitid, 0))
                return;
 
-       cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+       cval = kzalloc(sizeof(*cval), GFP_KERNEL);
        if (! cval)
                return;
 
@@ -1258,7 +1244,7 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char
                        continue;
                if (check_ignored_ctl(state, unitid, valinfo->control))
                        continue;
-               cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+               cval = kzalloc(sizeof(*cval), GFP_KERNEL);
                if (! cval) {
                        snd_printk(KERN_ERR "cannot malloc kcontrol\n");
                        return -ENOMEM;
@@ -1444,7 +1430,7 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned
        if (check_ignored_ctl(state, unitid, 0))
                return 0;
 
-       cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+       cval = kzalloc(sizeof(*cval), GFP_KERNEL);
        if (! cval) {
                snd_printk(KERN_ERR "cannot malloc kcontrol\n");
                return -ENOMEM;
@@ -1635,11 +1621,22 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
 static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
                                        int unitid)
 {
-       /* SB remote control */
-       if (mixer->rc_type != RC_NONE && unitid == 0) {
-               /* read control code from device memory */
+       if (mixer->rc_type == RC_NONE)
+               return;
+       /* unit ids specific to Extigy/Audigy 2 NX: */
+       switch (unitid) {
+       case 0: /* remote control */
                mixer->rc_urb->dev = mixer->chip->dev;
                usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
+               break;
+       case 4: /* digital in jack */
+       case 7: /* line in jacks */
+       case 19: /* speaker out jacks */
+       case 20: /* headphones out jack */
+               break;
+       default:
+               snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
+               break;
        }
 }
 
@@ -1775,25 +1772,6 @@ static unsigned int snd_usb_sbrc_hwdep_poll(snd_hwdep_t *hw, struct file *file,
        return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
 }
 
-static int snd_usb_sbrc_hwdep_ioctl(snd_hwdep_t *hw, struct file *file,
-                                   unsigned int cmd, unsigned long arg)
-{
-       u32 __user *argp = (u32 __user *)arg;
-       u32 mode;
-
-       switch (cmd) {
-       case LIRC_GET_FEATURES:
-               return put_user(LIRC_CAN_REC_CODE, argp);
-       case LIRC_GET_REC_MODE:
-               return put_user(LIRC_MODE_CODE, argp);
-       case LIRC_SET_REC_MODE:
-               if (get_user(mode, argp))
-                       return -EFAULT;
-               return mode == LIRC_MODE_CODE ? 0 : -ENOSYS;
-       }
-       return -ENOTTY;
-}
-
 static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
 {
        snd_hwdep_t *hwdep;
@@ -1824,7 +1802,6 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
        hwdep->ops.open = snd_usb_sbrc_hwdep_open;
        hwdep->ops.release = snd_usb_sbrc_hwdep_release;
        hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
-       hwdep->ops.ioctl = snd_usb_sbrc_hwdep_ioctl; 
 
        mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!mixer->rc_urb)
@@ -1927,6 +1904,37 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
        return 0;
 }
 
+static void snd_audigy2nx_proc_read(snd_info_entry_t *entry,
+                                   snd_info_buffer_t *buffer)
+{
+       static const struct {
+               int unitid;
+               const char *name;
+       } jacks[] = {
+               {4,  "dig in "},
+               {7,  "line in"},
+               {19, "spk out"},
+               {20, "hph out"},
+       };
+       struct usb_mixer_interface *mixer = entry->private_data;
+       int i, err;
+       u8 buf[3];
+
+       snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
+       for (i = 0; i < ARRAY_SIZE(jacks); ++i) {
+               snd_iprintf(buffer, "%s: ", jacks[i].name);
+               err = snd_usb_ctl_msg(mixer->chip->dev,
+                                     usb_rcvctrlpipe(mixer->chip->dev, 0),
+                                     GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
+                                     USB_RECIP_INTERFACE, 0,
+                                     jacks[i].unitid << 8, buf, 3, 100);
+               if (err == 3 && buf[0] == 3)
+                       snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
+               else
+                       snd_iprintf(buffer, "?\n");
+       }
+}
+
 int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
 {
        static snd_device_ops_t dev_ops = {
@@ -1937,7 +1945,7 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
 
        strcpy(chip->card->mixername, "USB Mixer");
 
-       mixer = kcalloc(1, sizeof(*mixer), GFP_KERNEL);
+       mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
        if (!mixer)
                return -ENOMEM;
        mixer->chip = chip;
@@ -1959,8 +1967,13 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
                goto _error;
 
        if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) {
+               snd_info_entry_t *entry;
+
                if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
                        goto _error;
+               if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
+                       snd_info_set_text_ops(entry, mixer, 1024,
+                                             snd_audigy2nx_proc_read);
        }
 
        err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);