update for support non-interrupt applications
authorPeter Li <peter-li@ti.com>
Fri, 10 Mar 2017 02:25:50 +0000 (10:25 +0800)
committerPeter Li <peter-li@ti.com>
Fri, 10 Mar 2017 02:25:50 +0000 (10:25 +0800)
DRV2624EVMmini_20170309.h [new file with mode: 0755]
DRV2624EVMmini_20170309.xml [new file with mode: 0755]
drv2624.bin
drv2624.c
drv2624.h

diff --git a/DRV2624EVMmini_20170309.h b/DRV2624EVMmini_20170309.h
new file mode 100755 (executable)
index 0000000..a83a5b0
--- /dev/null
@@ -0,0 +1,16 @@
+/*\r
+** =============================================================================\r
+** Created at 4:58:12 PM\r
+** Target : DRV2624EVMmini\r
+** Please be noted that the data begin at address 0x0000.\r
+** =============================================================================\r
+*/\r
+\r
+const static unsigned char wavedata[25]={\r
+0x00, /* version byte */\r
+0x0, 0x7, 0x4, /* header for waveform 0*/
+0x0, 0xb, 0xe, /* header for waveform 1*/
+0x3f, 0x9, 0x41, 0x5, 0x3f, 0x4, 0x13, 0x6, 0x41, 0x3, 0x0, 0xc, 0x3f, 0x4, 0x13, 0x6, 
+0x41, 0x3
+};
+\r
diff --git a/DRV2624EVMmini_20170309.xml b/DRV2624EVMmini_20170309.xml
new file mode 100755 (executable)
index 0000000..45d35c9
--- /dev/null
@@ -0,0 +1,36 @@
+<library>\r
+  <magic>0x2624</magic>\r
+  <size>45</size>\r
+  <date>0x20170309</date>\r
+  <checksum>0x2ba</checksum>\r
+  <count>2</count>\r
+  <effect>\r
+    <header>\r
+      <offset>0x7</offset>\r
+      <repeat>0</repeat>\r
+      <length>4</length>\r
+      <duration>70ms</duration>\r
+    </header>\r
+    <data>\r
+      <point>0x3f09</point>\r
+      <point>0x4105</point>\r
+    </data>\r
+  </effect>\r
+  <effect>\r
+    <header>\r
+      <offset>0xb</offset>\r
+      <repeat>0</repeat>\r
+      <length>14</length>\r
+      <duration>190ms</duration>\r
+    </header>\r
+    <data>\r
+      <point>0x3f04</point>\r
+      <point>0x1306</point>\r
+      <point>0x4103</point>\r
+      <point>0xc</point>\r
+      <point>0x3f04</point>\r
+      <point>0x1306</point>\r
+      <point>0x4103</point>\r
+    </data>\r
+  </effect>\r
+</library>
\ No newline at end of file
index 295334b951ecaeb3c605b2a49469ce6ca044cc41..1d3c66fac170ef0eef6f34011fa52d2f3913691f 100755 (executable)
Binary files a/drv2624.bin and b/drv2624.bin differ
index 481d57dc0dc3ca1e1abafc8acae7760fbadf7353..502ce00aa95ec5e4dbfb04b8cc79171b4a178af5 100755 (executable)
--- a/drv2624.c
+++ b/drv2624.c
 #include <linux/miscdevice.h>
 #include "drv2624.h"
 
-//#define      AUTOCALIBRATION_ENABLE
 
 static struct drv2624_data *g_DRV2624data = NULL;
+static bool g_logEnable = false;
 
-static int drv2624_reg_read(struct drv2624_data *pDRV2624, unsigned char reg)
+static int drv2624_reg_read(struct drv2624_data *pDRV2624,
+       unsigned char reg)
 {
        unsigned int val;
-       int ret;
-
-       mutex_lock(&pDRV2624->dev_lock);        
-       ret = regmap_read(pDRV2624->mpRegmap, reg, &val);
-    mutex_unlock(&pDRV2624->dev_lock); 
-
-       if (ret < 0){
-               dev_err(pDRV2624->dev, 
-                       "%s reg=0x%x error %d\n", __FUNCTION__, reg, ret);
-               return ret;
-       }else{
-               dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]=0x%x\n", 
-                       __FUNCTION__, reg, val);
+       int nResult;
+
+       mutex_lock(&pDRV2624->dev_lock);
+       nResult = regmap_read(pDRV2624->mpRegmap, reg, &val);
+    mutex_unlock(&pDRV2624->dev_lock);
+
+       if (nResult < 0) {
+               dev_err(pDRV2624->dev, "%s I2C error %d\n", __func__, nResult);
+               return nResult;
+       } else {
+               if (g_logEnable)
+                       dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]=0x%x\n", __func__, reg, val);
                return val;
        }
 }
 
-static int drv2624_reg_write(struct drv2624_data *pDRV2624, 
+static int drv2624_reg_write(struct drv2624_data *pDRV2624,
        unsigned char reg, unsigned char val)
 {
-       int ret;
-
-       mutex_lock(&pDRV2624->dev_lock);                
-       ret = regmap_write(pDRV2624->mpRegmap, reg, val);
-    mutex_unlock(&pDRV2624->dev_lock);         
-       if (ret < 0){
-               dev_err(pDRV2624->dev, 
-                       "%s reg=0x%x, value=0%x error %d\n", 
-                       __FUNCTION__, reg, val, ret);
-       }else{
-               dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]=0x%x\n", 
-                       __FUNCTION__, reg, val);
-       }
-       
-       return ret;
+       int nResult;
+
+       mutex_lock(&pDRV2624->dev_lock);
+       nResult = regmap_write(pDRV2624->mpRegmap, reg, val);
+       mutex_unlock(&pDRV2624->dev_lock);
+       if (nResult < 0)
+               dev_err(pDRV2624->dev, "%s reg=0x%x, value=0%x error %d\n",
+                       __func__, reg, val, nResult);
+       else if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]=0x%x\n", __func__, reg, val);
+
+       return nResult;
 }
 
-static int drv2624_bulk_read(struct drv2624_data *pDRV2624, 
-       unsigned char reg, u8 *buf, unsigned int count)
+static int drv2624_bulk_read(struct drv2624_data *pDRV2624,
+       unsigned char reg, unsigned char *buf, unsigned int count)
 {
-       int ret;
-       mutex_lock(&pDRV2624->dev_lock);        
-       ret = regmap_bulk_read(pDRV2624->mpRegmap, reg, buf, count);
-    mutex_unlock(&pDRV2624->dev_lock);         
-       if (ret < 0){
-               dev_err(pDRV2624->dev, 
-                       "%s reg=0%x, count=%d error %d\n", 
-                       __FUNCTION__, reg, count, ret);
-       }
-       
-       return ret;
+       int nResult;
+
+       mutex_lock(&pDRV2624->dev_lock);
+       nResult = regmap_bulk_read(pDRV2624->mpRegmap, reg, buf, count);
+       mutex_unlock(&pDRV2624->dev_lock);
+       if (nResult < 0)
+               dev_err(pDRV2624->dev, "%s reg=0%x, count=%d error %d\n",
+                       __func__, reg, count, nResult);
+
+       return nResult;
 }
 
-static int drv2624_bulk_write(struct drv2624_data *pDRV2624, 
+static int drv2624_bulk_write(struct drv2624_data *pDRV2624,
        unsigned char reg, const u8 *buf, unsigned int count)
 {
-       int ret, i;
-       mutex_lock(&pDRV2624->dev_lock);        
-       ret = regmap_bulk_write(pDRV2624->mpRegmap, reg, buf, count);
-    mutex_unlock(&pDRV2624->dev_lock);         
-       if (ret < 0){
-               dev_err(pDRV2624->dev, 
-                       "%s reg=0%x, count=%d error %d\n", 
-                       __FUNCTION__, reg, count, ret);
-       }else{
+       int nResult, i;
+
+       mutex_lock(&pDRV2624->dev_lock);
+       nResult = regmap_bulk_write(pDRV2624->mpRegmap, reg, buf, count);
+       mutex_unlock(&pDRV2624->dev_lock);
+       if (nResult < 0)
+               dev_err(pDRV2624->dev, "%s reg=0%x, count=%d error %d\n",
+                       __func__, reg, count, nResult);
+       else if (g_logEnable)
                for(i = 0; i < count; i++)
-                       dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]=0x%x\n", 
-                               __FUNCTION__,reg+i, buf[i]);
-       }
-       return ret;     
+                       dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]=0x%x\n",
+                               __func__, reg+i, buf[i]);
+
+       return nResult;
 }
 
-static int drv2624_set_bits(struct drv2624_data *pDRV2624, 
+static int drv2624_set_bits(struct drv2624_data *pDRV2624,
        unsigned char reg, unsigned char mask, unsigned char val)
 {
-       int ret;
-    mutex_lock(&pDRV2624->dev_lock);           
-       ret = regmap_update_bits(pDRV2624->mpRegmap, reg, mask, val);
-       mutex_unlock(&pDRV2624->dev_lock);      
-       if (ret < 0){
-               dev_err(pDRV2624->dev, 
-                       "%s reg=%x, mask=0x%x, value=0x%x error %d\n", 
-                       __FUNCTION__, reg, mask, val, ret);
-       }else{
-               dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]:M=0x%x, V=0x%x\n", 
-                       __FUNCTION__, reg, mask, val);
-       }
-       
-       return ret;     
+       int nResult;
+
+       mutex_lock(&pDRV2624->dev_lock);
+       nResult = regmap_update_bits(pDRV2624->mpRegmap, reg, mask, val);
+       mutex_unlock(&pDRV2624->dev_lock);
+       if (nResult < 0)
+               dev_err(pDRV2624->dev, "%s reg=%x, mask=0x%x, value=0x%x error %d\n",
+                       __func__, reg, mask, val, nResult);
+       else if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "%s, Reg[0x%x]:M=0x%x, V=0x%x\n",
+                       __func__, reg, mask, val);
+
+       return nResult;
 }
 
-static void drv2624_enableIRQ(struct drv2624_data *pDRV2624, unsigned char bRTP)
+static int drv2624_enableIRQ(struct drv2624_data *pDRV2624, unsigned char bRTP)
 {
+       int nResult = 0;
        unsigned char mask = INT_ENABLE_CRITICAL;
-       
-       if(bRTP == 0){
+
+       if (!pDRV2624->mbIRQUsed)
+               goto end;
+
+       if (pDRV2624->mbIRQEnabled)
+               goto end;
+
+       if (bRTP == 0)
                mask = INT_ENABLE_ALL;
-       }
-       
-       drv2624_reg_read(pDRV2624,DRV2624_REG_STATUS);  
-       drv2624_reg_write(pDRV2624, DRV2624_REG_INT_ENABLE, mask);
+
+       nResult = drv2624_reg_read(pDRV2624,DRV2624_REG_STATUS);
+       if (nResult < 0)
+               goto end;
+       nResult = drv2624_reg_write(pDRV2624, DRV2624_REG_INT_ENABLE, mask);
+       if (nResult < 0)
+               goto end;
+
        enable_irq(pDRV2624->mnIRQ);
+       pDRV2624->mbIRQEnabled = true;
+
+end:
+
+       return nResult;
 }
 
 static void drv2624_disableIRQ(struct drv2624_data *pDRV2624)
 {
-       disable_irq(pDRV2624->mnIRQ);
-       drv2624_reg_write(pDRV2624, DRV2624_REG_INT_ENABLE, INT_MASK_ALL);
+       if (pDRV2624->mbIRQUsed) {
+               if (pDRV2624->mbIRQEnabled) {
+                       disable_irq_nosync(pDRV2624->mnIRQ);
+                       drv2624_reg_write(pDRV2624, DRV2624_REG_INT_ENABLE, INT_MASK_ALL);
+                       pDRV2624->mbIRQEnabled = false;
+               }
+       }
 }
 
 static int drv2624_set_go_bit(struct drv2624_data *pDRV2624, unsigned char val)
 {
-       int ret = 0, value =0;
-       int retry = 10; // to finish auto-brake
-       
-       val &= 0x01;    
-       ret = drv2624_reg_write(pDRV2624, DRV2624_REG_GO, val);
-       if(ret >= 0 ){          
-               if(val == 1){
-                       mdelay(1);
+       int nResult = 0, value =0;
+       int retry = POLL_GO_BIT_RETRY; 
+
+       val &= 0x01;
+       nResult = drv2624_reg_write(pDRV2624, DRV2624_REG_GO, val);
+       if (nResult < 0) 
+               goto end;
+
+       mdelay(POLL_GO_BIT_INTERVAL);
+       value = drv2624_reg_read(pDRV2624, DRV2624_REG_GO);
+       if (value < 0) {
+               nResult = value;
+               goto end;
+       }
+
+       if (val) {
+               if (value != GO) {
+                       nResult = -EIO;
+                       dev_warn(pDRV2624->dev, "%s, GO fail, stop action\n", __func__);
+               }
+       } else {
+               while (retry > 0) {
                        value = drv2624_reg_read(pDRV2624, DRV2624_REG_GO);
-                       if(value < 0){
-                               ret = value;
-                       }else if(value != 1){
-                               ret = -1;
-                               dev_warn(pDRV2624->dev, 
-                                       "%s, GO fail, stop action\n", __FUNCTION__);
-                       }
-               }else{
-                       while(retry > 0){
-                               value = drv2624_reg_read(pDRV2624, DRV2624_REG_GO);
-                               if(value < 0){
-                                       ret = value;
-                                       break;
-                               }
-                               
-                               if(value==0) break;
-                               mdelay(10);
-                               retry--;                                
-                       }       
-                       
-                       if(retry == 0){
-                               dev_err(pDRV2624->dev, 
-                                       "%s, ERROR: clear GO fail\n", __FUNCTION__);
+                       if (value < 0) {
+                               nResult = value;
+                               break;
                        }
+
+                       if(value==0)
+                               break;
+
+                       mdelay(POLL_GO_BIT_INTERVAL);
+                       retry--;
                }
+
+               if (retry == 0)
+                       dev_err(pDRV2624->dev,
+                               "%s, ERROR: clear GO fail\n", __func__);
+               else if (g_logEnable)
+                       dev_dbg(pDRV2624->dev,
+                               "%s, clear GO, remain=%d\n", __func__, retry);
        }
-               
-       return ret;
+
+end:
+
+       return nResult;
 }
 
-static void drv2624_change_mode(struct drv2624_data *pDRV2624, unsigned char work_mode)
+static int drv2624_change_mode(struct drv2624_data *pDRV2624,
+       unsigned char work_mode)
 {
-       drv2624_set_bits(pDRV2624, DRV2624_REG_MODE, WORKMODE_MASK , work_mode);
+       return drv2624_set_bits(pDRV2624,
+                       DRV2624_REG_MODE, WORKMODE_MASK, work_mode);
 }
 
 static int vibrator_get_time(struct timed_output_dev *dev)
 {
        struct drv2624_data *pDRV2624 = container_of(dev, struct drv2624_data, to_dev);
 
-    if (hrtimer_active(&pDRV2624->timer)) {
-        ktime_t r = hrtimer_get_remaining(&pDRV2624->timer);
-        return ktime_to_ms(r);
-    }
+       if (hrtimer_active(&pDRV2624->timer)) {
+               ktime_t r = hrtimer_get_remaining(&pDRV2624->timer);
+               return ktime_to_ms(r);
+       }
 
-    return 0;
+       return 0;
 }
 
-static void drv2624_stop(struct drv2624_data *pDRV2624)
+static void drv2624_set_stopflag(struct drv2624_data *pDRV2624)
 {
-       if(pDRV2624->mnVibratorPlaying == YES){
-               dev_dbg(pDRV2624->dev, "%s\n", __FUNCTION__);
-               drv2624_disableIRQ(pDRV2624);
-               hrtimer_cancel(&pDRV2624->timer);       
-               drv2624_set_go_bit(pDRV2624, STOP);
-               pDRV2624->mnVibratorPlaying = NO;
-               wake_unlock(&pDRV2624->wklock);
+       pDRV2624->mnVibratorPlaying = NO;
+       wake_unlock(&pDRV2624->wklock);
+       if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "wklock unlock");
+}
+
+static int drv2624_get_diag_result(struct drv2624_data *pDRV2624, unsigned char nStatus)
+{
+       int nResult = 0;
+
+       pDRV2624->mDiagResult.mnResult = nStatus;
+       if((nStatus&DIAG_MASK) != DIAG_SUCCESS)
+               dev_err(pDRV2624->dev, "Diagnostic fail\n");
+       else {
+               nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_DIAG_Z);
+               if (nResult < 0)
+                       goto end;
+               pDRV2624->mDiagResult.mnDiagZ = nResult;
+
+               nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_DIAG_K);
+               if (nResult < 0)
+                       goto end;
+               pDRV2624->mDiagResult.mnDiagK = nResult;
+
+               dev_dbg(pDRV2624->dev, "Diag : ZResult=0x%x, CurrentK=0x%x\n",
+                       pDRV2624->mDiagResult.mnDiagZ,
+                       pDRV2624->mDiagResult.mnDiagK);
+       }
+
+end:
+       return nResult;
+}
+
+static int drv2624_get_calibration_result(struct drv2624_data *pDRV2624, unsigned char nStatus)
+{
+       int nResult = 0;
+
+       pDRV2624->mAutoCalResult.mnResult = nStatus;
+       if ((nStatus&DIAG_MASK) != DIAG_SUCCESS)
+               dev_err(pDRV2624->dev, "Calibration fail\n");
+       else {
+               nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_CAL_COMP);
+               if (nResult < 0)
+                       goto end;
+               pDRV2624->mAutoCalResult.mnCalComp = nResult;
+
+               nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_CAL_BEMF);
+               if (nResult < 0)
+                       goto end;
+               pDRV2624->mAutoCalResult.mnCalBemf = nResult;
+
+               nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_CAL_COMP) & BEMFGAIN_MASK;
+               if (nResult < 0)
+                       goto end;
+               pDRV2624->mAutoCalResult.mnCalGain = nResult;
+
+               dev_dbg(pDRV2624->dev, "AutoCal : Comp=0x%x, Bemf=0x%x, Gain=0x%x\n",
+                       pDRV2624->mAutoCalResult.mnCalComp,
+                       pDRV2624->mAutoCalResult.mnCalBemf,
+                       pDRV2624->mAutoCalResult.mnCalGain);
        }
+end:
+       return nResult;
+}
+
+static int drv2624_stop(struct drv2624_data *pDRV2624)
+{
+       int nResult = 0;
+
+       if (pDRV2624->mnVibratorPlaying == YES) {
+               dev_dbg(pDRV2624->dev, "%s\n", __func__);
+               if (pDRV2624->mbIRQUsed)
+                       drv2624_disableIRQ(pDRV2624);
+               if (hrtimer_active(&pDRV2624->timer))
+                       hrtimer_cancel(&pDRV2624->timer);
+               nResult = drv2624_set_go_bit(pDRV2624, STOP);
+               drv2624_set_stopflag(pDRV2624);
+       }
+
+       return nResult;
 }
 
 static void vibrator_enable( struct timed_output_dev *dev, int value)
 {
-       int ret = 0;
+       int nResult = 0;
        struct drv2624_data *pDRV2624 = 
                container_of(dev, struct drv2624_data, to_dev);
-       //int status;
-       
-       dev_dbg(pDRV2624->dev, 
-               "%s, value=%d\n", __FUNCTION__, value);
-               
-    mutex_lock(&pDRV2624->lock);
-       
+
+       dev_dbg(pDRV2624->dev, "%s, value=%d\n", __func__, value);
+
+       mutex_lock(&pDRV2624->lock);
+
        pDRV2624->mnWorkMode = WORK_IDLE;
-       dev_dbg(pDRV2624->dev, 
-               "%s, afer mnWorkMode=0x%x\n", 
-               __FUNCTION__, pDRV2624->mnWorkMode);
-               
+       if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "%s, afer mnWorkMode=0x%x\n", 
+                       __func__, pDRV2624->mnWorkMode);
+
        drv2624_stop(pDRV2624);
 
-    if (value > 0) {
+       if (value > 0) {
                wake_lock(&pDRV2624->wklock);
-       
-               drv2624_change_mode(pDRV2624, MODE_RTP);
-               pDRV2624->mnVibratorPlaying = YES;
-               drv2624_enableIRQ(pDRV2624, YES);       
-               ret = drv2624_set_go_bit(pDRV2624, GO);
-               if(ret <0){
-                       dev_warn(pDRV2624->dev, "Start RTP failed\n");
-                       wake_unlock(&pDRV2624->wklock);
-                       pDRV2624->mnVibratorPlaying = NO;
-                       drv2624_disableIRQ(pDRV2624);
-               }else{
-                       value = (value>MAX_TIMEOUT)?MAX_TIMEOUT:value;
+               if (g_logEnable)
+                       dev_dbg(pDRV2624->dev, "wklock lock");
+
+               nResult = drv2624_change_mode(pDRV2624, MODE_RTP);
+               if (nResult < 0)
+                       goto end;
+
+               nResult = drv2624_set_go_bit(pDRV2624, GO);
+               if (nResult >= 0) {
+                       value = (value > MAX_TIMEOUT) ? MAX_TIMEOUT : value;
+                       pDRV2624->mnWorkMode |= WORK_VIBRATOR;
                        hrtimer_start(&pDRV2624->timer, 
                                ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+                       pDRV2624->mnVibratorPlaying = YES;
+
+                       if (pDRV2624->mbIRQUsed)
+                               nResult = drv2624_enableIRQ(pDRV2624, YES);
                }
-    }
-       
+       }
+
+end:
+       if (nResult < 0) {
+               wake_unlock(&pDRV2624->wklock);
+               if (g_logEnable)
+                       dev_dbg(pDRV2624->dev, "wklock unlock");
+       }
        mutex_unlock(&pDRV2624->lock);
 }
 
 static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
 {
-       struct drv2624_data *pDRV2624 = 
+       struct drv2624_data *pDRV2624 =
                container_of(timer, struct drv2624_data, timer);
 
-       dev_dbg(pDRV2624->dev, "%s\n", __FUNCTION__);
-       pDRV2624->mnWorkMode |= WORK_VIBRATOR;
+       dev_dbg(pDRV2624->dev, "%s\n", __func__);
        schedule_work(&pDRV2624->vibrator_work);
-    return HRTIMER_NORESTART;
+       return HRTIMER_NORESTART;
 }
 
 static void vibrator_work_routine(struct work_struct *work)
 {
-       struct drv2624_data *pDRV2624 = 
+       struct drv2624_data *pDRV2624 =
                container_of(work, struct drv2624_data, vibrator_work);
        unsigned char mode = MODE_RTP;
        unsigned char status; 
-       int ret = 0;
-               
+       int nResult = 0;
+
        mutex_lock(&pDRV2624->lock);
 
-       dev_dbg(pDRV2624->dev, 
-               "%s, afer mnWorkMode=0x%x\n", 
-               __FUNCTION__, pDRV2624->mnWorkMode);
-               
-       if(pDRV2624->mnWorkMode & WORK_IRQ){    
-               ret = drv2624_reg_read(pDRV2624,DRV2624_REG_STATUS);
-               if(ret >= 0) pDRV2624->mnIntStatus = ret;
-               drv2624_disableIRQ(pDRV2624);   
-               if(ret < 0){
-                       dev_err(pDRV2624->dev, 
-                               "%s, reg read error\n",
-                               __FUNCTION__);
-                       goto err;               
-               }
-               
+       if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "%s, afer mnWorkMode=0x%x\n",
+                       __func__, pDRV2624->mnWorkMode);
+
+       if ((pDRV2624->mnWorkMode & WORK_IRQ) && pDRV2624->mbIRQUsed) {
+               nResult = drv2624_reg_read(pDRV2624,DRV2624_REG_STATUS);
+               if (nResult >= 0)
+                       pDRV2624->mnIntStatus = nResult;
+               drv2624_disableIRQ(pDRV2624);
+               if (nResult < 0)
+                       goto err;
+
                status = pDRV2624->mnIntStatus;
-               dev_dbg(pDRV2624->dev, 
-                       "%s, status=0x%x\n", 
-                       __FUNCTION__, pDRV2624->mnIntStatus);
-               
-               if(status & OVERCURRENT_MASK){
-                       dev_err(pDRV2624->dev, 
-                               "ERROR, Over Current detected!!\n");
-               }
-               
-               if(status & OVERTEMPRATURE_MASK){
-                       dev_err(pDRV2624->dev, 
-                               "ERROR, Over Temperature detected!!\n");
-               }
-               
-               if(status & ULVO_MASK){
-                       dev_err(pDRV2624->dev, 
-                               "ERROR, VDD drop observed!!\n");
-               }
+               dev_dbg(pDRV2624->dev, "%s, status=0x%x\n",
+                       __func__, pDRV2624->mnIntStatus);
 
-               if(status & PRG_ERR_MASK){
-                       dev_err(pDRV2624->dev, 
-                               "ERROR, PRG error!!\n");                        
-               }
+               if (status & OVERCURRENT_MASK)
+                       dev_err(pDRV2624->dev, "ERROR, Over Current detected!!\n");
 
-               if(status & PROCESS_DONE_MASK){
-                       ret = drv2624_reg_read(pDRV2624, DRV2624_REG_MODE);
-                       if(ret < 0)     {
-                               dev_err(pDRV2624->dev, 
-                                       "%s, reg read error\n",
-                                       __FUNCTION__);
-                               goto err;               
-                       }
-               
-                       mode =  ret& WORKMODE_MASK;
-                       if(mode == MODE_CALIBRATION){
-                               pDRV2624->mAutoCalResult.mnResult = status;
-                               if((status&DIAG_MASK) != DIAG_SUCCESS){
-                                       dev_err(pDRV2624->dev, "Calibration fail\n");
-                               }else{
-                                       pDRV2624->mAutoCalResult.mnCalComp = 
-                                               drv2624_reg_read(pDRV2624, DRV2624_REG_CAL_COMP);
-                                       pDRV2624->mAutoCalResult.mnCalBemf = 
-                                               drv2624_reg_read(pDRV2624, DRV2624_REG_CAL_BEMF);
-                                       pDRV2624->mAutoCalResult.mnCalGain = 
-                                               drv2624_reg_read(pDRV2624, DRV2624_REG_CAL_COMP) & BEMFGAIN_MASK;
-                                       dev_dbg(pDRV2624->dev, 
-                                               "AutoCal : Comp=0x%x, Bemf=0x%x, Gain=0x%x\n",
-                                               pDRV2624->mAutoCalResult.mnCalComp, 
-                                               pDRV2624->mAutoCalResult.mnCalBemf,
-                                               pDRV2624->mAutoCalResult.mnCalGain);
-                               }       
-                       }else if(mode == MODE_DIAGNOSTIC){
-                               pDRV2624->mDiagResult.mnResult = status;
-                               if((status&DIAG_MASK) != DIAG_SUCCESS){
-                                       dev_err(pDRV2624->dev, "Diagnostic fail\n");
-                               }else{
-                                       pDRV2624->mDiagResult.mnDiagZ = 
-                                               drv2624_reg_read(pDRV2624, DRV2624_REG_DIAG_Z);
-                                       pDRV2624->mDiagResult.mnDiagK = 
-                                               drv2624_reg_read(pDRV2624, DRV2624_REG_DIAG_K);
-                                       dev_dbg(pDRV2624->dev, 
-                                               "Diag : ZResult=0x%x, CurrentK=0x%x\n",
-                                               pDRV2624->mDiagResult.mnDiagZ,
-                                               pDRV2624->mDiagResult.mnDiagK);
-                               }                                               
-                       }else if(mode == MODE_WAVEFORM_SEQUENCER){
-                               dev_dbg(pDRV2624->dev, 
+               if (status & OVERTEMPRATURE_MASK)
+                       dev_err(pDRV2624->dev, "ERROR, Over Temperature detected!!\n");
+
+               if (status & ULVO_MASK)
+                       dev_err(pDRV2624->dev, "ERROR, VDD drop observed!!\n");
+
+               if (status & PRG_ERR_MASK)
+                       dev_err(pDRV2624->dev, "ERROR, PRG error!!\n");
+
+               if (status & PROCESS_DONE_MASK) {
+                       nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_MODE);
+                       if (nResult < 0)
+                               goto err;
+
+                       mode =  nResult & WORKMODE_MASK;
+                       if (mode == MODE_CALIBRATION)
+                               nResult = drv2624_get_calibration_result(pDRV2624, status);
+                       else if (mode == MODE_DIAGNOSTIC)
+                               nResult = drv2624_get_diag_result(pDRV2624, status);
+                       else if (mode == MODE_WAVEFORM_SEQUENCER)
+                               dev_dbg(pDRV2624->dev,
                                        "Waveform Sequencer Playback finished\n");
-                       }else if(mode == MODE_RTP){
-                               dev_dbg(pDRV2624->dev, 
-                                       "RTP IRQ\n");
-                       }
-               }
-               
-               if((mode != MODE_RTP)&&
-                       (pDRV2624->mnVibratorPlaying == YES)){
-                       dev_info(pDRV2624->dev, "release wklock\n");
-                       pDRV2624->mnVibratorPlaying = NO;
-                       wake_unlock(&pDRV2624->wklock);
+                       else if(mode == MODE_RTP)
+                               dev_dbg(pDRV2624->dev, "RTP IRQ\n");
                }
-                       
+
+               if ((mode != MODE_RTP) && (pDRV2624->mnVibratorPlaying == YES))
+                       drv2624_set_stopflag(pDRV2624);
+
                pDRV2624->mnWorkMode &= ~WORK_IRQ;
        }
-       
-       if(pDRV2624->mnWorkMode & WORK_VIBRATOR){
+
+       if (pDRV2624->mnWorkMode & WORK_VIBRATOR) {
                drv2624_stop(pDRV2624);
                pDRV2624->mnWorkMode &= ~WORK_VIBRATOR;
        }
+
+       if (pDRV2624->mnWorkMode & WORK_EFFECTSEQUENCER) {
+               status = drv2624_reg_read(pDRV2624, DRV2624_REG_GO);
+               if ((status < 0) || (status == STOP) || !pDRV2624->mnVibratorPlaying) {
+                       drv2624_stop(pDRV2624);
+                       pDRV2624->mnWorkMode &= ~WORK_EFFECTSEQUENCER;
+               } else {
+                       if (!hrtimer_active(&pDRV2624->timer)) {
+                               if (g_logEnable)
+                                       dev_dbg(pDRV2624->dev, "will check GO bit after %d ms\n", POLL_GO_BIT_INTERVAL);
+                               hrtimer_start(&pDRV2624->timer, 
+                                       ns_to_ktime((u64)POLL_GO_BIT_INTERVAL * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+                       }
+               }
+       }
+
+       if (pDRV2624->mnWorkMode & WORK_CALIBRATION) {
+               status = drv2624_reg_read(pDRV2624, DRV2624_REG_GO);
+               if ((status < 0) || (status == STOP) || !pDRV2624->mnVibratorPlaying) {
+                       drv2624_stop(pDRV2624);
+                       pDRV2624->mnWorkMode &= ~WORK_CALIBRATION;
+                       if (status < 0)
+                               goto err;
+                       nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_STATUS);
+                       if (nResult >= 0)
+                               nResult = drv2624_get_calibration_result(pDRV2624, nResult);
+               } else {
+                       if (!hrtimer_active(&pDRV2624->timer)) {
+                               if (g_logEnable)
+                                       dev_dbg(pDRV2624->dev, "will check GO bit after %d ms\n", POLL_GO_BIT_INTERVAL);
+                               hrtimer_start(&pDRV2624->timer, 
+                                       ns_to_ktime((u64)POLL_GO_BIT_INTERVAL * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+                       }
+               }
+       }
+
+       if (pDRV2624->mnWorkMode & WORK_DIAGNOSTIC) {
+               status = drv2624_reg_read(pDRV2624, DRV2624_REG_GO);
+               if ((status < 0) || (status == STOP) || !pDRV2624->mnVibratorPlaying) {
+                       drv2624_stop(pDRV2624);
+                       pDRV2624->mnWorkMode &= ~WORK_DIAGNOSTIC;
+                       if (status < 0)
+                               goto err;
+                       nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_STATUS);
+                       if (nResult >= 0)
+                               nResult = drv2624_get_diag_result(pDRV2624, nResult);
+               } else {
+                       if (!hrtimer_active(&pDRV2624->timer)) {
+                               if (g_logEnable)
+                                       dev_dbg(pDRV2624->dev, "will check GO bit after %d ms\n", POLL_GO_BIT_INTERVAL);
+                               hrtimer_start(&pDRV2624->timer, 
+                                       ns_to_ktime((u64)POLL_GO_BIT_INTERVAL * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+                       }
+               }
+       }
+
 err:
-       
+
        mutex_unlock(&pDRV2624->lock);
 }
 
 static int dev_auto_calibrate(struct drv2624_data *pDRV2624)
 {
-       int ret = 0;
-       
-       dev_info(pDRV2624->dev, "%s\n", __FUNCTION__);
+       int nResult = 0;
+
+       dev_info(pDRV2624->dev, "%s\n", __func__);
        wake_lock(&pDRV2624->wklock);
-       pDRV2624->mnVibratorPlaying = YES;      
-       drv2624_change_mode(pDRV2624, MODE_CALIBRATION);
-       ret = drv2624_set_go_bit(pDRV2624, GO);
-       if(ret < 0){
-               dev_warn(pDRV2624->dev, "calibration start fail\n");
+       if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "wklock lock");
+
+       nResult = drv2624_change_mode(pDRV2624, MODE_CALIBRATION);
+       if (nResult < 0)
+               goto end;
+
+       nResult = drv2624_set_go_bit(pDRV2624, GO);
+       if (nResult < 0)
+               goto end;
+
+       dev_dbg(pDRV2624->dev, "calibration start\n");
+       pDRV2624->mnVibratorPlaying = YES;
+
+       if (!pDRV2624->mbIRQUsed) {
+               pDRV2624->mnWorkMode |= WORK_CALIBRATION;
+               schedule_work(&pDRV2624->vibrator_work);
+       }
+
+end:
+       if (nResult < 0) {
                wake_unlock(&pDRV2624->wklock);
-               pDRV2624->mnVibratorPlaying = NO;                       
-       }else{
-               dev_dbg(pDRV2624->dev, "calibration start\n");
+               if (g_logEnable)
+                       dev_dbg(pDRV2624->dev, "wklock unlock");
        }
-       return ret;
+       return nResult;
 }
 
 static int dev_run_diagnostics(struct drv2624_data *pDRV2624)
 {
-       int ret = 0;
-       
-       dev_info(pDRV2624->dev, "%s\n", __FUNCTION__);
+       int nResult = 0;
+
+       dev_info(pDRV2624->dev, "%s\n", __func__);
        wake_lock(&pDRV2624->wklock);
-       pDRV2624->mnVibratorPlaying = YES;      
-       drv2624_change_mode(pDRV2624, MODE_DIAGNOSTIC);
-       ret = drv2624_set_go_bit(pDRV2624, GO);
-       if(ret < 0){
-               dev_warn(pDRV2624->dev, "Diag start fail\n");
+       if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "wklock lock");
+
+       nResult = drv2624_change_mode(pDRV2624, MODE_DIAGNOSTIC);
+       if (nResult < 0) 
+               goto end;
+
+       nResult = drv2624_set_go_bit(pDRV2624, GO);
+       if (nResult < 0)
+               goto end;
+
+       dev_dbg(pDRV2624->dev, "Diag start\n");
+       pDRV2624->mnVibratorPlaying = YES;
+
+       if (!pDRV2624->mbIRQUsed) {
+               pDRV2624->mnWorkMode |= WORK_DIAGNOSTIC;
+               schedule_work(&pDRV2624->vibrator_work);
+       }
+
+end:
+       if (nResult < 0) {
                wake_unlock(&pDRV2624->wklock);
-               pDRV2624->mnVibratorPlaying = NO;                       
-       }else{
-               dev_dbg(pDRV2624->dev, "Diag start\n");
+               if (g_logEnable)
+                       dev_dbg(pDRV2624->dev, "wklock unlock");
        }
-       
-       return ret;
+       return nResult;
 }
 
 static int drv2624_playEffect(struct drv2624_data *pDRV2624)
 {
-       int ret = 0;
-       dev_info(pDRV2624->dev, "%s\n", __FUNCTION__);
+       int nResult = 0;
+
+       dev_info(pDRV2624->dev, "%s\n", __func__);
        wake_lock(&pDRV2624->wklock);
-       pDRV2624->mnVibratorPlaying = YES;      
-       drv2624_change_mode(pDRV2624, MODE_WAVEFORM_SEQUENCER);
-       ret = drv2624_set_go_bit(pDRV2624, GO);
-       if(ret < 0){
-               dev_warn(pDRV2624->dev, "effects start fail\n");
+       if (g_logEnable)
+               dev_dbg(pDRV2624->dev, "wklock lock");
+
+       nResult = drv2624_change_mode(pDRV2624, MODE_WAVEFORM_SEQUENCER);
+       if (nResult < 0) 
+               goto end;
+
+       nResult = drv2624_set_go_bit(pDRV2624, GO);
+       if (nResult < 0) 
+               goto end;
+
+       dev_dbg(pDRV2624->dev, "effects start\n");
+       pDRV2624->mnVibratorPlaying = YES;
+
+       if (!pDRV2624->mbIRQUsed) {
+               pDRV2624->mnWorkMode |= WORK_EFFECTSEQUENCER;
+               schedule_work(&pDRV2624->vibrator_work);
+       }
+
+end:
+       if (nResult < 0) {
                wake_unlock(&pDRV2624->wklock);
-               pDRV2624->mnVibratorPlaying = NO;                       
-       }else{
-               dev_dbg(pDRV2624->dev, "effects start\n");
+               dev_dbg(pDRV2624->dev, "wklock unlock");
        }
-       
-       return ret;
+       return nResult;
 }
        
 static int drv2624_config_waveform(struct drv2624_data *pDRV2624,
        struct drv2624_wave_setting *psetting)
 {
-       int ret = 0;
+       int nResult = 0;
        int value = 0;
-       
-       ret = drv2624_reg_write(pDRV2624, 
-                       DRV2624_REG_MAIN_LOOP, psetting->mnLoop&0x07);
-       if(ret >= 0){
-               value |= ((psetting->mnInterval&0x01)<<INTERVAL_SHIFT);
-               value |= (psetting->mnScale&0x03);
-               drv2624_set_bits(pDRV2624,
-                       DRV2624_REG_CONTROL2, INTERVAL_MASK|SCALE_MASK, value);
+
+       nResult = drv2624_reg_write(pDRV2624,
+                       DRV2624_REG_MAIN_LOOP, psetting->mnLoop & 0x07);
+       if (nResult >= 0) {
+               value |= ((psetting->mnInterval & 0x01) << INTERVAL_SHIFT);
+               value |= (psetting->mnScale & 0x03);
+               nResult = drv2624_set_bits(pDRV2624, DRV2624_REG_CONTROL2,
+                                       INTERVAL_MASK | SCALE_MASK, value);
        }
-       return ret;
+       return nResult;
 }
 
 static int drv2624_set_waveform(struct drv2624_data *pDRV2624,
        struct drv2624_waveform_sequencer *pSequencer)
 {
-       int ret = 0;
+       int nResult = 0;
        int i = 0;
        unsigned char loop[2] = {0};
        unsigned char effects[DRV2624_SEQUENCER_SIZE] = {0};
        unsigned char len = 0;
-       
-       for(i = 0; i < DRV2624_SEQUENCER_SIZE; i++){
+
+       for (i = 0; i < DRV2624_SEQUENCER_SIZE; i++) {
                len++;
-               if(pSequencer->msWaveform[i].mnEffect != 0){                    
-                       if(i < 4) 
-                               loop[0] |= 
-                                               (pSequencer->msWaveform[i].mnLoop << (2*i));
+               if (pSequencer->msWaveform[i].mnEffect != 0) {
+                       if (i < 4) 
+                               loop[0] |= (pSequencer->msWaveform[i].mnLoop << (2*i));
                        else
-                               loop[1] |= 
-                                               (pSequencer->msWaveform[i].mnLoop << (2*(i-4)));
-                       
+                               loop[1] |= (pSequencer->msWaveform[i].mnLoop << (2*(i-4)));
+
                        effects[i] = pSequencer->msWaveform[i].mnEffect;
-               }else{                  
+               } else
                        break;
-               }               
        }
-       
-       if(len == 1)
-               ret = drv2624_reg_write(pDRV2624, DRV2624_REG_SEQUENCER_1, 0);
+
+       if (len == 1)
+               nResult = drv2624_reg_write(pDRV2624, DRV2624_REG_SEQUENCER_1, 0);
        else 
-               ret = drv2624_bulk_write(pDRV2624, DRV2624_REG_SEQUENCER_1, effects, len);
+               nResult = drv2624_bulk_write(pDRV2624, DRV2624_REG_SEQUENCER_1, effects, len);
 
-       if(ret < 0)
+       if (nResult < 0) 
                dev_err(pDRV2624->dev, "sequence error\n");
+               goto end;
        }
-       
-       if(ret >= 0){
-               if(len > 1){
-                       if((len-1) <= 4)
-                               drv2624_reg_write(pDRV2624, DRV2624_REG_SEQ_LOOP_1, loop[0]);
-                       else
-                               drv2624_bulk_write(pDRV2624, DRV2624_REG_SEQ_LOOP_1, loop, 2);  
-               }
+
+       if (len > 1) {
+               if ((len-1) <= 4)
+                       drv2624_reg_write(pDRV2624, DRV2624_REG_SEQ_LOOP_1, loop[0]);
+               else
+                       drv2624_bulk_write(pDRV2624, DRV2624_REG_SEQ_LOOP_1, loop, 2);
        }
-       
-       return ret;
+
+end:
+
+       return nResult;
 }
 
-static int fw_chksum(const struct firmware *fw){
+static int fw_chksum(const struct firmware *fw)
+{
        int sum = 0;
        int i=0;
        int size = fw->size;
        const unsigned char *pBuf = fw->data;
-       
-       for (i=0; i< size; i++){
-               if((i>11) && (i<16)){
-               
-               }else{
+
+       for (i=0; i < size; i++) {
+               if ((i <= 11) || (i >= 16))
                        sum += pBuf[i];
-               }
        }
 
        return sum;
 }
 
-/* drv2624_firmware_load:   This function is called by the
- *             request_firmware_nowait function as soon
- *             as the firmware has been loaded from the file.
- *             The firmware structure contains the data and$
- *             the size of the firmware loaded.
- * @fw: pointer to firmware file to be dowloaded
- * @context: pointer variable to drv2624 data
- *
- * 
- */
+/* drv2624_firmware_load:
+* This function is called by the
+* request_firmware_nowait function as soon
+* as the firmware has been loaded from the file.
+* The firmware structure contains the data and$
+* the size of the firmware loaded.
+*
+* @fw: pointer to firmware file to be dowloaded
+* @context: pointer variable to drv2624 data
+*/
 static void drv2624_firmware_load(const struct firmware *fw, void *context)
 {
        struct drv2624_data *pDRV2624 = context;
        int size = 0, fwsize = 0, i=0;
        const unsigned char *pBuf = NULL;
 
-    mutex_lock(&pDRV2624->lock);
-       
-       if(fw != NULL){
+       mutex_lock(&pDRV2624->lock);
+
+       if (fw != NULL) {
                pBuf = fw->data;
                size = fw->size;
-               if(size > 1024){
-                       dev_err(pDRV2624->dev,"%s, ERROR!! firmware size %d too big\n", 
-                               __FUNCTION__, size);
-               }else{
+               if (size > 1024)
+                       dev_err(pDRV2624->dev,"%s, ERROR!! firmware size %d too big\n",
+                               __func__, size);
+               else {
                        memcpy(&(pDRV2624->fw_header), pBuf, sizeof(struct drv2624_fw_header));
-                       if((pDRV2624->fw_header.fw_magic != DRV2624_MAGIC) 
-                               ||(pDRV2624->fw_header.fw_size != size)
-                               ||(pDRV2624->fw_header.fw_chksum != fw_chksum(fw))){
-                               dev_err(pDRV2624->dev,"%s, ERROR!! firmware not right:Magic=0x%x,Size=%d,chksum=0x%x\n", 
-                                       __FUNCTION__, pDRV2624->fw_header.fw_magic, 
+                       if ((pDRV2624->fw_header.fw_magic != DRV2624_MAGIC)
+                               || (pDRV2624->fw_header.fw_size != size)
+                               || (pDRV2624->fw_header.fw_chksum != fw_chksum(fw)))
+                               dev_err(pDRV2624->dev,
+                                       "%s, ERROR!! firmware not right:Magic=0x%x, Size=%d, chksum=0x%x\n", 
+                                       __func__, pDRV2624->fw_header.fw_magic,
                                        pDRV2624->fw_header.fw_size, pDRV2624->fw_header.fw_chksum);
-                       }else{
-                               dev_info(pDRV2624->dev,"%s, firmware good\n", __FUNCTION__);
-               
+                       else {
+                               dev_info(pDRV2624->dev,"%s, firmware good\n", __func__);
+
                                pBuf += sizeof(struct drv2624_fw_header);
-                               
                                drv2624_reg_write(pDRV2624, DRV2624_REG_RAM_ADDR_UPPER, 0);
                                drv2624_reg_write(pDRV2624, DRV2624_REG_RAM_ADDR_LOWER, 0);
-                               
+
                                fwsize = size - sizeof(struct drv2624_fw_header);
-                               for(i = 0; i < fwsize; i++){
+                               for(i = 0; i < fwsize; i++)
                                        drv2624_reg_write(pDRV2624, DRV2624_REG_RAM_DATA, pBuf[i]);
-                               }       
-                       }                               
+                       }
                }
-       }else{
-               dev_err(pDRV2624->dev, "%s, ERROR!! firmware not found\n", __FUNCTION__);
-       }
-       
+       } else
+               dev_err(pDRV2624->dev, "%s, ERROR!! firmware not found\n", __func__);
+
        release_firmware(fw);
-       
+
     mutex_unlock(&pDRV2624->lock);
 }
 
 static int drv2624_file_open(struct inode *inode, struct file *file)
 {
-       if (!try_module_get(THIS_MODULE)) return -ENODEV;
+       if (!try_module_get(THIS_MODULE))
+               return -ENODEV;
 
        file->private_data = (void*)g_DRV2624data;
        return 0;
@@ -620,351 +770,336 @@ static long drv2624_file_unlocked_ioctl(struct file *file, unsigned int cmd, uns
 {
        struct drv2624_data *pDRV2624 = file->private_data;
        //void __user *user_arg = (void __user *)arg;
-       int ret = 0;
-       
+       int nResult = 0;
+
        mutex_lock(&pDRV2624->lock);
-       
+
        dev_dbg(pDRV2624->dev, "ioctl 0x%x\n", cmd);
-       
+
        switch (cmd) {
-               
+
        }
-       
+
        mutex_unlock(&pDRV2624->lock);
-       
-       return ret;
+
+       return nResult;
 }
 
 static ssize_t drv2624_file_read(struct file* filp, char* buff, size_t length, loff_t* offset)
 {
        struct drv2624_data *pDRV2624 = (struct drv2624_data *)filp->private_data;
-       int ret = 0;
+       int nResult = 0;
        unsigned char value = 0;
        unsigned char *p_kBuf = NULL;
 
        mutex_lock(&pDRV2624->lock);
 
-       switch(pDRV2624->mnFileCmd)
-       {
-               case HAPTIC_CMDID_REG_READ:
-               {
-                       if(length == 1){
-                               ret = drv2624_reg_read(pDRV2624, pDRV2624->mnCurrentReg);
-                               if( 0 > ret) {
-                                       dev_err(pDRV2624->dev, "dev read fail %d\n", ret);
-                               }else{
-                                       value = ret;
-                                       ret = copy_to_user(buff, &value, 1);
-                                       if (0 != ret) {
-                                               /* Failed to copy all the data, exit */
-                                               dev_err(pDRV2624->dev, "copy to user fail %d\n", ret);
-                                       }       
+       switch (pDRV2624->mnFileCmd) {
+       case HAPTIC_CMDID_REG_READ:
+               if (length == 1) {
+                       nResult = drv2624_reg_read(pDRV2624, pDRV2624->mnCurrentReg);
+                       if (nResult >= 0) {
+                               value = nResult;
+                               nResult = copy_to_user(buff, &value, 1);
+                               if (0 != nResult) {
+                                       /* Failed to copy all the data, exit */
+                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
                                }
-                       }else if(length > 1){
-                               p_kBuf = (unsigned char *)kzalloc(length, GFP_KERNEL);
-                               if(p_kBuf != NULL){
-                                       ret = drv2624_bulk_read(pDRV2624, 
-                                               pDRV2624->mnCurrentReg, p_kBuf, length);
-                                       if( 0 > ret) {
-                                               dev_err(pDRV2624->dev, "dev bulk read fail %d\n", ret);
-                                       }else{
-                                               ret = copy_to_user(buff, p_kBuf, length);
-                                               if (0 != ret) {
-                                                       /* Failed to copy all the data, exit */
-                                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", ret);
-                                               }
+                       }
+               } else if (length > 1) {
+                       p_kBuf = (unsigned char *)kzalloc(length, GFP_KERNEL);
+                       if (p_kBuf != NULL) {
+                               nResult = drv2624_bulk_read(pDRV2624,
+                                       pDRV2624->mnCurrentReg, p_kBuf, length);
+                               if (nResult >= 0) {
+                                       nResult = copy_to_user(buff, p_kBuf, length);
+                                       if (0 != nResult) {
+                                               /* Failed to copy all the data, exit */
+                                               dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
                                        }
-                                       
-                                       kfree(p_kBuf);
-                               }else{
-                                       dev_err(pDRV2624->dev, "read no mem\n");
-                                       ret = -ENOMEM;
                                }
+
+                               kfree(p_kBuf);
+                       } else {
+                               dev_err(pDRV2624->dev, "read no mem\n");
+                               nResult = -ENOMEM;
                        }
-                       break;
                }
-               
-               case HAPTIC_CMDID_RUN_DIAG:
-               {
-                       if(pDRV2624->mnVibratorPlaying){
-                               length = 0;
-                       }else{
-                               unsigned char buf[3] ;
-                               buf[0] = pDRV2624->mDiagResult.mnResult;
-                               buf[1] = pDRV2624->mDiagResult.mnDiagZ;
-                               buf[2] = pDRV2624->mDiagResult.mnDiagK;
-                               ret = copy_to_user(buff, buf, 3);
-                               if (0 != ret) {
-                                       /* Failed to copy all the data, exit */
-                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", ret);
-                               }
+               break;
+
+       case HAPTIC_CMDID_RUN_DIAG:
+               if (pDRV2624->mnVibratorPlaying)
+                       length = 0;
+               else {
+                       unsigned char buf[3];
+
+                       buf[0] = pDRV2624->mDiagResult.mnResult;
+                       buf[1] = pDRV2624->mDiagResult.mnDiagZ;
+                       buf[2] = pDRV2624->mDiagResult.mnDiagK;
+                       nResult = copy_to_user(buff, buf, 3);
+                       if (0 != nResult) {
+                               /* Failed to copy all the data, exit */
+                               dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
                        }
-                       break;
                }
-               
-               case HAPTIC_CMDID_RUN_CALIBRATION:
-               {
-                       if(pDRV2624->mnVibratorPlaying){
-                               length = 0;
-                       }else{
-                               unsigned char buf[4] ;
-                               buf[0] = pDRV2624->mAutoCalResult.mnResult;
-                               buf[1] = pDRV2624->mAutoCalResult.mnCalComp;
-                               buf[2] = pDRV2624->mAutoCalResult.mnCalBemf;
-                               buf[3] = pDRV2624->mAutoCalResult.mnCalGain;
-                               ret = copy_to_user(buff, buf, 4);
-                               if (0 != ret) {
-                                       /* Failed to copy all the data, exit */
-                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", ret);
-                               }
+               break;
+
+       case HAPTIC_CMDID_RUN_CALIBRATION:
+               if (pDRV2624->mnVibratorPlaying)
+                       length = 0;
+               else {
+                       unsigned char buf[4];
+
+                       buf[0] = pDRV2624->mAutoCalResult.mnResult;
+                       buf[1] = pDRV2624->mAutoCalResult.mnCalComp;
+                       buf[2] = pDRV2624->mAutoCalResult.mnCalBemf;
+                       buf[3] = pDRV2624->mAutoCalResult.mnCalGain;
+                       nResult = copy_to_user(buff, buf, 4);
+                       if (0 != nResult) {
+                               /* Failed to copy all the data, exit */
+                               dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
                        }
-                       break;
                }
-               
-               case HAPTIC_CMDID_CONFIG_WAVEFORM:
-               {
-                       if(length == sizeof(struct drv2624_wave_setting)){
-                               struct drv2624_wave_setting wavesetting;                
-                               value = drv2624_reg_read(pDRV2624, DRV2624_REG_CONTROL2);
-                               wavesetting.mnLoop = 
-                                       drv2624_reg_read(pDRV2624, DRV2624_REG_MAIN_LOOP)&0x07;
-                               wavesetting.mnInterval = ((value&INTERVAL_MASK)>>INTERVAL_SHIFT);
-                               wavesetting.mnScale = (value&SCALE_MASK);
-                               ret = copy_to_user(buff, &wavesetting, length);
-                               if (0 != ret) {
-                                       /* Failed to copy all the data, exit */
-                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", ret);
-                               }       
+               break;
+
+       case HAPTIC_CMDID_CONFIG_WAVEFORM:
+               if (length == sizeof(struct drv2624_wave_setting)) {
+                       struct drv2624_wave_setting wavesetting;
+
+                       value = drv2624_reg_read(pDRV2624, DRV2624_REG_CONTROL2);
+                       wavesetting.mnLoop = drv2624_reg_read(pDRV2624, DRV2624_REG_MAIN_LOOP)&0x07;
+                       wavesetting.mnInterval = ((value&INTERVAL_MASK)>>INTERVAL_SHIFT);
+                       wavesetting.mnScale = (value&SCALE_MASK);
+                       nResult = copy_to_user(buff, &wavesetting, length);
+                       if (0 != nResult) {
+                               /* Failed to copy all the data, exit */
+                               dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
                        }
-                       
-                       break;
                }
-               
-               case HAPTIC_CMDID_SET_SEQUENCER:
-               {
-                       if(length == sizeof(struct drv2624_waveform_sequencer)){
-                               struct drv2624_waveform_sequencer sequencer;
-                               unsigned char effects[DRV2624_SEQUENCER_SIZE] = {0};
-                               unsigned char loop[2] = {0};
-                               int i = 0;
-                               ret = drv2624_bulk_read(pDRV2624, 
-                                               DRV2624_REG_SEQUENCER_1, 
+               break;
+
+       case HAPTIC_CMDID_SET_SEQUENCER:
+               if (length == sizeof(struct drv2624_waveform_sequencer)) {
+                       struct drv2624_waveform_sequencer sequencer;
+                       unsigned char effects[DRV2624_SEQUENCER_SIZE] = {0};
+                       unsigned char loop[2] = {0};
+                       int i = 0;
+
+                       nResult = drv2624_bulk_read(pDRV2624, DRV2624_REG_SEQUENCER_1,
                                                effects, DRV2624_SEQUENCER_SIZE);
-                               if(ret < 0){
-                                       dev_err(pDRV2624->dev, "bulk read error %d\n", ret);
+                       if (nResult < 0)
+                               break;
+
+                       nResult = drv2624_bulk_read(pDRV2624, DRV2624_REG_SEQ_LOOP_1, loop, 2);
+                       if (nResult < 0)
+                               break;
+
+                       for(i = 0; i < DRV2624_SEQUENCER_SIZE; i++){
+                               sequencer.msWaveform[i].mnEffect = effects[i];
+                               if(i < 4)
+                                       sequencer.msWaveform[i].mnLoop = ((loop[0]>>(2*i))&0x03);
+                               else
+                                       sequencer.msWaveform[i].mnLoop = ((loop[1]>>(2*(i-4)))&0x03);
+                       }
+
+                       nResult = copy_to_user(buff, &sequencer, length);
+                       if (0 != nResult) {
+                               /* Failed to copy all the data, exit */
+                               dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
+                       }
+               }
+               break;
+
+       case HAPTIC_CMDID_READ_FIRMWARE:
+               if (length > 0) {
+                       int i = 0;
+
+                       p_kBuf = (unsigned char *)kzalloc(length, GFP_KERNEL);
+                       if(p_kBuf != NULL){
+                               nResult = drv2624_reg_write(pDRV2624, DRV2624_REG_RAM_ADDR_UPPER, pDRV2624->mRAMMSB);
+                               if (nResult < 0)
                                        break;
+                               nResult = drv2624_reg_write(pDRV2624, DRV2624_REG_RAM_ADDR_LOWER, pDRV2624->mRAMLSB);
+                               if (nResult < 0)
+                                       break;
+
+                               for (i = 0; i < length; i++) {
+                                       nResult = drv2624_reg_read(pDRV2624,DRV2624_REG_RAM_DATA);
+                                       if (nResult < 0)
+                                               break;
+                                       p_kBuf[i] = nResult; 
                                }
-                                       
-                               ret = drv2624_bulk_read(pDRV2624, 
-                                               DRV2624_REG_SEQ_LOOP_1,
-                                               loop, 2);
-                                               
-                               for(i=0; i < DRV2624_SEQUENCER_SIZE; i++){
-                                       sequencer.msWaveform[i].mnEffect = effects[i];
-                                       if(i < 4)
-                                               sequencer.msWaveform[i].mnLoop = ((loop[0]>>(2*i))&0x03);
-                                       else
-                                               sequencer.msWaveform[i].mnLoop = ((loop[1]>>(2*(i-4)))&0x03);
-                               }
-                               
-                               ret = copy_to_user(buff, &sequencer, length);
-                               if (0 != ret) {
+                               if(0 > nResult)
+                                       break;
+
+                               nResult = copy_to_user(buff, p_kBuf, length);
+                               if (0 != nResult) {
                                        /* Failed to copy all the data, exit */
-                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", ret);
-                               }       
+                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
+                               }
+
+                               kfree(p_kBuf);
+                       } else {
+                               dev_err(pDRV2624->dev, "read no mem\n");
+                               nResult = -ENOMEM;
                        }
-                       
-                       break;
                }
-               
-               case HAPTIC_CMDID_READ_FIRMWARE:
-               {
-                       if(length > 0){
-                               int i = 0;
-                               p_kBuf = (unsigned char *)kzalloc(length, GFP_KERNEL);
-                               if(p_kBuf != NULL){
-                                       
-                                       drv2624_reg_write(pDRV2624, DRV2624_REG_RAM_ADDR_UPPER, pDRV2624->mRAMMSB);
-                                       drv2624_reg_write(pDRV2624, DRV2624_REG_RAM_ADDR_LOWER, pDRV2624->mRAMLSB);
-                               
-                                       for(i=0; i < length; i++)
-                                               p_kBuf[i] = drv2624_reg_read(pDRV2624,DRV2624_REG_RAM_DATA);
-                                       
-                                       if( 0 > ret) {
-                                               dev_err(pDRV2624->dev, "dev read fail %d\n", ret);
-                                       }else{
-                                               ret = copy_to_user(buff, p_kBuf, length);
-                                               if (0 != ret) {
-                                                       /* Failed to copy all the data, exit */
-                                                       dev_err(pDRV2624->dev, "copy to user fail %d\n", ret);
-                                               }
-                                       }
-                                       
-                                       kfree(p_kBuf);
-                               }else{
-                                       dev_err(pDRV2624->dev, "read no mem\n");
-                                       ret = -ENOMEM;
-                               }
+               break;
+
+       case HAPTIC_CMDID_REGLOG_ENABLE:
+               if (length == 1) {
+                       nResult = copy_to_user(buff, &g_logEnable, 1);
+                       if (0 != nResult) {
+                               /* Failed to copy all the data, exit */
+                               dev_err(pDRV2624->dev, "copy to user fail %d\n", nResult);
                        }
-                       break;                  
                }
+               break;
 
-               default:
-                       pDRV2624->mnFileCmd = 0;
-                       break;
+       default:
+               pDRV2624->mnFileCmd = 0;
+               break;
        }
-       
+
        mutex_unlock(&pDRV2624->lock);
-       
+
     return length;
 }
 
 static ssize_t drv2624_file_write(struct file* filp, const char* buff, size_t len, loff_t* off)
 {
-       struct drv2624_data *pDRV2624 = 
-               (struct drv2624_data *)filp->private_data;
+       struct drv2624_data *pDRV2624 = (struct drv2624_data *)filp->private_data;
        unsigned char *p_kBuf = NULL;
-       int ret = 0;
-       
-    mutex_lock(&pDRV2624->lock);
-       
+       int nResult = 0;
+
+       mutex_lock(&pDRV2624->lock);
+
        p_kBuf = (unsigned char *)kzalloc(len, GFP_KERNEL);
-       if(p_kBuf == NULL) {
+       if (p_kBuf == NULL) {
                dev_err(pDRV2624->dev, "write no mem\n");
                goto err;
        }
-       
-       ret = copy_from_user(p_kBuf, buff, len);
-       if (0 != ret) {
+
+       nResult = copy_from_user(p_kBuf, buff, len);
+       if (0 != nResult) {
                dev_err(pDRV2624->dev,"copy_from_user failed.\n");
                goto err;
        }
 
        pDRV2624->mnFileCmd = p_kBuf[0];
-       
-    switch(pDRV2624->mnFileCmd)
-    {
-               case HAPTIC_CMDID_REG_READ:
-               {
-                       if(len == 2){
-                               pDRV2624->mnCurrentReg = p_kBuf[1];
-                       }else{
-                               dev_err(pDRV2624->dev, 
-                                       " read cmd len %d err\n", len);
-                       }
-                       break;
-               }
-               
-               case HAPTIC_CMDID_REG_WRITE:
-               {
-                       if((len-1) == 2){
-                               drv2624_reg_write(pDRV2624, p_kBuf[1], p_kBuf[2]);      
-                       }else if((len-1)>2){
-                               drv2624_bulk_write(pDRV2624, p_kBuf[1], &p_kBuf[2], len-2);
-                       }else{
-                               dev_err(pDRV2624->dev, 
-                                       "%s, reg_write len %d error\n", __FUNCTION__, len);
-                       }
-                       break;
-               }
-               
-               case HAPTIC_CMDID_REG_SETBIT:
-               {
-                       if(len == 4){
-                               drv2624_set_bits(pDRV2624, p_kBuf[1], p_kBuf[2], p_kBuf[3]);
-                       }else{
-                               dev_err(pDRV2624->dev, 
-                                       "setbit len %d error\n", len);
-                       }
+
+       switch(pDRV2624->mnFileCmd) {
+       case HAPTIC_CMDID_REG_READ:
+               if (len == 2)
+                       pDRV2624->mnCurrentReg = p_kBuf[1];
+               else
+                       dev_err(pDRV2624->dev, " read cmd len %d err\n", len);
+               break;
+
+       case HAPTIC_CMDID_REG_WRITE:
+               if ((len - 1) == 2)
+                       nResult = drv2624_reg_write(pDRV2624, p_kBuf[1], p_kBuf[2]);
+               else if ((len - 1) > 2)
+                       nResult = drv2624_bulk_write(pDRV2624, p_kBuf[1], &p_kBuf[2], len-2);
+               else
+                       dev_err(pDRV2624->dev, "%s, reg_write len %d error\n", __func__, len);
+               break;
+
+       case HAPTIC_CMDID_REG_SETBIT:
+               if (len == 4)
+                       nResult = drv2624_set_bits(pDRV2624, p_kBuf[1], p_kBuf[2], p_kBuf[3]);
+               else
+                       dev_err(pDRV2624->dev, "setbit len %d error\n", len);
+               break;
+
+       case HAPTIC_CMDID_RUN_DIAG:
+               nResult = drv2624_stop(pDRV2624);
+               if (nResult < 0)
                        break;
-               }       
-               
-               case HAPTIC_CMDID_RUN_DIAG:
-               {
-                       drv2624_stop(pDRV2624); 
-                       drv2624_enableIRQ(pDRV2624, NO);        
-                       ret = dev_run_diagnostics(pDRV2624);
-                       if(ret < 0) drv2624_disableIRQ(pDRV2624);
+               nResult = dev_run_diagnostics(pDRV2624);
+               if ((nResult >= 0) && pDRV2624->mbIRQUsed)
+                       drv2624_enableIRQ(pDRV2624, NO);
+               break;
+
+       case HAPTIC_CMDID_UPDATE_FIRMWARE:
+               nResult = drv2624_stop(pDRV2624);
+               if (nResult < 0)
                        break;
-               }
-               
-               case HAPTIC_CMDID_UPDATE_FIRMWARE:
-               {
-                       ret = request_firmware_nowait(THIS_MODULE, 
+               nResult = request_firmware_nowait(THIS_MODULE,
                                                        FW_ACTION_HOTPLUG,
                                                        "drv2624.bin",
-                                                       pDRV2624->dev, 
-                                                       GFP_KERNEL, 
-                                                       pDRV2624, 
-                                                       drv2624_firmware_load); 
-                       break;
-               }
-               
-               case HAPTIC_CMDID_READ_FIRMWARE:
-               {
-                       if(len == 3){
-                               pDRV2624->mRAMMSB = buff[1];
-                               pDRV2624->mRAMLSB = buff[2];
-                       }else{
-                               dev_err(pDRV2624->dev, "%s, read fw len error\n", __FUNCTION__);
-                       }
-                       break;
-               }
-               
-               case HAPTIC_CMDID_RUN_CALIBRATION:
-               {
-                       drv2624_stop(pDRV2624); 
-                       drv2624_enableIRQ(pDRV2624, NO);        
-                       ret = dev_auto_calibrate(pDRV2624);
-                       if(ret < 0) drv2624_disableIRQ(pDRV2624);
+                                                       pDRV2624->dev,
+                                                       GFP_KERNEL,
+                                                       pDRV2624,
+                                                       drv2624_firmware_load);
+               break;
+
+       case HAPTIC_CMDID_READ_FIRMWARE:
+               if (len == 3) {
+                       pDRV2624->mRAMMSB = buff[1];
+                       pDRV2624->mRAMLSB = buff[2];
+               } else
+                       dev_err(pDRV2624->dev, "%s, read fw len error\n", __func__);
+               break;
+
+       case HAPTIC_CMDID_RUN_CALIBRATION:
+               nResult = drv2624_stop(pDRV2624);
+               if (nResult < 0)
                        break;
-               }
-               
-               case HAPTIC_CMDID_CONFIG_WAVEFORM:
-               {
-                       if(len == (1+ sizeof(struct drv2624_wave_setting))){
-                               struct drv2624_wave_setting wavesetting;
-                               memcpy(&wavesetting, &p_kBuf[1], 
-                                       sizeof(struct drv2624_wave_setting));
-                               ret = drv2624_config_waveform(pDRV2624, &wavesetting);
-                       }else{
-                               dev_dbg(pDRV2624->dev, "pass cmd, prepare for read\n");
-                       }
-               }
-               break;  
-
-               case HAPTIC_CMDID_SET_SEQUENCER:
-               {
-                       if(len == (1+ sizeof(struct drv2624_waveform_sequencer))){
-                               struct drv2624_waveform_sequencer sequencer;
-                               memcpy(&sequencer, &p_kBuf[1], 
-                                       sizeof(struct drv2624_waveform_sequencer));
-                               ret = drv2624_set_waveform(pDRV2624, &sequencer);
-                       }else{
-                               dev_dbg(pDRV2624->dev, "pass cmd, prepare for read\n");
-                       }
-               }
-               break;  
-               
-               case HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE:
-               {
-                       drv2624_stop(pDRV2624); 
-                       drv2624_enableIRQ(pDRV2624, NO);        
-                       ret = drv2624_playEffect(pDRV2624);
-                       if(ret < 0) drv2624_disableIRQ(pDRV2624);
-                       break;
-               }
-                               
-               default:
-                       dev_err(pDRV2624->dev, 
-                       "%s, unknown cmd\n", __FUNCTION__);
+
+               nResult = dev_auto_calibrate(pDRV2624);
+               if ((nResult >= 0) && pDRV2624->mbIRQUsed)
+                       drv2624_enableIRQ(pDRV2624, NO);
+               break;
+
+       case HAPTIC_CMDID_CONFIG_WAVEFORM:
+               if (len == (1 + sizeof(struct drv2624_wave_setting))) {
+                       struct drv2624_wave_setting wavesetting;
+
+                       memcpy(&wavesetting, &p_kBuf[1], sizeof(struct drv2624_wave_setting));
+                       nResult = drv2624_config_waveform(pDRV2624, &wavesetting);
+               } else
+                       dev_dbg(pDRV2624->dev, "pass cmd, prepare for read\n");
+               break;
+
+       case HAPTIC_CMDID_SET_SEQUENCER:
+               if (len == (1 + sizeof(struct drv2624_waveform_sequencer))) {
+                       struct drv2624_waveform_sequencer sequencer;
+
+                       memcpy(&sequencer, &p_kBuf[1], sizeof(struct drv2624_waveform_sequencer));
+                       nResult = drv2624_set_waveform(pDRV2624, &sequencer);
+               } else
+                       dev_dbg(pDRV2624->dev, "pass cmd, prepare for read\n");
+               break;
+
+       case HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE:
+               nResult = drv2624_stop(pDRV2624);
+               if (nResult < 0)
                        break;
-    }
-       
+
+               nResult = drv2624_playEffect(pDRV2624);
+               if ((nResult >= 0) && pDRV2624->mbIRQUsed)
+                       drv2624_enableIRQ(pDRV2624, NO);
+               break;
+
+       case HAPTIC_CMDID_STOP:
+               nResult = drv2624_stop(pDRV2624);
+               break;
+
+       case HAPTIC_CMDID_REGLOG_ENABLE:
+               if (len == 2)
+                       g_logEnable = p_kBuf[1];
+               break;
+
+       default:
+               dev_err(pDRV2624->dev, "%s, unknown cmd\n", __func__);
+               break;
+       }
+
 err:
-       if(p_kBuf != NULL)
+       if (p_kBuf != NULL)
                kfree(p_kBuf);
-       
+
     mutex_unlock(&pDRV2624->lock);
 
     return len;
@@ -989,34 +1124,32 @@ static struct miscdevice drv2624_misc =
  
 static int Haptics_init(struct drv2624_data *pDRV2624)
 {
-    int ret = 0;
-       
+       int nResult = 0;
+
        pDRV2624->to_dev.name = "vibrator";
        pDRV2624->to_dev.get_time = vibrator_get_time;
        pDRV2624->to_dev.enable = vibrator_enable;
 
-       ret = timed_output_dev_register(&(pDRV2624->to_dev));
-    if ( ret < 0){
-        dev_err(pDRV2624->dev, 
-                       "drv2624: fail to create timed output dev\n");
-        return ret;
-    }
-       
-       ret = misc_register(&drv2624_misc);
-       if (ret) {
-               dev_err(pDRV2624->dev, 
-                       "drv2624 misc fail: %d\n", ret);
-               return ret;
+       nResult = timed_output_dev_register(&(pDRV2624->to_dev));
+       if (nResult < 0) {
+               dev_err(pDRV2624->dev, "drv2624: fail to create timed output dev\n");
+               return nResult;
        }
-       
-    hrtimer_init(&pDRV2624->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-    pDRV2624->timer.function = vibrator_timer_func;
-    INIT_WORK(&pDRV2624->vibrator_work, vibrator_work_routine);
-    
-    wake_lock_init(&pDRV2624->wklock, WAKE_LOCK_SUSPEND, "vibrator");
-    mutex_init(&pDRV2624->lock);
-       
-    return 0;
+
+       nResult = misc_register(&drv2624_misc);
+       if (nResult) {
+               dev_err(pDRV2624->dev, "drv2624 misc fail: %d\n", nResult);
+               return nResult;
+       }
+
+       hrtimer_init(&pDRV2624->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       pDRV2624->timer.function = vibrator_timer_func;
+       INIT_WORK(&pDRV2624->vibrator_work, vibrator_work_routine);
+
+       wake_lock_init(&pDRV2624->wklock, WAKE_LOCK_SUSPEND, "vibrator");
+       mutex_init(&pDRV2624->lock);
+
+       return 0;
 }
 
 static void dev_init_platform_data(struct drv2624_data *pDRV2624)
@@ -1025,190 +1158,187 @@ static void dev_init_platform_data(struct drv2624_data *pDRV2624)
        struct actuator_data actuator = pDrv2624Platdata->msActuator;
        unsigned char value_temp = 0;
        unsigned char mask_temp = 0;
-       
+
        drv2624_set_bits(pDRV2624, 
                DRV2624_REG_MODE, PINFUNC_MASK, (PINFUNC_INT<<PINFUNC_SHIFT));
-       
-       if((actuator.mnActuatorType == ERM)||
-               (actuator.mnActuatorType == LRA)){
+
+       if ((actuator.mnActuatorType == ERM)
+               || (actuator.mnActuatorType == LRA)) {
                mask_temp |= ACTUATOR_MASK;
                value_temp |= (actuator.mnActuatorType << ACTUATOR_SHIFT);
        }
-       
-       if((pDrv2624Platdata->mnLoop == CLOSE_LOOP)||
-               (pDrv2624Platdata->mnLoop == OPEN_LOOP)){
+
+       if ((pDrv2624Platdata->mnLoop == CLOSE_LOOP)
+               || (pDrv2624Platdata->mnLoop == OPEN_LOOP)) {
                mask_temp |= LOOP_MASK;
                value_temp |= (pDrv2624Platdata->mnLoop << LOOP_SHIFT);
        }
-       
-       if(value_temp != 0){
-               drv2624_set_bits(pDRV2624, 
-                       DRV2624_REG_CONTROL1, 
+
+       if (value_temp != 0)
+               drv2624_set_bits(pDRV2624, DRV2624_REG_CONTROL1, 
                        mask_temp|AUTOBRK_OK_MASK, value_temp|AUTOBRK_OK_ENABLE);
-       }
-       
+
        value_temp = 0;
-       if(actuator.mnActuatorType == ERM)
+       if (actuator.mnActuatorType == ERM)
                value_temp = LIB_ERM;
-       else if(actuator.mnActuatorType == LRA)
+       else if (actuator.mnActuatorType == LRA)
                value_temp = LIB_LRA;
-       if(value_temp != 0){
-               drv2624_set_bits(pDRV2624, 
-                       DRV2624_REG_CONTROL2, LIB_MASK, value_temp<<LIB_SHIFT);
-       }
-               
-       if(actuator.mnRatedVoltage != 0){
-               drv2624_reg_write(pDRV2624, 
-                       DRV2624_REG_RATED_VOLTAGE, actuator.mnRatedVoltage);
-       }else{
-               dev_err(pDRV2624->dev, 
-                       "%s, ERROR Rated ZERO\n", __FUNCTION__);
-       }
+       if (value_temp != 0)
+               drv2624_set_bits(pDRV2624, DRV2624_REG_CONTROL2, LIB_MASK, value_temp<<LIB_SHIFT);
 
-       if(actuator.mnOverDriveClampVoltage != 0){
-               drv2624_reg_write(pDRV2624, 
-                       DRV2624_REG_OVERDRIVE_CLAMP, actuator.mnOverDriveClampVoltage);
-       }else{
-               dev_err(pDRV2624->dev,
-                       "%s, ERROR OverDriveVol ZERO\n", __FUNCTION__);
-       }
-               
-       if(actuator.mnActuatorType == LRA){
+       if (actuator.mnRatedVoltage != 0)
+               drv2624_reg_write(pDRV2624, DRV2624_REG_RATED_VOLTAGE, actuator.mnRatedVoltage);
+       else
+               dev_err(pDRV2624->dev, "%s, ERROR Rated ZERO\n", __func__);
+
+       if (actuator.mnOverDriveClampVoltage != 0)
+               drv2624_reg_write(pDRV2624, DRV2624_REG_OVERDRIVE_CLAMP, actuator.mnOverDriveClampVoltage);
+       else
+               dev_err(pDRV2624->dev,"%s, ERROR OverDriveVol ZERO\n", __func__);
+
+
+       if (actuator.mnActuatorType == LRA) {
                unsigned char DriveTime = 5*(1000 - actuator.mnLRAFreq)/actuator.mnLRAFreq;
-               unsigned short openLoopPeriod = 
+               unsigned short openLoopPeriod =
                        (unsigned short)((unsigned int)1000000000 / (24619 * actuator.mnLRAFreq)); 
-                       
-               if(actuator.mnLRAFreq < 125) 
+
+               if (actuator.mnLRAFreq < 125) 
                        DriveTime |= (MINFREQ_SEL_45HZ << MINFREQ_SEL_SHIFT);
-               drv2624_set_bits(pDRV2624, 
-                       DRV2624_REG_DRIVE_TIME, 
-                       DRIVE_TIME_MASK | MINFREQ_SEL_MASK, DriveTime); 
-               drv2624_set_bits(pDRV2624, 
-                       DRV2624_REG_OL_PERIOD_H, 0x03, (openLoopPeriod&0x0300)>>8);                     
-               drv2624_reg_write(pDRV2624, 
-                       DRV2624_REG_OL_PERIOD_L, (openLoopPeriod&0x00ff));
-               
-               dev_info(pDRV2624->dev,
-                       "%s, LRA = %d, DriveTime=0x%x\n", 
-                       __FUNCTION__, actuator.mnLRAFreq, DriveTime);
-       }       
+               drv2624_set_bits(pDRV2624, DRV2624_REG_DRIVE_TIME,
+                       DRIVE_TIME_MASK | MINFREQ_SEL_MASK, DriveTime);
+               drv2624_set_bits(pDRV2624, DRV2624_REG_OL_PERIOD_H, 0x03, (openLoopPeriod&0x0300)>>8);
+               drv2624_reg_write(pDRV2624, DRV2624_REG_OL_PERIOD_L, (openLoopPeriod&0x00ff));
+
+               dev_info(pDRV2624->dev, "%s, LRA = %d, DriveTime=0x%x\n", 
+                       __func__, actuator.mnLRAFreq, DriveTime);
+       }
 }
 
 static irqreturn_t drv2624_irq_handler(int irq, void *dev_id)
 {
        struct drv2624_data *pDRV2624 = (struct drv2624_data *)dev_id;
-       
+
        pDRV2624->mnWorkMode |= WORK_IRQ;
        schedule_work(&pDRV2624->vibrator_work);
        return IRQ_HANDLED;
 }
 
-static int drv2624_parse_dt(struct device *dev,
-                       struct drv2624_data *pDRV2624)
+static int drv2624_parse_dt(struct device *dev, struct drv2624_data *pDRV2624)
 {
        struct device_node *np = dev->of_node;
        struct drv2624_platform_data *pPlatData = &pDRV2624->msPlatData;
-       int rc= 0, ret = 0;
+       int rc= 0, nResult = 0;
        unsigned int value;
-       
+
        pPlatData->mnGpioNRST = of_get_named_gpio(np, "ti,reset-gpio", 0);
        if (pPlatData->mnGpioNRST < 0) {
                dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
-                       "ti,reset-gpio", np->full_name,
-                       pPlatData->mnGpioNRST);
-               ret = -1;
-       }else{
+                       "ti,reset-gpio", np->full_name, pPlatData->mnGpioNRST);
+               nResult = -EINVAL;
+       } else
                dev_dbg(pDRV2624->dev, "ti,reset-gpio=%d\n", pPlatData->mnGpioNRST);
-       }
-       
-       if(ret >=0){
-               pPlatData->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
-               if (pPlatData->mnGpioINT < 0) {
-                       dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
-                               "ti,irq-gpio", np->full_name,
-                               pPlatData->mnGpioINT);
-                       ret = -1;
-               }else{
-                       dev_dbg(pDRV2624->dev, "ti,irq-gpio=%d\n", pPlatData->mnGpioINT);
-               }
-       }
-       
-       if(ret >=0){
+
+       if (nResult >=0) {
                rc = of_property_read_u32(np, "ti,smart-loop", &value);
                if (rc) {
                        dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
                                "ti,smart-loop", np->full_name, rc);
-                       ret = -2;
-               }else{
-                       pPlatData->mnLoop = value&0x01;
-                       dev_dbg(pDRV2624->dev, 
-                               "ti,smart-loop=%d\n", pPlatData->mnLoop);
+                       nResult = -EINVAL;
+               } else {
+                       pPlatData->mnLoop = value & 0x01;
+                       dev_dbg(pDRV2624->dev, "ti,smart-loop=%d\n", pPlatData->mnLoop);
                }
-       }       
-       
-       if(ret >=0){
+       }
+
+       if (nResult >=0) {
                rc = of_property_read_u32(np, "ti,actuator", &value);
                if (rc) {
                        dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
                                "ti,actuator", np->full_name, rc);
-                       ret = -2;
-               }else{
-                       pPlatData->msActuator.mnActuatorType = value&0x01;
-                       dev_dbg(pDRV2624->dev, 
-                               "ti,actuator=%d\n", pPlatData->msActuator.mnActuatorType);
+                       nResult = -EINVAL;
+               } else {
+                       pPlatData->msActuator.mnActuatorType = value & 0x01;
+                       dev_dbg(pDRV2624->dev, "ti,actuator=%d\n",
+                               pPlatData->msActuator.mnActuatorType);
                }
        }
-               
-       if(ret >=0){
+
+       if (nResult >=0) {
                rc = of_property_read_u32(np, "ti,rated-voltage", &value);
                if (rc) {
                        dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
                                "ti,rated-voltage", np->full_name, rc);
-                       ret = -2;
+                       nResult = -EINVAL;
                }else{
                        pPlatData->msActuator.mnRatedVoltage = value;
-                       dev_dbg(pDRV2624->dev, 
-                               "ti,rated-voltage=0x%x\n", pPlatData->msActuator.mnRatedVoltage);
+                       dev_dbg(pDRV2624->dev, "ti,rated-voltage=0x%x\n",
+                               pPlatData->msActuator.mnRatedVoltage);
                }
        }
-       
-       if(ret >=0){
+
+       if (nResult >=0) {
                rc = of_property_read_u32(np, "ti,odclamp-voltage", &value);
                if (rc) {
                        dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
                                "ti,odclamp-voltage", np->full_name, rc);
-                       ret = -2;
-               }else{
+                       nResult = -EINVAL;
+               } else {
                        pPlatData->msActuator.mnOverDriveClampVoltage = value;
-                       dev_dbg(pDRV2624->dev, 
-                               "ti,odclamp-voltage=0x%x\n", 
+                       dev_dbg(pDRV2624->dev, "ti,odclamp-voltage=0x%x\n", 
                                pPlatData->msActuator.mnOverDriveClampVoltage);
                }
        }
-       
-       if((ret >=0)&&(pPlatData->msActuator.mnActuatorType == LRA)){
+
+       if ((nResult >= 0) && (pPlatData->msActuator.mnActuatorType == LRA)) {
                rc = of_property_read_u32(np, "ti,lra-frequency", &value);
                if (rc) {
                        dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
                                "ti,lra-frequency", np->full_name, rc);
-                       ret = -3;
-               }else{
-                       if((value >= 45) &&(value <= 300)){
+                       nResult = -EINVAL;
+               } else {
+                       if ((value >= 45) && (value <= 300)) {
                                pPlatData->msActuator.mnLRAFreq = value;
-                               dev_dbg(pDRV2624->dev, 
-                                       "ti,lra-frequency=%d\n", 
+                               dev_dbg(pDRV2624->dev, "ti,lra-frequency=%d\n",
+                                       pPlatData->msActuator.mnLRAFreq);
+                       } else {
+                               nResult = -EINVAL;
+                               dev_err(pDRV2624->dev, "ERROR, ti,lra-frequency=%d, out of range\n", 
                                        pPlatData->msActuator.mnLRAFreq);
-                       }else{
-                               ret = -1;
-                               dev_err(pDRV2624->dev, 
-                                       "ERROR, ti,lra-frequency=%d, out of range\n", 
-                                       pPlatData->msActuator.mnLRAFreq);                               
                        }
                }
        }
-       
-       return ret;
+
+       if (nResult >= 0) {
+               pPlatData->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
+               if (pPlatData->mnGpioINT < 0) {
+                       dev_err(pDRV2624->dev, "Looking up %s property in node %s failed %d\n",
+                               "ti,irq-gpio", np->full_name, pPlatData->mnGpioINT);
+               } else
+                       dev_dbg(pDRV2624->dev, "ti,irq-gpio=%d\n", pPlatData->mnGpioINT);
+       }
+
+       return nResult;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int drv2624_suspend(struct device *dev)
+{
+       struct drv2624_data *pDRV2624 = dev_get_drvdata(dev);
+
+       dev_dbg(pDRV2624->dev, "%s\n", __func__);
+       mutex_lock(&pDRV2624->lock);
+       if (hrtimer_active(&pDRV2624->timer) || pDRV2624->mnVibratorPlaying)
+               drv2624_stop(pDRV2624);
+       mutex_unlock(&pDRV2624->lock);
+
+       return 0;
+}
+
+static int drv2624_resume(struct device *dev)
+{
+       return 0; 
 }
+#endif
 
 static struct regmap_config drv2624_i2c_regmap = {
        .reg_bits = 8,
@@ -1219,64 +1349,58 @@ static struct regmap_config drv2624_i2c_regmap = {
 static int drv2624_i2c_probe(struct i2c_client* client, const struct i2c_device_id* id)
 {
        struct drv2624_data *pDRV2624;
-       int err = 0;
+       int nResult = 0;
 
-       dev_info(&client->dev, "%s enter\n", __FUNCTION__);
-       
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
-       {
-               dev_err(&client->dev, "%s:I2C check failed\n", __FUNCTION__);
+       dev_info(&client->dev, "%s enter\n", __func__);
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               dev_err(&client->dev, "%s:I2C check failed\n", __func__);
                return -ENODEV;
        }
 
        pDRV2624 = devm_kzalloc(&client->dev, sizeof(struct drv2624_data), GFP_KERNEL);
-       if (pDRV2624 == NULL){
-               dev_err(&client->dev, "%s:no memory\n", __FUNCTION__);
+       if (pDRV2624 == NULL) {
+               dev_err(&client->dev, "%s:no memory\n", __func__);
                return -ENOMEM;
        }
 
        pDRV2624->dev = &client->dev;
        i2c_set_clientdata(client,pDRV2624);
        dev_set_drvdata(&client->dev, pDRV2624);
-       
+
        pDRV2624->mpRegmap = devm_regmap_init_i2c(client, &drv2624_i2c_regmap);
        if (IS_ERR(pDRV2624->mpRegmap)) {
-               err = PTR_ERR(pDRV2624->mpRegmap);
-               dev_err(pDRV2624->dev, 
-                       "%s:Failed to allocate register map: %d\n",__FUNCTION__,err);
-               return err;
+               nResult = PTR_ERR(pDRV2624->mpRegmap);
+               dev_err(pDRV2624->dev, "%s:Failed to allocate register map: %d\n",
+                       __func__, nResult);
+               return nResult;
        }
 
-       if (client->dev.of_node){
+       if (client->dev.of_node) {
                dev_dbg(pDRV2624->dev, "of node parse\n");
-               err = drv2624_parse_dt(&client->dev, pDRV2624);
-       }else if(client->dev.platform_data){
+               nResult = drv2624_parse_dt(&client->dev, pDRV2624);
+       } else if (client->dev.platform_data) {
                dev_dbg(pDRV2624->dev, "platform data parse\n");
-               memcpy(&pDRV2624->msPlatData, 
-                       client->dev.platform_data, sizeof(struct drv2624_platform_data));
-       }else{
-               dev_err(pDRV2624->dev, 
-                       "%s: ERROR no platform data\n",__FUNCTION__);
-               return -1;
+               memcpy(&pDRV2624->msPlatData, client->dev.platform_data,
+                       sizeof(struct drv2624_platform_data));
+       } else {
+               dev_err(pDRV2624->dev, "%s: ERROR no platform data\n",__func__);
+               return -EINVAL;
        }
-       
-       if((err < 0)
-               ||(pDRV2624->msPlatData.mnGpioNRST <= 0)
-               ||(pDRV2624->msPlatData.mnGpioINT <= 0)){
-               dev_err(pDRV2624->dev, 
-                       "%s: platform data error\n",__FUNCTION__);
-               return -1;              
+
+       if ((nResult < 0) || !gpio_is_valid(pDRV2624->msPlatData.mnGpioNRST)) {
+               dev_err(pDRV2624->dev, "%s: platform data error\n",__func__);
+               return -EINVAL;
        }
-               
-       if(pDRV2624->msPlatData.mnGpioNRST){
-               err = gpio_request(pDRV2624->msPlatData.mnGpioNRST,"DRV2624-NRST");
-               if(err < 0){
-                       dev_err(pDRV2624->dev, 
-                               "%s: GPIO %d request NRST error\n", 
-                               __FUNCTION__, pDRV2624->msPlatData.mnGpioNRST);                         
-                       return err;
+
+       if (gpio_is_valid(pDRV2624->msPlatData.mnGpioNRST)) {
+               nResult = gpio_request(pDRV2624->msPlatData.mnGpioNRST,"DRV2624-NRST");
+               if (nResult < 0) {
+                       dev_err(pDRV2624->dev, "%s: GPIO %d request NRST error\n",
+                               __func__, pDRV2624->msPlatData.mnGpioNRST);
+                       return nResult;
                }
-               
+
                gpio_direction_output(pDRV2624->msPlatData.mnGpioNRST, 0);
                mdelay(5);
                gpio_direction_output(pDRV2624->msPlatData.mnGpioNRST, 1);
@@ -1284,85 +1408,68 @@ static int drv2624_i2c_probe(struct i2c_client* client, const struct i2c_device_
        }
 
        mutex_init(&pDRV2624->dev_lock);
-       err = drv2624_reg_read(pDRV2624, DRV2624_REG_ID);
-       if(err < 0){
-               dev_err(pDRV2624->dev, 
-                       "%s, i2c bus fail (%d)\n", __FUNCTION__, err);
+       nResult = drv2624_reg_read(pDRV2624, DRV2624_REG_ID);
+       if (nResult < 0)
                goto exit_gpio_request_failed1;
-       }else{
-               dev_info(pDRV2624->dev, 
-                       "%s, ID status (0x%x)\n", __FUNCTION__, err);
-               pDRV2624->mnDeviceID = err;
+       else {
+               dev_info(pDRV2624->dev, "%s, ID status (0x%x)\n", __func__, nResult);
+               pDRV2624->mnDeviceID = nResult;
        }
-       
-       if((pDRV2624->mnDeviceID&0xf0) != DRV2624_ID){
-               dev_err(pDRV2624->dev, 
-                       "%s, device_id(0x%x) fail\n",
-                       __FUNCTION__, pDRV2624->mnDeviceID);
+
+       if ((pDRV2624->mnDeviceID & 0xf0) != DRV2624_ID) {
+               dev_err(pDRV2624->dev, "%s, device_id(0x%x) fail\n",
+                       __func__, pDRV2624->mnDeviceID);
                goto exit_gpio_request_failed1;
        }
-       
+
        dev_init_platform_data(pDRV2624);
 
-       if(pDRV2624->msPlatData.mnGpioINT){
-               err = gpio_request(pDRV2624->msPlatData.mnGpioINT, "DRV2624-IRQ");
-               if(err < 0){
-                       dev_err(pDRV2624->dev, 
-                               "%s: GPIO %d request INT error\n", 
-                               __FUNCTION__, pDRV2624->msPlatData.mnGpioINT);                                  
+       if (gpio_is_valid(pDRV2624->msPlatData.mnGpioINT)) {
+               nResult = gpio_request(pDRV2624->msPlatData.mnGpioINT, "DRV2624-IRQ");
+               if (nResult < 0) {
+                       dev_err(pDRV2624->dev, "%s: GPIO %d request INT error\n",
+                               __func__, pDRV2624->msPlatData.mnGpioINT);
                        goto exit_gpio_request_failed1;
                }
-
                gpio_direction_input(pDRV2624->msPlatData.mnGpioINT);
-
                pDRV2624->mnIRQ = gpio_to_irq(pDRV2624->msPlatData.mnGpioINT);
                dev_dbg(pDRV2624->dev, "irq = %d \n", pDRV2624->mnIRQ);
-               
-               err = request_threaded_irq(pDRV2624->mnIRQ, drv2624_irq_handler,
-                               NULL, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                               client->name, pDRV2624);
-
-               if (err < 0) {
-                       dev_err(pDRV2624->dev, 
-                               "request_irq failed, %d\n", err);                                                       
+
+               nResult = request_threaded_irq(pDRV2624->mnIRQ, drv2624_irq_handler,
+                               NULL, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, pDRV2624);
+               if (nResult < 0) {
+                       dev_err(pDRV2624->dev, "request_irq failed, %d\n", nResult);
                        goto exit_gpio_request_failed2;
                }
-               drv2624_disableIRQ(pDRV2624);
-       }
+               disable_irq_nosync(pDRV2624->mnIRQ);
+               pDRV2624->mbIRQEnabled = false;
+               pDRV2624->mbIRQUsed = true;
+       } else
+               pDRV2624->mbIRQUsed = false;
 
        g_DRV2624data = pDRV2624;
-       
-    Haptics_init(pDRV2624);
 
-       request_firmware_nowait(THIS_MODULE, 
-                                               FW_ACTION_HOTPLUG,
-                                               "drv2624.bin",
-                                               &(client->dev), 
-                                               GFP_KERNEL, 
-                                               pDRV2624, 
-                                               drv2624_firmware_load); 
-               
-    dev_info(pDRV2624->dev, 
-               "drv2624 probe succeeded\n");
+       Haptics_init(pDRV2624);
+
+       request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "drv2624.bin", 
+               &(client->dev), GFP_KERNEL, pDRV2624, drv2624_firmware_load);
+
+       dev_info(pDRV2624->dev, "drv2624 probe succeeded\n");
 
-    return 0;
+       return 0;
 
 exit_gpio_request_failed2:
-       if(pDRV2624->msPlatData.mnGpioINT > 0){
+       if (gpio_is_valid(pDRV2624->msPlatData.mnGpioINT))
                gpio_free(pDRV2624->msPlatData.mnGpioINT);
-       }
-       
-exit_gpio_request_failed1:     
-       if(pDRV2624->msPlatData.mnGpioNRST > 0){
+
+exit_gpio_request_failed1:
+       if (gpio_is_valid(pDRV2624->msPlatData.mnGpioNRST))
                gpio_free(pDRV2624->msPlatData.mnGpioNRST);
-       }
 
        mutex_destroy(&pDRV2624->dev_lock);
-       
-    dev_err(pDRV2624->dev, 
-               "%s failed, err=%d\n",
-               __FUNCTION__, err);
-       return err;
+
+       dev_err(pDRV2624->dev, "%s failed, err=%d\n", __func__, nResult);
+       return nResult;
 }
 
 static int drv2624_i2c_remove(struct i2c_client* client)
@@ -1377,10 +1484,10 @@ static int drv2624_i2c_remove(struct i2c_client* client)
 
        misc_deregister(&drv2624_misc);
 
-       mutex_destroy(&pDRV2624->lock); 
+       mutex_destroy(&pDRV2624->lock);
        mutex_destroy(&pDRV2624->dev_lock);
-       
-    return 0;
+
+       return 0;
 }
 
 static const struct i2c_device_id drv2624_i2c_id[] = {
@@ -1388,6 +1495,12 @@ static const struct i2c_device_id drv2624_i2c_id[] = {
        {}
 };
 
+#ifdef CONFIG_PM_SLEEP
+static const struct dev_pm_ops drv2624_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(drv2624_suspend, drv2624_resume)
+};
+#endif
+
 MODULE_DEVICE_TABLE(i2c, drv2624_i2c_id);
 
 #if defined(CONFIG_OF)
@@ -1403,6 +1516,9 @@ static struct i2c_driver drv2624_i2c_driver = {
        .driver = {
                        .name = "drv2624",
                        .owner = THIS_MODULE,
+#ifdef CONFIG_PM_SLEEP
+                       .pm = &drv2624_pm_ops,
+#endif
 #if defined(CONFIG_OF)
                        .of_match_table = of_match_ptr(drv2624_of_match),
 #endif
index 9d2cd49273f1e9eb70f7c7bbdc29e057be3f1410..b827e5d9ffbbe940e45873fe6ac97233f58284ac 100755 (executable)
--- a/drv2624.h
+++ b/drv2624.h
 #define        INTERVAL_SHIFT                          0x05
 
 #define        DRV2624_REG_RTP_INPUT           0x0e
-
 #define        DRV2624_REG_SEQUENCER_1         0x0f
-
 #define        DRV2624_REG_SEQ_LOOP_1          0x17
-
 #define        DRV2624_REG_SEQ_LOOP_2          0x18
-
 #define        DRV2624_REG_MAIN_LOOP           0x19
-
 #define        DRV2624_REG_RATED_VOLTAGE       0x1f
-
 #define        DRV2624_REG_OVERDRIVE_CLAMP     0x20
-
 #define        DRV2624_REG_CAL_COMP            0x21
-
 #define        DRV2624_REG_CAL_BEMF            0x22
-
 #define        DRV2624_REG_LOOP_CONTROL        0x23
 #define        BEMFGAIN_MASK                           0x03
 
 #define        MINFREQ_SEL_SHIFT                       0x07
 
 #define        DRV2624_REG_OL_PERIOD_H         0x2e
-
 #define        DRV2624_REG_OL_PERIOD_L         0x2f
-
 #define        DRV2624_REG_DIAG_K                      0x30
 
-#define GO_BIT_POLL_INTERVAL    15
-#define STANDBY_WAKE_DELAY      1
-#define WAKE_STANDBY_DELAY      3
+#define        GO_BIT_POLL_INTERVAL    15
+#define        STANDBY_WAKE_DELAY              1
+#define        WAKE_STANDBY_DELAY              3
 
 #define        DRV2624_REG_RAM_ADDR_UPPER      0xfd
 #define        DRV2624_REG_RAM_ADDR_LOWER      0xfe
 #define        DRV2624_REG_RAM_DATA                    0xff
 
 /* Commands */
-#define HAPTIC_CMDID_PLAY_SINGLE_EFFECT     0x01
-#define HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE   0x02
-#define HAPTIC_CMDID_PLAY_TIMED_EFFECT      0x03
-#define HAPTIC_CMDID_GET_DEV_ID             0x04
-#define HAPTIC_CMDID_RUN_DIAG               0x05
-#define HAPTIC_CMDID_AUDIOHAPTIC_ENABLE     0x06
-#define HAPTIC_CMDID_AUDIOHAPTIC_DISABLE    0x07
-#define HAPTIC_CMDID_AUDIOHAPTIC_GETSTATUS  0x08
-
-#define HAPTIC_CMDID_REG_WRITE         0x09
-#define HAPTIC_CMDID_REG_READ          0x0a
-#define HAPTIC_CMDID_REG_SETBIT        0x0b
-
-#define HAPTIC_CMDID_PATTERN_RTP      0x0c
-#define HAPTIC_CMDID_RTP_SEQUENCE        0x0d
-#define HAPTIC_CMDID_GET_EFFECT_COUNT          0x10
-#define HAPTIC_CMDID_UPDATE_FIRMWARE           0x11
-#define HAPTIC_CMDID_READ_FIRMWARE                     0x12
-#define HAPTIC_CMDID_RUN_CALIBRATION        0x13
-#define        HAPTIC_CMDID_CONFIG_WAVEFORM            0x14
-#define        HAPTIC_CMDID_SET_SEQUENCER                      0x15
-
-#define HAPTIC_CMDID_STOP                   0xFF
-
-#define MAX_TIMEOUT    10000 /* 10s */
+#define        HAPTIC_CMDID_PLAY_SINGLE_EFFECT         0x01
+#define        HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE       0x02
+#define        HAPTIC_CMDID_PLAY_TIMED_EFFECT          0x03
+#define        HAPTIC_CMDID_GET_DEV_ID                         0x04
+#define        HAPTIC_CMDID_RUN_DIAG                           0x05
+#define        HAPTIC_CMDID_AUDIOHAPTIC_ENABLE         0x06
+#define        HAPTIC_CMDID_AUDIOHAPTIC_DISABLE        0x07
+#define        HAPTIC_CMDID_AUDIOHAPTIC_GETSTATUS      0x08
+#define        HAPTIC_CMDID_REG_WRITE                          0x09
+#define        HAPTIC_CMDID_REG_READ                           0x0a
+#define        HAPTIC_CMDID_REG_SETBIT                         0x0b
+#define        HAPTIC_CMDID_PATTERN_RTP                        0x0c
+#define        HAPTIC_CMDID_RTP_SEQUENCE                       0x0d
+#define        HAPTIC_CMDID_GET_EFFECT_COUNT           0x10
+#define        HAPTIC_CMDID_UPDATE_FIRMWARE            0x11
+#define        HAPTIC_CMDID_READ_FIRMWARE                      0x12
+#define        HAPTIC_CMDID_RUN_CALIBRATION            0x13
+#define        HAPTIC_CMDID_CONFIG_WAVEFORM            0x14
+#define        HAPTIC_CMDID_SET_SEQUENCER                      0x15
+#define        HAPTIC_CMDID_REGLOG_ENABLE                      0x16
+
+#define        HAPTIC_CMDID_STOP               0xFF
+
+#define        MAX_TIMEOUT             10000 /* 10s */
 #define        MAX_READ_BYTES  0xff
 #define        DRV2624_SEQUENCER_SIZE  8
 
 #define        WORK_IDLE                                       0
 #define        WORK_VIBRATOR                           0x01
 #define        WORK_IRQ                                        0x02
+#define        WORK_EFFECTSEQUENCER            0x04
+#define        WORK_CALIBRATION                        0x08
+#define        WORK_DIAGNOSTIC                         0x10
 
 #define        YES             1
-#define NO             0
+#define        NO              0
 #define        GO              1
-#define STOP   0
+#define        STOP    0
 
+#define        POLL_GO_BIT_INTERVAL    5       /* 5 ms */
+#define        POLL_GO_BIT_RETRY               20      /* 50 times */
 
 enum actuator_type {
        ERM,
@@ -183,7 +176,7 @@ struct actuator_data {
        unsigned char mnActuatorType;
        unsigned char mnRatedVoltage;
        unsigned char mnOverDriveClampVoltage;
-       unsigned char mnLRAFreq;        
+       unsigned char mnLRAFreq;
 };
 
 enum wave_seq_loop {
@@ -218,7 +211,7 @@ enum wave_main_interval {
 
 struct drv2624_waveform {
        unsigned char mnEffect;
-       unsigned char mnLoop;   
+       unsigned char mnLoop;
 };
 
 struct drv2624_waveform_sequencer {
@@ -228,7 +221,7 @@ struct drv2624_waveform_sequencer {
 struct drv2624_wave_setting {
        unsigned char mnLoop;
        unsigned char mnInterval;
-       unsigned char mnScale;  
+       unsigned char mnScale;
 };
 
 struct drv2624_autocal_result {
@@ -247,8 +240,8 @@ struct drv2624_diag_result {
 };
 
 struct drv2624_platform_data {
-       int     mnGpioNRST;
-       int     mnGpioINT;
+       int mnGpioNRST;
+       int mnGpioINT;
        unsigned char mnLoop; 
        struct actuator_data msActuator;
 };
@@ -265,42 +258,41 @@ struct drv2624_fw_header{
 
 struct drv2624_data {
        struct drv2624_platform_data msPlatData;
-       struct mutex dev_lock;  
+       struct mutex dev_lock;
        unsigned char mnDeviceID;
        struct device *dev;
        struct regmap *mpRegmap;
        unsigned int mnIRQ;
        unsigned char mnIntStatus;
+       bool mbIRQEnabled;
+       bool mbIRQUsed;
        struct drv2624_wave_setting msWaveformSetting;
-       struct drv2624_waveform_sequencer msWaveformSequencer;  
+       struct drv2624_waveform_sequencer msWaveformSequencer;
        unsigned char mnFileCmd;
        volatile int mnVibratorPlaying;
        volatile char mnWorkMode;
        unsigned char mnCurrentReg;
-    struct wake_lock wklock;
-    struct hrtimer timer;
-    struct mutex lock;
-    struct work_struct vibrator_work;
-       struct timed_output_dev to_dev; 
-       
+       struct wake_lock wklock;
+       struct hrtimer timer;
+       struct mutex lock;
+       struct work_struct vibrator_work;
+       struct timed_output_dev to_dev;
+
        struct drv2624_autocal_result mAutoCalResult;
        struct drv2624_diag_result mDiagResult;
-       
+
        struct drv2624_fw_header fw_header;
        unsigned char mRAMLSB;
        unsigned char mRAMMSB;
 };
 
-#define        DRV2624_MAGIC_NUMBER    0x32363234      /* '2624' */
-
-
-
-#define        DRV2624_WAVSEQ_PLAY                                     _IOWR(DRV2624_MAGIC_NUMBER, 4, unsigned long)
-#define        DRV2624_STOP                                            _IOWR(DRV2624_MAGIC_NUMBER, 5, unsigned long)
-#define        DRV2624_RUN_DIAGNOSTIC                          _IOWR(DRV2624_MAGIC_NUMBER, 6, unsigned long)
-#define        DRV2624_GET_DIAGRESULT                          _IOWR(DRV2624_MAGIC_NUMBER, 7, struct drv2624_diag_result *)
-#define        DRV2624_RUN_AUTOCAL                                     _IOWR(DRV2624_MAGIC_NUMBER, 8, unsigned long)
-#define        DRV2624_GET_CALRESULT                           _IOWR(DRV2624_MAGIC_NUMBER, 9, struct drv2624_autocal_result *)
+#define DRV2624_MAGIC_NUMBER   0x32363234      /* '2624' */
 
+#define DRV2624_WAVSEQ_PLAY                                    _IOWR(DRV2624_MAGIC_NUMBER, 4, unsigned long)
+#define DRV2624_STOP                                           _IOWR(DRV2624_MAGIC_NUMBER, 5, unsigned long)
+#define DRV2624_RUN_DIAGNOSTIC                         _IOWR(DRV2624_MAGIC_NUMBER, 6, unsigned long)
+#define DRV2624_GET_DIAGRESULT                         _IOWR(DRV2624_MAGIC_NUMBER, 7, struct drv2624_diag_result *)
+#define DRV2624_RUN_AUTOCAL                                    _IOWR(DRV2624_MAGIC_NUMBER, 8, unsigned long)
+#define DRV2624_GET_CALRESULT                          _IOWR(DRV2624_MAGIC_NUMBER, 9, struct drv2624_autocal_result *)
 
 #endif