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.c142
1 files changed, 84 insertions, 58 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 2bde79216fa5..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 {
@@ -109,6 +110,8 @@ struct mixer_build {
109 const struct usbmix_selector_map *selector_map; 110 const struct usbmix_selector_map *selector_map;
110}; 111};
111 112
113#define MAX_CHANNELS 10 /* max logical channels */
114
112struct usb_mixer_elem_info { 115struct usb_mixer_elem_info {
113 struct usb_mixer_interface *mixer; 116 struct usb_mixer_interface *mixer;
114 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 */
@@ -119,6 +122,8 @@ struct usb_mixer_elem_info {
119 int channels; 122 int channels;
120 int val_type; 123 int val_type;
121 int min, max, res; 124 int min, max, res;
125 int cached;
126 int cache_val[MAX_CHANNELS];
122 u8 initialized; 127 u8 initialized;
123}; 128};
124 129
@@ -180,8 +185,6 @@ enum {
180 USB_PROC_DCR_RELEASE = 6, 185 USB_PROC_DCR_RELEASE = 6,
181}; 186};
182 187
183#define MAX_CHANNELS 10 /* max logical channels */
184
185 188
186/* 189/*
187 * manual mapping of mixer names 190 * manual mapping of mixer names
@@ -218,7 +221,10 @@ static int check_ignored_ctl(struct mixer_build *state, int unitid, int control)
218 for (p = state->map; p->id; p++) { 221 for (p = state->map; p->id; p++) {
219 if (p->id == unitid && ! p->name && 222 if (p->id == unitid && ! p->name &&
220 (! control || ! p->control || control == p->control)) { 223 (! control || ! p->control || control == p->control)) {
221 // printk("ignored control %d:%d\n", unitid, control); 224 /*
225 printk(KERN_DEBUG "ignored control %d:%d\n",
226 unitid, control);
227 */
222 return 1; 228 return 1;
223 } 229 }
224 } 230 }
@@ -375,11 +381,35 @@ static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *
375} 381}
376 382
377/* channel = 0: master, 1 = first channel */ 383/* channel = 0: master, 1 = first channel */
378static 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)
379{ 386{
380 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);
381} 388}
382 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
383/* 413/*
384 * set a mixer value 414 * set a mixer value
385 */ 415 */
@@ -411,9 +441,17 @@ static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int v
411 return set_ctl_value(cval, SET_CUR, validx, value); 441 return set_ctl_value(cval, SET_CUR, validx, value);
412} 442}
413 443
414static 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)
415{ 446{
416 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;
417} 455}
418 456
419/* 457/*
@@ -717,7 +755,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
717 if (cval->min + cval->res < cval->max) { 755 if (cval->min + cval->res < cval->max) {
718 int last_valid_res = cval->res; 756 int last_valid_res = cval->res;
719 int saved, test, check; 757 int saved, test, check;
720 get_cur_mix_value(cval, minchn, &saved); 758 get_cur_mix_raw(cval, minchn, &saved);
721 for (;;) { 759 for (;;) {
722 test = saved; 760 test = saved;
723 if (test < cval->max) 761 if (test < cval->max)
@@ -725,8 +763,8 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
725 else 763 else
726 test -= cval->res; 764 test -= cval->res;
727 if (test < cval->min || test > cval->max || 765 if (test < cval->min || test > cval->max ||
728 set_cur_mix_value(cval, minchn, test) || 766 set_cur_mix_value(cval, minchn, 0, test) ||
729 get_cur_mix_value(cval, minchn, &check)) { 767 get_cur_mix_raw(cval, minchn, &check)) {
730 cval->res = last_valid_res; 768 cval->res = last_valid_res;
731 break; 769 break;
732 } 770 }
@@ -734,7 +772,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
734 break; 772 break;
735 cval->res *= 2; 773 cval->res *= 2;
736 } 774 }
737 set_cur_mix_value(cval, minchn, saved); 775 set_cur_mix_value(cval, minchn, 0, saved);
738 } 776 }
739 777
740 cval->initialized = 1; 778 cval->initialized = 1;
@@ -774,35 +812,25 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
774 struct usb_mixer_elem_info *cval = kcontrol->private_data; 812 struct usb_mixer_elem_info *cval = kcontrol->private_data;
775 int c, cnt, val, err; 813 int c, cnt, val, err;
776 814
815 ucontrol->value.integer.value[0] = cval->min;
777 if (cval->cmask) { 816 if (cval->cmask) {
778 cnt = 0; 817 cnt = 0;
779 for (c = 0; c < MAX_CHANNELS; c++) { 818 for (c = 0; c < MAX_CHANNELS; c++) {
780 if (cval->cmask & (1 << c)) { 819 if (!(cval->cmask & (1 << c)))
781 err = get_cur_mix_value(cval, c + 1, &val); 820 continue;
782 if (err < 0) { 821 err = get_cur_mix_value(cval, c + 1, cnt, &val);
783 if (cval->mixer->ignore_ctl_error) { 822 if (err < 0)
784 ucontrol->value.integer.value[0] = cval->min; 823 return cval->mixer->ignore_ctl_error ? 0 : err;
785 return 0; 824 val = get_relative_value(cval, val);
786 } 825 ucontrol->value.integer.value[cnt] = val;
787 snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n", cval->control, c + 1, err); 826 cnt++;
788 return err;
789 }
790 val = get_relative_value(cval, val);
791 ucontrol->value.integer.value[cnt] = val;
792 cnt++;
793 }
794 } 827 }
828 return 0;
795 } else { 829 } else {
796 /* master channel */ 830 /* master channel */
797 err = get_cur_mix_value(cval, 0, &val); 831 err = get_cur_mix_value(cval, 0, 0, &val);
798 if (err < 0) { 832 if (err < 0)
799 if (cval->mixer->ignore_ctl_error) { 833 return cval->mixer->ignore_ctl_error ? 0 : err;
800 ucontrol->value.integer.value[0] = cval->min;
801 return 0;
802 }
803 snd_printd(KERN_ERR "cannot get current value for control %d master ch: err = %d\n", cval->control, err);
804 return err;
805 }
806 val = get_relative_value(cval, val); 834 val = get_relative_value(cval, val);
807 ucontrol->value.integer.value[0] = val; 835 ucontrol->value.integer.value[0] = val;
808 } 836 }
@@ -819,34 +847,28 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
819 if (cval->cmask) { 847 if (cval->cmask) {
820 cnt = 0; 848 cnt = 0;
821 for (c = 0; c < MAX_CHANNELS; c++) { 849 for (c = 0; c < MAX_CHANNELS; c++) {
822 if (cval->cmask & (1 << c)) { 850 if (!(cval->cmask & (1 << c)))
823 err = get_cur_mix_value(cval, c + 1, &oval); 851 continue;
824 if (err < 0) { 852 err = get_cur_mix_value(cval, c + 1, cnt, &oval);
825 if (cval->mixer->ignore_ctl_error) 853 if (err < 0)
826 return 0; 854 return cval->mixer->ignore_ctl_error ? 0 : err;
827 return err; 855 val = ucontrol->value.integer.value[cnt];
828 } 856 val = get_abs_value(cval, val);
829 val = ucontrol->value.integer.value[cnt]; 857 if (oval != val) {
830 val = get_abs_value(cval, val); 858 set_cur_mix_value(cval, c + 1, cnt, val);
831 if (oval != val) { 859 changed = 1;
832 set_cur_mix_value(cval, c + 1, val);
833 changed = 1;
834 }
835 get_cur_mix_value(cval, c + 1, &val);
836 cnt++;
837 } 860 }
861 cnt++;
838 } 862 }
839 } else { 863 } else {
840 /* master channel */ 864 /* master channel */
841 err = get_cur_mix_value(cval, 0, &oval); 865 err = get_cur_mix_value(cval, 0, 0, &oval);
842 if (err < 0 && cval->mixer->ignore_ctl_error)
843 return 0;
844 if (err < 0) 866 if (err < 0)
845 return err; 867 return cval->mixer->ignore_ctl_error ? 0 : err;
846 val = ucontrol->value.integer.value[0]; 868 val = ucontrol->value.integer.value[0];
847 val = get_abs_value(cval, val); 869 val = get_abs_value(cval, val);
848 if (val != oval) { 870 if (val != oval) {
849 set_cur_mix_value(cval, 0, val); 871 set_cur_mix_value(cval, 0, 0, val);
850 changed = 1; 872 changed = 1;
851 } 873 }
852 } 874 }
@@ -1705,7 +1727,8 @@ static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1705 break; 1727 break;
1706 /* live24ext: 4 = line-in jack */ 1728 /* live24ext: 4 = line-in jack */
1707 case 3: /* hp-out jack (may actuate Mute) */ 1729 case 3: /* hp-out jack (may actuate Mute) */
1708 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))
1709 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);
1710 break; 1733 break;
1711 default: 1734 default:
@@ -1936,8 +1959,9 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
1936 int i, err; 1959 int i, err;
1937 1960
1938 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { 1961 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
1939 if (i > 1 && /* Live24ext has 2 LEDs only */ 1962 if (i > 1 && /* Live24ext has 2 LEDs only */
1940 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)))
1941 break; 1965 break;
1942 err = snd_ctl_add(mixer->chip->card, 1966 err = snd_ctl_add(mixer->chip->card,
1943 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer)); 1967 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
@@ -1974,7 +1998,8 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
1974 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname); 1998 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
1975 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) 1999 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
1976 jacks = jacks_audigy2nx; 2000 jacks = jacks_audigy2nx;
1977 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))
1978 jacks = jacks_live24ext; 2003 jacks = jacks_live24ext;
1979 else 2004 else
1980 return; 2005 return;
@@ -2024,7 +2049,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2024 goto _error; 2049 goto _error;
2025 2050
2026 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || 2051 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2027 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)) {
2028 struct snd_info_entry *entry; 2054 struct snd_info_entry *entry;
2029 2055
2030 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 2056 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)