aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbmixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usbmixer.c')
-rw-r--r--sound/usb/usbmixer.c164
1 files changed, 85 insertions, 79 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 00397c8a765b..ecb58e7a6245 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -66,6 +66,7 @@ static const struct rc_config {
66 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */ 66 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
67 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ 67 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
68 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ 68 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
69 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
69}; 70};
70 71
71struct usb_mixer_interface { 72struct usb_mixer_interface {
@@ -78,7 +79,6 @@ struct usb_mixer_interface {
78 79
79 /* Sound Blaster remote control stuff */ 80 /* Sound Blaster remote control stuff */
80 const struct rc_config *rc_cfg; 81 const struct rc_config *rc_cfg;
81 unsigned long rc_hwdep_open;
82 u32 rc_code; 82 u32 rc_code;
83 wait_queue_head_t rc_waitq; 83 wait_queue_head_t rc_waitq;
84 struct urb *rc_urb; 84 struct urb *rc_urb;
@@ -110,6 +110,8 @@ struct mixer_build {
110 const struct usbmix_selector_map *selector_map; 110 const struct usbmix_selector_map *selector_map;
111}; 111};
112 112
113#define MAX_CHANNELS 10 /* max logical channels */
114
113struct usb_mixer_elem_info { 115struct usb_mixer_elem_info {
114 struct usb_mixer_interface *mixer; 116 struct usb_mixer_interface *mixer;
115 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */ 117 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
@@ -120,6 +122,8 @@ struct usb_mixer_elem_info {
120 int channels; 122 int channels;
121 int val_type; 123 int val_type;
122 int min, max, res; 124 int min, max, res;
125 int cached;
126 int cache_val[MAX_CHANNELS];
123 u8 initialized; 127 u8 initialized;
124}; 128};
125 129
@@ -181,8 +185,6 @@ enum {
181 USB_PROC_DCR_RELEASE = 6, 185 USB_PROC_DCR_RELEASE = 6,
182}; 186};
183 187
184#define MAX_CHANNELS 10 /* max logical channels */
185
186 188
187/* 189/*
188 * manual mapping of mixer names 190 * manual mapping of mixer names
@@ -219,7 +221,10 @@ static int check_ignored_ctl(struct mixer_build *state, int unitid, int control)
219 for (p = state->map; p->id; p++) { 221 for (p = state->map; p->id; p++) {
220 if (p->id == unitid && ! p->name && 222 if (p->id == unitid && ! p->name &&
221 (! control || ! p->control || control == p->control)) { 223 (! control || ! p->control || control == p->control)) {
222 // printk("ignored control %d:%d\n", unitid, control); 224 /*
225 printk(KERN_DEBUG "ignored control %d:%d\n",
226 unitid, control);
227 */
223 return 1; 228 return 1;
224 } 229 }
225 } 230 }
@@ -376,11 +381,35 @@ static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *
376} 381}
377 382
378/* channel = 0: master, 1 = first channel */ 383/* channel = 0: master, 1 = first channel */
379static inline int get_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, int *value) 384static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
385 int channel, int *value)
380{ 386{
381 return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value); 387 return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value);
382} 388}
383 389
390static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
391 int channel, int index, int *value)
392{
393 int err;
394
395 if (cval->cached & (1 << channel)) {
396 *value = cval->cache_val[index];
397 return 0;
398 }
399 err = get_cur_mix_raw(cval, channel, value);
400 if (err < 0) {
401 if (!cval->mixer->ignore_ctl_error)
402 snd_printd(KERN_ERR "cannot get current value for "
403 "control %d ch %d: err = %d\n",
404 cval->control, channel, err);
405 return err;
406 }
407 cval->cached |= 1 << channel;
408 cval->cache_val[index] = *value;
409 return 0;
410}
411
412
384/* 413/*
385 * set a mixer value 414 * set a mixer value
386 */ 415 */
@@ -412,9 +441,17 @@ static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int v
412 return set_ctl_value(cval, SET_CUR, validx, value); 441 return set_ctl_value(cval, SET_CUR, validx, value);
413} 442}
414 443
415static inline int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, int value) 444static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
445 int index, int value)
416{ 446{
417 return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value); 447 int err;
448 err = set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel,
449 value);
450 if (err < 0)
451 return err;
452 cval->cached |= 1 << channel;
453 cval->cache_val[index] = value;
454 return 0;
418} 455}
419 456
420/* 457/*
@@ -718,7 +755,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
718 if (cval->min + cval->res < cval->max) { 755 if (cval->min + cval->res < cval->max) {
719 int last_valid_res = cval->res; 756 int last_valid_res = cval->res;
720 int saved, test, check; 757 int saved, test, check;
721 get_cur_mix_value(cval, minchn, &saved); 758 get_cur_mix_raw(cval, minchn, &saved);
722 for (;;) { 759 for (;;) {
723 test = saved; 760 test = saved;
724 if (test < cval->max) 761 if (test < cval->max)
@@ -726,8 +763,8 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
726 else 763 else
727 test -= cval->res; 764 test -= cval->res;
728 if (test < cval->min || test > cval->max || 765 if (test < cval->min || test > cval->max ||
729 set_cur_mix_value(cval, minchn, test) || 766 set_cur_mix_value(cval, minchn, 0, test) ||
730 get_cur_mix_value(cval, minchn, &check)) { 767 get_cur_mix_raw(cval, minchn, &check)) {
731 cval->res = last_valid_res; 768 cval->res = last_valid_res;
732 break; 769 break;
733 } 770 }
@@ -735,7 +772,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
735 break; 772 break;
736 cval->res *= 2; 773 cval->res *= 2;
737 } 774 }
738 set_cur_mix_value(cval, minchn, saved); 775 set_cur_mix_value(cval, minchn, 0, saved);
739 } 776 }
740 777
741 cval->initialized = 1; 778 cval->initialized = 1;
@@ -775,35 +812,25 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
775 struct usb_mixer_elem_info *cval = kcontrol->private_data; 812 struct usb_mixer_elem_info *cval = kcontrol->private_data;
776 int c, cnt, val, err; 813 int c, cnt, val, err;
777 814
815 ucontrol->value.integer.value[0] = cval->min;
778 if (cval->cmask) { 816 if (cval->cmask) {
779 cnt = 0; 817 cnt = 0;
780 for (c = 0; c < MAX_CHANNELS; c++) { 818 for (c = 0; c < MAX_CHANNELS; c++) {
781 if (cval->cmask & (1 << c)) { 819 if (!(cval->cmask & (1 << c)))
782 err = get_cur_mix_value(cval, c + 1, &val); 820 continue;
783 if (err < 0) { 821 err = get_cur_mix_value(cval, c + 1, cnt, &val);
784 if (cval->mixer->ignore_ctl_error) { 822 if (err < 0)
785 ucontrol->value.integer.value[0] = cval->min; 823 return cval->mixer->ignore_ctl_error ? 0 : err;
786 return 0; 824 val = get_relative_value(cval, val);
787 } 825 ucontrol->value.integer.value[cnt] = val;
788 snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n", cval->control, c + 1, err); 826 cnt++;
789 return err;
790 }
791 val = get_relative_value(cval, val);
792 ucontrol->value.integer.value[cnt] = val;
793 cnt++;
794 }
795 } 827 }
828 return 0;
796 } else { 829 } else {
797 /* master channel */ 830 /* master channel */
798 err = get_cur_mix_value(cval, 0, &val); 831 err = get_cur_mix_value(cval, 0, 0, &val);
799 if (err < 0) { 832 if (err < 0)
800 if (cval->mixer->ignore_ctl_error) { 833 return cval->mixer->ignore_ctl_error ? 0 : err;
801 ucontrol->value.integer.value[0] = cval->min;
802 return 0;
803 }
804 snd_printd(KERN_ERR "cannot get current value for control %d master ch: err = %d\n", cval->control, err);
805 return err;
806 }
807 val = get_relative_value(cval, val); 834 val = get_relative_value(cval, val);
808 ucontrol->value.integer.value[0] = val; 835 ucontrol->value.integer.value[0] = val;
809 } 836 }
@@ -820,34 +847,28 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
820 if (cval->cmask) { 847 if (cval->cmask) {
821 cnt = 0; 848 cnt = 0;
822 for (c = 0; c < MAX_CHANNELS; c++) { 849 for (c = 0; c < MAX_CHANNELS; c++) {
823 if (cval->cmask & (1 << c)) { 850 if (!(cval->cmask & (1 << c)))
824 err = get_cur_mix_value(cval, c + 1, &oval); 851 continue;
825 if (err < 0) { 852 err = get_cur_mix_value(cval, c + 1, cnt, &oval);
826 if (cval->mixer->ignore_ctl_error) 853 if (err < 0)
827 return 0; 854 return cval->mixer->ignore_ctl_error ? 0 : err;
828 return err; 855 val = ucontrol->value.integer.value[cnt];
829 } 856 val = get_abs_value(cval, val);
830 val = ucontrol->value.integer.value[cnt]; 857 if (oval != val) {
831 val = get_abs_value(cval, val); 858 set_cur_mix_value(cval, c + 1, cnt, val);
832 if (oval != val) { 859 changed = 1;
833 set_cur_mix_value(cval, c + 1, val);
834 changed = 1;
835 }
836 get_cur_mix_value(cval, c + 1, &val);
837 cnt++;
838 } 860 }
861 cnt++;
839 } 862 }
840 } else { 863 } else {
841 /* master channel */ 864 /* master channel */
842 err = get_cur_mix_value(cval, 0, &oval); 865 err = get_cur_mix_value(cval, 0, 0, &oval);
843 if (err < 0 && cval->mixer->ignore_ctl_error)
844 return 0;
845 if (err < 0) 866 if (err < 0)
846 return err; 867 return cval->mixer->ignore_ctl_error ? 0 : err;
847 val = ucontrol->value.integer.value[0]; 868 val = ucontrol->value.integer.value[0];
848 val = get_abs_value(cval, val); 869 val = get_abs_value(cval, val);
849 if (val != oval) { 870 if (val != oval) {
850 set_cur_mix_value(cval, 0, val); 871 set_cur_mix_value(cval, 0, 0, val);
851 changed = 1; 872 changed = 1;
852 } 873 }
853 } 874 }
@@ -1706,7 +1727,8 @@ static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1706 break; 1727 break;
1707 /* live24ext: 4 = line-in jack */ 1728 /* live24ext: 4 = line-in jack */
1708 case 3: /* hp-out jack (may actuate Mute) */ 1729 case 3: /* hp-out jack (may actuate Mute) */
1709 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040)) 1730 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
1731 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
1710 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id); 1732 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
1711 break; 1733 break;
1712 default: 1734 default:
@@ -1797,24 +1819,6 @@ static void snd_usb_soundblaster_remote_complete(struct urb *urb)
1797 wake_up(&mixer->rc_waitq); 1819 wake_up(&mixer->rc_waitq);
1798} 1820}
1799 1821
1800static int snd_usb_sbrc_hwdep_open(struct snd_hwdep *hw, struct file *file)
1801{
1802 struct usb_mixer_interface *mixer = hw->private_data;
1803
1804 if (test_and_set_bit(0, &mixer->rc_hwdep_open))
1805 return -EBUSY;
1806 return 0;
1807}
1808
1809static int snd_usb_sbrc_hwdep_release(struct snd_hwdep *hw, struct file *file)
1810{
1811 struct usb_mixer_interface *mixer = hw->private_data;
1812
1813 clear_bit(0, &mixer->rc_hwdep_open);
1814 smp_mb__after_clear_bit();
1815 return 0;
1816}
1817
1818static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf, 1822static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
1819 long count, loff_t *offset) 1823 long count, loff_t *offset)
1820{ 1824{
@@ -1867,9 +1871,8 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
1867 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC; 1871 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
1868 hwdep->private_data = mixer; 1872 hwdep->private_data = mixer;
1869 hwdep->ops.read = snd_usb_sbrc_hwdep_read; 1873 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
1870 hwdep->ops.open = snd_usb_sbrc_hwdep_open;
1871 hwdep->ops.release = snd_usb_sbrc_hwdep_release;
1872 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll; 1874 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
1875 hwdep->exclusive = 1;
1873 1876
1874 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL); 1877 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
1875 if (!mixer->rc_urb) 1878 if (!mixer->rc_urb)
@@ -1956,8 +1959,9 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
1956 int i, err; 1959 int i, err;
1957 1960
1958 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { 1961 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
1959 if (i > 1 && /* Live24ext has 2 LEDs only */ 1962 if (i > 1 && /* Live24ext has 2 LEDs only */
1960 mixer->chip->usb_id == USB_ID(0x041e, 0x3040)) 1963 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
1964 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
1961 break; 1965 break;
1962 err = snd_ctl_add(mixer->chip->card, 1966 err = snd_ctl_add(mixer->chip->card,
1963 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer)); 1967 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
@@ -1994,7 +1998,8 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
1994 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname); 1998 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
1995 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) 1999 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
1996 jacks = jacks_audigy2nx; 2000 jacks = jacks_audigy2nx;
1997 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040)) 2001 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2002 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
1998 jacks = jacks_live24ext; 2003 jacks = jacks_live24ext;
1999 else 2004 else
2000 return; 2005 return;
@@ -2044,7 +2049,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2044 goto _error; 2049 goto _error;
2045 2050
2046 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || 2051 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2047 mixer->chip->usb_id == USB_ID(0x041e, 0x3040)) { 2052 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2053 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
2048 struct snd_info_entry *entry; 2054 struct snd_info_entry *entry;
2049 2055
2050 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 2056 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)