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