tg3: fix tigon3_dma_hwbug_workaround()
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / intel_sst / intelmid_msic_control.c
blob70cdb16978153624258069e72714dd955ef052b4
1 /*
2 * intelmid_vm_control.c - Intel Sound card driver for MID
4 * Copyright (C) 2010 Intel Corp
5 * Authors: Vinod Koul <vinod.koul@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 * This file contains the control operations of msic vendors
27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29 #include <linux/pci.h>
30 #include <linux/file.h>
31 #include <linux/delay.h>
32 #include <sound/control.h>
33 #include "intel_sst.h"
34 #include <linux/input.h>
35 #include "intelmid_snd_control.h"
36 #include "intelmid.h"
38 #define AUDIOMUX12 0x24c
39 #define AUDIOMUX34 0x24d
41 static int msic_init_card(void)
43 struct sc_reg_access sc_access[] = {
44 /* dmic configuration */
45 {0x241, 0x85, 0},
46 {0x242, 0x02, 0},
47 /* audio paths config */
48 {0x24C, 0x10, 0},
49 {0x24D, 0x32, 0},
50 /* PCM2 interface slots */
51 /* preconfigured slots for 0-5 both tx, rx */
52 {0x272, 0x10, 0},
53 {0x273, 0x32, 0},
54 {0x274, 0xFF, 0},
55 {0x275, 0x10, 0},
56 {0x276, 0x32, 0},
57 {0x277, 0x54, 0},
58 /*Sinc5 decimator*/
59 {0x24E, 0x28, 0},
60 /*TI vibra w/a settings*/
61 {0x384, 0x80, 0},
62 {0x385, 0x80, 0},
63 {0x267, 0x00, 0},
64 {0x261, 0x00, 0},
65 /* pcm port setting */
66 {0x278, 0x00, 0},
67 {0x27B, 0x01, 0},
68 {0x27C, 0x0a, 0},
69 /* Set vol HSLRVOLCTRL, IHFVOL */
70 {0x259, 0x08, 0},
71 {0x25A, 0x08, 0},
72 {0x25B, 0x08, 0},
73 {0x25C, 0x08, 0},
74 /* HSEPRXCTRL Enable the headset left and right FIR filters */
75 {0x250, 0x30, 0},
76 /* HSMIXER */
77 {0x256, 0x11, 0},
78 /* amic configuration */
79 {0x249, 0x01, 0x0},
80 {0x24A, 0x01, 0x0},
81 /* unmask ocaudio/accdet interrupts */
82 {0x1d, 0x00, 0x00},
83 {0x1e, 0x00, 0x00},
85 snd_msic_ops.card_status = SND_CARD_INIT_DONE;
86 sst_sc_reg_access(sc_access, PMIC_WRITE, 28);
87 snd_msic_ops.pb_on = 0;
88 snd_msic_ops.pbhs_on = 0;
89 snd_msic_ops.cap_on = 0;
90 snd_msic_ops.input_dev_id = DMIC; /*def dev*/
91 snd_msic_ops.output_dev_id = STEREO_HEADPHONE;
92 snd_msic_ops.jack_interrupt_status = false;
93 pr_debug("msic init complete!!\n");
94 return 0;
96 static int msic_line_out_restore(u8 value)
98 struct sc_reg_access hs_drv_en[] = {
99 {0x25d, 0x03, 0x03},
101 struct sc_reg_access ep_drv_en[] = {
102 {0x25d, 0x40, 0x40},
104 struct sc_reg_access ihf_drv_en[] = {
105 {0x25d, 0x0c, 0x0c},
107 struct sc_reg_access vib1_drv_en[] = {
108 {0x25d, 0x10, 0x10},
110 struct sc_reg_access vib2_drv_en[] = {
111 {0x25d, 0x20, 0x20},
113 struct sc_reg_access pmode_enable[] = {
114 {0x381, 0x10, 0x10},
116 int retval = 0;
118 pr_debug("msic_lineout_restore_lineout_dev:%d\n", value);
120 switch (value) {
121 case HEADSET:
122 pr_debug("Selecting Lineout-HEADSET-restore\n");
123 if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE)
124 retval = sst_sc_reg_access(hs_drv_en,
125 PMIC_READ_MODIFY, 1);
126 else
127 retval = sst_sc_reg_access(ep_drv_en,
128 PMIC_READ_MODIFY, 1);
129 break;
130 case IHF:
131 pr_debug("Selecting Lineout-IHF-restore\n");
132 retval = sst_sc_reg_access(ihf_drv_en, PMIC_READ_MODIFY, 1);
133 if (retval)
134 return retval;
135 retval = sst_sc_reg_access(pmode_enable, PMIC_READ_MODIFY, 1);
136 break;
137 case VIBRA1:
138 pr_debug("Selecting Lineout-Vibra1-restore\n");
139 retval = sst_sc_reg_access(vib1_drv_en, PMIC_READ_MODIFY, 1);
140 break;
141 case VIBRA2:
142 pr_debug("Selecting Lineout-VIBRA2-restore\n");
143 retval = sst_sc_reg_access(vib2_drv_en, PMIC_READ_MODIFY, 1);
144 break;
145 case NONE:
146 pr_debug("Selecting Lineout-NONE-restore\n");
147 break;
148 default:
149 return -EINVAL;
151 return retval;
153 static int msic_get_lineout_prvstate(void)
155 struct sc_reg_access hs_ihf_drv[2] = {
156 {0x257, 0x0, 0x0},
157 {0x25d, 0x0, 0x0},
159 struct sc_reg_access vib1drv[2] = {
160 {0x264, 0x0, 0x0},
161 {0x25D, 0x0, 0x0},
163 struct sc_reg_access vib2drv[2] = {
164 {0x26A, 0x0, 0x0},
165 {0x25D, 0x0, 0x0},
167 int retval = 0, drv_en, dac_en, dev_id, mask;
168 for (dev_id = 0; dev_id < snd_msic_ops.line_out_names_cnt; dev_id++) {
169 switch (dev_id) {
170 case HEADSET:
171 pr_debug("msic_get_lineout_prvs_state: HEADSET\n");
172 sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
174 mask = (MASK0|MASK1);
175 dac_en = (hs_ihf_drv[0].value) & mask;
177 mask = ((MASK0|MASK1)|MASK6);
178 drv_en = (hs_ihf_drv[1].value) & mask;
180 if (dac_en && (!drv_en)) {
181 snd_msic_ops.prev_lineout_dev_id = HEADSET;
182 return retval;
184 break;
185 case IHF:
186 pr_debug("msic_get_lineout_prvstate: IHF\n");
187 sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
189 mask = (MASK2 | MASK3);
190 dac_en = (hs_ihf_drv[0].value) & mask;
192 mask = (MASK2 | MASK3);
193 drv_en = (hs_ihf_drv[1].value) & mask;
195 if (dac_en && (!drv_en)) {
196 snd_msic_ops.prev_lineout_dev_id = IHF;
197 return retval;
199 break;
200 case VIBRA1:
201 pr_debug("msic_get_lineout_prvstate: vibra1\n");
202 sst_sc_reg_access(vib1drv, PMIC_READ, 2);
204 mask = MASK1;
205 dac_en = (vib1drv[0].value) & mask;
207 mask = MASK4;
208 drv_en = (vib1drv[1].value) & mask;
210 if (dac_en && (!drv_en)) {
211 snd_msic_ops.prev_lineout_dev_id = VIBRA1;
212 return retval;
214 break;
215 case VIBRA2:
216 pr_debug("msic_get_lineout_prvstate: vibra2\n");
217 sst_sc_reg_access(vib2drv, PMIC_READ, 2);
219 mask = MASK1;
220 dac_en = (vib2drv[0].value) & mask;
222 mask = MASK5;
223 drv_en = ((vib2drv[1].value) & mask);
225 if (dac_en && (!drv_en)) {
226 snd_msic_ops.prev_lineout_dev_id = VIBRA2;
227 return retval;
229 break;
230 case NONE:
231 pr_debug("msic_get_lineout_prvstate: NONE\n");
232 snd_msic_ops.prev_lineout_dev_id = NONE;
233 return retval;
234 default:
235 pr_debug("Invalid device id\n");
236 snd_msic_ops.prev_lineout_dev_id = NONE;
237 return -EINVAL;
240 return retval;
242 static int msic_set_selected_lineout_dev(u8 value)
244 struct sc_reg_access lout_hs[] = {
245 {0x25e, 0x33, 0xFF},
246 {0x25d, 0x0, 0x43},
248 struct sc_reg_access lout_ihf[] = {
249 {0x25e, 0x55, 0xff},
250 {0x25d, 0x0, 0x0c},
252 struct sc_reg_access lout_vibra1[] = {
254 {0x25e, 0x61, 0xff},
255 {0x25d, 0x0, 0x10},
257 struct sc_reg_access lout_vibra2[] = {
259 {0x25e, 0x16, 0xff},
260 {0x25d, 0x0, 0x20},
262 struct sc_reg_access lout_def[] = {
263 {0x25e, 0x66, 0x0},
265 struct sc_reg_access pmode_disable[] = {
266 {0x381, 0x00, 0x10},
268 struct sc_reg_access pmode_enable[] = {
269 {0x381, 0x10, 0x10},
271 int retval = 0;
273 pr_debug("msic_set_selected_lineout_dev:%d\n", value);
274 msic_get_lineout_prvstate();
275 msic_line_out_restore(snd_msic_ops.prev_lineout_dev_id);
276 snd_msic_ops.lineout_dev_id = value;
278 switch (value) {
279 case HEADSET:
280 pr_debug("Selecting Lineout-HEADSET\n");
281 if (snd_msic_ops.pb_on)
282 retval = sst_sc_reg_access(lout_hs,
283 PMIC_READ_MODIFY, 2);
284 if (retval)
285 return retval;
286 retval = sst_sc_reg_access(pmode_disable,
287 PMIC_READ_MODIFY, 1);
288 break;
289 case IHF:
290 pr_debug("Selecting Lineout-IHF\n");
291 if (snd_msic_ops.pb_on)
292 retval = sst_sc_reg_access(lout_ihf,
293 PMIC_READ_MODIFY, 2);
294 if (retval)
295 return retval;
296 retval = sst_sc_reg_access(pmode_enable,
297 PMIC_READ_MODIFY, 1);
298 break;
299 case VIBRA1:
300 pr_debug("Selecting Lineout-Vibra1\n");
301 if (snd_msic_ops.pb_on)
302 retval = sst_sc_reg_access(lout_vibra1,
303 PMIC_READ_MODIFY, 2);
304 if (retval)
305 return retval;
306 retval = sst_sc_reg_access(pmode_disable,
307 PMIC_READ_MODIFY, 1);
308 break;
309 case VIBRA2:
310 pr_debug("Selecting Lineout-VIBRA2\n");
311 if (snd_msic_ops.pb_on)
312 retval = sst_sc_reg_access(lout_vibra2,
313 PMIC_READ_MODIFY, 2);
314 if (retval)
315 return retval;
316 retval = sst_sc_reg_access(pmode_disable,
317 PMIC_READ_MODIFY, 1);
318 break;
319 case NONE:
320 pr_debug("Selecting Lineout-NONE\n");
321 retval = sst_sc_reg_access(lout_def,
322 PMIC_WRITE, 1);
323 if (retval)
324 return retval;
325 retval = sst_sc_reg_access(pmode_disable,
326 PMIC_READ_MODIFY, 1);
327 break;
328 default:
329 return -EINVAL;
331 return retval;
335 static int msic_power_up_pb(unsigned int device)
337 struct sc_reg_access vaud[] = {
338 /* turn on the audio power supplies */
339 {0x0DB, 0x07, 0},
341 struct sc_reg_access pll[] = {
342 /* turn on PLL */
343 {0x240, 0x20, 0},
345 struct sc_reg_access vhs[] = {
346 /* VHSP */
347 {0x0DC, 0x3D, 0},
348 /* VHSN */
349 {0x0DD, 0x3F, 0},
351 struct sc_reg_access hsdac[] = {
352 {0x382, 0x40, 0x40},
353 /* disable driver */
354 {0x25D, 0x0, 0x43},
355 /* DAC CONFIG ; both HP, LP on */
356 {0x257, 0x03, 0x03},
358 struct sc_reg_access hs_filter[] = {
359 /* HSEPRXCTRL Enable the headset left and right FIR filters */
360 {0x250, 0x30, 0},
361 /* HSMIXER */
362 {0x256, 0x11, 0},
364 struct sc_reg_access hs_enable[] = {
365 /* enable driver */
366 {0x25D, 0x3, 0x3},
367 {0x26C, 0x0, 0x2},
368 /* unmute the headset */
369 { 0x259, 0x80, 0x80},
370 { 0x25A, 0x80, 0x80},
372 struct sc_reg_access vihf[] = {
373 /* VIHF ON */
374 {0x0C9, 0x27, 0x00},
376 struct sc_reg_access ihf_filter[] = {
377 /* disable driver */
378 {0x25D, 0x00, 0x0C},
379 /*Filer DAC enable*/
380 {0x251, 0x03, 0x03},
381 {0x257, 0x0C, 0x0C},
383 struct sc_reg_access ihf_en[] = {
384 /*enable drv*/
385 {0x25D, 0x0C, 0x0c},
387 struct sc_reg_access ihf_unmute[] = {
388 /*unmute headset*/
389 {0x25B, 0x80, 0x80},
390 {0x25C, 0x80, 0x80},
392 struct sc_reg_access epdac[] = {
393 /* disable driver */
394 {0x25D, 0x0, 0x43},
395 /* DAC CONFIG ; both HP, LP on */
396 {0x257, 0x03, 0x03},
398 struct sc_reg_access ep_enable[] = {
399 /* enable driver */
400 {0x25D, 0x40, 0x40},
401 /* unmute the headset */
402 { 0x259, 0x80, 0x80},
403 { 0x25A, 0x80, 0x80},
405 struct sc_reg_access vib1_en[] = {
406 /* enable driver, ADC */
407 {0x25D, 0x10, 0x10},
408 {0x264, 0x02, 0x82},
410 struct sc_reg_access vib2_en[] = {
411 /* enable driver, ADC */
412 {0x25D, 0x20, 0x20},
413 {0x26A, 0x02, 0x82},
415 struct sc_reg_access pcm2_en[] = {
416 /* enable pcm 2 */
417 {0x27C, 0x1, 0x1},
419 int retval = 0;
421 if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
422 retval = msic_init_card();
423 if (retval)
424 return retval;
427 pr_debug("powering up pb.... Device %d\n", device);
428 sst_sc_reg_access(vaud, PMIC_WRITE, 1);
429 msleep(1);
430 sst_sc_reg_access(pll, PMIC_WRITE, 1);
431 msleep(1);
432 switch (device) {
433 case SND_SST_DEVICE_HEADSET:
434 snd_msic_ops.pb_on = 1;
435 snd_msic_ops.pbhs_on = 1;
436 if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) {
437 sst_sc_reg_access(vhs, PMIC_WRITE, 2);
438 sst_sc_reg_access(hsdac, PMIC_READ_MODIFY, 3);
439 sst_sc_reg_access(hs_filter, PMIC_WRITE, 2);
440 sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 4);
441 } else {
442 sst_sc_reg_access(epdac, PMIC_READ_MODIFY, 2);
443 sst_sc_reg_access(hs_filter, PMIC_WRITE, 2);
444 sst_sc_reg_access(ep_enable, PMIC_READ_MODIFY, 3);
446 if (snd_msic_ops.lineout_dev_id == HEADSET)
447 msic_set_selected_lineout_dev(HEADSET);
448 break;
449 case SND_SST_DEVICE_IHF:
450 snd_msic_ops.pb_on = 1;
451 sst_sc_reg_access(vihf, PMIC_WRITE, 1);
452 sst_sc_reg_access(ihf_filter, PMIC_READ_MODIFY, 3);
453 sst_sc_reg_access(ihf_en, PMIC_READ_MODIFY, 1);
454 sst_sc_reg_access(ihf_unmute, PMIC_READ_MODIFY, 2);
455 if (snd_msic_ops.lineout_dev_id == IHF)
456 msic_set_selected_lineout_dev(IHF);
457 break;
459 case SND_SST_DEVICE_VIBRA:
460 snd_msic_ops.pb_on = 1;
461 sst_sc_reg_access(vib1_en, PMIC_READ_MODIFY, 2);
462 if (snd_msic_ops.lineout_dev_id == VIBRA1)
463 msic_set_selected_lineout_dev(VIBRA1);
464 break;
466 case SND_SST_DEVICE_HAPTIC:
467 snd_msic_ops.pb_on = 1;
468 sst_sc_reg_access(vib2_en, PMIC_READ_MODIFY, 2);
469 if (snd_msic_ops.lineout_dev_id == VIBRA2)
470 msic_set_selected_lineout_dev(VIBRA2);
471 break;
473 default:
474 pr_warn("Wrong Device %d, selected %d\n",
475 device, snd_msic_ops.output_dev_id);
477 return sst_sc_reg_access(pcm2_en, PMIC_READ_MODIFY, 1);
480 static int msic_power_up_cp(unsigned int device)
482 struct sc_reg_access vaud[] = {
483 /* turn on the audio power supplies */
484 {0x0DB, 0x07, 0},
486 struct sc_reg_access pll[] = {
487 /* turn on PLL */
488 {0x240, 0x20, 0},
490 struct sc_reg_access dmic_bias[] = {
491 /* Turn on AMIC supply */
492 {0x247, 0xA0, 0xA0},
494 struct sc_reg_access dmic[] = {
495 /* mic demux enable */
496 {0x245, 0x3F, 0x3F},
497 {0x246, 0x07, 0x07},
500 struct sc_reg_access amic_bias[] = {
501 /* Turn on AMIC supply */
502 {0x247, 0xFC, 0xFC},
504 struct sc_reg_access amic[] = {
505 /*MIC EN*/
506 {0x249, 0x01, 0x01},
507 {0x24A, 0x01, 0x01},
508 /*ADC EN*/
509 {0x248, 0x05, 0x0F},
512 struct sc_reg_access pcm2[] = {
513 /* enable pcm 2 */
514 {0x27C, 0x1, 0x1},
516 struct sc_reg_access tx_on[] = {
517 /*wait for mic to stabalize before turning on audio channels*/
518 {0x24F, 0x3C, 0x0},
520 int retval = 0;
522 if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
523 retval = msic_init_card();
524 if (retval)
525 return retval;
528 pr_debug("powering up cp....%d\n", snd_msic_ops.input_dev_id);
529 sst_sc_reg_access(vaud, PMIC_WRITE, 1);
530 msleep(500);/*FIXME need optimzed value here*/
531 sst_sc_reg_access(pll, PMIC_WRITE, 1);
532 msleep(1);
533 snd_msic_ops.cap_on = 1;
534 if (snd_msic_ops.input_dev_id == AMIC) {
535 sst_sc_reg_access(amic_bias, PMIC_READ_MODIFY, 1);
536 msleep(1);
537 sst_sc_reg_access(amic, PMIC_READ_MODIFY, 3);
538 } else {
539 sst_sc_reg_access(dmic_bias, PMIC_READ_MODIFY, 1);
540 msleep(1);
541 sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 2);
543 msleep(1);
544 sst_sc_reg_access(tx_on, PMIC_WRITE, 1);
545 return sst_sc_reg_access(pcm2, PMIC_READ_MODIFY, 1);
548 static int msic_power_down(void)
550 struct sc_reg_access power_dn[] = {
551 /* VHSP */
552 {0x0DC, 0xC4, 0},
553 /* VHSN */
554 {0x0DD, 0x04, 0},
555 /* VIHF */
556 {0x0C9, 0x24, 0},
558 struct sc_reg_access pll[] = {
559 /* turn off PLL*/
560 {0x240, 0x00, 0x0},
562 struct sc_reg_access vaud[] = {
563 /* turn off VAUD*/
564 {0x0DB, 0x04, 0},
567 pr_debug("powering dn msic\n");
568 snd_msic_ops.pbhs_on = 0;
569 snd_msic_ops.pb_on = 0;
570 snd_msic_ops.cap_on = 0;
571 sst_sc_reg_access(power_dn, PMIC_WRITE, 3);
572 msleep(1);
573 sst_sc_reg_access(pll, PMIC_WRITE, 1);
574 msleep(1);
575 sst_sc_reg_access(vaud, PMIC_WRITE, 1);
576 return 0;
579 static int msic_power_down_pb(unsigned int device)
581 struct sc_reg_access drv_enable[] = {
582 {0x25D, 0x00, 0x00},
584 struct sc_reg_access hs_mute[] = {
585 {0x259, 0x80, 0x80},
586 {0x25A, 0x80, 0x80},
587 {0x26C, 0x02, 0x02},
589 struct sc_reg_access hs_off[] = {
590 {0x257, 0x00, 0x03},
591 {0x250, 0x00, 0x30},
592 {0x382, 0x00, 0x40},
594 struct sc_reg_access ihf_mute[] = {
595 {0x25B, 0x80, 0x80},
596 {0x25C, 0x80, 0x80},
598 struct sc_reg_access ihf_off[] = {
599 {0x257, 0x00, 0x0C},
600 {0x251, 0x00, 0x03},
602 struct sc_reg_access vib1_off[] = {
603 {0x264, 0x00, 0x82},
605 struct sc_reg_access vib2_off[] = {
606 {0x26A, 0x00, 0x82},
608 struct sc_reg_access lout_off[] = {
609 {0x25e, 0x66, 0x00},
611 struct sc_reg_access pmode_disable[] = {
612 {0x381, 0x00, 0x10},
617 pr_debug("powering dn pb for device %d\n", device);
618 switch (device) {
619 case SND_SST_DEVICE_HEADSET:
620 snd_msic_ops.pbhs_on = 0;
621 sst_sc_reg_access(hs_mute, PMIC_READ_MODIFY, 3);
622 drv_enable[0].mask = 0x43;
623 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
624 sst_sc_reg_access(hs_off, PMIC_READ_MODIFY, 3);
625 if (snd_msic_ops.lineout_dev_id == HEADSET)
626 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
627 break;
629 case SND_SST_DEVICE_IHF:
630 sst_sc_reg_access(ihf_mute, PMIC_READ_MODIFY, 2);
631 drv_enable[0].mask = 0x0C;
632 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
633 sst_sc_reg_access(ihf_off, PMIC_READ_MODIFY, 2);
634 if (snd_msic_ops.lineout_dev_id == IHF) {
635 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
636 sst_sc_reg_access(pmode_disable, PMIC_READ_MODIFY, 1);
638 break;
640 case SND_SST_DEVICE_VIBRA:
641 sst_sc_reg_access(vib1_off, PMIC_READ_MODIFY, 1);
642 drv_enable[0].mask = 0x10;
643 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
644 if (snd_msic_ops.lineout_dev_id == VIBRA1)
645 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
646 break;
648 case SND_SST_DEVICE_HAPTIC:
649 sst_sc_reg_access(vib2_off, PMIC_READ_MODIFY, 1);
650 drv_enable[0].mask = 0x20;
651 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
652 if (snd_msic_ops.lineout_dev_id == VIBRA2)
653 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
654 break;
656 return 0;
659 static int msic_power_down_cp(unsigned int device)
661 struct sc_reg_access dmic[] = {
662 {0x247, 0x00, 0xA0},
663 {0x245, 0x00, 0x38},
664 {0x246, 0x00, 0x07},
666 struct sc_reg_access amic[] = {
667 {0x248, 0x00, 0x05},
668 {0x249, 0x00, 0x01},
669 {0x24A, 0x00, 0x01},
670 {0x247, 0x00, 0xA3},
672 struct sc_reg_access tx_off[] = {
673 {0x24F, 0x00, 0x3C},
676 pr_debug("powering dn cp....\n");
677 snd_msic_ops.cap_on = 0;
678 sst_sc_reg_access(tx_off, PMIC_READ_MODIFY, 1);
679 if (snd_msic_ops.input_dev_id == DMIC)
680 sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 3);
681 else
682 sst_sc_reg_access(amic, PMIC_READ_MODIFY, 4);
683 return 0;
686 static int msic_set_selected_output_dev(u8 value)
688 int retval = 0;
690 pr_debug("msic set selected output:%d\n", value);
691 snd_msic_ops.output_dev_id = value;
692 if (snd_msic_ops.pbhs_on)
693 msic_power_up_pb(SND_SST_DEVICE_HEADSET);
694 return retval;
697 static int msic_set_selected_input_dev(u8 value)
700 struct sc_reg_access sc_access_dmic[] = {
701 {0x24C, 0x10, 0x0},
703 struct sc_reg_access sc_access_amic[] = {
704 {0x24C, 0x76, 0x0},
707 int retval = 0;
709 pr_debug("msic_set_selected_input_dev:%d\n", value);
710 snd_msic_ops.input_dev_id = value;
711 switch (value) {
712 case AMIC:
713 pr_debug("Selecting AMIC1\n");
714 retval = sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 1);
715 break;
716 case DMIC:
717 pr_debug("Selecting DMIC1\n");
718 retval = sst_sc_reg_access(sc_access_dmic, PMIC_WRITE, 1);
719 break;
720 default:
721 return -EINVAL;
724 if (snd_msic_ops.cap_on)
725 retval = msic_power_up_cp(SND_SST_DEVICE_CAPTURE);
726 return retval;
729 static int msic_set_hw_dmic_route(u8 hw_ch_index)
731 struct sc_reg_access sc_access_router;
732 int retval = -EINVAL;
734 switch (hw_ch_index) {
735 case HW_CH0:
736 sc_access_router.reg_addr = AUDIOMUX12;
737 sc_access_router.value = snd_msic_ops.hw_dmic_map[0];
738 sc_access_router.mask = (MASK2 | MASK1 | MASK0);
739 pr_debug("hw_ch0. value = 0x%x\n",
740 sc_access_router.value);
741 retval = sst_sc_reg_access(&sc_access_router,
742 PMIC_READ_MODIFY, 1);
743 break;
745 case HW_CH1:
746 sc_access_router.reg_addr = AUDIOMUX12;
747 sc_access_router.value = (snd_msic_ops.hw_dmic_map[1]) << 4;
748 sc_access_router.mask = (MASK6 | MASK5 | MASK4);
749 pr_debug("### hw_ch1. value = 0x%x\n",
750 sc_access_router.value);
751 retval = sst_sc_reg_access(&sc_access_router,
752 PMIC_READ_MODIFY, 1);
753 break;
755 case HW_CH2:
756 sc_access_router.reg_addr = AUDIOMUX34;
757 sc_access_router.value = snd_msic_ops.hw_dmic_map[2];
758 sc_access_router.mask = (MASK2 | MASK1 | MASK0);
759 pr_debug("hw_ch2. value = 0x%x\n",
760 sc_access_router.value);
761 retval = sst_sc_reg_access(&sc_access_router,
762 PMIC_READ_MODIFY, 1);
763 break;
765 case HW_CH3:
766 sc_access_router.reg_addr = AUDIOMUX34;
767 sc_access_router.value = (snd_msic_ops.hw_dmic_map[3]) << 4;
768 sc_access_router.mask = (MASK6 | MASK5 | MASK4);
769 pr_debug("hw_ch3. value = 0x%x\n",
770 sc_access_router.value);
771 retval = sst_sc_reg_access(&sc_access_router,
772 PMIC_READ_MODIFY, 1);
773 break;
776 return retval;
780 static int msic_set_pcm_voice_params(void)
782 return 0;
785 static int msic_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
787 return 0;
790 static int msic_set_audio_port(int status)
792 return 0;
795 static int msic_set_voice_port(int status)
797 return 0;
800 static int msic_set_mute(int dev_id, u8 value)
802 return 0;
805 static int msic_set_vol(int dev_id, int value)
807 return 0;
810 static int msic_get_mute(int dev_id, u8 *value)
812 return 0;
815 static int msic_get_vol(int dev_id, int *value)
817 return 0;
820 static int msic_set_headset_state(int state)
822 struct sc_reg_access hs_enable[] = {
823 {0x25D, 0x03, 0x03},
826 if (state)
827 /*enable*/
828 sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1);
829 else {
830 hs_enable[0].value = 0;
831 sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1);
833 return 0;
836 static int msic_enable_mic_bias(void)
838 struct sc_reg_access jack_interrupt_reg[] = {
839 {0x0DB, 0x07, 0x00},
842 struct sc_reg_access jack_bias_reg[] = {
843 {0x247, 0x0C, 0x0C},
846 sst_sc_reg_access(jack_interrupt_reg, PMIC_WRITE, 1);
847 sst_sc_reg_access(jack_bias_reg, PMIC_READ_MODIFY, 1);
848 return 0;
851 static int msic_disable_mic_bias(void)
853 if (snd_msic_ops.jack_interrupt_status == true)
854 return 0;
855 if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on))
856 msic_power_down();
857 return 0;
860 static int msic_disable_jack_btn(void)
862 struct sc_reg_access btn_disable[] = {
863 {0x26C, 0x00, 0x01}
866 if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on))
867 msic_power_down();
868 snd_msic_ops.jack_interrupt_status = false;
869 return sst_sc_reg_access(btn_disable, PMIC_READ_MODIFY, 1);
872 static int msic_enable_jack_btn(void)
874 struct sc_reg_access btn_enable[] = {
875 {0x26b, 0x77, 0x00},
876 {0x26C, 0x01, 0x00},
878 return sst_sc_reg_access(btn_enable, PMIC_WRITE, 2);
880 static int msic_convert_adc_to_mvolt(unsigned int mic_bias)
882 return (ADC_ONE_LSB_MULTIPLIER * mic_bias) / 1000;
884 int msic_get_headset_state(int mic_bias)
886 struct sc_reg_access msic_hs_toggle[] = {
887 {0x070, 0x00, 0x01},
889 if (mic_bias >= 0 && mic_bias < 400) {
891 pr_debug("Detected Headphone!!!\n");
892 sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
894 } else if (mic_bias > 400 && mic_bias < 650) {
896 pr_debug("Detected American headset\n");
897 msic_hs_toggle[0].value = 0x01;
898 sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
900 } else if (mic_bias >= 650 && mic_bias < 2000) {
902 pr_debug("Detected Headset!!!\n");
903 sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
904 /*power on jack and btn*/
905 snd_msic_ops.jack_interrupt_status = true;
906 msic_enable_jack_btn();
907 msic_enable_mic_bias();
908 return SND_JACK_HEADSET;
910 } else
911 pr_debug("Detected Open Cable!!!\n");
913 return SND_JACK_HEADPHONE;
916 static int msic_get_mic_bias(void *arg)
918 struct snd_intelmad *intelmad_drv = (struct snd_intelmad *)arg;
919 u16 adc_adr = intelmad_drv->adc_address;
920 u16 adc_val;
921 int ret;
922 struct sc_reg_access adc_ctrl3[2] = {
923 {0x1C2, 0x05, 0x0},
926 struct sc_reg_access audio_adc_reg1 = {0,};
927 struct sc_reg_access audio_adc_reg2 = {0,};
929 msic_enable_mic_bias();
930 /* Enable the msic for conversion before reading */
931 ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1);
932 if (ret)
933 return ret;
934 adc_ctrl3[0].value = 0x04;
935 /* Re-toggle the RRDATARD bit */
936 ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1);
937 if (ret)
938 return ret;
940 audio_adc_reg1.reg_addr = adc_adr;
941 /* Read the higher bits of data */
942 msleep(1000);
943 ret = sst_sc_reg_access(&audio_adc_reg1, PMIC_READ, 1);
944 if (ret)
945 return ret;
946 pr_debug("adc read value %x", audio_adc_reg1.value);
948 /* Shift bits to accomodate the lower two data bits */
949 adc_val = (audio_adc_reg1.value << 2);
950 adc_adr++;
951 audio_adc_reg2. reg_addr = adc_adr;
952 ret = sst_sc_reg_access(&audio_adc_reg2, PMIC_READ, 1);
953 if (ret)
954 return ret;
955 pr_debug("adc read value %x", audio_adc_reg2.value);
957 /* Adding lower two bits to the higher bits */
958 audio_adc_reg2.value &= 03;
959 adc_val += audio_adc_reg2.value;
961 pr_debug("ADC value 0x%x", adc_val);
962 msic_disable_mic_bias();
963 return adc_val;
966 static void msic_pmic_irq_cb(void *cb_data, u8 intsts)
968 struct mad_jack *mjack = NULL;
969 unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
970 struct snd_intelmad *intelmaddata = cb_data;
971 int retval = 0;
973 pr_debug("value returned = 0x%x\n", intsts);
975 if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
976 retval = msic_init_card();
977 if (retval)
978 return;
981 mjack = &intelmaddata->jack[0];
982 if (intsts & 0x1) {
983 pr_debug("MAD short_push detected\n");
984 present = SND_JACK_BTN_0;
985 jack_event_flag = buttonpressflag = 1;
986 mjack->jack.type = SND_JACK_BTN_0;
987 mjack->jack.key[0] = BTN_0 ;
990 if (intsts & 0x2) {
991 pr_debug(":MAD long_push detected\n");
992 jack_event_flag = buttonpressflag = 1;
993 mjack->jack.type = present = SND_JACK_BTN_1;
994 mjack->jack.key[1] = BTN_1;
997 if (intsts & 0x4) {
998 unsigned int mic_bias;
999 jack_event_flag = 1;
1000 buttonpressflag = 0;
1001 mic_bias = msic_get_mic_bias(intelmaddata);
1002 pr_debug("mic_bias = %d\n", mic_bias);
1003 mic_bias = msic_convert_adc_to_mvolt(mic_bias);
1004 pr_debug("mic_bias after conversion = %d mV\n", mic_bias);
1005 mjack->jack_dev_state = msic_get_headset_state(mic_bias);
1006 mjack->jack.type = present = mjack->jack_dev_state;
1009 if (intsts & 0x8) {
1010 mjack->jack.type = mjack->jack_dev_state;
1011 present = 0;
1012 jack_event_flag = 1;
1013 buttonpressflag = 0;
1014 msic_disable_jack_btn();
1015 msic_disable_mic_bias();
1017 if (jack_event_flag)
1018 sst_mad_send_jack_report(&mjack->jack,
1019 buttonpressflag, present);
1024 struct snd_pmic_ops snd_msic_ops = {
1025 .set_input_dev = msic_set_selected_input_dev,
1026 .set_output_dev = msic_set_selected_output_dev,
1027 .set_lineout_dev = msic_set_selected_lineout_dev,
1028 .set_hw_dmic_route = msic_set_hw_dmic_route,
1029 .set_mute = msic_set_mute,
1030 .get_mute = msic_get_mute,
1031 .set_vol = msic_set_vol,
1032 .get_vol = msic_get_vol,
1033 .init_card = msic_init_card,
1034 .set_pcm_audio_params = msic_set_pcm_audio_params,
1035 .set_pcm_voice_params = msic_set_pcm_voice_params,
1036 .set_voice_port = msic_set_voice_port,
1037 .set_audio_port = msic_set_audio_port,
1038 .power_up_pmic_pb = msic_power_up_pb,
1039 .power_up_pmic_cp = msic_power_up_cp,
1040 .power_down_pmic_pb = msic_power_down_pb,
1041 .power_down_pmic_cp = msic_power_down_cp,
1042 .power_down_pmic = msic_power_down,
1043 .pmic_irq_cb = msic_pmic_irq_cb,
1044 .pmic_jack_enable = msic_enable_mic_bias,
1045 .pmic_get_mic_bias = msic_get_mic_bias,
1046 .pmic_set_headset_state = msic_set_headset_state,