aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/drivers/dummy.c290
-rw-r--r--sound/usb/usbmixer.c125
-rw-r--r--sound/usb/usbmixer_maps.c23
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)
50static 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
148static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 61static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
149static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 62static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
150static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; 63static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
64static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
151static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 65static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
152static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; 66static 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);
162MODULE_PARM_DESC(id, "ID string for dummy soundcard."); 76MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
163module_param_array(enable, bool, NULL, 0444); 77module_param_array(enable, bool, NULL, 0444);
164MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); 78MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
79module_param_array(model, charp, NULL, 0444);
80MODULE_PARM_DESC(model, "Soundcard model.");
165module_param_array(pcm_devs, int, NULL, 0444); 81module_param_array(pcm_devs, int, NULL, 0444);
166MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); 82MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
167module_param_array(pcm_substreams, int, NULL, 0444); 83module_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
112struct 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
196struct snd_dummy { 129struct 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
144static 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
156struct dummy_model model_emu10k1 = {
157 .name = "emu10k1",
158 .playback_constraints = emu10k1_playback_constraints,
159 .buffer_bytes_max = 128 * 1024,
160};
161
162struct 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
172struct 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
182struct 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
192struct 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
202struct 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
216struct 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)
538static int dummy_pcm_open(struct snd_pcm_substream *substream) 559static 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 */
826static void print_formats(struct snd_info_buffer *buffer) 854static 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
836static void print_rates(struct snd_info_buffer *buffer) 865static 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
858struct dummy_hw_field { 888struct dummy_hw_field {
859 const char *name; 889 const char *name;
@@ -884,20 +914,21 @@ static struct dummy_hw_field fields[] = {
884static void dummy_proc_read(struct snd_info_entry *entry, 914static 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,
905static void dummy_proc_write(struct snd_info_entry *entry, 936static 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 */ 213static const struct usbmix_name_map *
213static int check_mapped_name(struct mixer_build *state, int unitid, int control, char *buf, int buflen) 214find_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 */
231static int check_ignored_ctl(struct mixer_build *state, int unitid, int control) 230static int
231check_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 */
241static inline int
242check_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", 250static 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
22struct usbmix_dB_map {
23 u32 min;
24 u32 max;
25};
22 26
23struct usbmix_name_map { 27struct 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
29struct usbmix_selector_map { 34struct 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 */
110static struct usbmix_dB_map mp3plus_dB_1 = {-4781, 0}; /* just guess */
111static struct usbmix_dB_map mp3plus_dB_2 = {-1781, 618}; /* just guess */
112
105static struct usbmix_name_map mp3plus_map[] = { 113static 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};