asoc: codecs: update the TIAIC326x driver
Nikesh Oswal [Tue, 6 Mar 2012 10:32:57 +0000 (15:32 +0530)]
update the TIAIC326x driver for voice call

Change-Id: I1443b462b5b7e049fe4cbf39215aea6eeb955500
Reviewed-on: http://git-master/r/88012
Tested-by: Nikesh Oswal <noswal@nvidia.com>
Reviewed-by: Scott Peterson <speterson@nvidia.com>

sound/soc/codecs/tlv320aic326x.c
sound/soc/codecs/tlv320aic326x.h
sound/soc/codecs/tlv320aic326x_mini-dsp.c

index 12201e4..8bbd295 100644 (file)
@@ -63,7 +63,7 @@
 #include <linux/spi/spi.h>
 
 #include "tlv320aic326x.h"
-
+#include <linux/gpio.h>
 /*
  *****************************************************************************
  * Global Variable
@@ -733,16 +733,10 @@ static const struct snd_kcontrol_new aic3262_snd_controls[] = {
                                        RAGC_CNTL_R7, 0, 0x0F, 0),
 
        SOC_SINGLE("DAC PRB Selection",DAC_PRB, 0, 25, 0),
-
-       SOC_SINGLE("INTERRUPT FLAG - Read only", 46, 0, 255,0),
-       SOC_SINGLE("INTERRUPT STICKY FLAG - Read only", 44, 0, 255,0),
-       SOC_SINGLE("INT1 CONTROL", 48, 0, 255,0),
-       SOC_SINGLE("GPIO1 CONTROL", GPIO1_IO_CNTL, 0, 255,0),
        SOC_SINGLE("HP_DEPOP", HP_DEPOP, 0, 255,0),
        SOC_DOUBLE("IN1 LO BYPASS VOLUME" , LINE_AMP_CNTL_R2, 3, 0, 3, 1),
        SOC_ENUM("Input CM mode", input_cm_mode),
        SOC_ENUM("Output CM mode", output_cm_mode),
-
 };
 
 
@@ -819,6 +813,8 @@ static const struct aic3262_rate_divs aic3262_divs[] = {
 #ifdef CONFIG_MINI_DSP
        {12288000, 48000, 1, 8, 52, 128, 2, 8, 128, 2, 8, 4,
                {{0, 60, 0}, {0, 61, 0} } },
+       {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4,
+         {{0, 60, 0}, {0, 61, 0}}},
 #else
        /* 48k rate */
        {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2, 4,
@@ -827,8 +823,6 @@ static const struct aic3262_rate_divs aic3262_divs[] = {
                {{0, 60, 1}, {0, 61, 1} } },
        {24000000, 48000, 1, 4, 960, 128, 4, 4, 128, 4, 4, 4,
                {{0, 60, 1}, {0, 61, 1} } },
-       {26000000, 48000, 2, 7, 5618, 128, 8, 2, 128, 8, 2, 4,
-               {{0, 60, 1}, {0, 61, 1} } },
 #endif
 
        /*96k rate */
@@ -1480,7 +1474,6 @@ static int aic3262_multi_i2s_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        case AIC3262_FREQ_12000000:
        case AIC3262_FREQ_12288000:
        case AIC3262_FREQ_24000000:
-       case AIC3262_FREQ_26000000:
                aic3262->sysclk = freq;
                return 0;
                break;
@@ -2188,13 +2181,13 @@ static struct snd_soc_dai_driver tlv320aic3262_dai[] = {
        .name = "aic3262-asi1",
        .id = 1,
        .playback = {
-               .stream_name = "Playback",
+               .stream_name = "ASI1 Playback",
                .channels_min = 1,
                .channels_max = 2,
                .rates = AIC3262_RATES,
                .formats = AIC3262_FORMATS},
        .capture = { /* dummy for fast DAI switching */
-               .stream_name = "Capture",
+               .stream_name = "ASI1 Capture",
                .channels_min = 1,
                .channels_max = 2,
                .rates = AIC3262_RATES,
@@ -2206,13 +2199,13 @@ static struct snd_soc_dai_driver tlv320aic3262_dai[] = {
        .name = "aic3262-asi2",
        .id = 2,
        .playback = {
-               .stream_name = "Playback",
+               .stream_name = "ASI2 Playback",
                .channels_min = 1,
                .channels_max = 2,
                .rates = AIC3262_RATES,
                .formats = AIC3262_FORMATS,},
        .capture = {
-               .stream_name = "Capture",
+               .stream_name = "ASI2 Capture",
                .channels_min = 1,
                .channels_max = 2,
                .rates = AIC3262_RATES,
@@ -2225,13 +2218,13 @@ static struct snd_soc_dai_driver tlv320aic3262_dai[] = {
        .name = "aic3262-asi3",
        .id = 3,
        .playback = {
-               .stream_name = "Playback",
+               .stream_name = "ASI3 Playback",
                .channels_min = 1,
                .channels_max = 2,
                .rates = AIC3262_RATES,
                .formats = AIC3262_FORMATS, },
        .capture = {
-               .stream_name = "Capture",
+               .stream_name = "ASI3 Capture",
                .channels_min = 1,
                .channels_max = 2,
                .rates = AIC3262_RATES,
@@ -2440,8 +2433,8 @@ static const struct aic3262_configs aic3262_reg_init[] = {
        /* set default volumes */
        {0, DAC_LVOL, 0x01},
        {0, DAC_RVOL, 0x01},
-       {0, HPL_VOL,  0x3a},
-       {0, HPR_VOL,  0x3a},
+       {0, HPL_VOL,  0x80},
+       {0, HPR_VOL,  0x80},
        {0, SPK_AMP_CNTL_R2, 0x14},
        {0, SPK_AMP_CNTL_R3, 0x14},
        {0, SPK_AMP_CNTL_R4, 0x33},
@@ -2482,33 +2475,34 @@ static const struct aic3262_configs aic3262_reg_init[] = {
 
        {0, ADC_CHANNEL_POW, 0x0}, /*ladc, radc ON , SOFT STEP disabled*/
        {0, ADC_FINE_GAIN, 0x00},   /*ladc - unmute, radc - unmute*/
-       {0, MICL_PGA, 0x4f},
-       {0, MICR_PGA, 0x4f},
+       {0, MICL_PGA, 0x3f},
+       {0, MICR_PGA, 0x3f},
        /*controls MicBias ext power based on B0_P1_R51_D6*/
        {0, MIC_BIAS_CNTL, 0x80},
        /*   ASI1 Configuration */
        {0, ASI1_BUS_FMT, 0},
        {0, ASI1_BWCLK_CNTL_REG, 0x00},         /* originaly 0x24*/
        {0, ASI1_BCLK_N_CNTL, 1},
-       {0, ASI1_BCLK_N, 0x84},
+       {0, ASI1_BCLK_N, 0x04},
 
        {0, MA_CNTL, 0},                        /* Mixer Amp disabled */
        {0, LINE_AMP_CNTL_R2, 0x00},            /* Line Amp Cntl disabled */
 
        /* ASI2 Configuration */
        {0, ASI2_BUS_FMT, 0},
-       {0, ASI2_BCLK_N_CNTL, 0x0},
-       {0, ASI2_BCLK_N, 0x84},
+       {0, ASI2_BCLK_N_CNTL, 0x01},
+       {0, ASI2_BCLK_N, 0x04},
        {0, ASI2_BWCLK_OUT_CNTL, 0x20},
 
        {0, BEEP_CNTL_R1, 0x05},
        {0, BEEP_CNTL_R2, 0x04},
 
        /* Interrupt config for headset detection */
-       //{0, INT1_CNTL, 0x80}, /*INT enabled after Jack registration*/
+       {0,HEADSET_TUNING1_REG,0x7f},
+       {0, INT1_CNTL, 0x40},
+       /*{0, TIMER_REG, 0x8c},*/
        {0, INT_FMT, 0x40},
        {0, GPIO1_IO_CNTL, 0x14},
-       /* enables debounce with 512ms*/
        {0, HP_DETECT, 0x96},
 
 #if defined(CONFIG_MINI_DSP)
@@ -2799,15 +2793,173 @@ static int pll_power_on_event(struct snd_soc_dapm_widget *w,
        }
        return 0;
 }
+
+static int polling_loop(struct snd_soc_codec *codec, unsigned int reg,
+                       int mask, int on_off)
+{
+       unsigned int counter, status;
+
+       counter = 0;
+       switch(on_off) {
+               case 0: /*off*/
+                       do {
+                               status = snd_soc_read(codec, reg);
+                               counter++;
+                       } while ((counter < 500) && ((status & mask) == mask));
+               break;
+               case 1: /*on*/
+                       do {
+                               status = snd_soc_read(codec, reg);
+                               counter++;
+                       } while ((counter < 500) && ((status & mask) != mask));
+               break;
+               default:
+                       printk("%s: unknown arguement\n", __func__);
+                       break;
+       }
+
+       printk("%s: exiting with count value %d \n", __func__, counter);
+       if(counter >= 500)
+               return -1;
+       return 0;
+}
+
+int poll_dac(struct snd_soc_codec *codec, int left_right, int on_off)
+{
+       int ret = 0;
+
+       aic3262_change_page(codec, 0);
+       aic3262_change_book(codec, 0);
+
+       switch(on_off) {
+
+               case 0:/*power off polling*/
+                       /*DAC power polling logic*/
+                       switch(left_right) {
+                               case 0: /*left dac polling*/
+                                       ret = polling_loop(codec, DAC_FLAG_R1, LDAC_POW_FLAG_MASK, 0);
+                                       break;
+                               case 1:/*right dac polling*/
+                                       ret = polling_loop(codec, DAC_FLAG_R1, RDAC_POW_FLAG_MASK, 0);
+                                       break;
+                       }
+                       break;
+               case 1:/*power on polling*/
+                       /*DAC power polling logic*/
+                       switch(left_right) {
+                               case 0: /*left dac polling*/
+                                       ret = polling_loop(codec, DAC_FLAG_R1, LDAC_POW_FLAG_MASK, 1);
+                                       break;
+                               case 1:/*right dac polling*/
+                                       ret = polling_loop(codec, DAC_FLAG_R1, RDAC_POW_FLAG_MASK, 1);
+                                       break;
+                       }
+               break;
+               default:
+                       printk("%s:unknown arguement\n", __func__);
+                       break;
+               }
+       if(ret)
+               printk("%s: power %s %s failure", __func__, left_right?"right":"left", on_off?"on":"off");
+       return ret;
+}
+
+int poll_adc(struct snd_soc_codec *codec, int left_right, int on_off)
+{
+       int ret = 0;
+
+       aic3262_change_page(codec, 0);
+       aic3262_change_book(codec, 0);
+
+       switch(on_off) {
+
+               case 0:/*power off polling*/
+                       /*DAC power polling logic*/
+                       switch(left_right) {
+                               case 0: /*left dac polling*/
+                                       ret = polling_loop(codec, ADC_FLAG_R1, LADC_POW_FLAG_MASK, 0);
+                                       break;
+                               case 1:/*right dac polling*/
+                                       ret = polling_loop(codec, ADC_FLAG_R1, RADC_POW_FLAG_MASK, 0);
+                                       break;
+       }
+                       break;
+               case 1:/*power on polling*/
+                       /*DAC power polling logic*/
+                       switch(left_right) {
+                               case 0: /*left dac polling*/
+                                       ret = polling_loop(codec, ADC_FLAG_R1, LADC_POW_FLAG_MASK, 1);
+                                       break;
+                               case 1:/*right dac polling*/
+                                       ret = polling_loop(codec, ADC_FLAG_R1, RADC_POW_FLAG_MASK, 1);
+                                       break;
+               }
+                       break;
+               default:
+                       printk("%s:unknown arguement\n", __func__);
+                       break;
+       }
+
+       if(ret)
+               printk("%s: power %s %s failure", __func__, left_right?"right":"left", on_off?"on":"off");
+       return ret;
+}
+
+static int  slave_dac_event(struct snd_soc_dapm_widget *w,
+                              struct snd_kcontrol *kcontrol, int event)
+
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       if (event & SND_SOC_DAPM_POST_PMU) {
+               /* Poll for DAC Power-up first */
+               poll_dac(codec, 0, 1);
+               poll_dac(codec, 1, 1);
+       }
+
+       if (event & SND_SOC_DAPM_POST_PMD) {
+               poll_dac(codec, 0, 0);
+               poll_dac(codec, 1, 0);
+       }
+       return 0;
+}
+
+
+static int  slave_adc_event(struct snd_soc_dapm_widget *w,
+                              struct snd_kcontrol *kcontrol, int event)
+
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       if (event & SND_SOC_DAPM_POST_PMU) {
+
+               /* Poll for ADC Power-up first */
+               poll_adc(codec, 0, 1);
+               poll_adc(codec, 1, 1);
+       }
+
+
+       if (event & SND_SOC_DAPM_POST_PMD) {
+               poll_adc(codec, 0, 0);
+               poll_adc(codec, 1, 0);
+       }
+
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget aic3262_dapm_widgets[] = {
        /* TODO: Can we switch these off ? */
        SND_SOC_DAPM_AIF_IN("ASI1IN", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
        SND_SOC_DAPM_AIF_IN("ASI2IN", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
        SND_SOC_DAPM_AIF_IN("ASI3IN", "ASI3 Playback", 0, SND_SOC_NOPM, 0, 0),
 
-       SND_SOC_DAPM_DAC("Left DAC", NULL, PASI_DAC_DP_SETUP, 7, 0),
-       SND_SOC_DAPM_DAC("Right DAC", NULL, PASI_DAC_DP_SETUP, 6, 0),
 
+       SND_SOC_DAPM_DAC_E("Left DAC", NULL, PASI_DAC_DP_SETUP, 7, 0,
+                       slave_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
+                       SND_SOC_DAPM_PRE_PMD),
+       SND_SOC_DAPM_DAC_E("Right DAC", NULL, PASI_DAC_DP_SETUP, 6, 0,
+                       slave_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
+                       SND_SOC_DAPM_PRE_PMD),
 
        /* dapm widget (path domain) for HPL Output Mixer */
        SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
@@ -2931,9 +3083,13 @@ SND_SOC_DAPM_MUX("DAC MiniDSP IN2 Route",
        SND_SOC_DAPM_PGA("ADC MiniDSP OUT3", SND_SOC_NOPM, 0, 0, NULL, 0),
 
 
-       SND_SOC_DAPM_ADC("Left ADC", NULL, ADC_CHANNEL_POW, 7, 0),
-       SND_SOC_DAPM_ADC("Right ADC", NULL, ADC_CHANNEL_POW, 6, 0),
 
+       SND_SOC_DAPM_ADC_E("Left ADC", NULL, ADC_CHANNEL_POW, 7, 0,
+                       slave_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
+                       SND_SOC_DAPM_PRE_PMD),
+       SND_SOC_DAPM_ADC_E("Right ADC", NULL, ADC_CHANNEL_POW, 6, 0,
+                       slave_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD |
+                       SND_SOC_DAPM_PRE_PMD),
 
        SND_SOC_DAPM_PGA("Left MicPGA",MICL_PGA, 7, 1, NULL, 0),
        SND_SOC_DAPM_PGA("Right MicPGA",MICR_PGA, 7, 1, NULL, 0),
@@ -3829,7 +3985,6 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data)
        struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
        unsigned int value;
        unsigned int micbits, hsbits = 0;
-
        DBG(KERN_INFO "%s++\n", __func__);
 
        aic3262_change_page(codec, 0);
@@ -3872,7 +4027,6 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data)
                snd_soc_jack_report(aic3262->headset_jack,
                                SND_JACK_HEADSET, SND_JACK_HEADSET);
        }
-
        DBG(KERN_INFO "%s--\n", __func__);
        return IRQ_HANDLED;
 }
@@ -3895,7 +4049,25 @@ int aic326x_headset_detect(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(aic326x_headset_detect);
 
+int aic326x_headset_button_init(struct snd_soc_codec *codec,
+       struct snd_soc_jack *jack, int jack_type)
+{
+       struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
+
+       aic3262->button_dev = input_allocate_device();
+       aic3262->button_dev->name = "aic326x_headset_button";
+       aic3262->button_dev->phys = "codec/input0";
+       aic3262->button_dev->dev.parent = snd_card_get_device_link(codec->card->snd_card);
+       input_set_capability(aic3262->button_dev, EV_KEY, KEY_MEDIA);
 
+       if (input_register_device(aic3262->button_dev))
+       {
+          printk( "Unable to register input device headset button");
+       }
+
+       aic3262_jack_handler(aic3262->irq, codec);
+       return 0;
+}
 #ifdef AIC3262_MULTI_I2S
 /*
 * aic3262_asi_default_config
index 3e56d83..a31cc9e 100644 (file)
 
 #ifndef _TLV320AIC3262_H
 #define _TLV320AIC3262_H
-
+#include <linux/input.h>
 #define AUDIO_NAME "aic3262"
 #define AIC3262_VERSION "1.1"
 
-#define AIC3262_ASI2_MASTER 1
+//#define AIC3262_ASI2_MASTER 1
 
 /* Enable this macro allow for different ASI formats */
 /*#define ASI_MULTI_FMT*/
 #undef ASI_MULTI_FMT
 
+#define  INT_FLAG2_BUTTN_PRESSBIT 0x20
+
 /* Enable register caching on write */
 #define EN_REG_CACHE 1
 
@@ -64,7 +66,6 @@ page, so fix that before commenting this line*/
 #define AIC3262_FREQ_12000000 12000000
 #define AIC3262_FREQ_12288000 12288000
 #define AIC3262_FREQ_24000000 24000000
-#define AIC3262_FREQ_26000000 26000000
 
 /* Macro for enabling the Multi_I2S Support in Driver */
 #define AIC3262_MULTI_I2S      1
@@ -143,6 +144,13 @@ page, so fix that before commenting this line*/
 #define DAC_FLAG_R1_NOHS       0
 #define DAC_FLAG_R1_MONOHS     1
 #define DAC_FLAG_R1_STEREOHS   2
+
+/*mask patterns for DAC and ADC polling logic*/
+#define LDAC_POW_FLAG_MASK     0x80
+#define RDAC_POW_FLAG_MASK     0x08
+#define LADC_POW_FLAG_MASK     0x40
+#define RADC_POW_FLAG_MASK     0x04
+
 /* ****************** Book 0 Registers **************************************/
 
 /* ****************** Page 0 Registers **************************************/
@@ -186,6 +194,7 @@ page, so fix that before commenting this line*/
 #define STICKY_FLAG1           42
 #define INT_FLAG1              43
 #define STICKY_FLAG2           44
+#define STICKY_FLAG3           45
 #define INT_FLAG2              46
 #define INT1_CNTL              48
 #define INT2_CNTL              49
@@ -557,6 +566,7 @@ struct aic3262_priv {
        u8 spk_amp;
        struct spi_device *spi;
        struct snd_soc_jack *headset_jack;
+       struct input_dev *button_dev;
        int codec_audio_mode;
 #if defined(LOCAL_REG_ACCESS)
        void *control_data;
@@ -644,7 +654,8 @@ struct aic3262_rate_divs {
  */
 extern int aic326x_headset_detect(struct snd_soc_codec *codec,
        struct snd_soc_jack *jack, int jack_type);
-
+extern int aic326x_headset_button_init(struct snd_soc_codec *codec,
+       struct snd_soc_jack *jack, int jack_type);
 
 extern u8 aic3262_read(struct snd_soc_codec *codec, u16 reg);
 extern u16 aic3262_read_2byte(struct snd_soc_codec *codec, u16 reg);
@@ -656,6 +667,8 @@ extern void aic3262_write_reg_cache(struct snd_soc_codec *codec,
 extern int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book);
 extern int reg_def_conf(struct snd_soc_codec *codec);
 extern int i2c_verify_book0(struct snd_soc_codec *codec);
+extern int poll_dac(struct snd_soc_codec *codec, int left_right, int on_off);
+extern int poll_adc(struct snd_soc_codec *codec, int left_right, int on_off);
 
 #ifdef CONFIG_MINI_DSP
 extern int aic3262_minidsp_program(struct snd_soc_codec *codec);
index 3683702..6d55abb 100644 (file)
@@ -231,7 +231,6 @@ int byte_i2c_array_transfer(struct snd_soc_codec *codec,
                /* Check if current Reg offset is zero */
                if (program_ptr[j].reg_off == 0) {
                        /* Check for the Book Change Request */
-                       printk(KERN_INFO "inside if 1 j =%d\n", j);
                        if ((j < (size - 1)) &&
                                (program_ptr[j+1].reg_off == 127)) {
                                aic3262_change_book(codec,
@@ -561,9 +560,10 @@ struct process_flow{
        ARRAY_SIZE(main44_miniDSP_D_reg_values),main44_miniDSP_D_reg_values,
        ARRAY_SIZE(main44_REG_Section_post_program),main44_REG_Section_post_program,
        {
-               { 0, 0, ARRAY_SIZE(handset_miniDSP_D_reg_values), handset_miniDSP_D_reg_values},
-               { 0, 0, ARRAY_SIZE(handphone_miniDSP_D_reg_values), handphone_miniDSP_D_reg_values},
-               { 0, 0, ARRAY_SIZE(speaker_miniDSP_D_reg_values), speaker_miniDSP_D_reg_values},
+
+               { 0, 0, 0, 0},
+               { 0, 0, 0, 0},
+               { 0, 0, 0, 0},
                { 0, 0, 0, 0},
 
 
@@ -844,6 +844,69 @@ int i2c_verify(struct snd_soc_codec *codec)
        return 0;
 }
 
+
+int change_codec_power_status(struct snd_soc_codec * codec, int off_restore, int power_mask)
+{
+       int minidsp_power_mask;
+       u8 dac_status;
+       u8 adc_status;
+
+       minidsp_power_mask = 0;
+
+       aic3262_change_page (codec, 0);
+       aic3262_change_book (codec, 0);
+
+
+       switch (off_restore) {
+
+               case 0: /* Power-off the Codec */
+                       dac_status = snd_soc_read (codec, DAC_FLAG_R1);
+
+                       if(dac_status & 0x88) {
+                               minidsp_power_mask |= 0x1;
+                               snd_soc_update_bits(codec, PASI_DAC_DP_SETUP, 0xC0, 0x0);
+
+                               poll_dac(codec, 0x0, 0x0);
+                               poll_dac(codec, 0x1, 0x0);
+                       }
+
+                       adc_status = snd_soc_read (codec, ADC_FLAG_R1);
+
+                       if(adc_status & 0x44) {
+                               minidsp_power_mask |= 0x2;
+                               snd_soc_update_bits(codec, ADC_CHANNEL_POW, 0xC0, 0x0);
+
+                               poll_adc(codec, 0x0, 0x0);
+                               poll_adc(codec, 0x1, 0x0);
+                       }
+               break;
+               case 1: /* For Restoring Codec to Previous Power State */
+
+                       if(power_mask & 0x1) {
+
+                               snd_soc_update_bits(codec, PASI_DAC_DP_SETUP, 0xC0, 0xC0);
+
+                               poll_dac(codec, 0x0, 0x1);
+                               poll_dac(codec, 0x1, 0x1);
+                       }
+
+                       if(power_mask & 0x2) {
+
+                               snd_soc_update_bits(codec, ADC_CHANNEL_POW, 0xC0, 0xC0);
+
+                               poll_adc(codec, 0x0, 0x1);
+                               poll_adc(codec, 0x1, 0x1);
+                       }
+               break;
+               default:
+                       printk(KERN_ERR "#%s: Unknown Power State Requested..\n",
+                               __func__);
+       }
+
+       return minidsp_power_mask;
+
+}
+
 /*
  *----------------------------------------------------------------------------
  * Function  : boot_minidsp
@@ -853,9 +916,11 @@ int i2c_verify(struct snd_soc_codec *codec)
 int
 boot_minidsp(struct snd_soc_codec *codec, int new_mode)
 {
-struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec);
-struct process_flow *  pflows = &miniDSP_programs[new_mode];
-int (*ptransfer)(struct snd_soc_codec *codec,
+       struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec);
+       struct process_flow *  pflows = &miniDSP_programs[new_mode];
+       int minidsp_stat;
+
+       int (*ptransfer)(struct snd_soc_codec *codec,
                                reg_value *program_ptr,
                                int size);
 
@@ -871,15 +936,21 @@ int (*ptransfer)(struct snd_soc_codec *codec,
 #else
        ptransfer = minidsp_i2c_multibyte_transfer;
 #endif
-       ptransfer(codec, pflows->miniDSP_init,             pflows->init_size);
-          ptransfer(codec, pflows->miniDSP_A_values,  pflows->A_size);
-          ptransfer(codec, pflows->miniDSP_D_values,  pflows->D_size);
-          ptransfer(codec, pflows->miniDSP_post,                pflows->post_size);
 
+       minidsp_stat = change_codec_power_status (codec, 0x0, 0x3);
+
+       ptransfer(codec, pflows->miniDSP_init,             pflows->init_size);
+       ptransfer(codec, pflows->miniDSP_A_values,  pflows->A_size);
+       ptransfer(codec, pflows->miniDSP_D_values,  pflows->D_size);
+       ptransfer(codec, pflows->miniDSP_post,           pflows->post_size);
 
        aic326x->process_flow = new_mode;
 
+       change_codec_power_status(codec, 1, minidsp_stat);
+
+       aic3262_change_page( codec,0);
        aic3262_change_book( codec,0);
+
        return 0;
 }