ASoC: Fix DAPM sync for TLV320AIC3x custom DAPM widget
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / intel_sst / intelmid_v0_control.c
blobb8dfdb9bc1aa8bba8d7515479e80a93de7b3562f
1 /*
2 * intel_sst_v0_control.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-10 Intel Corporation
5 * Authors: Vinod Koul <vinod.koul@intel.com>
6 * Harsha Priya <priya.harsha@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 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 * This file contains the control operations of vendor 1
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #include <linux/pci.h>
32 #include <linux/file.h>
33 #include <sound/control.h>
34 #include "intel_sst.h"
35 #include "intelmid_snd_control.h"
36 #include "intelmid.h"
38 enum _reg_v1 {
39 VOICEPORT1 = 0x180,
40 VOICEPORT2 = 0x181,
41 AUDIOPORT1 = 0x182,
42 AUDIOPORT2 = 0x183,
43 MISCVOICECTRL = 0x184,
44 MISCAUDCTRL = 0x185,
45 DMICCTRL1 = 0x186,
46 AUDIOBIAS = 0x187,
47 MICCTRL = 0x188,
48 MICLICTRL1 = 0x189,
49 MICLICTRL2 = 0x18A,
50 MICLICTRL3 = 0x18B,
51 VOICEDACCTRL1 = 0x18C,
52 STEREOADCCTRL = 0x18D,
53 AUD15 = 0x18E,
54 AUD16 = 0x18F,
55 AUD17 = 0x190,
56 AUD18 = 0x191,
57 RMIXOUTSEL = 0x192,
58 ANALOGLBR = 0x193,
59 ANALOGLBL = 0x194,
60 POWERCTRL1 = 0x195,
61 POWERCTRL2 = 0x196,
62 HEADSETDETECTINT = 0x197,
63 HEADSETDETECTINTMASK = 0x198,
64 TRIMENABLE = 0x199,
67 int rev_id = 0x20;
68 static bool jack_det_enabled;
70 /****
71 * fs_init_card - initialize the sound card
73 * This initializes the audio paths to know values in case of this sound card
75 static int fs_init_card(void)
77 struct sc_reg_access sc_access[] = {
78 {0x180, 0x00, 0x0},
79 {0x181, 0x00, 0x0},
80 {0x182, 0xF8, 0x0},
81 {0x183, 0x08, 0x0},
82 {0x184, 0x00, 0x0},
83 {0x185, 0x40, 0x0},
84 {0x186, 0x06, 0x0},
85 {0x187, 0x80, 0x0},
86 {0x188, 0x40, 0x0},
87 {0x189, 0x39, 0x0},
88 {0x18a, 0x39, 0x0},
89 {0x18b, 0x1F, 0x0},
90 {0x18c, 0x00, 0x0},
91 {0x18d, 0x00, 0x0},
92 {0x18e, 0x39, 0x0},
93 {0x18f, 0x39, 0x0},
94 {0x190, 0x39, 0x0},
95 {0x191, 0x11, 0x0},
96 {0x192, 0x0E, 0x0},
97 {0x193, 0x00, 0x0},
98 {0x194, 0x00, 0x0},
99 {0x195, 0x00, 0x0},
100 {0x196, 0x7C, 0x0},
101 {0x197, 0x00, 0x0},
102 {0x198, 0x0B, 0x0},
103 {0x199, 0x00, 0x0},
104 {0x037, 0x3F, 0x0},
107 snd_pmic_ops_fs.card_status = SND_CARD_INIT_DONE;
108 snd_pmic_ops_fs.master_mute = UNMUTE;
109 snd_pmic_ops_fs.mute_status = UNMUTE;
110 snd_pmic_ops_fs.num_channel = 2;
111 return sst_sc_reg_access(sc_access, PMIC_WRITE, 27);
114 static int fs_enable_audiodac(int value)
116 struct sc_reg_access sc_access[3];
117 sc_access[0].reg_addr = AUD16;
118 sc_access[1].reg_addr = AUD17;
119 sc_access[2].reg_addr = AUD15;
120 sc_access[0].mask = sc_access[1].mask = sc_access[2].mask = MASK7;
122 if (snd_pmic_ops_fs.mute_status == MUTE)
123 return 0;
124 if (value == MUTE) {
125 sc_access[0].value = sc_access[1].value =
126 sc_access[2].value = 0x80;
128 } else {
129 sc_access[0].value = sc_access[1].value =
130 sc_access[2].value = 0x0;
132 if (snd_pmic_ops_fs.num_channel == 1)
133 sc_access[1].value = sc_access[2].value = 0x80;
134 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
138 static int fs_power_up_pb(unsigned int port)
140 struct sc_reg_access sc_access[] = {
141 {AUDIOBIAS, 0x00, MASK7},
142 {POWERCTRL1, 0xC6, 0xC6},
143 {POWERCTRL2, 0x30, 0x30},
146 int retval = 0;
148 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
149 retval = fs_init_card();
150 if (retval)
151 return retval;
152 retval = fs_enable_audiodac(MUTE);
153 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
155 if (retval)
156 return retval;
158 pr_debug("in fs power up pb\n");
159 return fs_enable_audiodac(UNMUTE);
162 static int fs_power_down_pb(unsigned int device)
164 struct sc_reg_access sc_access[] = {
165 {POWERCTRL1, 0x00, 0xC6},
166 {POWERCTRL2, 0x00, 0x30},
168 int retval = 0;
170 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
171 retval = fs_init_card();
172 if (retval)
173 return retval;
174 retval = fs_enable_audiodac(MUTE);
175 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
177 if (retval)
178 return retval;
180 pr_debug("in fsl power down pb\n");
181 return fs_enable_audiodac(UNMUTE);
184 static int fs_power_up_cp(unsigned int port)
186 struct sc_reg_access sc_access[] = {
187 {POWERCTRL2, 0x32, 0x32}, /*NOTE power up A ADC only as*/
188 {AUDIOBIAS, 0x00, MASK7},
189 /*as turning on V ADC causes noise*/
191 int retval = 0;
193 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
194 retval = fs_init_card();
195 if (retval)
196 return retval;
197 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
200 static int fs_power_down_cp(unsigned int device)
202 struct sc_reg_access sc_access[] = {
203 {POWERCTRL2, 0x00, 0x03},
205 int retval = 0;
207 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
208 retval = fs_init_card();
209 if (retval)
210 return retval;
211 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
214 static int fs_power_down(void)
216 int retval = 0;
217 struct sc_reg_access sc_access[] = {
218 {AUDIOBIAS, MASK7, MASK7},
221 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
222 retval = fs_init_card();
223 if (retval)
224 return retval;
225 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
228 static int fs_set_pcm_voice_params(void)
230 struct sc_reg_access sc_access[] = {
231 {0x180, 0xA0, 0},
232 {0x181, 0x04, 0},
233 {0x182, 0x0, 0},
234 {0x183, 0x0, 0},
235 {0x184, 0x18, 0},
236 {0x185, 0x40, 0},
237 {0x186, 0x06, 0},
238 {0x187, 0x0, 0},
239 {0x188, 0x10, 0},
240 {0x189, 0x39, 0},
241 {0x18a, 0x39, 0},
242 {0x18b, 0x02, 0},
243 {0x18c, 0x0, 0},
244 {0x18d, 0x0, 0},
245 {0x18e, 0x39, 0},
246 {0x18f, 0x0, 0},
247 {0x190, 0x0, 0},
248 {0x191, 0x20, 0},
249 {0x192, 0x20, 0},
250 {0x193, 0x0, 0},
251 {0x194, 0x0, 0},
252 {0x195, 0x06, 0},
253 {0x196, 0x25, 0},
254 {0x197, 0x0, 0},
255 {0x198, 0xF, 0},
256 {0x199, 0x0, 0},
258 int retval = 0;
260 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
261 retval = fs_init_card();
262 if (retval)
263 return retval;
264 return sst_sc_reg_access(sc_access, PMIC_WRITE, 26);
267 static int fs_set_audio_port(int status)
269 struct sc_reg_access sc_access[2];
270 int retval = 0;
272 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
273 retval = fs_init_card();
274 if (retval)
275 return retval;
276 if (status == DEACTIVATE) {
277 /* Deactivate audio port-tristate and power */
278 sc_access[0].value = 0x00;
279 sc_access[0].mask = MASK6|MASK7;
280 sc_access[0].reg_addr = AUDIOPORT1;
281 sc_access[1].value = 0x00;
282 sc_access[1].mask = MASK4|MASK5;
283 sc_access[1].reg_addr = POWERCTRL2;
284 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
285 } else if (status == ACTIVATE) {
286 /* activate audio port */
287 sc_access[0].value = 0xC0;
288 sc_access[0].mask = MASK6|MASK7;
289 sc_access[0].reg_addr = AUDIOPORT1;
290 sc_access[1].value = 0x30;
291 sc_access[1].mask = MASK4|MASK5;
292 sc_access[1].reg_addr = POWERCTRL2;
293 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
294 } else
295 return -EINVAL;
298 static int fs_set_voice_port(int status)
300 struct sc_reg_access sc_access[2];
301 int retval = 0;
303 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
304 retval = fs_init_card();
305 if (retval)
306 return retval;
307 if (status == DEACTIVATE) {
308 /* Deactivate audio port-tristate and power */
309 sc_access[0].value = 0x00;
310 sc_access[0].mask = MASK6|MASK7;
311 sc_access[0].reg_addr = VOICEPORT1;
312 sc_access[1].value = 0x00;
313 sc_access[1].mask = MASK0|MASK1;
314 sc_access[1].reg_addr = POWERCTRL2;
315 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
316 } else if (status == ACTIVATE) {
317 /* activate audio port */
318 sc_access[0].value = 0xC0;
319 sc_access[0].mask = MASK6|MASK7;
320 sc_access[0].reg_addr = VOICEPORT1;
321 sc_access[1].value = 0x03;
322 sc_access[1].mask = MASK0|MASK1;
323 sc_access[1].reg_addr = POWERCTRL2;
324 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
325 } else
326 return -EINVAL;
329 static int fs_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
331 u8 config1 = 0;
332 struct sc_reg_access sc_access[4];
333 int retval = 0, num_value = 0;
335 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
336 retval = fs_init_card();
337 if (retval)
338 return retval;
339 switch (sfreq) {
340 case 8000:
341 config1 = 0x00;
342 break;
343 case 11025:
344 config1 = 0x01;
345 break;
346 case 12000:
347 config1 = 0x02;
348 break;
349 case 16000:
350 config1 = 0x03;
351 break;
352 case 22050:
353 config1 = 0x04;
354 break;
355 case 24000:
356 config1 = 0x05;
357 break;
358 case 26000:
359 config1 = 0x06;
360 break;
361 case 32000:
362 config1 = 0x07;
363 break;
364 case 44100:
365 config1 = 0x08;
366 break;
367 case 48000:
368 config1 = 0x09;
369 break;
371 snd_pmic_ops_fs.num_channel = num_channel;
372 if (snd_pmic_ops_fs.num_channel == 1) {
373 sc_access[0].reg_addr = AUD17;
374 sc_access[1].reg_addr = AUD15;
375 sc_access[0].mask = sc_access[1].mask = MASK7;
376 sc_access[0].value = sc_access[1].value = 0x80;
377 sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
379 } else {
380 sc_access[0].reg_addr = AUD17;
381 sc_access[1].reg_addr = AUD15;
382 sc_access[0].mask = sc_access[1].mask = MASK7;
383 sc_access[0].value = sc_access[1].value = 0x00;
384 sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
387 pr_debug("sfreq:%d,Register value = %x\n", sfreq, config1);
389 if (word_size == 24) {
390 sc_access[0].reg_addr = AUDIOPORT1;
391 sc_access[0].mask = MASK0|MASK1|MASK2|MASK3;
392 sc_access[0].value = 0xFB;
395 sc_access[1].reg_addr = AUDIOPORT2;
396 sc_access[1].value = config1 | 0x10;
397 sc_access[1].mask = MASK0 | MASK1 | MASK2 | MASK3
398 | MASK4 | MASK5 | MASK6;
400 sc_access[2].reg_addr = MISCAUDCTRL;
401 sc_access[2].value = 0x02;
402 sc_access[2].mask = 0x02;
404 num_value = 3 ;
406 } else {
408 sc_access[0].reg_addr = AUDIOPORT2;
409 sc_access[0].value = config1;
410 sc_access[0].mask = MASK0|MASK1|MASK2|MASK3;
412 sc_access[1].reg_addr = MISCAUDCTRL;
413 sc_access[1].value = 0x00;
414 sc_access[1].mask = 0x02;
415 num_value = 2;
417 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_value);
421 static int fs_set_selected_input_dev(u8 value)
423 struct sc_reg_access sc_access_dmic[] = {
424 {MICCTRL, 0x81, 0xf7},
425 {MICLICTRL3, 0x00, 0xE0},
427 struct sc_reg_access sc_access_mic[] = {
428 {MICCTRL, 0x40, MASK2|MASK4|MASK5|MASK6|MASK7},
429 {MICLICTRL3, 0x00, 0xE0},
431 struct sc_reg_access sc_access_hsmic[] = {
432 {MICCTRL, 0x10, MASK2|MASK4|MASK5|MASK6|MASK7},
433 {MICLICTRL3, 0x00, 0xE0},
436 int retval = 0;
438 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
439 retval = fs_init_card();
440 if (retval)
441 return retval;
443 switch (value) {
444 case AMIC:
445 pr_debug("Selecting amic not supported in mono cfg\n");
446 return sst_sc_reg_access(sc_access_mic, PMIC_READ_MODIFY, 2);
447 break;
449 case HS_MIC:
450 pr_debug("Selecting hsmic\n");
451 return sst_sc_reg_access(sc_access_hsmic,
452 PMIC_READ_MODIFY, 2);
453 break;
455 case DMIC:
456 pr_debug("Selecting dmic\n");
457 return sst_sc_reg_access(sc_access_dmic, PMIC_READ_MODIFY, 2);
458 break;
460 default:
461 return -EINVAL;
466 static int fs_set_selected_output_dev(u8 value)
468 struct sc_reg_access sc_access_hp[] = {
469 {0x191, 0x11, 0x0},
470 {0x192, 0x0E, 0x0},
472 struct sc_reg_access sc_access_is[] = {
473 {0x191, 0x17, 0xFF},
474 {0x192, 0x08, 0xFF},
476 int retval = 0;
478 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
479 retval = fs_init_card();
480 if (retval)
481 return retval;
483 switch (value) {
484 case STEREO_HEADPHONE:
485 pr_debug("SST DBG:Selecting headphone\n");
486 return sst_sc_reg_access(sc_access_hp, PMIC_WRITE, 2);
487 break;
488 case MONO_EARPIECE:
489 case INTERNAL_SPKR:
490 pr_debug("SST DBG:Selecting internal spkr\n");
491 return sst_sc_reg_access(sc_access_is, PMIC_READ_MODIFY, 2);
492 break;
494 default:
495 return -EINVAL;
500 static int fs_set_mute(int dev_id, u8 value)
502 struct sc_reg_access sc_access[6] = {{0,},};
503 int reg_num = 0;
504 int retval = 0;
506 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
507 retval = fs_init_card();
508 if (retval)
509 return retval;
512 pr_debug("dev_id:0x%x value:0x%x\n", dev_id, value);
513 switch (dev_id) {
514 case PMIC_SND_DMIC_MUTE:
515 sc_access[0].reg_addr = MICCTRL;
516 sc_access[1].reg_addr = MICLICTRL1;
517 sc_access[2].reg_addr = MICLICTRL2;
518 sc_access[0].mask = MASK5;
519 sc_access[1].mask = sc_access[2].mask = MASK6;
520 if (value == MUTE) {
521 sc_access[0].value = 0x20;
522 sc_access[2].value = sc_access[1].value = 0x40;
523 } else
524 sc_access[0].value = sc_access[1].value
525 = sc_access[2].value = 0x0;
526 reg_num = 3;
527 break;
528 case PMIC_SND_HP_MIC_MUTE:
529 case PMIC_SND_AMIC_MUTE:
530 sc_access[0].reg_addr = MICLICTRL1;
531 sc_access[1].reg_addr = MICLICTRL2;
532 sc_access[0].mask = sc_access[1].mask = MASK6;
533 if (value == MUTE)
534 sc_access[0].value = sc_access[1].value = 0x40;
535 else
536 sc_access[0].value = sc_access[1].value = 0x0;
537 reg_num = 2;
538 break;
539 case PMIC_SND_LEFT_SPEAKER_MUTE:
540 case PMIC_SND_LEFT_HP_MUTE:
541 sc_access[0].reg_addr = AUD16;
542 sc_access[1].reg_addr = AUD15;
544 sc_access[0].mask = sc_access[1].mask = MASK7;
545 if (value == MUTE)
546 sc_access[0].value = sc_access[1].value = 0x80;
547 else
548 sc_access[0].value = sc_access[1].value = 0x0;
549 reg_num = 2;
550 snd_pmic_ops_fs.mute_status = value;
551 break;
552 case PMIC_SND_RIGHT_HP_MUTE:
553 case PMIC_SND_RIGHT_SPEAKER_MUTE:
554 sc_access[0].reg_addr = AUD17;
555 sc_access[1].reg_addr = AUD15;
556 sc_access[0].mask = sc_access[1].mask = MASK7;
557 if (value == MUTE)
558 sc_access[0].value = sc_access[1].value = 0x80;
559 else
560 sc_access[0].value = sc_access[1].value = 0x0;
561 snd_pmic_ops_fs.mute_status = value;
562 if (snd_pmic_ops_fs.num_channel == 1)
563 sc_access[0].value = sc_access[1].value = 0x80;
564 reg_num = 2;
565 break;
566 case PMIC_SND_MUTE_ALL:
567 sc_access[0].reg_addr = AUD16;
568 sc_access[1].reg_addr = AUD17;
569 sc_access[2].reg_addr = AUD15;
570 sc_access[3].reg_addr = MICCTRL;
571 sc_access[4].reg_addr = MICLICTRL1;
572 sc_access[5].reg_addr = MICLICTRL2;
573 sc_access[0].mask = sc_access[1].mask =
574 sc_access[2].mask = MASK7;
575 sc_access[3].mask = MASK5;
576 sc_access[4].mask = sc_access[5].mask = MASK6;
578 if (value == MUTE) {
579 sc_access[0].value =
580 sc_access[1].value = sc_access[2].value = 0x80;
581 sc_access[3].value = 0x20;
582 sc_access[4].value = sc_access[5].value = 0x40;
584 } else {
585 sc_access[0].value = sc_access[1].value =
586 sc_access[2].value = sc_access[3].value =
587 sc_access[4].value = sc_access[5].value = 0x0;
589 if (snd_pmic_ops_fs.num_channel == 1)
590 sc_access[1].value = sc_access[2].value = 0x80;
591 reg_num = 6;
592 snd_pmic_ops_fs.mute_status = value;
593 snd_pmic_ops_fs.master_mute = value;
594 break;
597 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, reg_num);
600 static int fs_set_vol(int dev_id, int value)
602 struct sc_reg_access sc_acces, sc_access[4] = {{0},};
603 int reg_num = 0;
604 int retval = 0;
606 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
607 retval = fs_init_card();
608 if (retval)
609 return retval;
611 switch (dev_id) {
612 case PMIC_SND_LEFT_PB_VOL:
613 pr_debug("PMIC_SND_LEFT_PB_VOL:%d\n", value);
614 sc_access[0].value = sc_access[1].value = value;
615 sc_access[0].reg_addr = AUD16;
616 sc_access[1].reg_addr = AUD15;
617 sc_access[0].mask = sc_access[1].mask =
618 (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
619 reg_num = 2;
620 break;
622 case PMIC_SND_RIGHT_PB_VOL:
623 pr_debug("PMIC_SND_RIGHT_PB_VOL:%d\n", value);
624 sc_access[0].value = sc_access[1].value = value;
625 sc_access[0].reg_addr = AUD17;
626 sc_access[1].reg_addr = AUD15;
627 sc_access[0].mask = sc_access[1].mask =
628 (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
629 if (snd_pmic_ops_fs.num_channel == 1) {
630 sc_access[0].value = sc_access[1].value = 0x80;
631 sc_access[0].mask = sc_access[1].mask = MASK7;
633 reg_num = 2;
634 break;
635 case PMIC_SND_CAPTURE_VOL:
636 pr_debug("PMIC_SND_CAPTURE_VOL:%d\n", value);
637 sc_access[0].reg_addr = MICLICTRL1;
638 sc_access[1].reg_addr = MICLICTRL2;
639 sc_access[2].reg_addr = DMICCTRL1;
640 sc_access[2].value = value;
641 sc_access[0].value = sc_access[1].value = value;
642 sc_acces.reg_addr = MICLICTRL3;
643 sc_acces.value = value;
644 sc_acces.mask = (MASK0|MASK1|MASK2|MASK3|MASK5|MASK6|MASK7);
645 retval = sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1);
646 sc_access[0].mask = sc_access[1].mask =
647 sc_access[2].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
648 reg_num = 3;
649 break;
651 default:
652 return -EINVAL;
655 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, reg_num);
658 static int fs_get_mute(int dev_id, u8 *value)
660 struct sc_reg_access sc_access[6] = {{0,},};
662 int retval = 0, temp_value = 0, mask = 0;
664 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
665 retval = fs_init_card();
666 if (retval)
667 return retval;
669 switch (dev_id) {
671 case PMIC_SND_AMIC_MUTE:
672 case PMIC_SND_HP_MIC_MUTE:
673 sc_access[0].reg_addr = MICLICTRL1;
674 mask = MASK6;
675 retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
676 if (sc_access[0].value & mask)
677 *value = MUTE;
678 else
679 *value = UNMUTE;
680 break;
681 case PMIC_SND_DMIC_MUTE:
682 sc_access[0].reg_addr = MICCTRL;
683 mask = MASK5;
684 retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
685 temp_value = (sc_access[0].value & mask);
686 if (temp_value == 0)
687 *value = UNMUTE;
688 else
689 *value = MUTE;
690 break;
692 case PMIC_SND_LEFT_HP_MUTE:
693 case PMIC_SND_LEFT_SPEAKER_MUTE:
694 sc_access[0].reg_addr = AUD16;
695 mask = MASK7;
696 retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
697 temp_value = sc_access[0].value & mask;
698 if (temp_value == 0)
699 *value = UNMUTE;
700 else
701 *value = MUTE;
702 break;
703 case PMIC_SND_RIGHT_HP_MUTE:
704 case PMIC_SND_RIGHT_SPEAKER_MUTE:
705 sc_access[0].reg_addr = AUD17;
706 mask = MASK7;
707 retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
708 temp_value = sc_access[0].value & mask;
709 if (temp_value == 0)
710 *value = UNMUTE;
711 else
712 *value = MUTE;
713 break;
714 default:
715 return -EINVAL;
718 return retval;
721 static int fs_get_vol(int dev_id, int *value)
723 struct sc_reg_access sc_access = {0,};
724 int retval = 0, mask = 0;
726 if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
727 retval = fs_init_card();
728 if (retval)
729 return retval;
731 switch (dev_id) {
732 case PMIC_SND_CAPTURE_VOL:
733 pr_debug("PMIC_SND_CAPTURE_VOL\n");
734 sc_access.reg_addr = MICLICTRL1;
735 mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
736 break;
737 case PMIC_SND_LEFT_PB_VOL:
738 pr_debug("PMIC_SND_LEFT_PB_VOL\n");
739 sc_access.reg_addr = AUD16;
740 mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
741 break;
742 case PMIC_SND_RIGHT_PB_VOL:
743 pr_debug("PMIC_SND_RT_PB_VOL\n");
744 sc_access.reg_addr = AUD17;
745 mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
746 break;
747 default:
748 return -EINVAL;
751 retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
752 pr_debug("value read = 0x%x\n", sc_access.value);
753 *value = (int) (sc_access.value & mask);
754 pr_debug("value returned = 0x%x\n", *value);
755 return retval;
758 static void fs_pmic_irq_enable(void *data)
760 struct snd_intelmad *intelmaddata = data;
761 struct sc_reg_access sc_access[] = {
762 {0x187, 0x00, MASK7},
763 {0x188, 0x10, MASK4},
764 {0x18b, 0x10, MASK4},
767 struct sc_reg_access sc_access_write[] = {
768 {0x198, 0x00, 0x0},
770 pr_debug("Audio interrupt enable\n");
771 sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
772 sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
774 intelmaddata->jack[0].jack_status = 0;
775 /*intelmaddata->jack[1].jack_status = 0;*/
777 jack_det_enabled = true;
778 return;
781 static void fs_pmic_irq_cb(void *cb_data, u8 value)
783 struct mad_jack *mjack = NULL;
784 struct snd_intelmad *intelmaddata = cb_data;
785 unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
787 mjack = &intelmaddata->jack[0];
789 if (value & 0x4) {
790 if (!jack_det_enabled)
791 fs_pmic_irq_enable(intelmaddata);
793 /* send headphone detect */
794 pr_debug(":MAD headphone %d\n", value & 0x4);
795 present = !(mjack->jack_status);
796 mjack->jack_status = present;
797 jack_event_flag = 1;
798 mjack->jack.type = SND_JACK_HEADPHONE;
801 if (value & 0x2) {
802 /* send short push */
803 pr_debug(":MAD short push %d\n", value & 0x2);
804 present = 1;
805 jack_event_flag = 1;
806 buttonpressflag = 1;
807 mjack->jack.type = MID_JACK_HS_SHORT_PRESS;
810 if (value & 0x1) {
811 /* send long push */
812 pr_debug(":MAD long push %d\n", value & 0x1);
813 present = 1;
814 jack_event_flag = 1;
815 buttonpressflag = 1;
816 mjack->jack.type = MID_JACK_HS_LONG_PRESS;
819 if (value & 0x8) {
820 if (!jack_det_enabled)
821 fs_pmic_irq_enable(intelmaddata);
822 /* send headset detect */
823 pr_debug(":MAD headset = %d\n", value & 0x8);
824 present = !(mjack->jack_status);
825 mjack->jack_status = present;
826 jack_event_flag = 1;
827 mjack->jack.type = SND_JACK_HEADSET;
831 if (jack_event_flag)
832 sst_mad_send_jack_report(&mjack->jack,
833 buttonpressflag, present);
835 return;
837 static int fs_jack_enable(void)
839 return 0;
842 struct snd_pmic_ops snd_pmic_ops_fs = {
843 .set_input_dev = fs_set_selected_input_dev,
844 .set_output_dev = fs_set_selected_output_dev,
845 .set_mute = fs_set_mute,
846 .get_mute = fs_get_mute,
847 .set_vol = fs_set_vol,
848 .get_vol = fs_get_vol,
849 .init_card = fs_init_card,
850 .set_pcm_audio_params = fs_set_pcm_audio_params,
851 .set_pcm_voice_params = fs_set_pcm_voice_params,
852 .set_voice_port = fs_set_voice_port,
853 .set_audio_port = fs_set_audio_port,
854 .power_up_pmic_pb = fs_power_up_pb,
855 .power_up_pmic_cp = fs_power_up_cp,
856 .power_down_pmic_pb = fs_power_down_pb,
857 .power_down_pmic_cp = fs_power_down_cp,
858 .power_down_pmic = fs_power_down,
859 .pmic_irq_cb = fs_pmic_irq_cb,
861 * Jack detection enabling
862 * need be delayed till first IRQ happen.
864 .pmic_irq_enable = NULL,
865 .pmic_jack_enable = fs_jack_enable,