Merge tag 'AU_LINUX_ANDROID_KK.04.04.02.010.421' into HEAD

AU_LINUX_ANDROID_KK.04.04.02.010.421 based on quic/aosp/kk

Change-Id: I2d3ae6b15f13aeb9f087767b60fa040b05854fe3
diff --git a/FMRecord/res/values-zh-rTW/strings.xml b/FMRecord/res/values-zh-rTW/strings.xml
index a92881c..8820deb 100644
--- a/FMRecord/res/values-zh-rTW/strings.xml
+++ b/FMRecord/res/values-zh-rTW/strings.xml
@@ -30,6 +30,14 @@
     <string name="spaceIsLow_content">USB 存儲設備空間不足,請更改錄音時長設置,或刪除某些錄音或者其他檔案。</string>
     <string name="sdcard_no_space_cannot_recording">SD卡空間不足,不能錄音</string>
     <string name="recording_stop_no_space">SD卡空間不足,錄音停止</string>
+	<string name="audio_db_artist_name">我的FM錄音</string>
+	<!-- all recordings will show up in the media database with this 'album' name -->
+	<string name="audio_db_album_name">FM 錄音</string>
+	<!-- all recordings will show up in the media database in a playlist with this name -->
+	<string name="audio_db_playlist_name">FM 錄音</string>
+	<string name="fm_record_progress">FM 錄音進行中</string>
+	<string name="unable_to_store">無法保存已錄音頻</string>
+	<string name="FMRecording_reach_size_limit">已到達最長限制.</string>
     <!-- prompt message for stopping record -->
     <string name="save_record_file">錄音已保存至 "<xliff:g id="record_file">%1$s</xliff:g>"</string>
 </resources>
diff --git a/FMRecord/src/com/codeaurora/fmrecording/FMRecordingService.java b/FMRecord/src/com/codeaurora/fmrecording/FMRecordingService.java
index 62f4a94..d1c6154 100644
--- a/FMRecord/src/com/codeaurora/fmrecording/FMRecordingService.java
+++ b/FMRecord/src/com/codeaurora/fmrecording/FMRecordingService.java
@@ -92,7 +92,6 @@
     private Thread mStatusCheckThread = null;
     private int clientPid = -1;
     private String clientProcessName = "";
-    private BroadcastReceiver mSdcardUnmountReceiver = null;
     private String mAudioType = "audio/*";
 
     public void onCreate() {
@@ -101,7 +100,6 @@
         Log.d(TAG, "FMRecording Service onCreate");
         registerRecordingListner();
         registerShutdownListner();
-        registerStorageMediaListener();
     }
 
     public int onStartCommand(Intent intent, int flags, int startId) {
@@ -118,7 +116,6 @@
         }
         unregisterBroadCastReceiver(mFmRecordingReceiver);
         unregisterBroadCastReceiver(mFmShutdownReceiver);
-        unregisterBroadCastReceiver(mSdcardUnmountReceiver);
         super.onDestroy();
     }
 
@@ -200,33 +197,6 @@
         return true;
     }
 
-    private void registerStorageMediaListener() {
-        if (mSdcardUnmountReceiver == null) {
-            mSdcardUnmountReceiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                     String action = intent.getAction();
-                    if ((action.equals(Intent.ACTION_MEDIA_UNMOUNTED))
-                          || action.equals(Intent.ACTION_MEDIA_EJECT)) {
-                         Log.d(TAG, "ACTION_MEDIA_UNMOUNTED Intent received");
-                        if (mFmRecordingOn == true) {
-                             try {
-                                  stopRecord();
-                             } catch (Exception e) {
-                                  e.printStackTrace();
-                             }
-                         }
-                     }
-                 }
-             };
-             IntentFilter iFilter = new IntentFilter();
-             iFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
-             iFilter.addAction(Intent.ACTION_MEDIA_EJECT);
-             iFilter.addDataScheme("file");
-             registerReceiver(mSdcardUnmountReceiver, iFilter);
-         }
-     }
-
     private void sendRecordingStatusIntent(int status) {
         Intent intent = new Intent(ACTION_FM_RECORDING_STATUS);
         intent.putExtra("state", status);
diff --git a/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java
index 4410664..5b858c4 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadio.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadio.java
@@ -2624,9 +2624,15 @@
    Runnable mOnStereo = new Runnable() {
       public void run() {
          if (FMRADIO_UI_STATION_AUDIO_STEREO == mStereo) {
-             mStereoTV.setText(R.string.audio_type_stereo);
-         }else if (FMRADIO_UI_STATION_AUDIO_MONO == mStereo) {
-             mStereoTV.setText(R.string.audio_type_mono);
+             if ((Locale.getDefault().getLanguage().equals("zh")))
+                 mStereoTV.setText("立體聲");
+             else
+                 mStereoTV.setText(R.string.audio_type_stereo);
+         } else if (FMRADIO_UI_STATION_AUDIO_MONO == mStereo) {
+             if ((Locale.getDefault().getLanguage().equals("zh")))
+                 mStereoTV.setText("單聲道");
+             else
+                 mStereoTV.setText(R.string.audio_type_mono);
          }else {
              mStereoTV.setText("");
          }
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 12e6841..41947da 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -1056,12 +1056,6 @@
 
        if((TelephonyManager.CALL_STATE_OFFHOOK == state)||
           (TelephonyManager.CALL_STATE_RINGING == state)) {
-           if (state == TelephonyManager.CALL_STATE_RINGING) {
-               int ringvolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
-               if (ringvolume == 0) {
-                   return;
-               }
-           }
            boolean bTempSpeaker = mSpeakerPhoneOn; //need to restore SpeakerPhone
            boolean bTempMute = mMuted;// need to restore Mute status
            int bTempCall = mCallStatus;//need to restore call status
diff --git a/fmapp2/src/com/caf/fmradio/Settings.java b/fmapp2/src/com/caf/fmradio/Settings.java
index 03f88c1..0ad85f1 100644
--- a/fmapp2/src/com/caf/fmradio/Settings.java
+++ b/fmapp2/src/com/caf/fmradio/Settings.java
@@ -230,10 +230,6 @@
              }
           }
 
-          // Add a new category
-          PreferenceCategory prefCat = new PreferenceCategory(this);
-          root.addPreference(prefCat);
-
           mRestoreDefaultPreference = new Preference(this);
           mRestoreDefaultPreference.setTitle(
                                        R.string.settings_revert_defaults_title);
@@ -317,7 +313,11 @@
                   setBandSummary(summaryBandItems.length - 1);
                   clearStationList();
                }else {
-                  Toast.makeText(this, getString(R.string.user_defind_band_msg),
+                  if ((Locale.getDefault().getLanguage().equals("zh")))
+                      Toast.makeText(this,"請輸入有效的頻道範圍76.0-108.0",
+                                                            Toast.LENGTH_SHORT).show();
+                  else
+                      Toast.makeText(this, getString(R.string.user_defind_band_msg),
                                                             Toast.LENGTH_SHORT).show();
                }
            }else if(key.equals(USER_DEFINED_BAND_MAX_KEY)) {
@@ -337,7 +337,11 @@
                   setBandSummary(summaryBandItems.length - 1);
                   clearStationList();
                }else {
-                  Toast.makeText(this, getString(R.string.user_defind_band_msg),
+                  if ((Locale.getDefault().getLanguage().equals("zh")))
+                      Toast.makeText(this,"請輸入有效的頻道範圍76.0-108.0",
+                                                            Toast.LENGTH_SHORT).show();
+                  else
+                      Toast.makeText(this, getString(R.string.user_defind_band_msg),
                                                             Toast.LENGTH_SHORT).show();
                }
           }else {
diff --git a/jni/android_hardware_fm.cpp b/jni/android_hardware_fm.cpp
index 46ae7c4..b3090dd 100644
--- a/jni/android_hardware_fm.cpp
+++ b/jni/android_hardware_fm.cpp
@@ -53,6 +53,7 @@
 #define V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION           (V4L2_CTRL_CLASS_USER + 0x92A)
 #define V4L2_CID_PRIVATE_TAVARUA_ON_CHANNEL_THRESHOLD   (V4L2_CTRL_CLASS_USER + 0x92B)
 #define V4L2_CID_PRIVATE_TAVARUA_OFF_CHANNEL_THRESHOLD  (V4L2_CTRL_CLASS_USER + 0x92C)
+#define V4L2_CID_PRIVATE_IRIS_SET_SPURTABLE             (V4L2_CTRL_CLASS_USER + 0x92D)
 #define TX_RT_LENGTH       63
 #define WAIT_TIMEOUT 200000 /* 200*1000us */
 #define TX_RT_DELIMITER    0x0d
@@ -103,28 +104,35 @@
     } else {
        return FM_JNI_FAILURE;
     }
-    /*Set the mode for soc downloader*/
-    property_set("hw.fm.mode", "normal");
-    /* Need to clear the hw.fm.init firstly */
-    property_set("hw.fm.init", "0");
-    property_set("ctl.start", "fm_dl");
-    sched_yield();
-    for(i=0; i<45; i++) {
-        property_get("hw.fm.init", value, NULL);
-        if (strcmp(value, "1") == 0) {
+
+    property_get("qcom.bluetooth.soc", value, NULL);
+
+    ALOGD("BT soc is %s\n", value);
+
+    if (strcmp(value, "rome") != 0)
+    {
+       /*Set the mode for soc downloader*/
+       property_set("hw.fm.mode", "normal");
+       /* Need to clear the hw.fm.init firstly */
+       property_set("hw.fm.init", "0");
+       property_set("ctl.start", "fm_dl");
+       sched_yield();
+       for(i=0; i<45; i++) {
+         property_get("hw.fm.init", value, NULL);
+         if (strcmp(value, "1") == 0) {
             init_success = 1;
             break;
-        } else {
+         } else {
             usleep(WAIT_TIMEOUT);
-        }
-    }
-    ALOGE("init_success:%d after %f seconds \n", init_success, 0.2*i);
-    if(!init_success) {
-        property_set("ctl.stop", "fm_dl");
-       // close the fd(power down)
-
-       close(fd);
-        return FM_JNI_FAILURE;
+         }
+       }
+       ALOGE("init_success:%d after %f seconds \n", init_success, 0.2*i);
+       if(!init_success) {
+         property_set("ctl.stop", "fm_dl");
+         // close the fd(power down)
+         close(fd);
+         return FM_JNI_FAILURE;
+       }
     }
     return fd;
 }
@@ -135,9 +143,17 @@
 {
     int i = 0;
     int cleanup_success = 0;
-    char value = 0, retval =0;
+    char retval =0;
+    char value[PROPERTY_VALUE_MAX] = {'\0'};
 
-    property_set("ctl.stop", "fm_dl");
+    property_get("qcom.bluetooth.soc", value, NULL);
+
+    ALOGD("BT soc is %s\n", value);
+
+    if (strcmp(value, "rome") != 0)
+    {
+       property_set("ctl.stop", "fm_dl");
+    }
     close(fd);
     return FM_JNI_SUCCESS;
 }
@@ -418,40 +434,48 @@
     char notch[PROPERTY_VALUE_MAX] = {0x00};
     struct v4l2_control control;
     int err;
-    /*Enable/Disable the WAN avoidance*/
-    property_set("hw.fm.init", "0");
-    if (aValue)
-       property_set("hw.fm.mode", "wa_enable");
-    else
-       property_set("hw.fm.mode", "wa_disable");
 
-    property_set("ctl.start", "fm_dl");
-    sched_yield();
-    for(i=0; i<10; i++) {
-       property_get("hw.fm.init", value, NULL);
-       if (strcmp(value, "1") == 0) {
-          init_success = 1;
-          break;
-       } else {
-          usleep(WAIT_TIMEOUT);
+    property_get("qcom.bluetooth.soc", value, NULL);
+
+    ALOGD("BT soc is %s\n", value);
+
+    if (strcmp(value, "rome") != 0)
+    {
+       /*Enable/Disable the WAN avoidance*/
+       property_set("hw.fm.init", "0");
+       if (aValue)
+          property_set("hw.fm.mode", "wa_enable");
+       else
+          property_set("hw.fm.mode", "wa_disable");
+
+       property_set("ctl.start", "fm_dl");
+       sched_yield();
+       for(i=0; i<10; i++) {
+          property_get("hw.fm.init", value, NULL);
+          if (strcmp(value, "1") == 0) {
+             init_success = 1;
+             break;
+          } else {
+             usleep(WAIT_TIMEOUT);
+          }
        }
-    }
-    ALOGE("init_success:%d after %f seconds \n", init_success, 0.2*i);
+       ALOGE("init_success:%d after %f seconds \n", init_success, 0.2*i);
 
-    property_get("notch.value", notch, NULL);
-    ALOGE("Notch = %s",notch);
-    if (!strncmp("HIGH",notch,strlen("HIGH")))
-        control.value = HIGH_BAND;
-    else if(!strncmp("LOW",notch,strlen("LOW")))
-        control.value = LOW_BAND;
-    else
-        control.value = 0;
+       property_get("notch.value", notch, NULL);
+       ALOGE("Notch = %s",notch);
+       if (!strncmp("HIGH",notch,strlen("HIGH")))
+           control.value = HIGH_BAND;
+       else if(!strncmp("LOW",notch,strlen("LOW")))
+           control.value = LOW_BAND;
+       else
+           control.value = 0;
 
-    ALOGE("Notch value : %d", control.value);
-    control.id = id;
-    err = ioctl(fd, VIDIOC_S_CTRL,&control );
-    if(err < 0){
-          return FM_JNI_FAILURE;
+       ALOGE("Notch value : %d", control.value);
+       control.id = id;
+       err = ioctl(fd, VIDIOC_S_CTRL,&control );
+       if(err < 0){
+             return FM_JNI_FAILURE;
+       }
     }
     return FM_JNI_SUCCESS;
 }
@@ -464,22 +488,29 @@
     char value[PROPERTY_VALUE_MAX] = {'\0'};
     char firmwareVersion[80];
 
-    /*Enable/Disable Analog Mode FM*/
-    property_set("hw.fm.init", "0");
-    if (aValue) {
-        property_set("hw.fm.isAnalog", "true");
-    } else {
-        property_set("hw.fm.isAnalog", "false");
-    }
-    property_set("hw.fm.mode","config_dac");
-    property_set("ctl.start", "fm_dl");
-    sched_yield();
-    for(i=0; i<10; i++) {
-       property_get("hw.fm.init", value, NULL);
-       if (strcmp(value, "1") == 0) {
-          return 1;
+    property_get("qcom.bluetooth.soc", value, NULL);
+
+    ALOGD("BT soc is %s\n", value);
+
+    if (strcmp(value, "rome") != 0)
+    {
+       /*Enable/Disable Analog Mode FM*/
+       property_set("hw.fm.init", "0");
+       if (aValue) {
+           property_set("hw.fm.isAnalog", "true");
        } else {
-          usleep(WAIT_TIMEOUT);
+           property_set("hw.fm.isAnalog", "false");
+       }
+       property_set("hw.fm.mode","config_dac");
+       property_set("ctl.start", "fm_dl");
+       sched_yield();
+       for(i=0; i<10; i++) {
+          property_get("hw.fm.init", value, NULL);
+          if (strcmp(value, "1") == 0) {
+             return 1;
+          } else {
+             usleep(WAIT_TIMEOUT);
+          }
        }
     }
 
@@ -736,6 +767,45 @@
     return FM_JNI_SUCCESS;
 }
 
+/* native interface */
+static jint android_hardware_fmradio_FmReceiverJNI_setSpurDataNative
+ (JNIEnv * env, jobject thiz, jint fd, jshortArray buff, jint count)
+{
+    ALOGE("entered JNI's setSpurDataNative\n");
+    int err, i = 0;
+    struct v4l2_ext_control ext_ctl;
+    struct v4l2_ext_controls v4l2_ctls;
+    uint8_t *data;
+    short *spur_data = env->GetShortArrayElements(buff, NULL);
+    if (spur_data == NULL) {
+        ALOGE("Spur data is NULL\n");
+        return FM_JNI_FAILURE;
+    }
+    data = (uint8_t *) malloc(count);
+    if (data == NULL) {
+        ALOGE("Allocation failed for data\n");
+        return FM_JNI_FAILURE;
+    }
+    for(i = 0; i < count; i++)
+        data[i] = (uint8_t) spur_data[i];
+
+    ext_ctl.id = V4L2_CID_PRIVATE_IRIS_SET_SPURTABLE;
+    ext_ctl.string = (char*)data;
+    ext_ctl.size = count;
+    v4l2_ctls.ctrl_class = V4L2_CTRL_CLASS_USER;
+    v4l2_ctls.count   = 1;
+    v4l2_ctls.controls  = &ext_ctl;
+
+    err = ioctl(fd, VIDIOC_S_EXT_CTRLS, &v4l2_ctls );
+    if (err < 0){
+        ALOGE("Set ioctl failed\n");
+        free(data);
+        return FM_JNI_FAILURE;
+    }
+    free(data);
+    return FM_JNI_SUCCESS;
+}
+
 /*
  * JNI registration.
  */
@@ -795,7 +865,8 @@
             (void*)android_hardware_fmradio_FmReceiverJNI_SetCalibrationNative},
         { "configureSpurTable", "(I)I",
             (void*)android_hardware_fmradio_FmReceiverJNI_configureSpurTable},
-
+        { "setSpurDataNative", "(I[SI)I",
+            (void*)android_hardware_fmradio_FmReceiverJNI_setSpurDataNative},
 };
 
 int register_android_hardware_fm_fmradio(JNIEnv* env)
diff --git a/qcom/fmradio/FmConfig.java b/qcom/fmradio/FmConfig.java
index 3044cc2..728d1d3 100644
--- a/qcom/fmradio/FmConfig.java
+++ b/qcom/fmradio/FmConfig.java
@@ -30,7 +30,7 @@
 
 import android.util.Log;
 import android.os.SystemProperties;
-
+import java.util.List;
 
 /**
  *
@@ -47,6 +47,9 @@
      private static final int V4L2_CID_PRIVATE_TAVARUA_SPACING        = V4L2_CID_PRIVATE_BASE + 14;
      private static final int V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM = V4L2_CID_PRIVATE_BASE + 0x2B;
 
+     private static final int each_Spur_entry_size = 16;
+     public static final int no_Of_Spurs_For_Entry = 3;
+
      private static final String TAG = "FmConfig";
 
 
@@ -91,6 +94,54 @@
      */
     private int mBandUpperLimit;
 
+    public static boolean fmSpurConfig(int fd) {
+        SpurFileParser parser = new SpurFileParser();
+        SpurTable t;
+        int freq = 0, i = 0, j = 0;
+        byte no_of_spur_freq = 0;
+        int rotation_value = 0;
+        int re;
+
+        t = parser.GetSpurTable("/etc/fm/SpurTableFile.txt");
+        List <Spur> list = t.GetSpurList();
+        no_of_spur_freq = t.GetspurNoOfFreq();
+        short [] buff = new short[2 + (no_of_spur_freq * each_Spur_entry_size)];
+        buff[0] = t.GetMode();
+        buff[1] = no_of_spur_freq;
+        for(i = 0; i < no_of_spur_freq; i++) {
+            List <Spur> spur = t.GetSpurList();
+            freq = spur.get(i).getSpurFreq();
+            buff[(i * each_Spur_entry_size) + 2] = (short)(freq & 0xff);
+            buff[(i * each_Spur_entry_size) + 3] = (short)((freq >> 8) & 0xff);
+            buff[(i * each_Spur_entry_size) + 4] = (short)((freq >> 16) & 0xff);
+            buff[(i * each_Spur_entry_size) + 5] = spur.get(i).getNoOfSpursToTrack();
+            List <SpurDetails> spurDetails =
+                                spur.get(i).getSpurDetailsList();
+            for(j = 0; j < no_Of_Spurs_For_Entry; j++) {
+                rotation_value = spurDetails.get(j).getRotationValue();
+                buff[(j * 4) + 6 + (i * each_Spur_entry_size)]  =
+                                        (short)(rotation_value & 0xff);
+                buff[(j * 4) + 7 + (i * each_Spur_entry_size)]  =
+                                 (short)((rotation_value >> 8) & 0xff);
+                buff[(j * 4) + 8 + (i * each_Spur_entry_size)]  =
+                                (short)((rotation_value >> 12) & 0xff);
+                buff[(j * 4) + 8 + (i * each_Spur_entry_size)] |=
+                 (short)(spurDetails.get(j).getLsbOfIntegrationLength() << 4);
+                buff[(j * 4) + 8 + (i * each_Spur_entry_size)] |=
+                      (short)(spurDetails.get(j).getFilterCoefficeint() << 5);
+                buff[(j * 4) + 8 + (i * each_Spur_entry_size)] |=
+                    (short)(spurDetails.get(j).getIsEnableSpur() << 7);
+                buff[(j * 4) + 9 + (i * each_Spur_entry_size)]  =
+                              (short)spurDetails.get(j).getSpurLevel();
+            }
+        }
+        re = FmReceiverJNI.setSpurDataNative(fd, buff,
+                        (2 + (no_of_spur_freq * each_Spur_entry_size)));
+        if (re < 0)
+            return false;
+        return true;
+    }
+
     public int getRadioBand(){
         return mRadioBand;
     }
diff --git a/qcom/fmradio/FmReceiver.java b/qcom/fmradio/FmReceiver.java
index b1bdb31..832cb29 100644
--- a/qcom/fmradio/FmReceiver.java
+++ b/qcom/fmradio/FmReceiver.java
@@ -259,6 +259,8 @@
 
    private static final int V4L2_CID_PRIVATE_BASE = 0x8000000;
    private static final int V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH = V4L2_CID_PRIVATE_BASE + 8;
+   private static final int V4L2_CTRL_CLASS_USER = 0x00980000;
+   private static final int V4L2_CID_PRIVATE_IRIS_GET_SPUR_TBL = (V4L2_CTRL_CLASS_USER + 0x92E);
 
 
    private static final int TAVARUA_BUF_SRCH_LIST=0;
@@ -2535,4 +2537,48 @@
    {
        return mControl.configureSpurTable(sFd);
    }
+
+   public static int getSpurConfiguration(int freq)
+   {
+       int retval;
+
+       retval = FmReceiverJNI.setControlNative(sFd, V4L2_CID_PRIVATE_IRIS_GET_SPUR_TBL, freq);
+
+        if (retval !=0)
+            Log.d(TAG, "Failed/No Spurs for " +freq);
+       return retval;
+   }
+
+   public static void getSpurTableData()
+   {
+     int freq;
+     byte no_of_spurs;
+     int rotation_value;
+     byte lsbOfLen;
+     byte filterCoe;
+     byte isEnbale;
+     byte [] buff = new byte[STD_BUF_SIZE];
+     int i = 0;
+     FmReceiverJNI.getBufferNative(sFd, buff, 13);
+
+     freq = buff[0] & 0xFF;
+     freq |= ((buff[1] & 0xFF) << 8);
+     freq |= ((buff[2] & 0xFF) << 16);
+     Log.d (TAG, "freq = " +freq);
+     no_of_spurs =  buff[3];
+     Log.d (TAG, "no_of_spurs = " + no_of_spurs);
+     for(i = 0; i < FmConfig.no_Of_Spurs_For_Entry; i++) {
+         rotation_value =  buff[(i * 4) + 4] & 0xFF;
+         rotation_value |= ((buff[(i * 4) + 5] & 0xFF) << 8);
+         rotation_value |= ((buff[(i * 4) + 6] & 0x0F) << 12);
+         Log.d (TAG, "rotation_value = " +rotation_value);
+         lsbOfLen = (byte) (((buff[(i * 4) + 6] & 0xF0) >> 4) & 0x01);
+         Log.d (TAG, "lsbOfLen = "+lsbOfLen);
+         filterCoe = (byte) (((buff[(i * 4) + 6] & 0xF0) >> 5) & 0x03);
+         Log.d (TAG, "filterCoe = " +filterCoe);
+         isEnbale = (byte) (((buff[(i * 4) + 6] & 0xF0) >> 7) & 0x01);
+         Log.d (TAG, "spur level: " +buff[(i * 4) + 7]);
+     }
+     return;
+   }
 }
diff --git a/qcom/fmradio/FmReceiverJNI.java b/qcom/fmradio/FmReceiverJNI.java
index 3c779c2..db75ccb 100644
--- a/qcom/fmradio/FmReceiverJNI.java
+++ b/qcom/fmradio/FmReceiverJNI.java
@@ -282,4 +282,12 @@
      *         {@link #FM_JNI_FAILURE}
      */
     static native int configureSpurTable(int fd);
+
+    /**
+     * native method: Configures the new spur table
+     * @param fd file descriptor of device
+     * @return {@link #FM_JNI_SUCCESS}
+     *         {@link #FM_JNI_FAILURE}
+     */
+    static native int setSpurDataNative(int fd, short  buff[], int len);
 }
diff --git a/qcom/fmradio/FmRxEventListner.java b/qcom/fmradio/FmRxEventListner.java
index 865aac7..de39d91 100644
--- a/qcom/fmradio/FmRxEventListner.java
+++ b/qcom/fmradio/FmRxEventListner.java
@@ -230,6 +230,10 @@
                                 Log.d(TAG, "got eRT event");
                                 cb.FmRxEvERTInfo();
                                 break;
+                            case 22:
+                                Log.d(TAG, "got IRIS_EVT_SPUR_TBL event");
+                                FmReceiver.getSpurTableData();
+                                break;
                             default:
                                 Log.d(TAG, "Unknown event");
                                 break;
diff --git a/qcom/fmradio/FmTransceiver.java b/qcom/fmradio/FmTransceiver.java
index 20f0544..fa2378e 100644
--- a/qcom/fmradio/FmTransceiver.java
+++ b/qcom/fmradio/FmTransceiver.java
@@ -29,6 +29,7 @@
 
 package qcom.fmradio;
 import android.util.Log;
+import java.io.File;
 
 /** <code>FmTransceiver</code> is the superclass of classes
  * <code>FmReceiver</code> and <code>FmTransmitter</code>
@@ -406,6 +407,12 @@
       if( !acquire("/dev/radio0")){
          return false;
       }
+      if (new File("/etc/fm/SpurTableFile.txt").isFile()) {
+          Log.d(TAG, "Send Spur roation table");
+          FmConfig.fmSpurConfig(sFd);
+      } else {
+          Log.d(TAG, "No existing file to do spur configuration");
+      }
       Log.d(TAG, "turning on " + device);
       mControl.fmOn(sFd, device);
 
diff --git a/qcom/fmradio/Spur.java b/qcom/fmradio/Spur.java
new file mode 100644
index 0000000..d60d4e9
--- /dev/null
+++ b/qcom/fmradio/Spur.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package qcom.fmradio;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Spur {
+
+    private int SpurFreq;
+    private byte NoOfSpursToTrack;
+    private List <SpurDetails> spurDetailsList;
+
+    Spur() {
+
+    }
+
+    Spur(int SpurFreq, byte NoOfSpursToTrack,
+         List <SpurDetails> spurDetailsList) {
+
+        this.SpurFreq = SpurFreq;
+        this.NoOfSpursToTrack = NoOfSpursToTrack;
+        this.spurDetailsList = spurDetailsList;
+    }
+
+    public int getSpurFreq() {
+        return SpurFreq;
+    }
+
+    public void setSpurFreq(int spurFreq) {
+        SpurFreq = spurFreq;
+    }
+
+    public byte getNoOfSpursToTrack() {
+        return NoOfSpursToTrack;
+    }
+
+    public void setNoOfSpursToTrack(byte noOfSpursToTrack) {
+        NoOfSpursToTrack = noOfSpursToTrack;
+    }
+
+    public List<SpurDetails> getSpurDetailsList() {
+        return spurDetailsList;
+    }
+
+    public void setSpurDetailsList(List<SpurDetails> spurDetailsList) {
+        this.spurDetailsList = spurDetailsList;
+    }
+
+    public void addSpurDetails(SpurDetails spurDetails) {
+        if (spurDetailsList == null) {
+            spurDetailsList = new ArrayList<SpurDetails>();
+        }
+        spurDetailsList.add(spurDetails);
+    }
+
+}
+
diff --git a/qcom/fmradio/SpurDetails.java b/qcom/fmradio/SpurDetails.java
new file mode 100644
index 0000000..2683b1c
--- /dev/null
+++ b/qcom/fmradio/SpurDetails.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package qcom.fmradio;
+
+import java.util.List;
+
+public class SpurDetails {
+
+    private int RotationValue;
+    private byte LsbOfIntegrationLength;
+    private byte FilterCoefficeint;
+    private byte IsEnableSpur;
+    private byte SpurLevel;
+
+
+    public int getRotationValue() {
+        return RotationValue;
+    }
+
+    public void setRotationValue(int rotationValue) {
+        RotationValue = rotationValue;
+    }
+
+    public byte getLsbOfIntegrationLength() {
+        return LsbOfIntegrationLength;
+    }
+
+    public void setLsbOfIntegrationLength(byte lsbOfIntegrationLength) {
+        LsbOfIntegrationLength = lsbOfIntegrationLength;
+    }
+
+    public byte getFilterCoefficeint() {
+        return FilterCoefficeint;
+    }
+
+    public void setFilterCoefficeint(byte filterCoefficeint) {
+        FilterCoefficeint = filterCoefficeint;
+    }
+
+    public byte getIsEnableSpur() {
+        return IsEnableSpur;
+    }
+
+    public void setIsEnableSpur(byte isEnableSpur) {
+        IsEnableSpur = isEnableSpur;
+    }
+
+    public byte getSpurLevel() {
+        return SpurLevel;
+    }
+
+    public void setSpurLevel(byte spurLevel) {
+        SpurLevel = spurLevel;
+    }
+
+    SpurDetails(int RotationValue, byte LsbOfIntegrationLength,
+                byte FilterCoefficeint, byte IsEnableSpur, byte SpurLevel) {
+
+        this.RotationValue = RotationValue;
+        this.LsbOfIntegrationLength = LsbOfIntegrationLength;
+        this.IsEnableSpur = IsEnableSpur;
+        this.SpurLevel = SpurLevel;
+    }
+
+    public SpurDetails() {
+
+    }
+
+    public SpurDetails(SpurDetails spurDetails) {
+        if (spurDetails != null) {
+            this.RotationValue = spurDetails.RotationValue;
+            this.LsbOfIntegrationLength =
+                          spurDetails.LsbOfIntegrationLength;
+            this.IsEnableSpur = spurDetails.IsEnableSpur;
+            this.SpurLevel = spurDetails.SpurLevel;
+        }
+    }
+
+}
diff --git a/qcom/fmradio/SpurFileFormatConst.java b/qcom/fmradio/SpurFileFormatConst.java
new file mode 100644
index 0000000..e9c03aa
--- /dev/null
+++ b/qcom/fmradio/SpurFileFormatConst.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package qcom.fmradio;
+
+import java.util.regex.Pattern;
+
+public final class SpurFileFormatConst {
+    public static final String SPUR_MODE = "Mode";
+    public static final String SPUR_NUM_ENTRY = "SpurNumEntry";
+    public static final String SPUR_FREQ = "SpurFreq";
+    public static final String SPUR_NO_OF = "NoOfSpursToTrack";
+    public static final String SPUR_ROTATION_VALUE = "RotationValue";
+    public static final String SPUR_LSB_LENGTH = "LsbOfIntegrationLength";
+    public static final String SPUR_FILTER_COEFF = "FilterCoefficeint";
+    public static final String SPUR_IS_ENABLE = "IsEnableSpur";
+    public static final String SPUR_LEVEL = "SpurLevel";
+    public static final char COMMENT = '#';
+    public static final char DELIMETER = '=';
+    public static final Pattern SPACE_PATTERN = Pattern.compile("\\s");
+    public static int SPUR_DETAILS_FOR_EACH_FREQ_CNT = 5;
+
+    public enum LineType {
+        EMPTY_LINE,
+        SPUR_MODE_LINE,
+        SPUR_N_ENTRY_LINE,
+        SPUR_FR_LINE,
+        SPUR_NO_OF_LINE,
+        SPUR_ROT0_LINE,
+        SPUR_LSB0_LINE,
+        SPUR_FILTER0_LINE,
+        SPUR_ENABLE0_LINE,
+        SPUR_LEVEL0_LINE,
+    }
+}
diff --git a/qcom/fmradio/SpurFileParser.java b/qcom/fmradio/SpurFileParser.java
new file mode 100644
index 0000000..d9f494e
--- /dev/null
+++ b/qcom/fmradio/SpurFileParser.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package qcom.fmradio;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.regex.Matcher;
+import android.util.Log;
+import qcom.fmradio.SpurFileFormatConst.LineType;
+
+public class SpurFileParser implements SpurFileParserInterface {
+
+    private static final String TAG = "SPUR";
+
+    private boolean parse(BufferedReader reader, SpurTable t) {
+        int entryFound = 0;
+
+        if (t == null ) {
+            return false;
+        }
+
+        if ((reader != null)) {
+            String line;
+            LineType lastLine = LineType.EMPTY_LINE;
+            int indexEqual;
+            int SpurFreq = 0;
+            byte NoOfSpursToTrack = 0;
+            int RotationValue = 0;
+            byte LsbOfIntegrationLength = 0;
+            byte FilterCoefficeint = 0;
+            byte IsEnableSpur = 0;
+            byte spurLevel = 0;
+            byte noOfSpursFreq = 0;
+            byte mode;
+            byte freqCnt = 0;
+
+            try {
+                 while(reader.ready() && (line = reader.readLine()) != null) {
+                     line = removeSpaces(line);
+                     System.out.println("line : " + line);
+                     if (lineIsComment(line)) {
+                         continue;
+                     }
+                     if ((entryFound == 2) && (freqCnt <= noOfSpursFreq)) {
+                         if ((lastLine == LineType.EMPTY_LINE) &&
+                              lineIsOfType(line, SpurFileFormatConst.SPUR_FREQ)) {
+
+                             indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                             SpurFreq = Integer.parseInt(line.substring(indexEqual + 1));
+                             lastLine = LineType.SPUR_FR_LINE;
+                             freqCnt++;
+                         } else if((lastLine == LineType.SPUR_FR_LINE) &&
+                                    lineIsOfType(line, SpurFileFormatConst.SPUR_NO_OF)) {
+
+                             indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                             NoOfSpursToTrack = Byte.parseByte(line.substring(indexEqual + 1));
+                             Spur spur = new Spur();
+                             spur.setSpurFreq(SpurFreq);
+                             spur.setNoOfSpursToTrack(NoOfSpursToTrack);
+                             for(int i = 0; i < 3; i++) {
+                                 SpurDetails spurDetails = new SpurDetails();
+                                 for(int j = 0; (reader.ready()) &&
+                                   (j < SpurFileFormatConst.SPUR_DETAILS_FOR_EACH_FREQ_CNT); j++) {
+
+                                     line = reader.readLine();
+                                     line = removeSpaces(line);
+                                     System.out.println("inside line: " + line);
+                                     if (lineIsOfType(line,
+                                            (SpurFileFormatConst.SPUR_ROTATION_VALUE + i))) {
+
+                                         indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                                         RotationValue = Integer.parseInt(
+                                                            line.substring(indexEqual + 1));
+                                         spurDetails.setRotationValue(RotationValue);
+                                     } else if(lineIsOfType(line,
+                                             SpurFileFormatConst.SPUR_LSB_LENGTH + i)) {
+
+                                         indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                                         LsbOfIntegrationLength = Byte.parseByte(
+                                                            line.substring(indexEqual + 1));
+                                         spurDetails.setLsbOfIntegrationLength(
+                                                                    LsbOfIntegrationLength);
+                                     } else if(lineIsOfType(line,
+                                             SpurFileFormatConst.SPUR_FILTER_COEFF + i)) {
+
+                                         indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                                         FilterCoefficeint = Byte.parseByte(
+                                                            line.substring(indexEqual + 1));
+                                         spurDetails.setFilterCoefficeint(FilterCoefficeint);
+                                     } else if(lineIsOfType(line,
+                                             SpurFileFormatConst.SPUR_IS_ENABLE + i)) {
+
+                                         indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                                         IsEnableSpur = Byte.parseByte(
+                                                         line.substring(indexEqual + 1));
+                                         spurDetails.setIsEnableSpur(IsEnableSpur);
+                                     } else if(lineIsOfType(line,
+                                             SpurFileFormatConst.SPUR_LEVEL + i)) {
+
+                                         indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                                         spurLevel = Byte.parseByte(line.substring(indexEqual + 1));
+                                         spurDetails.setSpurLevel(spurLevel);
+                                     }
+                                 }
+                                 spur.addSpurDetails(spurDetails);
+                             }
+                             t.InsertSpur(spur);
+                             lastLine = LineType.EMPTY_LINE;
+                         } else {
+                             return false;
+                         }
+                     } else if(entryFound == 1) {
+                         if (lineIsOfType(line, SpurFileFormatConst.SPUR_NUM_ENTRY)) {
+                             indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                             noOfSpursFreq = Byte.parseByte(line.substring(indexEqual + 1));
+                             t.SetspurNoOfFreq(noOfSpursFreq);
+                             entryFound++;
+                         } else {
+                               return false;
+                         }
+                     } else {
+                         if (lineIsOfType(line, SpurFileFormatConst.SPUR_MODE)) {
+                             indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+                             mode = Byte.parseByte(line.substring(indexEqual + 1));
+                             t.SetMode(mode);
+                             entryFound++;
+                         } else {
+                             return false;
+                         }
+                     }
+                 } // END of while
+            } catch (NumberFormatException e) {
+                 Log.d(TAG, "NumberFormatException");
+                 e.printStackTrace();
+                 return false;
+            } catch (IOException e) {
+                 Log.d(TAG, "IOException");
+                 e.printStackTrace();
+                 return false;
+            }
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    private String removeSpaces(String s) {
+        Matcher matcher = SpurFileFormatConst.SPACE_PATTERN.matcher(s);
+        String newLine = matcher.replaceAll("");
+        return newLine;
+    }
+
+    private boolean lineIsOfType(String line, String lineType) {
+        int indexEqual;
+
+        try {
+             indexEqual = line.indexOf(SpurFileFormatConst.DELIMETER);
+             if ((indexEqual >= 0) && indexEqual < line.length()) {
+                 if (line.startsWith(lineType)) {
+                     int num = Integer.parseInt(line.substring(indexEqual + 1));
+                 } else {
+                     return false;
+                 }
+             } else {
+                 return false;
+             }
+        } catch (NumberFormatException e) {
+             return false;
+        }
+        return true;
+    }
+
+    private boolean lineIsComment(String s) {
+        if ((s == null) || (s == "") || (s == " ") || s.length() == 0) {
+            return true;
+        } else if(s.charAt(0) == SpurFileFormatConst.COMMENT) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public SpurTable GetSpurTable(String fileName) {
+        BufferedReader reader = null;
+        SpurTable t = new SpurTable();
+        try {
+             reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
+             parse(reader, t);
+             reader.close();
+        } catch (IOException e) {
+             e.printStackTrace();
+        }
+        return t;
+    }
+
+}
diff --git a/qcom/fmradio/SpurFileParserInterface.java b/qcom/fmradio/SpurFileParserInterface.java
new file mode 100644
index 0000000..e151769
--- /dev/null
+++ b/qcom/fmradio/SpurFileParserInterface.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package qcom.fmradio;
+
+public interface SpurFileParserInterface {
+
+    SpurTable GetSpurTable(String fileName);
+}
diff --git a/qcom/fmradio/SpurTable.java b/qcom/fmradio/SpurTable.java
new file mode 100644
index 0000000..fd65c58
--- /dev/null
+++ b/qcom/fmradio/SpurTable.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package qcom.fmradio;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SpurTable {
+
+    private byte mode;
+    private byte spurNoOfFreq;
+    private List <Spur> spurs;
+
+    SpurTable() {
+        this.mode = -1;
+        this.spurNoOfFreq = 0;
+        this.spurs = null;
+    }
+
+    public List <Spur> GetSpurList() {
+        return spurs;
+    }
+
+    public void SetspurNoOfFreq(byte spurNoOfFreq) {
+        this.spurNoOfFreq = spurNoOfFreq;
+    }
+
+    public void SetMode(byte mode) {
+        this.mode = mode;
+    }
+
+    public void InsertSpur(Spur s) {
+        if (spurs == null) {
+            spurs = new ArrayList<Spur>();
+        }
+        spurs.add(s);
+    }
+
+    public byte GetMode() {
+        return mode;
+    }
+
+    public byte GetspurNoOfFreq() {
+        return spurNoOfFreq;
+    }
+}