diff options
Diffstat (limited to 'drivers/staging/intel_sst/intelmid_msic_control.c')
-rw-r--r-- | drivers/staging/intel_sst/intelmid_msic_control.c | 1047 |
1 files changed, 0 insertions, 1047 deletions
diff --git a/drivers/staging/intel_sst/intelmid_msic_control.c b/drivers/staging/intel_sst/intelmid_msic_control.c deleted file mode 100644 index 70cdb16..0000000 --- a/drivers/staging/intel_sst/intelmid_msic_control.c +++ /dev/null @@ -1,1047 +0,0 @@ -/* - * intelmid_vm_control.c - Intel Sound card driver for MID - * - * Copyright (C) 2010 Intel Corp - * Authors: Vinod Koul <vinod.koul@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This file contains the control operations of msic vendors - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/pci.h> -#include <linux/file.h> -#include <linux/delay.h> -#include <sound/control.h> -#include "intel_sst.h" -#include <linux/input.h> -#include "intelmid_snd_control.h" -#include "intelmid.h" - -#define AUDIOMUX12 0x24c -#define AUDIOMUX34 0x24d - -static int msic_init_card(void) -{ - struct sc_reg_access sc_access[] = { - /* dmic configuration */ - {0x241, 0x85, 0}, - {0x242, 0x02, 0}, - /* audio paths config */ - {0x24C, 0x10, 0}, - {0x24D, 0x32, 0}, - /* PCM2 interface slots */ - /* preconfigured slots for 0-5 both tx, rx */ - {0x272, 0x10, 0}, - {0x273, 0x32, 0}, - {0x274, 0xFF, 0}, - {0x275, 0x10, 0}, - {0x276, 0x32, 0}, - {0x277, 0x54, 0}, - /*Sinc5 decimator*/ - {0x24E, 0x28, 0}, - /*TI vibra w/a settings*/ - {0x384, 0x80, 0}, - {0x385, 0x80, 0}, - {0x267, 0x00, 0}, - {0x261, 0x00, 0}, - /* pcm port setting */ - {0x278, 0x00, 0}, - {0x27B, 0x01, 0}, - {0x27C, 0x0a, 0}, - /* Set vol HSLRVOLCTRL, IHFVOL */ - {0x259, 0x08, 0}, - {0x25A, 0x08, 0}, - {0x25B, 0x08, 0}, - {0x25C, 0x08, 0}, - /* HSEPRXCTRL Enable the headset left and right FIR filters */ - {0x250, 0x30, 0}, - /* HSMIXER */ - {0x256, 0x11, 0}, - /* amic configuration */ - {0x249, 0x01, 0x0}, - {0x24A, 0x01, 0x0}, - /* unmask ocaudio/accdet interrupts */ - {0x1d, 0x00, 0x00}, - {0x1e, 0x00, 0x00}, - }; - snd_msic_ops.card_status = SND_CARD_INIT_DONE; - sst_sc_reg_access(sc_access, PMIC_WRITE, 28); - snd_msic_ops.pb_on = 0; - snd_msic_ops.pbhs_on = 0; - snd_msic_ops.cap_on = 0; - snd_msic_ops.input_dev_id = DMIC; /*def dev*/ - snd_msic_ops.output_dev_id = STEREO_HEADPHONE; - snd_msic_ops.jack_interrupt_status = false; - pr_debug("msic init complete!!\n"); - return 0; -} -static int msic_line_out_restore(u8 value) -{ - struct sc_reg_access hs_drv_en[] = { - {0x25d, 0x03, 0x03}, - }; - struct sc_reg_access ep_drv_en[] = { - {0x25d, 0x40, 0x40}, - }; - struct sc_reg_access ihf_drv_en[] = { - {0x25d, 0x0c, 0x0c}, - }; - struct sc_reg_access vib1_drv_en[] = { - {0x25d, 0x10, 0x10}, - }; - struct sc_reg_access vib2_drv_en[] = { - {0x25d, 0x20, 0x20}, - }; - struct sc_reg_access pmode_enable[] = { - {0x381, 0x10, 0x10}, - }; - int retval = 0; - - pr_debug("msic_lineout_restore_lineout_dev:%d\n", value); - - switch (value) { - case HEADSET: - pr_debug("Selecting Lineout-HEADSET-restore\n"); - if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) - retval = sst_sc_reg_access(hs_drv_en, - PMIC_READ_MODIFY, 1); - else - retval = sst_sc_reg_access(ep_drv_en, - PMIC_READ_MODIFY, 1); - break; - case IHF: - pr_debug("Selecting Lineout-IHF-restore\n"); - retval = sst_sc_reg_access(ihf_drv_en, PMIC_READ_MODIFY, 1); - if (retval) - return retval; - retval = sst_sc_reg_access(pmode_enable, PMIC_READ_MODIFY, 1); - break; - case VIBRA1: - pr_debug("Selecting Lineout-Vibra1-restore\n"); - retval = sst_sc_reg_access(vib1_drv_en, PMIC_READ_MODIFY, 1); - break; - case VIBRA2: - pr_debug("Selecting Lineout-VIBRA2-restore\n"); - retval = sst_sc_reg_access(vib2_drv_en, PMIC_READ_MODIFY, 1); - break; - case NONE: - pr_debug("Selecting Lineout-NONE-restore\n"); - break; - default: - return -EINVAL; - } - return retval; -} -static int msic_get_lineout_prvstate(void) -{ - struct sc_reg_access hs_ihf_drv[2] = { - {0x257, 0x0, 0x0}, - {0x25d, 0x0, 0x0}, - }; - struct sc_reg_access vib1drv[2] = { - {0x264, 0x0, 0x0}, - {0x25D, 0x0, 0x0}, - }; - struct sc_reg_access vib2drv[2] = { - {0x26A, 0x0, 0x0}, - {0x25D, 0x0, 0x0}, - }; - int retval = 0, drv_en, dac_en, dev_id, mask; - for (dev_id = 0; dev_id < snd_msic_ops.line_out_names_cnt; dev_id++) { - switch (dev_id) { - case HEADSET: - pr_debug("msic_get_lineout_prvs_state: HEADSET\n"); - sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2); - - mask = (MASK0|MASK1); - dac_en = (hs_ihf_drv[0].value) & mask; - - mask = ((MASK0|MASK1)|MASK6); - drv_en = (hs_ihf_drv[1].value) & mask; - - if (dac_en && (!drv_en)) { - snd_msic_ops.prev_lineout_dev_id = HEADSET; - return retval; - } - break; - case IHF: - pr_debug("msic_get_lineout_prvstate: IHF\n"); - sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2); - - mask = (MASK2 | MASK3); - dac_en = (hs_ihf_drv[0].value) & mask; - - mask = (MASK2 | MASK3); - drv_en = (hs_ihf_drv[1].value) & mask; - - if (dac_en && (!drv_en)) { - snd_msic_ops.prev_lineout_dev_id = IHF; - return retval; - } - break; - case VIBRA1: - pr_debug("msic_get_lineout_prvstate: vibra1\n"); - sst_sc_reg_access(vib1drv, PMIC_READ, 2); - - mask = MASK1; - dac_en = (vib1drv[0].value) & mask; - - mask = MASK4; - drv_en = (vib1drv[1].value) & mask; - - if (dac_en && (!drv_en)) { - snd_msic_ops.prev_lineout_dev_id = VIBRA1; - return retval; - } - break; - case VIBRA2: - pr_debug("msic_get_lineout_prvstate: vibra2\n"); - sst_sc_reg_access(vib2drv, PMIC_READ, 2); - - mask = MASK1; - dac_en = (vib2drv[0].value) & mask; - - mask = MASK5; - drv_en = ((vib2drv[1].value) & mask); - - if (dac_en && (!drv_en)) { - snd_msic_ops.prev_lineout_dev_id = VIBRA2; - return retval; - } - break; - case NONE: - pr_debug("msic_get_lineout_prvstate: NONE\n"); - snd_msic_ops.prev_lineout_dev_id = NONE; - return retval; - default: - pr_debug("Invalid device id\n"); - snd_msic_ops.prev_lineout_dev_id = NONE; - return -EINVAL; - } - } - return retval; -} -static int msic_set_selected_lineout_dev(u8 value) -{ - struct sc_reg_access lout_hs[] = { - {0x25e, 0x33, 0xFF}, - {0x25d, 0x0, 0x43}, - }; - struct sc_reg_access lout_ihf[] = { - {0x25e, 0x55, 0xff}, - {0x25d, 0x0, 0x0c}, - }; - struct sc_reg_access lout_vibra1[] = { - - {0x25e, 0x61, 0xff}, - {0x25d, 0x0, 0x10}, - }; - struct sc_reg_access lout_vibra2[] = { - - {0x25e, 0x16, 0xff}, - {0x25d, 0x0, 0x20}, - }; - struct sc_reg_access lout_def[] = { - {0x25e, 0x66, 0x0}, - }; - struct sc_reg_access pmode_disable[] = { - {0x381, 0x00, 0x10}, - }; - struct sc_reg_access pmode_enable[] = { - {0x381, 0x10, 0x10}, - }; - int retval = 0; - - pr_debug("msic_set_selected_lineout_dev:%d\n", value); - msic_get_lineout_prvstate(); - msic_line_out_restore(snd_msic_ops.prev_lineout_dev_id); - snd_msic_ops.lineout_dev_id = value; - - switch (value) { - case HEADSET: - pr_debug("Selecting Lineout-HEADSET\n"); - if (snd_msic_ops.pb_on) - retval = sst_sc_reg_access(lout_hs, - PMIC_READ_MODIFY, 2); - if (retval) - return retval; - retval = sst_sc_reg_access(pmode_disable, - PMIC_READ_MODIFY, 1); - break; - case IHF: - pr_debug("Selecting Lineout-IHF\n"); - if (snd_msic_ops.pb_on) - retval = sst_sc_reg_access(lout_ihf, - PMIC_READ_MODIFY, 2); - if (retval) - return retval; - retval = sst_sc_reg_access(pmode_enable, - PMIC_READ_MODIFY, 1); - break; - case VIBRA1: - pr_debug("Selecting Lineout-Vibra1\n"); - if (snd_msic_ops.pb_on) - retval = sst_sc_reg_access(lout_vibra1, - PMIC_READ_MODIFY, 2); - if (retval) - return retval; - retval = sst_sc_reg_access(pmode_disable, - PMIC_READ_MODIFY, 1); - break; - case VIBRA2: - pr_debug("Selecting Lineout-VIBRA2\n"); - if (snd_msic_ops.pb_on) - retval = sst_sc_reg_access(lout_vibra2, - PMIC_READ_MODIFY, 2); - if (retval) - return retval; - retval = sst_sc_reg_access(pmode_disable, - PMIC_READ_MODIFY, 1); - break; - case NONE: - pr_debug("Selecting Lineout-NONE\n"); - retval = sst_sc_reg_access(lout_def, - PMIC_WRITE, 1); - if (retval) - return retval; - retval = sst_sc_reg_access(pmode_disable, - PMIC_READ_MODIFY, 1); - break; - default: - return -EINVAL; - } - return retval; -} - - -static int msic_power_up_pb(unsigned int device) -{ - struct sc_reg_access vaud[] = { - /* turn on the audio power supplies */ - {0x0DB, 0x07, 0}, - }; - struct sc_reg_access pll[] = { - /* turn on PLL */ - {0x240, 0x20, 0}, - }; - struct sc_reg_access vhs[] = { - /* VHSP */ - {0x0DC, 0x3D, 0}, - /* VHSN */ - {0x0DD, 0x3F, 0}, - }; - struct sc_reg_access hsdac[] = { - {0x382, 0x40, 0x40}, - /* disable driver */ - {0x25D, 0x0, 0x43}, - /* DAC CONFIG ; both HP, LP on */ - {0x257, 0x03, 0x03}, - }; - struct sc_reg_access hs_filter[] = { - /* HSEPRXCTRL Enable the headset left and right FIR filters */ - {0x250, 0x30, 0}, - /* HSMIXER */ - {0x256, 0x11, 0}, - }; - struct sc_reg_access hs_enable[] = { - /* enable driver */ - {0x25D, 0x3, 0x3}, - {0x26C, 0x0, 0x2}, - /* unmute the headset */ - { 0x259, 0x80, 0x80}, - { 0x25A, 0x80, 0x80}, - }; - struct sc_reg_access vihf[] = { - /* VIHF ON */ - {0x0C9, 0x27, 0x00}, - }; - struct sc_reg_access ihf_filter[] = { - /* disable driver */ - {0x25D, 0x00, 0x0C}, - /*Filer DAC enable*/ - {0x251, 0x03, 0x03}, - {0x257, 0x0C, 0x0C}, - }; - struct sc_reg_access ihf_en[] = { - /*enable drv*/ - {0x25D, 0x0C, 0x0c}, - }; - struct sc_reg_access ihf_unmute[] = { - /*unmute headset*/ - {0x25B, 0x80, 0x80}, - {0x25C, 0x80, 0x80}, - }; - struct sc_reg_access epdac[] = { - /* disable driver */ - {0x25D, 0x0, 0x43}, - /* DAC CONFIG ; both HP, LP on */ - {0x257, 0x03, 0x03}, - }; - struct sc_reg_access ep_enable[] = { - /* enable driver */ - {0x25D, 0x40, 0x40}, - /* unmute the headset */ - { 0x259, 0x80, 0x80}, - { 0x25A, 0x80, 0x80}, - }; - struct sc_reg_access vib1_en[] = { - /* enable driver, ADC */ - {0x25D, 0x10, 0x10}, - {0x264, 0x02, 0x82}, - }; - struct sc_reg_access vib2_en[] = { - /* enable driver, ADC */ - {0x25D, 0x20, 0x20}, - {0x26A, 0x02, 0x82}, - }; - struct sc_reg_access pcm2_en[] = { - /* enable pcm 2 */ - {0x27C, 0x1, 0x1}, - }; - int retval = 0; - - if (snd_msic_ops.card_status == SND_CARD_UN_INIT) { - retval = msic_init_card(); - if (retval) - return retval; - } - - pr_debug("powering up pb.... Device %d\n", device); - sst_sc_reg_access(vaud, PMIC_WRITE, 1); - msleep(1); - sst_sc_reg_access(pll, PMIC_WRITE, 1); - msleep(1); - switch (device) { - case SND_SST_DEVICE_HEADSET: - snd_msic_ops.pb_on = 1; - snd_msic_ops.pbhs_on = 1; - if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) { - sst_sc_reg_access(vhs, PMIC_WRITE, 2); - sst_sc_reg_access(hsdac, PMIC_READ_MODIFY, 3); - sst_sc_reg_access(hs_filter, PMIC_WRITE, 2); - sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 4); - } else { - sst_sc_reg_access(epdac, PMIC_READ_MODIFY, 2); - sst_sc_reg_access(hs_filter, PMIC_WRITE, 2); - sst_sc_reg_access(ep_enable, PMIC_READ_MODIFY, 3); - } - if (snd_msic_ops.lineout_dev_id == HEADSET) - msic_set_selected_lineout_dev(HEADSET); - break; - case SND_SST_DEVICE_IHF: - snd_msic_ops.pb_on = 1; - sst_sc_reg_access(vihf, PMIC_WRITE, 1); - sst_sc_reg_access(ihf_filter, PMIC_READ_MODIFY, 3); - sst_sc_reg_access(ihf_en, PMIC_READ_MODIFY, 1); - sst_sc_reg_access(ihf_unmute, PMIC_READ_MODIFY, 2); - if (snd_msic_ops.lineout_dev_id == IHF) - msic_set_selected_lineout_dev(IHF); - break; - - case SND_SST_DEVICE_VIBRA: - snd_msic_ops.pb_on = 1; - sst_sc_reg_access(vib1_en, PMIC_READ_MODIFY, 2); - if (snd_msic_ops.lineout_dev_id == VIBRA1) - msic_set_selected_lineout_dev(VIBRA1); - break; - - case SND_SST_DEVICE_HAPTIC: - snd_msic_ops.pb_on = 1; - sst_sc_reg_access(vib2_en, PMIC_READ_MODIFY, 2); - if (snd_msic_ops.lineout_dev_id == VIBRA2) - msic_set_selected_lineout_dev(VIBRA2); - break; - - default: - pr_warn("Wrong Device %d, selected %d\n", - device, snd_msic_ops.output_dev_id); - } - return sst_sc_reg_access(pcm2_en, PMIC_READ_MODIFY, 1); -} - -static int msic_power_up_cp(unsigned int device) -{ - struct sc_reg_access vaud[] = { - /* turn on the audio power supplies */ - {0x0DB, 0x07, 0}, - }; - struct sc_reg_access pll[] = { - /* turn on PLL */ - {0x240, 0x20, 0}, - }; - struct sc_reg_access dmic_bias[] = { - /* Turn on AMIC supply */ - {0x247, 0xA0, 0xA0}, - }; - struct sc_reg_access dmic[] = { - /* mic demux enable */ - {0x245, 0x3F, 0x3F}, - {0x246, 0x07, 0x07}, - - }; - struct sc_reg_access amic_bias[] = { - /* Turn on AMIC supply */ - {0x247, 0xFC, 0xFC}, - }; - struct sc_reg_access amic[] = { - /*MIC EN*/ - {0x249, 0x01, 0x01}, - {0x24A, 0x01, 0x01}, - /*ADC EN*/ - {0x248, 0x05, 0x0F}, - - }; - struct sc_reg_access pcm2[] = { - /* enable pcm 2 */ - {0x27C, 0x1, 0x1}, - }; - struct sc_reg_access tx_on[] = { - /*wait for mic to stabalize before turning on audio channels*/ - {0x24F, 0x3C, 0x0}, - }; - int retval = 0; - - if (snd_msic_ops.card_status == SND_CARD_UN_INIT) { - retval = msic_init_card(); - if (retval) - return retval; - } - - pr_debug("powering up cp....%d\n", snd_msic_ops.input_dev_id); - sst_sc_reg_access(vaud, PMIC_WRITE, 1); - msleep(500);/*FIXME need optimzed value here*/ - sst_sc_reg_access(pll, PMIC_WRITE, 1); - msleep(1); - snd_msic_ops.cap_on = 1; - if (snd_msic_ops.input_dev_id == AMIC) { - sst_sc_reg_access(amic_bias, PMIC_READ_MODIFY, 1); - msleep(1); - sst_sc_reg_access(amic, PMIC_READ_MODIFY, 3); - } else { - sst_sc_reg_access(dmic_bias, PMIC_READ_MODIFY, 1); - msleep(1); - sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 2); - } - msleep(1); - sst_sc_reg_access(tx_on, PMIC_WRITE, 1); - return sst_sc_reg_access(pcm2, PMIC_READ_MODIFY, 1); -} - -static int msic_power_down(void) -{ - struct sc_reg_access power_dn[] = { - /* VHSP */ - {0x0DC, 0xC4, 0}, - /* VHSN */ - {0x0DD, 0x04, 0}, - /* VIHF */ - {0x0C9, 0x24, 0}, - }; - struct sc_reg_access pll[] = { - /* turn off PLL*/ - {0x240, 0x00, 0x0}, - }; - struct sc_reg_access vaud[] = { - /* turn off VAUD*/ - {0x0DB, 0x04, 0}, - }; - - pr_debug("powering dn msic\n"); - snd_msic_ops.pbhs_on = 0; - snd_msic_ops.pb_on = 0; - snd_msic_ops.cap_on = 0; - sst_sc_reg_access(power_dn, PMIC_WRITE, 3); - msleep(1); - sst_sc_reg_access(pll, PMIC_WRITE, 1); - msleep(1); - sst_sc_reg_access(vaud, PMIC_WRITE, 1); - return 0; -} - -static int msic_power_down_pb(unsigned int device) -{ - struct sc_reg_access drv_enable[] = { - {0x25D, 0x00, 0x00}, - }; - struct sc_reg_access hs_mute[] = { - {0x259, 0x80, 0x80}, - {0x25A, 0x80, 0x80}, - {0x26C, 0x02, 0x02}, - }; - struct sc_reg_access hs_off[] = { - {0x257, 0x00, 0x03}, - {0x250, 0x00, 0x30}, - {0x382, 0x00, 0x40}, - }; - struct sc_reg_access ihf_mute[] = { - {0x25B, 0x80, 0x80}, - {0x25C, 0x80, 0x80}, - }; - struct sc_reg_access ihf_off[] = { - {0x257, 0x00, 0x0C}, - {0x251, 0x00, 0x03}, - }; - struct sc_reg_access vib1_off[] = { - {0x264, 0x00, 0x82}, - }; - struct sc_reg_access vib2_off[] = { - {0x26A, 0x00, 0x82}, - }; - struct sc_reg_access lout_off[] = { - {0x25e, 0x66, 0x00}, - }; - struct sc_reg_access pmode_disable[] = { - {0x381, 0x00, 0x10}, - }; - - - - pr_debug("powering dn pb for device %d\n", device); - switch (device) { - case SND_SST_DEVICE_HEADSET: - snd_msic_ops.pbhs_on = 0; - sst_sc_reg_access(hs_mute, PMIC_READ_MODIFY, 3); - drv_enable[0].mask = 0x43; - sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); - sst_sc_reg_access(hs_off, PMIC_READ_MODIFY, 3); - if (snd_msic_ops.lineout_dev_id == HEADSET) - sst_sc_reg_access(lout_off, PMIC_WRITE, 1); - break; - - case SND_SST_DEVICE_IHF: - sst_sc_reg_access(ihf_mute, PMIC_READ_MODIFY, 2); - drv_enable[0].mask = 0x0C; - sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); - sst_sc_reg_access(ihf_off, PMIC_READ_MODIFY, 2); - if (snd_msic_ops.lineout_dev_id == IHF) { - sst_sc_reg_access(lout_off, PMIC_WRITE, 1); - sst_sc_reg_access(pmode_disable, PMIC_READ_MODIFY, 1); - } - break; - - case SND_SST_DEVICE_VIBRA: - sst_sc_reg_access(vib1_off, PMIC_READ_MODIFY, 1); - drv_enable[0].mask = 0x10; - sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); - if (snd_msic_ops.lineout_dev_id == VIBRA1) - sst_sc_reg_access(lout_off, PMIC_WRITE, 1); - break; - - case SND_SST_DEVICE_HAPTIC: - sst_sc_reg_access(vib2_off, PMIC_READ_MODIFY, 1); - drv_enable[0].mask = 0x20; - sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); - if (snd_msic_ops.lineout_dev_id == VIBRA2) - sst_sc_reg_access(lout_off, PMIC_WRITE, 1); - break; - } - return 0; -} - -static int msic_power_down_cp(unsigned int device) -{ - struct sc_reg_access dmic[] = { - {0x247, 0x00, 0xA0}, - {0x245, 0x00, 0x38}, - {0x246, 0x00, 0x07}, - }; - struct sc_reg_access amic[] = { - {0x248, 0x00, 0x05}, - {0x249, 0x00, 0x01}, - {0x24A, 0x00, 0x01}, - {0x247, 0x00, 0xA3}, - }; - struct sc_reg_access tx_off[] = { - {0x24F, 0x00, 0x3C}, - }; - - pr_debug("powering dn cp....\n"); - snd_msic_ops.cap_on = 0; - sst_sc_reg_access(tx_off, PMIC_READ_MODIFY, 1); - if (snd_msic_ops.input_dev_id == DMIC) - sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 3); - else - sst_sc_reg_access(amic, PMIC_READ_MODIFY, 4); - return 0; -} - -static int msic_set_selected_output_dev(u8 value) -{ - int retval = 0; - - pr_debug("msic set selected output:%d\n", value); - snd_msic_ops.output_dev_id = value; - if (snd_msic_ops.pbhs_on) - msic_power_up_pb(SND_SST_DEVICE_HEADSET); - return retval; -} - -static int msic_set_selected_input_dev(u8 value) -{ - - struct sc_reg_access sc_access_dmic[] = { - {0x24C, 0x10, 0x0}, - }; - struct sc_reg_access sc_access_amic[] = { - {0x24C, 0x76, 0x0}, - - }; - int retval = 0; - - pr_debug("msic_set_selected_input_dev:%d\n", value); - snd_msic_ops.input_dev_id = value; - switch (value) { - case AMIC: - pr_debug("Selecting AMIC1\n"); - retval = sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 1); - break; - case DMIC: - pr_debug("Selecting DMIC1\n"); - retval = sst_sc_reg_access(sc_access_dmic, PMIC_WRITE, 1); - break; - default: - return -EINVAL; - - } - if (snd_msic_ops.cap_on) - retval = msic_power_up_cp(SND_SST_DEVICE_CAPTURE); - return retval; -} - -static int msic_set_hw_dmic_route(u8 hw_ch_index) -{ - struct sc_reg_access sc_access_router; - int retval = -EINVAL; - - switch (hw_ch_index) { - case HW_CH0: - sc_access_router.reg_addr = AUDIOMUX12; - sc_access_router.value = snd_msic_ops.hw_dmic_map[0]; - sc_access_router.mask = (MASK2 | MASK1 | MASK0); - pr_debug("hw_ch0. value = 0x%x\n", - sc_access_router.value); - retval = sst_sc_reg_access(&sc_access_router, - PMIC_READ_MODIFY, 1); - break; - - case HW_CH1: - sc_access_router.reg_addr = AUDIOMUX12; - sc_access_router.value = (snd_msic_ops.hw_dmic_map[1]) << 4; - sc_access_router.mask = (MASK6 | MASK5 | MASK4); - pr_debug("### hw_ch1. value = 0x%x\n", - sc_access_router.value); - retval = sst_sc_reg_access(&sc_access_router, - PMIC_READ_MODIFY, 1); - break; - - case HW_CH2: - sc_access_router.reg_addr = AUDIOMUX34; - sc_access_router.value = snd_msic_ops.hw_dmic_map[2]; - sc_access_router.mask = (MASK2 | MASK1 | MASK0); - pr_debug("hw_ch2. value = 0x%x\n", - sc_access_router.value); - retval = sst_sc_reg_access(&sc_access_router, - PMIC_READ_MODIFY, 1); - break; - - case HW_CH3: - sc_access_router.reg_addr = AUDIOMUX34; - sc_access_router.value = (snd_msic_ops.hw_dmic_map[3]) << 4; - sc_access_router.mask = (MASK6 | MASK5 | MASK4); - pr_debug("hw_ch3. value = 0x%x\n", - sc_access_router.value); - retval = sst_sc_reg_access(&sc_access_router, - PMIC_READ_MODIFY, 1); - break; - } - - return retval; -} - - -static int msic_set_pcm_voice_params(void) -{ - return 0; -} - -static int msic_set_pcm_audio_params(int sfreq, int word_size, int num_channel) -{ - return 0; -} - -static int msic_set_audio_port(int status) -{ - return 0; -} - -static int msic_set_voice_port(int status) -{ - return 0; -} - -static int msic_set_mute(int dev_id, u8 value) -{ - return 0; -} - -static int msic_set_vol(int dev_id, int value) -{ - return 0; -} - -static int msic_get_mute(int dev_id, u8 *value) -{ - return 0; -} - -static int msic_get_vol(int dev_id, int *value) -{ - return 0; -} - -static int msic_set_headset_state(int state) -{ - struct sc_reg_access hs_enable[] = { - {0x25D, 0x03, 0x03}, - }; - - if (state) - /*enable*/ - sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1); - else { - hs_enable[0].value = 0; - sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1); - } - return 0; -} - -static int msic_enable_mic_bias(void) -{ - struct sc_reg_access jack_interrupt_reg[] = { - {0x0DB, 0x07, 0x00}, - - }; - struct sc_reg_access jack_bias_reg[] = { - {0x247, 0x0C, 0x0C}, - }; - - sst_sc_reg_access(jack_interrupt_reg, PMIC_WRITE, 1); - sst_sc_reg_access(jack_bias_reg, PMIC_READ_MODIFY, 1); - return 0; -} - -static int msic_disable_mic_bias(void) -{ - if (snd_msic_ops.jack_interrupt_status == true) - return 0; - if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on)) - msic_power_down(); - return 0; -} - -static int msic_disable_jack_btn(void) -{ - struct sc_reg_access btn_disable[] = { - {0x26C, 0x00, 0x01} - }; - - if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on)) - msic_power_down(); - snd_msic_ops.jack_interrupt_status = false; - return sst_sc_reg_access(btn_disable, PMIC_READ_MODIFY, 1); -} - -static int msic_enable_jack_btn(void) -{ - struct sc_reg_access btn_enable[] = { - {0x26b, 0x77, 0x00}, - {0x26C, 0x01, 0x00}, - }; - return sst_sc_reg_access(btn_enable, PMIC_WRITE, 2); -} -static int msic_convert_adc_to_mvolt(unsigned int mic_bias) -{ - return (ADC_ONE_LSB_MULTIPLIER * mic_bias) / 1000; -} -int msic_get_headset_state(int mic_bias) -{ - struct sc_reg_access msic_hs_toggle[] = { - {0x070, 0x00, 0x01}, - }; - if (mic_bias >= 0 && mic_bias < 400) { - - pr_debug("Detected Headphone!!!\n"); - sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1); - - } else if (mic_bias > 400 && mic_bias < 650) { - - pr_debug("Detected American headset\n"); - msic_hs_toggle[0].value = 0x01; - sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1); - - } else if (mic_bias >= 650 && mic_bias < 2000) { - - pr_debug("Detected Headset!!!\n"); - sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1); - /*power on jack and btn*/ - snd_msic_ops.jack_interrupt_status = true; - msic_enable_jack_btn(); - msic_enable_mic_bias(); - return SND_JACK_HEADSET; - - } else - pr_debug("Detected Open Cable!!!\n"); - - return SND_JACK_HEADPHONE; -} - -static int msic_get_mic_bias(void *arg) -{ - struct snd_intelmad *intelmad_drv = (struct snd_intelmad *)arg; - u16 adc_adr = intelmad_drv->adc_address; - u16 adc_val; - int ret; - struct sc_reg_access adc_ctrl3[2] = { - {0x1C2, 0x05, 0x0}, - }; - - struct sc_reg_access audio_adc_reg1 = {0,}; - struct sc_reg_access audio_adc_reg2 = {0,}; - - msic_enable_mic_bias(); - /* Enable the msic for conversion before reading */ - ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1); - if (ret) - return ret; - adc_ctrl3[0].value = 0x04; - /* Re-toggle the RRDATARD bit */ - ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1); - if (ret) - return ret; - - audio_adc_reg1.reg_addr = adc_adr; - /* Read the higher bits of data */ - msleep(1000); - ret = sst_sc_reg_access(&audio_adc_reg1, PMIC_READ, 1); - if (ret) - return ret; - pr_debug("adc read value %x", audio_adc_reg1.value); - - /* Shift bits to accomodate the lower two data bits */ - adc_val = (audio_adc_reg1.value << 2); - adc_adr++; - audio_adc_reg2. reg_addr = adc_adr; - ret = sst_sc_reg_access(&audio_adc_reg2, PMIC_READ, 1); - if (ret) - return ret; - pr_debug("adc read value %x", audio_adc_reg2.value); - - /* Adding lower two bits to the higher bits */ - audio_adc_reg2.value &= 03; - adc_val += audio_adc_reg2.value; - - pr_debug("ADC value 0x%x", adc_val); - msic_disable_mic_bias(); - return adc_val; -} - -static void msic_pmic_irq_cb(void *cb_data, u8 intsts) -{ - struct mad_jack *mjack = NULL; - unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0; - struct snd_intelmad *intelmaddata = cb_data; - int retval = 0; - - pr_debug("value returned = 0x%x\n", intsts); - - if (snd_msic_ops.card_status == SND_CARD_UN_INIT) { - retval = msic_init_card(); - if (retval) - return; - } - - mjack = &intelmaddata->jack[0]; - if (intsts & 0x1) { - pr_debug("MAD short_push detected\n"); - present = SND_JACK_BTN_0; - jack_event_flag = buttonpressflag = 1; - mjack->jack.type = SND_JACK_BTN_0; - mjack->jack.key[0] = BTN_0 ; - } - - if (intsts & 0x2) { - pr_debug(":MAD long_push detected\n"); - jack_event_flag = buttonpressflag = 1; - mjack->jack.type = present = SND_JACK_BTN_1; - mjack->jack.key[1] = BTN_1; - } - - if (intsts & 0x4) { - unsigned int mic_bias; - jack_event_flag = 1; - buttonpressflag = 0; - mic_bias = msic_get_mic_bias(intelmaddata); - pr_debug("mic_bias = %d\n", mic_bias); - mic_bias = msic_convert_adc_to_mvolt(mic_bias); - pr_debug("mic_bias after conversion = %d mV\n", mic_bias); - mjack->jack_dev_state = msic_get_headset_state(mic_bias); - mjack->jack.type = present = mjack->jack_dev_state; - } - - if (intsts & 0x8) { - mjack->jack.type = mjack->jack_dev_state; - present = 0; - jack_event_flag = 1; - buttonpressflag = 0; - msic_disable_jack_btn(); - msic_disable_mic_bias(); - } - if (jack_event_flag) - sst_mad_send_jack_report(&mjack->jack, - buttonpressflag, present); -} - - - -struct snd_pmic_ops snd_msic_ops = { - .set_input_dev = msic_set_selected_input_dev, - .set_output_dev = msic_set_selected_output_dev, - .set_lineout_dev = msic_set_selected_lineout_dev, - .set_hw_dmic_route = msic_set_hw_dmic_route, - .set_mute = msic_set_mute, - .get_mute = msic_get_mute, - .set_vol = msic_set_vol, - .get_vol = msic_get_vol, - .init_card = msic_init_card, - .set_pcm_audio_params = msic_set_pcm_audio_params, - .set_pcm_voice_params = msic_set_pcm_voice_params, - .set_voice_port = msic_set_voice_port, - .set_audio_port = msic_set_audio_port, - .power_up_pmic_pb = msic_power_up_pb, - .power_up_pmic_cp = msic_power_up_cp, - .power_down_pmic_pb = msic_power_down_pb, - .power_down_pmic_cp = msic_power_down_cp, - .power_down_pmic = msic_power_down, - .pmic_irq_cb = msic_pmic_irq_cb, - .pmic_jack_enable = msic_enable_mic_bias, - .pmic_get_mic_bias = msic_get_mic_bias, - .pmic_set_headset_state = msic_set_headset_state, -}; |