staging:iio:trigger handle name attr in core, remove old alloc and register any contr...
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / intel_sst / intelmid_ctrl.c
blob19ec474b362a75d496d9dbbb0e6642d034faf603
1 /*
2 * intelmid_ctrl.c - Intel Sound card driver for MID
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 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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.
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.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 * ALSA driver handling mixer controls for Intel MAD chipset
28 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30 #include <sound/core.h>
31 #include <sound/control.h>
32 #include "intel_sst.h"
33 #include "intel_sst_ioctl.h"
34 #include "intelmid_snd_control.h"
35 #include "intelmid.h"
37 #define HW_CH_BASE 4
40 #define HW_CH_0 "Hw1"
41 #define HW_CH_1 "Hw2"
42 #define HW_CH_2 "Hw3"
43 #define HW_CH_3 "Hw4"
45 static char *router_dmics[] = { "DMIC1",
46 "DMIC2",
47 "DMIC3",
48 "DMIC4",
49 "DMIC5",
50 "DMIC6"
53 static char *out_names_mrst[] = {"Headphones",
54 "Internal speakers"};
55 static char *in_names_mrst[] = {"AMIC",
56 "DMIC",
57 "HS_MIC"};
58 static char *line_out_names_mfld[] = {"Headset",
59 "IHF ",
60 "Vibra1 ",
61 "Vibra2 ",
62 "NONE "};
63 static char *out_names_mfld[] = {"Headset ",
64 "EarPiece "};
65 static char *in_names_mfld[] = {"AMIC",
66 "DMIC"};
68 struct snd_control_val intelmad_ctrl_val[MAX_VENDORS] = {
70 .playback_vol_max = 63,
71 .playback_vol_min = 0,
72 .capture_vol_max = 63,
73 .capture_vol_min = 0,
76 .playback_vol_max = 0,
77 .playback_vol_min = -31,
78 .capture_vol_max = 0,
79 .capture_vol_min = -20,
82 .playback_vol_max = 0,
83 .playback_vol_min = -31,
84 .capture_vol_max = 0,
85 .capture_vol_min = -31,
86 .master_vol_max = 0,
87 .master_vol_min = -126,
91 /* control path functionalities */
93 static inline int snd_intelmad_volume_info(struct snd_ctl_elem_info *uinfo,
94 int control_type, int max, int min)
96 WARN_ON(!uinfo);
98 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
99 uinfo->count = control_type;
100 uinfo->value.integer.min = min;
101 uinfo->value.integer.max = max;
102 return 0;
106 * snd_intelmad_mute_info - provides information about the mute controls
108 * @kcontrol: pointer to the control
109 * @uinfo: pointer to the structure where the control's info need
110 * to be filled
112 * This function is called when a mixer application requests for control's info
114 static int snd_intelmad_mute_info(struct snd_kcontrol *kcontrol,
115 struct snd_ctl_elem_info *uinfo)
117 WARN_ON(!uinfo);
118 WARN_ON(!kcontrol);
120 /* set up the mute as a boolean mono control with min-max values */
121 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
122 uinfo->count = MONO_CNTL;
123 uinfo->value.integer.min = MIN_MUTE;
124 uinfo->value.integer.max = MAX_MUTE;
125 return 0;
129 * snd_intelmad_capture_volume_info - provides info about the volume control
131 * @kcontrol: pointer to the control
132 * @uinfo: pointer to the structure where the control's info need
133 * to be filled
135 * This function is called when a mixer application requests for control's info
137 static int snd_intelmad_capture_volume_info(struct snd_kcontrol *kcontrol,
138 struct snd_ctl_elem_info *uinfo)
140 snd_intelmad_volume_info(uinfo, MONO_CNTL,
141 intelmad_ctrl_val[sst_card_vendor_id].capture_vol_max,
142 intelmad_ctrl_val[sst_card_vendor_id].capture_vol_min);
143 return 0;
147 * snd_intelmad_playback_volume_info - provides info about the volume control
149 * @kcontrol: pointer to the control
150 * @uinfo: pointer to the structure where the control's info need
151 * to be filled
153 * This function is called when a mixer application requests for control's info
155 static int snd_intelmad_playback_volume_info(struct snd_kcontrol *kcontrol,
156 struct snd_ctl_elem_info *uinfo)
158 snd_intelmad_volume_info(uinfo, STEREO_CNTL,
159 intelmad_ctrl_val[sst_card_vendor_id].playback_vol_max,
160 intelmad_ctrl_val[sst_card_vendor_id].playback_vol_min);
161 return 0;
164 static int snd_intelmad_master_volume_info(struct snd_kcontrol *kcontrol,
165 struct snd_ctl_elem_info *uinfo)
167 snd_intelmad_volume_info(uinfo, STEREO_CNTL,
168 intelmad_ctrl_val[sst_card_vendor_id].master_vol_max,
169 intelmad_ctrl_val[sst_card_vendor_id].master_vol_min);
170 return 0;
174 * snd_intelmad_device_info_mrst - provides information about the devices available
176 * @kcontrol: pointer to the control
177 * @uinfo: pointer to the structure where the devices's info need
178 * to be filled
180 * This function is called when a mixer application requests for device's info
182 static int snd_intelmad_device_info_mrst(struct snd_kcontrol *kcontrol,
183 struct snd_ctl_elem_info *uinfo)
186 WARN_ON(!kcontrol);
187 WARN_ON(!uinfo);
189 /* setup device select as drop down controls with different values */
190 if (kcontrol->id.numid == OUTPUT_SEL)
191 uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mrst);
192 else
193 uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mrst);
194 uinfo->count = MONO_CNTL;
195 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
197 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
198 uinfo->value.enumerated.item = 1;
199 if (kcontrol->id.numid == OUTPUT_SEL)
200 strncpy(uinfo->value.enumerated.name,
201 out_names_mrst[uinfo->value.enumerated.item],
202 sizeof(uinfo->value.enumerated.name)-1);
203 else
204 strncpy(uinfo->value.enumerated.name,
205 in_names_mrst[uinfo->value.enumerated.item],
206 sizeof(uinfo->value.enumerated.name)-1);
207 return 0;
210 static int snd_intelmad_device_info_mfld(struct snd_kcontrol *kcontrol,
211 struct snd_ctl_elem_info *uinfo)
213 struct snd_pmic_ops *scard_ops;
214 struct snd_intelmad *intelmaddata;
216 WARN_ON(!kcontrol);
217 WARN_ON(!uinfo);
219 intelmaddata = kcontrol->private_data;
221 WARN_ON(!intelmaddata->sstdrv_ops);
223 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
224 /* setup device select as drop down controls with different values */
225 if (kcontrol->id.numid == OUTPUT_SEL)
226 uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mfld);
227 else if (kcontrol->id.numid == INPUT_SEL)
228 uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mfld);
229 else if (kcontrol->id.numid == LINEOUT_SEL_MFLD) {
230 uinfo->value.enumerated.items = ARRAY_SIZE(line_out_names_mfld);
231 scard_ops->line_out_names_cnt = uinfo->value.enumerated.items;
232 } else
233 return -EINVAL;
234 uinfo->count = MONO_CNTL;
235 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
237 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
238 uinfo->value.enumerated.item = 1;
239 if (kcontrol->id.numid == OUTPUT_SEL)
240 strncpy(uinfo->value.enumerated.name,
241 out_names_mfld[uinfo->value.enumerated.item],
242 sizeof(uinfo->value.enumerated.name)-1);
243 else if (kcontrol->id.numid == INPUT_SEL)
244 strncpy(uinfo->value.enumerated.name,
245 in_names_mfld[uinfo->value.enumerated.item],
246 sizeof(uinfo->value.enumerated.name)-1);
247 else if (kcontrol->id.numid == LINEOUT_SEL_MFLD)
248 strncpy(uinfo->value.enumerated.name,
249 line_out_names_mfld[uinfo->value.enumerated.item],
250 sizeof(uinfo->value.enumerated.name)-1);
251 else
252 return -EINVAL;
253 return 0;
257 * snd_intelmad_volume_get - gets the current volume for the control
259 * @kcontrol: pointer to the control
260 * @uval: pointer to the structure where the control's info need
261 * to be filled
263 * This function is called when .get function of a control is invoked from app
265 static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,
266 struct snd_ctl_elem_value *uval)
268 int ret_val = 0, cntl_list[2] = {0,};
269 int value = 0;
270 struct snd_intelmad *intelmaddata;
271 struct snd_pmic_ops *scard_ops;
273 pr_debug("snd_intelmad_volume_get called\n");
275 WARN_ON(!uval);
276 WARN_ON(!kcontrol);
278 intelmaddata = kcontrol->private_data;
280 WARN_ON(!intelmaddata->sstdrv_ops);
282 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
284 WARN_ON(!scard_ops);
286 switch (kcontrol->id.numid) {
287 case PLAYBACK_VOL:
288 cntl_list[0] = PMIC_SND_RIGHT_PB_VOL;
289 cntl_list[1] = PMIC_SND_LEFT_PB_VOL;
290 break;
292 case CAPTURE_VOL:
293 cntl_list[0] = PMIC_SND_CAPTURE_VOL;
294 break;
296 case MASTER_VOL:
297 cntl_list[0] = PMIC_SND_RIGHT_MASTER_VOL;
298 cntl_list[1] = PMIC_SND_LEFT_MASTER_VOL;
299 break;
300 default:
301 return -EINVAL;
304 ret_val = scard_ops->get_vol(cntl_list[0], &value);
305 uval->value.integer.value[0] = value;
307 if (ret_val)
308 return ret_val;
310 if (kcontrol->id.numid == PLAYBACK_VOL ||
311 kcontrol->id.numid == MASTER_VOL) {
312 ret_val = scard_ops->get_vol(cntl_list[1], &value);
313 uval->value.integer.value[1] = value;
315 return ret_val;
319 * snd_intelmad_mute_get - gets the current mute status for the control
321 * @kcontrol: pointer to the control
322 * @uval: pointer to the structure where the control's info need
323 * to be filled
325 * This function is called when .get function of a control is invoked from app
327 static int snd_intelmad_mute_get(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *uval)
331 int cntl_list = 0, ret_val = 0;
332 u8 value = 0;
333 struct snd_intelmad *intelmaddata;
334 struct snd_pmic_ops *scard_ops;
336 pr_debug("Mute_get called\n");
338 WARN_ON(!uval);
339 WARN_ON(!kcontrol);
341 intelmaddata = kcontrol->private_data;
343 WARN_ON(!intelmaddata->sstdrv_ops);
345 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
347 WARN_ON(!scard_ops);
349 switch (kcontrol->id.numid) {
350 case PLAYBACK_MUTE:
351 if (intelmaddata->output_sel == STEREO_HEADPHONE)
352 cntl_list = PMIC_SND_LEFT_HP_MUTE;
353 else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
354 (intelmaddata->output_sel == MONO_EARPIECE))
355 cntl_list = PMIC_SND_LEFT_SPEAKER_MUTE;
356 break;
358 case CAPTURE_MUTE:
359 if (intelmaddata->input_sel == DMIC)
360 cntl_list = PMIC_SND_DMIC_MUTE;
361 else if (intelmaddata->input_sel == AMIC)
362 cntl_list = PMIC_SND_AMIC_MUTE;
363 else if (intelmaddata->input_sel == HS_MIC)
364 cntl_list = PMIC_SND_HP_MIC_MUTE;
365 break;
366 case MASTER_MUTE:
367 uval->value.integer.value[0] = intelmaddata->master_mute;
368 return 0;
369 default:
370 return -EINVAL;
373 ret_val = scard_ops->get_mute(cntl_list, &value);
374 uval->value.integer.value[0] = value;
375 return ret_val;
379 * snd_intelmad_volume_set - sets the volume control's info
381 * @kcontrol: pointer to the control
382 * @uval: pointer to the structure where the control's info is
383 * available to be set
385 * This function is called when .set function of a control is invoked from app
387 static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,
388 struct snd_ctl_elem_value *uval)
391 int ret_val, cntl_list[2] = {0,};
392 struct snd_intelmad *intelmaddata;
393 struct snd_pmic_ops *scard_ops;
395 pr_debug("volume set called:%ld %ld\n",
396 uval->value.integer.value[0],
397 uval->value.integer.value[1]);
399 WARN_ON(!uval);
400 WARN_ON(!kcontrol);
402 intelmaddata = kcontrol->private_data;
404 WARN_ON(!intelmaddata->sstdrv_ops);
406 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
408 WARN_ON(!scard_ops);
410 switch (kcontrol->id.numid) {
411 case PLAYBACK_VOL:
412 cntl_list[0] = PMIC_SND_LEFT_PB_VOL;
413 cntl_list[1] = PMIC_SND_RIGHT_PB_VOL;
414 break;
416 case CAPTURE_VOL:
417 cntl_list[0] = PMIC_SND_CAPTURE_VOL;
418 break;
420 case MASTER_VOL:
421 cntl_list[0] = PMIC_SND_LEFT_MASTER_VOL;
422 cntl_list[1] = PMIC_SND_RIGHT_MASTER_VOL;
423 break;
425 default:
426 return -EINVAL;
429 ret_val = scard_ops->set_vol(cntl_list[0],
430 uval->value.integer.value[0]);
431 if (ret_val)
432 return ret_val;
434 if (kcontrol->id.numid == PLAYBACK_VOL ||
435 kcontrol->id.numid == MASTER_VOL)
436 ret_val = scard_ops->set_vol(cntl_list[1],
437 uval->value.integer.value[1]);
438 return ret_val;
442 * snd_intelmad_mute_set - sets the mute control's info
444 * @kcontrol: pointer to the control
445 * @uval: pointer to the structure where the control's info is
446 * available to be set
448 * This function is called when .set function of a control is invoked from app
450 static int snd_intelmad_mute_set(struct snd_kcontrol *kcontrol,
451 struct snd_ctl_elem_value *uval)
453 int cntl_list[2] = {0,}, ret_val;
454 struct snd_intelmad *intelmaddata;
455 struct snd_pmic_ops *scard_ops;
457 pr_debug("snd_intelmad_mute_set called\n");
459 WARN_ON(!uval);
460 WARN_ON(!kcontrol);
462 intelmaddata = kcontrol->private_data;
464 WARN_ON(!intelmaddata->sstdrv_ops);
466 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
468 WARN_ON(!scard_ops);
470 kcontrol->private_value = uval->value.integer.value[0];
472 switch (kcontrol->id.numid) {
473 case PLAYBACK_MUTE:
474 if (intelmaddata->output_sel == STEREO_HEADPHONE) {
475 cntl_list[0] = PMIC_SND_LEFT_HP_MUTE;
476 cntl_list[1] = PMIC_SND_RIGHT_HP_MUTE;
477 } else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
478 (intelmaddata->output_sel == MONO_EARPIECE)) {
479 cntl_list[0] = PMIC_SND_LEFT_SPEAKER_MUTE;
480 cntl_list[1] = PMIC_SND_RIGHT_SPEAKER_MUTE;
482 break;
484 case CAPTURE_MUTE:/*based on sel device mute the i/p dev*/
485 if (intelmaddata->input_sel == DMIC)
486 cntl_list[0] = PMIC_SND_DMIC_MUTE;
487 else if (intelmaddata->input_sel == AMIC)
488 cntl_list[0] = PMIC_SND_AMIC_MUTE;
489 else if (intelmaddata->input_sel == HS_MIC)
490 cntl_list[0] = PMIC_SND_HP_MIC_MUTE;
491 break;
492 case MASTER_MUTE:
493 cntl_list[0] = PMIC_SND_MUTE_ALL;
494 intelmaddata->master_mute = uval->value.integer.value[0];
495 break;
496 default:
497 return -EINVAL;
500 ret_val = scard_ops->set_mute(cntl_list[0],
501 uval->value.integer.value[0]);
502 if (ret_val)
503 return ret_val;
505 if (kcontrol->id.numid == PLAYBACK_MUTE)
506 ret_val = scard_ops->set_mute(cntl_list[1],
507 uval->value.integer.value[0]);
508 return ret_val;
512 * snd_intelmad_device_get - get the device select control's info
514 * @kcontrol: pointer to the control
515 * @uval: pointer to the structure where the control's info is
516 * to be filled
518 * This function is called when .get function of a control is invoked from app
520 static int snd_intelmad_device_get(struct snd_kcontrol *kcontrol,
521 struct snd_ctl_elem_value *uval)
523 struct snd_intelmad *intelmaddata;
524 struct snd_pmic_ops *scard_ops;
525 pr_debug("device_get called\n");
527 WARN_ON(!uval);
528 WARN_ON(!kcontrol);
530 intelmaddata = kcontrol->private_data;
531 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
532 if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
533 if (kcontrol->id.numid == OUTPUT_SEL)
534 uval->value.enumerated.item[0] =
535 scard_ops->output_dev_id;
536 else if (kcontrol->id.numid == INPUT_SEL)
537 uval->value.enumerated.item[0] =
538 scard_ops->input_dev_id;
539 else if (kcontrol->id.numid == LINEOUT_SEL_MFLD)
540 uval->value.enumerated.item[0] =
541 scard_ops->lineout_dev_id;
542 else
543 return -EINVAL;
544 } else if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT) {
545 if (kcontrol->id.numid == OUTPUT_SEL)
546 /* There is a mismatch here.
547 * ALSA expects 1 for internal speaker.
548 * But internally, we may give 2 for internal speaker.
550 if (scard_ops->output_dev_id == MONO_EARPIECE ||
551 scard_ops->output_dev_id == INTERNAL_SPKR)
552 uval->value.enumerated.item[0] = MONO_EARPIECE;
553 else if (scard_ops->output_dev_id == STEREO_HEADPHONE)
554 uval->value.enumerated.item[0] =
555 STEREO_HEADPHONE;
556 else
557 return -EINVAL;
558 else if (kcontrol->id.numid == INPUT_SEL)
559 uval->value.enumerated.item[0] =
560 scard_ops->input_dev_id;
561 else
562 return -EINVAL;
563 } else
564 uval->value.enumerated.item[0] = kcontrol->private_value;
565 return 0;
569 * snd_intelmad_device_set - set the device select control's info
571 * @kcontrol: pointer to the control
572 * @uval: pointer to the structure where the control's info is
573 * available to be set
575 * This function is called when .set function of a control is invoked from app
577 static int snd_intelmad_device_set(struct snd_kcontrol *kcontrol,
578 struct snd_ctl_elem_value *uval)
580 struct snd_intelmad *intelmaddata;
581 struct snd_pmic_ops *scard_ops;
582 int ret_val = 0, vendor, status;
583 struct intel_sst_pcm_control *pcm_control;
585 pr_debug("snd_intelmad_device_set called\n");
587 WARN_ON(!uval);
588 WARN_ON(!kcontrol);
589 status = -1;
591 intelmaddata = kcontrol->private_data;
593 WARN_ON(!intelmaddata->sstdrv_ops);
595 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
597 WARN_ON(!scard_ops);
599 /* store value with driver */
600 kcontrol->private_value = uval->value.enumerated.item[0];
602 switch (kcontrol->id.numid) {
603 case OUTPUT_SEL:
604 ret_val = scard_ops->set_output_dev(
605 uval->value.enumerated.item[0]);
606 intelmaddata->output_sel = uval->value.enumerated.item[0];
607 break;
608 case INPUT_SEL:
609 vendor = intelmaddata->sstdrv_ops->vendor_id;
610 if ((vendor == SND_MX) || (vendor == SND_FS)) {
611 pcm_control = intelmaddata->sstdrv_ops->pcm_control;
612 if (uval->value.enumerated.item[0] == HS_MIC)
613 status = 1;
614 else
615 status = 0;
616 pcm_control->device_control(
617 SST_ENABLE_RX_TIME_SLOT, &status);
619 ret_val = scard_ops->set_input_dev(
620 uval->value.enumerated.item[0]);
621 intelmaddata->input_sel = uval->value.enumerated.item[0];
622 break;
623 case LINEOUT_SEL_MFLD:
624 ret_val = scard_ops->set_lineout_dev(
625 uval->value.enumerated.item[0]);
626 intelmaddata->lineout_sel = uval->value.enumerated.item[0];
627 break;
628 default:
629 return -EINVAL;
631 kcontrol->private_value = uval->value.enumerated.item[0];
632 return ret_val;
635 static int snd_intelmad_device_dmic_get(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *uval)
638 struct snd_intelmad *intelmaddata;
639 struct snd_pmic_ops *scard_ops;
641 WARN_ON(!uval);
642 WARN_ON(!kcontrol);
644 intelmaddata = kcontrol->private_data;
645 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
647 if (scard_ops->input_dev_id != DMIC) {
648 pr_debug("input dev = 0x%x\n", scard_ops->input_dev_id);
649 return 0;
652 if (intelmaddata->cpu_id == CPU_CHIP_PENWELL)
653 uval->value.enumerated.item[0] = kcontrol->private_value;
654 else
655 pr_debug(" CPU id = 0x%xis invalid.\n",
656 intelmaddata->cpu_id);
657 return 0;
660 void msic_set_bit(u8 index, unsigned int *available_dmics)
662 *available_dmics |= (1 << index);
665 void msic_clear_bit(u8 index, unsigned int *available_dmics)
667 *available_dmics &= ~(1 << index);
670 int msic_is_set_bit(u8 index, unsigned int *available_dmics)
672 int ret_val;
674 ret_val = (*available_dmics & (1 << index));
675 return ret_val;
678 static int snd_intelmad_device_dmic_set(struct snd_kcontrol *kcontrol,
679 struct snd_ctl_elem_value *uval)
681 struct snd_intelmad *intelmaddata;
682 struct snd_pmic_ops *scard_ops;
683 int i, dmic_index;
684 unsigned int available_dmics;
685 int jump_count;
686 int max_dmics = ARRAY_SIZE(router_dmics);
688 WARN_ON(!uval);
689 WARN_ON(!kcontrol);
691 intelmaddata = kcontrol->private_data;
692 WARN_ON(!intelmaddata->sstdrv_ops);
694 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
695 WARN_ON(!scard_ops);
697 if (scard_ops->input_dev_id != DMIC) {
698 pr_debug("input dev = 0x%x\n", scard_ops->input_dev_id);
699 return 0;
702 available_dmics = scard_ops->available_dmics;
704 if (kcontrol->private_value > uval->value.enumerated.item[0]) {
705 pr_debug("jump count -1.\n");
706 jump_count = -1;
707 } else {
708 pr_debug("jump count 1.\n");
709 jump_count = 1;
712 dmic_index = uval->value.enumerated.item[0];
713 pr_debug("set function. dmic_index = %d, avl_dmic = 0x%x\n",
714 dmic_index, available_dmics);
715 for (i = 0; i < max_dmics; i++) {
716 pr_debug("set function. loop index = 0x%x. dmic_index = 0x%x\n",
717 i, dmic_index);
718 if (!msic_is_set_bit(dmic_index, &available_dmics)) {
719 msic_clear_bit(kcontrol->private_value,
720 &available_dmics);
721 msic_set_bit(dmic_index, &available_dmics);
722 kcontrol->private_value = dmic_index;
723 scard_ops->available_dmics = available_dmics;
724 scard_ops->hw_dmic_map[kcontrol->id.numid-HW_CH_BASE] =
725 kcontrol->private_value;
726 scard_ops->set_hw_dmic_route
727 (kcontrol->id.numid-HW_CH_BASE);
728 return 0;
731 dmic_index += jump_count;
733 if (dmic_index > (max_dmics - 1) && jump_count == 1) {
734 pr_debug("Resettingthe dmic index to 0.\n");
735 dmic_index = 0;
736 } else if (dmic_index == -1 && jump_count == -1) {
737 pr_debug("Resetting the dmic index to 5.\n");
738 dmic_index = max_dmics - 1;
742 return -EINVAL;
745 static int snd_intelmad_device_dmic_info_mfld(struct snd_kcontrol *kcontrol,
746 struct snd_ctl_elem_info *uinfo)
748 struct snd_intelmad *intelmaddata;
749 struct snd_pmic_ops *scard_ops;
751 uinfo->count = MONO_CNTL;
752 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
753 uinfo->value.enumerated.items = ARRAY_SIZE(router_dmics);
755 intelmaddata = kcontrol->private_data;
756 WARN_ON(!intelmaddata->sstdrv_ops);
758 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
759 WARN_ON(!scard_ops);
761 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
762 uinfo->value.enumerated.item =
763 uinfo->value.enumerated.items - 1;
765 strncpy(uinfo->value.enumerated.name,
766 router_dmics[uinfo->value.enumerated.item],
767 sizeof(uinfo->value.enumerated.name)-1);
770 msic_set_bit(kcontrol->private_value, &scard_ops->available_dmics);
771 pr_debug("info function. avl_dmic = 0x%x",
772 scard_ops->available_dmics);
774 scard_ops->hw_dmic_map[kcontrol->id.numid-HW_CH_BASE] =
775 kcontrol->private_value;
777 return 0;
780 struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = {
782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
783 .name = "PCM Playback Source",
784 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
785 .info = snd_intelmad_device_info_mrst,
786 .get = snd_intelmad_device_get,
787 .put = snd_intelmad_device_set,
788 .private_value = 0,
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792 .name = "PCM Capture Source",
793 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
794 .info = snd_intelmad_device_info_mrst,
795 .get = snd_intelmad_device_get,
796 .put = snd_intelmad_device_set,
797 .private_value = 0,
800 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
801 .name = "PCM Playback Volume",
802 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
803 .info = snd_intelmad_playback_volume_info,
804 .get = snd_intelmad_volume_get,
805 .put = snd_intelmad_volume_set,
806 .private_value = 0,
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "PCM Playback Switch",
811 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
812 .info = snd_intelmad_mute_info,
813 .get = snd_intelmad_mute_get,
814 .put = snd_intelmad_mute_set,
815 .private_value = 0,
818 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
819 .name = "PCM Capture Volume",
820 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
821 .info = snd_intelmad_capture_volume_info,
822 .get = snd_intelmad_volume_get,
823 .put = snd_intelmad_volume_set,
824 .private_value = 0,
827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
828 .name = "PCM Capture Switch",
829 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
830 .info = snd_intelmad_mute_info,
831 .get = snd_intelmad_mute_get,
832 .put = snd_intelmad_mute_set,
833 .private_value = 0,
836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
837 .name = "Master Playback Volume",
838 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
839 .info = snd_intelmad_master_volume_info,
840 .get = snd_intelmad_volume_get,
841 .put = snd_intelmad_volume_set,
842 .private_value = 0,
845 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
846 .name = "Master Playback Switch",
847 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
848 .info = snd_intelmad_mute_info,
849 .get = snd_intelmad_mute_get,
850 .put = snd_intelmad_mute_set,
851 .private_value = 0,
855 struct snd_kcontrol_new
856 snd_intelmad_controls_mfld[MAX_CTRL_MFLD] __devinitdata = {
858 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
859 .name = "PCM Playback Source",
860 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
861 .info = snd_intelmad_device_info_mfld,
862 .get = snd_intelmad_device_get,
863 .put = snd_intelmad_device_set,
864 .private_value = 0,
867 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
868 .name = "PCM Capture Source",
869 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
870 .info = snd_intelmad_device_info_mfld,
871 .get = snd_intelmad_device_get,
872 .put = snd_intelmad_device_set,
873 .private_value = 0,
876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
877 .name = "Line out",
878 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
879 .info = snd_intelmad_device_info_mfld,
880 .get = snd_intelmad_device_get,
881 .put = snd_intelmad_device_set,
882 .private_value = 0,
885 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
886 .name = HW_CH_0,
887 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
888 .info = snd_intelmad_device_dmic_info_mfld,
889 .get = snd_intelmad_device_dmic_get,
890 .put = snd_intelmad_device_dmic_set,
891 .private_value = 0
894 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
895 .name = HW_CH_1,
896 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
897 .info = snd_intelmad_device_dmic_info_mfld,
898 .get = snd_intelmad_device_dmic_get,
899 .put = snd_intelmad_device_dmic_set,
900 .private_value = 1
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = HW_CH_2,
905 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
906 .info = snd_intelmad_device_dmic_info_mfld,
907 .get = snd_intelmad_device_dmic_get,
908 .put = snd_intelmad_device_dmic_set,
909 .private_value = 2
912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
913 .name = HW_CH_3,
914 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
915 .info = snd_intelmad_device_dmic_info_mfld,
916 .get = snd_intelmad_device_dmic_get,
917 .put = snd_intelmad_device_dmic_set,
918 .private_value = 3