~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/oxygen/oxygen_mixer.c

Version: ~ [ linux-5.6-rc1 ] ~ [ linux-5.5.2 ] ~ [ linux-5.4.17 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.102 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.170 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.213 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.213 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * C-Media CMI8788 driver - mixer code
  3  *
  4  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
  5  *
  6  *
  7  *  This driver is free software; you can redistribute it and/or modify
  8  *  it under the terms of the GNU General Public License, version 2.
  9  *
 10  *  This driver is distributed in the hope that it will be useful,
 11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  *  GNU General Public License for more details.
 14  *
 15  *  You should have received a copy of the GNU General Public License
 16  *  along with this driver; if not, write to the Free Software
 17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 18  */
 19 
 20 #include <linux/mutex.h>
 21 #include <sound/ac97_codec.h>
 22 #include <sound/asoundef.h>
 23 #include <sound/control.h>
 24 #include <sound/tlv.h>
 25 #include "oxygen.h"
 26 #include "cm9780.h"
 27 
 28 static int dac_volume_info(struct snd_kcontrol *ctl,
 29                            struct snd_ctl_elem_info *info)
 30 {
 31         struct oxygen *chip = ctl->private_data;
 32 
 33         info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 34         info->count = chip->model.dac_channels_mixer;
 35         info->value.integer.min = chip->model.dac_volume_min;
 36         info->value.integer.max = chip->model.dac_volume_max;
 37         return 0;
 38 }
 39 
 40 static int dac_volume_get(struct snd_kcontrol *ctl,
 41                           struct snd_ctl_elem_value *value)
 42 {
 43         struct oxygen *chip = ctl->private_data;
 44         unsigned int i;
 45 
 46         mutex_lock(&chip->mutex);
 47         for (i = 0; i < chip->model.dac_channels_mixer; ++i)
 48                 value->value.integer.value[i] = chip->dac_volume[i];
 49         mutex_unlock(&chip->mutex);
 50         return 0;
 51 }
 52 
 53 static int dac_volume_put(struct snd_kcontrol *ctl,
 54                           struct snd_ctl_elem_value *value)
 55 {
 56         struct oxygen *chip = ctl->private_data;
 57         unsigned int i;
 58         int changed;
 59 
 60         changed = 0;
 61         mutex_lock(&chip->mutex);
 62         for (i = 0; i < chip->model.dac_channels_mixer; ++i)
 63                 if (value->value.integer.value[i] != chip->dac_volume[i]) {
 64                         chip->dac_volume[i] = value->value.integer.value[i];
 65                         changed = 1;
 66                 }
 67         if (changed)
 68                 chip->model.update_dac_volume(chip);
 69         mutex_unlock(&chip->mutex);
 70         return changed;
 71 }
 72 
 73 static int dac_mute_get(struct snd_kcontrol *ctl,
 74                         struct snd_ctl_elem_value *value)
 75 {
 76         struct oxygen *chip = ctl->private_data;
 77 
 78         mutex_lock(&chip->mutex);
 79         value->value.integer.value[0] = !chip->dac_mute;
 80         mutex_unlock(&chip->mutex);
 81         return 0;
 82 }
 83 
 84 static int dac_mute_put(struct snd_kcontrol *ctl,
 85                           struct snd_ctl_elem_value *value)
 86 {
 87         struct oxygen *chip = ctl->private_data;
 88         int changed;
 89 
 90         mutex_lock(&chip->mutex);
 91         changed = (!value->value.integer.value[0]) != chip->dac_mute;
 92         if (changed) {
 93                 chip->dac_mute = !value->value.integer.value[0];
 94                 chip->model.update_dac_mute(chip);
 95         }
 96         mutex_unlock(&chip->mutex);
 97         return changed;
 98 }
 99 
100 static unsigned int upmix_item_count(struct oxygen *chip)
101 {
102         if (chip->model.dac_channels_pcm < 8)
103                 return 2;
104         else if (chip->model.update_center_lfe_mix)
105                 return 5;
106         else
107                 return 3;
108 }
109 
110 static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
111 {
112         static const char *const names[5] = {
113                 "Front",
114                 "Front+Surround",
115                 "Front+Surround+Back",
116                 "Front+Surround+Center/LFE",
117                 "Front+Surround+Center/LFE+Back",
118         };
119         struct oxygen *chip = ctl->private_data;
120         unsigned int count = upmix_item_count(chip);
121 
122         return snd_ctl_enum_info(info, 1, count, names);
123 }
124 
125 static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
126 {
127         struct oxygen *chip = ctl->private_data;
128 
129         mutex_lock(&chip->mutex);
130         value->value.enumerated.item[0] = chip->dac_routing;
131         mutex_unlock(&chip->mutex);
132         return 0;
133 }
134 
135 void oxygen_update_dac_routing(struct oxygen *chip)
136 {
137         /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */
138         static const unsigned int reg_values[5] = {
139                 /* stereo -> front */
140                 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
141                 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
142                 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
143                 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
144                 /* stereo -> front+surround */
145                 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
146                 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
147                 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
148                 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
149                 /* stereo -> front+surround+back */
150                 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
151                 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
152                 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
153                 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
154                 /* stereo -> front+surround+center/LFE */
155                 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
156                 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
157                 (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
158                 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
159                 /* stereo -> front+surround+center/LFE+back */
160                 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
161                 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
162                 (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
163                 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
164         };
165         u8 channels;
166         unsigned int reg_value;
167 
168         channels = oxygen_read8(chip, OXYGEN_PLAY_CHANNELS) &
169                 OXYGEN_PLAY_CHANNELS_MASK;
170         if (channels == OXYGEN_PLAY_CHANNELS_2)
171                 reg_value = reg_values[chip->dac_routing];
172         else if (channels == OXYGEN_PLAY_CHANNELS_8)
173                 /* in 7.1 mode, "rear" channels go to the "back" jack */
174                 reg_value = (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
175                             (3 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
176                             (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
177                             (1 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
178         else
179                 reg_value = (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
180                             (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
181                             (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
182                             (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
183         if (chip->model.adjust_dac_routing)
184                 reg_value = chip->model.adjust_dac_routing(chip, reg_value);
185         oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value,
186                               OXYGEN_PLAY_DAC0_SOURCE_MASK |
187                               OXYGEN_PLAY_DAC1_SOURCE_MASK |
188                               OXYGEN_PLAY_DAC2_SOURCE_MASK |
189                               OXYGEN_PLAY_DAC3_SOURCE_MASK);
190         if (chip->model.update_center_lfe_mix)
191                 chip->model.update_center_lfe_mix(chip, chip->dac_routing > 2);
192 }
193 EXPORT_SYMBOL(oxygen_update_dac_routing);
194 
195 static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
196 {
197         struct oxygen *chip = ctl->private_data;
198         unsigned int count = upmix_item_count(chip);
199         int changed;
200 
201         if (value->value.enumerated.item[0] >= count)
202                 return -EINVAL;
203         mutex_lock(&chip->mutex);
204         changed = value->value.enumerated.item[0] != chip->dac_routing;
205         if (changed) {
206                 chip->dac_routing = value->value.enumerated.item[0];
207                 oxygen_update_dac_routing(chip);
208         }
209         mutex_unlock(&chip->mutex);
210         return changed;
211 }
212 
213 static int spdif_switch_get(struct snd_kcontrol *ctl,
214                             struct snd_ctl_elem_value *value)
215 {
216         struct oxygen *chip = ctl->private_data;
217 
218         mutex_lock(&chip->mutex);
219         value->value.integer.value[0] = chip->spdif_playback_enable;
220         mutex_unlock(&chip->mutex);
221         return 0;
222 }
223 
224 static unsigned int oxygen_spdif_rate(unsigned int oxygen_rate)
225 {
226         switch (oxygen_rate) {
227         case OXYGEN_RATE_32000:
228                 return IEC958_AES3_CON_FS_32000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
229         case OXYGEN_RATE_44100:
230                 return IEC958_AES3_CON_FS_44100 << OXYGEN_SPDIF_CS_RATE_SHIFT;
231         default: /* OXYGEN_RATE_48000 */
232                 return IEC958_AES3_CON_FS_48000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
233         case OXYGEN_RATE_64000:
234                 return 0xb << OXYGEN_SPDIF_CS_RATE_SHIFT;
235         case OXYGEN_RATE_88200:
236                 return IEC958_AES3_CON_FS_88200 << OXYGEN_SPDIF_CS_RATE_SHIFT;
237         case OXYGEN_RATE_96000:
238                 return IEC958_AES3_CON_FS_96000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
239         case OXYGEN_RATE_176400:
240                 return IEC958_AES3_CON_FS_176400 << OXYGEN_SPDIF_CS_RATE_SHIFT;
241         case OXYGEN_RATE_192000:
242                 return IEC958_AES3_CON_FS_192000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
243         }
244 }
245 
246 void oxygen_update_spdif_source(struct oxygen *chip)
247 {
248         u32 old_control, new_control;
249         u16 old_routing, new_routing;
250         unsigned int oxygen_rate;
251 
252         old_control = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
253         old_routing = oxygen_read16(chip, OXYGEN_PLAY_ROUTING);
254         if (chip->pcm_active & (1 << PCM_SPDIF)) {
255                 new_control = old_control | OXYGEN_SPDIF_OUT_ENABLE;
256                 new_routing = (old_routing & ~OXYGEN_PLAY_SPDIF_MASK)
257                         | OXYGEN_PLAY_SPDIF_SPDIF;
258                 oxygen_rate = (old_control >> OXYGEN_SPDIF_OUT_RATE_SHIFT)
259                         & OXYGEN_I2S_RATE_MASK;
260                 /* S/PDIF rate was already set by the caller */
261         } else if ((chip->pcm_active & (1 << PCM_MULTICH)) &&
262                    chip->spdif_playback_enable) {
263                 new_routing = (old_routing & ~OXYGEN_PLAY_SPDIF_MASK)
264                         | OXYGEN_PLAY_SPDIF_MULTICH_01;
265                 oxygen_rate = oxygen_read16(chip, OXYGEN_I2S_MULTICH_FORMAT)
266                         & OXYGEN_I2S_RATE_MASK;
267                 new_control = (old_control & ~OXYGEN_SPDIF_OUT_RATE_MASK) |
268                         (oxygen_rate << OXYGEN_SPDIF_OUT_RATE_SHIFT) |
269                         OXYGEN_SPDIF_OUT_ENABLE;
270         } else {
271                 new_control = old_control & ~OXYGEN_SPDIF_OUT_ENABLE;
272                 new_routing = old_routing;
273                 oxygen_rate = OXYGEN_RATE_44100;
274         }
275         if (old_routing != new_routing) {
276                 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL,
277                                new_control & ~OXYGEN_SPDIF_OUT_ENABLE);
278                 oxygen_write16(chip, OXYGEN_PLAY_ROUTING, new_routing);
279         }
280         if (new_control & OXYGEN_SPDIF_OUT_ENABLE)
281                 oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS,
282                                oxygen_spdif_rate(oxygen_rate) |
283                                ((chip->pcm_active & (1 << PCM_SPDIF)) ?
284                                 chip->spdif_pcm_bits : chip->spdif_bits));
285         oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, new_control);
286 }
287 
288 static int spdif_switch_put(struct snd_kcontrol *ctl,
289                             struct snd_ctl_elem_value *value)
290 {
291         struct oxygen *chip = ctl->private_data;
292         int changed;
293 
294         mutex_lock(&chip->mutex);
295         changed = value->value.integer.value[0] != chip->spdif_playback_enable;
296         if (changed) {
297                 chip->spdif_playback_enable = !!value->value.integer.value[0];
298                 spin_lock_irq(&chip->reg_lock);
299                 oxygen_update_spdif_source(chip);
300                 spin_unlock_irq(&chip->reg_lock);
301         }
302         mutex_unlock(&chip->mutex);
303         return changed;
304 }
305 
306 static int spdif_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
307 {
308         info->type = SNDRV_CTL_ELEM_TYPE_IEC958;
309         info->count = 1;
310         return 0;
311 }
312 
313 static void oxygen_to_iec958(u32 bits, struct snd_ctl_elem_value *value)
314 {
315         value->value.iec958.status[0] =
316                 bits & (OXYGEN_SPDIF_NONAUDIO | OXYGEN_SPDIF_C |
317                         OXYGEN_SPDIF_PREEMPHASIS);
318         value->value.iec958.status[1] = /* category and original */
319                 bits >> OXYGEN_SPDIF_CATEGORY_SHIFT;
320 }
321 
322 static u32 iec958_to_oxygen(struct snd_ctl_elem_value *value)
323 {
324         u32 bits;
325 
326         bits = value->value.iec958.status[0] &
327                 (OXYGEN_SPDIF_NONAUDIO | OXYGEN_SPDIF_C |
328                  OXYGEN_SPDIF_PREEMPHASIS);
329         bits |= value->value.iec958.status[1] << OXYGEN_SPDIF_CATEGORY_SHIFT;
330         if (bits & OXYGEN_SPDIF_NONAUDIO)
331                 bits |= OXYGEN_SPDIF_V;
332         return bits;
333 }
334 
335 static inline void write_spdif_bits(struct oxygen *chip, u32 bits)
336 {
337         oxygen_write32_masked(chip, OXYGEN_SPDIF_OUTPUT_BITS, bits,
338                               OXYGEN_SPDIF_NONAUDIO |
339                               OXYGEN_SPDIF_C |
340                               OXYGEN_SPDIF_PREEMPHASIS |
341                               OXYGEN_SPDIF_CATEGORY_MASK |
342                               OXYGEN_SPDIF_ORIGINAL |
343                               OXYGEN_SPDIF_V);
344 }
345 
346 static int spdif_default_get(struct snd_kcontrol *ctl,
347                              struct snd_ctl_elem_value *value)
348 {
349         struct oxygen *chip = ctl->private_data;
350 
351         mutex_lock(&chip->mutex);
352         oxygen_to_iec958(chip->spdif_bits, value);
353         mutex_unlock(&chip->mutex);
354         return 0;
355 }
356 
357 static int spdif_default_put(struct snd_kcontrol *ctl,
358                              struct snd_ctl_elem_value *value)
359 {
360         struct oxygen *chip = ctl->private_data;
361         u32 new_bits;
362         int changed;
363 
364         new_bits = iec958_to_oxygen(value);
365         mutex_lock(&chip->mutex);
366         changed = new_bits != chip->spdif_bits;
367         if (changed) {
368                 chip->spdif_bits = new_bits;
369                 if (!(chip->pcm_active & (1 << PCM_SPDIF)))
370                         write_spdif_bits(chip, new_bits);
371         }
372         mutex_unlock(&chip->mutex);
373         return changed;
374 }
375 
376 static int spdif_mask_get(struct snd_kcontrol *ctl,
377                           struct snd_ctl_elem_value *value)
378 {
379         value->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
380                 IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS;
381         value->value.iec958.status[1] =
382                 IEC958_AES1_CON_CATEGORY | IEC958_AES1_CON_ORIGINAL;
383         return 0;
384 }
385 
386 static int spdif_pcm_get(struct snd_kcontrol *ctl,
387                          struct snd_ctl_elem_value *value)
388 {
389         struct oxygen *chip = ctl->private_data;
390 
391         mutex_lock(&chip->mutex);
392         oxygen_to_iec958(chip->spdif_pcm_bits, value);
393         mutex_unlock(&chip->mutex);
394         return 0;
395 }
396 
397 static int spdif_pcm_put(struct snd_kcontrol *ctl,
398                          struct snd_ctl_elem_value *value)
399 {
400         struct oxygen *chip = ctl->private_data;
401         u32 new_bits;
402         int changed;
403 
404         new_bits = iec958_to_oxygen(value);
405         mutex_lock(&chip->mutex);
406         changed = new_bits != chip->spdif_pcm_bits;
407         if (changed) {
408                 chip->spdif_pcm_bits = new_bits;
409                 if (chip->pcm_active & (1 << PCM_SPDIF))
410                         write_spdif_bits(chip, new_bits);
411         }
412         mutex_unlock(&chip->mutex);
413         return changed;
414 }
415 
416 static int spdif_input_mask_get(struct snd_kcontrol *ctl,
417                                 struct snd_ctl_elem_value *value)
418 {
419         value->value.iec958.status[0] = 0xff;
420         value->value.iec958.status[1] = 0xff;
421         value->value.iec958.status[2] = 0xff;
422         value->value.iec958.status[3] = 0xff;
423         return 0;
424 }
425 
426 static int spdif_input_default_get(struct snd_kcontrol *ctl,
427                                    struct snd_ctl_elem_value *value)
428 {
429         struct oxygen *chip = ctl->private_data;
430         u32 bits;
431 
432         bits = oxygen_read32(chip, OXYGEN_SPDIF_INPUT_BITS);
433         value->value.iec958.status[0] = bits;
434         value->value.iec958.status[1] = bits >> 8;
435         value->value.iec958.status[2] = bits >> 16;
436         value->value.iec958.status[3] = bits >> 24;
437         return 0;
438 }
439 
440 static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
441                                 struct snd_ctl_elem_value *value)
442 {
443         struct oxygen *chip = ctl->private_data;
444         u32 bit = ctl->private_value;
445 
446         value->value.integer.value[0] =
447                 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
448         return 0;
449 }
450 
451 static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
452                                 struct snd_ctl_elem_value *value)
453 {
454         struct oxygen *chip = ctl->private_data;
455         u32 bit = ctl->private_value;
456         u32 oldreg, newreg;
457         int changed;
458 
459         spin_lock_irq(&chip->reg_lock);
460         oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
461         if (value->value.integer.value[0])
462                 newreg = oldreg | bit;
463         else
464                 newreg = oldreg & ~bit;
465         changed = newreg != oldreg;
466         if (changed)
467                 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
468         spin_unlock_irq(&chip->reg_lock);
469         return changed;
470 }
471 
472 static int monitor_volume_info(struct snd_kcontrol *ctl,
473                                struct snd_ctl_elem_info *info)
474 {
475         info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
476         info->count = 1;
477         info->value.integer.min = 0;
478         info->value.integer.max = 1;
479         return 0;
480 }
481 
482 static int monitor_get(struct snd_kcontrol *ctl,
483                        struct snd_ctl_elem_value *value)
484 {
485         struct oxygen *chip = ctl->private_data;
486         u8 bit = ctl->private_value;
487         int invert = ctl->private_value & (1 << 8);
488 
489         value->value.integer.value[0] =
490                 !!invert ^ !!(oxygen_read8(chip, OXYGEN_ADC_MONITOR) & bit);
491         return 0;
492 }
493 
494 static int monitor_put(struct snd_kcontrol *ctl,
495                        struct snd_ctl_elem_value *value)
496 {
497         struct oxygen *chip = ctl->private_data;
498         u8 bit = ctl->private_value;
499         int invert = ctl->private_value & (1 << 8);
500         u8 oldreg, newreg;
501         int changed;
502 
503         spin_lock_irq(&chip->reg_lock);
504         oldreg = oxygen_read8(chip, OXYGEN_ADC_MONITOR);
505         if ((!!value->value.integer.value[0] ^ !!invert) != 0)
506                 newreg = oldreg | bit;
507         else
508                 newreg = oldreg & ~bit;
509         changed = newreg != oldreg;
510         if (changed)
511                 oxygen_write8(chip, OXYGEN_ADC_MONITOR, newreg);
512         spin_unlock_irq(&chip->reg_lock);
513         return changed;
514 }
515 
516 static int ac97_switch_get(struct snd_kcontrol *ctl,
517                            struct snd_ctl_elem_value *value)
518 {
519         struct oxygen *chip = ctl->private_data;
520         unsigned int codec = (ctl->private_value >> 24) & 1;
521         unsigned int index = ctl->private_value & 0xff;
522         unsigned int bitnr = (ctl->private_value >> 8) & 0xff;
523         int invert = ctl->private_value & (1 << 16);
524         u16 reg;
525 
526         mutex_lock(&chip->mutex);
527         reg = oxygen_read_ac97(chip, codec, index);
528         mutex_unlock(&chip->mutex);
529         if (!(reg & (1 << bitnr)) ^ !invert)
530                 value->value.integer.value[0] = 1;
531         else
532                 value->value.integer.value[0] = 0;
533         return 0;
534 }
535 
536 static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
537 {
538         unsigned int priv_idx;
539         u16 value;
540 
541         if (!chip->controls[control])
542                 return;
543         priv_idx = chip->controls[control]->private_value & 0xff;
544         value = oxygen_read_ac97(chip, 0, priv_idx);
545         if (!(value & 0x8000)) {
546                 oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
547                 if (chip->model.ac97_switch)
548                         chip->model.ac97_switch(chip, priv_idx, 0x8000);
549                 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
550                                &chip->controls[control]->id);
551         }
552 }
553 
554 static int ac97_switch_put(struct snd_kcontrol *ctl,
555                            struct snd_ctl_elem_value *value)
556 {
557         struct oxygen *chip = ctl->private_data;
558         unsigned int codec = (ctl->private_value >> 24) & 1;
559         unsigned int index = ctl->private_value & 0xff;
560         unsigned int bitnr = (ctl->private_value >> 8) & 0xff;
561         int invert = ctl->private_value & (1 << 16);
562         u16 oldreg, newreg;
563         int change;
564 
565         mutex_lock(&chip->mutex);
566         oldreg = oxygen_read_ac97(chip, codec, index);
567         newreg = oldreg;
568         if (!value->value.integer.value[0] ^ !invert)
569                 newreg |= 1 << bitnr;
570         else
571                 newreg &= ~(1 << bitnr);
572         change = newreg != oldreg;
573         if (change) {
574                 oxygen_write_ac97(chip, codec, index, newreg);
575                 if (codec == 0 && chip->model.ac97_switch)
576                         chip->model.ac97_switch(chip, index, newreg & 0x8000);
577                 if (index == AC97_LINE) {
578                         oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
579                                                  newreg & 0x8000 ?
580                                                  CM9780_GPO0 : 0, CM9780_GPO0);
581                         if (!(newreg & 0x8000)) {
582                                 mute_ac97_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH);
583                                 mute_ac97_ctl(chip, CONTROL_CD_CAPTURE_SWITCH);
584                                 mute_ac97_ctl(chip, CONTROL_AUX_CAPTURE_SWITCH);
585                         }
586                 } else if ((index == AC97_MIC || index == AC97_CD ||
587                             index == AC97_VIDEO || index == AC97_AUX) &&
588                            bitnr == 15 && !(newreg & 0x8000)) {
589                         mute_ac97_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH);
590                         oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
591                                                  CM9780_GPO0, CM9780_GPO0);
592                 }
593         }
594         mutex_unlock(&chip->mutex);
595         return change;
596 }
597 
598 static int ac97_volume_info(struct snd_kcontrol *ctl,
599                             struct snd_ctl_elem_info *info)
600 {
601         int stereo = (ctl->private_value >> 16) & 1;
602 
603         info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
604         info->count = stereo ? 2 : 1;
605         info->value.integer.min = 0;
606         info->value.integer.max = 0x1f;
607         return 0;
608 }
609 
610 static int ac97_volume_get(struct snd_kcontrol *ctl,
611                            struct snd_ctl_elem_value *value)
612 {
613         struct oxygen *chip = ctl->private_data;
614         unsigned int codec = (ctl->private_value >> 24) & 1;
615         int stereo = (ctl->private_value >> 16) & 1;
616         unsigned int index = ctl->private_value & 0xff;
617         u16 reg;
618 
619         mutex_lock(&chip->mutex);
620         reg = oxygen_read_ac97(chip, codec, index);
621         mutex_unlock(&chip->mutex);
622         if (!stereo) {
623                 value->value.integer.value[0] = 31 - (reg & 0x1f);
624         } else {
625                 value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f);
626                 value->value.integer.value[1] = 31 - (reg & 0x1f);
627         }
628         return 0;
629 }
630 
631 static int ac97_volume_put(struct snd_kcontrol *ctl,
632                            struct snd_ctl_elem_value *value)
633 {
634         struct oxygen *chip = ctl->private_data;
635         unsigned int codec = (ctl->private_value >> 24) & 1;
636         int stereo = (ctl->private_value >> 16) & 1;
637         unsigned int index = ctl->private_value & 0xff;
638         u16 oldreg, newreg;
639         int change;
640 
641         mutex_lock(&chip->mutex);
642         oldreg = oxygen_read_ac97(chip, codec, index);
643         if (!stereo) {
644                 newreg = oldreg & ~0x1f;
645                 newreg |= 31 - (value->value.integer.value[0] & 0x1f);
646         } else {
647                 newreg = oldreg & ~0x1f1f;
648                 newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8;
649                 newreg |= 31 - (value->value.integer.value[1] & 0x1f);
650         }
651         change = newreg != oldreg;
652         if (change)
653                 oxygen_write_ac97(chip, codec, index, newreg);
654         mutex_unlock(&chip->mutex);
655         return change;
656 }
657 
658 static int mic_fmic_source_info(struct snd_kcontrol *ctl,
659                            struct snd_ctl_elem_info *info)
660 {
661         static const char *const names[] = { "Mic Jack", "Front Panel" };
662 
663         return snd_ctl_enum_info(info, 1, 2, names);
664 }
665 
666 static int mic_fmic_source_get(struct snd_kcontrol *ctl,
667                                struct snd_ctl_elem_value *value)
668 {
669         struct oxygen *chip = ctl->private_data;
670 
671         mutex_lock(&chip->mutex);
672         value->value.enumerated.item[0] =
673                 !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
674         mutex_unlock(&chip->mutex);
675         return 0;
676 }
677 
678 static int mic_fmic_source_put(struct snd_kcontrol *ctl,
679                                struct snd_ctl_elem_value *value)
680 {
681         struct oxygen *chip = ctl->private_data;
682         u16 oldreg, newreg;
683         int change;
684 
685         mutex_lock(&chip->mutex);
686         oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
687         if (value->value.enumerated.item[0])
688                 newreg = oldreg | CM9780_FMIC2MIC;
689         else
690                 newreg = oldreg & ~CM9780_FMIC2MIC;
691         change = newreg != oldreg;
692         if (change)
693                 oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
694         mutex_unlock(&chip->mutex);
695         return change;
696 }
697 
698 static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
699                                    struct snd_ctl_elem_info *info)
700 {
701         info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
702         info->count = 2;
703         info->value.integer.min = 0;
704         info->value.integer.max = 7;
705         return 0;
706 }
707 
708 static int ac97_fp_rec_volume_get(struct snd_kcontrol *ctl,
709                                   struct snd_ctl_elem_value *value)
710 {
711         struct oxygen *chip = ctl->private_data;
712         u16 reg;
713 
714         mutex_lock(&chip->mutex);
715         reg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
716         mutex_unlock(&chip->mutex);
717         value->value.integer.value[0] = reg & 7;
718         value->value.integer.value[1] = (reg >> 8) & 7;
719         return 0;
720 }
721 
722 static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
723                                   struct snd_ctl_elem_value *value)
724 {
725         struct oxygen *chip = ctl->private_data;
726         u16 oldreg, newreg;
727         int change;
728 
729         mutex_lock(&chip->mutex);
730         oldreg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
731         newreg = oldreg & ~0x0707;
732         newreg = newreg | (value->value.integer.value[0] & 7);
733         newreg = newreg | ((value->value.integer.value[0] & 7) << 8);
734         change = newreg != oldreg;
735         if (change)
736                 oxygen_write_ac97(chip, 1, AC97_REC_GAIN, newreg);
737         mutex_unlock(&chip->mutex);
738         return change;
739 }
740 
741 #define AC97_SWITCH(xname, codec, index, bitnr, invert) { \
742                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
743                 .name = xname, \
744                 .info = snd_ctl_boolean_mono_info, \
745                 .get = ac97_switch_get, \
746                 .put = ac97_switch_put, \
747                 .private_value = ((codec) << 24) | ((invert) << 16) | \
748                                  ((bitnr) << 8) | (index), \
749         }
750 #define AC97_VOLUME(xname, codec, index, stereo) { \
751                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
752                 .name = xname, \
753                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
754                           SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
755                 .info = ac97_volume_info, \
756                 .get = ac97_volume_get, \
757                 .put = ac97_volume_put, \
758                 .tlv = { .p = ac97_db_scale, }, \
759                 .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \
760         }
761 
762 static DECLARE_TLV_DB_SCALE(monitor_db_scale, -600, 600, 0);
763 static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0);
764 static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0);
765 
766 static const struct snd_kcontrol_new controls[] = {
767         {
768                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
769                 .name = "Master Playback Volume",
770                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
771                 .info = dac_volume_info,
772                 .get = dac_volume_get,
773                 .put = dac_volume_put,
774         },
775         {
776                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
777                 .name = "Master Playback Switch",
778                 .info = snd_ctl_boolean_mono_info,
779                 .get = dac_mute_get,
780                 .put = dac_mute_put,
781         },
782         {
783                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
784                 .name = "Stereo Upmixing",
785                 .info = upmix_info,
786                 .get = upmix_get,
787                 .put = upmix_put,
788         },
789 };
790 
791 static const struct snd_kcontrol_new spdif_output_controls[] = {
792         {
793                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
794                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
795                 .info = snd_ctl_boolean_mono_info,
796                 .get = spdif_switch_get,
797                 .put = spdif_switch_put,
798         },
799         {
800                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
801                 .device = 1,
802                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
803                 .info = spdif_info,
804                 .get = spdif_default_get,
805                 .put = spdif_default_put,
806         },
807         {
808                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
809                 .device = 1,
810                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
811                 .access = SNDRV_CTL_ELEM_ACCESS_READ,
812                 .info = spdif_info,
813                 .get = spdif_mask_get,
814         },
815         {
816                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
817                 .device = 1,
818                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
819                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
820                           SNDRV_CTL_ELEM_ACCESS_INACTIVE,
821                 .info = spdif_info,
822                 .get = spdif_pcm_get,
823                 .put = spdif_pcm_put,
824         },
825 };
826 
827 static const struct snd_kcontrol_new spdif_input_controls[] = {
828         {
829                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
830                 .device = 1,
831                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
832                 .access = SNDRV_CTL_ELEM_ACCESS_READ,
833                 .info = spdif_info,
834                 .get = spdif_input_mask_get,
835         },
836         {
837                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
838                 .device = 1,
839                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
840                 .access = SNDRV_CTL_ELEM_ACCESS_READ,
841                 .info = spdif_info,
842                 .get = spdif_input_default_get,
843         },
844         {
845                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
846                 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
847                 .info = snd_ctl_boolean_mono_info,
848                 .get = spdif_bit_switch_get,
849                 .put = spdif_bit_switch_put,
850                 .private_value = OXYGEN_SPDIF_LOOPBACK,
851         },
852         {
853                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
854                 .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
855                 .info = snd_ctl_boolean_mono_info,
856                 .get = spdif_bit_switch_get,
857                 .put = spdif_bit_switch_put,
858                 .private_value = OXYGEN_SPDIF_SPDVALID,
859         },
860 };
861 
862 static const struct {
863         unsigned int pcm_dev;
864         struct snd_kcontrol_new controls[2];
865 } monitor_controls[] = {
866         {
867                 .pcm_dev = CAPTURE_0_FROM_I2S_1,
868                 .controls = {
869                         {
870                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
871                                 .name = "Analog Input Monitor Playback Switch",
872                                 .info = snd_ctl_boolean_mono_info,
873                                 .get = monitor_get,
874                                 .put = monitor_put,
875                                 .private_value = OXYGEN_ADC_MONITOR_A,
876                         },
877                         {
878                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
879                                 .name = "Analog Input Monitor Playback Volume",
880                                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
881                                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
882                                 .info = monitor_volume_info,
883                                 .get = monitor_get,
884                                 .put = monitor_put,
885                                 .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL
886                                                 | (1 << 8),
887                                 .tlv = { .p = monitor_db_scale, },
888                         },
889                 },
890         },
891         {
892                 .pcm_dev = CAPTURE_0_FROM_I2S_2,
893                 .controls = {
894                         {
895                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
896                                 .name = "Analog Input Monitor Playback Switch",
897                                 .info = snd_ctl_boolean_mono_info,
898                                 .get = monitor_get,
899                                 .put = monitor_put,
900                                 .private_value = OXYGEN_ADC_MONITOR_B,
901                         },
902                         {
903                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904                                 .name = "Analog Input Monitor Playback Volume",
905                                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
906                                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
907                                 .info = monitor_volume_info,
908                                 .get = monitor_get,
909                                 .put = monitor_put,
910                                 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
911                                                 | (1 << 8),
912                                 .tlv = { .p = monitor_db_scale, },
913                         },
914                 },
915         },
916         {
917                 .pcm_dev = CAPTURE_2_FROM_I2S_2,
918                 .controls = {
919                         {
920                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
921                                 .name = "Analog Input Monitor Playback Switch",
922                                 .index = 1,
923                                 .info = snd_ctl_boolean_mono_info,
924                                 .get = monitor_get,
925                                 .put = monitor_put,
926                                 .private_value = OXYGEN_ADC_MONITOR_B,
927                         },
928                         {
929                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
930                                 .name = "Analog Input Monitor Playback Volume",
931                                 .index = 1,
932                                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
933                                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
934                                 .info = monitor_volume_info,
935                                 .get = monitor_get,
936                                 .put = monitor_put,
937                                 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
938                                                 | (1 << 8),
939                                 .tlv = { .p = monitor_db_scale, },
940                         },
941                 },
942         },
943         {
944                 .pcm_dev = CAPTURE_3_FROM_I2S_3,
945                 .controls = {
946                         {
947                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
948                                 .name = "Analog Input Monitor Playback Switch",
949                                 .index = 2,
950                                 .info = snd_ctl_boolean_mono_info,
951                                 .get = monitor_get,
952                                 .put = monitor_put,
953                                 .private_value = OXYGEN_ADC_MONITOR_C,
954                         },
955                         {
956                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
957                                 .name = "Analog Input Monitor Playback Volume",
958                                 .index = 2,
959                                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
960                                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
961                                 .info = monitor_volume_info,
962                                 .get = monitor_get,
963                                 .put = monitor_put,
964                                 .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
965                                                 | (1 << 8),
966                                 .tlv = { .p = monitor_db_scale, },
967                         },
968                 },
969         },
970         {
971                 .pcm_dev = CAPTURE_1_FROM_SPDIF,
972                 .controls = {
973                         {
974                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
975                                 .name = "Digital Input Monitor Playback Switch",
976                                 .info = snd_ctl_boolean_mono_info,
977                                 .get = monitor_get,
978                                 .put = monitor_put,
979                                 .private_value = OXYGEN_ADC_MONITOR_C,
980                         },
981                         {
982                                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
983                                 .name = "Digital Input Monitor Playback Volume",
984                                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
985                                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
986                                 .info = monitor_volume_info,
987                                 .get = monitor_get,
988                                 .put = monitor_put,
989                                 .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
990                                                 | (1 << 8),
991                                 .tlv = { .p = monitor_db_scale, },
992                         },
993                 },
994         },
995 };
996 
997 static const struct snd_kcontrol_new ac97_controls[] = {
998         AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
999         AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
1000         AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
1001         {
1002                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1003                 .name = "Mic Source Capture Enum",
1004                 .info = mic_fmic_source_info,
1005                 .get = mic_fmic_source_get,
1006                 .put = mic_fmic_source_put,
1007         },
1008         AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
1009         AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
1010         AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
1011         AC97_VOLUME("Aux Capture Volume", 0, AC97_AUX, 1),
1012         AC97_SWITCH("Aux Capture Switch", 0, AC97_AUX, 15, 1),
1013 };
1014 
1015 static const struct snd_kcontrol_new ac97_fp_controls[] = {
1016         AC97_VOLUME("Front Panel Playback Volume", 1, AC97_HEADPHONE, 1),
1017         AC97_SWITCH("Front Panel Playback Switch", 1, AC97_HEADPHONE, 15, 1),
1018         {
1019                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1020                 .name = "Front Panel Capture Volume",
1021                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1022                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1023                 .info = ac97_fp_rec_volume_info,
1024                 .get = ac97_fp_rec_volume_get,
1025                 .put = ac97_fp_rec_volume_put,
1026                 .tlv = { .p = ac97_rec_db_scale, },
1027         },
1028         AC97_SWITCH("Front Panel Capture Switch", 1, AC97_REC_GAIN, 15, 1),
1029 };
1030 
1031 static void oxygen_any_ctl_free(struct snd_kcontrol *ctl)
1032 {
1033         struct oxygen *chip = ctl->private_data;
1034         unsigned int i;
1035 
1036         /* I'm too lazy to write a function for each control :-) */
1037         for (i = 0; i < ARRAY_SIZE(chip->controls); ++i)
1038                 chip->controls[i] = NULL;
1039 }
1040 
1041 static int add_controls(struct oxygen *chip,
1042                         const struct snd_kcontrol_new controls[],
1043                         unsigned int count)
1044 {
1045         static const char *const known_ctl_names[CONTROL_COUNT] = {
1046                 [CONTROL_SPDIF_PCM] =
1047                         SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
1048                 [CONTROL_SPDIF_INPUT_BITS] =
1049                         SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1050                 [CONTROL_MIC_CAPTURE_SWITCH] = "Mic Capture Switch",
1051                 [CONTROL_LINE_CAPTURE_SWITCH] = "Line Capture Switch",
1052                 [CONTROL_CD_CAPTURE_SWITCH] = "CD Capture Switch",
1053                 [CONTROL_AUX_CAPTURE_SWITCH] = "Aux Capture Switch",
1054         };
1055         unsigned int i;
1056         struct snd_kcontrol_new template;
1057         struct snd_kcontrol *ctl;
1058         int j, err;
1059 
1060         for (i = 0; i < count; ++i) {
1061                 template = controls[i];
1062                 if (chip->model.control_filter) {
1063                         err = chip->model.control_filter(&template);
1064                         if (err < 0)
1065                                 return err;
1066                         if (err == 1)
1067                                 continue;
1068                 }
1069                 if (!strcmp(template.name, "Stereo Upmixing") &&
1070                     chip->model.dac_channels_pcm == 2)
1071                         continue;
1072                 if (!strcmp(template.name, "Mic Source Capture Enum") &&
1073                     !(chip->model.device_config & AC97_FMIC_SWITCH))
1074                         continue;
1075                 if (!strncmp(template.name, "CD Capture ", 11) &&
1076                     !(chip->model.device_config & AC97_CD_INPUT))
1077                         continue;
1078                 if (!strcmp(template.name, "Master Playback Volume") &&
1079                     chip->model.dac_tlv) {
1080                         template.tlv.p = chip->model.dac_tlv;
1081                         template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1082                 }
1083                 ctl = snd_ctl_new1(&template, chip);
1084                 if (!ctl)
1085                         return -ENOMEM;
1086                 err = snd_ctl_add(chip->card, ctl);
1087                 if (err < 0)
1088                         return err;
1089                 j = match_string(known_ctl_names, CONTROL_COUNT, ctl->id.name);
1090                 if (j >= 0) {
1091                         chip->controls[j] = ctl;
1092                         ctl->private_free = oxygen_any_ctl_free;
1093                 }
1094         }
1095         return 0;
1096 }
1097 
1098 int oxygen_mixer_init(struct oxygen *chip)
1099 {
1100         unsigned int i;
1101         int err;
1102 
1103         err = add_controls(chip, controls, ARRAY_SIZE(controls));
1104         if (err < 0)
1105                 return err;
1106         if (chip->model.device_config & PLAYBACK_1_TO_SPDIF) {
1107                 err = add_controls(chip, spdif_output_controls,
1108                                    ARRAY_SIZE(spdif_output_controls));
1109                 if (err < 0)
1110                         return err;
1111         }
1112         if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
1113                 err = add_controls(chip, spdif_input_controls,
1114                                    ARRAY_SIZE(spdif_input_controls));
1115                 if (err < 0)
1116                         return err;
1117         }
1118         for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
1119                 if (!(chip->model.device_config & monitor_controls[i].pcm_dev))
1120                         continue;
1121                 err = add_controls(chip, monitor_controls[i].controls,
1122                                    ARRAY_SIZE(monitor_controls[i].controls));
1123                 if (err < 0)
1124                         return err;
1125         }
1126         if (chip->has_ac97_0) {
1127                 err = add_controls(chip, ac97_controls,
1128                                    ARRAY_SIZE(ac97_controls));
1129                 if (err < 0)
1130                         return err;
1131         }
1132         if (chip->has_ac97_1) {
1133                 err = add_controls(chip, ac97_fp_controls,
1134                                    ARRAY_SIZE(ac97_fp_controls));
1135                 if (err < 0)
1136                         return err;
1137         }
1138         return chip->model.mixer_init ? chip->model.mixer_init(chip) : 0;
1139 }
1140 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp