1 /* intel_sst_v1_control.c - Intel SST Driver for audio engine
2 *
3 * Copyright (C) 2008-10 Intel Corp
4 * Authors: Vinod Koul <vinod.koul@intel.com>
5 * Harsha Priya <priya.harsha@intel.com>
6 * Dharageswari R <dharageswari.r@intel.com>
7 * KP Jeeja <jeeja.kp@intel.com>
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 *
25 * This file contains the control operations of vendor 2
26 */
27
28 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29
30 #include <linux/pci.h>
31 #include <linux/delay.h>
32 #include <linux/file.h>
33 #include <asm/mrst.h>
34 #include <sound/pcm.h>
35 #include "jack.h"
36 #include <sound/pcm_params.h>
37 #include <sound/control.h>
38 #include <sound/initval.h>
39 #include "intel_sst.h"
40 #include "intel_sst_ioctl.h"
41 #include "intelmid.h"
42 #include "intelmid_snd_control.h"
43
44 #include <linux/gpio.h>
45 #define KOSKI_VOICE_CODEC_ENABLE 46
46
47 enum _reg_v2 {
48
49 MASTER_CLOCK_PRESCALAR = 0x205,
50 SET_MASTER_AND_LR_CLK1 = 0x20b,
51 SET_MASTER_AND_LR_CLK2 = 0x20c,
52 MASTER_MODE_AND_DATA_DELAY = 0x20d,
53 DIGITAL_INTERFACE_TO_DAI2 = 0x20e,
54 CLK_AND_FS1 = 0x208,
55 CLK_AND_FS2 = 0x209,
56 DAI2_TO_DAC_HP = 0x210,
57 HP_OP_SINGLE_ENDED = 0x224,
58 ENABLE_OPDEV_CTRL = 0x226,
59 ENABLE_DEV_AND_USE_XTAL = 0x227,
60
61 /* Max audio subsystem (PQ49) MAX 8921 */
62 AS_IP_MODE_CTL = 0xF9,
63 AS_LEFT_SPKR_VOL_CTL = 0xFA, /* Mono Earpiece volume control */
64 AS_RIGHT_SPKR_VOL_CTL = 0xFB,
65 AS_LEFT_HP_VOL_CTL = 0xFC,
66 AS_RIGHT_HP_VOL_CTL = 0xFD,
67 AS_OP_MIX_CTL = 0xFE,
68 AS_CONFIG = 0xFF,
69
70 /* Headphone volume control & mute registers */
71 VOL_CTRL_LT = 0x21c,
72 VOL_CTRL_RT = 0x21d,
73
74 };
75 /**
76 * mx_init_card - initialize the sound card
77 *
78 * This initializes the audio paths to know values in case of this sound card
79 */
mx_init_card(void)80 static int mx_init_card(void)
81 {
82 struct sc_reg_access sc_access[] = {
83 {0x200, 0x80, 0x00},
84 {0x201, 0xC0, 0x00},
85 {0x202, 0x00, 0x00},
86 {0x203, 0x00, 0x00},
87 {0x204, 0x02, 0x00},
88 {0x205, 0x10, 0x00},
89 {0x206, 0x60, 0x00},
90 {0x207, 0x00, 0x00},
91 {0x208, 0x90, 0x00},
92 {0x209, 0x51, 0x00},
93 {0x20a, 0x00, 0x00},
94 {0x20b, 0x10, 0x00},
95 {0x20c, 0x00, 0x00},
96 {0x20d, 0x00, 0x00},
97 {0x20e, 0x21, 0x00},
98 {0x20f, 0x00, 0x00},
99 {0x210, 0x84, 0x00},
100 {0x211, 0xB3, 0x00},
101 {0x212, 0x00, 0x00},
102 {0x213, 0x00, 0x00},
103 {0x214, 0x41, 0x00},
104 {0x215, 0x00, 0x00},
105 {0x216, 0x00, 0x00},
106 {0x217, 0x00, 0x00},
107 {0x218, 0x03, 0x00},
108 {0x219, 0x03, 0x00},
109 {0x21a, 0x00, 0x00},
110 {0x21b, 0x00, 0x00},
111 {0x21c, 0x00, 0x00},
112 {0x21d, 0x00, 0x00},
113 {0x21e, 0x00, 0x00},
114 {0x21f, 0x00, 0x00},
115 {0x220, 0x20, 0x00},
116 {0x221, 0x20, 0x00},
117 {0x222, 0x51, 0x00},
118 {0x223, 0x20, 0x00},
119 {0x224, 0x04, 0x00},
120 {0x225, 0x80, 0x00},
121 {0x226, 0x0F, 0x00},
122 {0x227, 0x08, 0x00},
123 {0xf9, 0x40, 0x00},
124 {0xfa, 0x1f, 0x00},
125 {0xfb, 0x1f, 0x00},
126 {0xfc, 0x1f, 0x00},
127 {0xfd, 0x1f, 0x00},
128 {0xfe, 0x00, 0x00},
129 {0xff, 0x0c, 0x00},
130 };
131 snd_pmic_ops_mx.card_status = SND_CARD_INIT_DONE;
132 snd_pmic_ops_mx.num_channel = 2;
133 snd_pmic_ops_mx.master_mute = UNMUTE;
134 snd_pmic_ops_mx.mute_status = UNMUTE;
135 return sst_sc_reg_access(sc_access, PMIC_WRITE, 47);
136 }
137
mx_enable_audiodac(int value)138 static int mx_enable_audiodac(int value)
139 {
140 struct sc_reg_access sc_access[3];
141 int mute_val = 0;
142 int mute_val1 = 0;
143 int retval = 0;
144
145 sc_access[0].reg_addr = AS_LEFT_HP_VOL_CTL;
146 sc_access[1].reg_addr = AS_RIGHT_HP_VOL_CTL;
147
148 if (value == UNMUTE) {
149 mute_val = 0x1F;
150 mute_val1 = 0x00;
151 } else {
152 mute_val = 0x00;
153 mute_val1 = 0x40;
154 }
155 sc_access[0].mask = sc_access[1].mask = MASK0|MASK1|MASK2|MASK3|MASK4;
156 sc_access[0].value = sc_access[1].value = (u8)mute_val;
157 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
158 if (retval)
159 return retval;
160 pr_debug("mute status = %d\n", snd_pmic_ops_mx.mute_status);
161 if (snd_pmic_ops_mx.mute_status == MUTE ||
162 snd_pmic_ops_mx.master_mute == MUTE)
163 return retval;
164
165 sc_access[0].reg_addr = VOL_CTRL_LT;
166 sc_access[1].reg_addr = VOL_CTRL_RT;
167 sc_access[0].mask = sc_access[1].mask = MASK6;
168 sc_access[0].value = sc_access[1].value = mute_val1;
169 if (snd_pmic_ops_mx.num_channel == 1)
170 sc_access[1].value = 0x40;
171 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
172 }
173
mx_power_up_pb(unsigned int port)174 static int mx_power_up_pb(unsigned int port)
175 {
176
177 int retval = 0;
178 struct sc_reg_access sc_access[3];
179
180 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
181 retval = mx_init_card();
182 if (retval)
183 return retval;
184 }
185 retval = mx_enable_audiodac(MUTE);
186 if (retval)
187 return retval;
188
189 msleep(10);
190
191 sc_access[0].reg_addr = AS_CONFIG;
192 sc_access[0].mask = MASK7;
193 sc_access[0].value = 0x80;
194 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
195 if (retval)
196 return retval;
197
198 sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
199 sc_access[0].mask = 0xff;
200 sc_access[0].value = 0x3C;
201 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
202 if (retval)
203 return retval;
204
205 sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL;
206 sc_access[0].mask = 0x80;
207 sc_access[0].value = 0x80;
208 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
209 if (retval)
210 return retval;
211
212 return mx_enable_audiodac(UNMUTE);
213 }
214
mx_power_down_pb(void)215 static int mx_power_down_pb(void)
216 {
217 struct sc_reg_access sc_access[3];
218 int retval = 0;
219
220 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
221 retval = mx_init_card();
222 if (retval)
223 return retval;
224 }
225
226 retval = mx_enable_audiodac(MUTE);
227 if (retval)
228 return retval;
229
230 sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
231 sc_access[0].mask = MASK3|MASK2;
232 sc_access[0].value = 0x00;
233
234 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
235 if (retval)
236 return retval;
237
238 return mx_enable_audiodac(UNMUTE);
239 }
240
mx_power_up_cp(unsigned int port)241 static int mx_power_up_cp(unsigned int port)
242 {
243 int retval = 0;
244 struct sc_reg_access sc_access[] = {
245 {ENABLE_DEV_AND_USE_XTAL, 0x80, MASK7},
246 {ENABLE_OPDEV_CTRL, 0x3, 0x3},
247 };
248
249 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
250 retval = mx_init_card();
251 if (retval)
252 return retval;
253 }
254
255 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
256 }
257
mx_power_down_cp(void)258 static int mx_power_down_cp(void)
259 {
260 struct sc_reg_access sc_access[] = {
261 {ENABLE_OPDEV_CTRL, 0x00, MASK1|MASK0},
262 };
263 int retval = 0;
264
265 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
266 retval = mx_init_card();
267 if (retval)
268 return retval;
269 }
270
271 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
272 }
273
mx_power_down(void)274 static int mx_power_down(void)
275 {
276 int retval = 0;
277 struct sc_reg_access sc_access[3];
278
279 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
280 retval = mx_init_card();
281 if (retval)
282 return retval;
283 }
284
285 retval = mx_enable_audiodac(MUTE);
286 if (retval)
287 return retval;
288
289 sc_access[0].reg_addr = AS_CONFIG;
290 sc_access[0].mask = MASK7;
291 sc_access[0].value = 0x00;
292 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
293 if (retval)
294 return retval;
295
296 sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL;
297 sc_access[0].mask = MASK7;
298 sc_access[0].value = 0x00;
299 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
300 if (retval)
301 return retval;
302
303 sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
304 sc_access[0].mask = MASK3|MASK2;
305 sc_access[0].value = 0x00;
306 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
307 if (retval)
308 return retval;
309
310 return mx_enable_audiodac(UNMUTE);
311 }
312
mx_set_pcm_voice_params(void)313 static int mx_set_pcm_voice_params(void)
314 {
315 int retval = 0;
316 struct sc_reg_access sc_access[] = {
317 {0x200, 0x80, 0x00},
318 {0x201, 0xC0, 0x00},
319 {0x202, 0x00, 0x00},
320 {0x203, 0x00, 0x00},
321 {0x204, 0x0e, 0x00},
322 {0x205, 0x20, 0x00},
323 {0x206, 0x8f, 0x00},
324 {0x207, 0x21, 0x00},
325 {0x208, 0x18, 0x00},
326 {0x209, 0x32, 0x00},
327 {0x20a, 0x00, 0x00},
328 {0x20b, 0x5A, 0x00},
329 {0x20c, 0xBE, 0x00},/* 0x00 -> 0xBE Koski */
330 {0x20d, 0x00, 0x00}, /* DAI2 'off' */
331 {0x20e, 0x40, 0x00},
332 {0x20f, 0x00, 0x00},
333 {0x210, 0x84, 0x00},
334 {0x211, 0x33, 0x00}, /* Voice filter */
335 {0x212, 0x00, 0x00},
336 {0x213, 0x00, 0x00},
337 {0x214, 0x41, 0x00},
338 {0x215, 0x00, 0x00},
339 {0x216, 0x00, 0x00},
340 {0x217, 0x20, 0x00},
341 {0x218, 0x00, 0x00},
342 {0x219, 0x00, 0x00},
343 {0x21a, 0x40, 0x00},
344 {0x21b, 0x40, 0x00},
345 {0x21c, 0x09, 0x00},
346 {0x21d, 0x09, 0x00},
347 {0x21e, 0x00, 0x00},
348 {0x21f, 0x00, 0x00},
349 {0x220, 0x00, 0x00}, /* Microphone configurations */
350 {0x221, 0x00, 0x00}, /* Microphone configurations */
351 {0x222, 0x50, 0x00}, /* Microphone configurations */
352 {0x223, 0x21, 0x00}, /* Microphone configurations */
353 {0x224, 0x00, 0x00},
354 {0x225, 0x80, 0x00},
355 {0xf9, 0x40, 0x00},
356 {0xfa, 0x19, 0x00},
357 {0xfb, 0x19, 0x00},
358 {0xfc, 0x12, 0x00},
359 {0xfd, 0x12, 0x00},
360 {0xfe, 0x00, 0x00},
361 };
362
363 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
364 retval = mx_init_card();
365 if (retval)
366 return retval;
367 }
368 pr_debug("SST DBG:mx_set_pcm_voice_params called\n");
369 return sst_sc_reg_access(sc_access, PMIC_WRITE, 44);
370 }
371
mx_set_pcm_audio_params(int sfreq,int word_size,int num_channel)372 static int mx_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
373 {
374 int retval = 0;
375
376 int config1 = 0, config2 = 0, filter = 0xB3;
377 struct sc_reg_access sc_access[5];
378
379 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
380 retval = mx_init_card();
381 if (retval)
382 return retval;
383 }
384
385 switch (sfreq) {
386 case 8000:
387 config1 = 0x10;
388 config2 = 0x00;
389 filter = 0x33;
390 break;
391 case 11025:
392 config1 = 0x16;
393 config2 = 0x0d;
394 break;
395 case 12000:
396 config1 = 0x18;
397 config2 = 0x00;
398 break;
399 case 16000:
400 config1 = 0x20;
401 config2 = 0x00;
402 break;
403 case 22050:
404 config1 = 0x2c;
405 config2 = 0x1a;
406 break;
407 case 24000:
408 config1 = 0x30;
409 config2 = 0x00;
410 break;
411 case 32000:
412 config1 = 0x40;
413 config2 = 0x00;
414 break;
415 case 44100:
416 config1 = 0x58;
417 config2 = 0x33;
418 break;
419 case 48000:
420 config1 = 0x60;
421 config2 = 0x00;
422 break;
423 }
424 snd_pmic_ops_mx.num_channel = num_channel;
425 /*mute the right channel if MONO*/
426 if (snd_pmic_ops_mx.num_channel == 1) {
427 sc_access[0].reg_addr = VOL_CTRL_RT;
428 sc_access[0].value = 0x40;
429 sc_access[0].mask = MASK6;
430
431 sc_access[1].reg_addr = 0x224;
432 sc_access[1].value = 0x05;
433 sc_access[1].mask = MASK0|MASK1|MASK2;
434
435 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
436 if (retval)
437 return retval;
438 } else {
439 sc_access[0].reg_addr = VOL_CTRL_RT;
440 sc_access[0].value = 0x00;
441 sc_access[0].mask = MASK6;
442
443 sc_access[1].reg_addr = 0x224;
444 sc_access[1].value = 0x04;
445 sc_access[1].mask = MASK0|MASK1|MASK2;
446
447 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
448 if (retval)
449 return retval;
450 }
451 sc_access[0].reg_addr = 0x206;
452 sc_access[0].value = config1;
453 sc_access[1].reg_addr = 0x207;
454 sc_access[1].value = config2;
455
456 if (word_size == 16) {
457 sc_access[2].value = 0x51;
458 sc_access[3].value = 0x31;
459 } else if (word_size == 24) {
460 sc_access[2].value = 0x52;
461 sc_access[3].value = 0x92;
462 }
463
464 sc_access[2].reg_addr = 0x209;
465 sc_access[3].reg_addr = 0x20e;
466
467 sc_access[4].reg_addr = 0x211;
468 sc_access[4].value = filter;
469
470 return sst_sc_reg_access(sc_access, PMIC_WRITE, 5);
471 }
472
mx_set_selected_output_dev(u8 dev_id)473 static int mx_set_selected_output_dev(u8 dev_id)
474 {
475 struct sc_reg_access sc_access[2];
476 int num_reg = 0;
477 int retval = 0;
478
479 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
480 retval = mx_init_card();
481 if (retval)
482 return retval;
483 }
484
485 pr_debug("mx_set_selected_output_dev dev_id:0x%x\n", dev_id);
486 snd_pmic_ops_mx.output_dev_id = dev_id;
487 switch (dev_id) {
488 case STEREO_HEADPHONE:
489 sc_access[0].reg_addr = 0xFF;
490 sc_access[0].value = 0x8C;
491 sc_access[0].mask =
492 MASK2|MASK3|MASK5|MASK6|MASK4;
493
494 num_reg = 1;
495 break;
496 case MONO_EARPIECE:
497 case INTERNAL_SPKR:
498 sc_access[0].reg_addr = 0xFF;
499 sc_access[0].value = 0xb0;
500 sc_access[0].mask = MASK2|MASK3|MASK5|MASK6|MASK4;
501
502 num_reg = 1;
503 break;
504 case RECEIVER:
505 pr_debug("RECEIVER Koski selected\n");
506
507 /* configuration - AS enable, receiver enable */
508 sc_access[0].reg_addr = 0xFF;
509 sc_access[0].value = 0x81;
510 sc_access[0].mask = 0xff;
511
512 num_reg = 1;
513 break;
514 default:
515 pr_err("Not a valid output dev\n");
516 return 0;
517 }
518 return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
519 }
520
521
mx_set_voice_port(int status)522 static int mx_set_voice_port(int status)
523 {
524 int retval = 0;
525
526 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
527 retval = mx_init_card();
528 if (retval)
529 return retval;
530 }
531 if (status == ACTIVATE)
532 retval = mx_set_pcm_voice_params();
533
534 return retval;
535 }
536
mx_set_audio_port(int status)537 static int mx_set_audio_port(int status)
538 {
539 return 0;
540 }
541
mx_set_selected_input_dev(u8 dev_id)542 static int mx_set_selected_input_dev(u8 dev_id)
543 {
544 struct sc_reg_access sc_access[2];
545 int num_reg = 0;
546 int retval = 0;
547
548 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
549 retval = mx_init_card();
550 if (retval)
551 return retval;
552 }
553 snd_pmic_ops_mx.input_dev_id = dev_id;
554 pr_debug("mx_set_selected_input_dev dev_id:0x%x\n", dev_id);
555
556 switch (dev_id) {
557 case AMIC:
558 sc_access[0].reg_addr = 0x223;
559 sc_access[0].value = 0x00;
560 sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
561 sc_access[1].reg_addr = 0x222;
562 sc_access[1].value = 0x50;
563 sc_access[1].mask = MASK7|MASK6|MASK5|MASK4;
564 num_reg = 2;
565 break;
566
567 case HS_MIC:
568 sc_access[0].reg_addr = 0x223;
569 sc_access[0].value = 0x20;
570 sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
571 sc_access[1].reg_addr = 0x222;
572 sc_access[1].value = 0x51;
573 sc_access[1].mask = MASK7|MASK6|MASK5|MASK4;
574 num_reg = 2;
575 break;
576 case DMIC:
577 sc_access[1].reg_addr = 0x222;
578 sc_access[1].value = 0x00;
579 sc_access[1].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
580 sc_access[0].reg_addr = 0x223;
581 sc_access[0].value = 0x20;
582 sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
583 num_reg = 2;
584 break;
585 }
586 return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
587 }
588
mx_set_mute(int dev_id,u8 value)589 static int mx_set_mute(int dev_id, u8 value)
590 {
591 struct sc_reg_access sc_access[5];
592 int num_reg = 0;
593 int retval = 0;
594
595 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
596 retval = mx_init_card();
597 if (retval)
598 return retval;
599 }
600
601
602 pr_debug("set_mute dev_id:0x%x , value:%d\n", dev_id, value);
603
604 switch (dev_id) {
605 case PMIC_SND_DMIC_MUTE:
606 case PMIC_SND_AMIC_MUTE:
607 case PMIC_SND_HP_MIC_MUTE:
608 sc_access[0].reg_addr = 0x220;
609 sc_access[1].reg_addr = 0x221;
610 sc_access[2].reg_addr = 0x223;
611 if (value == MUTE) {
612 sc_access[0].value = 0x00;
613 sc_access[1].value = 0x00;
614 if (snd_pmic_ops_mx.input_dev_id == DMIC)
615 sc_access[2].value = 0x00;
616 else
617 sc_access[2].value = 0x20;
618 } else {
619 sc_access[0].value = 0x20;
620 sc_access[1].value = 0x20;
621 if (snd_pmic_ops_mx.input_dev_id == DMIC)
622 sc_access[2].value = 0x20;
623 else
624 sc_access[2].value = 0x00;
625 }
626 sc_access[0].mask = MASK5|MASK6;
627 sc_access[1].mask = MASK5|MASK6;
628 sc_access[2].mask = MASK5|MASK6;
629 num_reg = 3;
630 break;
631 case PMIC_SND_LEFT_SPEAKER_MUTE:
632 case PMIC_SND_LEFT_HP_MUTE:
633 sc_access[0].reg_addr = VOL_CTRL_LT;
634 if (value == MUTE)
635 sc_access[0].value = 0x40;
636 else
637 sc_access[0].value = 0x00;
638 sc_access[0].mask = MASK6;
639 num_reg = 1;
640 snd_pmic_ops_mx.mute_status = value;
641 break;
642 case PMIC_SND_RIGHT_SPEAKER_MUTE:
643 case PMIC_SND_RIGHT_HP_MUTE:
644 sc_access[0].reg_addr = VOL_CTRL_RT;
645 if (snd_pmic_ops_mx.num_channel == 1)
646 value = MUTE;
647 if (value == MUTE)
648 sc_access[0].value = 0x40;
649 else
650 sc_access[0].value = 0x00;
651 sc_access[0].mask = MASK6;
652 num_reg = 1;
653 snd_pmic_ops_mx.mute_status = value;
654 break;
655 case PMIC_SND_MUTE_ALL:
656 sc_access[0].reg_addr = VOL_CTRL_RT;
657 sc_access[1].reg_addr = VOL_CTRL_LT;
658 sc_access[2].reg_addr = 0x220;
659 sc_access[3].reg_addr = 0x221;
660 sc_access[4].reg_addr = 0x223;
661 snd_pmic_ops_mx.master_mute = value;
662 if (value == MUTE) {
663 sc_access[0].value = sc_access[1].value = 0x40;
664 sc_access[2].value = 0x00;
665 sc_access[3].value = 0x00;
666 if (snd_pmic_ops_mx.input_dev_id == DMIC)
667 sc_access[4].value = 0x00;
668 else
669 sc_access[4].value = 0x20;
670
671 } else {
672 sc_access[0].value = sc_access[1].value = 0x00;
673 sc_access[2].value = sc_access[3].value = 0x20;
674 sc_access[4].value = 0x20;
675 if (snd_pmic_ops_mx.input_dev_id == DMIC)
676 sc_access[4].value = 0x20;
677 else
678 sc_access[4].value = 0x00;
679
680
681 }
682 if (snd_pmic_ops_mx.num_channel == 1)
683 sc_access[0].value = 0x40;
684 sc_access[0].mask = sc_access[1].mask = MASK6;
685 sc_access[2].mask = MASK5|MASK6;
686 sc_access[3].mask = MASK5|MASK6|MASK2|MASK4;
687 sc_access[4].mask = MASK5|MASK6|MASK4;
688
689 num_reg = 5;
690 break;
691 case PMIC_SND_RECEIVER_MUTE:
692 sc_access[0].reg_addr = VOL_CTRL_RT;
693 if (value == MUTE)
694 sc_access[0].value = 0x40;
695 else
696 sc_access[0].value = 0x00;
697 sc_access[0].mask = MASK6;
698 num_reg = 1;
699 break;
700 }
701
702 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
703 }
704
mx_set_vol(int dev_id,int value)705 static int mx_set_vol(int dev_id, int value)
706 {
707 struct sc_reg_access sc_access[2] = {{0},};
708 int num_reg = 0;
709 int retval = 0;
710
711 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
712 retval = mx_init_card();
713 if (retval)
714 return retval;
715 }
716 pr_debug("set_vol dev_id:0x%x ,value:%d\n", dev_id, value);
717 switch (dev_id) {
718 case PMIC_SND_RECEIVER_VOL:
719 return 0;
720 break;
721 case PMIC_SND_CAPTURE_VOL:
722 sc_access[0].reg_addr = 0x220;
723 sc_access[1].reg_addr = 0x221;
724 sc_access[0].value = sc_access[1].value = -value;
725 sc_access[0].mask = sc_access[1].mask =
726 (MASK0|MASK1|MASK2|MASK3|MASK4);
727 num_reg = 2;
728 break;
729 case PMIC_SND_LEFT_PB_VOL:
730 sc_access[0].value = -value;
731 sc_access[0].reg_addr = VOL_CTRL_LT;
732 sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
733 num_reg = 1;
734 break;
735 case PMIC_SND_RIGHT_PB_VOL:
736 sc_access[0].value = -value;
737 sc_access[0].reg_addr = VOL_CTRL_RT;
738 sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
739 if (snd_pmic_ops_mx.num_channel == 1) {
740 sc_access[0].value = 0x40;
741 sc_access[0].mask = MASK6;
742 sc_access[0].reg_addr = VOL_CTRL_RT;
743 }
744 num_reg = 1;
745 break;
746 }
747 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
748 }
749
mx_get_mute(int dev_id,u8 * value)750 static int mx_get_mute(int dev_id, u8 *value)
751 {
752 struct sc_reg_access sc_access[4] = {{0},};
753 int retval = 0, num_reg = 0, mask = 0;
754
755 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
756 retval = mx_init_card();
757 if (retval)
758 return retval;
759 }
760 switch (dev_id) {
761 case PMIC_SND_DMIC_MUTE:
762 case PMIC_SND_AMIC_MUTE:
763 case PMIC_SND_HP_MIC_MUTE:
764 sc_access[0].reg_addr = 0x220;
765 mask = MASK5|MASK6;
766 num_reg = 1;
767 retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
768 if (retval)
769 return retval;
770 *value = sc_access[0].value & mask;
771 if (*value)
772 *value = UNMUTE;
773 else
774 *value = MUTE;
775 return retval;
776 case PMIC_SND_LEFT_HP_MUTE:
777 case PMIC_SND_LEFT_SPEAKER_MUTE:
778 sc_access[0].reg_addr = VOL_CTRL_LT;
779 num_reg = 1;
780 mask = MASK6;
781 break;
782 case PMIC_SND_RIGHT_HP_MUTE:
783 case PMIC_SND_RIGHT_SPEAKER_MUTE:
784 sc_access[0].reg_addr = VOL_CTRL_RT;
785 num_reg = 1;
786 mask = MASK6;
787 break;
788 }
789 retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
790 if (retval)
791 return retval;
792 *value = sc_access[0].value & mask;
793 if (*value)
794 *value = MUTE;
795 else
796 *value = UNMUTE;
797 return retval;
798 }
799
mx_get_vol(int dev_id,int * value)800 static int mx_get_vol(int dev_id, int *value)
801 {
802 struct sc_reg_access sc_access = {0,};
803 int retval = 0, mask = 0, num_reg = 0;
804
805 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
806 retval = mx_init_card();
807 if (retval)
808 return retval;
809 }
810 switch (dev_id) {
811 case PMIC_SND_CAPTURE_VOL:
812 sc_access.reg_addr = 0x220;
813 mask = MASK0|MASK1|MASK2|MASK3|MASK4;
814 num_reg = 1;
815 break;
816 case PMIC_SND_LEFT_PB_VOL:
817 sc_access.reg_addr = VOL_CTRL_LT;
818 mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
819 num_reg = 1;
820 break;
821 case PMIC_SND_RIGHT_PB_VOL:
822 sc_access.reg_addr = VOL_CTRL_RT;
823 mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
824 num_reg = 1;
825 break;
826 }
827 retval = sst_sc_reg_access(&sc_access, PMIC_READ, num_reg);
828 if (retval)
829 return retval;
830 *value = -(sc_access.value & mask);
831 pr_debug("get volume value extracted %d\n", *value);
832 return retval;
833 }
834
835 struct snd_pmic_ops snd_pmic_ops_mx = {
836 .set_input_dev = mx_set_selected_input_dev,
837 .set_output_dev = mx_set_selected_output_dev,
838 .set_mute = mx_set_mute,
839 .get_mute = mx_get_mute,
840 .set_vol = mx_set_vol,
841 .get_vol = mx_get_vol,
842 .init_card = mx_init_card,
843 .set_pcm_audio_params = mx_set_pcm_audio_params,
844 .set_pcm_voice_params = mx_set_pcm_voice_params,
845 .set_voice_port = mx_set_voice_port,
846 .set_audio_port = mx_set_audio_port,
847 .power_up_pmic_pb = mx_power_up_pb,
848 .power_up_pmic_cp = mx_power_up_cp,
849 .power_down_pmic_pb = mx_power_down_pb,
850 .power_down_pmic_cp = mx_power_down_cp,
851 .power_down_pmic = mx_power_down,
852 };
853
854