From 5e8c7c54a9b297dae0081dd19a7bb94e23040a3d Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Tue, 18 May 2010 14:51:13 +0100 Subject: linux-moblin: add 2.6.33.2 kernel from MeeGo 1.0 Signed-off-by: Joshua Lock --- ...ux-2.6.34-moorestown-audio-driver-6.0-6-8.patch | 2861 ++++++++++++++++++++ 1 file changed, 2861 insertions(+) create mode 100644 meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch') diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch new file mode 100644 index 000000000..c75fd6d28 --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch @@ -0,0 +1,2861 @@ +From 14d8fbc882908c792b3640b3f2730990539d6645 Mon Sep 17 00:00:00 2001 +From: R, Dharageswari +Date: Thu, 29 Apr 2010 20:27:36 +0530 +Subject: [PATCH] ADR-Post-Beta-0.05.002.03-6/8-Moorestown Audio Drivers: SST sound card modules + +This adds the support for vendor PMICs for widget control and configurations. +The Moorestown platform supports three different vendor implementation of PMIC. +The sound card, ie all analog components like DAC, ADC, mixer settings are +different for three vendors. This module implements these settings for each +of the vendor. +All PMIC vendors - NEC, Freescale and MAXIM are supported + +Signed-off-by: Vinod Koul + + new file: sound/pci/sst/intelmid_snd_control.h + new file: sound/pci/sst/intelmid_v0_control.c + new file: sound/pci/sst/intelmid_v1_control.c + new file: sound/pci/sst/intelmid_v2_control.c +Patch-mainline: 2.6.35? +--- + sound/pci/sst/intelmid_snd_control.h | 114 ++++ + sound/pci/sst/intelmid_v0_control.c | 813 +++++++++++++++++++++++++++ + sound/pci/sst/intelmid_v1_control.c | 846 ++++++++++++++++++++++++++++ + sound/pci/sst/intelmid_v2_control.c | 1031 ++++++++++++++++++++++++++++++++++ + 4 files changed, 2804 insertions(+), 0 deletions(-) + create mode 100644 sound/pci/sst/intelmid_snd_control.h + create mode 100644 sound/pci/sst/intelmid_v0_control.c + create mode 100644 sound/pci/sst/intelmid_v1_control.c + create mode 100644 sound/pci/sst/intelmid_v2_control.c + +diff --git a/sound/pci/sst/intelmid_snd_control.h b/sound/pci/sst/intelmid_snd_control.h +new file mode 100644 +index 0000000..0cb9eb1 +--- /dev/null ++++ b/sound/pci/sst/intelmid_snd_control.h +@@ -0,0 +1,114 @@ ++#ifndef __INTELMID_SND_CTRL_H__ ++#define __INTELMID_SND_CTRL_H__ ++/* ++ * intelmid_snd_control.h - Intel Sound card driver for MID ++ * ++ * Copyright (C) 2008-10 Intel Corporation ++ * Authors: Vinod Koul ++ * Harsha Priya ++ * Dharageswari R ++ * KP Jeeja ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * 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 defines all snd control functions ++ */ ++ ++/* ++Mask bits ++*/ ++#define MASK0 0x01 /* 0000 0001 */ ++#define MASK1 0x02 /* 0000 0010 */ ++#define MASK2 0x04 /* 0000 0100 */ ++#define MASK3 0x08 /* 0000 1000 */ ++#define MASK4 0x10 /* 0001 0000 */ ++#define MASK5 0x20 /* 0010 0000 */ ++#define MASK6 0x40 /* 0100 0000 */ ++#define MASK7 0x80 /* 1000 0000 */ ++/* ++value bits ++*/ ++#define VALUE0 0x01 /* 0000 0001 */ ++#define VALUE1 0x02 /* 0000 0010 */ ++#define VALUE2 0x04 /* 0000 0100 */ ++#define VALUE3 0x08 /* 0000 1000 */ ++#define VALUE4 0x10 /* 0001 0000 */ ++#define VALUE5 0x20 /* 0010 0000 */ ++#define VALUE6 0x40 /* 0100 0000 */ ++#define VALUE7 0x80 /* 1000 0000 */ ++ ++#define MUTE 0 /* ALSA Passes 0 for mute */ ++#define UNMUTE 1 /* ALSA Passes 1 for unmute */ ++ ++#define MAX_VOL_PMIC_VENDOR0 0x3f /* max vol in dB for stereo & voice DAC */ ++#define MIN_VOL_PMIC_VENDOR0 0 /* min vol in dB for stereo & voice DAC */ ++/* Head phone volume control */ ++#define MAX_HP_VOL_PMIC_VENDOR1 6 /* max volume in dB for HP */ ++#define MIN_HP_VOL_PMIC_VENDOR1 (-84) /* min volume in dB for HP */ ++#define MAX_HP_VOL_INDX_PMIC_VENDOR1 40 /* Number of HP volume control values */ ++ ++/* Mono Earpiece Volume control */ ++#define MAX_EP_VOL_PMIC_VENDOR1 0 /* max volume in dB for EP */ ++#define MIN_EP_VOL_PMIC_VENDOR1 (-75) /* min volume in dB for EP */ ++#define MAX_EP_VOL_INDX_PMIC_VENDOR1 32 /* Number of EP volume control values */ ++ ++int sst_sc_reg_access(struct sc_reg_access *sc_access, ++ int type, int num_val); ++extern struct snd_pmic_ops snd_pmic_ops_fs; ++extern struct snd_pmic_ops snd_pmic_ops_mx; ++extern struct snd_pmic_ops snd_pmic_ops_nc; ++ ++/* device */ ++enum SND_INPUT_DEVICE { ++ HS_MIC, ++ AMIC, ++ DMIC, ++ IN_UNDEFINED ++}; ++ ++enum SND_OUTPUT_DEVICE { ++ STEREO_HEADPHONE, ++ INTERNAL_SPKR, ++ OUT_UNDEFINED ++}; ++ ++enum SND_CARDS { ++ SND_FS = 0, ++ SND_MX, ++ SND_NC, ++}; ++ ++enum pmic_controls { ++ PMIC_SND_HP_MIC_MUTE = 0x0001, ++ PMIC_SND_AMIC_MUTE = 0x0002, ++ PMIC_SND_DMIC_MUTE = 0x0003, ++ PMIC_SND_CAPTURE_VOL = 0x0004, ++/* Output controls */ ++ PMIC_SND_LEFT_PB_VOL = 0x0010, ++ PMIC_SND_RIGHT_PB_VOL = 0x0011, ++ PMIC_SND_LEFT_HP_MUTE = 0x0012, ++ PMIC_SND_RIGHT_HP_MUTE = 0x0013, ++ PMIC_SND_LEFT_SPEAKER_MUTE = 0x0014, ++ PMIC_SND_RIGHT_SPEAKER_MUTE = 0x0015, ++/* Other controls */ ++ PMIC_SND_MUTE_ALL = 0x0020, ++ PMIC_MAX_CONTROLS = 0x0020, ++}; ++ ++#endif /* __INTELMID_SND_CTRL_H__ */ ++ ++ +diff --git a/sound/pci/sst/intelmid_v0_control.c b/sound/pci/sst/intelmid_v0_control.c +new file mode 100644 +index 0000000..3252fa5 +--- /dev/null ++++ b/sound/pci/sst/intelmid_v0_control.c +@@ -0,0 +1,813 @@ ++/* ++ * intel_sst_v0_control.c - Intel SST Driver for audio engine ++ * ++ * Copyright (C) 2008-10 Intel Corporation ++ * Authors: Vinod Koul ++ * Harsha Priya ++ * Dharageswari R ++ * KP Jeeja ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * 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 vendor 1 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "intel_sst_fw_ipc.h" ++#include "intel_sst_common.h" ++#include "intelmid_snd_control.h" ++ ++ ++enum _reg_v1 { ++ VOICEPORT1 = 0x180, ++ VOICEPORT2 = 0x181, ++ AUDIOPORT1 = 0x182, ++ AUDIOPORT2 = 0x183, ++ MISCVOICECTRL = 0x184, ++ MISCAUDCTRL = 0x185, ++ DMICCTRL1 = 0x186, ++ DMICCTRL2 = 0x187, ++ MICCTRL = 0x188, ++ MICLICTRL1 = 0x189, ++ MICLICTRL2 = 0x18A, ++ MICLICTRL3 = 0x18B, ++ VOICEDACCTRL1 = 0x18C, ++ STEREOADCCTRL = 0x18D, ++ AUD15 = 0x18E, ++ AUD16 = 0x18F, ++ AUD17 = 0x190, ++ AUD18 = 0x191, ++ RMIXOUTSEL = 0x192, ++ ANALOGLBR = 0x193, ++ ANALOGLBL = 0x194, ++ POWERCTRL1 = 0x195, ++ POWERCTRL2 = 0x196, ++ HEADSETDETECTINT = 0x197, ++ HEADSETDETECTINTMASK = 0x198, ++ TRIMENABLE = 0x199, ++}; ++ ++int rev_id = 0x20; ++ ++int fs_init_card(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {0x180, 0x00, 0x0}, ++ {0x181, 0x00, 0x0}, ++ {0x182, 0xF8, 0x0}, ++ {0x183, 0x08, 0x0}, ++ {0x184, 0x00, 0x0}, ++ {0x185, 0x40, 0x0}, ++ {0x186, 0x06, 0x0}, ++ {0x187, 0x80, 0x0}, ++ {0x188, 0x00, 0x0}, ++ {0x189, 0x39, 0x0}, ++ {0x18a, 0x39, 0x0}, ++ {0x18b, 0x1F, 0x0}, ++ {0x18c, 0x00, 0x0}, ++ {0x18d, 0x00, 0x0}, ++ {0x18e, 0x39, 0x0}, ++ {0x18f, 0x39, 0x0}, ++ {0x190, 0x39, 0x0}, ++ {0x191, 0x11, 0x0}, ++ {0x192, 0x0E, 0x0}, ++ {0x193, 0x00, 0x0}, ++ {0x194, 0x00, 0x0}, ++ {0x195, 0x06, 0x0}, ++ {0x196, 0x7F, 0x0}, ++ {0x197, 0x00, 0x0}, ++ {0x198, 0x0B, 0x0}, ++ {0x199, 0x00, 0x0}, ++ {0x037, 0x3F, 0x0}, ++ }; ++ ++ snd_pmic_ops_fs.card_status = SND_CARD_INIT_DONE; ++ return sst_sc_reg_access(sc_access, PMIC_WRITE, 27); ++} ++ ++int fs_enable_audiodac(int value) ++{ ++ struct sc_reg_access sc_access[3]; ++ sc_access[0].reg_addr = AUD16; ++ sc_access[1].reg_addr = AUD17; ++ sc_access[2].reg_addr = AUD15; ++ sc_access[0].mask = sc_access[1].mask = sc_access[2].mask = MASK7; ++ ++ if (PMIC_SND_MUTE_ALL == snd_pmic_ops_fs.mute_status ) ++ return 0; ++ if (value == MUTE) { ++ sc_access[0].value = sc_access[1].value = ++ sc_access[2].value = 0x80; ++ ++ } else { ++ sc_access[0].value = sc_access[1].value = ++ sc_access[2].value = 0x0; ++ } ++ if(snd_pmic_ops_fs.num_channel == 1) ++ sc_access[1].value = sc_access[2].value = 0x80; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3); ++ ++} ++int fs_power_up_pb(unsigned int port) ++{ ++ struct sc_reg_access sc_access[] = { ++ {POWERCTRL1, 0xC6, 0xC6}, ++ {POWERCTRL2, 0x30, 0x30}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ retval = fs_enable_audiodac(MUTE); ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ if (retval) ++ return retval; ++ ++ return fs_enable_audiodac(UNMUTE); ++} ++ ++int fs_power_up_cp(unsigned int port) ++{ ++ struct sc_reg_access sc_access[] = { ++ {POWERCTRL2, 0x02, 0x02}, /*NOTE power up A ADC only as*/ ++ /*as turning on V ADC causes noise*/ ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++} ++ ++int fs_power_down_pb(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {POWERCTRL1, 0x00, 0xC6}, ++ {POWERCTRL2, 0x00, 0x30}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ retval = fs_enable_audiodac(MUTE); ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ if (retval) ++ return retval; ++ return fs_enable_audiodac(UNMUTE); ++} ++ ++int fs_power_down(void) ++{ ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ return retval; ++} ++ ++int fs_power_down_cp(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {POWERCTRL2, 0x00, 0x03}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++} ++ ++int fs_set_pcm_voice_params(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {0x180, 0xA0, 0}, ++ {0x181, 0x04, 0}, ++ {0x182, 0x0, 0}, ++ {0x183, 0x0, 0}, ++ {0x184, 0x18, 0}, ++ {0x185, 0x40, 0}, ++ {0x186, 0x06, 0}, ++ {0x187, 0x0, 0}, ++ {0x188, 0x10, 0}, ++ {0x189, 0x39, 0}, ++ {0x18a, 0x39, 0}, ++ {0x18b, 0x02, 0}, ++ {0x18c, 0x0, 0}, ++ {0x18d, 0x0, 0}, ++ {0x18e, 0x39, 0}, ++ {0x18f, 0x0, 0}, ++ {0x190, 0x0, 0}, ++ {0x191, 0x20, 0}, ++ {0x192, 0x20, 0}, ++ {0x193, 0x0, 0}, ++ {0x194, 0x0, 0}, ++ {0x195, 0x6, 0}, ++ {0x196, 0x25, 0}, ++ {0x197, 0x0, 0}, ++ {0x198, 0xF, 0}, ++ {0x199, 0x0, 0}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ return sst_sc_reg_access(sc_access, PMIC_WRITE, 26); ++} ++ ++int fs_set_audio_port(int status) ++{ ++ struct sc_reg_access sc_access[2]; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ if (status == DEACTIVATE) { ++ /* Deactivate audio port-tristate and power */ ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK6|MASK7; ++ sc_access[0].reg_addr = AUDIOPORT1; ++ sc_access[1].value = 0x00; ++ sc_access[1].mask = MASK4|MASK5; ++ sc_access[1].reg_addr = POWERCTRL2; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ } else if (status == ACTIVATE) { ++ /* activate audio port */ ++ sc_access[0].value = 0xC0; ++ sc_access[0].mask = MASK6|MASK7; ++ sc_access[0].reg_addr = AUDIOPORT1; ++ sc_access[1].value = 0x30; ++ sc_access[1].mask = MASK4|MASK5; ++ sc_access[1].reg_addr = POWERCTRL2; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ } else ++ return -EINVAL; ++} ++ ++int fs_set_voice_port(int status) ++{ ++ struct sc_reg_access sc_access[2]; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ if (status == DEACTIVATE) { ++ /* Deactivate audio port-tristate and power */ ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK6|MASK7; ++ sc_access[0].reg_addr = VOICEPORT1; ++ sc_access[1].value = 0x00; ++ sc_access[1].mask = MASK0|MASK1; ++ sc_access[1].reg_addr = POWERCTRL2; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ } else if (status == ACTIVATE) { ++ /* activate audio port */ ++ sc_access[0].value = 0xC0; ++ sc_access[0].mask = MASK6|MASK7; ++ sc_access[0].reg_addr = VOICEPORT1; ++ sc_access[1].value = 0x03; ++ sc_access[1].mask = MASK0|MASK1; ++ sc_access[1].reg_addr = POWERCTRL2; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ } else ++ return -EINVAL; ++} ++ ++int fs_set_pcm_audio_params(int sfreq, int word_size, int num_channel) ++{ ++ u8 config1 = 0; ++ struct sc_reg_access sc_access[4]; ++ int retval = 0, num_value = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ switch (sfreq) { ++ case 8000: ++ config1 = 0x00; ++ break; ++ case 11025: ++ config1 = 0x01; ++ break; ++ case 12000: ++ config1 = 0x02; ++ break; ++ case 16000: ++ config1 = 0x03; ++ break; ++ case 22050: ++ config1 = 0x04; ++ break; ++ case 24000: ++ config1 = 0x05; ++ break; ++ case 26000: ++ config1 = 0x06; ++ break; ++ case 32000: ++ config1 = 0x07; ++ break; ++ case 44100: ++ config1 = 0x08; ++ break; ++ case 48000: ++ config1 = 0x09; ++ break; ++ } ++ snd_pmic_ops_fs.num_channel = num_channel; ++ if(snd_pmic_ops_fs.num_channel == 1) ++ { ++ sc_access[0].reg_addr = AUD17; ++ sc_access[1].reg_addr = AUD15; ++ sc_access[0].mask = sc_access[1].mask = MASK7; ++ sc_access[0].value = sc_access[1].value = 0x80; ++ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ } ++ else ++ { ++ sc_access[0].reg_addr = AUD17; ++ sc_access[1].reg_addr = AUD15; ++ sc_access[0].mask = sc_access[1].mask = MASK7; ++ sc_access[0].value = sc_access[1].value = 0x00; ++ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ } ++ printk(KERN_DEBUG "SST DBG:sfreq:%d, +\ ++ Register value = %x\n", sfreq, config1); ++ ++ if (word_size == 24) { ++ sc_access[0].reg_addr = AUDIOPORT1; ++ sc_access[0].mask = MASK0|MASK1|MASK2|MASK3; ++ sc_access[0].value = 0xFB; ++ ++ ++ sc_access[1].reg_addr = AUDIOPORT2; ++ sc_access[1].value = config1 |0x10; ++ sc_access[1].mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6; ++ ++ sc_access[2].reg_addr = MISCAUDCTRL; ++ sc_access[2].value = 0x02; ++ sc_access[2].mask = 0x02; ++ ++ num_value = 3 ; ++ ++ } else { ++ ++ sc_access[0].reg_addr = AUDIOPORT2; ++ sc_access[0].value = config1; ++ sc_access[0].mask = MASK0|MASK1|MASK2|MASK3; ++ ++ sc_access[1].reg_addr = MISCAUDCTRL; ++ sc_access[1].value = 0x00; ++ sc_access[1].mask = 0x02; ++ num_value = 2; ++ } ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_value); ++ ++} ++ ++int fs_set_selected_input_dev(u8 value) ++{ ++ struct sc_reg_access sc_access_dmic[] = { ++ {MICCTRL, 0x81, 0xf7}, ++ {MICLICTRL3, 0x00, 0xE0}, ++ }; ++ struct sc_reg_access sc_access_mic[] = { ++ {MICCTRL, 0x10, MASK2|MASK4|MASK5|MASK6|MASK7}, ++ {MICLICTRL3, 0x00, 0xE0}, ++ }; ++ struct sc_reg_access sc_access_hsmic[] = { ++ {MICCTRL, 0x40, MASK2|MASK4|MASK5|MASK6|MASK7}, ++ {MICLICTRL3, 0x00, 0xE0}, ++ }; ++ ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (value) { ++ case AMIC: ++ printk(KERN_DEBUG "SST DBG:Selecting amic not supported in mono cfg\n"); ++ return sst_sc_reg_access(sc_access_mic, PMIC_READ_MODIFY, 2); ++ break; ++ ++ case HS_MIC: ++ printk(KERN_DEBUG "SST DBG:Selecting hsmic\n"); ++ return sst_sc_reg_access(sc_access_hsmic, ++ PMIC_READ_MODIFY, 2); ++ break; ++ ++ case DMIC: ++ printk(KERN_DEBUG "SST DBG:Selecting dmic\n"); ++ return sst_sc_reg_access(sc_access_dmic, PMIC_READ_MODIFY, 2); ++ break; ++ ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ rcvd illegal request \n"); ++ return -EINVAL; ++ ++ } ++} ++ ++int fs_set_selected_output_dev(u8 value) ++{ ++ struct sc_reg_access sc_access_hp[] = { ++ {0x191, 0x11, 0x0}, ++ {0x192, 0x0E, 0x0}, ++ {0x195, 0x06, 0x0}, ++ {0x196, 0x7E, 0x0}, ++ }; ++ struct sc_reg_access sc_access_is[] = { ++ {0x191, 0x17, 0xFF}, ++ {0x192, 0x08, 0xFF}, ++ {0x195, 0xC0, 0xFF}, ++ {0x196, 0x12, 0x12}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (value) { ++ case STEREO_HEADPHONE: ++ printk(KERN_DEBUG "SST DBG:Selecting headphone \n"); ++ return sst_sc_reg_access(sc_access_hp, PMIC_WRITE, 4); ++ break; ++ ++ case INTERNAL_SPKR: ++ printk(KERN_DEBUG "SST DBG:Selecting internal spkr\n"); ++ return sst_sc_reg_access(sc_access_is, PMIC_READ_MODIFY, 4); ++ break; ++ ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ rcvd illegal request \n"); ++ return -EINVAL; ++ ++ } ++} ++ ++int fs_set_mute(int dev_id, u8 value) ++{ ++ struct sc_reg_access sc_access[6] = {{0,},}; ++ int reg_num = 0; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ ++ snd_pmic_ops_fs.mute_status = dev_id; ++ ++ printk(KERN_DEBUG "SST DBG:dev_id:0x%x value:0x%x\n", dev_id, value); ++ switch (dev_id) { ++ case PMIC_SND_DMIC_MUTE: ++ sc_access[0].reg_addr = MICCTRL; ++ sc_access[1].reg_addr = MICLICTRL1; ++ sc_access[2].reg_addr = MICLICTRL2; ++ sc_access[0].mask = MASK5; ++ sc_access[1].mask = sc_access[2].mask = MASK6; ++ if (value == MUTE) { ++ sc_access[0].value = 0x20; ++ sc_access[2].value = sc_access[1].value = 0x40; ++ } else ++ sc_access[0].value = sc_access[1].value ++ = sc_access[2].value = 0x0; ++ reg_num = 3; ++ break; ++ case PMIC_SND_HP_MIC_MUTE: ++ case PMIC_SND_AMIC_MUTE: ++ sc_access[0].reg_addr = MICLICTRL1; ++ sc_access[1].reg_addr = MICLICTRL2; ++ sc_access[0].mask = sc_access[1].mask = MASK6; ++ if (value == MUTE) ++ sc_access[0].value = sc_access[1].value = 0x40; ++ else ++ sc_access[0].value = sc_access[1].value = 0x0; ++ reg_num = 2; ++ break; ++ case PMIC_SND_LEFT_SPEAKER_MUTE: ++ case PMIC_SND_LEFT_HP_MUTE: ++ sc_access[0].reg_addr = AUD16; ++ sc_access[1].reg_addr = AUD15; ++ ++ sc_access[0].mask = sc_access[1].mask = MASK7; ++ if (value == MUTE) ++ sc_access[0].value = sc_access[1].value = 0x80; ++ else ++ sc_access[0].value = sc_access[1].value = 0x0; ++ reg_num = 2; ++ break; ++ case PMIC_SND_RIGHT_HP_MUTE: ++ case PMIC_SND_RIGHT_SPEAKER_MUTE: ++ sc_access[0].reg_addr = AUD17; ++ sc_access[1].reg_addr = AUD15; ++ sc_access[0].mask = sc_access[1].mask = MASK7; ++ if (value == MUTE) ++ sc_access[0].value = sc_access[1].value = 0x80; ++ else ++ sc_access[0].value = sc_access[1].value = 0x0; ++ if(snd_pmic_ops_fs.num_channel == 1) ++ sc_access[0].value = sc_access[1].value = 0x80; ++ reg_num = 2; ++ break; ++ case PMIC_SND_MUTE_ALL: ++ sc_access[0].reg_addr = AUD16; ++ sc_access[1].reg_addr = AUD17; ++ sc_access[2].reg_addr = AUD15; ++ sc_access[3].reg_addr = MICCTRL; ++ sc_access[4].reg_addr = MICLICTRL1; ++ sc_access[5].reg_addr = MICLICTRL2; ++ sc_access[0].mask = sc_access[1].mask = ++ sc_access[2].mask = MASK7; ++ sc_access[3].mask = MASK5; ++ sc_access[4].mask = sc_access[5].mask = MASK6; ++ ++ if (value == MUTE) { ++ sc_access[0].value = ++ sc_access[1].value = sc_access[2].value = 0x80; ++ sc_access[3].value = 0x20; ++ sc_access[4].value = sc_access[5].value = 0x40; ++ ++ } else { ++ sc_access[0].value = sc_access[1].value = ++ sc_access[2].value = sc_access[3].value = ++ sc_access[4].value = sc_access[5].value = 0x0; ++ } ++ if(snd_pmic_ops_fs.num_channel == 1) ++ sc_access[1].value = sc_access[2].value = 0x80; ++ reg_num = 6; ++ break; ++ ++ } ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, reg_num); ++} ++ ++int fs_set_vol(int dev_id, u8 value) ++{ ++ struct sc_reg_access sc_acces, sc_access[4] = {{0},}; ++ int reg_num = 0; ++ int retval = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (dev_id) { ++ case PMIC_SND_LEFT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_LEFT_PB_VOL:%d \n", value); ++ sc_access[0].value = sc_access[1].value = value; ++ sc_access[0].reg_addr = AUD16; ++ sc_access[1].reg_addr = AUD15; ++ sc_access[0].mask = sc_access[1].mask = ++ (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); ++ reg_num = 2; ++ break; ++ ++ case PMIC_SND_RIGHT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_PB_VOL:%d \n", value); ++ sc_access[0].value = sc_access[1].value = value; ++ sc_access[0].reg_addr = AUD17; ++ sc_access[1].reg_addr = AUD15; ++ sc_access[0].mask = sc_access[1].mask = ++ (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); ++ if(snd_pmic_ops_fs.num_channel == 1) { ++ sc_access[0].value = sc_access[1].value = 0x80; ++ sc_access[0].mask = sc_access[1].mask = MASK7; ++ } ++ reg_num = 2; ++ break; ++ ++ case PMIC_SND_CAPTURE_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_CAPTURE_VOL:%d \n", value); ++ sc_access[0].reg_addr = MICLICTRL1; ++ sc_access[1].reg_addr = MICLICTRL2; ++ sc_access[2].reg_addr = DMICCTRL1; ++ sc_access[2].value = 0x3F - value; ++ sc_access[0].value = sc_access[1].value = value; ++ sc_acces.reg_addr = MICLICTRL3; ++ sc_acces.value = value; ++ sc_acces.mask = (MASK0|MASK1|MASK2|MASK3|MASK5|MASK6|MASK7); ++ retval = sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1); ++ sc_access[0].mask = sc_access[1].mask = ++ sc_access[2].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); ++ reg_num = 3; ++ break; ++ ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ rcvd illegal request \n"); ++ return -EINVAL; ++ } ++ ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, reg_num); ++} ++ ++int fs_get_mute(int dev_id, u8 *value) ++{ ++ struct sc_reg_access sc_access[6] = {{0,},}; ++ ++ int retval = 0, temp_value = 0, mask = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (dev_id) { ++ ++ case PMIC_SND_AMIC_MUTE: ++ case PMIC_SND_HP_MIC_MUTE: ++ sc_access[0].reg_addr = MICLICTRL1; ++ mask = MASK6; ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, 1); ++ if (sc_access[0].value & mask) ++ *value = MUTE; ++ else ++ *value = UNMUTE; ++ break; ++ case PMIC_SND_DMIC_MUTE: ++ sc_access[0].reg_addr = MICCTRL; ++ mask = MASK5; ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, 1); ++ temp_value = (sc_access[0].value & mask); ++ if (temp_value == 0) ++ *value = UNMUTE; ++ else ++ *value = MUTE; ++ break; ++ ++ case PMIC_SND_LEFT_HP_MUTE: ++ case PMIC_SND_LEFT_SPEAKER_MUTE: ++ sc_access[0].reg_addr = AUD16; ++ mask = MASK7; ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, 1); ++ temp_value = sc_access[0].value & mask; ++ if (temp_value == 0) ++ *value = UNMUTE; ++ else ++ *value = MUTE; ++ break; ++ case PMIC_SND_RIGHT_HP_MUTE: ++ case PMIC_SND_RIGHT_SPEAKER_MUTE: ++ sc_access[0].reg_addr = AUD17; ++ mask = MASK7; ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, 1); ++ temp_value = sc_access[0].value & mask; ++ if (temp_value == 0) ++ *value = UNMUTE; ++ else ++ *value = MUTE; ++ break; ++ case PMIC_SND_MUTE_ALL: ++ sc_access[0].reg_addr = AUD15; ++ sc_access[1].reg_addr = AUD16; ++ sc_access[2].reg_addr = AUD17; ++ sc_access[3].reg_addr = MICCTRL; ++ sc_access[4].reg_addr = MICLICTRL1; ++ sc_access[5].reg_addr = MICLICTRL2; ++ sc_access[0].mask = sc_access[1].mask = ++ sc_access[2].mask = MASK7; ++ sc_access[3].mask = MASK5; ++ sc_access[4].mask = sc_access[5].mask = MASK6; ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, 6); ++ if (((sc_access[0].value & sc_access[0].mask) == ++ sc_access[0].mask) ++ && ((sc_access[1].value & sc_access[1].mask) == ++ sc_access[1].mask) ++ && ((sc_access[2].value & sc_access[2].mask) == ++ sc_access[2].mask) ++ && ((sc_access[3].value & sc_access[3].mask) == ++ sc_access[3].mask) ++ && ((sc_access[4].value & sc_access[4].mask) == ++ sc_access[4].mask) ++ && ((sc_access[5].value & sc_access[5].mask) == ++ sc_access[5].mask)) ++ *value = MUTE; ++ else ++ *value = UNMUTE; ++ break; ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ rcvd illegal request \n"); ++ return -EINVAL; ++ } ++ ++ return retval; ++} ++ ++int fs_get_vol(int dev_id, u8 *value) ++{ ++ struct sc_reg_access sc_access = {0,}; ++ int retval = 0, mask = 0; ++ ++ if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT) ++ retval = fs_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (dev_id) { ++ case PMIC_SND_CAPTURE_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_CAPTURE_VOL\n"); ++ sc_access.reg_addr = MICLICTRL1; ++ mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0); ++ break; ++ case PMIC_SND_LEFT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_LEFT_PB_VOL\n"); ++ sc_access.reg_addr = AUD16; ++ mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0); ++ break; ++ case PMIC_SND_RIGHT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_LEFT_PB_VOL\n"); ++ sc_access.reg_addr = AUD17; ++ mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0); ++ break; ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ rcvd illegal request \n"); ++ return -EINVAL; ++ } ++ ++ retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1); ++ printk(KERN_DEBUG "SST DBG:value read = 0x%x\n", sc_access.value); ++ *value = (sc_access.value) & mask; ++ printk(KERN_DEBUG "SST DBG:value returned = 0x%x\n", *value); ++ return retval; ++} ++ ++struct snd_pmic_ops snd_pmic_ops_fs = { ++ .set_input_dev = fs_set_selected_input_dev, ++ .set_output_dev = fs_set_selected_output_dev, ++ .set_mute = fs_set_mute, ++ .get_mute = fs_get_mute, ++ .set_vol = fs_set_vol, ++ .get_vol = fs_get_vol, ++ .init_card = fs_init_card, ++ .set_pcm_audio_params = fs_set_pcm_audio_params, ++ .set_pcm_voice_params = fs_set_pcm_voice_params, ++ .set_voice_port = fs_set_voice_port, ++ .set_audio_port = fs_set_audio_port, ++ .power_up_pmic_pb = fs_power_up_pb, ++ .power_up_pmic_cp = fs_power_up_cp, ++ .power_down_pmic_pb = fs_power_down_pb, ++ .power_down_pmic_cp = fs_power_down_cp, ++ .power_down_pmic = fs_power_down, ++}; +diff --git a/sound/pci/sst/intelmid_v1_control.c b/sound/pci/sst/intelmid_v1_control.c +new file mode 100644 +index 0000000..740ffaf +--- /dev/null ++++ b/sound/pci/sst/intelmid_v1_control.c +@@ -0,0 +1,846 @@ ++/* ++ * intel_sst_v1_control.c - Intel SST Driver for audio engine ++ * ++ * Copyright (C) 2008-10 Intel Corp ++ * Authors: Vinod Koul ++ * Harsha Priya ++ * Dharageswari R ++ * KP Jeeja ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * 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 vendor 2 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "intel_sst_fw_ipc.h" ++#include "intel_sst_common.h" ++#include "intelmid_snd_control.h" ++ ++enum _reg_v2 { ++ ++ MASTER_CLOCK_PRESCALAR = 0x205, ++ SET_MASTER_AND_LR_CLK1 = 0x20b, ++ SET_MASTER_AND_LR_CLK2 = 0x20c, ++ MASTER_MODE_AND_DATA_DELAY = 0x20d, ++ DIGITAL_INTERFACE_TO_DAI2 = 0x20e, ++ CLK_AND_FS1 = 0x208, ++ CLK_AND_FS2 = 0x209, ++ DAI2_TO_DAC_HP = 0x210, ++ HP_OP_SINGLE_ENDED = 0x224, ++ ENABLE_OPDEV_CTRL = 0x226, ++ ENABLE_DEV_AND_USE_XTAL = 0x227, ++ ++ /* Max audio subsystem (PQ49) MAX 8921 */ ++ AS_IP_MODE_CTL = 0xF9, ++ AS_LEFT_SPKR_VOL_CTL = 0xFA, /* Mono Earpiece volume control */ ++ AS_RIGHT_SPKR_VOL_CTL = 0xFB, ++ AS_LEFT_HP_VOL_CTL = 0xFC, ++ AS_RIGHT_HP_VOL_CTL = 0xFD, ++ AS_OP_MIX_CTL = 0xFE, ++ AS_CONFIG = 0xFF, ++ ++ /* Headphone volume control & mute registers */ ++ VOL_CTRL_LT = 0x21c, ++ VOL_CTRL_RT = 0x21d, ++ ++}; ++ ++int mx_init_card(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {0x200, 0x80, 0x00}, ++ {0x201, 0xC0, 0x00}, ++ {0x202, 0x00, 0x00}, ++ {0x203, 0x00, 0x00}, ++ {0x204, 0x02, 0x00}, ++ {0x205, 0x10, 0x00}, ++ {0x206, 0x60, 0x00}, ++ {0x207, 0x00, 0x00}, ++ {0x208, 0x90, 0x00}, ++ {0x209, 0x51, 0x00}, ++ {0x20a, 0x00, 0x00}, ++ {0x20b, 0x10, 0x00}, ++ {0x20c, 0x00, 0x00}, ++ {0x20d, 0x00, 0x00}, ++ {0x20e, 0x11, 0x00}, ++ {0x20f, 0x00, 0x00}, ++ {0x210, 0x84, 0x00}, ++ {0x211, 0xB3, 0x00}, ++ {0x212, 0x00, 0x00}, ++ {0x213, 0x00, 0x00}, ++ {0x214, 0x41, 0x00}, ++ {0x215, 0x00, 0x00}, ++ {0x216, 0x00, 0x00}, ++ {0x217, 0x00, 0x00}, ++ {0x218, 0x03, 0x00}, ++ {0x219, 0x03, 0x00}, ++ {0x21a, 0x00, 0x00}, ++ {0x21b, 0x00, 0x00}, ++ {0x21c, 0x09, 0x00}, ++ {0x21d, 0x09, 0x00}, ++ {0x21e, 0x00, 0x00}, ++ {0x21f, 0x00, 0x00}, ++ {0x220, 0x54, 0x00}, ++ {0x221, 0x54, 0x00}, ++ {0x222, 0x50, 0x00}, ++ {0x223, 0x00, 0x00}, ++ {0x224, 0x04, 0x00}, ++ {0x225, 0x80, 0x00}, ++ {0x226, 0x0F, 0x00}, ++ {0x227, 0x08, 0x00}, ++ {0xf9, 0x40, 0x00}, ++ {0xfa, 0x1f, 0x00}, ++ {0xfb, 0x1f, 0x00}, ++ {0xfc, 0x1f, 0x00}, ++ {0xfd, 0x1f, 0x00}, ++ {0xfe, 0x00, 0x00}, ++ {0xff, 0x0c, 0x00}, ++ }; ++ snd_pmic_ops_mx.card_status = SND_CARD_INIT_DONE; ++ snd_pmic_ops_mx.num_channel = 2; ++ return sst_sc_reg_access(sc_access, PMIC_WRITE, 47); ++} ++ ++ ++ ++int mx_enable_audiodac(int value) ++{ ++ struct sc_reg_access sc_access[3]; ++ int mute_val = 0; ++ int mute_val1 = 0; ++ u8 vol_value; ++ ++ sc_access[0].reg_addr = AS_LEFT_HP_VOL_CTL; ++ sc_access[1].reg_addr = AS_RIGHT_HP_VOL_CTL; ++ ++ ++ if (value == UNMUTE) { ++ ++ mute_val = 0x1f; ++ mute_val1 = 0x00; ++ ++ } else { ++ ++ mute_val = 0x00; ++ mute_val1 = 0x40; ++ ++ } ++ ++ ++ sc_access[0].mask = sc_access[1].mask = MASK0|MASK1|MASK2|MASK3|MASK4; ++ sc_access[0].value = sc_access[1].value = mute_val; ++ ++ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ sc_access[0].reg_addr = VOL_CTRL_LT; ++ sc_access[1].reg_addr = VOL_CTRL_RT; ++ sc_access[0].mask = sc_access[1].mask = MASK6; ++ sc_access[0].value = sc_access[1].value = mute_val1; ++ if ( snd_pmic_ops_mx.num_channel == 1) ++ sc_access[1].value = 0x40; ++ ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ ++ ++} ++int mx_power_up_pb(unsigned int port) ++{ ++ ++ int retval = 0; ++ struct sc_reg_access sc_access[3]; ++ ++ ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ ++ ++ retval = mx_enable_audiodac(MUTE); ++ ++ mdelay(10); ++ ++ sc_access[0].reg_addr = AS_CONFIG; ++ sc_access[0].mask = MASK7; ++ sc_access[0].value = 0x80; ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ ++ ++ ++ sc_access[0].reg_addr = ENABLE_OPDEV_CTRL; ++ sc_access[0].mask = MASK3|MASK2; ++ sc_access[0].value = 0x0C; ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL; ++ sc_access[0].mask = MASK7|MASK3; ++ sc_access[0].value = 0x88; ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ ++ ++ ++ retval = mx_enable_audiodac(UNMUTE); ++ ++ return retval; ++ ++} ++ ++int mx_power_up_cp(unsigned int port) ++{ ++ struct sc_reg_access sc_access[] = { ++ {0x226, 0x03, MASK1|MASK0}, ++ {0x227, 0x88, MASK7|MASK3}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++} ++ ++int mx_power_down_pb(void) ++{ ++ ++ struct sc_reg_access sc_access[3]; ++ int retval = 0; ++ ++ ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ retval = mx_enable_audiodac(MUTE); ++ ++ ++ sc_access[0].reg_addr = ENABLE_OPDEV_CTRL; ++ sc_access[0].mask = MASK3|MASK2; ++ sc_access[0].value = 0x00; ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ ++ ++ retval = mx_enable_audiodac(UNMUTE); ++ ++ return retval; ++ ++ ++} ++ ++int mx_power_down_cp(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {0x226, 0x00, MASK1|MASK0}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ ++} ++ ++int mx_power_down(void) ++{ ++ int retval = 0; ++ struct sc_reg_access sc_access[3]; ++ ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ ++ retval = mx_enable_audiodac(MUTE); ++ ++ sc_access[0].reg_addr = AS_CONFIG; ++ sc_access[0].mask = MASK7; ++ sc_access[0].value = 0x00; ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ ++ sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL; ++ sc_access[0].mask = MASK7; ++ sc_access[0].value = 0x00; ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ ++ retval = mx_enable_audiodac(UNMUTE); ++ ++ return retval; ++ ++ ++} ++ ++int mx_set_voice_port(int status) ++{ ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ return retval; ++} ++ ++int mx_set_audio_port(int status) ++{ ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ return retval; ++} ++int mx_set_pcm_voice_params(void) ++{ ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ return retval; ++} ++ ++int mx_set_pcm_audio_params(int sfreq, int word_size , int num_channel) ++{ ++ int config1 = 0, config2 = 0, filter = 0xB3; ++ struct sc_reg_access sc_access[5]; ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ ++ switch (sfreq) { ++ case 8000: ++ config1 = 0x10; ++ config2 = 0x00; ++ filter = 0x33; ++ break; ++ case 11025: ++ config1 = 0x16; ++ config2 = 0x0d; ++ break; ++ case 12000: ++ config1 = 0x18; ++ config2 = 0x00; ++ break; ++ case 16000: ++ config1 = 0x20; ++ config2 = 0x00; ++ break; ++ case 22050: ++ config1 = 0x2c; ++ config2 = 0x1a; ++ break; ++ case 24000: ++ config1 = 0x30; ++ config2 = 0x00; ++ break; ++ case 32000: ++ config1 = 0x40; ++ config2 = 0x00; ++ break; ++ case 44100: ++ config1 = 0x58; ++ config2 = 0x33; ++ break; ++ case 48000: ++ config1 = 0x60; ++ config2 = 0x00; ++ break; ++ } ++ ++ snd_pmic_ops_mx.num_channel = num_channel; ++ /*mute the right channel if MONO*/ ++ if(snd_pmic_ops_mx.num_channel == 1) ++ { ++ ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ sc_access[0].value = 0x40; ++ sc_access[0].mask = MASK6; ++ ++ sc_access[1].reg_addr = 0x224; ++ sc_access[1].value = 0x05; ++ sc_access[1].mask = MASK0|MASK1|MASK2; ++ ++ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ } ++ else ++ { ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK6; ++ ++ sc_access[1].reg_addr = 0x224; ++ sc_access[1].value = 0x04; ++ sc_access[1].mask = MASK0|MASK1|MASK2; ++ ++ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ } ++ sc_access[0].reg_addr = 0x206; ++ sc_access[0].value = config1; ++ sc_access[1].reg_addr = 0x207; ++ sc_access[1].value = config2; ++ ++ if (word_size == 16) { ++ sc_access[2].value = 0x51; ++ sc_access[3].value = 0x31; ++ } ++ else if (word_size == 24) { ++ sc_access[2].value =0x52; ++ sc_access[3].value = 0x92; ++ ++ } ++ ++ sc_access[2].reg_addr = 0x209; ++ sc_access[3].reg_addr = 0x20e; ++ ++ sc_access[4].reg_addr = 0x211; ++ sc_access[4].value = filter; ++ ++ sst_sc_reg_access(sc_access, PMIC_WRITE, 5); ++ ++ return 0; ++} ++ ++int mx_set_selected_output_dev(u8 dev_id) ++{ ++ struct sc_reg_access sc_access[6]; ++ int num_reg = 0; ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ printk(KERN_DEBUG "SST DBG:mx_set_selected_output_dev +\ ++ dev_id:0x%x\n", dev_id); ++ switch (dev_id) { ++ case STEREO_HEADPHONE: ++ sc_access[0].reg_addr = 0x226; ++ sc_access[0].value = 0x0C; ++ sc_access[0].mask = 0x3F; ++ ++ /*sc_access[3].reg_addr = 0xFA; ++ sc_access[3].value = 0x00; ++ sc_access[3].mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6|MASK7; ++ ++ sc_access[5].reg_addr = 0xFB; ++ sc_access[5].value = 0x00; ++ sc_access[5].mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6|MASK7; ++ ++ ++ sc_access[1].reg_addr = 0xFC; ++ sc_access[1].value = 0x1F; ++ sc_access[1].mask = 0x1F; ++ ++ sc_access[4].reg_addr = 0xFD; ++ sc_access[4].value = 0x1F; ++ sc_access[4].mask = 0x1F; */ ++ ++ sc_access[1].reg_addr = 0xFF; ++ sc_access[1].value = 0x0C; ++ sc_access[1].mask = MASK2|MASK3|MASK5|MASK6|MASK4; ++ ++ num_reg = 2; ++ break; ++ case INTERNAL_SPKR: ++ sc_access[0].reg_addr = 0x226; ++ sc_access[0].value = 0x3F; ++ sc_access[0].mask = 0x3F; ++ ++ ++ /*sc_access[1].reg_addr = 0xFA; ++ sc_access[1].value = 0x1F; ++ sc_access[1].mask = 0x1F; ++ ++ sc_access[2].reg_addr = 0xFB; ++ sc_access[2].value = 0x1F; ++ sc_access[2].mask = 0x1F; ++ ++ sc_access[3].reg_addr = 0xFC; ++ sc_access[3].value = 0x00; ++ sc_access[3].mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6|MASK7; ++ ++ ++ ++ sc_access[4].reg_addr = 0xFD; ++ sc_access[4].value = 0x00; ++ sc_access[4].mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6|MASK7; */ ++ ++ sc_access[1].reg_addr = 0xFF; ++ sc_access[1].value = 0x30; ++ sc_access[1].mask = MASK2|MASK3|MASK5|MASK6|MASK4; ++ ++ num_reg = 2; ++ break; ++ } ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg); ++} ++ ++int mx_set_selected_input_dev(u8 dev_id) ++{ ++ struct sc_reg_access sc_access[2]; ++ int num_reg = 0; ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ snd_pmic_ops_mx.input_dev_id = dev_id; ++ printk(KERN_DEBUG "SST DBG:mx_set_selected_input_+\ ++ dev dev_id:0x%x\n", dev_id); ++ ++ switch (dev_id) { ++ case AMIC: ++ sc_access[0].reg_addr = 0x223; ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0; ++ sc_access[1].reg_addr = 0x222; ++ sc_access[1].value = 0x50; ++ sc_access[1].mask = MASK7|MASK6|MASK5|MASK4; ++ num_reg = 2; ++ break; ++ ++ case HS_MIC: ++ sc_access[0].reg_addr = 0x223; ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0; ++ sc_access[1].reg_addr = 0x222; ++ sc_access[1].value = 0x70; ++ sc_access[1].mask = MASK7|MASK6|MASK5|MASK4; ++ num_reg = 2; ++ break; ++ case DMIC: ++ sc_access[1].reg_addr = 0x222; ++ sc_access[1].value = 0x00; ++ sc_access[1].mask = MASK7|MASK6|MASK5|MASK4|MASK0; ++ sc_access[0].reg_addr = 0x223; ++ sc_access[0].value = 0x20; ++ sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0; ++ num_reg = 2; ++ break; ++ } ++ return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg); ++} ++ ++int mx_set_mute(int dev_id, u8 value) ++{ ++ struct sc_reg_access sc_access[5], sc_acces; ++ int num_reg = 0; ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ ++ ++ printk(KERN_DEBUG "SST DBG:mx_set_mute +\ ++ dev_id:0x%x , value:%d \n", dev_id, value); ++ ++ switch (dev_id) { ++ case PMIC_SND_DMIC_MUTE: ++ case PMIC_SND_AMIC_MUTE: ++ case PMIC_SND_HP_MIC_MUTE: ++ sc_access[0].reg_addr = 0x220; ++ sc_access[1].reg_addr = 0x221; ++ sc_access[2].reg_addr = 0x223; ++ if (value == MUTE) { ++ sc_access[0].value = 0x00; ++ sc_access[1].value = 0x00; ++ if (snd_pmic_ops_mx.input_dev_id == DMIC) ++ sc_access[2].value = 0x00; ++ else ++ sc_access[2].value = 0x20; ++ } else { ++ sc_access[0].value = 0x20; ++ sc_access[1].value = 0x20; ++ if (snd_pmic_ops_mx.input_dev_id == DMIC) ++ sc_access[2].value = 0x20; ++ else ++ sc_access[2].value = 0x00; ++ } ++ sc_access[0].mask = MASK5|MASK6; ++ sc_access[1].mask = MASK5|MASK6; ++ sc_access[2].mask = MASK5|MASK6; ++ num_reg = 3; ++ break; ++ case PMIC_SND_LEFT_SPEAKER_MUTE: ++ case PMIC_SND_LEFT_HP_MUTE: ++ sc_access[0].reg_addr = VOL_CTRL_LT; ++ if (value == MUTE) ++ sc_access[0].value = 0x40; ++ else ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK6; ++ num_reg = 1; ++ break; ++ case PMIC_SND_RIGHT_SPEAKER_MUTE: ++ case PMIC_SND_RIGHT_HP_MUTE: ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ if(snd_pmic_ops_mx.num_channel == 1) ++ value = MUTE; ++ if (value == MUTE) ++ sc_access[0].value = 0x40; ++ else ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK6; ++ num_reg = 1; ++ break; ++ ++ case PMIC_SND_MUTE_ALL: ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ sc_access[1].reg_addr = VOL_CTRL_LT; ++ sc_access[2].reg_addr = 0x220; ++ sc_access[3].reg_addr = 0x221; ++ sc_access[4].reg_addr = 0x223; ++ if (value == MUTE) { ++ sc_access[0].value = sc_access[1].value = 0x40; ++ sc_access[2].value = 0x00; ++ sc_access[3].value = 0x00; ++ sc_acces.reg_addr = 0x222; ++ sc_acces.value = 0x00; ++ sc_acces.mask = MASK4|MASK5|MASK6|MASK7; ++ sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1); ++ sc_access[4].value = 0x00; ++ ++ } else { ++ sc_access[0].value = sc_access[1].value = 0x00; ++ sc_access[2].value = 0x20; ++ sc_access[3].value = 0x20; ++ sc_access[4].value = 0x20; ++ } ++ if(snd_pmic_ops_mx.num_channel == 1) ++ sc_access[0].value = 0x40; ++ sc_access[0].mask = sc_access[1].mask = MASK6; ++ sc_access[2].mask = MASK5|MASK6; ++ sc_access[3].mask = MASK5|MASK6|MASK2|MASK4; ++ sc_access[4].mask = MASK5|MASK6; ++ num_reg = 5; ++ break; ++ } ++ ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg); ++} ++ ++int mx_set_vol(int dev_id, u8 value) ++{ ++ struct sc_reg_access sc_access[2] = {{0},}; ++ int num_reg = 0; ++ int retval = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ printk(KERN_DEBUG "SST DBG:mx_set_vol dev_id:0x%x , \ ++ value:%d \n", dev_id, value); ++ switch (dev_id) { ++ case PMIC_SND_CAPTURE_VOL: ++ sc_access[0].reg_addr = 0x220; ++ sc_access[1].reg_addr = 0x221; ++ sc_access[0].value = sc_access[1].value = -value; ++ sc_access[0].mask = sc_access[1].mask = ++ (MASK0|MASK1|MASK2|MASK3|MASK4); ++ num_reg = 2; ++ break; ++ case PMIC_SND_LEFT_PB_VOL: ++ sc_access[0].value = -value; ++ sc_access[0].reg_addr = VOL_CTRL_LT; ++ sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); ++ num_reg = 1; ++ break; ++ case PMIC_SND_RIGHT_PB_VOL: ++ sc_access[0].value = -value; ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); ++ if(snd_pmic_ops_mx.num_channel == 1) { ++ sc_access[0].value = 0x40; ++ sc_access[0].mask = MASK6; ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ } ++ num_reg = 1; ++ break; ++ } ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg); ++} ++ ++int mx_get_mute(int dev_id, u8 *value) ++{ ++ struct sc_reg_access sc_access[4] = {{0},}; ++ int retval = 0, num_reg = 0, mask = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (dev_id) { ++ case PMIC_SND_DMIC_MUTE: ++ case PMIC_SND_AMIC_MUTE: ++ case PMIC_SND_HP_MIC_MUTE: ++ sc_access[0].reg_addr = 0x220; ++ mask = MASK5|MASK6; ++ num_reg = 1; ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg); ++ if (retval) ++ return retval; ++ *value = sc_access[0].value & mask; ++ if (*value) ++ *value = UNMUTE; ++ else ++ *value = MUTE; ++ return retval; ++ ++ case PMIC_SND_LEFT_HP_MUTE: ++ case PMIC_SND_LEFT_SPEAKER_MUTE: ++ sc_access[0].reg_addr = VOL_CTRL_LT; ++ num_reg = 1; ++ mask = MASK6; ++ break; ++ case PMIC_SND_RIGHT_HP_MUTE: ++ case PMIC_SND_RIGHT_SPEAKER_MUTE: ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ num_reg = 1; ++ mask = MASK6; ++ break; ++ case PMIC_SND_MUTE_ALL: ++ sc_access[0].reg_addr = VOL_CTRL_RT; ++ sc_access[1].reg_addr = VOL_CTRL_LT; ++ sc_access[2].reg_addr = 0x220; ++ sc_access[3].reg_addr = 0x221; ++ num_reg = 4; ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg); ++ if (((sc_access[0].value & MASK6) == MASK6) && ++ ((sc_access[1].value & MASK6) == MASK6) && ++ ((sc_access[2].value & (MASK5|MASK6)) == 0) && ++ ((sc_access[3].value & (MASK5|MASK6)) == 0)) ++ *value = MUTE; ++ else ++ *value = UNMUTE; ++ break; ++ } ++ retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg); ++ if (retval) ++ return retval; ++ *value = sc_access[0].value & mask; ++ if (*value) ++ *value = MUTE; ++ else ++ *value = UNMUTE; ++ return retval; ++} ++ ++int mx_get_vol(int dev_id, u8 *value) ++{ ++ struct sc_reg_access sc_access = {0,}; ++ int retval = 0, mask = 0, num_reg = 0; ++ ++ if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) ++ retval = mx_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (dev_id) { ++ case PMIC_SND_CAPTURE_VOL: ++ sc_access.reg_addr = 0x220; ++ mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5; ++ num_reg = 1; ++ break; ++ case PMIC_SND_LEFT_PB_VOL: ++ sc_access.reg_addr = VOL_CTRL_LT; ++ mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5; ++ num_reg = 1; ++ break; ++ case PMIC_SND_RIGHT_PB_VOL: ++ sc_access.reg_addr = VOL_CTRL_RT; ++ mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5; ++ num_reg = 1; ++ break; ++ } ++ retval = sst_sc_reg_access(&sc_access, PMIC_READ, num_reg); ++ if (retval) ++ return retval; ++ *value = -(sc_access.value & mask); ++ printk(KERN_DEBUG "SST DBG:value extracted 0x%x\n", *value); ++ return retval; ++} ++ ++struct snd_pmic_ops snd_pmic_ops_mx = { ++ .set_input_dev = mx_set_selected_input_dev, ++ .set_output_dev = mx_set_selected_output_dev, ++ .set_mute = mx_set_mute, ++ .get_mute = mx_get_mute, ++ .set_vol = mx_set_vol, ++ .get_vol = mx_get_vol, ++ .init_card = mx_init_card, ++ .set_pcm_audio_params = mx_set_pcm_audio_params, ++ .set_pcm_voice_params = mx_set_pcm_voice_params, ++ .set_voice_port = mx_set_voice_port, ++ .set_audio_port = mx_set_audio_port, ++ .power_up_pmic_pb = mx_power_up_pb, ++ .power_up_pmic_cp = mx_power_up_cp, ++ .power_down_pmic_pb = mx_power_down_pb, ++ .power_down_pmic_cp = mx_power_down_cp, ++ .power_down_pmic = mx_power_down, ++}; ++ +diff --git a/sound/pci/sst/intelmid_v2_control.c b/sound/pci/sst/intelmid_v2_control.c +new file mode 100644 +index 0000000..d42b564 +--- /dev/null ++++ b/sound/pci/sst/intelmid_v2_control.c +@@ -0,0 +1,1031 @@ ++/* ++ * intelmid_v2_control.c - Intel Sound card driver for MID ++ * ++ * Copyright (C) 2008-10 Intel Corp ++ * Authors: Vinod Koul ++ * Harsha Priya ++ * KP Jeeja ++ * Dharageswari R ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * 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 vendor 3 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "intel_sst_fw_ipc.h" ++#include "intel_sst_common.h" ++#include "intelmid_snd_control.h" ++ ++enum reg_v3 { ++ VAUDIOCNT = 0x51, ++ VOICEPORT1 = 0x100, ++ VOICEPORT2 = 0x101, ++ AUDIOPORT1 = 0x102, ++ AUDIOPORT2 = 0x103, ++ ADCSAMPLERATE = 0x104, ++ DMICCTRL1 = 0x105, ++ DMICCTRL2 = 0x106, ++ MICCTRL = 0x107, ++ MICSELVOL = 0x108, ++ LILSEL = 0x109, ++ LIRSEL = 0x10a, ++ VOICEVOL = 0x10b, ++ AUDIOLVOL = 0x10c, ++ AUDIORVOL = 0x10d, ++ LMUTE = 0x10e, ++ RMUTE = 0x10f, ++ POWERCTRL1 = 0x110, ++ POWERCTRL2 = 0x111, ++ DRVPOWERCTRL = 0x112, ++ VREFPLL = 0x113, ++ PCMBUFCTRL = 0x114, ++ SOFTMUTE = 0x115, ++ DTMFPATH = 0x116, ++ DTMFVOL = 0x117, ++ DTMFFREQ = 0x118, ++ DTMFHFREQ = 0x119, ++ DTMFLFREQ = 0x11a, ++ DTMFCTRL = 0x11b, ++ DTMFASON = 0x11c, ++ DTMFASOFF = 0x11d, ++ DTMFASINUM = 0x11e, ++ CLASSDVOL = 0x11f, ++ VOICEDACAVOL = 0x120, ++ AUDDACAVOL = 0x121, ++ LOMUTEVOL = 0x122, ++ HPLVOL = 0x123, ++ HPRVOL = 0x124, ++ MONOVOL = 0x125, ++ LINEOUTMIXVOL = 0x126, ++ EPMIXVOL = 0x127, ++ LINEOUTLSEL = 0x128, ++ LINEOUTRSEL = 0x129, ++ EPMIXOUTSEL = 0x12a, ++ HPLMIXSEL = 0x12b, ++ HPRMIXSEL = 0x12c, ++ LOANTIPOP = 0x12d, ++}; ++ ++ ++int nc_init_card(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {VAUDIOCNT, 0x25, 0}, ++ {VOICEPORT1, 0x00, 0}, ++ {VOICEPORT2, 0x00, 0}, ++ {AUDIOPORT1, 0x98, 0}, ++ {AUDIOPORT2, 0x09, 0}, ++ {AUDIOLVOL, 0x0e, 0}, ++ {AUDIORVOL, 0x0e, 0}, ++ {LMUTE, 0x03, 0}, ++ {RMUTE, 0x03, 0}, ++ {POWERCTRL1, 0x00, 0}, ++ {POWERCTRL2, 0x00, 0}, ++ {DRVPOWERCTRL, 0x00, 0}, ++ {VREFPLL, 0x10, 0}, ++ {HPLMIXSEL, 0xee, 0}, ++ {HPRMIXSEL, 0xf6, 0}, ++ {PCMBUFCTRL, 0x0, 0}, ++ {VOICEVOL, 0x0e, 0}, ++ {HPLVOL, 0x06, 0}, ++ {HPRVOL, 0x06, 0}, ++ {MICCTRL, 0x11, 0x00}, ++ {ADCSAMPLERATE, 0x8B, 0x00}, ++ {MICSELVOL, 0x5B, 0x00}, ++ {LILSEL, 0x46, 0}, ++ {LIRSEL, 0x06, 0}, ++ {LOANTIPOP, 0x00, 0}, ++ }; ++ snd_pmic_ops_nc.card_status = SND_CARD_INIT_DONE; ++ sst_sc_reg_access(sc_access, PMIC_WRITE, 25); ++ snd_pmic_ops_nc.mute_status = 1; ++ printk(KERN_DEBUG "SST DBG:init complete!!\n"); ++ return 0; ++} ++ ++int nc_enable_audiodac(int value) ++{ ++ struct sc_reg_access sc_access[3]; ++ int mute_val = 0; ++ ++ printk(KERN_DEBUG "SST DBG:+\ ++ PMIC_SND_INPUT_MUTE_: value::%d\n", snd_pmic_ops_nc.mute_status ); ++ if (snd_pmic_ops_nc.mute_status == MUTE) ++ return 0; ++ ++ if ((snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR) && ++ (value == UNMUTE)) ++ return 0; ++ if (value == UNMUTE) { ++ /* unmute the system, set the 7th bit to zero */ ++ mute_val = 0x00; ++ } else { ++ /* MUTE:Set the seventh bit */ ++ mute_val = 0x04; ++ ++ } ++ sc_access[0].reg_addr = LMUTE; ++ sc_access[1].reg_addr = RMUTE; ++ sc_access[0].mask = sc_access[1].mask = MASK2; ++ sc_access[0].value = sc_access[1].value = mute_val; ++ ++ if (snd_pmic_ops_nc.num_channel == 1) ++ sc_access[1].value = 0x04; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++} ++ ++ ++int nc_power_up_pb(unsigned int port) ++{ ++ struct sc_reg_access sc_access[7]; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ if (port == 0xFF) ++ return 0; ++ nc_enable_audiodac(MUTE); ++ mdelay(30); ++ ++ printk(KERN_DEBUG "SST DBG:powering up pb....\n"); ++ ++ sc_access[0].reg_addr = VAUDIOCNT; ++ sc_access[0].value = 0x27; ++ sc_access[0].mask = 0x27; ++ sc_access[1].reg_addr = VREFPLL; ++ if (port == 0) { ++ sc_access[1].value = 0x3A; ++ sc_access[1].mask = 0x3A; ++ } else if (port == 1) { ++ sc_access[1].value = 0x35; ++ sc_access[1].mask = 0x35; ++ } ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ ++ ++ sc_access[0].reg_addr = POWERCTRL1; ++ if (port == 0) { ++ sc_access[0].value = 0x40; ++ sc_access[0].mask = 0x40; ++ } else if (port == 1) { ++ sc_access[0].value = 0x01; ++ sc_access[0].mask = 0x01; ++ } ++ sc_access[1].reg_addr = POWERCTRL2; ++ sc_access[1].value = 0x0C; ++ sc_access[1].mask = 0x0C; ++ ++ sc_access[2].reg_addr = DRVPOWERCTRL; ++ sc_access[2].value = 0x86; ++ sc_access[2].mask = 0x86; ++ ++ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3); ++ ++ mdelay(30); ++ ++ return nc_enable_audiodac(UNMUTE); ++ ++} ++ ++int nc_power_up_cp(unsigned int port) ++{ ++ struct sc_reg_access sc_access[5]; ++ int retval = 0; ++ ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ ++ printk(KERN_DEBUG "SST DBG:powering up cp....\n"); ++ ++ if (port == 0xFF) ++ return 0; ++ sc_access[0].reg_addr = VAUDIOCNT; ++ sc_access[0].value = 0x27; ++ sc_access[0].mask = 0x27; ++ sc_access[1].reg_addr = VREFPLL; ++ if (port == 0) { ++ sc_access[1].value = 0x3E; ++ sc_access[1].mask = 0x3E; ++ } else if (port == 1) { ++ sc_access[1].value = 0x35; ++ sc_access[1].mask = 0x35; ++ } ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ ++ sc_access[0].reg_addr = POWERCTRL1; ++ if (port == 0) { ++ sc_access[0].value = 0xB4; ++ sc_access[0].mask = 0xB4; ++ } else if (port == 1) { ++ sc_access[0].value = 0xBF; ++ sc_access[0].mask = 0xBF; ++ } ++ sc_access[1].reg_addr = POWERCTRL2; ++ if (port == 0) { ++ sc_access[1].value = 0x0C; ++ sc_access[1].mask = 0x0C; ++ } else if (port == 1) { ++ sc_access[1].value = 0x02; ++ sc_access[1].mask = 0x02; ++ } ++ ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++} ++int nc_power_down(void) ++{ ++ int retval = 0; ++ struct sc_reg_access sc_access[5]; ++ ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ nc_enable_audiodac(MUTE); ++ ++ ++ printk(KERN_DEBUG "SST DBG:powering dn nc_power_down ....\n"); ++ ++ ++ ++ mdelay(30); ++ ++ sc_access[0].reg_addr = DRVPOWERCTRL; ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = 0x00; ++ ++ sst_sc_reg_access(sc_access, PMIC_WRITE, 1); ++ ++ sc_access[0].reg_addr = POWERCTRL1; ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = 0x00; ++ ++ sc_access[1].reg_addr = POWERCTRL2; ++ sc_access[1].value = 0x00; ++ sc_access[1].mask = 0x00; ++ ++ ++ ++ sst_sc_reg_access(sc_access, PMIC_WRITE, 2); ++ ++ mdelay(30); ++ sc_access[0].reg_addr = VREFPLL; ++ sc_access[0].value = 0x10; ++ sc_access[0].mask = 0x10; ++ ++ sc_access[1].reg_addr = VAUDIOCNT; ++ sc_access[1].value = 0x25; ++ sc_access[1].mask = 0x25; ++ ++ ++ retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 2); ++ ++ mdelay(30); ++ return nc_enable_audiodac(UNMUTE); ++} ++int nc_power_down_pb(void) ++{ ++ ++ int retval = 0; ++ struct sc_reg_access sc_access[5]; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ printk(KERN_DEBUG "SST DBG:powering dn pb....\n"); ++ ++ nc_enable_audiodac(MUTE); ++ ++ ++ mdelay(30); ++ ++ ++ sc_access[0].reg_addr = DRVPOWERCTRL; ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = 0x00; ++ ++ sst_sc_reg_access(sc_access, PMIC_WRITE, 1); ++ ++ mdelay(30); ++ ++ sc_access[0].reg_addr = POWERCTRL1; ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = 0x41; ++ ++ sc_access[1].reg_addr = POWERCTRL2; ++ sc_access[1].value = 0x00; ++ sc_access[1].mask = 0x0C; ++ ++ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); ++ ++ mdelay(30); ++ ++ return nc_enable_audiodac(UNMUTE); ++ ++ ++} ++ ++int nc_power_down_cp(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {POWERCTRL1, 0x00, 0xBF}, ++ {POWERCTRL2, 0x00, 0x02}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ printk(KERN_DEBUG "SST DBG:powering dn cp....\n"); ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++} ++ ++int nc_set_pcm_voice_params(void) ++{ ++ struct sc_reg_access sc_access[] = { ++ {0x100, 0xD5, 0}, ++ {0x101, 0x08, 0}, ++ {0x104, 0x03, 0}, ++ {0x107, 0x10, 0}, ++ {0x10B, 0x0E, 0}, ++ {0x10E, 0x03, 0}, ++ {0x10F, 0x03, 0}, ++ {0x114, 0x13, 0}, ++ {0x115, 0x00, 0}, ++ {0x128, 0xFE, 0}, ++ {0x129, 0xFE, 0}, ++ {0x12A, 0xFE, 0}, ++ {0x12B, 0xDE, 0}, ++ {0x12C, 0xDE, 0}, ++ }; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ sst_sc_reg_access(sc_access, PMIC_WRITE, 14); ++ printk(KERN_DEBUG "SST DBG:Voice parameters set successfully!!\n"); ++ return 0; ++} ++int nc_audio_init(void) ++{ ++ struct sc_reg_access sc_acces, sc_access[] = { ++ {0x100, 0x00, 0}, ++ {0x101, 0x00, 0}, ++ {0x104, 0x8B, 0}, ++ {0x107, 0x11, 0}, ++ {0x10B, 0x0E, 0}, ++ {0x10E, 0x03, 0}, ++ {0x10F, 0x03, 0}, ++ {0x114, 0x00, 0}, ++ {0x115, 0x00, 0}, ++ {0x128, 0x00, 0}, ++ {0x129, 0x00, 0}, ++ {0x12A, 0x00, 0}, ++ {0x12B, 0xee, 0}, ++ {0x12C, 0xf6, 0}, ++ }; ++ ++ sst_sc_reg_access(sc_access, PMIC_WRITE, 14); ++ printk(KERN_DEBUG "SST DBG:Audio Init successfully!!\n"); ++ if(snd_pmic_ops_nc.num_channel == 1) { ++ sc_acces.value = 0x07; ++ sc_acces.reg_addr = RMUTE; ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_HP_MUTE:: value::%d\n", ++ sc_acces.value); ++ sc_acces.mask = MASK2; ++ sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1); ++ } ++ else { ++ sc_acces.value = 0x00; ++ sc_acces.reg_addr = RMUTE; ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_HP_MUTE:: value::%d\n", ++ sc_acces.value); ++ sc_acces.mask = MASK2; ++ sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1); ++ } ++ ++ return 0; ++} ++ ++int nc_set_pcm_audio_params(int sfreq, int word_size, int num_channel) ++{ ++ int config2 = 0; ++ struct sc_reg_access sc_access; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (sfreq) { ++ case 8000: ++ config2 = 0x00; ++ break; ++ case 11025: ++ config2 = 0x01; ++ break; ++ case 12000: ++ config2 = 0x02; ++ break; ++ case 16000: ++ config2 = 0x03; ++ break; ++ case 22050: ++ config2 = 0x04; ++ break; ++ case 24000: ++ config2 = 0x05; ++ break; ++ case 32000: ++ config2 = 0x07; ++ break; ++ case 44100: ++ config2 = 0x08; ++ break; ++ case 48000: ++ config2 = 0x09; ++ break; ++ } ++ ++ snd_pmic_ops_nc.num_channel = num_channel; ++ if(snd_pmic_ops_nc.num_channel == 1) ++ { ++ ++ sc_access.value = 0x07; ++ sc_access.reg_addr = RMUTE; ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_HP_MUTE:: value::%d\n", ++ sc_access.value); ++ sc_access.mask = MASK2; ++ sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); ++ } ++ else ++ { ++ sc_access.value = 0x00; ++ sc_access.reg_addr = RMUTE; ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_HP_MUTE:: value::%d\n", ++ sc_access.value); ++ sc_access.mask = MASK2; ++ sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); ++ ++ ++ } ++ ++ printk(KERN_DEBUG "SST DBG:word_size = %d\n", word_size); ++ ++ if(word_size == 24) { ++ sc_access.reg_addr = AUDIOPORT2; ++ sc_access.value = config2 |0x10; ++ sc_access.mask = 0x1F; ++ } ++ else { ++ sc_access.value = config2; ++ sc_access.mask = 0x1F; ++ sc_access.reg_addr = AUDIOPORT2; ++ } ++ sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); ++ ++ printk(KERN_DEBUG "SST DBG:word_size = %d\n", word_size); ++ sc_access.reg_addr = AUDIOPORT1; ++ sc_access.mask = MASK5|MASK4|MASK1|MASK0; ++ if (word_size == 16) ++ sc_access.value = 0x98; ++ else if (word_size == 24) ++ sc_access.value = 0xAB; ++ ++ return sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); ++ ++ ++ ++} ++ ++int nc_set_audio_port(int status) ++{ ++ struct sc_reg_access sc_access[2] = {{0,},}; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ if (status == DEACTIVATE) { ++ /* Deactivate audio port-tristate and power */ ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK4|MASK5; ++ sc_access[0].reg_addr = AUDIOPORT1; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ } else if (status == ACTIVATE) { ++ /* activate audio port */ ++ nc_audio_init(); ++ sc_access[0].value = 0x10; ++ sc_access[0].mask = MASK4|MASK5 ; ++ sc_access[0].reg_addr = AUDIOPORT1; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ } else ++ return -EINVAL; ++ ++} ++ ++int nc_set_voice_port(int status) ++{ ++ struct sc_reg_access sc_access[2] = {{0,},}; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ if (status == DEACTIVATE) { ++ /* Activate Voice port */ ++ sc_access[0].value = 0x00; ++ sc_access[0].mask = MASK4; ++ sc_access[0].reg_addr = VOICEPORT1; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ } else if (status == ACTIVATE) { ++ /* Deactivate voice port */ ++ nc_set_pcm_voice_params(); ++ sc_access[0].value = 0x10; ++ sc_access[0].mask = MASK4; ++ sc_access[0].reg_addr = VOICEPORT1; ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ } else ++ return -EINVAL; ++} ++int nc_set_selected_output_dev(u8 value) ++{ ++ struct sc_reg_access sc_acces, sc_access_HP[] = { ++ {LMUTE, 0x02, 0x06}, ++ {RMUTE, 0x02, 0x06} ++ }; ++ struct sc_reg_access sc_access_IS[] = { ++ {LMUTE, 0x04, 0x06}, ++ {RMUTE, 0x04, 0x06} ++ }; ++ int retval = 0; ++ ++ snd_pmic_ops_nc.output_dev_id = value; ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ printk(KERN_DEBUG "SST DBG:nc set selected output:%d \n", value); ++ switch (value) { ++ case STEREO_HEADPHONE: ++ retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2); ++ if(snd_pmic_ops_nc.num_channel == 1) { ++ sc_acces.value = 0x07; ++ sc_acces.reg_addr = RMUTE; ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_HP_MUTE:: value::%d\n", ++ sc_acces.value); ++ sc_acces.mask = MASK2; ++ retval = sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1); ++ } ++ break; ++ case INTERNAL_SPKR: ++ return sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 2); ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ rcvd illegal request: %d \n", value); ++ return -EINVAL; ++ } ++ return retval; ++} ++ ++int nc_set_mute(int dev_id, u8 value) ++{ ++ struct sc_reg_access sc_access[3]; ++ u8 mute_val, cap_mute; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ printk(KERN_DEBUG "SST DBG:set device id::%d, +\ ++ value %d\n", dev_id, value); ++ ++ switch (dev_id) { ++ case PMIC_SND_MUTE_ALL: ++ printk(KERN_DEBUG "SST DBG:+\ ++ PMIC_SND_MUTE_ALL: value::%d \n", value); ++ snd_pmic_ops_nc.mute_status = value; ++ if (value == UNMUTE) { ++ /* unmute the system, set the 7th bit to zero */ ++ mute_val = cap_mute = 0x00; ++ ++ } else { ++ /* MUTE:Set the seventh bit */ ++ mute_val = 0x80; ++ cap_mute = 0x40; ++ } ++ sc_access[0].reg_addr = AUDIOLVOL; ++ sc_access[1].reg_addr = AUDIORVOL; ++ sc_access[0].mask = sc_access[1].mask = MASK7; ++ sc_access[0].value = sc_access[1].value = mute_val; ++ if(snd_pmic_ops_nc.num_channel == 1) ++ sc_access[1].value = 0x80; ++ if (!sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2)) { ++ sc_access[0].reg_addr = 0x109; ++ sc_access[1].reg_addr = 0x10a; ++ sc_access[2].reg_addr = 0x105; ++ sc_access[0].mask = sc_access[1].mask = sc_access[2].mask = MASK6; ++ sc_access[0].value = sc_access[1].value = sc_access[2].value = cap_mute; ++ ++ if ((snd_pmic_ops_nc.input_dev_id == AMIC ) || ++ (snd_pmic_ops_nc.input_dev_id == DMIC )) ++ sc_access[1].value = 0x40; ++ if (snd_pmic_ops_nc.input_dev_id == HS_MIC) ++ sc_access[0].value = 0x40; ++ return sst_sc_reg_access(sc_access, ++ PMIC_READ_MODIFY, 3); ++ } ++ break; ++ case PMIC_SND_HP_MIC_MUTE: ++ printk(KERN_DEBUG "SST DBG:+\ ++ PMIC_SND_HPMIC_MUTE: value::%d\n", value); ++ if (value == UNMUTE) { ++ /* unmute the system, set the 6th bit to one */ ++ sc_access[0].value = 0x00; ++ } else { ++ /* mute the system, reset the 6th bit to zero */ ++ sc_access[0].value = 0x40; ++ } ++ sc_access[0].reg_addr = LIRSEL; ++ sc_access[0].mask = MASK6; ++ break; ++ case PMIC_SND_AMIC_MUTE: ++ printk(KERN_DEBUG "SST DBG:+\ ++ PMIC_SND_AMIC_MUTE: value::%d\n", value); ++ if (value == UNMUTE) { ++ /* unmute the system, set the 6th bit to one */ ++ sc_access[0].value = 0x00; ++ } else { ++ /* mute the system, reset the 6th bit to zero */ ++ sc_access[0].value = 0x40; ++ } ++ sc_access[0].reg_addr = LILSEL; ++ sc_access[0].mask = MASK6; ++ break; ++ ++ case PMIC_SND_DMIC_MUTE: ++ printk(KERN_DEBUG "SST DBG:+\ ++ PMIC_SND_INPUT_MUTE_DMIC: value::%d\n", value); ++ if (value == UNMUTE) { ++ /* unmute the system, set the 6th bit to one */ ++ sc_access[1].value = 0x00; ++ sc_access[0].value = 0x00; ++ } else { ++ /* mute the system, reset the 6th bit to zero */ ++ sc_access[1].value = 0x40; ++ sc_access[0].value = 0x40; ++ } ++ sc_access[0].reg_addr = DMICCTRL1; ++ sc_access[0].mask = MASK6; ++ sc_access[1].reg_addr = LILSEL; ++ sc_access[1].mask = MASK6; ++ return sst_sc_reg_access(sc_access, ++ PMIC_READ_MODIFY, 2); ++ break; ++ ++ case PMIC_SND_LEFT_HP_MUTE: ++ case PMIC_SND_RIGHT_HP_MUTE: ++ snd_pmic_ops_nc.mute_status = value; ++ if (value == UNMUTE) ++ sc_access[0].value = 0x0; ++ else ++ sc_access[0].value = 0x04; ++ ++ if (dev_id == PMIC_SND_LEFT_HP_MUTE) { ++ sc_access[0].reg_addr = LMUTE; ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_LEFT_HP_MUTE:: value::%d\n", ++ sc_access[0].value); ++ } else { ++ if(snd_pmic_ops_nc.num_channel == 1) ++ sc_access[0].value = 0x04; ++ sc_access[0].reg_addr = RMUTE; ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_HP_MUTE:: value::%d\n", ++ sc_access[0].value); ++ } ++ sc_access[0].mask = MASK2; ++ break; ++ case PMIC_SND_LEFT_SPEAKER_MUTE: ++ case PMIC_SND_RIGHT_SPEAKER_MUTE: ++ if (value == UNMUTE) ++ sc_access[0].value = 0x00; ++ else ++ sc_access[0].value = 0x03; ++ sc_access[0].reg_addr = LMUTE; ++ printk(KERN_DEBUG "SST DBG:+\ ++ PMIC_SND_SPEAKER_MUTE %d\n", sc_access[0].value); ++ sc_access[0].mask = MASK1; ++ break; ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ Invalid Device_id \n"); ++ return -EINVAL; ++ } ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); ++ ++} ++ ++int nc_set_vol(int dev_id, u8 value) ++{ ++ struct sc_reg_access sc_access; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ printk(KERN_DEBUG "SST DBG:set volume:%d\n", dev_id); ++ switch (dev_id) { ++ case PMIC_SND_CAPTURE_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_CAPTURE_VOL:: +\ ++ value::%d \n", value); ++ sc_access.value = -value; ++ sc_access.reg_addr = LILSEL; ++ sc_access.mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5; ++ break; ++ ++ case PMIC_SND_LEFT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:+\ ++ PMIC_SND_LEFT_HP_VOL:%d \n", value); ++ sc_access.value = -value; ++ sc_access.reg_addr = AUDIOLVOL; ++ sc_access.mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); ++ break; ++ ++ case PMIC_SND_RIGHT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_RIGHT_HP_VOL: +\ ++ value::%d\n", value); ++ if(snd_pmic_ops_nc.num_channel == 1) { ++ sc_access.value = 0x04; ++ sc_access.reg_addr = RMUTE; ++ sc_access.mask = MASK2; ++ } else { ++ sc_access.value = -value; ++ sc_access.reg_addr = AUDIORVOL; ++ sc_access.mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); ++ } ++ break; ++ ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ Invalid Device_id \n"); ++ return -EINVAL; ++ ++ } ++ /* sst_sc_read_modify(®_adrs, &difference, 1);*/ ++ return sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); ++} ++ ++int nc_set_selected_input_dev(u8 value) ++{ ++ struct sc_reg_access sc_access[6]; ++ u8 num_val; ++ int retval = 0; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ snd_pmic_ops_nc.input_dev_id = value; ++ ++ printk(KERN_DEBUG "SST DBG:nc set selected input:%d \n", value); ++ ++ switch (value) { ++ case AMIC: ++ printk(KERN_DEBUG "SST DBG:Selecting AMIC\n"); ++ sc_access[0].reg_addr = 0x107; ++ sc_access[0].value = 0x40; ++ sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0; ++ sc_access[1].reg_addr = 0x10a; ++ sc_access[1].value = 0x40; ++ sc_access[1].mask = MASK6; ++ sc_access[2].reg_addr = 0x109; ++ sc_access[2].value = 0x00; ++ sc_access[2].mask = MASK6; ++ num_val = 3; ++ break; ++ ++ case HS_MIC: ++ printk(KERN_DEBUG "SST DBG:+\ ++ Selecting HS_MIC\n"); ++ sc_access[0].reg_addr = 0x107; ++ sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0; ++ sc_access[0].value = 0x10; ++ sc_access[1].reg_addr = 0x109; ++ sc_access[1].mask = MASK6; ++ sc_access[1].value = 0x40; ++ sc_access[2].reg_addr = 0x10a; ++ sc_access[2].mask = MASK6; ++ sc_access[2].value = 0x00; ++ num_val = 3; ++ break; ++ ++ case DMIC: ++ printk(KERN_DEBUG "SST DBG:DMIC\n"); ++ sc_access[0].reg_addr = 0x107; ++ sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0; ++ sc_access[0].value = 0x0B; ++ sc_access[1].reg_addr = 0x105; ++ sc_access[1].value = 0x80; ++ sc_access[1].mask = MASK7|MASK6; ++ sc_access[2].reg_addr = 0x10a; ++ sc_access[2].value = 0x40; ++ sc_access[2].mask = MASK6; ++ num_val = 3; ++ break; ++ default: ++ printk(KERN_ERR "SST ERR:+\ ++ rcvd illegal request: %d \n", value); ++ return -EINVAL; ++ } ++ return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_val); ++} ++ ++int nc_get_mute(int dev_id, u8 *value) ++{ ++ int retval = 0, mask = 0; ++ struct sc_reg_access sc_access = {0,}; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ printk(KERN_DEBUG "SST DBG:get mute::%d\n", dev_id); ++ ++ switch (dev_id) { ++ case PMIC_SND_MUTE_ALL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_INPUT_MASTER_MUTE: +\ ++ value::%d\n", *value); ++ sc_access.reg_addr = AUDIOLVOL; ++ sc_access.mask = MASK7; ++ break; ++ case PMIC_SND_AMIC_MUTE: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_INPUT_MUTE_MIC1\n"); ++ sc_access.reg_addr = LILSEL; ++ mask = MASK6; ++ break; ++ case PMIC_SND_HP_MIC_MUTE: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_INPUT_MUTE_MIC2\n"); ++ sc_access.reg_addr = LIRSEL; ++ mask = MASK6; ++ break; ++ case PMIC_SND_LEFT_HP_MUTE: ++ case PMIC_SND_RIGHT_HP_MUTE: ++ mask = MASK2; ++ printk(KERN_DEBUG "SST DBG:PMIC_SN_LEFT/RIGHT_HP_MUTE\n"); ++ if (dev_id == PMIC_SND_RIGHT_HP_MUTE) ++ sc_access.reg_addr = RMUTE; ++ else ++ sc_access.reg_addr = LMUTE; ++ break; ++ ++ case PMIC_SND_LEFT_SPEAKER_MUTE: ++ printk(KERN_DEBUG "SST DBG:PMIC_MONO_EARPIECE_MUTE\n"); ++ sc_access.reg_addr = RMUTE; ++ mask = MASK1; ++ break; ++ case PMIC_SND_DMIC_MUTE: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_INPUT_MUTE_DMIC\n"); ++ sc_access.reg_addr = 0x105; ++ mask = MASK6; ++ break; ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ Invalid Device_id \n"); ++ return -EINVAL; ++ ++ } ++ retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1); ++ printk(KERN_DEBUG "SST DBG:reg value = %d\n", sc_access.value); ++ if (retval) ++ return retval; ++ *value = (sc_access.value) & mask; ++ printk(KERN_DEBUG "SST DBG:masked value = %d\n", *value); ++ if (*value) ++ *value = 0; ++ else ++ *value = 1; ++ printk(KERN_DEBUG "SST DBG:value returned = 0x%x\n", *value); ++ return retval; ++} ++ ++int nc_get_vol(int dev_id, u8 *value) ++{ ++ int retval = 0, mask = 0; ++ struct sc_reg_access sc_access = {0,}; ++ ++ if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) ++ retval = nc_init_card(); ++ if (retval) ++ return retval; ++ ++ switch (dev_id) { ++ case PMIC_SND_CAPTURE_VOL: ++ printk(KERN_DEBUG "SST DBG:PMIC_SND_INPUT_CAPTURE_VOL\n"); ++ sc_access.reg_addr = LILSEL; ++ mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); ++ break; ++ ++ case PMIC_SND_RIGHT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:GET_VOLUME_PMIC_LEFT_HP_VOL\n"); ++ sc_access.reg_addr = AUDIOLVOL; ++ mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); ++ break; ++ ++ case PMIC_SND_LEFT_PB_VOL: ++ printk(KERN_DEBUG "SST DBG:GET_VOLUME_PMIC_RIGHT_HP_VOL\n"); ++ sc_access.reg_addr = AUDIORVOL; ++ mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); ++ break; ++ ++ default: ++ printk(KERN_ERR "SST ERR: +\ ++ Invalid Device_id = %d \n", dev_id); ++ return -EINVAL; ++ ++ } ++ retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1); ++ printk(KERN_DEBUG "SST DBG:value read = 0x%x\n", sc_access.value); ++ *value = (sc_access.value) & mask; ++ *value = -*value; ++ printk(KERN_DEBUG "SST DBG:value returned = 0x%x\n", *value); ++ return retval; ++} ++ ++struct snd_pmic_ops snd_pmic_ops_nc = { ++ .set_input_dev = nc_set_selected_input_dev, ++ .set_output_dev = nc_set_selected_output_dev, ++ .set_mute = nc_set_mute, ++ .get_mute = nc_get_mute, ++ .set_vol = nc_set_vol, ++ .get_vol = nc_get_vol, ++ .init_card = nc_init_card, ++ .set_pcm_audio_params = nc_set_pcm_audio_params, ++ .set_pcm_voice_params = nc_set_pcm_voice_params, ++ .set_voice_port = nc_set_voice_port, ++ .set_audio_port = nc_set_audio_port, ++ .power_up_pmic_pb = nc_power_up_pb, ++ .power_up_pmic_cp = nc_power_up_cp, ++ .power_down_pmic_pb = nc_power_down_pb, ++ .power_down_pmic_cp = nc_power_down_cp, ++ .power_down_pmic = nc_power_down, ++}; +-- +1.6.2.2 + -- cgit v1.2.3