aboutsummaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-6-8.patch2861
1 files changed, 2861 insertions, 0 deletions
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 0000000000..c75fd6d281
--- /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 <dharageswari.r@intel.com>
+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 <vinod.koul@intel.com>
+
+ 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 <vinod.koul@intel.com>
++ * Harsha Priya <priya.harsha@intel.com>
++ * Dharageswari R <dharageswari.r@intel.com>
++ * KP Jeeja <jeeja.kp@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 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 <vinod.koul@intel.com>
++ * Harsha Priya <priya.harsha@intel.com>
++ * Dharageswari R <dharageswari.r@intel.com>
++ * KP Jeeja <jeeja.kp@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 vendor 1
++ */
++
++#include <linux/cdev.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/syscalls.h>
++#include <linux/file.h>
++#include <linux/fcntl.h>
++#include <linux/uaccess.h>
++#include <linux/interrupt.h>
++#include <linux/list.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/workqueue.h>
++#include <linux/pci.h>
++#include <linux/firmware.h>
++#include <sound/intel_lpe.h>
++#include <sound/intel_sst_ioctl.h>
++#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 <vinod.koul@intel.com>
++ * Harsha Priya <priya.harsha@intel.com>
++ * Dharageswari R <dharageswari.r@intel.com>
++ * KP Jeeja <jeeja.kp@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 vendor 2
++ */
++
++#include <linux/cdev.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/syscalls.h>
++#include <linux/file.h>
++#include <linux/fcntl.h>
++#include <linux/uaccess.h>
++#include <linux/interrupt.h>
++#include <linux/list.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/workqueue.h>
++#include <linux/pci.h>
++#include <linux/firmware.h>
++#include <sound/intel_lpe.h>
++#include <sound/intel_sst_ioctl.h>
++#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 <vinod.koul@intel.com>
++ * Harsha Priya <priya.harsha@intel.com>
++ * KP Jeeja <jeeja.kp@intel.com>
++ * Dharageswari R <dharageswari.r@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 vendor 3
++ */
++
++#include <linux/cdev.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/syscalls.h>
++#include <linux/file.h>
++#include <linux/fcntl.h>
++#include <linux/uaccess.h>
++#include <linux/interrupt.h>
++#include <linux/list.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/workqueue.h>
++#include <linux/pci.h>
++#include <linux/firmware.h>
++#include <sound/intel_lpe.h>
++#include <sound/intel_sst_ioctl.h>
++#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(&reg_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
+