Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / intel_sst / intelmid_ctrl.c
1 /*
2  *  intelmid_ctrl.c - Intel Sound card driver for MID
3  *
4  *  Copyright (C) 2008-10 Intel Corp
5  *  Authors:    Harsha Priya <priya.harsha@intel.com>
6  *              Vinod Koul <vinod.koul@intel.com>
7  *              Dharageswari R <dharageswari.r@intel.com>
8  *              KP Jeeja <jeeja.kp@intel.com>
9  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation version 2 of the License.
14  *
15  *  This program is distributed in the hope that it will be useful, but
16  *  WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License along
21  *  with this program; if not, write to the Free Software Foundation, Inc.,
22  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23  *
24  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25  *  ALSA driver handling mixer controls for Intel MAD chipset
26  */
27
28 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29
30 #include <sound/core.h>
31 #include <sound/control.h>
32 #include "jack.h"
33 #include "intel_sst.h"
34 #include "intel_sst_ioctl.h"
35 #include "intelmid_snd_control.h"
36 #include "intelmid.h"
37
38 static char *out_names_mrst[] = {"Headphones",
39                                 "Internal speakers"};
40 static char *in_names_mrst[] = {"AMIC",
41                                 "DMIC",
42                                 "HS_MIC"};
43 static char *out_names_mfld[] = {"Headset ",
44                                 "EarPiece  "};
45 static char *in_names_mfld[] = {"AMIC",
46                                 "DMIC"};
47
48 struct snd_control_val intelmad_ctrl_val[MAX_VENDORS] = {
49         {
50                 .playback_vol_max = 63,
51                 .playback_vol_min = 0,
52                 .capture_vol_max = 63,
53                 .capture_vol_min = 0,
54         },
55         {
56                 .playback_vol_max = 0,
57                 .playback_vol_min = -31,
58                 .capture_vol_max = 0,
59                 .capture_vol_min = -20,
60         },
61         {
62                 .playback_vol_max = 0,
63                 .playback_vol_min = -126,
64                 .capture_vol_max = 0,
65                 .capture_vol_min = -31,
66         },
67 };
68
69 /* control path functionalities */
70
71 static inline int snd_intelmad_volume_info(struct snd_ctl_elem_info *uinfo,
72                                         int control_type, int max, int min)
73 {
74         WARN_ON(!uinfo);
75
76         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
77         uinfo->count = control_type;
78         uinfo->value.integer.min = min;
79         uinfo->value.integer.max = max;
80         return 0;
81 }
82
83 /**
84 * snd_intelmad_mute_info - provides information about the mute controls
85 *
86 * @kcontrol:    pointer to the control
87 * @uinfo:       pointer to the structure where the control's info need
88 *               to be filled
89 *
90 * This function is called when a mixer application requests for control's info
91 */
92 static int snd_intelmad_mute_info(struct snd_kcontrol *kcontrol,
93                                         struct snd_ctl_elem_info *uinfo)
94 {
95         WARN_ON(!uinfo);
96         WARN_ON(!kcontrol);
97
98         /* set up the mute as a boolean mono control with min-max values */
99         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
100         uinfo->count = MONO_CNTL;
101         uinfo->value.integer.min = MIN_MUTE;
102         uinfo->value.integer.max = MAX_MUTE;
103         return 0;
104 }
105
106 /**
107 * snd_intelmad_capture_volume_info - provides info about the volume control
108 *
109 * @kcontrol:    pointer to the control
110 * @uinfo:       pointer to the structure where the control's info need
111 *               to be filled
112 *
113 * This function is called when a mixer application requests for control's info
114 */
115 static int snd_intelmad_capture_volume_info(struct snd_kcontrol *kcontrol,
116                                         struct snd_ctl_elem_info *uinfo)
117 {
118         snd_intelmad_volume_info(uinfo, MONO_CNTL,
119                 intelmad_ctrl_val[sst_card_vendor_id].capture_vol_max,
120                 intelmad_ctrl_val[sst_card_vendor_id].capture_vol_min);
121         return 0;
122 }
123
124 /**
125 * snd_intelmad_playback_volume_info - provides info about the volume control
126 *
127 * @kcontrol:    pointer to the control
128 * @uinfo:       pointer to the structure where the control's info need
129 *               to be filled
130 *
131 * This function is called when a mixer application requests for control's info
132 */
133 static int snd_intelmad_playback_volume_info(struct snd_kcontrol *kcontrol,
134                                         struct snd_ctl_elem_info *uinfo)
135 {
136         snd_intelmad_volume_info(uinfo, STEREO_CNTL,
137                 intelmad_ctrl_val[sst_card_vendor_id].playback_vol_max,
138                 intelmad_ctrl_val[sst_card_vendor_id].playback_vol_min);
139         return 0;
140 }
141
142 /**
143 * snd_intelmad_device_info_mrst - provides information about the devices available
144 *
145 * @kcontrol:    pointer to the control
146 * @uinfo:       pointer to the structure where the devices's info need
147 *               to be filled
148 *
149 * This function is called when a mixer application requests for device's info
150 */
151 static int snd_intelmad_device_info_mrst(struct snd_kcontrol *kcontrol,
152                                         struct snd_ctl_elem_info *uinfo)
153 {
154
155         WARN_ON(!kcontrol);
156         WARN_ON(!uinfo);
157
158         /* setup device select as drop down controls with different values */
159         if (kcontrol->id.numid == OUTPUT_SEL)
160                 uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mrst);
161         else
162                 uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mrst);
163         uinfo->count = MONO_CNTL;
164         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
165
166         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
167                 uinfo->value.enumerated.item = 1;
168         if (kcontrol->id.numid == OUTPUT_SEL)
169                 strncpy(uinfo->value.enumerated.name,
170                         out_names_mrst[uinfo->value.enumerated.item],
171                         sizeof(uinfo->value.enumerated.name)-1);
172         else
173                 strncpy(uinfo->value.enumerated.name,
174                         in_names_mrst[uinfo->value.enumerated.item],
175                         sizeof(uinfo->value.enumerated.name)-1);
176         return 0;
177 }
178
179 static int snd_intelmad_device_info_mfld(struct snd_kcontrol *kcontrol,
180                                         struct snd_ctl_elem_info *uinfo)
181 {
182         WARN_ON(!kcontrol);
183         WARN_ON(!uinfo);
184         /* setup device select as drop down controls with different values */
185         if (kcontrol->id.numid == OUTPUT_SEL)
186                 uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mfld);
187         else
188                 uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mfld);
189         uinfo->count = MONO_CNTL;
190         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
191
192         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
193                 uinfo->value.enumerated.item = 1;
194         if (kcontrol->id.numid == OUTPUT_SEL)
195                 strncpy(uinfo->value.enumerated.name,
196                         out_names_mfld[uinfo->value.enumerated.item],
197                         sizeof(uinfo->value.enumerated.name)-1);
198         else
199                 strncpy(uinfo->value.enumerated.name,
200                         in_names_mfld[uinfo->value.enumerated.item],
201                         sizeof(uinfo->value.enumerated.name)-1);
202         return 0;
203 }
204
205 /**
206 * snd_intelmad_volume_get - gets the current volume for the control
207 *
208 * @kcontrol:    pointer to the control
209 * @uval:        pointer to the structure where the control's info need
210 *               to be filled
211 *
212 * This function is called when .get function of a control is invoked from app
213 */
214 static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,
215                                 struct snd_ctl_elem_value *uval)
216 {
217         int ret_val = 0, cntl_list[2] = {0,};
218         int value = 0;
219         struct snd_intelmad *intelmaddata;
220         struct snd_pmic_ops *scard_ops;
221
222         pr_debug("snd_intelmad_volume_get called\n");
223
224         WARN_ON(!uval);
225         WARN_ON(!kcontrol);
226
227         intelmaddata = kcontrol->private_data;
228
229         WARN_ON(!intelmaddata->sstdrv_ops);
230
231         scard_ops = intelmaddata->sstdrv_ops->scard_ops;
232
233         WARN_ON(!scard_ops);
234
235         switch (kcontrol->id.numid) {
236         case PLAYBACK_VOL:
237                 cntl_list[0] = PMIC_SND_RIGHT_PB_VOL;
238                 cntl_list[1] = PMIC_SND_LEFT_PB_VOL;
239                 break;
240
241         case CAPTURE_VOL:
242                 cntl_list[0] = PMIC_SND_CAPTURE_VOL;
243                 break;
244         default:
245                 return -EINVAL;
246         }
247
248         ret_val = scard_ops->get_vol(cntl_list[0], &value);
249         uval->value.integer.value[0] = value;
250
251         if (ret_val)
252                 return ret_val;
253
254         if (kcontrol->id.numid == PLAYBACK_VOL) {
255                 ret_val = scard_ops->get_vol(cntl_list[1], &value);
256                 uval->value.integer.value[1] = value;
257         }
258         return ret_val;
259 }
260
261 /**
262 * snd_intelmad_mute_get - gets the current mute status for the control
263 *
264 * @kcontrol:    pointer to the control
265 * @uval:        pointer to the structure where the control's info need
266 *               to be filled
267 *
268 * This function is called when .get function of a control is invoked from app
269 */
270 static int snd_intelmad_mute_get(struct snd_kcontrol *kcontrol,
271                                         struct snd_ctl_elem_value *uval)
272 {
273
274         int cntl_list = 0, ret_val = 0;
275         u8 value = 0;
276         struct snd_intelmad *intelmaddata;
277         struct snd_pmic_ops *scard_ops;
278
279         pr_debug("Mute_get called\n");
280
281         WARN_ON(!uval);
282         WARN_ON(!kcontrol);
283
284         intelmaddata = kcontrol->private_data;
285
286         WARN_ON(!intelmaddata->sstdrv_ops);
287
288         scard_ops = intelmaddata->sstdrv_ops->scard_ops;
289
290         WARN_ON(!scard_ops);
291
292         switch (kcontrol->id.numid) {
293         case PLAYBACK_MUTE:
294                 if (intelmaddata->output_sel == STEREO_HEADPHONE)
295                         cntl_list = PMIC_SND_LEFT_HP_MUTE;
296                 else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
297                         (intelmaddata->output_sel == MONO_EARPIECE))
298                         cntl_list = PMIC_SND_LEFT_SPEAKER_MUTE;
299                 break;
300
301         case CAPTURE_MUTE:
302                 if (intelmaddata->input_sel == DMIC)
303                         cntl_list = PMIC_SND_DMIC_MUTE;
304                 else if (intelmaddata->input_sel == AMIC)
305                         cntl_list = PMIC_SND_AMIC_MUTE;
306                 else if (intelmaddata->input_sel == HS_MIC)
307                         cntl_list = PMIC_SND_HP_MIC_MUTE;
308                 break;
309         case MASTER_MUTE:
310                 uval->value.integer.value[0] = intelmaddata->master_mute;
311                 return 0;
312         default:
313                 return -EINVAL;
314         }
315
316         ret_val = scard_ops->get_mute(cntl_list, &value);
317         uval->value.integer.value[0] = value;
318         return ret_val;
319 }
320
321 /**
322 * snd_intelmad_volume_set - sets the volume control's info
323 *
324 * @kcontrol:    pointer to the control
325 * @uval:        pointer to the structure where the control's info is
326 *               available to be set
327 *
328 * This function is called when .set function of a control is invoked from app
329 */
330 static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,
331                                         struct snd_ctl_elem_value *uval)
332 {
333
334         int ret_val, cntl_list[2] = {0,};
335         struct snd_intelmad *intelmaddata;
336         struct snd_pmic_ops *scard_ops;
337
338         pr_debug("volume set called:%ld %ld\n",
339                         uval->value.integer.value[0],
340                         uval->value.integer.value[1]);
341
342         WARN_ON(!uval);
343         WARN_ON(!kcontrol);
344
345         intelmaddata = kcontrol->private_data;
346
347         WARN_ON(!intelmaddata->sstdrv_ops);
348
349         scard_ops = intelmaddata->sstdrv_ops->scard_ops;
350
351         WARN_ON(!scard_ops);
352
353         switch (kcontrol->id.numid) {
354         case PLAYBACK_VOL:
355                 cntl_list[0] = PMIC_SND_LEFT_PB_VOL;
356                 cntl_list[1] = PMIC_SND_RIGHT_PB_VOL;
357                 break;
358
359         case CAPTURE_VOL:
360                 cntl_list[0] = PMIC_SND_CAPTURE_VOL;
361                 break;
362         default:
363                 return -EINVAL;
364         }
365
366         ret_val = scard_ops->set_vol(cntl_list[0],
367                                 uval->value.integer.value[0]);
368         if (ret_val)
369                 return ret_val;
370
371         if (kcontrol->id.numid == PLAYBACK_VOL)
372                 ret_val = scard_ops->set_vol(cntl_list[1],
373                                 uval->value.integer.value[1]);
374         return ret_val;
375 }
376
377 /**
378 * snd_intelmad_mute_set - sets the mute control's info
379 *
380 * @kcontrol:    pointer to the control
381 * @uval:        pointer to the structure where the control's info is
382 *               available to be set
383 *
384 * This function is called when .set function of a control is invoked from app
385 */
386 static int snd_intelmad_mute_set(struct snd_kcontrol *kcontrol,
387                                         struct snd_ctl_elem_value *uval)
388 {
389         int cntl_list[2] = {0,}, ret_val;
390         struct snd_intelmad *intelmaddata;
391         struct snd_pmic_ops *scard_ops;
392
393         pr_debug("snd_intelmad_mute_set called\n");
394
395         WARN_ON(!uval);
396         WARN_ON(!kcontrol);
397
398         intelmaddata = kcontrol->private_data;
399
400         WARN_ON(!intelmaddata->sstdrv_ops);
401
402         scard_ops = intelmaddata->sstdrv_ops->scard_ops;
403
404         WARN_ON(!scard_ops);
405
406         kcontrol->private_value = uval->value.integer.value[0];
407
408         switch (kcontrol->id.numid) {
409         case PLAYBACK_MUTE:
410                 if (intelmaddata->output_sel == STEREO_HEADPHONE) {
411                         cntl_list[0] = PMIC_SND_LEFT_HP_MUTE;
412                         cntl_list[1] = PMIC_SND_RIGHT_HP_MUTE;
413                 } else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
414                                 (intelmaddata->output_sel == MONO_EARPIECE)) {
415                         cntl_list[0] = PMIC_SND_LEFT_SPEAKER_MUTE;
416                         cntl_list[1] = PMIC_SND_RIGHT_SPEAKER_MUTE;
417                 }
418                 break;
419
420         case CAPTURE_MUTE:/*based on sel device mute the i/p dev*/
421                 if (intelmaddata->input_sel == DMIC)
422                         cntl_list[0] = PMIC_SND_DMIC_MUTE;
423                 else if (intelmaddata->input_sel == AMIC)
424                         cntl_list[0] = PMIC_SND_AMIC_MUTE;
425                 else if (intelmaddata->input_sel == HS_MIC)
426                         cntl_list[0] = PMIC_SND_HP_MIC_MUTE;
427                 break;
428         case MASTER_MUTE:
429                 cntl_list[0] = PMIC_SND_MUTE_ALL;
430                 intelmaddata->master_mute = uval->value.integer.value[0];
431                 break;
432         default:
433                 return -EINVAL;
434         }
435
436         ret_val = scard_ops->set_mute(cntl_list[0],
437                                 uval->value.integer.value[0]);
438         if (ret_val)
439                 return ret_val;
440
441         if (kcontrol->id.numid == PLAYBACK_MUTE)
442                 ret_val = scard_ops->set_mute(cntl_list[1],
443                                         uval->value.integer.value[0]);
444         return ret_val;
445 }
446
447 /**
448 * snd_intelmad_device_get - get the device select control's info
449 *
450 * @kcontrol:    pointer to the control
451 * @uval:        pointer to the structure where the control's info is
452 *               to be filled
453 *
454 * This function is called when .get function of a control is invoked from app
455 */
456 static int snd_intelmad_device_get(struct snd_kcontrol *kcontrol,
457                                         struct snd_ctl_elem_value *uval)
458 {
459         struct snd_intelmad *intelmaddata;
460         struct snd_pmic_ops *scard_ops;
461         pr_debug("device_get called\n");
462
463         WARN_ON(!uval);
464         WARN_ON(!kcontrol);
465
466         intelmaddata = kcontrol->private_data;
467         if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
468                 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
469                 if (kcontrol->id.numid == OUTPUT_SEL)
470                         uval->value.enumerated.item[0] =
471                                         scard_ops->output_dev_id;
472                 else if (kcontrol->id.numid == INPUT_SEL)
473                         uval->value.enumerated.item[0] =
474                                         scard_ops->input_dev_id;
475                 else
476                         return -EINVAL;
477         } else
478         uval->value.enumerated.item[0] = kcontrol->private_value;
479         return 0;
480 }
481
482 /**
483 * snd_intelmad_device_set - set the device select control's info
484 *
485 * @kcontrol:    pointer to the control
486 * @uval:        pointer to the structure where the control's info is
487 *               available to be set
488 *
489 * This function is called when .set function of a control is invoked from app
490 */
491 static int snd_intelmad_device_set(struct snd_kcontrol *kcontrol,
492                                         struct snd_ctl_elem_value *uval)
493 {
494         struct snd_intelmad *intelmaddata;
495         struct snd_pmic_ops *scard_ops;
496         int ret_val = 0, vendor, status;
497         struct intel_sst_pcm_control *pcm_control;
498
499         pr_debug("snd_intelmad_device_set called\n");
500
501         WARN_ON(!uval);
502         WARN_ON(!kcontrol);
503         status = -1;
504
505         intelmaddata = kcontrol->private_data;
506
507         WARN_ON(!intelmaddata->sstdrv_ops);
508
509         scard_ops = intelmaddata->sstdrv_ops->scard_ops;
510
511         WARN_ON(!scard_ops);
512
513         /* store value with driver */
514         kcontrol->private_value = uval->value.enumerated.item[0];
515
516         switch (kcontrol->id.numid) {
517         case OUTPUT_SEL:
518                 ret_val = scard_ops->set_output_dev(
519                                 uval->value.enumerated.item[0]);
520                 intelmaddata->output_sel = uval->value.enumerated.item[0];
521                 break;
522         case INPUT_SEL:
523                 vendor = intelmaddata->sstdrv_ops->vendor_id;
524                 if ((vendor == SND_MX) || (vendor == SND_FS)) {
525                         pcm_control = intelmaddata->sstdrv_ops->pcm_control;
526                         if (uval->value.enumerated.item[0] == HS_MIC)
527                                 status = 1;
528                         else
529                                 status = 0;
530                         pcm_control->device_control(
531                                         SST_ENABLE_RX_TIME_SLOT, &status);
532                 }
533                 ret_val = scard_ops->set_input_dev(
534                                 uval->value.enumerated.item[0]);
535                 intelmaddata->input_sel = uval->value.enumerated.item[0];
536                 break;
537         default:
538                 return -EINVAL;
539         }
540         kcontrol->private_value = uval->value.enumerated.item[0];
541         return ret_val;
542 }
543
544 struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = {
545 {
546         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
547         .name           =       "PCM Playback Source",
548         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
549         .info           =       snd_intelmad_device_info_mrst,
550         .get            =       snd_intelmad_device_get,
551         .put            =       snd_intelmad_device_set,
552         .private_value  =       0,
553 },
554 {
555         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
556         .name           =       "PCM Capture Source",
557         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
558         .info           =       snd_intelmad_device_info_mrst,
559         .get            =       snd_intelmad_device_get,
560         .put            =       snd_intelmad_device_set,
561         .private_value  =       0,
562 },
563 {
564         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
565         .name           =       "PCM Playback Volume",
566         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
567         .info           =       snd_intelmad_playback_volume_info,
568         .get            =       snd_intelmad_volume_get,
569         .put            =       snd_intelmad_volume_set,
570         .private_value  =       0,
571 },
572 {
573         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
574         .name           =       "PCM Playback Switch",
575         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
576         .info           =       snd_intelmad_mute_info,
577         .get            =       snd_intelmad_mute_get,
578         .put            =       snd_intelmad_mute_set,
579         .private_value  =       0,
580 },
581 {
582         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
583         .name           =       "PCM Capture Volume",
584         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
585         .info           =       snd_intelmad_capture_volume_info,
586         .get            =       snd_intelmad_volume_get,
587         .put            =       snd_intelmad_volume_set,
588         .private_value  =       0,
589 },
590 {
591         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
592         .name           =       "PCM Capture Switch",
593         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
594         .info           =       snd_intelmad_mute_info,
595         .get            =       snd_intelmad_mute_get,
596         .put            =       snd_intelmad_mute_set,
597         .private_value  =       0,
598 },
599 {
600         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
601         .name           =       "Master Playback Switch",
602         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
603         .info           =       snd_intelmad_mute_info,
604         .get            =       snd_intelmad_mute_get,
605         .put            =       snd_intelmad_mute_set,
606         .private_value  =       0,
607 },
608 };
609
610 struct snd_kcontrol_new
611 snd_intelmad_controls_mfld[MAX_CTRL_MFLD] __devinitdata = {
612 {
613         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
614         .name           =       "PCM Playback Source",
615         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
616         .info           =       snd_intelmad_device_info_mfld,
617         .get            =       snd_intelmad_device_get,
618         .put            =       snd_intelmad_device_set,
619         .private_value  =       0,
620 },
621 {
622         .iface          =       SNDRV_CTL_ELEM_IFACE_MIXER,
623         .name           =       "PCM Capture Source",
624         .access         =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
625         .info           =       snd_intelmad_device_info_mfld,
626         .get            =       snd_intelmad_device_get,
627         .put            =       snd_intelmad_device_set,
628         .private_value  =       0,
629 },
630 };
631