diff options
Diffstat (limited to 'sound')
-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 | }; |