Merge the latest patches from TI delivered till 6AK1.1 release

Change-Id: I2701f518ac318fa34557ff802de70893db06627b
diff --git a/LDC_3001_TouchScreen_Controller.idc b/LDC_3001_TouchScreen_Controller.idc
new file mode 100755
index 0000000..2d4c26a
--- /dev/null
+++ b/LDC_3001_TouchScreen_Controller.idc
@@ -0,0 +1,25 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Input Device Configuration File for the Atmel Maxtouch touch screen.
+#
+# These calibration values are derived from empirical measurements
+# and may not be appropriate for use with other touch screens.
+# Refer to the input device configuration documentation for more details.
+#
+
+# Basic Parameters
+touch.deviceType = touchScreen
+touch.orientationAware = 1
diff --git a/audio/Android.mk b/audio/Android.mk
index 7d6cb91..da7bcfe 100644
--- a/audio/Android.mk
+++ b/audio/Android.mk
@@ -14,6 +14,14 @@
 
 LOCAL_PATH := $(call my-dir)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := mixer_paths.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
 # build multizone audio if the OMAP_MULTIZONE_AUDIO flag is set to true
 ifeq ($(OMAP_MULTIZONE_AUDIO),true)
 include $(CLEAR_VARS)
diff --git a/audio/legacy/Android.mk b/audio/legacy/Android.mk
index c50fb5b..1e6c223 100644
--- a/audio/legacy/Android.mk
+++ b/audio/legacy/Android.mk
@@ -33,6 +33,7 @@
 
 LOCAL_C_INCLUDES += \
 	external/tinyalsa/include \
+	system/media/audio_route/include \
 	system/media/audio_utils/include \
 	system/media/audio_effects/include
 
@@ -40,6 +41,7 @@
 	liblog \
 	libcutils \
 	libtinyalsa \
+	libaudioroute \
 	libaudioutils
 
 LOCAL_MODULE_TAGS := optional
diff --git a/audio/legacy/audio_hw.c b/audio/legacy/audio_hw.c
index cef97c5..e54ee45 100644
--- a/audio/legacy/audio_hw.c
+++ b/audio/legacy/audio_hw.c
@@ -33,6 +33,7 @@
 #include <cutils/properties.h>
 
 #include <audio_utils/resampler.h>
+#include <audio_route/audio_route.h>
 #include <system/audio.h>
 #include <hardware/hardware.h>
 #include <hardware/audio.h>
@@ -43,6 +44,12 @@
 /* yet another definition of ARRAY_SIZE macro) */
 #define ARRAY_SIZE(x)           (sizeof(x)/sizeof(x[0]))
 
+/*
+ * additional space in resampler buffer allowing for extra samples to be returned
+ * by speex resampler when sample rates ratio is not an integer
+ */
+#define RESAMPLER_HEADROOM_FRAMES   10
+
 /* buffer_remix: functor for doing in-place buffer manipulations.
  *
  * NB. When remix_func is called, the memory at `buf` must be at least
@@ -55,18 +62,45 @@
     size_t out_chans;   /* number of output channels */
 };
 
+struct j6_voice_stream {
+    struct j6_audio_device *dev;
+    struct pcm *pcm_in;
+    struct pcm *pcm_out;
+    struct pcm_config in_config;
+    struct pcm_config out_config;
+    struct resampler_itfe *resampler;
+    struct resampler_buffer_provider buf_provider;
+    struct buffer_remix *remix;
+    pthread_t thread;
+    int16_t *in_buffer;
+    int16_t *out_buffer;
+    size_t in_frames;
+    size_t out_frames;
+    size_t frame_size;
+    char *name;
+};
+
+struct j6_voice {
+    struct j6_voice_stream ul;
+    struct j6_voice_stream dl;
+};
+
 struct j6_audio_device {
     struct audio_hw_device device;
     struct j6_stream_in *in;
     struct j6_stream_out *out;
-    struct mixer *mixer;
+    struct j6_voice voice;
+    struct audio_route *route;
     audio_devices_t in_device;
     audio_devices_t out_device;
     pthread_mutex_t lock;
     unsigned int card;
     unsigned int in_port;
     unsigned int out_port;
+    unsigned int bt_port;
     bool mic_mute;
+    bool in_call;
+    audio_mode_t mode;
 };
 
 struct j6_stream_in {
@@ -92,6 +126,7 @@
     struct j6_audio_device *dev;
     struct pcm_config config;
     struct pcm *pcm;
+    struct timespec last;
     pthread_mutex_t lock;
     bool standby;
     int64_t written; /* total frames written, not cleared when entering standby */
@@ -112,8 +147,8 @@
                                         AUDIO_DEVICE_OUT_DEFAULT)
 
 #define CAPTURE_SAMPLE_RATE             44100
-#define CAPTURE_PERIOD_SIZE             320
-#define CAPTURE_PERIOD_COUNT            2
+#define CAPTURE_PERIOD_SIZE             960
+#define CAPTURE_PERIOD_COUNT            4
 #define CAPTURE_BUFFER_SIZE             (CAPTURE_PERIOD_SIZE * CAPTURE_PERIOD_COUNT)
 
 #define PLAYBACK_SAMPLE_RATE            44100
@@ -121,6 +156,11 @@
 #define PLAYBACK_PERIOD_COUNT           4
 #define PLAYBACK_BUFFER_SIZE            (PLAYBACK_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT)
 
+#define BT_SAMPLE_RATE                  8000
+#define BT_PERIOD_SIZE                  160
+#define BT_PERIOD_COUNT                 4
+#define BT_BUFFER_SIZE                  (BT_PERIOD_SIZE * BT_PERIOD_COUNT)
+
 struct pcm_config pcm_config_capture = {
     .channels        = 2,
     .rate            = CAPTURE_SAMPLE_RATE,
@@ -142,148 +182,27 @@
     .avail_min       = PLAYBACK_PERIOD_SIZE,
 };
 
-/* Mixer control names */
-
-/* Capture */
-#define MIXER_PGA_CAPTURE_SWITCH        "PGA Capture Switch"
-#define MIXER_PGA_CAPTURE_VOLUME        "PGA Capture Volume"
-
-/* Capture gain (0dB, 59.5dB) step=0.5 */
-#define CAPTURE_DB_TO_VAL(x)            ((int)(2 * (float)(x)))
-
-/* Microphone specific */
-#define MIXER_LEFT_PGA_MIC3L_SWITCH     "Left PGA Mixer Mic3L Switch"
-#define MIXER_RIGHT_PGA_MIC3R_SWITCH    "Right PGA Mixer Mic3R Switch"
-
-/* Line-In specific */
-#define MIXER_LEFT_PGA_LINE1L_SWITCH    "Left PGA Mixer Line1L Switch"
-#define MIXER_RIGHT_PGA_LINE1R_SWITCH   "Right PGA Mixer Line1R Switch"
-#define MIXER_LEFT_LINE1L_MUX           "Left Line1L Mux"
-#define MIXER_RIGHT_LINE1L_MUX          "Right Line1L Mux"
-#define MIXER_LEFT_LINE1R_MUX           "Left Line1R Mux"
-#define MIXER_RIGHT_LINE1R_MUX          "Right Line1R Mux"
-#define MIXER_LINE_IN_SINGLE_ENDED      "single-ended"
-#define MIXER_LINE_IN_DIFFERENTIAL      "differential"
-
-/* Playback */
-#define MIXER_LEFT_DAC_MUX              "Left DAC Mux"
-#define MIXER_RIGHT_DAC_MUX             "Right DAC Mux"
-#define MIXER_MUX_DAC_L1                "DAC_L1"
-#define MIXER_MUX_DAC_R1                "DAC_R1"
-#define MIXER_PCM_PLAYBACK_VOLUME       "PCM Playback Volume"
-
- /* Playback gain (-63.5dB, 0dB) step=0.5dB */
-#define PLAYBACK_DB_TO_VAL(x)           ((int)(2 * ((float)(x) + 63.5)))
-
-/* Headphone specific */
-#define MIXER_HP_PLAYBACK_SWITCH        "HP Playback Switch"
-#define MIXER_LEFT_HP_DACL1_SWITCH      "Left HP Mixer DACL1 Switch"
-#define MIXER_RIGHT_HP_DACR1_SWITCH     "Right HP Mixer DACR1 Switch"
-#define HP_PLAYBACK_VOLUME              "HP DAC Playback Volume"
-#define HP_DRIVER_POWER_ON_TIME         "Output Driver Power-On time"
-#define HP_DRIVER_DELAY                 "200ms"
-
-/* Line-Out specific */
-#define MIXER_LINE_PLAYBACK_SWITCH      "Line Playback Switch"
-#define MIXER_LEFT_LINE_DACL1_SWITCH    "Left Line Mixer DACL1 Switch"
-#define MIXER_RIGHT_LINE_DACR1_SWITCH   "Right Line Mixer DACR1 Switch"
-#define LINE_PLAYBACK_VOLUME            "Line DAC Playback Volume"
-
- /* Output stage gain (-59.0dB, 0dB) step=0.5dB */
-#define OUTPUT_DB_TO_VAL(x)             ((int)(2 * ((float)(x) + 59.0)))
-
-struct route_setting {
-    char *ctl_name;
-    int intval;
-    char *strval;
+struct pcm_config pcm_config_bt_in = {
+    .channels        = 2,
+    .rate            = BT_SAMPLE_RATE,
+    .format          = PCM_FORMAT_S16_LE,
+    .period_size     = BT_PERIOD_SIZE,
+    .period_count    = BT_PERIOD_COUNT,
+    .start_threshold = 1,
+    .stop_threshold  = BT_BUFFER_SIZE,
 };
 
-#define RS_STR(ctrl, str) { .ctl_name = ctrl, .strval = str }
-#define RS_INT(ctrl, val) { .ctl_name = ctrl, .intval = val }
-#define RS_END            { .ctl_name = NULL, .strval = NULL }
-
-/* These are values that never change */
-static struct route_setting rs_defaults[] = {
-    /* Capture: Mic */
-    RS_INT(MIXER_LEFT_PGA_MIC3L_SWITCH, 1),
-    RS_INT(MIXER_RIGHT_PGA_MIC3R_SWITCH, 1),
-    RS_INT(MIXER_PGA_CAPTURE_SWITCH, 1),
-    RS_INT(MIXER_PGA_CAPTURE_VOLUME, CAPTURE_DB_TO_VAL(12)), /* 12dB */
-    RS_STR(MIXER_LEFT_LINE1L_MUX, MIXER_LINE_IN_SINGLE_ENDED),
-    RS_STR(MIXER_RIGHT_LINE1L_MUX, MIXER_LINE_IN_SINGLE_ENDED),
-    RS_STR(MIXER_LEFT_LINE1R_MUX, MIXER_LINE_IN_SINGLE_ENDED),
-    RS_STR(MIXER_RIGHT_LINE1R_MUX, MIXER_LINE_IN_SINGLE_ENDED),
-
-    /* Playback: Line-Out and Headphone */
-    RS_STR(MIXER_LEFT_DAC_MUX, MIXER_MUX_DAC_L1),
-    RS_STR(MIXER_RIGHT_DAC_MUX, MIXER_MUX_DAC_R1),
-    RS_INT(MIXER_PCM_PLAYBACK_VOLUME, PLAYBACK_DB_TO_VAL(0)), /* 0dB */
-
-    RS_INT(MIXER_LEFT_HP_DACL1_SWITCH, 1),
-    RS_INT(MIXER_RIGHT_HP_DACR1_SWITCH, 1),
-    RS_INT(MIXER_HP_PLAYBACK_SWITCH, 1),
-    RS_INT(HP_PLAYBACK_VOLUME, OUTPUT_DB_TO_VAL(0)), /* 0 dB */
-    RS_STR(HP_DRIVER_POWER_ON_TIME, HP_DRIVER_DELAY),
-
-    RS_INT(MIXER_LEFT_LINE_DACL1_SWITCH, 1),
-    RS_INT(MIXER_RIGHT_LINE_DACR1_SWITCH, 1),
-    RS_INT(MIXER_LINE_PLAYBACK_SWITCH, 1),
-    RS_INT(LINE_PLAYBACK_VOLUME, OUTPUT_DB_TO_VAL(0)), /* 0 dB */
+struct pcm_config pcm_config_bt_out = {
+    .channels        = 2,
+    .rate            = BT_SAMPLE_RATE,
+    .format          = PCM_FORMAT_S16_LE,
+    .period_size     = BT_PERIOD_SIZE,
+    .period_count    = BT_PERIOD_COUNT,
+    .start_threshold = BT_BUFFER_SIZE / 2,
+    .stop_threshold  = BT_BUFFER_SIZE,
+    .avail_min       = BT_PERIOD_SIZE,
 };
 
-/* Capture switch used for mic mute */
-static struct route_setting rs_capture[] = {
-    RS_INT(MIXER_PGA_CAPTURE_SWITCH, 1),
-    RS_END
-};
-
-/*
- * The enable flag when 0 makes the assumption that enums are disabled by
- * "Off" and integers/booleans by 0
- */
-static int set_route_by_array(struct mixer *mixer, struct route_setting *route,
-                              int enable)
-{
-    struct mixer_ctl *ctl;
-    unsigned int i, j;
-
-    ALOGV("set_route_by_array() route=%p %s", route, enable ? "enable" : "disable");
-
-    /* Go through the route array and set each value */
-    i = 0;
-    while (route[i].ctl_name) {
-        ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name);
-        if (!ctl) {
-            ALOGE("set_route_by_array() failed to get control '%s'", route[i].ctl_name);
-            return -EINVAL;
-        }
-
-        if (route[i].strval) {
-            ALOGV("set_route_by_array() control='%s' val='%s'",
-                  route[i].ctl_name, enable ? route[i].strval: "Off");
-
-            if (enable)
-                mixer_ctl_set_enum_by_string(ctl, route[i].strval);
-            else
-                mixer_ctl_set_enum_by_string(ctl, "Off");
-        } else {
-            ALOGV("set_route_by_array() control='%s' val=%d",
-                  route[i].ctl_name, route[i].intval);
-
-            /* This ensures multiple (i.e. stereo) values are set jointly */
-            for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) {
-                if (enable)
-                    mixer_ctl_set_value(ctl, j, route[i].intval);
-                else
-                    mixer_ctl_set_value(ctl, j, 0);
-            }
-        }
-        i++;
-    }
-
-    return 0;
-}
-
 static int find_supported_card(void)
 {
     char name[256] = "";
@@ -315,6 +234,8 @@
     return card;
 }
 
+static void do_out_standby(struct j6_stream_out *out);
+
 /* must be called with device lock held */
 static void select_input_device(struct j6_audio_device *adev)
 {
@@ -400,6 +321,362 @@
     return 0;
 }
 
+/*
+ * Implementation of buffer_remix::remix_func that duplicates the first
+ * channel into the rest of channels in the frame without doing any other
+ * processing. It assumes data in 16-bits, but it's not explicitly checked
+ */
+static void mono_remix(struct buffer_remix *data, void *buf, size_t frames)
+{
+    int16_t *buffer = (int16_t*)buf;
+    size_t i;
+
+    ALOGVV("mono_remix() remix=%p buf=%p frames=%u", data, buf, frames);
+
+    if (frames == 0)
+        return;
+
+    /* duplicate first channel into the rest of channels in the frame */
+    while (frames--) {
+        for (i = 1; i < data->out_chans; i++)
+            buffer[i] = buffer[0];
+        buffer += data->out_chans;
+    }
+}
+
+static int setup_mono_input_remix(struct j6_voice_stream *stream)
+{
+    ALOGV("setup_mono_input_remix() %s stream", stream->name);
+
+    struct buffer_remix *br = (struct buffer_remix *)malloc(sizeof(struct buffer_remix));
+    if (!br)
+        return -ENOMEM;
+
+    br->remix_func = mono_remix;
+    br->sample_size = sizeof(int16_t);
+    br->in_chans = stream->in_config.channels;
+    br->out_chans = stream->out_config.channels;
+    stream->remix = br;
+
+    return 0;
+}
+
+static int voice_get_next_buffer(struct resampler_buffer_provider *buffer_provider,
+                                 struct resampler_buffer* buffer)
+{
+    struct j6_voice_stream *stream;
+    int ret;
+
+    if (buffer_provider == NULL || buffer == NULL) {
+        ALOGE("voice_get_next_buffer() invalid buffer/provider");
+        return -EINVAL;
+    }
+
+    stream = (struct j6_voice_stream *)((char *)buffer_provider -
+                     offsetof(struct j6_voice_stream, buf_provider));
+
+    if (stream->pcm_in == NULL) {
+        buffer->raw = NULL;
+        buffer->frame_count = 0;
+        return -ENODEV;
+    }
+
+    if (buffer->frame_count > stream->in_frames) {
+        ALOGW("voice_get_next_buffer() %s unexpected frame count %u, "
+              "buffer was allocated for %u frames",
+              stream->name, buffer->frame_count, stream->in_frames);
+        buffer->frame_count = stream->in_frames;
+    }
+
+    ret = pcm_read(stream->pcm_in, stream->in_buffer,
+                   buffer->frame_count * stream->frame_size);
+    if (ret) {
+        ALOGE("voice_get_next_buffer() failed to read %s: %s",
+              stream->name, pcm_get_error(stream->pcm_in));
+        buffer->raw = NULL;
+        buffer->frame_count = 0;
+        return ret;
+    }
+
+    buffer->i16 = stream->in_buffer;
+
+    return ret;
+}
+
+static void voice_release_buffer(struct resampler_buffer_provider *buffer_provider,
+                                 struct resampler_buffer* buffer)
+{
+}
+
+static void *voice_thread_func(void *arg)
+{
+    struct j6_voice_stream *stream = (struct j6_voice_stream *)arg;
+    struct j6_audio_device *adev = stream->dev;
+    struct timespec now;
+    size_t frames = stream->out_frames;
+    uint32_t periods = 0;
+    uint32_t avail;
+    bool in_steady = false;
+    bool out_steady = false;
+    int ret = 0;
+
+    pcm_start(stream->pcm_in);
+
+    memset(stream->out_buffer, 0, stream->out_frames * stream->frame_size);
+
+    while (adev->in_call) {
+        if (out_steady) {
+            if (in_steady) {
+                stream->resampler->resample_from_provider(stream->resampler,
+                                                          stream->out_buffer,
+                                                          &frames);
+            } else {
+                ret = pcm_get_htimestamp(stream->pcm_in, &avail, &now);
+                if (!ret && (avail > 0)) {
+                    in_steady = true;
+                    continue;
+                }
+            }
+        } else if (++periods == stream->out_config.period_count) {
+            out_steady = true;
+        }
+
+        if (stream->remix)
+            stream->remix->remix_func(stream->remix, stream->out_buffer, frames);
+
+        ret = pcm_write(stream->pcm_out, stream->out_buffer,
+                        frames * stream->frame_size);
+        if (ret) {
+            ALOGE("voice_thread_func() failed to write %s: %s",
+                  stream->name, pcm_get_error(stream->pcm_out));
+            usleep((frames * 1000000) / stream->out_config.rate);
+        }
+    }
+
+    return (void*)ret;
+}
+
+static void voice_stream_exit(struct j6_voice_stream *stream)
+{
+    if (stream->resampler) {
+        release_resampler(stream->resampler);
+        stream->resampler = NULL;
+    }
+
+    if (stream->pcm_out) {
+        pcm_close(stream->pcm_out);
+        stream->pcm_out = NULL;
+    }
+
+    if (stream->pcm_in) {
+        pcm_close(stream->pcm_in);
+        stream->pcm_in = NULL;
+    }
+
+    if (stream->in_buffer) {
+        free(stream->in_buffer);
+        stream->in_buffer = NULL;
+        stream->in_frames = 0;
+    }
+
+    if (stream->out_buffer) {
+        free(stream->out_buffer);
+        stream->out_buffer = NULL;
+        stream->out_frames = 0;
+    }
+
+    if (stream->remix) {
+        free(stream->remix);
+        stream->remix = NULL;
+    }
+
+    if (stream->name) {
+        free(stream->name);
+        stream->name = NULL;
+    }
+}
+
+static int voice_stream_init(struct j6_voice_stream *stream,
+                             unsigned int in_port,
+                             unsigned int out_port,
+                             bool needs_mono_remix)
+{
+    struct j6_audio_device *adev = stream->dev;
+    int ret;
+
+    stream->buf_provider.get_next_buffer = voice_get_next_buffer;
+    stream->buf_provider.release_buffer = voice_release_buffer;
+    ret = create_resampler(stream->in_config.rate,
+                           stream->out_config.rate,
+                           2,
+                           RESAMPLER_QUALITY_DEFAULT,
+                           &stream->buf_provider,
+                           &stream->resampler);
+    if (ret) {
+        ALOGE("voice_stream_init() failed to create %s resampler %d", stream->name, ret);
+        return ret;
+    }
+
+    stream->pcm_in = pcm_open(adev->card, in_port, PCM_IN, &stream->in_config);
+    stream->pcm_out = pcm_open(adev->card, out_port, PCM_OUT, &stream->out_config);
+
+    if (!pcm_is_ready(stream->pcm_in) || !pcm_is_ready(stream->pcm_out)) {
+        ALOGE("voice_stream_init() failed to open pcm %s devices", stream->name);
+        voice_stream_exit(stream);
+        return -ENODEV;
+    }
+
+    stream->frame_size = pcm_frames_to_bytes(stream->pcm_in, 1);
+
+    /* out_buffer will store the resampled data */
+    stream->out_frames = stream->out_config.period_size;
+    stream->out_buffer = malloc(stream->out_frames * stream->frame_size);
+
+    /* in_buffer will store the frames recorded from the PCM device */
+    stream->in_frames = (stream->out_frames * stream->in_config.rate) / stream->out_config.rate +
+                        RESAMPLER_HEADROOM_FRAMES;
+    stream->in_buffer = malloc(stream->in_frames * stream->frame_size);
+
+    if (!stream->in_buffer || !stream->out_buffer) {
+        ALOGE("voice_stream_init() failed to allocate %s buffers", stream->name);
+        voice_stream_exit(stream);
+        return -ENOMEM;
+    }
+
+    if (needs_mono_remix) {
+        ret = setup_mono_input_remix(stream);
+        if (ret) {
+            ALOGE("voice_stream_init() failed to setup mono remix %d", ret);
+            voice_stream_exit(stream);
+            return ret;
+        }
+    } else {
+        stream->remix = NULL;
+    }
+
+    return 0;
+}
+
+static int enter_voice_call(struct j6_audio_device *adev)
+{
+    struct j6_voice *voice = &adev->voice;
+    int ret;
+
+    ALOGI("enter_voice_call() entering bluetooth voice call");
+
+    audio_route_apply_path(adev->route, "BT SCO Master");
+    audio_route_update_mixer(adev->route);
+
+    /* Let the primary output switch to a dummy sink */
+    if (adev->out)
+        do_out_standby(adev->out);
+
+    /* Uplink: Mic (44.1kHz) -> BT (8kHz) */
+    voice->ul.name = strdup("UL");
+    voice->ul.in_config = pcm_config_capture;
+    voice->ul.out_config = pcm_config_bt_out;
+    voice->ul.dev = adev;
+    ret = voice_stream_init(&voice->ul, adev->in_port, adev->bt_port, false);
+    if (ret) {
+        ALOGE("enter_voice_call() failed to init uplink %d", ret);
+        goto err_ul_init;
+    }
+
+    /* Downlink: BT (8kHz) -> HP/Spk (44.1kHz) */
+    voice->dl.name = strdup("DL");
+    voice->dl.in_config = pcm_config_bt_in;
+    voice->dl.out_config = pcm_config_playback;
+    voice->dl.dev = adev;
+    ret = voice_stream_init(&voice->dl, adev->bt_port, adev->out_port, true);
+    if (ret) {
+        ALOGE("enter_voice_call() failed to init downlink %d", ret);
+        goto err_dl_init;
+    }
+
+    adev->in_call = true;
+
+    /* Create uplink thread: Mic -> BT */
+    ret = pthread_create(&voice->ul.thread, NULL, voice_thread_func, &voice->ul);
+    if (ret) {
+        ALOGE("enter_voice_call() failed to create uplink thread %d", ret);
+        adev->in_call = false;
+        goto err_ul_thread;
+    }
+
+    /* Create downlink thread: BT -> HP/Spk */
+    ret = pthread_create(&voice->dl.thread, NULL, voice_thread_func, &voice->dl);
+    if (ret) {
+        ALOGE("enter_voice_call() failed to create downlink thread %d", ret);
+        adev->in_call = false;
+        goto err_dl_thread;
+    }
+
+    return 0;
+
+ err_dl_thread:
+    pthread_join(voice->ul.thread, NULL);
+ err_ul_thread:
+    voice_stream_exit(&voice->ul);
+ err_dl_init:
+    voice_stream_exit(&voice->dl);
+ err_ul_init:
+    audio_route_reset_path(adev->route, "BT SCO Master");
+    audio_route_update_mixer(adev->route);
+
+    return ret;
+}
+
+static void leave_voice_call(struct j6_audio_device *adev)
+{
+    struct j6_voice *voice = &adev->voice;
+    struct j6_voice_stream *ul = &voice->ul;
+    struct j6_voice_stream *dl = &voice->dl;
+    void *ret;
+
+    ALOGI("leave_voice_call() leaving bluetooth voice call");
+
+    adev->in_call = false;
+
+    /*
+     * The PCM ports used for Bluetooth are slaves and they can lose the
+     * BCLK and FSYNC while still active. That leads to blocking read() and
+     * write() calls, which is prevented by switching the clock source to
+     * an internal one and explicitly stopping both ports for the new source
+     * to take effect at kernel level
+     */
+    audio_route_reset_path(adev->route, "BT SCO Master");
+    audio_route_update_mixer(adev->route);
+    if (ul->pcm_out)
+        pcm_stop(ul->pcm_out);
+    if (dl->pcm_in)
+        pcm_stop(dl->pcm_in);
+
+    pthread_join(voice->dl.thread, &ret);
+    pthread_join(voice->ul.thread, &ret);
+
+    voice_stream_exit(&voice->dl);
+    voice_stream_exit(&voice->ul);
+
+    /* Let the primary output switch back to its ALSA PCM device */
+    if (adev->out)
+        do_out_standby(adev->out);
+}
+
+static uint32_t time_diff(struct timespec t1, struct timespec t0)
+{
+    struct timespec temp;
+
+    if ((t1.tv_nsec - t0.tv_nsec) < 0) {
+        temp.tv_sec = t1.tv_sec - t0.tv_sec-1;
+        temp.tv_nsec = 1000000000UL + t1.tv_nsec - t0.tv_nsec;
+    } else {
+        temp.tv_sec = t1.tv_sec - t0.tv_sec;
+        temp.tv_nsec = t1.tv_nsec - t0.tv_nsec;
+    }
+
+    return (temp.tv_sec * 1000000UL + temp.tv_nsec / 1000);
+}
+
 /* audio HAL functions */
 
 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
@@ -465,9 +742,13 @@
     struct j6_audio_device *adev = out->dev;
 
     if (!out->standby) {
-        ALOGI("do_out_standby() close card %u port %u", adev->card, adev->out_port);
-        pcm_close(out->pcm);
-        out->pcm = NULL;
+        if (adev->mode != AUDIO_MODE_IN_CALL) {
+            ALOGI("do_out_standby() close card %u port %u", adev->card, adev->out_port);
+            pcm_close(out->pcm);
+            out->pcm = NULL;
+        } else {
+            ALOGI("do_out_standby() close dummy card");
+        }
         out->standby = true;
     }
 }
@@ -552,10 +833,13 @@
 {
     struct j6_stream_out *out = (struct j6_stream_out *)(stream);
     struct j6_audio_device *adev = out->dev;
+    struct timespec now;
     const size_t frame_size = audio_stream_frame_size(&stream->common);
     const size_t frames = bytes / frame_size;
     uint32_t rate = out->config.rate;
     uint32_t write_usecs = frames * 1000000 / rate;
+    uint32_t diff_usecs;
+    int ret = 0;
 
     ALOGVV("out_write() stream=%p buffer=%p size=%u/%u time=%u usecs",
            out, buffer, frames, rate, write_usecs);
@@ -564,18 +848,27 @@
     pthread_mutex_lock(&out->lock);
 
     if (out->standby) {
-        select_output_device(adev);
+        if (!adev->in_call) {
+            select_output_device(adev);
 
-        ALOGI("out_write() open card %u port %u", adev->card, adev->out_port);
-        out->pcm = pcm_open(adev->card, adev->out_port, PCM_OUT | PCM_MMAP, &out->config);
-        if (!pcm_is_ready(out->pcm)) {
-            ALOGE("out_write() failed to open pcm out: %s", pcm_get_error(out->pcm));
-            pcm_close(out->pcm);
-            out->pcm = NULL;
+            ALOGI("out_write() open card %u port %u", adev->card, adev->out_port);
+            out->pcm = pcm_open(adev->card, adev->out_port, PCM_OUT, &out->config);
+            if (!pcm_is_ready(out->pcm)) {
+                ALOGE("out_write() failed to open pcm out: %s", pcm_get_error(out->pcm));
+                pcm_close(out->pcm);
+                out->pcm = NULL;
+                ret = -ENODEV;
+            }
+        } else {
+            ALOGI("out_write() open dummy port");
+            clock_gettime(CLOCK_REALTIME, &out->last);
+        }
+
+        if (ret) {
             usleep(write_usecs); /* limits the rate of error messages */
             pthread_mutex_unlock(&out->lock);
             pthread_mutex_unlock(&adev->lock);
-            return -ENODEV;
+            return ret;
         }
 
         out->standby = false;
@@ -583,10 +876,19 @@
 
     pthread_mutex_unlock(&adev->lock);
 
-    int ret = pcm_mmap_write(out->pcm, buffer, bytes);
-    if (ret) {
-        ALOGE("out_write() failed to write audio data %d", ret);
-        usleep(write_usecs); /* limits the rate of error messages */
+    if (!adev->in_call) {
+        ret = pcm_write(out->pcm, buffer, bytes);
+        if (ret) {
+            ALOGE("out_write() failed to write audio data %d", ret);
+            usleep(write_usecs); /* limits the rate of error messages */
+        }
+    } else {
+        clock_gettime(CLOCK_REALTIME, &now);
+        diff_usecs = time_diff(now, out->last);
+        if (write_usecs > diff_usecs)
+            usleep(write_usecs - diff_usecs);
+
+        clock_gettime(CLOCK_REALTIME, &out->last);
     }
 
     out->written += frames;
@@ -622,18 +924,27 @@
                                          uint64_t *frames, struct timespec *timestamp)
 {
     struct j6_stream_out *out = (struct j6_stream_out *)(stream);
+    struct j6_audio_device *adev = out->dev;
+    int64_t signed_frames = -1;
     size_t avail;
     int ret = -1;
 
     pthread_mutex_lock(&out->lock);
 
-    if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
-        int64_t signed_frames = out->written - pcm_get_buffer_size(out->pcm) + avail;
-        /* It would be unusual for this value to be negative, but check just in case ... */
-        if (signed_frames >= 0) {
-            *frames = signed_frames;
-            ret = 0;
+    if (!adev->in_call) {
+        if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
+            signed_frames = out->written - pcm_get_buffer_size(out->pcm) + avail;
         }
+    } else {
+        clock_gettime(CLOCK_REALTIME, timestamp);
+        signed_frames = out->written +
+            (time_diff(*timestamp, out->last) * out->config.rate) / 1000000;
+    }
+
+    /* It would be unusual for this value to be negative, but check just in case ... */
+    if (signed_frames >= 0) {
+        *frames = signed_frames;
+        ret = 0;
     }
 
     pthread_mutex_unlock(&out->lock);
@@ -924,6 +1235,8 @@
         ALOGE("in_read() failed to read audio data %d", ret);
         usleep(read_usecs); /* limits the rate of error messages */
         memset(buffer, 0, bytes);
+    } else if (adev->mic_mute) {
+        memset(buffer, 0, bytes);
     }
 
     pthread_mutex_unlock(&in->lock);
@@ -1060,9 +1373,37 @@
 
 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
 {
+    struct j6_audio_device *adev = (struct j6_audio_device *)dev;
+    struct j6_stream_out *out = adev->out;
+    int ret = 0;
+
     ALOGV("adev_set_mode() mode=0x%08x", mode);
 
-    return 0;
+    pthread_mutex_lock(&adev->lock);
+    pthread_mutex_lock(&out->lock);
+
+    if (adev->mode == mode) {
+        ALOGV("adev_set_mode() already in mode=0x%08x", mode);
+        goto out;
+    }
+
+    if (mode == AUDIO_MODE_IN_CALL) {
+        ret = enter_voice_call(adev);
+        if (ret) {
+            ALOGE("adev_set_mode() failed to initialize voice call %d", ret);
+            goto out;
+        }
+    } else {
+        leave_voice_call(adev);
+    }
+
+    adev->mode = mode;
+
+out:
+    pthread_mutex_unlock(&out->lock);
+    pthread_mutex_unlock(&adev->lock);
+
+    return ret;
 }
 
 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
@@ -1070,11 +1411,7 @@
     struct j6_audio_device *adev = (struct j6_audio_device *)dev;
 
     ALOGV("adev_set_mic_mute() state=%s", state ? "mute" : "unmute");
-
-    pthread_mutex_lock(&adev->lock);
-    set_route_by_array(adev->mixer, rs_capture, !state);
     adev->mic_mute = state;
-    pthread_mutex_unlock(&adev->lock);
 
     return 0;
 }
@@ -1143,6 +1480,8 @@
     in->requested_channels = popcount(config->channel_mask);
     in->hw_frame_size = in->config.channels * sizeof(int16_t);
     in->remix = NULL;
+    in->resampler = NULL;
+    in->buffer = NULL;
     adev->in = in;
 
     /* in-place stereo-to-mono remix since capture stream is stereo */
@@ -1246,8 +1585,7 @@
 
     ALOGI("adev_close()");
 
-    mixer_close(adev->mixer);
-    adev->mixer = NULL;
+    audio_route_free(adev->route);
     free(device);
 
     return 0;
@@ -1298,19 +1636,20 @@
     adev->card = find_supported_card();
     adev->in_port = 0;
     adev->out_port = 0;
+    adev->bt_port = 2;
     adev->mic_mute = false;
+    adev->in_call = false;
+    adev->mode = AUDIO_MODE_NORMAL;
 
-    adev->mixer = mixer_open(adev->card);
-    if (!adev->mixer) {
+    adev->route = audio_route_init(adev->card, NULL);
+    if (!adev->route) {
+        ALOGE("Unable to initialize audio routes");
         free(adev);
-        ALOGE("Unable to open the mixer, aborting.");
         return -EINVAL;
     }
 
     *device = &adev->device.common;
 
-    set_route_by_array(adev->mixer, rs_defaults, 1);
-
     return 0;
 }
 
diff --git a/audio/mixer_paths.xml b/audio/mixer_paths.xml
new file mode 100755
index 0000000..09949fa
--- /dev/null
+++ b/audio/mixer_paths.xml
@@ -0,0 +1,85 @@
+<mixer>
+
+<!-- Card default routes -->
+
+<!-- Capture: Mic -->
+<ctl name="Left PGA Mixer Mic3L Switch" value="1" />
+<ctl name="Right PGA Mixer Mic3R Switch" value="1" />
+<ctl name="PGA Capture Switch" value="1" />
+<ctl name="PGA Capture Volume" value="24" />
+<ctl name="Left Line1L Mux" value="single-ended" />
+<ctl name="Right Line1L Mux" value="single-ended" />
+<ctl name="Left Line1R Mux" value="single-ended" />
+<ctl name="Right Line1R Mux" value="single-ended" />
+
+<!-- Playback: Line-Out and Headphone -->
+<ctl name="Left DAC Mux" value="DAC_L1" />
+<ctl name="Right DAC Mux" value="DAC_R1" />
+<ctl name="PCM Playback Volume" value="127" />
+
+<ctl name="Left HP Mixer DACL1 Switch" value="1" />
+<ctl name="Right HP Mixer DACR1 Switch" value="1" />
+<ctl name="HP Playback Switch" value="1" />
+<ctl name="HP DAC Playback Volume" value="118" />
+<ctl name="Output Driver Power-On time" value="200ms" />
+
+<ctl name="Left Line Mixer DACL1 Switch" value="1" />
+<ctl name="Right Line Mixer DACR1 Switch" value="1" />
+<ctl name="Line Playback Switch" value="1" />
+<ctl name="Line DAC Playback Volume" value="118" />
+
+<!-- JAMR3 board, codec-A input: Line-In -->
+<ctl name="J3A Left PGA Mixer Line1L Switch" value="1" />
+<ctl name="J3A Right PGA Mixer Line1R Switch" value="1" />
+<ctl name="J3A PGA Capture Switch" value="1" />
+<ctl name="J3A PGA Capture Volume" value="0" />
+<ctl name="J3A Left Line1L Mux" value="differential" />
+<ctl name="J3A Right Line1L Mux" value="differential" />
+<ctl name="J3A Left Line1R Mux" value="differential" />
+<ctl name="J3A Right Line1R Mux" value="differential" />
+
+<!-- JAMR3 board, codec-B input: Mic -->
+<ctl name="J3B Left PGA Mixer Line1L Switch" value="1" />
+<ctl name="J3B Right PGA Mixer Line1R Switch" value="1" />
+<ctl name="J3B PGA Capture Switch" value="1" />
+<ctl name="J3B PGA Capture Volume" value="0" />
+<ctl name="J3B Left Line1L Mux" value="differential" />
+<ctl name="J3B Right Line1L Mux" value="differential" />
+<ctl name="J3B Left Line1R Mux" value="differential" />
+<ctl name="J3B Right Line1R Mux" value="differential" />
+
+<!-- JAMR3 board, codec-A output: Line-Out -->
+<ctl name="J3A Left DAC Mux" value="DAC_L1" />
+<ctl name="J3A Right DAC Mux" value="DAC_R1" />
+<ctl name="J3A Left Line Mixer DACL1 Switch" value="1" />
+<ctl name="J3A Right Line Mixer DACR1 Switch" value="1" />
+<ctl name="J3A Line DAC Playback Volume" value="118" />
+<ctl name="J3A Line Playback Switch" value="1" />
+<ctl name="J3A PCM Playback Volume" value="127" />
+
+<!-- JAMR3 board, codec-B Output: Line-Out -->
+<ctl name="J3B Left DAC Mux" value="DAC_L1" />
+<ctl name="J3B Right DAC Mux" value="DAC_R1" />
+<ctl name="J3B Left Line Mixer DACL1 Switch" value="1" />
+<ctl name="J3B Right Line Mixer DACR1 Switch" value="1" />
+<ctl name="J3B Line DAC Playback Volume" value="118" />
+<ctl name="J3B Line Playback Switch" value="1" />
+<ctl name="J3B PCM Playback Volume" value="127" />
+
+<!-- JAMR3 board, codec-C Output: Line-Out -->
+<ctl name="J3C Left DAC Mux" value="DAC_L1" />
+<ctl name="J3C Right DAC Mux" value="DAC_R1" />
+<ctl name="J3C Left Line Mixer DACL1 Switch" value="1" />
+<ctl name="J3C Right Line Mixer DACR1 Switch" value="1" />
+<ctl name="J3C Line DAC Playback Volume" value="118" />
+<ctl name="J3C Line Playback Switch" value="1" />
+<ctl name="J3C PCM Playback Volume" value="127" />
+
+<!-- Bluetooth -->
+<ctl name="Bluetooth Mode" value="Slave" />
+
+<path name="BT SCO Master">
+  <ctl name="Bluetooth Mode" value="Master" />
+</path>
+
+</mixer>
diff --git a/audio/multizone/Android.mk b/audio/multizone/Android.mk
index 061e20f..bf1c4d7 100644
--- a/audio/multizone/Android.mk
+++ b/audio/multizone/Android.mk
@@ -23,14 +23,6 @@
 include $(BUILD_PREBUILT)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := dra7evm_paths.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
 
 LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
 
diff --git a/device.mk b/device.mk
index 387798f..6857f02 100644
--- a/device.mk
+++ b/device.mk
@@ -44,6 +44,9 @@
 PRODUCT_PACKAGES := \
 	e2fsck
 
+PRODUCT_PROPERTY_OVERRIDES :=\
+        ro.serialno=2E6404F017F20121
+
 PRODUCT_PROPERTY_OVERRIDES := \
 	hwui.render_dirty_regions=false
 
@@ -81,20 +84,23 @@
 	camera_test \
 	ion_tiler_test \
 	iontest \
-	ion_ti_test2
+	ion_ti_test2 \
+	vpetest
 
 # Audio HAL modules
 PRODUCT_PACKAGES += audio.primary.jacinto6
 PRODUCT_PACKAGES += audio.hdmi.jacinto6
 # BlueDroid a2dp Audio HAL module
 PRODUCT_PACKAGES += audio.a2dp.default
+# Remote submix
+PRODUCT_PACKAGES += audio.r_submix.default
 
 # Audio policy
 PRODUCT_PACKAGES += audio_policy.jacinto6
 
 PRODUCT_PACKAGES += \
 	audio_policy.conf \
-	dra7evm_paths.xml
+	mixer_paths.xml
 
 PRODUCT_PACKAGES += \
 	tinymix \
@@ -158,11 +164,11 @@
 	ro.com.ti.omap_multizone_audio=true
 
 $(call inherit-product, frameworks/native/build/tablet-7in-hdpi-1024-dalvik-heap.mk)
-$(call inherit-product-if-exists, hardware/ti/omap4xxx/jacinto6.mk)
+$(call inherit-product-if-exists, hardware/ti/omap4xxx/Android.mk)
 #$(call inherit-product-if-exists, hardware/ti/wpan/ti-wpan-products.mk)
 $(call inherit-product-if-exists, vendor/ti/omap5sevm/device-vendor.mk)
-$(call inherit-product-if-exists, device/ti/proprietary-open/jacinto6/ti-jacinto6-vendor.mk)
+$(call inherit-product-if-exists, device/ti/proprietary-open-jacinto/jacinto6/ti-jacinto6-vendor.mk)
 #$(call inherit-product-if-exists, device/ti/common-open/s3d/s3d-products.mk)
-$(call inherit-product-if-exists, device/ti/proprietary-open/jacinto6/ducati-full_jacinto6evm.mk)
+$(call inherit-product-if-exists, device/ti/proprietary-open-jacinto/jacinto6/ducati-full_jacinto6evm.mk)
 #$(call inherit-product-if-exists, device/ti/proprietary-open/wl12xx/wlan/wl12xx-wlan-fw-products.mk)
 #$(call inherit-product-if-exists, device/ti/proprietary-open/wl12xx/wpan/wl12xx-wpan-fw-products.mk)
diff --git a/fastboot.sh b/fastboot.sh
index 1defc0b..51cb777 100755
--- a/fastboot.sh
+++ b/fastboot.sh
@@ -57,23 +57,12 @@
         exit -1;
 fi
 
-# Skip board/silicon type detection for time being
 ## poll the board to find out its configuration
 #product=`${FASTBOOT} getvar product 2>&1 | grep product | awk '{print$2}'`
-#cpu=`${FASTBOOT} getvar cpu 2>&1         | grep cpu     | awk '{print$2}'`
+cpu=`${FASTBOOT} getvar cpu 2>&1         | grep cpu     | awk '{print$2}'`
 cputype=`${FASTBOOT} getvar secure 2>&1  | grep secure  | awk '{print$2}'`
-#cpurev=`${FASTBOOT} getvar cpurev 2>&1   | grep cpurev  | awk '{print$2}'`
-#
-## Panda board can not be flashed using fastboot
-#if [ "${product}" = "PANDA" ]; then
-#        errormsg "Panda board can not be flashed using fastboot"
-#fi
-#
-## Backwards compatibility for older bootloader versions
-#if [ "${product}" = "SDP4" ]; then
-#        product="Blaze"
-#fi
-#
+
+
 # Make EMU = HS
 if [ ${cputype} = "EMU" ]; then
         cputype="HS"
@@ -84,11 +73,18 @@
 	cputype="GP"
 fi
 
+# Based on cpu, decide the dtb to flash, default fall back to J6
+if [ ${cpu} = "J6ECO" ]; then
+        environment="${PRODUCT_OUT}dra72-evm.dtb"
+else
+        environment="${PRODUCT_OUT}dra7-evm.dtb"
+fi
+
+
 # Create the filename
 bootimg="${PRODUCT_OUT}boot.img"
 xloader="${PRODUCT_OUT}${cputype}_MLO"
 uboot="${PRODUCT_OUT}u-boot.img"
-environment="${PRODUCT_OUT}dra7-evm.dtb"
 systemimg="${PRODUCT_OUT}system.img"
 userdataimg="${PRODUCT_OUT}userdata.img"
 cacheimg="${PRODUCT_OUT}cache.img"
@@ -158,6 +154,7 @@
 
 echo "Flash android partitions"
 ${FASTBOOT} flash boot		${bootimg}
+echo "Flashing device tree ${environment}"
 ${FASTBOOT} flash environment	${environment}
 ${FASTBOOT} flash recovery	${recoveryimg}
 ${FASTBOOT} flash system	${systemimg}
diff --git a/fstab.jacinto6evmboard b/fstab.jacinto6evmboard
index 87cef2f..1637a46 100644
--- a/fstab.jacinto6evmboard
+++ b/fstab.jacinto6evmboard
@@ -10,6 +10,6 @@
 /dev/block/mmcblk0p7		/recovery	emmc	defaults		defaults
 /dev/block/mmcblk0p4		/misc		emmc	defaults		defaults
 
-/devices/ocp.2/488c0000.omap_dwc3/488d0000.dwc3		/storage/usb0		vfat	defaults	voldmanaged=usb0:auto
-/devices/ocp.2/48880000.omap_dwc3/48890000.dwc3		/storage/usb1		vfat	defaults	voldmanaged=usb1:auto
-/devices/ocp.2/4809c000.mmc/mmc_host/mmc0		/storage/sdcard1	vfat	defaults	voldmanaged=sdcard1:auto
+/devices/44000000.ocp/488c0000.omap_dwc3/488d0000.dwc3		/storage/usb0		vfat	defaults	voldmanaged=usb0:auto
+/devices/44000000.ocp/48880000.omap_dwc3/48890000.dwc3		/storage/usb1		vfat	defaults	voldmanaged=usb1:auto
+/devices/44000000.ocp/4809c000.mmc/mmc_host/mmc0		/storage/sdcard1	vfat	defaults	voldmanaged=sdcard1:auto
diff --git a/init.jacinto6evmboard.rc b/init.jacinto6evmboard.rc
index 94373c3..e7026e2 100644
--- a/init.jacinto6evmboard.rc
+++ b/init.jacinto6evmboard.rc
@@ -40,6 +40,17 @@
 #for Bluetooth HID
     chmod 0666 /dev/uhid
 
+# Create GPS folders and set its permissions
+    mkdir /data/gnss
+    chown system system /data/gnss
+    mkdir /data/gnss/logs/
+    mkdir /data/gnss/nvs/
+    mkdir /data/gnss/log_MD/
+    chown system system /data/gnss/logs/
+    chown system system /data/gnss/nvs/
+    chown system system /data/gnss/log_MD/
+    insmod /system/lib/modules/gps_drv.ko
+
 on boot
     chmod 0666 /dev/pvrsrvkm
 
@@ -54,6 +65,9 @@
     insmod /system/lib/modules/wl18xx.ko board_type=hdk
     insmod /system/lib/modules/wlcore_sdio.ko
 
+    # CMEM for Radio
+    insmod /system/lib/modules/cmemk.ko phys_start=0x95400000 phys_end=0x95800000 pools=15x262144 allowOverlap=1
+
 on fs
     mkdir /factory 0775 radio radio
     mount_all /fstab.jacinto6evmboard
@@ -112,14 +126,16 @@
 
 service p2p_supplicant /system/bin/wpa_supplicant \
     -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -N \
-    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf
+    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \
+    -O/data/misc/wifi/sockets -g@android:wpa_wlan0
     class main
     socket wpa_wlan0 dgram 660 wifi wifi
     disabled
     oneshot
 
 service wpa_supplicant /system/bin/wpa_supplicant \
-    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -e/data/misc/wifi/entropy.bin
+    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -e/data/misc/wifi/entropy.bin \
+    -O/data/misc/wifi/sockets -g@android:wpa_wlan0
     class main
     socket wpa_wlan0 dgram 660 wifi wifi
     disabled
@@ -180,9 +196,27 @@
     class late_start
     disabled
 
+service fuse_sdcard1 /system/bin/sdcard -u 1023 -g 1023 -d /mnt/media_rw/sdcard1 /storage/sdcard1
+    class late_start
+    disabled
+
 service lad_dra7xx /system/bin/logwrapper /system/bin/lad_dra7xx
     class main
     user system
     group system
     disabled
     oneshot
+
+service devproxy /system/bin/devproxy
+    class main
+    disabled
+    oneshot
+    user system
+    group system
+
+service agnss_connect /system/bin/agnss_connect -p
+    class main
+    disabled
+    oneshot
+    user system
+    group system
diff --git a/media_codecs.xml b/media_codecs.xml
index 45ae8ec..50e60bc 100644
--- a/media_codecs.xml
+++ b/media_codecs.xml
@@ -40,22 +40,6 @@
         <MediaCodec name="OMX.google.h263.decoder" type="video/3gpp" />
         <MediaCodec name="OMX.google.h264.decoder" type="video/avc" />
         <MediaCodec name="OMX.google.vpx.decoder" type="video/x-vnd.on2.vp8" />
-
-        <MediaCodec name="OMX.ITTIAM.WMA.decode" >
-            <Type name="audio/wma" />
-            <Quirk name="needs-flush-before-disable" />
-            <Quirk name="requires-flush-complete-emulation" />
-        </MediaCodec>
-        <MediaCodec name="OMX.ITTIAM.WMALSL.decode" >
-            <Type name="audio/wmalsl" />
-            <Quirk name="needs-flush-before-disable" />
-            <Quirk name="requires-flush-complete-emulation" />
-        </MediaCodec>
-        <MediaCodec name="OMX.ITTIAM.WMAPRO.decode" >
-            <Type name="audio/wmapro" />
-            <Quirk name="needs-flush-before-disable" />
-            <Quirk name="requires-flush-complete-emulation" />
-        </MediaCodec>
     </Decoders>
 
     <Encoders>
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index 8267f1b..009fd1f 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -54,7 +54,6 @@
     <string-array translatable="false" name="networkAttributes">
         <item>"wifi,1,1,1,-1,true"</item>
         <item>"bluetooth,7,7,1,-1,true"</item>
-        <item>"wifi_p2p,13,1,0,-1,true"</item>
         <item>"ethernet,9,9,0,-1,true"</item>
     </string-array>
 
diff --git a/system.prop b/system.prop
index d7367bf..9262fe6 100644
--- a/system.prop
+++ b/system.prop
@@ -1,3 +1,2 @@
 wifi.interface=wlan0
-com.ti.omap_enhancement=true
 persist.hwc.primary.tv=1
diff --git a/ueventd.jacinto6evmboard.rc b/ueventd.jacinto6evmboard.rc
index e5dc751..2949544 100644
--- a/ueventd.jacinto6evmboard.rc
+++ b/ueventd.jacinto6evmboard.rc
@@ -25,6 +25,8 @@
 /dev/i2c-0                0660   system system
 /dev/i2c-1                0660   system system
 /dev/i2c-3                0660   system system
+/dev/i2c-4                0660   system system
+/dev/cmem                 0660   system system
 
 #for GCX
 /dev/gcioctl              0666   system     system
@@ -33,3 +35,6 @@
 /dev/bus/usb/002/001      0666   root       root
 /dev/bus/usb/001/002      0666   root       root
 /dev/bus/usb/001/001      0666   root       root
+
+# for GNSS
+/dev/tigps                0666   root	    root