Commit | Line | Data |
---|---|---|
fffa1cca VK |
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 | */ | |
d0f40c50 JP |
27 | |
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
29 | ||
fffa1cca VK |
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 | ||
d0f40c50 | 222 | pr_debug("snd_intelmad_volume_get called\n"); |
fffa1cca VK |
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 | ||
d0f40c50 | 279 | pr_debug("Mute_get called\n"); |
fffa1cca VK |
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 | ||
d0f40c50 | 338 | pr_debug("volume set called:%ld %ld\n", |
fffa1cca VK |
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 | ||
d0f40c50 | 393 | pr_debug("snd_intelmad_mute_set called\n"); |
fffa1cca VK |
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; | |
d0f40c50 | 461 | pr_debug("device_get called\n"); |
fffa1cca VK |
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; | |
6f6ffec1 | 497 | struct intel_sst_pcm_control *pcm_control; |
fffa1cca | 498 | |
d0f40c50 | 499 | pr_debug("snd_intelmad_device_set called\n"); |
fffa1cca VK |
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)) { | |
6f6ffec1 VK |
525 | pcm_control = intelmaddata->sstdrv_ops->pcm_control; |
526 | if (uval->value.enumerated.item[0] == HS_MIC) | |
fffa1cca | 527 | status = 1; |
6f6ffec1 | 528 | else |
fffa1cca | 529 | status = 0; |
6f6ffec1 VK |
530 | pcm_control->device_control( |
531 | SST_ENABLE_RX_TIME_SLOT, &status); | |
fffa1cca VK |
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 |