Staging: sst: Intel SST audio driver
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / intel_sst / intelmid_ctrl.c
blob03b4ece02f913278d8b3506374482c059a0c6b1f
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
27 #include <sound/core.h>
28 #include <sound/control.h>
29 #include "jack.h"
30 #include "intel_sst.h"
31 #include "intel_sst_ioctl.h"
32 #include "intelmid_snd_control.h"
33 #include "intelmid.h"
35 static char *out_names_mrst[] = {"Headphones",
36 "Internal speakers"};
37 static char *in_names_mrst[] = {"AMIC",
38 "DMIC",
39 "HS_MIC"};
40 static char *out_names_mfld[] = {"Headset ",
41 "EarPiece "};
42 static char *in_names_mfld[] = {"AMIC",
43 "DMIC"};
45 struct snd_control_val intelmad_ctrl_val[MAX_VENDORS] = {
47 .playback_vol_max = 63,
48 .playback_vol_min = 0,
49 .capture_vol_max = 63,
50 .capture_vol_min = 0,
53 .playback_vol_max = 0,
54 .playback_vol_min = -31,
55 .capture_vol_max = 0,
56 .capture_vol_min = -20,
59 .playback_vol_max = 0,
60 .playback_vol_min = -126,
61 .capture_vol_max = 0,
62 .capture_vol_min = -31,
66 /* control path functionalities */
68 static inline int snd_intelmad_volume_info(struct snd_ctl_elem_info *uinfo,
69 int control_type, int max, int min)
71 WARN_ON(!uinfo);
73 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
74 uinfo->count = control_type;
75 uinfo->value.integer.min = min;
76 uinfo->value.integer.max = max;
77 return 0;
80 /**
81 * snd_intelmad_mute_info - provides information about the mute controls
83 * @kcontrol: pointer to the control
84 * @uinfo: pointer to the structure where the control's info need
85 * to be filled
87 * This function is called when a mixer application requests for control's info
89 static int snd_intelmad_mute_info(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_info *uinfo)
92 WARN_ON(!uinfo);
93 WARN_ON(!kcontrol);
95 /* set up the mute as a boolean mono control with min-max values */
96 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
97 uinfo->count = MONO_CNTL;
98 uinfo->value.integer.min = MIN_MUTE;
99 uinfo->value.integer.max = MAX_MUTE;
100 return 0;
104 * snd_intelmad_capture_volume_info - provides info about the volume control
106 * @kcontrol: pointer to the control
107 * @uinfo: pointer to the structure where the control's info need
108 * to be filled
110 * This function is called when a mixer application requests for control's info
112 static int snd_intelmad_capture_volume_info(struct snd_kcontrol *kcontrol,
113 struct snd_ctl_elem_info *uinfo)
115 snd_intelmad_volume_info(uinfo, MONO_CNTL,
116 intelmad_ctrl_val[sst_card_vendor_id].capture_vol_max,
117 intelmad_ctrl_val[sst_card_vendor_id].capture_vol_min);
118 return 0;
122 * snd_intelmad_playback_volume_info - provides info about the volume control
124 * @kcontrol: pointer to the control
125 * @uinfo: pointer to the structure where the control's info need
126 * to be filled
128 * This function is called when a mixer application requests for control's info
130 static int snd_intelmad_playback_volume_info(struct snd_kcontrol *kcontrol,
131 struct snd_ctl_elem_info *uinfo)
133 snd_intelmad_volume_info(uinfo, STEREO_CNTL,
134 intelmad_ctrl_val[sst_card_vendor_id].playback_vol_max,
135 intelmad_ctrl_val[sst_card_vendor_id].playback_vol_min);
136 return 0;
140 * snd_intelmad_device_info_mrst - provides information about the devices available
142 * @kcontrol: pointer to the control
143 * @uinfo: pointer to the structure where the devices's info need
144 * to be filled
146 * This function is called when a mixer application requests for device's info
148 static int snd_intelmad_device_info_mrst(struct snd_kcontrol *kcontrol,
149 struct snd_ctl_elem_info *uinfo)
152 WARN_ON(!kcontrol);
153 WARN_ON(!uinfo);
155 /* setup device select as drop down controls with different values */
156 if (kcontrol->id.numid == OUTPUT_SEL)
157 uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mrst);
158 else
159 uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mrst);
160 uinfo->count = MONO_CNTL;
161 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
163 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
164 uinfo->value.enumerated.item = 1;
165 if (kcontrol->id.numid == OUTPUT_SEL)
166 strncpy(uinfo->value.enumerated.name,
167 out_names_mrst[uinfo->value.enumerated.item],
168 sizeof(uinfo->value.enumerated.name)-1);
169 else
170 strncpy(uinfo->value.enumerated.name,
171 in_names_mrst[uinfo->value.enumerated.item],
172 sizeof(uinfo->value.enumerated.name)-1);
173 return 0;
176 static int snd_intelmad_device_info_mfld(struct snd_kcontrol *kcontrol,
177 struct snd_ctl_elem_info *uinfo)
179 WARN_ON(!kcontrol);
180 WARN_ON(!uinfo);
181 /* setup device select as drop down controls with different values */
182 if (kcontrol->id.numid == OUTPUT_SEL)
183 uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mfld);
184 else
185 uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mfld);
186 uinfo->count = MONO_CNTL;
187 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
189 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
190 uinfo->value.enumerated.item = 1;
191 if (kcontrol->id.numid == OUTPUT_SEL)
192 strncpy(uinfo->value.enumerated.name,
193 out_names_mfld[uinfo->value.enumerated.item],
194 sizeof(uinfo->value.enumerated.name)-1);
195 else
196 strncpy(uinfo->value.enumerated.name,
197 in_names_mfld[uinfo->value.enumerated.item],
198 sizeof(uinfo->value.enumerated.name)-1);
199 return 0;
203 * snd_intelmad_volume_get - gets the current volume for the control
205 * @kcontrol: pointer to the control
206 * @uval: pointer to the structure where the control's info need
207 * to be filled
209 * This function is called when .get function of a control is invoked from app
211 static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,
212 struct snd_ctl_elem_value *uval)
214 int ret_val = 0, cntl_list[2] = {0,};
215 int value = 0;
216 struct snd_intelmad *intelmaddata;
217 struct snd_pmic_ops *scard_ops;
219 pr_debug("sst: snd_intelmad_volume_get called\n");
221 WARN_ON(!uval);
222 WARN_ON(!kcontrol);
224 intelmaddata = kcontrol->private_data;
226 WARN_ON(!intelmaddata->sstdrv_ops);
228 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
230 WARN_ON(!scard_ops);
232 switch (kcontrol->id.numid) {
233 case PLAYBACK_VOL:
234 cntl_list[0] = PMIC_SND_RIGHT_PB_VOL;
235 cntl_list[1] = PMIC_SND_LEFT_PB_VOL;
236 break;
238 case CAPTURE_VOL:
239 cntl_list[0] = PMIC_SND_CAPTURE_VOL;
240 break;
241 default:
242 return -EINVAL;
245 ret_val = scard_ops->get_vol(cntl_list[0], &value);
246 uval->value.integer.value[0] = value;
248 if (ret_val)
249 return ret_val;
251 if (kcontrol->id.numid == PLAYBACK_VOL) {
252 ret_val = scard_ops->get_vol(cntl_list[1], &value);
253 uval->value.integer.value[1] = value;
255 return ret_val;
259 * snd_intelmad_mute_get - gets the current mute status for the control
261 * @kcontrol: pointer to the control
262 * @uval: pointer to the structure where the control's info need
263 * to be filled
265 * This function is called when .get function of a control is invoked from app
267 static int snd_intelmad_mute_get(struct snd_kcontrol *kcontrol,
268 struct snd_ctl_elem_value *uval)
271 int cntl_list = 0, ret_val = 0;
272 u8 value = 0;
273 struct snd_intelmad *intelmaddata;
274 struct snd_pmic_ops *scard_ops;
276 pr_debug("sst: Mute_get called\n");
278 WARN_ON(!uval);
279 WARN_ON(!kcontrol);
281 intelmaddata = kcontrol->private_data;
283 WARN_ON(!intelmaddata->sstdrv_ops);
285 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
287 WARN_ON(!scard_ops);
289 switch (kcontrol->id.numid) {
290 case PLAYBACK_MUTE:
291 if (intelmaddata->output_sel == STEREO_HEADPHONE)
292 cntl_list = PMIC_SND_LEFT_HP_MUTE;
293 else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
294 (intelmaddata->output_sel == MONO_EARPIECE))
295 cntl_list = PMIC_SND_LEFT_SPEAKER_MUTE;
296 break;
298 case CAPTURE_MUTE:
299 if (intelmaddata->input_sel == DMIC)
300 cntl_list = PMIC_SND_DMIC_MUTE;
301 else if (intelmaddata->input_sel == AMIC)
302 cntl_list = PMIC_SND_AMIC_MUTE;
303 else if (intelmaddata->input_sel == HS_MIC)
304 cntl_list = PMIC_SND_HP_MIC_MUTE;
305 break;
306 case MASTER_MUTE:
307 uval->value.integer.value[0] = intelmaddata->master_mute;
308 return 0;
309 default:
310 return -EINVAL;
313 ret_val = scard_ops->get_mute(cntl_list, &value);
314 uval->value.integer.value[0] = value;
315 return ret_val;
319 * snd_intelmad_volume_set - sets the volume control's info
321 * @kcontrol: pointer to the control
322 * @uval: pointer to the structure where the control's info is
323 * available to be set
325 * This function is called when .set function of a control is invoked from app
327 static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *uval)
331 int ret_val, cntl_list[2] = {0,};
332 struct snd_intelmad *intelmaddata;
333 struct snd_pmic_ops *scard_ops;
335 pr_debug("sst: volume set called:%ld %ld\n",
336 uval->value.integer.value[0],
337 uval->value.integer.value[1]);
339 WARN_ON(!uval);
340 WARN_ON(!kcontrol);
342 intelmaddata = kcontrol->private_data;
344 WARN_ON(!intelmaddata->sstdrv_ops);
346 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
348 WARN_ON(!scard_ops);
350 switch (kcontrol->id.numid) {
351 case PLAYBACK_VOL:
352 cntl_list[0] = PMIC_SND_LEFT_PB_VOL;
353 cntl_list[1] = PMIC_SND_RIGHT_PB_VOL;
354 break;
356 case CAPTURE_VOL:
357 cntl_list[0] = PMIC_SND_CAPTURE_VOL;
358 break;
359 default:
360 return -EINVAL;
363 ret_val = scard_ops->set_vol(cntl_list[0],
364 uval->value.integer.value[0]);
365 if (ret_val)
366 return ret_val;
368 if (kcontrol->id.numid == PLAYBACK_VOL)
369 ret_val = scard_ops->set_vol(cntl_list[1],
370 uval->value.integer.value[1]);
371 return ret_val;
375 * snd_intelmad_mute_set - sets the mute control's info
377 * @kcontrol: pointer to the control
378 * @uval: pointer to the structure where the control's info is
379 * available to be set
381 * This function is called when .set function of a control is invoked from app
383 static int snd_intelmad_mute_set(struct snd_kcontrol *kcontrol,
384 struct snd_ctl_elem_value *uval)
386 int cntl_list[2] = {0,}, ret_val;
387 struct snd_intelmad *intelmaddata;
388 struct snd_pmic_ops *scard_ops;
390 pr_debug("sst: snd_intelmad_mute_set called\n");
392 WARN_ON(!uval);
393 WARN_ON(!kcontrol);
395 intelmaddata = kcontrol->private_data;
397 WARN_ON(!intelmaddata->sstdrv_ops);
399 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
401 WARN_ON(!scard_ops);
403 kcontrol->private_value = uval->value.integer.value[0];
405 switch (kcontrol->id.numid) {
406 case PLAYBACK_MUTE:
407 if (intelmaddata->output_sel == STEREO_HEADPHONE) {
408 cntl_list[0] = PMIC_SND_LEFT_HP_MUTE;
409 cntl_list[1] = PMIC_SND_RIGHT_HP_MUTE;
410 } else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
411 (intelmaddata->output_sel == MONO_EARPIECE)) {
412 cntl_list[0] = PMIC_SND_LEFT_SPEAKER_MUTE;
413 cntl_list[1] = PMIC_SND_RIGHT_SPEAKER_MUTE;
415 break;
417 case CAPTURE_MUTE:/*based on sel device mute the i/p dev*/
418 if (intelmaddata->input_sel == DMIC)
419 cntl_list[0] = PMIC_SND_DMIC_MUTE;
420 else if (intelmaddata->input_sel == AMIC)
421 cntl_list[0] = PMIC_SND_AMIC_MUTE;
422 else if (intelmaddata->input_sel == HS_MIC)
423 cntl_list[0] = PMIC_SND_HP_MIC_MUTE;
424 break;
425 case MASTER_MUTE:
426 cntl_list[0] = PMIC_SND_MUTE_ALL;
427 intelmaddata->master_mute = uval->value.integer.value[0];
428 break;
429 default:
430 return -EINVAL;
433 ret_val = scard_ops->set_mute(cntl_list[0],
434 uval->value.integer.value[0]);
435 if (ret_val)
436 return ret_val;
438 if (kcontrol->id.numid == PLAYBACK_MUTE)
439 ret_val = scard_ops->set_mute(cntl_list[1],
440 uval->value.integer.value[0]);
441 return ret_val;
445 * snd_intelmad_device_get - get the device select control's info
447 * @kcontrol: pointer to the control
448 * @uval: pointer to the structure where the control's info is
449 * to be filled
451 * This function is called when .get function of a control is invoked from app
453 static int snd_intelmad_device_get(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *uval)
456 struct snd_intelmad *intelmaddata;
457 struct snd_pmic_ops *scard_ops;
458 pr_debug("sst: device_get called\n");
460 WARN_ON(!uval);
461 WARN_ON(!kcontrol);
463 intelmaddata = kcontrol->private_data;
464 if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
465 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
466 if (kcontrol->id.numid == OUTPUT_SEL)
467 uval->value.enumerated.item[0] =
468 scard_ops->output_dev_id;
469 else if (kcontrol->id.numid == INPUT_SEL)
470 uval->value.enumerated.item[0] =
471 scard_ops->input_dev_id;
472 else
473 return -EINVAL;
474 } else
475 uval->value.enumerated.item[0] = kcontrol->private_value;
476 return 0;
480 * snd_intelmad_device_set - set the device select control's info
482 * @kcontrol: pointer to the control
483 * @uval: pointer to the structure where the control's info is
484 * available to be set
486 * This function is called when .set function of a control is invoked from app
488 static int snd_intelmad_device_set(struct snd_kcontrol *kcontrol,
489 struct snd_ctl_elem_value *uval)
491 struct snd_intelmad *intelmaddata;
492 struct snd_pmic_ops *scard_ops;
493 int ret_val = 0, vendor, status;
495 pr_debug("sst: snd_intelmad_device_set called\n");
497 WARN_ON(!uval);
498 WARN_ON(!kcontrol);
499 status = -1;
501 intelmaddata = kcontrol->private_data;
503 WARN_ON(!intelmaddata->sstdrv_ops);
505 scard_ops = intelmaddata->sstdrv_ops->scard_ops;
507 WARN_ON(!scard_ops);
509 /* store value with driver */
510 kcontrol->private_value = uval->value.enumerated.item[0];
512 switch (kcontrol->id.numid) {
513 case OUTPUT_SEL:
514 ret_val = scard_ops->set_output_dev(
515 uval->value.enumerated.item[0]);
516 intelmaddata->output_sel = uval->value.enumerated.item[0];
517 break;
518 case INPUT_SEL:
519 vendor = intelmaddata->sstdrv_ops->vendor_id;
520 if ((vendor == SND_MX) || (vendor == SND_FS)) {
521 if (uval->value.enumerated.item[0] == HS_MIC) {
522 status = 1;
523 intelmaddata->sstdrv_ops->
524 control_set(SST_ENABLE_RX_TIME_SLOT, &status);
525 } else {
526 status = 0;
527 intelmaddata->sstdrv_ops->
528 control_set(SST_ENABLE_RX_TIME_SLOT, &status);
531 ret_val = scard_ops->set_input_dev(
532 uval->value.enumerated.item[0]);
533 intelmaddata->input_sel = uval->value.enumerated.item[0];
534 break;
535 default:
536 return -EINVAL;
538 kcontrol->private_value = uval->value.enumerated.item[0];
539 return ret_val;
542 struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = {
544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
545 .name = "PCM Playback Source",
546 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
547 .info = snd_intelmad_device_info_mrst,
548 .get = snd_intelmad_device_get,
549 .put = snd_intelmad_device_set,
550 .private_value = 0,
553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
554 .name = "PCM Capture Source",
555 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
556 .info = snd_intelmad_device_info_mrst,
557 .get = snd_intelmad_device_get,
558 .put = snd_intelmad_device_set,
559 .private_value = 0,
562 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
563 .name = "PCM Playback Volume",
564 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
565 .info = snd_intelmad_playback_volume_info,
566 .get = snd_intelmad_volume_get,
567 .put = snd_intelmad_volume_set,
568 .private_value = 0,
571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
572 .name = "PCM Playback Switch",
573 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
574 .info = snd_intelmad_mute_info,
575 .get = snd_intelmad_mute_get,
576 .put = snd_intelmad_mute_set,
577 .private_value = 0,
580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
581 .name = "PCM Capture Volume",
582 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
583 .info = snd_intelmad_capture_volume_info,
584 .get = snd_intelmad_volume_get,
585 .put = snd_intelmad_volume_set,
586 .private_value = 0,
589 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
590 .name = "PCM Capture Switch",
591 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
592 .info = snd_intelmad_mute_info,
593 .get = snd_intelmad_mute_get,
594 .put = snd_intelmad_mute_set,
595 .private_value = 0,
598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
599 .name = "Master Playback Switch",
600 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
601 .info = snd_intelmad_mute_info,
602 .get = snd_intelmad_mute_get,
603 .put = snd_intelmad_mute_set,
604 .private_value = 0,
608 struct snd_kcontrol_new
609 snd_intelmad_controls_mfld[MAX_CTRL_MFLD] __devinitdata = {
611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
612 .name = "PCM Playback Source",
613 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
614 .info = snd_intelmad_device_info_mfld,
615 .get = snd_intelmad_device_get,
616 .put = snd_intelmad_device_set,
617 .private_value = 0,
620 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
621 .name = "PCM Capture Source",
622 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
623 .info = snd_intelmad_device_info_mfld,
624 .get = snd_intelmad_device_get,
625 .put = snd_intelmad_device_set,
626 .private_value = 0,