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