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>
30 #include "intel_sst.h"
31 #include "intel_sst_ioctl.h"
32 #include "intelmid_snd_control.h"
35 static char *out_names_mrst
[] = {"Headphones",
37 static char *in_names_mrst
[] = {"AMIC",
40 static char *out_names_mfld
[] = {"Headset ",
42 static char *in_names_mfld
[] = {"AMIC",
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,
53 .playback_vol_max
= 0,
54 .playback_vol_min
= -31,
56 .capture_vol_min
= -20,
59 .playback_vol_max
= 0,
60 .playback_vol_min
= -126,
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
)
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
;
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
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
)
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
;
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
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
);
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
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
);
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
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
)
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
);
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);
170 strncpy(uinfo
->value
.enumerated
.name
,
171 in_names_mrst
[uinfo
->value
.enumerated
.item
],
172 sizeof(uinfo
->value
.enumerated
.name
)-1);
176 static int snd_intelmad_device_info_mfld(struct snd_kcontrol
*kcontrol
,
177 struct snd_ctl_elem_info
*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
);
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);
196 strncpy(uinfo
->value
.enumerated
.name
,
197 in_names_mfld
[uinfo
->value
.enumerated
.item
],
198 sizeof(uinfo
->value
.enumerated
.name
)-1);
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
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,};
216 struct snd_intelmad
*intelmaddata
;
217 struct snd_pmic_ops
*scard_ops
;
219 pr_debug("sst: snd_intelmad_volume_get called\n");
224 intelmaddata
= kcontrol
->private_data
;
226 WARN_ON(!intelmaddata
->sstdrv_ops
);
228 scard_ops
= intelmaddata
->sstdrv_ops
->scard_ops
;
232 switch (kcontrol
->id
.numid
) {
234 cntl_list
[0] = PMIC_SND_RIGHT_PB_VOL
;
235 cntl_list
[1] = PMIC_SND_LEFT_PB_VOL
;
239 cntl_list
[0] = PMIC_SND_CAPTURE_VOL
;
245 ret_val
= scard_ops
->get_vol(cntl_list
[0], &value
);
246 uval
->value
.integer
.value
[0] = value
;
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
;
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
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;
273 struct snd_intelmad
*intelmaddata
;
274 struct snd_pmic_ops
*scard_ops
;
276 pr_debug("sst: Mute_get called\n");
281 intelmaddata
= kcontrol
->private_data
;
283 WARN_ON(!intelmaddata
->sstdrv_ops
);
285 scard_ops
= intelmaddata
->sstdrv_ops
->scard_ops
;
289 switch (kcontrol
->id
.numid
) {
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
;
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
;
307 uval
->value
.integer
.value
[0] = intelmaddata
->master_mute
;
313 ret_val
= scard_ops
->get_mute(cntl_list
, &value
);
314 uval
->value
.integer
.value
[0] = value
;
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]);
342 intelmaddata
= kcontrol
->private_data
;
344 WARN_ON(!intelmaddata
->sstdrv_ops
);
346 scard_ops
= intelmaddata
->sstdrv_ops
->scard_ops
;
350 switch (kcontrol
->id
.numid
) {
352 cntl_list
[0] = PMIC_SND_LEFT_PB_VOL
;
353 cntl_list
[1] = PMIC_SND_RIGHT_PB_VOL
;
357 cntl_list
[0] = PMIC_SND_CAPTURE_VOL
;
363 ret_val
= scard_ops
->set_vol(cntl_list
[0],
364 uval
->value
.integer
.value
[0]);
368 if (kcontrol
->id
.numid
== PLAYBACK_VOL
)
369 ret_val
= scard_ops
->set_vol(cntl_list
[1],
370 uval
->value
.integer
.value
[1]);
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");
395 intelmaddata
= kcontrol
->private_data
;
397 WARN_ON(!intelmaddata
->sstdrv_ops
);
399 scard_ops
= intelmaddata
->sstdrv_ops
->scard_ops
;
403 kcontrol
->private_value
= uval
->value
.integer
.value
[0];
405 switch (kcontrol
->id
.numid
) {
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
;
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
;
426 cntl_list
[0] = PMIC_SND_MUTE_ALL
;
427 intelmaddata
->master_mute
= uval
->value
.integer
.value
[0];
433 ret_val
= scard_ops
->set_mute(cntl_list
[0],
434 uval
->value
.integer
.value
[0]);
438 if (kcontrol
->id
.numid
== PLAYBACK_MUTE
)
439 ret_val
= scard_ops
->set_mute(cntl_list
[1],
440 uval
->value
.integer
.value
[0]);
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
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");
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
;
475 uval
->value
.enumerated
.item
[0] = kcontrol
->private_value
;
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");
501 intelmaddata
= kcontrol
->private_data
;
503 WARN_ON(!intelmaddata
->sstdrv_ops
);
505 scard_ops
= intelmaddata
->sstdrv_ops
->scard_ops
;
509 /* store value with driver */
510 kcontrol
->private_value
= uval
->value
.enumerated
.item
[0];
512 switch (kcontrol
->id
.numid
) {
514 ret_val
= scard_ops
->set_output_dev(
515 uval
->value
.enumerated
.item
[0]);
516 intelmaddata
->output_sel
= uval
->value
.enumerated
.item
[0];
519 vendor
= intelmaddata
->sstdrv_ops
->vendor_id
;
520 if ((vendor
== SND_MX
) || (vendor
== SND_FS
)) {
521 if (uval
->value
.enumerated
.item
[0] == HS_MIC
) {
523 intelmaddata
->sstdrv_ops
->
524 control_set(SST_ENABLE_RX_TIME_SLOT
, &status
);
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];
538 kcontrol
->private_value
= uval
->value
.enumerated
.item
[0];
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,