misc: nct: error handling for no regulator
[linux-2.6.git] / drivers / misc / tfa9887.c
index ef91a96..6114140 100644 (file)
@@ -52,9 +52,13 @@ static int eq_mode, preset_mode, srate;
 
 static char calibdata[16];
 
-static int calibration_need = 0;
+static int calibration;
 
-unsigned int volume_step[5] = {0,2,4,6,12};
+static int recalibration;
+
+static int powerDown = 1;
+
+unsigned int volume_step[5] = {0, 2, 4, 6, 12};
 
 /* begin binary data: */
 unsigned char coldpatch_data[] = {/* 10 */
@@ -64,7 +68,6 @@ unsigned char coldpatch_data[] = {/* 10 */
 
 /* begin binary data: */
 
-
 /* begin binary data: */
 char n1d2_data[] = {/* 2380 */
 0x03, 0x00, 0x70, 0x00, 0x01, 0xFB, 0x00, 0x71, 0x40
@@ -477,25 +480,6 @@ int DspSetParam(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
        int rpcStatus = STATUS_OK;
        int tries = 0;
 
-#if 1
-    {
-        /* minimize the number of I2C transactions by making use of the autoincrement in I2C */
-        unsigned char buffer[7];
-        /* first the data for CF_CONTROLS */
-        buffer[0] = (unsigned char)((cf_ctrl >> 8) & 0xFF);
-        buffer[1] = (unsigned char)(cf_ctrl & 0xFF);
-        /* write the contents of CF_MAD which is the subaddress following CF_CONTROLS */
-        buffer[2] = (unsigned char)((cf_mad >> 8) & 0xFF);
-        buffer[3] = (unsigned char)(cf_mad & 0xFF);
-        /* write the module and RPC id into CF_MEM, which follows CF_MAD */
-        buffer[4] = 0;
-        buffer[5] = module_id + 128;
-        buffer[6] = param_id;
-        error =
-            regmap_raw_write(tfa9887_byte->regmap, TFA9887_CF_CONTROLS,
-                             buffer, sizeof(buffer));
-    }
-#else
        error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS, cf_ctrl);
        if (error == Tfa9887_Error_Ok) {
                error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, cf_mad);
@@ -507,7 +491,6 @@ int DspSetParam(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
                id[2] = param_id;
                error = regmap_raw_write(tfa9887_byte->regmap, TFA9887_CF_MEM,&id, 3);
        }
-#endif
 
        error = regmap_raw_write(tfa9887_byte->regmap, TFA9887_CF_MEM, data, num_bytes);
 
@@ -518,13 +501,13 @@ int DspSetParam(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
                do {
                        error = Tfa9887_ReadRegister(tfa9887, TFA9887_CF_STATUS, &cf_status);
                        tries++;
-                       udelay(100);
-               } while ( (error==Tfa9887_Error_Ok) && ((cf_status & 0x0100) == 0) && (tries < 10) ); /* don't wait forever, DSP is pretty quick to respond (< 1ms) */
+                       usleep_range(100, 200);
+               } while ((error == Tfa9887_Error_Ok) && ((cf_status & 0x0100) == 0) && (tries < 100)); /* don't wait forever, DSP is pretty quick to respond (< 1ms) */
 
-               if (tries >= 100) {
+               if (tries >= 100 && !powerDown) {
                        /* something wrong with communication with DSP */
-                       //pr_info("Setparam failed\n");
-                       error = -1;
+                       pr_info("Setparam failed\n");
+                       error = -1;
                }
        }
        cf_ctrl = 0x0002;
@@ -532,6 +515,7 @@ int DspSetParam(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
        if (error == Tfa9887_Error_Ok) {
                error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS,cf_ctrl);
     }
+
     if (error == Tfa9887_Error_Ok) {
             error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, cf_mad);
     }
@@ -581,12 +565,13 @@ int DspGetParam(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
                         error =
                             Tfa9887_ReadRegister(tfa9887, TFA9887_CF_STATUS,
                                                    &cf_status);
+                       msleep(1);
                         tries++;
-                }
-                while ((error == 0) && ((cf_status & 0x0100) == 0) && (tries < 10));     /* don't wait forever, DSP is pretty quick to respond (< 1ms) */
-                if (tries >= 10) {
+                } while (( error == 0) && ((cf_status & 0x0100) == 0)
+                       && (tries < 100));     /* don't wait forever, DSP is pretty quick to respond (< 1ms) */
+                if (tries >= 100) {
                         /* something wrong with communication with DSP */
-                       pr_info("something wrong with communication with DSP\n");
+                       pr_info("GetParam failed\n");
                         return -1;
                 }
         }
@@ -643,10 +628,15 @@ void calibrate (struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
        int data[2];
        int tries = 0;
 
-       if(calibration_need) {
+       if (!recalibration) {
                SetMute(tfa9887, Tfa9887_Mute_Digital);
                pr_info("Inside calib\n");
-               error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone);
+               while ((calibrateDone == 0) && (tries < 100)) {
+                       error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone);
+                       msleep(10);
+                       tries++;
+               }
+
                if (calibrateDone)
                {
                        DspGetParam(tfa9887, tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_GET_RE0, 3, bytes);
@@ -657,33 +647,52 @@ void calibrate (struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
                speaker_data[422] = 0;
                error = loadSettings(tfa9887, tfa9887_byte);
        }
+       calibrateDone = 0;
+       tries = 0;
+       /*SetConfigured*/
+       error = Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value);
 
-         //SetConfigured
-        error = Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value);
+       if (error == Tfa9887_Error_Ok) {
 
-        if(error == Tfa9887_Error_Ok)
-        {
                 value |= TFA9887_SYSCTRL_CONFIGURED;
                 error = Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value);
-        }
+       }
+       calibrateDone = 0;
+       tries = 0;
+
 
        error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone);
-       while ((calibrateDone == 0) && (tries < 1000)) {
+       while ((calibrateDone == 0) && (tries < 100)) {
                error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone);
+               msleep(10);
                tries++;
        }
-        if(tries >= 1000)
-                pr_info("Calibrate failed1\n");
+       if(tries >= 100)
+               pr_info("Calibrate failed1\n");
 
+       calibrateDone = 0;
        tries = 0;
+
        do {
                error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &status);
+               msleep(10);
                tries++;
        } while ( ((status & TFA9887_STATUS_MTPB) == TFA9887_STATUS_MTPB) && (tries < 100));
-       if(tries >= 100)
-               pr_info("Calibrate failed\n");
-        DspGetParam(tfa9887, tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_GET_RE0, 3, bytes);
-        convertBytes2Data(3, bytes, &data[0]);
+       if (tries >= 100)
+               pr_info("Calibrate failed2\n");
+
+       calibrateDone = 0;
+       tries = 0;
+       while ((calibrateDone == 0) && (tries < 100)) {
+                error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone);
+               msleep(10);
+                tries++;
+       }
+       if (tries >= 100)
+               pr_info("Calibrate failed3\n");
+
+       DspGetParam(tfa9887, tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_GET_RE0, 3, bytes);
+       convertBytes2Data(3, bytes, &data[0]);
        DspReadMem(tfa9887, tfa9887_byte, 232, 1, &data[1]);
        pr_info("%d %d\n",data[0], data[1]);
        memcpy(calibdata, (char *)data, 8);
@@ -696,7 +705,7 @@ void resetMtpEx(struct tfa9887_priv *tfa9887)
        int tries = 0;
        err = Tfa9887_ReadRegister(tfa9887, TFA9887_MTP, &mtp);
 
-       pr_info("%d****************1",mtp);
+       pr_info("%d****************mtp",mtp);
        /* all settings loaded, signal the DSP to start calibration, only needed once after cold boot */
        /* reset MTPEX bit if needed */
        err = Tfa9887_WriteRegister(tfa9887, 0x0B, 0x5A); /* unlock key2 */
@@ -706,6 +715,7 @@ void resetMtpEx(struct tfa9887_priv *tfa9887)
 
         do {
                 err = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &status);
+               msleep(10);
                tries++;
         } while ( ((status & TFA9887_STATUS_MTPB) == TFA9887_STATUS_MTPB) && (tries < 100));
 
@@ -727,58 +737,127 @@ int Tfa9887_Init(int sRate)
 {
        int error = 0;
        srate = sRate;
-       if((tfa9887R) && (tfa9887R->deviceInit)) {
-               coldStartup(tfa9887R, tfa9887R_byte, srate);
-                        //Tfa9887_WriteRegister(tfa9887R, 0x0B, 0x5A); /* unlock key2 */
-                        //Tfa9887_WriteRegister(tfa9887R, TFA9887_MTP, 0); /* MTPOTC=1, MTPEX=0 */
-
-               if((checkMTPEX(tfa9887R) == 0)) {
-                       calibration_need = 1;
-                        calibrate(tfa9887R, tfa9887R_byte, &calibdata[0]);
-               }
-               else {
-                       error = Init(tfa9887R,tfa9887R_byte, sRate);
-
+       if (tfa9887R) {
+               mutex_lock(&tfa9887R->lock);
+               if (tfa9887R->deviceInit) {
+                       coldStartup(tfa9887R, tfa9887R_byte, srate);
+                       //Tfa9887_WriteRegister(tfa9887R, 0x0B, 0x5A); /* unlock key2 */
+                       //Tfa9887_WriteRegister(tfa9887R, TFA9887_MTP, 0); /* MTPOTC=1, MTPEX=0 */
+                       setOtc(tfa9887R,1);
+
+                       if((checkMTPEX(tfa9887R) == 0)) {
+                               calibration = 1;
+                               calibrate(tfa9887R, tfa9887R_byte, &calibdata[0]);
+                       }
+                       else {
+                               error = Init(tfa9887R,tfa9887R_byte, sRate);
+
+                       }
                }
+               mutex_unlock(&tfa9887R->lock);
        }
-       if((tfa9887L) && (tfa9887L->deviceInit)) {
-               coldStartup(tfa9887L, tfa9887L_byte, srate);
-                        //Tfa9887_WriteRegister(tfa9887L, 0x0B, 0x5A); /* unlock key2 */
-                        //Tfa9887_WriteRegister(tfa9887L, TFA9887_MTP, 0); /* MTPOTC=1, MTPEX=0 */
-               if((checkMTPEX(tfa9887L) == 0)) {
-                       calibration_need = 1;
-                       calibrate(tfa9887L, tfa9887L_byte, &calibdata[8]);
-               }
-               else {
-                       error = Init(tfa9887L,tfa9887L_byte, sRate);
 
+       if (tfa9887L) {
+               mutex_lock(&tfa9887L->lock);
+               if (tfa9887L->deviceInit) {
+                       coldStartup(tfa9887L, tfa9887L_byte, srate);
+                       //Tfa9887_WriteRegister(tfa9887L, 0x0B, 0x5A); /* unlock key2 */
+                       //Tfa9887_WriteRegister(tfa9887L, TFA9887_MTP, 0); /* MTPOTC=1, MTPEX=0 */
+                       setOtc(tfa9887L,1);
+
+                       if((checkMTPEX(tfa9887L) == 0)) {
+                               calibration = 1;
+                               calibrate(tfa9887L, tfa9887L_byte, &calibdata[8]);
+                       }
+                       else {
+                               error = Init(tfa9887L,tfa9887L_byte, sRate);
+
+                       }
                }
+               mutex_unlock(&tfa9887L->lock);
        }
         if (error != 0)
                pr_info("Failed to Init tfa\n");
        return error;
 }
 
+void setOtc(struct tfa9887_priv *tfa9887, unsigned short otcOn)
+{
+
+       int err;
+       unsigned int mtp;
+       unsigned int status;
+       int mtpChanged = 0;
+       int tries = 0;
+
+       err = Tfa9887_ReadRegister(tfa9887, TFA9887_MTP, &mtp);
+       /* set reset MTPEX bit if needed */
+       if ( (mtp & TFA9887_MTP_MTPOTC) != otcOn) {
+       /* need to change the OTC bit, set MTPEX=0 in any case */
+               err = Tfa9887_WriteRegister(tfa9887, 0x0B, 0x5A); /* unlock key2 */
+
+               err = Tfa9887_WriteRegister(tfa9887, TFA9887_MTP, otcOn); /* MTPOTC=otcOn, MTPEX=0 */
+
+               err = Tfa9887_WriteRegister(tfa9887, 0x62, 1<<11); /* CIMTP=1 */
+
+               mtpChanged =1;
+
+       }
+       //Sleep(13*16); /* need to wait until all parameters are copied into MTP */
+       do {
+               err = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &status);
+               msleep(10);
+               tries++;
+       } while ( ((status & TFA9887_STATUS_MTPB) == TFA9887_STATUS_MTPB) && (tries < 100));
+
+       if (mtpChanged) {
+               /* ensure the DSP restarts after this to read out the new value */
+               err = Tfa9887_WriteRegister(tfa9887, 0x70, 0x1); /* DSP reset */
+       }
+
+}
+
 int Tfa9887_SetEq(void)
 {
-        int error = 0;
-       if((tfa9887R) && (tfa9887R->deviceInit))
-               error = SetEq(tfa9887R,tfa9887R_byte);
-       if((tfa9887L) && (tfa9887L->deviceInit))
-               error = SetEq(tfa9887L,tfa9887L_byte);
-        return error;
+       int error = 0;
+
+       if (tfa9887R) {
+               mutex_lock(&tfa9887R->lock);
+               if (tfa9887R->deviceInit)
+                       error = SetEq(tfa9887R, tfa9887R_byte);
+               mutex_unlock(&tfa9887R->lock);
+       }
+
+       if (tfa9887L) {
+               mutex_lock(&tfa9887L->lock);
+               if (tfa9887L->deviceInit)
+                       error = SetEq(tfa9887L, tfa9887L_byte);
+               mutex_unlock(&tfa9887L->lock);
+       }
+       return error;
 }
 
-int Tfa9887_SetPreset(void)
+int Tfa9887_SetPreset(unsigned int preset)
 {
-        int error = 0;
-        unsigned short status;
+       int error = 0;
+       if (preset != preset_mode) {
+               preset_mode = preset;
+
+               if (tfa9887R) {
+                       mutex_lock(&tfa9887R->lock);
+                       if (tfa9887R->deviceInit)
+                               error = SetPreset(tfa9887R, tfa9887R_byte);
+                       mutex_unlock(&tfa9887R->lock);
+               }
 
-        if((tfa9887R) && (tfa9887R->deviceInit))
-                error = SetPreset(tfa9887R,tfa9887R_byte);
-        if((tfa9887L) && (tfa9887L->deviceInit))
-                error = SetPreset(tfa9887L,tfa9887L_byte);
-        return error;
+               if (tfa9887L) {
+                       mutex_lock(&tfa9887L->lock);
+                       if (tfa9887L->deviceInit)
+                               error = SetPreset(tfa9887L, tfa9887L_byte);
+                       mutex_unlock(&tfa9887L->lock);
+               }
+       }
+       return error;
 }
 
 int coldStartup(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, int sRate)
@@ -888,6 +967,7 @@ int coldStartup(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte,
                error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &value);
                do {
                        error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &value);
+                       msleep(1);
                        tries++;
                } while ((error == Tfa9887_Error_Ok) && ((value & TFA9887_STATUS_PLLS) == 0) && (tries < 100));
 
@@ -924,7 +1004,7 @@ int Init(struct tfa9887_priv *tfa9887,struct tfa9887_priv *tfa9887_byte, int sRa
                 value |= TFA9887_SYSCTRL_CONFIGURED;
                 error = Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value);
         }
-       if (!calibration_need) {
+       if (!calibration) {
                SetMute(tfa9887, Tfa9887_Mute_Amplifier);
                //PowerDown
                if(error == Tfa9887_Error_Ok)
@@ -956,6 +1036,7 @@ int SetPreset(struct tfa9887_priv *tfa9887,struct tfa9887_priv *tfa9887_byte)
        int error = 0;
        unsigned int value = 0;
        unsigned int volume_value = 0;
+
     switch(preset_mode) {
             case 0:
                                        error = DspSetParam(tfa9887,tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_SET_PRESET, 87, preset_data0);
@@ -1065,10 +1146,22 @@ int stereoRouting(struct tfa9887_priv *tfa9887)
 int Tfa9887_Powerdown(int powerdown)
 {
        int error = 0;
-       if((tfa9887R) && (tfa9887R->deviceInit))
-               error = Powerdown(tfa9887R, tfa9887R_byte, powerdown);
-       if((tfa9887L) && (tfa9887L->deviceInit))
-               error = Powerdown(tfa9887L, tfa9887L_byte, powerdown);
+
+       powerDown = powerdown;
+
+       if (tfa9887R) {
+               mutex_lock(&tfa9887R->lock);
+               if (tfa9887R->deviceInit)
+                       error = Powerdown(tfa9887R, tfa9887R_byte, powerdown);
+               mutex_unlock(&tfa9887R->lock);
+       }
+
+       if (tfa9887L) {
+               mutex_lock(&tfa9887L->lock);
+               if (tfa9887L->deviceInit)
+                       error = Powerdown(tfa9887L, tfa9887L_byte, powerdown);
+               mutex_unlock(&tfa9887L->lock);
+       }
        return error;
 }
 
@@ -1103,7 +1196,6 @@ int Powerdown(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, i
                SetEq(tfa9887,tfa9887_byte);
        }
 
-
         return error;
 }
 
@@ -1187,18 +1279,19 @@ static ssize_t tfa9887_cal_show(struct kobject *kobj,
                struct kobj_attribute *attr, char *buf)
 {
        //printk("!tfa9887_cal_show\n");
-       if(calibration_need) {
+       if (calibration) {
                memcpy(buf, calibdata, 16);
+               return 16;
                //pr_info("copying data\n");
        }
-       return 16;
+       else
+       return -1;
 }
 
 static ssize_t tfa9887_cal_store(struct kobject *kobj,
        struct kobj_attribute *attr, const char *buf, size_t count)
 {
        ssize_t ret = count;
-       unsigned int value;
        //printk("+tfa9887_cal_store: %p, %d\n", buf, count);
 
        if (!buf || !count) {
@@ -1206,50 +1299,56 @@ static ssize_t tfa9887_cal_store(struct kobject *kobj,
                goto fail;
        }
        if (count == 6) {
-               if(calibration_need) {
+               if (calibration) {
+                       recalibration = 1;
+                       tegra_asoc_enable_clocks();
                        memcpy(&speaker_data[420],buf,3);
+                       recalibrate(tfa9887R, tfa9887R_byte);
                        memcpy(&speaker_data[420],buf+3,3);
-                       tegra_asoc_enable_clocks();
-                       resetMtpEx(tfa9887R);
-                       resetMtpEx(tfa9887L);
-                       SetMute(tfa9887R, Tfa9887_Mute_Amplifier);
-                       SetMute(tfa9887L, Tfa9887_Mute_Amplifier);
-                       coldStartup(tfa9887R, tfa9887R_byte, srate);
-                       Init(tfa9887R,tfa9887R_byte, srate);
-                       coldStartup(tfa9887L, tfa9887L_byte, srate);
-                       Init(tfa9887L,tfa9887L_byte, srate);
-                       calibration_need = 0;
-                       calibrate(tfa9887R, tfa9887R_byte, &calibdata[0]);
-                       calibrate(tfa9887L, tfa9887L_byte, &calibdata[0]);
-                        Tfa9887_ReadRegister(tfa9887R, TFA9887_SYSTEM_CONTROL, &value);
-                        value |= TFA9887_SYSCTRL_POWERDOWN;
-                        Tfa9887_WriteRegister(tfa9887R, TFA9887_SYSTEM_CONTROL, value);
-                        Tfa9887_ReadRegister(tfa9887L, TFA9887_SYSTEM_CONTROL, &value);
-                        value |= TFA9887_SYSCTRL_POWERDOWN;
-                        Tfa9887_WriteRegister(tfa9887L, TFA9887_SYSTEM_CONTROL, value);
+                       recalibrate(tfa9887L, tfa9887L_byte);
+                       recalibration = 0;
+                       calibration = 0;
                        tegra_asoc_disable_clocks();
                }
        }
-
 fail:
        //printk("-tfa9887_cal_store: %d\n", count);
        return ret;
 }
 
+void recalibrate(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte) {
+
+       unsigned int value;
+       if (tfa9887) {
+               mutex_lock(&tfa9887->lock);
+               if (tfa9887->deviceInit) {
+                       resetMtpEx(tfa9887);
+                       SetMute(tfa9887, Tfa9887_Mute_Amplifier);
+                       coldStartup(tfa9887, tfa9887_byte, srate);
+                       Init(tfa9887,tfa9887_byte, srate);
+                       calibrate(tfa9887, tfa9887_byte, &calibdata[0]);
+                       Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value);
+                       value |= TFA9887_SYSCTRL_POWERDOWN;
+                       Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value);
+               }
+               mutex_unlock(&tfa9887->lock);
+       }
+}
 
 static ssize_t tfa9887_config_show(struct kobject *kobj,
                struct kobj_attribute *attr, char *buf)
 {
-       printk("!tfa9887_config_show\n");
+       //printk("!tfa9887_config_show\n");
 
        if (buf) {
                if (eq_mode == 1)
-                       memcpy(buf, '1', 1);
+                       *buf = '1';
                else if (eq_mode == 2)
-                       memcpy(buf, '2', 1);
+                       *buf = '2';
                else
                        return -EINVAL;
        }
+       printk("%c\n",*buf);
        return 1;
 }
 
@@ -1289,25 +1388,20 @@ static ssize_t tfa9887_vol_store(struct kobject *kobj,
        struct kobj_attribute *attr, const char *buf, size_t count)
 {
        ssize_t ret = count;
+       unsigned int preset;
 
        //printk("+tfa9887_vol_store: %d, %d\n", *buf, count);
 
-       if (!tfa9887R || !tfa9887L ||
-               !tfa9887R->deviceInit || !tfa9887L->deviceInit) {
-               ret = -EINVAL;
-               goto fail;
-       }
-
        if (!buf || !count) {
                ret = -EINVAL;
                goto fail;
        }
        if (*buf >= DB_CUTOFF_INDEX)
-               preset_mode = MAX_DB_INDEX - *buf;
+               preset = MAX_DB_INDEX - *buf;
        else
-               preset_mode = PRESET_DEFAULT;
+               preset = PRESET_DEFAULT;
 
-       Tfa9887_SetPreset();
+       Tfa9887_SetPreset(preset);
 fail:
        //printk("-tfa9887_vol_store: %d\n", count);
        return ret;
@@ -1338,6 +1432,7 @@ static __devinit int tfa9887R_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, tfa9887R);
        i2c_set_clientdata(i2c, tfa9887R_byte);
+       mutex_init(&tfa9887R->lock);
        tfa9887R->irq = i2c->irq;
        tfa9887R_byte->irq = i2c->irq;
        ret = regmap_read(tfa9887R->regmap, TFA9887_REVISIONNUMBER, &val);
@@ -1349,24 +1444,28 @@ static __devinit int tfa9887R_i2c_probe(struct i2c_client *i2c,
        tfa9887_kobj = kobject_create_and_add("tfa9887", kernel_kobj);
 
        ret = sysfs_create_file(tfa9887_kobj, &tfa9887_config);
-       printk("tfa9887_add_sysfs ret=%d",ret);
+       printk("tfa9887_add_sysfs ret=%d\n", ret);
        if (ret != 0) {
                 dev_err(&i2c->dev, "Failed to add sysfs: %d\n", ret);
                goto err;
        }
        ret = sysfs_create_file(tfa9887_kobj, &tfa9887_cal);
-       printk("tfa9887_add_sysfs ret=%d",ret);
+       printk("tfa9887_add_sysfs ret=%d\n", ret);
        if (ret != 0) {
                 dev_err(&i2c->dev, "Failed to add sysfs: %d\n", ret);
                goto err;
        }
        ret = sysfs_create_file(tfa9887_kobj, &tfa9887_vol);
-       printk("tfa9887_add_sysfs ret=%d",ret);
+       printk("tfa9887_add_sysfs ret=%d\n", ret);
        if (ret != 0) {
                 dev_err(&i2c->dev, "Failed to add sysfs: %d\n", ret);
                goto err;
        }
-       tfa9887R->deviceInit = true;
+       if (tfa9887R) {
+               mutex_lock(&tfa9887R->lock);
+               tfa9887R->deviceInit = true;
+               mutex_unlock(&tfa9887R->lock);
+       }
        eq_mode = IN_HAND_MODE;
        preset_mode = PRESET_DEFAULT;
        return 0;
@@ -1386,6 +1485,17 @@ static __devexit int tfa9887R_i2c_remove(struct i2c_client *client)
        return 0;
 }
 
+static void tfa9887R_i2c_shutdown(struct i2c_client *i2c)
+{
+       if (tfa9887R) {
+               mutex_lock(&tfa9887R->lock);
+               if (i2c->irq)
+                       disable_irq(i2c->irq);
+               tfa9887R->deviceInit = false;
+               mutex_unlock(&tfa9887R->lock);
+        }
+}
+
 static const struct of_device_id tfa9887R_of_match[] = {
        { .compatible = "nxp,tfa9887R", },
        {},
@@ -1407,6 +1517,7 @@ static struct i2c_driver tfa9887R_i2c_driver = {
         .probe =    tfa9887R_i2c_probe,
         .remove =   __devexit_p(tfa9887R_i2c_remove),
         .id_table = tfa9887R_i2c_id,
+        .shutdown = tfa9887R_i2c_shutdown,
 };
 
 static __devinit int tfa9887L_i2c_probe(struct i2c_client *i2c,
@@ -1433,6 +1544,7 @@ static __devinit int tfa9887L_i2c_probe(struct i2c_client *i2c,
        }
 
        i2c_set_clientdata(i2c, tfa9887L);
+       mutex_init(&tfa9887L->lock);
        tfa9887L->irq = i2c->irq;
        ret = regmap_read(tfa9887L->regmap, TFA9887_REVISIONNUMBER, &val);
        if (ret != 0) {
@@ -1440,7 +1552,11 @@ static __devinit int tfa9887L_i2c_probe(struct i2c_client *i2c,
                goto err;
        }
        dev_info(&i2c->dev, "TFA9887 revision %d\n",val);
-       tfa9887L->deviceInit = true;
+       if (tfa9887L) {
+               mutex_lock(&tfa9887L->lock);
+               tfa9887L->deviceInit = true;
+               mutex_unlock(&tfa9887L->lock);
+       }
        return 0;
 err:
        regmap_exit(tfa9887L->regmap);
@@ -1454,6 +1570,17 @@ static __devexit int tfa9887L_i2c_remove(struct i2c_client *client)
        return 0;
 }
 
+static void tfa9887L_i2c_shutdown(struct i2c_client *i2c)
+{
+       if (tfa9887L) {
+               mutex_lock(&tfa9887L->lock);
+               if (i2c->irq)
+                       disable_irq(i2c->irq);
+               tfa9887L->deviceInit = false;
+               mutex_unlock(&tfa9887L->lock);
+       }
+}
+
 static const struct of_device_id tfa9887L_of_match[] = {
        { .compatible = "nxp,tfa9887L", },
        {},
@@ -1475,6 +1602,7 @@ static struct i2c_driver tfa9887L_i2c_driver = {
         .probe =    tfa9887L_i2c_probe,
         .remove =   __devexit_p(tfa9887L_i2c_remove),
         .id_table = tfa9887L_i2c_id,
+        .shutdown = tfa9887L_i2c_shutdown,
 };
 
 static int __init tfa9887_modinit(void)