1 /* intel_sst_v1_control.c - Intel SST Driver for audio engine
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 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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.
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.
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 * This file contains the control operations of vendor 2
28 #include <linux/pci.h>
29 #include <linux/file.h>
31 #include <sound/pcm.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"
39 #include "intelmid_snd_control.h"
41 #include <linux/gpio.h>
42 #define KOSKI_VOICE_CODEC_ENABLE 46
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,
53 DAI2_TO_DAC_HP = 0x210,
54 HP_OP_SINGLE_ENDED = 0x224,
55 ENABLE_OPDEV_CTRL = 0x226,
56 ENABLE_DEV_AND_USE_XTAL = 0x227,
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,
67 /* Headphone volume control & mute registers */
73 * mx_init_card - initilize the sound card
75 * This initilizes the audio paths to know values in case of this sound card
77 static int mx_init_card(void)
79 struct sc_reg_access sc_access[] = {
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);
135 static int mx_init_capture_card(void)
137 struct sc_reg_access sc_access[] = {
150 retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 8);
152 /* pmic communication fails */
153 pr_debug("sst: pmic commn failed\n");
157 pr_debug("sst: Capture configuration complete!!\n");
161 static int mx_init_playback_card(void)
163 struct sc_reg_access sc_access[] = {
174 retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 9);
176 /* pmic communication fails */
177 pr_debug("sst: pmic commn failed\n");
181 pr_debug("sst: Playback configuration complete!!\n");
185 static int mx_enable_audiodac(int value)
187 struct sc_reg_access sc_access[3];
192 sc_access[0].reg_addr = AS_LEFT_HP_VOL_CTL;
193 sc_access[1].reg_addr = AS_RIGHT_HP_VOL_CTL;
195 if (value == UNMUTE) {
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);
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)
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);
221 static int mx_power_up_pb(unsigned int port)
225 struct sc_reg_access sc_access[3];
227 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
228 retval = mx_init_card();
232 retval = mx_enable_audiodac(MUTE);
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);
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);
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);
259 return mx_enable_audiodac(UNMUTE);
262 static int mx_power_down_pb(void)
264 struct sc_reg_access sc_access[3];
267 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
268 retval = mx_init_card();
273 retval = mx_enable_audiodac(MUTE);
277 sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
278 sc_access[0].mask = MASK3|MASK2;
279 sc_access[0].value = 0x00;
281 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
285 return mx_enable_audiodac(UNMUTE);
288 static int mx_power_up_cp(unsigned int port)
291 struct sc_reg_access sc_access[] = {
292 {ENABLE_DEV_AND_USE_XTAL, 0x80, MASK7},
293 {ENABLE_OPDEV_CTRL, 0x3, 0x3},
296 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
297 retval = mx_init_card();
302 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
305 static int mx_power_down_cp(void)
307 struct sc_reg_access sc_access[] = {
308 {ENABLE_OPDEV_CTRL, 0x00, MASK1|MASK0},
312 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
313 retval = mx_init_card();
318 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
321 static int mx_power_down(void)
324 struct sc_reg_access sc_access[3];
326 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
327 retval = mx_init_card();
332 retval = mx_enable_audiodac(MUTE);
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);
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);
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);
357 return mx_enable_audiodac(UNMUTE);
360 static int mx_set_pcm_voice_params(void)
363 struct sc_reg_access sc_access[] = {
376 {0x20c, 0xBE, 0x00},/* 0x00 -> 0xBE Koski */
377 {0x20d, 0x00, 0x00}, /* DAI2 'off' */
381 {0x211, 0x33, 0x00}, /* Voice filter */
396 {0x220, 0x00, 0x00}, /* Microphone configurations */
397 {0x221, 0x00, 0x00}, /* Microphone configurations */
398 {0x222, 0x50, 0x00}, /* Microphone configurations */
399 {0x223, 0x21, 0x00}, /* Microphone configurations */
410 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
411 retval = mx_init_card();
415 pr_debug("sst: SST DBG mx_set_pcm_voice_params called\n");
416 return sst_sc_reg_access(sc_access, PMIC_WRITE, 44);
419 static int mx_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
423 int config1 = 0, config2 = 0, filter = 0xB3;
424 struct sc_reg_access sc_access[5];
426 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
427 retval = mx_init_card();
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;
478 sc_access[1].reg_addr = 0x224;
479 sc_access[1].value = 0x05;
480 sc_access[1].mask = MASK0|MASK1|MASK2;
482 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
486 sc_access[0].reg_addr = VOL_CTRL_RT;
487 sc_access[0].value = 0x00;
488 sc_access[0].mask = MASK6;
490 sc_access[1].reg_addr = 0x224;
491 sc_access[1].value = 0x04;
492 sc_access[1].mask = MASK0|MASK1|MASK2;
494 retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
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;
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;
511 sc_access[2].reg_addr = 0x209;
512 sc_access[3].reg_addr = 0x20e;
514 sc_access[4].reg_addr = 0x211;
515 sc_access[4].value = filter;
517 return sst_sc_reg_access(sc_access, PMIC_WRITE, 5);
520 static int mx_set_selected_output_dev(u8 dev_id)
522 struct sc_reg_access sc_access[2];
526 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
527 retval = mx_init_card();
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;
535 case STEREO_HEADPHONE:
536 sc_access[0].reg_addr = 0xFF;
537 sc_access[0].value = 0x8C;
539 MASK2|MASK3|MASK5|MASK6|MASK4;
545 sc_access[0].reg_addr = 0xFF;
546 sc_access[0].value = 0xb0;
547 sc_access[0].mask = MASK2|MASK3|MASK5|MASK6|MASK4;
552 pr_debug("sst: RECEIVER Koski selected\n");
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;
562 pr_err("sst: Not a valid output dev\n");
565 return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
569 static int mx_set_voice_port(int status)
573 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
574 retval = mx_init_card();
578 if (status == ACTIVATE)
579 retval = mx_set_pcm_voice_params();
584 static int mx_set_audio_port(int status)
589 static int mx_set_selected_input_dev(u8 dev_id)
591 struct sc_reg_access sc_access[2];
595 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
596 retval = mx_init_card();
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);
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;
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;
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;
633 return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
636 static int mx_set_mute(int dev_id, u8 value)
638 struct sc_reg_access sc_access[5];
642 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
643 retval = mx_init_card();
649 pr_debug("sst: set_mute dev_id:0x%x , value:%d\n", dev_id, value);
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;
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;
664 sc_access[2].value = 0x20;
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;
671 sc_access[2].value = 0x00;
673 sc_access[0].mask = MASK5|MASK6;
674 sc_access[1].mask = MASK5|MASK6;
675 sc_access[2].mask = MASK5|MASK6;
678 case PMIC_SND_LEFT_SPEAKER_MUTE:
679 case PMIC_SND_LEFT_HP_MUTE:
680 sc_access[0].reg_addr = VOL_CTRL_LT;
682 sc_access[0].value = 0x40;
684 sc_access[0].value = 0x00;
685 sc_access[0].mask = MASK6;
687 snd_pmic_ops_mx.mute_status = value;
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)
695 sc_access[0].value = 0x40;
697 sc_access[0].value = 0x00;
698 sc_access[0].mask = MASK6;
700 snd_pmic_ops_mx.mute_status = value;
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;
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;
716 sc_access[4].value = 0x20;
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;
725 sc_access[4].value = 0x00;
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;
738 case PMIC_SND_RECEIVER_MUTE:
739 sc_access[0].reg_addr = VOL_CTRL_RT;
741 sc_access[0].value = 0x40;
743 sc_access[0].value = 0x00;
744 sc_access[0].mask = MASK6;
749 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
752 static int mx_set_vol(int dev_id, int value)
754 struct sc_reg_access sc_access[2] = {{0},};
758 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
759 retval = mx_init_card();
763 pr_debug("sst: set_vol dev_id:0x%x ,value:%d\n", dev_id, value);
765 case PMIC_SND_RECEIVER_VOL:
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);
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);
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;
794 return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
797 static int mx_get_mute(int dev_id, u8 *value)
799 struct sc_reg_access sc_access[4] = {{0},};
800 int retval = 0, num_reg = 0, mask = 0;
802 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
803 retval = mx_init_card();
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;
814 retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
817 *value = sc_access[0].value & mask;
823 case PMIC_SND_LEFT_HP_MUTE:
824 case PMIC_SND_LEFT_SPEAKER_MUTE:
825 sc_access[0].reg_addr = VOL_CTRL_LT;
829 case PMIC_SND_RIGHT_HP_MUTE:
830 case PMIC_SND_RIGHT_SPEAKER_MUTE:
831 sc_access[0].reg_addr = VOL_CTRL_RT;
836 retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
839 *value = sc_access[0].value & mask;
847 static int mx_get_vol(int dev_id, int *value)
849 struct sc_reg_access sc_access = {0,};
850 int retval = 0, mask = 0, num_reg = 0;
852 if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
853 retval = mx_init_card();
858 case PMIC_SND_CAPTURE_VOL:
859 sc_access.reg_addr = 0x220;
860 mask = MASK0|MASK1|MASK2|MASK3|MASK4;
863 case PMIC_SND_LEFT_PB_VOL:
864 sc_access.reg_addr = VOL_CTRL_LT;
865 mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
868 case PMIC_SND_RIGHT_PB_VOL:
869 sc_access.reg_addr = VOL_CTRL_RT;
870 mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
874 retval = sst_sc_reg_access(&sc_access, PMIC_READ, num_reg);
877 *value = -(sc_access.value & mask);
878 pr_debug("sst: get volume value extracted %d\n", *value);
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,