diff options
| -rw-r--r-- | sound/drivers/dummy.c | 290 | ||||
| -rw-r--r-- | sound/usb/usbmixer.c | 125 | ||||
| -rw-r--r-- | sound/usb/usbmixer_maps.c | 23 |
3 files changed, 273 insertions, 165 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 252e04ce602f..7f41990ed68b 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
| @@ -45,109 +45,23 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}"); | |||
| 45 | #define MAX_PCM_SUBSTREAMS 128 | 45 | #define MAX_PCM_SUBSTREAMS 128 |
| 46 | #define MAX_MIDI_DEVICES 2 | 46 | #define MAX_MIDI_DEVICES 2 |
| 47 | 47 | ||
| 48 | #if 0 /* emu10k1 emulation */ | ||
| 49 | #define MAX_BUFFER_SIZE (128 * 1024) | ||
| 50 | static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime) | ||
| 51 | { | ||
| 52 | int err; | ||
| 53 | err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
| 54 | if (err < 0) | ||
| 55 | return err; | ||
| 56 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX); | ||
| 57 | if (err < 0) | ||
| 58 | return err; | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | #define add_playback_constraints emu10k1_playback_constraints | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #if 0 /* RME9652 emulation */ | ||
| 65 | #define MAX_BUFFER_SIZE (26 * 64 * 1024) | ||
| 66 | #define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE | ||
| 67 | #define USE_CHANNELS_MIN 26 | ||
| 68 | #define USE_CHANNELS_MAX 26 | ||
| 69 | #define USE_PERIODS_MIN 2 | ||
| 70 | #define USE_PERIODS_MAX 2 | ||
| 71 | #endif | ||
| 72 | |||
| 73 | #if 0 /* ICE1712 emulation */ | ||
| 74 | #define MAX_BUFFER_SIZE (256 * 1024) | ||
| 75 | #define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE | ||
| 76 | #define USE_CHANNELS_MIN 10 | ||
| 77 | #define USE_CHANNELS_MAX 10 | ||
| 78 | #define USE_PERIODS_MIN 1 | ||
| 79 | #define USE_PERIODS_MAX 1024 | ||
| 80 | #endif | ||
| 81 | |||
| 82 | #if 0 /* UDA1341 emulation */ | ||
| 83 | #define MAX_BUFFER_SIZE (16380) | ||
| 84 | #define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE | ||
| 85 | #define USE_CHANNELS_MIN 2 | ||
| 86 | #define USE_CHANNELS_MAX 2 | ||
| 87 | #define USE_PERIODS_MIN 2 | ||
| 88 | #define USE_PERIODS_MAX 255 | ||
| 89 | #endif | ||
| 90 | |||
| 91 | #if 0 /* simple AC97 bridge (intel8x0) with 48kHz AC97 only codec */ | ||
| 92 | #define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE | ||
| 93 | #define USE_CHANNELS_MIN 2 | ||
| 94 | #define USE_CHANNELS_MAX 2 | ||
| 95 | #define USE_RATE SNDRV_PCM_RATE_48000 | ||
| 96 | #define USE_RATE_MIN 48000 | ||
| 97 | #define USE_RATE_MAX 48000 | ||
| 98 | #endif | ||
| 99 | |||
| 100 | #if 0 /* CA0106 */ | ||
| 101 | #define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE | ||
| 102 | #define USE_CHANNELS_MIN 2 | ||
| 103 | #define USE_CHANNELS_MAX 2 | ||
| 104 | #define USE_RATE (SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000) | ||
| 105 | #define USE_RATE_MIN 48000 | ||
| 106 | #define USE_RATE_MAX 192000 | ||
| 107 | #define MAX_BUFFER_SIZE ((65536-64)*8) | ||
| 108 | #define MAX_PERIOD_SIZE (65536-64) | ||
| 109 | #define USE_PERIODS_MIN 2 | ||
| 110 | #define USE_PERIODS_MAX 8 | ||
| 111 | #endif | ||
| 112 | |||
| 113 | |||
| 114 | /* defaults */ | 48 | /* defaults */ |
| 115 | #ifndef MAX_BUFFER_SIZE | ||
| 116 | #define MAX_BUFFER_SIZE (64*1024) | 49 | #define MAX_BUFFER_SIZE (64*1024) |
| 117 | #endif | 50 | #define MIN_PERIOD_SIZE 64 |
| 118 | #ifndef MAX_PERIOD_SIZE | ||
| 119 | #define MAX_PERIOD_SIZE MAX_BUFFER_SIZE | 51 | #define MAX_PERIOD_SIZE MAX_BUFFER_SIZE |
| 120 | #endif | ||
| 121 | #ifndef USE_FORMATS | ||
| 122 | #define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE) | 52 | #define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE) |
| 123 | #endif | ||
| 124 | #ifndef USE_RATE | ||
| 125 | #define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000 | 53 | #define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000 |
| 126 | #define USE_RATE_MIN 5500 | 54 | #define USE_RATE_MIN 5500 |
| 127 | #define USE_RATE_MAX 48000 | 55 | #define USE_RATE_MAX 48000 |
| 128 | #endif | ||
| 129 | #ifndef USE_CHANNELS_MIN | ||
| 130 | #define USE_CHANNELS_MIN 1 | 56 | #define USE_CHANNELS_MIN 1 |
| 131 | #endif | ||
| 132 | #ifndef USE_CHANNELS_MAX | ||
| 133 | #define USE_CHANNELS_MAX 2 | 57 | #define USE_CHANNELS_MAX 2 |
| 134 | #endif | ||
| 135 | #ifndef USE_PERIODS_MIN | ||
| 136 | #define USE_PERIODS_MIN 1 | 58 | #define USE_PERIODS_MIN 1 |
| 137 | #endif | ||
| 138 | #ifndef USE_PERIODS_MAX | ||
| 139 | #define USE_PERIODS_MAX 1024 | 59 | #define USE_PERIODS_MAX 1024 |
| 140 | #endif | ||
| 141 | #ifndef add_playback_constraints | ||
| 142 | #define add_playback_constraints(x) 0 | ||
| 143 | #endif | ||
| 144 | #ifndef add_capture_constraints | ||
| 145 | #define add_capture_constraints(x) 0 | ||
| 146 | #endif | ||
| 147 | 60 | ||
| 148 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 61 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
| 149 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 62 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
| 150 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; | 63 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; |
| 64 | static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL}; | ||
| 151 | static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; | 65 | static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; |
| 152 | static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; | 66 | static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; |
| 153 | //static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; | 67 | //static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; |
| @@ -162,6 +76,8 @@ module_param_array(id, charp, NULL, 0444); | |||
| 162 | MODULE_PARM_DESC(id, "ID string for dummy soundcard."); | 76 | MODULE_PARM_DESC(id, "ID string for dummy soundcard."); |
| 163 | module_param_array(enable, bool, NULL, 0444); | 77 | module_param_array(enable, bool, NULL, 0444); |
| 164 | MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); | 78 | MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); |
| 79 | module_param_array(model, charp, NULL, 0444); | ||
| 80 | MODULE_PARM_DESC(model, "Soundcard model."); | ||
| 165 | module_param_array(pcm_devs, int, NULL, 0444); | 81 | module_param_array(pcm_devs, int, NULL, 0444); |
| 166 | MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); | 82 | MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); |
| 167 | module_param_array(pcm_substreams, int, NULL, 0444); | 83 | module_param_array(pcm_substreams, int, NULL, 0444); |
| @@ -193,9 +109,28 @@ struct dummy_timer_ops { | |||
| 193 | snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *); | 109 | snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *); |
| 194 | }; | 110 | }; |
| 195 | 111 | ||
| 112 | struct dummy_model { | ||
| 113 | const char *name; | ||
| 114 | int (*playback_constraints)(struct snd_pcm_runtime *runtime); | ||
| 115 | int (*capture_constraints)(struct snd_pcm_runtime *runtime); | ||
| 116 | u64 formats; | ||
| 117 | size_t buffer_bytes_max; | ||
| 118 | size_t period_bytes_min; | ||
| 119 | size_t period_bytes_max; | ||
| 120 | unsigned int periods_min; | ||
| 121 | unsigned int periods_max; | ||
| 122 | unsigned int rates; | ||
| 123 | unsigned int rate_min; | ||
| 124 | unsigned int rate_max; | ||
| 125 | unsigned int channels_min; | ||
| 126 | unsigned int channels_max; | ||
| 127 | }; | ||
| 128 | |||
| 196 | struct snd_dummy { | 129 | struct snd_dummy { |
| 197 | struct snd_card *card; | 130 | struct snd_card *card; |
| 131 | struct dummy_model *model; | ||
| 198 | struct snd_pcm *pcm; | 132 | struct snd_pcm *pcm; |
| 133 | struct snd_pcm_hardware pcm_hw; | ||
| 199 | spinlock_t mixer_lock; | 134 | spinlock_t mixer_lock; |
| 200 | int mixer_volume[MIXER_ADDR_LAST+1][2]; | 135 | int mixer_volume[MIXER_ADDR_LAST+1][2]; |
| 201 | int capture_source[MIXER_ADDR_LAST+1][2]; | 136 | int capture_source[MIXER_ADDR_LAST+1][2]; |
| @@ -203,6 +138,92 @@ struct snd_dummy { | |||
| 203 | }; | 138 | }; |
| 204 | 139 | ||
| 205 | /* | 140 | /* |
| 141 | * card models | ||
| 142 | */ | ||
| 143 | |||
| 144 | static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime) | ||
| 145 | { | ||
| 146 | int err; | ||
| 147 | err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
| 148 | if (err < 0) | ||
| 149 | return err; | ||
| 150 | err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX); | ||
| 151 | if (err < 0) | ||
| 152 | return err; | ||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | struct dummy_model model_emu10k1 = { | ||
| 157 | .name = "emu10k1", | ||
| 158 | .playback_constraints = emu10k1_playback_constraints, | ||
| 159 | .buffer_bytes_max = 128 * 1024, | ||
| 160 | }; | ||
| 161 | |||
| 162 | struct dummy_model model_rme9652 = { | ||
| 163 | .name = "rme9652", | ||
| 164 | .buffer_bytes_max = 26 * 64 * 1024, | ||
| 165 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
| 166 | .channels_min = 26, | ||
| 167 | .channels_max = 26, | ||
| 168 | .periods_min = 2, | ||
| 169 | .periods_max = 2, | ||
| 170 | }; | ||
| 171 | |||
| 172 | struct dummy_model model_ice1712 = { | ||
| 173 | .name = "ice1712", | ||
| 174 | .buffer_bytes_max = 256 * 1024, | ||
| 175 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
| 176 | .channels_min = 10, | ||
| 177 | .channels_max = 10, | ||
| 178 | .periods_min = 1, | ||
| 179 | .periods_max = 1024, | ||
| 180 | }; | ||
| 181 | |||
| 182 | struct dummy_model model_uda1341 = { | ||
| 183 | .name = "uda1341", | ||
| 184 | .buffer_bytes_max = 16380, | ||
| 185 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 186 | .channels_min = 2, | ||
| 187 | .channels_max = 2, | ||
| 188 | .periods_min = 2, | ||
| 189 | .periods_max = 255, | ||
| 190 | }; | ||
| 191 | |||
| 192 | struct dummy_model model_ac97 = { | ||
| 193 | .name = "ac97", | ||
| 194 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 195 | .channels_min = 2, | ||
| 196 | .channels_max = 2, | ||
| 197 | .rates = SNDRV_PCM_RATE_48000, | ||
| 198 | .rate_min = 48000, | ||
| 199 | .rate_max = 48000, | ||
| 200 | }; | ||
| 201 | |||
| 202 | struct dummy_model model_ca0106 = { | ||
| 203 | .name = "ca0106", | ||
| 204 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 205 | .buffer_bytes_max = ((65536-64)*8), | ||
| 206 | .period_bytes_max = (65536-64), | ||
| 207 | .periods_min = 2, | ||
| 208 | .periods_max = 8, | ||
| 209 | .channels_min = 2, | ||
| 210 | .channels_max = 2, | ||
| 211 | .rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000, | ||
| 212 | .rate_min = 48000, | ||
| 213 | .rate_max = 192000, | ||
| 214 | }; | ||
| 215 | |||
| 216 | struct dummy_model *dummy_models[] = { | ||
| 217 | &model_emu10k1, | ||
| 218 | &model_rme9652, | ||
| 219 | &model_ice1712, | ||
| 220 | &model_uda1341, | ||
| 221 | &model_ac97, | ||
| 222 | &model_ca0106, | ||
| 223 | NULL | ||
| 224 | }; | ||
| 225 | |||
| 226 | /* | ||
| 206 | * system timer interface | 227 | * system timer interface |
| 207 | */ | 228 | */ |
| 208 | 229 | ||
| @@ -509,7 +530,7 @@ static struct snd_pcm_hardware dummy_pcm_hardware = { | |||
| 509 | .channels_min = USE_CHANNELS_MIN, | 530 | .channels_min = USE_CHANNELS_MIN, |
| 510 | .channels_max = USE_CHANNELS_MAX, | 531 | .channels_max = USE_CHANNELS_MAX, |
| 511 | .buffer_bytes_max = MAX_BUFFER_SIZE, | 532 | .buffer_bytes_max = MAX_BUFFER_SIZE, |
| 512 | .period_bytes_min = 64, | 533 | .period_bytes_min = MIN_PERIOD_SIZE, |
| 513 | .period_bytes_max = MAX_PERIOD_SIZE, | 534 | .period_bytes_max = MAX_PERIOD_SIZE, |
| 514 | .periods_min = USE_PERIODS_MIN, | 535 | .periods_min = USE_PERIODS_MIN, |
| 515 | .periods_max = USE_PERIODS_MAX, | 536 | .periods_max = USE_PERIODS_MAX, |
| @@ -538,6 +559,7 @@ static int dummy_pcm_hw_free(struct snd_pcm_substream *substream) | |||
| 538 | static int dummy_pcm_open(struct snd_pcm_substream *substream) | 559 | static int dummy_pcm_open(struct snd_pcm_substream *substream) |
| 539 | { | 560 | { |
| 540 | struct snd_dummy *dummy = snd_pcm_substream_chip(substream); | 561 | struct snd_dummy *dummy = snd_pcm_substream_chip(substream); |
| 562 | struct dummy_model *model = dummy->model; | ||
| 541 | struct snd_pcm_runtime *runtime = substream->runtime; | 563 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 542 | int err; | 564 | int err; |
| 543 | 565 | ||
| @@ -551,7 +573,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream) | |||
| 551 | if (err < 0) | 573 | if (err < 0) |
| 552 | return err; | 574 | return err; |
| 553 | 575 | ||
| 554 | runtime->hw = dummy_pcm_hardware; | 576 | runtime->hw = dummy->pcm_hw; |
| 555 | if (substream->pcm->device & 1) { | 577 | if (substream->pcm->device & 1) { |
| 556 | runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; | 578 | runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; |
| 557 | runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; | 579 | runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; |
| @@ -560,10 +582,16 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream) | |||
| 560 | runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | | 582 | runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | |
| 561 | SNDRV_PCM_INFO_MMAP_VALID); | 583 | SNDRV_PCM_INFO_MMAP_VALID); |
| 562 | 584 | ||
| 563 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 585 | if (model == NULL) |
| 564 | err = add_playback_constraints(substream->runtime); | 586 | return 0; |
| 565 | else | 587 | |
| 566 | err = add_capture_constraints(substream->runtime); | 588 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 589 | if (model->playback_constraints) | ||
| 590 | err = model->playback_constraints(substream->runtime); | ||
| 591 | } else { | ||
| 592 | if (model->capture_constraints) | ||
| 593 | err = model->capture_constraints(substream->runtime); | ||
| 594 | } | ||
| 567 | if (err < 0) { | 595 | if (err < 0) { |
| 568 | dummy->timer_ops->free(substream); | 596 | dummy->timer_ops->free(substream); |
| 569 | return err; | 597 | return err; |
| @@ -823,17 +851,19 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy) | |||
| 823 | /* | 851 | /* |
| 824 | * proc interface | 852 | * proc interface |
| 825 | */ | 853 | */ |
| 826 | static void print_formats(struct snd_info_buffer *buffer) | 854 | static void print_formats(struct snd_dummy *dummy, |
| 855 | struct snd_info_buffer *buffer) | ||
| 827 | { | 856 | { |
| 828 | int i; | 857 | int i; |
| 829 | 858 | ||
| 830 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { | 859 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { |
| 831 | if (dummy_pcm_hardware.formats & (1ULL << i)) | 860 | if (dummy->pcm_hw.formats & (1ULL << i)) |
| 832 | snd_iprintf(buffer, " %s", snd_pcm_format_name(i)); | 861 | snd_iprintf(buffer, " %s", snd_pcm_format_name(i)); |
| 833 | } | 862 | } |
| 834 | } | 863 | } |
| 835 | 864 | ||
| 836 | static void print_rates(struct snd_info_buffer *buffer) | 865 | static void print_rates(struct snd_dummy *dummy, |
| 866 | struct snd_info_buffer *buffer) | ||
| 837 | { | 867 | { |
| 838 | static int rates[] = { | 868 | static int rates[] = { |
| 839 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, | 869 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, |
| @@ -841,19 +871,19 @@ static void print_rates(struct snd_info_buffer *buffer) | |||
| 841 | }; | 871 | }; |
| 842 | int i; | 872 | int i; |
| 843 | 873 | ||
| 844 | if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_CONTINUOUS) | 874 | if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS) |
| 845 | snd_iprintf(buffer, " continuous"); | 875 | snd_iprintf(buffer, " continuous"); |
| 846 | if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_KNOT) | 876 | if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT) |
| 847 | snd_iprintf(buffer, " knot"); | 877 | snd_iprintf(buffer, " knot"); |
| 848 | for (i = 0; i < ARRAY_SIZE(rates); i++) | 878 | for (i = 0; i < ARRAY_SIZE(rates); i++) |
| 849 | if (dummy_pcm_hardware.rates & (1 << i)) | 879 | if (dummy->pcm_hw.rates & (1 << i)) |
| 850 | snd_iprintf(buffer, " %d", rates[i]); | 880 | snd_iprintf(buffer, " %d", rates[i]); |
| 851 | } | 881 | } |
| 852 | 882 | ||
| 853 | #define get_dummy_int_ptr(ofs) \ | 883 | #define get_dummy_int_ptr(dummy, ofs) \ |
| 854 | (unsigned int *)((char *)&dummy_pcm_hardware + (ofs)) | 884 | (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs)) |
| 855 | #define get_dummy_ll_ptr(ofs) \ | 885 | #define get_dummy_ll_ptr(dummy, ofs) \ |
| 856 | (unsigned long long *)((char *)&dummy_pcm_hardware + (ofs)) | 886 | (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs)) |
| 857 | 887 | ||
| 858 | struct dummy_hw_field { | 888 | struct dummy_hw_field { |
| 859 | const char *name; | 889 | const char *name; |
| @@ -884,20 +914,21 @@ static struct dummy_hw_field fields[] = { | |||
| 884 | static void dummy_proc_read(struct snd_info_entry *entry, | 914 | static void dummy_proc_read(struct snd_info_entry *entry, |
| 885 | struct snd_info_buffer *buffer) | 915 | struct snd_info_buffer *buffer) |
| 886 | { | 916 | { |
| 917 | struct snd_dummy *dummy = entry->private_data; | ||
| 887 | int i; | 918 | int i; |
| 888 | 919 | ||
| 889 | for (i = 0; i < ARRAY_SIZE(fields); i++) { | 920 | for (i = 0; i < ARRAY_SIZE(fields); i++) { |
| 890 | snd_iprintf(buffer, "%s ", fields[i].name); | 921 | snd_iprintf(buffer, "%s ", fields[i].name); |
| 891 | if (fields[i].size == sizeof(int)) | 922 | if (fields[i].size == sizeof(int)) |
| 892 | snd_iprintf(buffer, fields[i].format, | 923 | snd_iprintf(buffer, fields[i].format, |
| 893 | *get_dummy_int_ptr(fields[i].offset)); | 924 | *get_dummy_int_ptr(dummy, fields[i].offset)); |
| 894 | else | 925 | else |
| 895 | snd_iprintf(buffer, fields[i].format, | 926 | snd_iprintf(buffer, fields[i].format, |
| 896 | *get_dummy_ll_ptr(fields[i].offset)); | 927 | *get_dummy_ll_ptr(dummy, fields[i].offset)); |
| 897 | if (!strcmp(fields[i].name, "formats")) | 928 | if (!strcmp(fields[i].name, "formats")) |
| 898 | print_formats(buffer); | 929 | print_formats(dummy, buffer); |
| 899 | else if (!strcmp(fields[i].name, "rates")) | 930 | else if (!strcmp(fields[i].name, "rates")) |
| 900 | print_rates(buffer); | 931 | print_rates(dummy, buffer); |
| 901 | snd_iprintf(buffer, "\n"); | 932 | snd_iprintf(buffer, "\n"); |
| 902 | } | 933 | } |
| 903 | } | 934 | } |
| @@ -905,6 +936,7 @@ static void dummy_proc_read(struct snd_info_entry *entry, | |||
| 905 | static void dummy_proc_write(struct snd_info_entry *entry, | 936 | static void dummy_proc_write(struct snd_info_entry *entry, |
| 906 | struct snd_info_buffer *buffer) | 937 | struct snd_info_buffer *buffer) |
| 907 | { | 938 | { |
| 939 | struct snd_dummy *dummy = entry->private_data; | ||
| 908 | char line[64]; | 940 | char line[64]; |
| 909 | 941 | ||
| 910 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 942 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
| @@ -924,9 +956,9 @@ static void dummy_proc_write(struct snd_info_entry *entry, | |||
| 924 | if (strict_strtoull(item, 0, &val)) | 956 | if (strict_strtoull(item, 0, &val)) |
| 925 | continue; | 957 | continue; |
| 926 | if (fields[i].size == sizeof(int)) | 958 | if (fields[i].size == sizeof(int)) |
| 927 | *get_dummy_int_ptr(fields[i].offset) = val; | 959 | *get_dummy_int_ptr(dummy, fields[i].offset) = val; |
| 928 | else | 960 | else |
| 929 | *get_dummy_ll_ptr(fields[i].offset) = val; | 961 | *get_dummy_ll_ptr(dummy, fields[i].offset) = val; |
| 930 | } | 962 | } |
| 931 | } | 963 | } |
| 932 | 964 | ||
| @@ -938,6 +970,7 @@ static void __devinit dummy_proc_init(struct snd_dummy *chip) | |||
| 938 | snd_info_set_text_ops(entry, chip, dummy_proc_read); | 970 | snd_info_set_text_ops(entry, chip, dummy_proc_read); |
| 939 | entry->c.text.write = dummy_proc_write; | 971 | entry->c.text.write = dummy_proc_write; |
| 940 | entry->mode |= S_IWUSR; | 972 | entry->mode |= S_IWUSR; |
| 973 | entry->private_data = chip; | ||
| 941 | } | 974 | } |
| 942 | } | 975 | } |
| 943 | #else | 976 | #else |
| @@ -948,6 +981,7 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr) | |||
| 948 | { | 981 | { |
| 949 | struct snd_card *card; | 982 | struct snd_card *card; |
| 950 | struct snd_dummy *dummy; | 983 | struct snd_dummy *dummy; |
| 984 | struct dummy_model *m = NULL, **mdl; | ||
| 951 | int idx, err; | 985 | int idx, err; |
| 952 | int dev = devptr->id; | 986 | int dev = devptr->id; |
| 953 | 987 | ||
| @@ -957,6 +991,15 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr) | |||
| 957 | return err; | 991 | return err; |
| 958 | dummy = card->private_data; | 992 | dummy = card->private_data; |
| 959 | dummy->card = card; | 993 | dummy->card = card; |
| 994 | for (mdl = dummy_models; *mdl && model[dev]; mdl++) { | ||
| 995 | if (strcmp(model[dev], (*mdl)->name) == 0) { | ||
| 996 | printk(KERN_INFO | ||
| 997 | "snd-dummy: Using model '%s' for card %i\n", | ||
| 998 | (*mdl)->name, card->number); | ||
| 999 | m = dummy->model = *mdl; | ||
| 1000 | break; | ||
| 1001 | } | ||
| 1002 | } | ||
| 960 | for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { | 1003 | for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { |
| 961 | if (pcm_substreams[dev] < 1) | 1004 | if (pcm_substreams[dev] < 1) |
| 962 | pcm_substreams[dev] = 1; | 1005 | pcm_substreams[dev] = 1; |
| @@ -966,6 +1009,33 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr) | |||
| 966 | if (err < 0) | 1009 | if (err < 0) |
| 967 | goto __nodev; | 1010 | goto __nodev; |
| 968 | } | 1011 | } |
| 1012 | |||
| 1013 | dummy->pcm_hw = dummy_pcm_hardware; | ||
| 1014 | if (m) { | ||
| 1015 | if (m->formats) | ||
| 1016 | dummy->pcm_hw.formats = m->formats; | ||
| 1017 | if (m->buffer_bytes_max) | ||
| 1018 | dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max; | ||
| 1019 | if (m->period_bytes_min) | ||
| 1020 | dummy->pcm_hw.period_bytes_min = m->period_bytes_min; | ||
| 1021 | if (m->period_bytes_max) | ||
| 1022 | dummy->pcm_hw.period_bytes_max = m->period_bytes_max; | ||
| 1023 | if (m->periods_min) | ||
| 1024 | dummy->pcm_hw.periods_min = m->periods_min; | ||
| 1025 | if (m->periods_max) | ||
| 1026 | dummy->pcm_hw.periods_max = m->periods_max; | ||
| 1027 | if (m->rates) | ||
| 1028 | dummy->pcm_hw.rates = m->rates; | ||
| 1029 | if (m->rate_min) | ||
| 1030 | dummy->pcm_hw.rate_min = m->rate_min; | ||
| 1031 | if (m->rate_max) | ||
| 1032 | dummy->pcm_hw.rate_max = m->rate_max; | ||
| 1033 | if (m->channels_min) | ||
| 1034 | dummy->pcm_hw.channels_min = m->channels_min; | ||
| 1035 | if (m->channels_max) | ||
| 1036 | dummy->pcm_hw.channels_max = m->channels_max; | ||
| 1037 | } | ||
| 1038 | |||
| 969 | err = snd_card_dummy_new_mixer(dummy); | 1039 | err = snd_card_dummy_new_mixer(dummy); |
| 970 | if (err < 0) | 1040 | if (err < 0) |
| 971 | goto __nodev; | 1041 | goto __nodev; |
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index f5596cfdbde1..dd0c1d7bf3ed 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
| @@ -123,6 +123,7 @@ struct usb_mixer_elem_info { | |||
| 123 | int channels; | 123 | int channels; |
| 124 | int val_type; | 124 | int val_type; |
| 125 | int min, max, res; | 125 | int min, max, res; |
| 126 | int dBmin, dBmax; | ||
| 126 | int cached; | 127 | int cached; |
| 127 | int cache_val[MAX_CHANNELS]; | 128 | int cache_val[MAX_CHANNELS]; |
| 128 | u8 initialized; | 129 | u8 initialized; |
| @@ -209,42 +210,50 @@ enum { | |||
| 209 | */ | 210 | */ |
| 210 | #include "usbmixer_maps.c" | 211 | #include "usbmixer_maps.c" |
| 211 | 212 | ||
| 212 | /* get the mapped name if the unit matches */ | 213 | static const struct usbmix_name_map * |
| 213 | static int check_mapped_name(struct mixer_build *state, int unitid, int control, char *buf, int buflen) | 214 | find_map(struct mixer_build *state, int unitid, int control) |
| 214 | { | 215 | { |
| 215 | const struct usbmix_name_map *p; | 216 | const struct usbmix_name_map *p = state->map; |
| 216 | 217 | ||
| 217 | if (! state->map) | 218 | if (!p) |
| 218 | return 0; | 219 | return NULL; |
| 219 | 220 | ||
| 220 | for (p = state->map; p->id; p++) { | 221 | for (p = state->map; p->id; p++) { |
| 221 | if (p->id == unitid && p->name && | 222 | if (p->id == unitid && |
| 222 | (! control || ! p->control || control == p->control)) { | 223 | (!control || !p->control || control == p->control)) |
| 223 | buflen--; | 224 | return p; |
| 224 | return strlcpy(buf, p->name, buflen); | ||
| 225 | } | ||
| 226 | } | 225 | } |
| 227 | return 0; | 226 | return NULL; |
| 228 | } | 227 | } |
| 229 | 228 | ||
| 230 | /* check whether the control should be ignored */ | 229 | /* get the mapped name if the unit matches */ |
| 231 | static int check_ignored_ctl(struct mixer_build *state, int unitid, int control) | 230 | static int |
| 231 | check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen) | ||
| 232 | { | 232 | { |
| 233 | const struct usbmix_name_map *p; | 233 | if (!p || !p->name) |
| 234 | return 0; | ||
| 234 | 235 | ||
| 235 | if (! state->map) | 236 | buflen--; |
| 237 | return strlcpy(buf, p->name, buflen); | ||
| 238 | } | ||
| 239 | |||
| 240 | /* check whether the control should be ignored */ | ||
| 241 | static inline int | ||
| 242 | check_ignored_ctl(const struct usbmix_name_map *p) | ||
| 243 | { | ||
| 244 | if (!p || p->name || p->dB) | ||
| 236 | return 0; | 245 | return 0; |
| 237 | for (p = state->map; p->id; p++) { | 246 | return 1; |
| 238 | if (p->id == unitid && ! p->name && | 247 | } |
| 239 | (! control || ! p->control || control == p->control)) { | 248 | |
| 240 | /* | 249 | /* dB mapping */ |
| 241 | printk(KERN_DEBUG "ignored control %d:%d\n", | 250 | static inline void check_mapped_dB(const struct usbmix_name_map *p, |
| 242 | unitid, control); | 251 | struct usb_mixer_elem_info *cval) |
| 243 | */ | 252 | { |
| 244 | return 1; | 253 | if (p && p->dB) { |
| 245 | } | 254 | cval->dBmin = p->dB->min; |
| 255 | cval->dBmax = p->dB->max; | ||
| 246 | } | 256 | } |
| 247 | return 0; | ||
| 248 | } | 257 | } |
| 249 | 258 | ||
| 250 | /* get the mapped selector source name */ | 259 | /* get the mapped selector source name */ |
| @@ -481,20 +490,8 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
| 481 | 490 | ||
| 482 | if (size < sizeof(scale)) | 491 | if (size < sizeof(scale)) |
| 483 | return -ENOMEM; | 492 | return -ENOMEM; |
| 484 | /* USB descriptions contain the dB scale in 1/256 dB unit | 493 | scale[2] = cval->dBmin; |
| 485 | * while ALSA TLV contains in 1/100 dB unit | 494 | scale[3] = cval->dBmax; |
| 486 | */ | ||
| 487 | scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256; | ||
| 488 | scale[3] = (convert_signed_value(cval, cval->max) * 100) / 256; | ||
| 489 | if (scale[3] <= scale[2]) { | ||
| 490 | /* something is wrong; assume it's either from/to 0dB */ | ||
| 491 | if (scale[2] < 0) | ||
| 492 | scale[3] = 0; | ||
| 493 | else if (scale[2] > 0) | ||
| 494 | scale[2] = 0; | ||
| 495 | else /* totally crap, return an error */ | ||
| 496 | return -EINVAL; | ||
| 497 | } | ||
| 498 | if (copy_to_user(_tlv, scale, sizeof(scale))) | 495 | if (copy_to_user(_tlv, scale, sizeof(scale))) |
| 499 | return -EFAULT; | 496 | return -EFAULT; |
| 500 | return 0; | 497 | return 0; |
| @@ -735,6 +732,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
| 735 | cval->min = default_min; | 732 | cval->min = default_min; |
| 736 | cval->max = cval->min + 1; | 733 | cval->max = cval->min + 1; |
| 737 | cval->res = 1; | 734 | cval->res = 1; |
| 735 | cval->dBmin = cval->dBmax = 0; | ||
| 738 | 736 | ||
| 739 | if (cval->val_type == USB_MIXER_BOOLEAN || | 737 | if (cval->val_type == USB_MIXER_BOOLEAN || |
| 740 | cval->val_type == USB_MIXER_INV_BOOLEAN) { | 738 | cval->val_type == USB_MIXER_INV_BOOLEAN) { |
| @@ -802,6 +800,24 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
| 802 | 800 | ||
| 803 | cval->initialized = 1; | 801 | cval->initialized = 1; |
| 804 | } | 802 | } |
| 803 | |||
| 804 | /* USB descriptions contain the dB scale in 1/256 dB unit | ||
| 805 | * while ALSA TLV contains in 1/100 dB unit | ||
| 806 | */ | ||
| 807 | cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256; | ||
| 808 | cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256; | ||
| 809 | if (cval->dBmin > cval->dBmax) { | ||
| 810 | /* something is wrong; assume it's either from/to 0dB */ | ||
| 811 | if (cval->dBmin < 0) | ||
| 812 | cval->dBmax = 0; | ||
| 813 | else if (cval->dBmin > 0) | ||
| 814 | cval->dBmin = 0; | ||
| 815 | if (cval->dBmin > cval->dBmax) { | ||
| 816 | /* totally crap, return an error */ | ||
| 817 | return -EINVAL; | ||
| 818 | } | ||
| 819 | } | ||
| 820 | |||
| 805 | return 0; | 821 | return 0; |
| 806 | } | 822 | } |
| 807 | 823 | ||
| @@ -927,6 +943,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, | |||
| 927 | int nameid = desc[desc[0] - 1]; | 943 | int nameid = desc[desc[0] - 1]; |
| 928 | struct snd_kcontrol *kctl; | 944 | struct snd_kcontrol *kctl; |
| 929 | struct usb_mixer_elem_info *cval; | 945 | struct usb_mixer_elem_info *cval; |
| 946 | const struct usbmix_name_map *map; | ||
| 930 | 947 | ||
| 931 | control++; /* change from zero-based to 1-based value */ | 948 | control++; /* change from zero-based to 1-based value */ |
| 932 | 949 | ||
| @@ -935,7 +952,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, | |||
| 935 | return; | 952 | return; |
| 936 | } | 953 | } |
| 937 | 954 | ||
| 938 | if (check_ignored_ctl(state, unitid, control)) | 955 | map = find_map(state, unitid, control); |
| 956 | if (check_ignored_ctl(map)) | ||
| 939 | return; | 957 | return; |
| 940 | 958 | ||
| 941 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 959 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
| @@ -969,10 +987,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, | |||
| 969 | } | 987 | } |
| 970 | kctl->private_free = usb_mixer_elem_free; | 988 | kctl->private_free = usb_mixer_elem_free; |
| 971 | 989 | ||
| 972 | len = check_mapped_name(state, unitid, control, kctl->id.name, sizeof(kctl->id.name)); | 990 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
| 973 | mapped_name = len != 0; | 991 | mapped_name = len != 0; |
| 974 | if (! len && nameid) | 992 | if (! len && nameid) |
| 975 | len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); | 993 | len = snd_usb_copy_string_desc(state, nameid, |
| 994 | kctl->id.name, sizeof(kctl->id.name)); | ||
| 976 | 995 | ||
| 977 | switch (control) { | 996 | switch (control) { |
| 978 | case USB_FEATURE_MUTE: | 997 | case USB_FEATURE_MUTE: |
| @@ -1010,6 +1029,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, | |||
| 1010 | kctl->vd[0].access |= | 1029 | kctl->vd[0].access |= |
| 1011 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 1030 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
| 1012 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | 1031 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; |
| 1032 | check_mapped_dB(map, cval); | ||
| 1013 | } | 1033 | } |
| 1014 | break; | 1034 | break; |
| 1015 | 1035 | ||
| @@ -1137,8 +1157,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc, | |||
| 1137 | unsigned int num_outs = desc[5 + input_pins]; | 1157 | unsigned int num_outs = desc[5 + input_pins]; |
| 1138 | unsigned int i, len; | 1158 | unsigned int i, len; |
| 1139 | struct snd_kcontrol *kctl; | 1159 | struct snd_kcontrol *kctl; |
| 1160 | const struct usbmix_name_map *map; | ||
| 1140 | 1161 | ||
| 1141 | if (check_ignored_ctl(state, unitid, 0)) | 1162 | map = find_map(state, unitid, 0); |
| 1163 | if (check_ignored_ctl(map)) | ||
| 1142 | return; | 1164 | return; |
| 1143 | 1165 | ||
| 1144 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1166 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
| @@ -1167,7 +1189,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc, | |||
| 1167 | } | 1189 | } |
| 1168 | kctl->private_free = usb_mixer_elem_free; | 1190 | kctl->private_free = usb_mixer_elem_free; |
| 1169 | 1191 | ||
| 1170 | len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name)); | 1192 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
| 1171 | if (! len) | 1193 | if (! len) |
| 1172 | len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); | 1194 | len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); |
| 1173 | if (! len) | 1195 | if (! len) |
| @@ -1382,6 +1404,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned | |||
| 1382 | int i, err, nameid, type, len; | 1404 | int i, err, nameid, type, len; |
| 1383 | struct procunit_info *info; | 1405 | struct procunit_info *info; |
| 1384 | struct procunit_value_info *valinfo; | 1406 | struct procunit_value_info *valinfo; |
| 1407 | const struct usbmix_name_map *map; | ||
| 1385 | static struct procunit_value_info default_value_info[] = { | 1408 | static struct procunit_value_info default_value_info[] = { |
| 1386 | { 0x01, "Switch", USB_MIXER_BOOLEAN }, | 1409 | { 0x01, "Switch", USB_MIXER_BOOLEAN }, |
| 1387 | { 0 } | 1410 | { 0 } |
| @@ -1411,7 +1434,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned | |||
| 1411 | /* FIXME: bitmap might be longer than 8bit */ | 1434 | /* FIXME: bitmap might be longer than 8bit */ |
| 1412 | if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) | 1435 | if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) |
| 1413 | continue; | 1436 | continue; |
| 1414 | if (check_ignored_ctl(state, unitid, valinfo->control)) | 1437 | map = find_map(state, unitid, valinfo->control); |
| 1438 | if (check_ignored_ctl(map)) | ||
| 1415 | continue; | 1439 | continue; |
| 1416 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1440 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
| 1417 | if (! cval) { | 1441 | if (! cval) { |
| @@ -1452,8 +1476,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned | |||
| 1452 | } | 1476 | } |
| 1453 | kctl->private_free = usb_mixer_elem_free; | 1477 | kctl->private_free = usb_mixer_elem_free; |
| 1454 | 1478 | ||
| 1455 | if (check_mapped_name(state, unitid, cval->control, kctl->id.name, sizeof(kctl->id.name))) | 1479 | if (check_mapped_name(map, kctl->id.name, |
| 1456 | ; | 1480 | sizeof(kctl->id.name))) |
| 1481 | /* nothing */ ; | ||
| 1457 | else if (info->name) | 1482 | else if (info->name) |
| 1458 | strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); | 1483 | strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); |
| 1459 | else { | 1484 | else { |
| @@ -1592,6 +1617,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi | |||
| 1592 | int err; | 1617 | int err; |
| 1593 | struct usb_mixer_elem_info *cval; | 1618 | struct usb_mixer_elem_info *cval; |
| 1594 | struct snd_kcontrol *kctl; | 1619 | struct snd_kcontrol *kctl; |
| 1620 | const struct usbmix_name_map *map; | ||
| 1595 | char **namelist; | 1621 | char **namelist; |
| 1596 | 1622 | ||
| 1597 | if (! num_ins || desc[0] < 5 + num_ins) { | 1623 | if (! num_ins || desc[0] < 5 + num_ins) { |
| @@ -1607,7 +1633,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi | |||
| 1607 | if (num_ins == 1) /* only one ? nonsense! */ | 1633 | if (num_ins == 1) /* only one ? nonsense! */ |
| 1608 | return 0; | 1634 | return 0; |
| 1609 | 1635 | ||
| 1610 | if (check_ignored_ctl(state, unitid, 0)) | 1636 | map = find_map(state, unitid, 0); |
| 1637 | if (check_ignored_ctl(map)) | ||
| 1611 | return 0; | 1638 | return 0; |
| 1612 | 1639 | ||
| 1613 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1640 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
| @@ -1662,7 +1689,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi | |||
| 1662 | kctl->private_free = usb_mixer_selector_elem_free; | 1689 | kctl->private_free = usb_mixer_selector_elem_free; |
| 1663 | 1690 | ||
| 1664 | nameid = desc[desc[0] - 1]; | 1691 | nameid = desc[desc[0] - 1]; |
| 1665 | len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name)); | 1692 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
| 1666 | if (len) | 1693 | if (len) |
| 1667 | ; | 1694 | ; |
| 1668 | else if (nameid) | 1695 | else if (nameid) |
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c index 77c35885e21c..79e903a60862 100644 --- a/sound/usb/usbmixer_maps.c +++ b/sound/usb/usbmixer_maps.c | |||
| @@ -19,11 +19,16 @@ | |||
| 19 | * | 19 | * |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | struct usbmix_dB_map { | ||
| 23 | u32 min; | ||
| 24 | u32 max; | ||
| 25 | }; | ||
| 22 | 26 | ||
| 23 | struct usbmix_name_map { | 27 | struct usbmix_name_map { |
| 24 | int id; | 28 | int id; |
| 25 | const char *name; | 29 | const char *name; |
| 26 | int control; | 30 | int control; |
| 31 | struct usbmix_dB_map *dB; | ||
| 27 | }; | 32 | }; |
| 28 | 33 | ||
| 29 | struct usbmix_selector_map { | 34 | struct usbmix_selector_map { |
| @@ -72,7 +77,7 @@ static struct usbmix_name_map extigy_map[] = { | |||
| 72 | { 8, "Line Playback" }, /* FU */ | 77 | { 8, "Line Playback" }, /* FU */ |
| 73 | /* 9: IT mic */ | 78 | /* 9: IT mic */ |
| 74 | { 10, "Mic Playback" }, /* FU */ | 79 | { 10, "Mic Playback" }, /* FU */ |
| 75 | { 11, "Capture Input Source" }, /* SU */ | 80 | { 11, "Capture Source" }, /* SU */ |
| 76 | { 12, "Capture" }, /* FU */ | 81 | { 12, "Capture" }, /* FU */ |
| 77 | /* 13: OT pcm capture */ | 82 | /* 13: OT pcm capture */ |
| 78 | /* 14: MU (w/o controls) */ | 83 | /* 14: MU (w/o controls) */ |
| @@ -102,6 +107,9 @@ static struct usbmix_name_map extigy_map[] = { | |||
| 102 | * e.g. no Master and fake PCM volume | 107 | * e.g. no Master and fake PCM volume |
| 103 | * Pavel Mihaylov <bin@bash.info> | 108 | * Pavel Mihaylov <bin@bash.info> |
| 104 | */ | 109 | */ |
| 110 | static struct usbmix_dB_map mp3plus_dB_1 = {-4781, 0}; /* just guess */ | ||
| 111 | static struct usbmix_dB_map mp3plus_dB_2 = {-1781, 618}; /* just guess */ | ||
| 112 | |||
| 105 | static struct usbmix_name_map mp3plus_map[] = { | 113 | static struct usbmix_name_map mp3plus_map[] = { |
| 106 | /* 1: IT pcm */ | 114 | /* 1: IT pcm */ |
| 107 | /* 2: IT mic */ | 115 | /* 2: IT mic */ |
| @@ -110,16 +118,19 @@ static struct usbmix_name_map mp3plus_map[] = { | |||
| 110 | /* 5: OT digital out */ | 118 | /* 5: OT digital out */ |
| 111 | /* 6: OT speaker */ | 119 | /* 6: OT speaker */ |
| 112 | /* 7: OT pcm capture */ | 120 | /* 7: OT pcm capture */ |
| 113 | { 8, "Capture Input Source" }, /* FU, default PCM Capture Source */ | 121 | { 8, "Capture Source" }, /* FU, default PCM Capture Source */ |
| 114 | /* (Mic, Input 1 = Line input, Input 2 = Optical input) */ | 122 | /* (Mic, Input 1 = Line input, Input 2 = Optical input) */ |
| 115 | { 9, "Master Playback" }, /* FU, default Speaker 1 */ | 123 | { 9, "Master Playback" }, /* FU, default Speaker 1 */ |
| 116 | /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */ | 124 | /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */ |
| 117 | /* { 10, "Mic Capture", 2 }, */ /* FU, Mic Capture */ | 125 | { 10, /* "Mic Capture", */ NULL, 2, .dB = &mp3plus_dB_2 }, |
| 126 | /* FU, Mic Capture */ | ||
| 118 | { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */ | 127 | { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */ |
| 119 | { 11, "Line Capture" }, /* FU, default PCM Capture */ | 128 | { 11, "Line Capture", .dB = &mp3plus_dB_2 }, |
| 129 | /* FU, default PCM Capture */ | ||
| 120 | { 12, "Digital In Playback" }, /* FU, default PCM 1 */ | 130 | { 12, "Digital In Playback" }, /* FU, default PCM 1 */ |
| 121 | /* { 13, "Mic Playback" }, */ /* FU, default Mic Playback */ | 131 | { 13, /* "Mic Playback", */ .dB = &mp3plus_dB_1 }, |
| 122 | { 14, "Line Playback" }, /* FU, default Speaker */ | 132 | /* FU, default Mic Playback */ |
| 133 | { 14, "Line Playback", .dB = &mp3plus_dB_1 }, /* FU, default Speaker */ | ||
| 123 | /* 15: MU */ | 134 | /* 15: MU */ |
| 124 | { 0 } /* terminator */ | 135 | { 0 } /* terminator */ |
| 125 | }; | 136 | }; |
