Merge "db845c.mk: set DB845C_KERNEL_DIR to use environment when specified"
diff --git a/Android.bp b/Android.bp
index 03c85c1..c9f7e86 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,6 +14,40 @@
 
 soong_namespace {}
 
+// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS.  PLEASE
+//     CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
+//     DEPENDING ON IT IN YOUR PROJECT. ***
+package {
+    default_applicable_licenses: ["device_linaro_dragonboard_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+    name: "device_linaro_dragonboard_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-MIT",
+        "SPDX-license-identifier-OpenSSL",
+        "legacy_by_exception_only", // by exception only
+    ],
+    // large-scale-change unable to identify any license_text files
+}
+
 subdirs = [
     "qcom/pd-mapper",
     "qcom/qrtr",
diff --git a/Android.mk b/Android.mk
index 12ec650..ed787c7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -20,7 +20,7 @@
 # to only building on ARM if they include assembly. Individual makefiles
 # are responsible for having their own logic, for fine-grained control.
 
-ifneq ($(filter db845c pixel3_mainline, $(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter db845c pixel3_mainline rb5, $(TARGET_BOARD_PLATFORM)),)
 
 LOCAL_PATH := $(call my-dir)
 
diff --git a/AndroidProducts.mk b/AndroidProducts.mk
index 84cf20f..e5d63dd 100644
--- a/AndroidProducts.mk
+++ b/AndroidProducts.mk
@@ -11,8 +11,10 @@
 
 PRODUCT_MAKEFILES := \
     $(LOCAL_DIR)/db845c.mk \
+    $(LOCAL_DIR)/rb5.mk \
     $(LOCAL_DIR)/pixel3_mainline.mk
 
 COMMON_LUNCH_CHOICES := \
     db845c-userdebug \
+    rb5-userdebug \
     pixel3_mainline-userdebug
diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk
index d527c0e..b879d96 100644
--- a/BoardConfigCommon.mk
+++ b/BoardConfigCommon.mk
@@ -41,9 +41,6 @@
 TARGET_COPY_OUT_PRODUCT := product
 BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_USES_METADATA_PARTITION := true
-# Cache partition size: 64M
-BOARD_CACHEIMAGE_PARTITION_SIZE := 67108864
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 # Super partition
 TARGET_USE_DYNAMIC_PARTITIONS := true
 BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
diff --git a/METADATA b/METADATA
index d97975c..3814b8d 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,6 @@
+# *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS.  PLEASE
+#     CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
+#     DEPENDING ON IT IN YOUR PROJECT. ***
 third_party {
-  license_type: NOTICE
+  license_type: BY_EXCEPTION_ONLY
 }
diff --git a/audio/Android.mk b/audio/Android.mk
index 228ccf2..4356384 100644
--- a/audio/Android.mk
+++ b/audio/Android.mk
@@ -24,15 +24,21 @@
 
 LOCAL_HEADER_LIBRARIES += libhardware_headers
 LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_VENDOR_MODULE := true
 
-LOCAL_SRC_FILES := audio_hw.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa
+LOCAL_SRC_FILES := audio_hw.c \
+    audio_aec.c \
+    fifo_wrapper.cpp \
+    fir_filter.c
+LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioroute libaudioutils
 LOCAL_CFLAGS := -Wno-unused-parameter
 LOCAL_C_INCLUDES += \
         external/tinyalsa/include \
         external/expat/lib \
+        $(call include-path-for, audio-route) \
         system/media/audio_utils/include \
         system/media/audio_effects/include
 
diff --git a/audio/audio_aec.c b/audio/audio_aec.c
new file mode 100644
index 0000000..ab99c93
--- /dev/null
+++ b/audio/audio_aec.c
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// clang-format off
+/*
+ * Typical AEC signal flow:
+ *
+ *                          Microphone Audio
+ *                          Timestamps
+ *                        +--------------------------------------+
+ *                        |                                      |       +---------------+
+ *                        |    Microphone +---------------+      |       |               |
+ *             O|======   |    Audio      | Sample Rate   |      +------->               |
+ *    (from         .  +--+    Samples    | +             |              |               |
+ *     mic          .  +==================> Format        |==============>               |
+ *     codec)       .                     | Conversion    |              |               |   Cleaned
+ *             O|======                   | (if required) |              |   Acoustic    |   Audio
+ *                                        +---------------+              |   Echo        |   Samples
+ *                                                                       |   Canceller   |===================>
+ *                                                                       |   (AEC)       |
+ *                            Reference   +---------------+              |               |
+ *                            Audio       | Sample Rate   |              |               |
+ *                            Samples     | +             |              |               |
+ *                          +=============> Format        |==============>               |
+ *                          |             | Conversion    |              |               |
+ *                          |             | (if required) |      +------->               |
+ *                          |             +---------------+      |       |               |
+ *                          |                                    |       +---------------+
+ *                          |    +-------------------------------+
+ *                          |    |  Reference Audio
+ *                          |    |  Timestamps
+ *                          |    |
+ *                       +--+----+---------+                                                       AUDIO CAPTURE
+ *                       | Speaker         |
+ *          +------------+ Audio/Timestamp +---------------------------------------------------------------------------+
+ *                       | Buffer          |
+ *                       +--^----^---------+                                                       AUDIO PLAYBACK
+ *                          |    |
+ *                          |    |
+ *                          |    |
+ *                          |    |
+ *                |\        |    |
+ *                | +-+     |    |
+ *      (to       | | +-----C----+
+ *       speaker  | | |     |                                                                  Playback
+ *       codec)   | | <=====+================================================================+ Audio
+ *                | +-+                                                                        Samples
+ *                |/
+ *
+ */
+// clang-format on
+
+#define LOG_TAG "audio_hw_aec"
+// #define LOG_NDEBUG 0
+
+#include <audio_utils/primitives.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <malloc.h>
+#include <sys/time.h>
+#include <tinyalsa/asoundlib.h>
+#include <unistd.h>
+#include <log/log.h>
+#include "audio_aec.h"
+
+#ifdef AEC_HAL
+#include "audio_aec_process.h"
+#else
+#define aec_spk_mic_init(...) ((int)0)
+#define aec_spk_mic_reset(...) ((void)0)
+#define aec_spk_mic_process(...) ((int32_t)0)
+#define aec_spk_mic_release(...) ((void)0)
+#endif
+
+#define MAX_TIMESTAMP_DIFF_USEC 200000
+
+#define MAX_READ_WAIT_TIME_MSEC 80
+
+uint64_t timespec_to_usec(struct timespec ts) {
+    return (ts.tv_sec * 1e6L + ts.tv_nsec/1000);
+}
+
+void get_reference_audio_in_place(struct aec_t *aec, size_t frames) {
+    if (aec->num_reference_channels == aec->spk_num_channels) {
+        /* Reference count equals speaker channels, nothing to do here. */
+        return;
+    } else if (aec->num_reference_channels != 1) {
+        /* We don't have  a rule for non-mono references, show error on log */
+        ALOGE("Invalid reference count - must be 1 or match number of playback channels!");
+        return;
+    }
+    int16_t *src_Nch = &aec->spk_buf_playback_format[0];
+    int16_t *dst_1ch = &aec->spk_buf_playback_format[0];
+    int32_t num_channels = (int32_t)aec->spk_num_channels;
+    size_t frame, ch;
+    for (frame = 0; frame < frames; frame++) {
+        int32_t acc = 0;
+        for (ch = 0; ch < aec->spk_num_channels; ch++) {
+            acc += src_Nch[ch];
+        }
+        *dst_1ch++ = clamp16(acc/num_channels);
+        src_Nch += aec->spk_num_channels;
+    }
+}
+
+void print_queue_status_to_log(struct aec_t *aec, bool write_side) {
+    ssize_t q1 = fifo_available_to_read(aec->spk_fifo);
+    ssize_t q2 = fifo_available_to_read(aec->ts_fifo);
+
+    ALOGV("Queue available %s: Spk %zd (count %zd) TS %zd (count %zd)",
+        (write_side) ? "(POST-WRITE)" : "(PRE-READ)",
+        q1, q1/aec->spk_frame_size_bytes/PLAYBACK_PERIOD_SIZE,
+        q2, q2/sizeof(struct aec_info));
+}
+
+void flush_aec_fifos(struct aec_t *aec) {
+    if (aec == NULL) {
+        return;
+    }
+    if (aec->spk_fifo != NULL) {
+        ALOGV("Flushing AEC Spk FIFO...");
+        fifo_flush(aec->spk_fifo);
+    }
+    if (aec->ts_fifo != NULL) {
+        ALOGV("Flushing AEC Timestamp FIFO...");
+        fifo_flush(aec->ts_fifo);
+    }
+    /* Reset FIFO read-write offset tracker */
+    aec->read_write_diff_bytes = 0;
+}
+
+void aec_set_spk_running_no_lock(struct aec_t* aec, bool state) {
+    aec->spk_running = state;
+}
+
+bool aec_get_spk_running_no_lock(struct aec_t* aec) {
+    return aec->spk_running;
+}
+
+void destroy_aec_reference_config_no_lock(struct aec_t* aec) {
+    if (!aec->spk_initialized) {
+        return;
+    }
+    aec_set_spk_running_no_lock(aec, false);
+    fifo_release(aec->spk_fifo);
+    fifo_release(aec->ts_fifo);
+    memset(&aec->last_spk_info, 0, sizeof(struct aec_info));
+    aec->spk_initialized = false;
+}
+
+void destroy_aec_mic_config_no_lock(struct aec_t* aec) {
+    if (!aec->mic_initialized) {
+        return;
+    }
+    release_resampler(aec->spk_resampler);
+    free(aec->mic_buf);
+    free(aec->spk_buf);
+    free(aec->spk_buf_playback_format);
+    free(aec->spk_buf_resampler_out);
+    memset(&aec->last_mic_info, 0, sizeof(struct aec_info));
+    aec->mic_initialized = false;
+}
+
+struct aec_t *init_aec_interface() {
+    ALOGV("%s enter", __func__);
+    struct aec_t *aec = (struct aec_t *)calloc(1, sizeof(struct aec_t));
+    if (aec == NULL) {
+        ALOGE("Failed to allocate memory for AEC interface!");
+    } else {
+        pthread_mutex_init(&aec->lock, NULL);
+    }
+
+    ALOGV("%s exit", __func__);
+    return aec;
+}
+
+void release_aec_interface(struct aec_t *aec) {
+    ALOGV("%s enter", __func__);
+    pthread_mutex_lock(&aec->lock);
+    destroy_aec_mic_config_no_lock(aec);
+    destroy_aec_reference_config_no_lock(aec);
+    pthread_mutex_unlock(&aec->lock);
+    free(aec);
+    ALOGV("%s exit", __func__);
+}
+
+int init_aec(int sampling_rate, int num_reference_channels,
+                int num_microphone_channels, struct aec_t **aec_ptr) {
+    ALOGV("%s enter", __func__);
+    int ret = 0;
+    int aec_ret = aec_spk_mic_init(
+                    sampling_rate,
+                    num_reference_channels,
+                    num_microphone_channels);
+    if (aec_ret) {
+        ALOGE("AEC object failed to initialize!");
+        ret = -EINVAL;
+    }
+    struct aec_t *aec = init_aec_interface();
+    if (!ret) {
+        aec->num_reference_channels = num_reference_channels;
+        /* Set defaults, will be overridden by settings in init_aec_(mic|referece_config) */
+        /* Capture uses 2-ch, 32-bit frames */
+        aec->mic_sampling_rate = CAPTURE_CODEC_SAMPLING_RATE;
+        aec->mic_frame_size_bytes = CHANNEL_STEREO * sizeof(int32_t);
+        aec->mic_num_channels = CHANNEL_STEREO;
+
+        /* Playback uses 2-ch, 16-bit frames */
+        aec->spk_sampling_rate = PLAYBACK_CODEC_SAMPLING_RATE;
+        aec->spk_frame_size_bytes = CHANNEL_STEREO * sizeof(int16_t);
+        aec->spk_num_channels = CHANNEL_STEREO;
+    }
+
+    (*aec_ptr) = aec;
+    ALOGV("%s exit", __func__);
+    return ret;
+}
+
+void release_aec(struct aec_t *aec) {
+    ALOGV("%s enter", __func__);
+    if (aec == NULL) {
+        return;
+    }
+    release_aec_interface(aec);
+    aec_spk_mic_release();
+    ALOGV("%s exit", __func__);
+}
+
+int init_aec_reference_config(struct aec_t *aec, struct alsa_stream_out *out) {
+    ALOGV("%s enter", __func__);
+    if (!aec) {
+        ALOGE("AEC: No valid interface found!");
+        return -EINVAL;
+    }
+
+    int ret = 0;
+    pthread_mutex_lock(&aec->lock);
+    if (aec->spk_initialized) {
+        destroy_aec_reference_config_no_lock(aec);
+    }
+
+    aec->spk_fifo = fifo_init(
+            out->config.period_count * out->config.period_size *
+                audio_stream_out_frame_size(&out->stream),
+            false /* reader_throttles_writer */);
+    if (aec->spk_fifo == NULL) {
+        ALOGE("AEC: Speaker loopback FIFO Init failed!");
+        ret = -EINVAL;
+        goto exit;
+    }
+    aec->ts_fifo = fifo_init(
+            out->config.period_count * sizeof(struct aec_info),
+            false /* reader_throttles_writer */);
+    if (aec->ts_fifo == NULL) {
+        ALOGE("AEC: Speaker timestamp FIFO Init failed!");
+        ret = -EINVAL;
+        fifo_release(aec->spk_fifo);
+        goto exit;
+    }
+
+    aec->spk_sampling_rate = out->config.rate;
+    aec->spk_frame_size_bytes = audio_stream_out_frame_size(&out->stream);
+    aec->spk_num_channels = out->config.channels;
+    aec->spk_initialized = true;
+exit:
+    pthread_mutex_unlock(&aec->lock);
+    ALOGV("%s exit", __func__);
+    return ret;
+}
+
+void destroy_aec_reference_config(struct aec_t* aec) {
+    ALOGV("%s enter", __func__);
+    if (aec == NULL) {
+        ALOGV("%s exit", __func__);
+        return;
+    }
+    pthread_mutex_lock(&aec->lock);
+    destroy_aec_reference_config_no_lock(aec);
+    pthread_mutex_unlock(&aec->lock);
+    ALOGV("%s exit", __func__);
+}
+
+int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info) {
+    ALOGV("%s enter", __func__);
+    int ret = 0;
+    size_t bytes = info->bytes;
+
+    /* Write audio samples to FIFO */
+    ssize_t written_bytes = fifo_write(aec->spk_fifo, buffer, bytes);
+    if (written_bytes != bytes) {
+        ALOGE("Could only write %zu of %zu bytes", written_bytes, bytes);
+        ret = -ENOMEM;
+    }
+
+    /* Write timestamp to FIFO */
+    info->bytes = written_bytes;
+    ALOGV("Speaker timestamp: %ld s, %ld nsec", info->timestamp.tv_sec, info->timestamp.tv_nsec);
+    ssize_t ts_bytes = fifo_write(aec->ts_fifo, info, sizeof(struct aec_info));
+    ALOGV("Wrote TS bytes: %zu", ts_bytes);
+    print_queue_status_to_log(aec, true);
+    ALOGV("%s exit", __func__);
+    return ret;
+}
+
+void get_spk_timestamp(struct aec_t* aec, ssize_t read_bytes, uint64_t* spk_time) {
+    *spk_time = 0;
+    uint64_t spk_time_offset = 0;
+    float usec_per_byte = 1E6 / ((float)(aec->spk_frame_size_bytes * aec->spk_sampling_rate));
+    if (aec->read_write_diff_bytes < 0) {
+        /* We're still reading a previous write packet. (We only need the first sample's timestamp,
+         * so even if we straddle packets we only care about the first one)
+         * So we just use the previous timestamp, with an appropriate offset
+         * based on the number of bytes remaining to be read from that write packet. */
+        spk_time_offset = (aec->last_spk_info.bytes + aec->read_write_diff_bytes) * usec_per_byte;
+        ALOGV("Reusing previous timestamp, calculated offset (usec) %" PRIu64, spk_time_offset);
+    } else {
+        /* If read_write_diff_bytes > 0, there are no new writes, so there won't be timestamps in
+         * the FIFO, and the check below will fail. */
+        if (!fifo_available_to_read(aec->ts_fifo)) {
+            ALOGE("Timestamp error: no new timestamps!");
+            return;
+        }
+        /* We just read valid data, so if we're here, we should have a valid timestamp to use. */
+        ssize_t ts_bytes = fifo_read(aec->ts_fifo, &aec->last_spk_info, sizeof(struct aec_info));
+        ALOGV("Read TS bytes: %zd, expected %zu", ts_bytes, sizeof(struct aec_info));
+        aec->read_write_diff_bytes -= aec->last_spk_info.bytes;
+    }
+
+    *spk_time = timespec_to_usec(aec->last_spk_info.timestamp) + spk_time_offset;
+
+    aec->read_write_diff_bytes += read_bytes;
+    struct aec_info spk_info = aec->last_spk_info;
+    while (aec->read_write_diff_bytes > 0) {
+        /* If read_write_diff_bytes > 0, it means that there are more write packet timestamps
+         * in FIFO (since there we read more valid data the size of the current timestamp's
+         * packet). Keep reading timestamps from FIFO to get to the most recent one. */
+        if (!fifo_available_to_read(aec->ts_fifo)) {
+            /* There are no more timestamps, we have the most recent one. */
+            ALOGV("At the end of timestamp FIFO, breaking...");
+            break;
+        }
+        fifo_read(aec->ts_fifo, &spk_info, sizeof(struct aec_info));
+        ALOGV("Fast-forwarded timestamp by %zd bytes, remaining bytes: %zd,"
+              " new timestamp (usec) %" PRIu64,
+              spk_info.bytes, aec->read_write_diff_bytes, timespec_to_usec(spk_info.timestamp));
+        aec->read_write_diff_bytes -= spk_info.bytes;
+    }
+    aec->last_spk_info = spk_info;
+}
+
+int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info) {
+    ALOGV("%s enter", __func__);
+
+    if (!aec->spk_initialized) {
+        ALOGE("%s called with no reference initialized", __func__);
+        return -EINVAL;
+    }
+
+    size_t bytes = info->bytes;
+    const size_t frames = bytes / aec->mic_frame_size_bytes;
+    const size_t sample_rate_ratio = aec->spk_sampling_rate / aec->mic_sampling_rate;
+
+    /* Read audio samples from FIFO */
+    const size_t req_bytes = frames * sample_rate_ratio * aec->spk_frame_size_bytes;
+    ssize_t available_bytes = 0;
+    unsigned int wait_count = MAX_READ_WAIT_TIME_MSEC;
+    while (true) {
+        available_bytes = fifo_available_to_read(aec->spk_fifo);
+        if (available_bytes >= req_bytes) {
+            break;
+        } else if (available_bytes < 0) {
+            ALOGE("fifo_read returned code %zu ", available_bytes);
+            return -ENOMEM;
+        }
+
+        ALOGV("Sleeping, required bytes: %zu, available bytes: %zd", req_bytes, available_bytes);
+        usleep(1000);
+        if ((wait_count--) == 0) {
+            ALOGE("Timed out waiting for read from reference FIFO");
+            return -ETIMEDOUT;
+        }
+    }
+
+    const size_t read_bytes = fifo_read(aec->spk_fifo, aec->spk_buf_playback_format, req_bytes);
+
+    /* Get timestamp*/
+    get_spk_timestamp(aec, read_bytes, &info->timestamp_usec);
+
+    /* Get reference - could be mono, downmixed from multichannel.
+     * Reference stored at spk_buf_playback_format */
+    const size_t resampler_in_frames = frames * sample_rate_ratio;
+    get_reference_audio_in_place(aec, resampler_in_frames);
+
+    int16_t* resampler_out_buf;
+    /* Resample to mic sampling rate (16-bit resampler) */
+    if (aec->spk_resampler != NULL) {
+        size_t in_frame_count = resampler_in_frames;
+        size_t out_frame_count = frames;
+        aec->spk_resampler->resample_from_input(aec->spk_resampler, aec->spk_buf_playback_format,
+                                                &in_frame_count, aec->spk_buf_resampler_out,
+                                                &out_frame_count);
+        resampler_out_buf = aec->spk_buf_resampler_out;
+    } else {
+        if (sample_rate_ratio != 1) {
+            ALOGE("Speaker sample rate %d, mic sample rate %d but no resampler defined!",
+                  aec->spk_sampling_rate, aec->mic_sampling_rate);
+        }
+        resampler_out_buf = aec->spk_buf_playback_format;
+    }
+
+    /* Convert to 32 bit */
+    int16_t* src16 = resampler_out_buf;
+    int32_t* dst32 = buffer;
+    size_t frame, ch;
+    for (frame = 0; frame < frames; frame++) {
+        for (ch = 0; ch < aec->num_reference_channels; ch++) {
+            *dst32++ = ((int32_t)*src16++) << 16;
+        }
+    }
+
+    info->bytes = bytes;
+
+    ALOGV("%s exit", __func__);
+    return 0;
+}
+
+int init_aec_mic_config(struct aec_t *aec, struct alsa_stream_in *in) {
+    ALOGV("%s enter", __func__);
+#if DEBUG_AEC
+    remove("/data/local/traces/aec_in.pcm");
+    remove("/data/local/traces/aec_out.pcm");
+    remove("/data/local/traces/aec_ref.pcm");
+    remove("/data/local/traces/aec_timestamps.txt");
+#endif /* #if DEBUG_AEC */
+
+    if (!aec) {
+        ALOGE("AEC: No valid interface found!");
+        return -EINVAL;
+    }
+
+    int ret = 0;
+    pthread_mutex_lock(&aec->lock);
+    if (aec->mic_initialized) {
+        destroy_aec_mic_config_no_lock(aec);
+    }
+    aec->mic_sampling_rate = in->config.rate;
+    aec->mic_frame_size_bytes = audio_stream_in_frame_size(&in->stream);
+    aec->mic_num_channels = in->config.channels;
+
+    aec->mic_buf_size_bytes = in->config.period_size * audio_stream_in_frame_size(&in->stream);
+    aec->mic_buf = (int32_t *)malloc(aec->mic_buf_size_bytes);
+    if (aec->mic_buf == NULL) {
+        ret = -ENOMEM;
+        goto exit;
+    }
+    memset(aec->mic_buf, 0, aec->mic_buf_size_bytes);
+    /* Reference buffer is the same number of frames as mic,
+     * only with a different number of channels in the frame. */
+    aec->spk_buf_size_bytes = in->config.period_size * aec->spk_frame_size_bytes;
+    aec->spk_buf = (int32_t *)malloc(aec->spk_buf_size_bytes);
+    if (aec->spk_buf == NULL) {
+        ret = -ENOMEM;
+        goto exit_1;
+    }
+    memset(aec->spk_buf, 0, aec->spk_buf_size_bytes);
+
+    /* Pre-resampler buffer */
+    size_t spk_frame_out_format_bytes = aec->spk_sampling_rate / aec->mic_sampling_rate *
+                                            aec->spk_buf_size_bytes;
+    aec->spk_buf_playback_format = (int16_t *)malloc(spk_frame_out_format_bytes);
+    if (aec->spk_buf_playback_format == NULL) {
+        ret = -ENOMEM;
+        goto exit_2;
+    }
+    /* Resampler is 16-bit */
+    aec->spk_buf_resampler_out = (int16_t *)malloc(aec->spk_buf_size_bytes);
+    if (aec->spk_buf_resampler_out == NULL) {
+        ret = -ENOMEM;
+        goto exit_3;
+    }
+
+    /* Don't use resampler if it's not required */
+    if (in->config.rate == aec->spk_sampling_rate) {
+        aec->spk_resampler = NULL;
+    } else {
+        int resampler_ret = create_resampler(
+                aec->spk_sampling_rate, in->config.rate, aec->num_reference_channels,
+                RESAMPLER_QUALITY_MAX - 1, /* MAX - 1 is the real max */
+                NULL,                      /* resampler_buffer_provider */
+                &aec->spk_resampler);
+        if (resampler_ret) {
+            ALOGE("AEC: Resampler initialization failed! Error code %d", resampler_ret);
+            ret = resampler_ret;
+            goto exit_4;
+        }
+    }
+
+    flush_aec_fifos(aec);
+    aec_spk_mic_reset();
+    aec->mic_initialized = true;
+
+exit:
+    pthread_mutex_unlock(&aec->lock);
+    ALOGV("%s exit", __func__);
+    return ret;
+
+exit_4:
+    free(aec->spk_buf_resampler_out);
+exit_3:
+    free(aec->spk_buf_playback_format);
+exit_2:
+    free(aec->spk_buf);
+exit_1:
+    free(aec->mic_buf);
+    pthread_mutex_unlock(&aec->lock);
+    ALOGV("%s exit", __func__);
+    return ret;
+}
+
+void aec_set_spk_running(struct aec_t *aec, bool state) {
+    ALOGV("%s enter", __func__);
+    pthread_mutex_lock(&aec->lock);
+    aec_set_spk_running_no_lock(aec, state);
+    pthread_mutex_unlock(&aec->lock);
+    ALOGV("%s exit", __func__);
+}
+
+bool aec_get_spk_running(struct aec_t *aec) {
+    ALOGV("%s enter", __func__);
+    pthread_mutex_lock(&aec->lock);
+    bool state = aec_get_spk_running_no_lock(aec);
+    pthread_mutex_unlock(&aec->lock);
+    ALOGV("%s exit", __func__);
+    return state;
+}
+
+void destroy_aec_mic_config(struct aec_t* aec) {
+    ALOGV("%s enter", __func__);
+    if (aec == NULL) {
+        ALOGV("%s exit", __func__);
+        return;
+    }
+
+    pthread_mutex_lock(&aec->lock);
+    destroy_aec_mic_config_no_lock(aec);
+    pthread_mutex_unlock(&aec->lock);
+    ALOGV("%s exit", __func__);
+}
+
+#ifdef AEC_HAL
+int process_aec(struct aec_t *aec, void* buffer, struct aec_info *info) {
+    ALOGV("%s enter", __func__);
+    int ret = 0;
+
+    if (aec == NULL) {
+        ALOGE("AEC: Interface uninitialized! Cannot process.");
+        return -EINVAL;
+    }
+
+    if ((!aec->mic_initialized) || (!aec->spk_initialized)) {
+        ALOGE("%s called with initialization: mic: %d, spk: %d", __func__, aec->mic_initialized,
+              aec->spk_initialized);
+        return -EINVAL;
+    }
+
+    size_t bytes = info->bytes;
+
+    size_t frame_size = aec->mic_frame_size_bytes;
+    size_t in_frames = bytes / frame_size;
+
+    /* Copy raw mic samples to AEC input buffer */
+    memcpy(aec->mic_buf, buffer, bytes);
+
+    uint64_t mic_time = timespec_to_usec(info->timestamp);
+    uint64_t spk_time = 0;
+
+    /*
+     * Only run AEC if there is speaker playback.
+     * The first time speaker state changes to running, flush FIFOs, so we're not stuck
+     * processing stale reference input.
+     */
+    bool spk_running = aec_get_spk_running(aec);
+
+    if (!spk_running) {
+        /* No new playback samples, so don't run AEC.
+         * 'buffer' already contains input samples. */
+        ALOGV("Speaker not running, skipping AEC..");
+        goto exit;
+    }
+
+    if (!aec->prev_spk_running) {
+        flush_aec_fifos(aec);
+    }
+
+    /* If there's no data in FIFO, exit */
+    if (fifo_available_to_read(aec->spk_fifo) <= 0) {
+        ALOGV("Echo reference buffer empty, zeroing reference....");
+        goto exit;
+    }
+
+    print_queue_status_to_log(aec, false);
+
+    /* Get reference, with format and sample rate required by AEC */
+    struct aec_info spk_info;
+    spk_info.bytes = bytes;
+    int ref_ret = get_reference_samples(aec, aec->spk_buf, &spk_info);
+    spk_time = spk_info.timestamp_usec;
+
+    if (ref_ret) {
+        ALOGE("get_reference_samples returned code %d", ref_ret);
+        ret = -ENOMEM;
+        goto exit;
+    }
+
+    int64_t time_diff = (mic_time > spk_time) ? (mic_time - spk_time) : (spk_time - mic_time);
+    if ((spk_time == 0) || (mic_time == 0) || (time_diff > MAX_TIMESTAMP_DIFF_USEC)) {
+        ALOGV("Speaker-mic timestamps diverged, skipping AEC");
+        flush_aec_fifos(aec);
+        aec_spk_mic_reset();
+        goto exit;
+    }
+
+    ALOGV("Mic time: %"PRIu64", spk time: %"PRIu64, mic_time, spk_time);
+
+    /*
+     * AEC processing call - output stored at 'buffer'
+     */
+    int32_t aec_status = aec_spk_mic_process(
+        aec->spk_buf, spk_time,
+        aec->mic_buf, mic_time,
+        in_frames,
+        buffer);
+
+    if (!aec_status) {
+        ALOGE("AEC processing failed!");
+        ret = -EINVAL;
+    }
+
+exit:
+    aec->prev_spk_running = spk_running;
+    ALOGV("Mic time: %"PRIu64", spk time: %"PRIu64, mic_time, spk_time);
+    if (ret) {
+        /* Best we can do is copy over the raw mic signal */
+        memcpy(buffer, aec->mic_buf, bytes);
+        flush_aec_fifos(aec);
+        aec_spk_mic_reset();
+    }
+
+#if DEBUG_AEC
+    /* ref data is 32-bit at this point */
+    size_t ref_bytes = in_frames*aec->num_reference_channels*sizeof(int32_t);
+
+    FILE *fp_in = fopen("/data/local/traces/aec_in.pcm", "a+");
+    if (fp_in) {
+        fwrite((char *)aec->mic_buf, 1, bytes, fp_in);
+        fclose(fp_in);
+    } else {
+        ALOGE("AEC debug: Could not open file aec_in.pcm!");
+    }
+    FILE *fp_out = fopen("/data/local/traces/aec_out.pcm", "a+");
+    if (fp_out) {
+        fwrite((char *)buffer, 1, bytes, fp_out);
+        fclose(fp_out);
+    } else {
+        ALOGE("AEC debug: Could not open file aec_out.pcm!");
+    }
+    FILE *fp_ref = fopen("/data/local/traces/aec_ref.pcm", "a+");
+    if (fp_ref) {
+        fwrite((char *)aec->spk_buf, 1, ref_bytes, fp_ref);
+        fclose(fp_ref);
+    } else {
+        ALOGE("AEC debug: Could not open file aec_ref.pcm!");
+    }
+    FILE *fp_ts = fopen("/data/local/traces/aec_timestamps.txt", "a+");
+    if (fp_ts) {
+        fprintf(fp_ts, "%"PRIu64",%"PRIu64"\n", mic_time, spk_time);
+        fclose(fp_ts);
+    } else {
+        ALOGE("AEC debug: Could not open file aec_timestamps.txt!");
+    }
+#endif /* #if DEBUG_AEC */
+    ALOGV("%s exit", __func__);
+    return ret;
+}
+
+#endif /*#ifdef AEC_HAL*/
diff --git a/audio/audio_aec.h b/audio/audio_aec.h
new file mode 100644
index 0000000..ac7a1dd
--- /dev/null
+++ b/audio/audio_aec.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+/*
+ * Definitions and interface related to HAL implementations of Acoustic Echo Canceller (AEC).
+ *
+ * AEC cleans the microphone signal by removing from it audio data corresponding to loudspeaker
+ * playback. Note that this process can be nonlinear.
+ *
+ */
+
+#ifndef _AUDIO_AEC_H_
+#define _AUDIO_AEC_H_
+
+#include <stdint.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <hardware/audio.h>
+#include <audio_utils/resampler.h>
+#include "audio_hw.h"
+#include "fifo_wrapper.h"
+
+struct aec_t {
+    pthread_mutex_t lock;
+    size_t num_reference_channels;
+    bool mic_initialized;
+    int32_t *mic_buf;
+    size_t mic_num_channels;
+    size_t mic_buf_size_bytes;
+    size_t mic_frame_size_bytes;
+    uint32_t mic_sampling_rate;
+    struct aec_info last_mic_info;
+    bool spk_initialized;
+    int32_t *spk_buf;
+    size_t spk_num_channels;
+    size_t spk_buf_size_bytes;
+    size_t spk_frame_size_bytes;
+    uint32_t spk_sampling_rate;
+    struct aec_info last_spk_info;
+    int16_t *spk_buf_playback_format;
+    int16_t *spk_buf_resampler_out;
+    void *spk_fifo;
+    void *ts_fifo;
+    ssize_t read_write_diff_bytes;
+    struct resampler_itfe *spk_resampler;
+    bool spk_running;
+    bool prev_spk_running;
+};
+
+/* Initialize AEC object.
+ * This must be called when the audio device is opened.
+ * ALSA device mutex must be held before calling this API.
+ * Returns -EINVAL if AEC object fails to initialize, else returns 0. */
+int init_aec (int sampling_rate, int num_reference_channels,
+                int num_microphone_channels, struct aec_t **);
+
+/* Release AEC object.
+ * This must be called when the audio device is closed. */
+void release_aec(struct aec_t* aec);
+
+/* Initialize reference configuration for AEC.
+ * Must be called when a new output stream is opened.
+ * Returns -EINVAL if any processing block fails to initialize,
+ * else returns 0. */
+int init_aec_reference_config (struct aec_t *aec, struct alsa_stream_out *out);
+
+/* Clear reference configuration for AEC.
+ * Must be called when the output stream is closed. */
+void destroy_aec_reference_config (struct aec_t *aec);
+
+/* Initialize microphone configuration for AEC.
+ * Must be called when a new input stream is opened.
+ * Returns -EINVAL if any processing block fails to initialize,
+ * else returns 0. */
+int init_aec_mic_config(struct aec_t* aec, struct alsa_stream_in* in);
+
+/* Clear microphone configuration for AEC.
+ * Must be called when the input stream is closed. */
+void destroy_aec_mic_config (struct aec_t *aec);
+
+/* Used to communicate playback state (running or not) to AEC interface.
+ * This is used by process_aec() to determine if AEC processing is to be run. */
+void aec_set_spk_running (struct aec_t *aec, bool state);
+
+/* Used to communicate playback state (running or not) to the caller. */
+bool aec_get_spk_running(struct aec_t* aec);
+
+/* Write audio samples to AEC reference FIFO for use in AEC.
+ * Both audio samples and timestamps are added in FIFO fashion.
+ * Must be called after every write to PCM.
+ * Returns -ENOMEM if the write fails, else returns 0. */
+int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info);
+
+/* Get reference audio samples + timestamp, in the format expected by AEC,
+ * i.e. same sample rate and bit rate as microphone audio.
+ * Timestamp is updated in field 'timestamp_usec', and not in 'timestamp'.
+ * Returns:
+ *  -EINVAL    if the AEC object is invalid.
+ *  -ENOMEM    if the reference FIFO overflows or is corrupted.
+ *  -ETIMEDOUT if we timed out waiting for the requested number of bytes
+ *  0          otherwise */
+int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info);
+
+#ifdef AEC_HAL
+
+/* Processing function call for AEC.
+ * AEC output is updated at location pointed to by 'buffer'.
+ * This function does not run AEC when there is no playback -
+ * as communicated to this AEC interface using aec_set_spk_running().
+ * Returns -EINVAL if processing fails, else returns 0. */
+int process_aec(struct aec_t* aec, void* buffer, struct aec_info* info);
+
+#else /* #ifdef AEC_HAL */
+
+#define process_aec(...) ((int)0)
+
+#endif /* #ifdef AEC_HAL */
+
+#endif /* _AUDIO_AEC_H_ */
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 805e2cd..c0cd55d 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -13,811 +13,520 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * Copied as it is from device/google/cuttlefish/guest/hals/audio/audio_hw.c
- * and fixed couple of typos pointed out by Lint during review.
+ * Copied as it is from device/amlogic/generic/hal/audio/
  */
 
-#define LOG_TAG "audio_hw_generic"
+#define LOG_TAG "audio_hw_yukawa"
+//#define LOG_NDEBUG 0
 
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <malloc.h>
 #include <pthread.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <sys/time.h>
-#include <dlfcn.h>
-#include <fcntl.h>
 #include <unistd.h>
 
 #include <log/log.h>
-#include <cutils/list.h>
 #include <cutils/str_parms.h>
+#include <cutils/properties.h>
 
 #include <hardware/hardware.h>
 #include <system/audio.h>
 #include <hardware/audio.h>
+
+#include <audio_effects/effect_aec.h>
+#include <audio_route/audio_route.h>
+#include <audio_utils/clock.h>
+#include <audio_utils/echo_reference.h>
+#include <audio_utils/resampler.h>
+#include <hardware/audio_alsaops.h>
+#include <hardware/audio_effect.h>
+#include <sound/asound.h>
 #include <tinyalsa/asoundlib.h>
 
-#define PCM_CARD 0
-#define PCM_DEVICE 0
+#include <sys/ioctl.h>
 
+#include "audio_aec.h"
+#include "audio_hw.h"
 
-#define OUT_PERIOD_MS 15
-#define OUT_PERIOD_COUNT 4
+static int adev_get_mic_mute(const struct audio_hw_device* dev, bool* state);
+static int adev_get_microphones(const struct audio_hw_device* dev,
+                                struct audio_microphone_characteristic_t* mic_array,
+                                size_t* mic_count);
+static size_t out_get_buffer_size(const struct audio_stream* stream);
 
-#define IN_PERIOD_MS 15
-#define IN_PERIOD_COUNT 4
-
-struct generic_audio_device {
-    struct audio_hw_device device;          // Constant after init
-    pthread_mutex_t lock;
-    bool mic_mute;                          // Protected by this->lock
-    struct mixer* mixer;                    // Protected by this->lock
-    struct listnode out_streams;            // Record for output streams, protected by this->lock
-    struct listnode in_streams;             // Record for input streams, protected by this->lock
-    audio_patch_handle_t next_patch_handle; // Protected by this->lock
-};
-
-/* If not NULL, this is a pointer to the fallback module.
- * This really is the original goldfish audio device /dev/eac which we will use
- * if no alsa devices are detected.
- */
-static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state);
-static int adev_get_microphones(const audio_hw_device_t *dev,
-                                struct audio_microphone_characteristic_t *mic_array,
-                                size_t *mic_count);
-
-
-typedef struct audio_vbuffer {
-    pthread_mutex_t lock;
-    uint8_t *  data;
-    size_t     frame_size;
-    size_t     frame_count;
-    size_t     head;
-    size_t     tail;
-    size_t     live;
-} audio_vbuffer_t;
-
-static int audio_vbuffer_init (audio_vbuffer_t * audio_vbuffer, size_t frame_count,
-                              size_t frame_size) {
-    if (!audio_vbuffer) {
-        return -EINVAL;
-    }
-    audio_vbuffer->frame_size = frame_size;
-    audio_vbuffer->frame_count = frame_count;
-    size_t bytes = frame_count * frame_size;
-    audio_vbuffer->data = calloc(bytes, 1);
-    if (!audio_vbuffer->data) {
-        return -ENOMEM;
-    }
-    audio_vbuffer->head = 0;
-    audio_vbuffer->tail = 0;
-    audio_vbuffer->live = 0;
-    pthread_mutex_init (&audio_vbuffer->lock, (const pthread_mutexattr_t *) NULL);
-    return 0;
+static bool is_aec_input(const struct alsa_stream_in* in) {
+    /* If AEC is in the app, only configure based on ECHO_REFERENCE spec.
+     * If AEC is in the HAL, configure using the given mic stream. */
+    bool aec_input = true;
+#if !defined(AEC_HAL)
+    aec_input = (in->source == AUDIO_SOURCE_ECHO_REFERENCE);
+#endif
+    return aec_input;
 }
 
-static int audio_vbuffer_destroy (audio_vbuffer_t * audio_vbuffer) {
-    if (!audio_vbuffer) {
-        return -EINVAL;
-    }
-    free(audio_vbuffer->data);
-    pthread_mutex_destroy(&audio_vbuffer->lock);
-    return 0;
+static int get_audio_output_port(audio_devices_t devices) {
+    /* Only HDMI out for now #FIXME */
+    return PORT_HDMI;
 }
 
-static int audio_vbuffer_live (audio_vbuffer_t * audio_vbuffer) {
-    if (!audio_vbuffer) {
-        return -EINVAL;
+static int get_audio_card(int direction, int port) {
+    struct pcm_params* params = NULL;
+    int card = 0;
+
+    while (!params && card < 8) {
+	/* Find the first input/output device that works */
+        params = pcm_params_get(card, port, direction);
+	card++;
     }
-    pthread_mutex_lock (&audio_vbuffer->lock);
-    int live = audio_vbuffer->live;
-    pthread_mutex_unlock (&audio_vbuffer->lock);
-    return live;
+    pcm_params_free(params);
+
+    return card - 1;
 }
 
-#define MIN(a,b) (((a)<(b))?(a):(b))
-static size_t audio_vbuffer_write (audio_vbuffer_t * audio_vbuffer, const void * buffer, size_t frame_count) {
-    size_t frames_written = 0;
-    pthread_mutex_lock (&audio_vbuffer->lock);
+static void timestamp_adjust(struct timespec* ts, ssize_t frames, uint32_t sampling_rate) {
+    /* This function assumes the adjustment (in nsec) is less than the max value of long,
+     * which for 32-bit long this is 2^31 * 1e-9 seconds, slightly over 2 seconds.
+     * For 64-bit long it is  9e+9 seconds. */
+    long adj_nsec = (frames / (float) sampling_rate) * 1E9L;
+    ts->tv_nsec += adj_nsec;
+    while (ts->tv_nsec > 1E9L) {
+        ts->tv_sec++;
+        ts->tv_nsec -= 1E9L;
+    }
+    if (ts->tv_nsec < 0) {
+        ts->tv_sec--;
+        ts->tv_nsec += 1E9L;
+    }
+}
 
-    while (frame_count != 0) {
-        int frames = 0;
-        if (audio_vbuffer->live == 0 || audio_vbuffer->head > audio_vbuffer->tail) {
-            frames = MIN(frame_count, audio_vbuffer->frame_count - audio_vbuffer->head);
-        } else if (audio_vbuffer->head < audio_vbuffer->tail) {
-            frames = MIN(frame_count, audio_vbuffer->tail - (audio_vbuffer->head));
-        } else {
-            // Full
+/* Helper function to get PCM hardware timestamp.
+ * Only the field 'timestamp' of argument 'ts' is updated. */
+static int get_pcm_timestamp(struct pcm* pcm, uint32_t sample_rate, struct aec_info* info,
+                             bool isOutput) {
+    int ret = 0;
+    if (pcm_get_htimestamp(pcm, &info->available, &info->timestamp) < 0) {
+        ALOGE("Error getting PCM timestamp!");
+        info->timestamp.tv_sec = 0;
+        info->timestamp.tv_nsec = 0;
+        return -EINVAL;
+    }
+    ssize_t frames;
+    if (isOutput) {
+        frames = pcm_get_buffer_size(pcm) - info->available;
+    } else {
+        frames = -info->available; /* rewind timestamp */
+    }
+    timestamp_adjust(&info->timestamp, frames, sample_rate);
+    return ret;
+}
+
+static int read_filter_from_file(const char* filename, int16_t* filter, int max_length) {
+    FILE* fp = fopen(filename, "r");
+    if (fp == NULL) {
+        ALOGI("%s: File %s not found.", __func__, filename);
+        return 0;
+    }
+    int num_taps = 0;
+    char* line = NULL;
+    size_t len = 0;
+    while (!feof(fp)) {
+        size_t size = getline(&line, &len, fp);
+        if ((line[0] == '#') || (size < 2)) {
+            continue;
+        }
+        int n = sscanf(line, "%" SCNd16 "\n", &filter[num_taps++]);
+        if (n < 1) {
+            ALOGE("Could not find coefficient %d! Exiting...", num_taps - 1);
+            return 0;
+        }
+        ALOGV("Coeff %d : %" PRId16, num_taps, filter[num_taps - 1]);
+        if (num_taps == max_length) {
+            ALOGI("%s: max tap length %d reached.", __func__, max_length);
             break;
         }
-        memcpy(&audio_vbuffer->data[audio_vbuffer->head*audio_vbuffer->frame_size],
-               &((uint8_t*)buffer)[frames_written*audio_vbuffer->frame_size],
-               frames*audio_vbuffer->frame_size);
-        audio_vbuffer->live += frames;
-        frames_written += frames;
-        frame_count -= frames;
-        audio_vbuffer->head = (audio_vbuffer->head + frames) % audio_vbuffer->frame_count;
     }
-
-    pthread_mutex_unlock (&audio_vbuffer->lock);
-    return frames_written;
+    free(line);
+    fclose(fp);
+    return num_taps;
 }
 
-static size_t audio_vbuffer_read (audio_vbuffer_t * audio_vbuffer, void * buffer, size_t frame_count) {
-    size_t frames_read = 0;
-    pthread_mutex_lock (&audio_vbuffer->lock);
+static void out_set_eq(struct alsa_stream_out* out) {
+    out->speaker_eq = NULL;
+    int16_t* speaker_eq_coeffs = (int16_t*)calloc(SPEAKER_MAX_EQ_LENGTH, sizeof(int16_t));
+    if (speaker_eq_coeffs == NULL) {
+        ALOGE("%s: Failed to allocate speaker EQ", __func__);
+        return;
+    }
+    int num_taps = read_filter_from_file(SPEAKER_EQ_FILE, speaker_eq_coeffs, SPEAKER_MAX_EQ_LENGTH);
+    if (num_taps == 0) {
+        ALOGI("%s: Empty filter file or 0 taps set.", __func__);
+        free(speaker_eq_coeffs);
+        return;
+    }
+    out->speaker_eq = fir_init(
+            out->config.channels, FIR_SINGLE_FILTER, num_taps,
+            out_get_buffer_size(&out->stream.common) / out->config.channels / sizeof(int16_t),
+            speaker_eq_coeffs);
+    free(speaker_eq_coeffs);
+}
 
-    while (frame_count != 0) {
-        int frames = 0;
-        if (audio_vbuffer->live == audio_vbuffer->frame_count ||
-            audio_vbuffer->tail > audio_vbuffer->head) {
-            frames = MIN(frame_count, audio_vbuffer->frame_count - audio_vbuffer->tail);
-        } else if (audio_vbuffer->tail < audio_vbuffer->head) {
-            frames = MIN(frame_count, audio_vbuffer->head - audio_vbuffer->tail);
-        } else {
+/* must be called with hw device and output stream mutexes locked */
+static int start_output_stream(struct alsa_stream_out *out)
+{
+    struct alsa_audio_device *adev = out->dev;
+
+    /* default to low power: will be corrected in out_write if necessary before first write to
+     * tinyalsa.
+     */
+    out->write_threshold = PLAYBACK_PERIOD_COUNT * PLAYBACK_PERIOD_SIZE;
+    out->config.start_threshold = PLAYBACK_PERIOD_START_THRESHOLD * PLAYBACK_PERIOD_SIZE;
+    out->config.avail_min = PLAYBACK_PERIOD_SIZE;
+    out->unavailable = true;
+    unsigned int pcm_retry_count = PCM_OPEN_RETRIES;
+    int out_port = get_audio_output_port(out->devices);
+    int out_card = get_audio_card(PCM_OUT, out_port);
+
+    while (1) {
+        out->pcm = pcm_open(out_card, out_port, PCM_OUT | PCM_MONOTONIC, &out->config);
+        if ((out->pcm != NULL) && pcm_is_ready(out->pcm)) {
             break;
+        } else {
+            ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm));
+            if (out->pcm != NULL) {
+                pcm_close(out->pcm);
+                out->pcm = NULL;
+            }
+            if (--pcm_retry_count == 0) {
+                ALOGE("Failed to open pcm_out after %d tries", PCM_OPEN_RETRIES);
+                return -ENODEV;
+            }
+            usleep(PCM_OPEN_WAIT_TIME_MS * 1000);
         }
-        memcpy(&((uint8_t*)buffer)[frames_read*audio_vbuffer->frame_size],
-               &audio_vbuffer->data[audio_vbuffer->tail*audio_vbuffer->frame_size],
-               frames*audio_vbuffer->frame_size);
-        audio_vbuffer->live -= frames;
-        frames_read += frames;
-        frame_count -= frames;
-        audio_vbuffer->tail = (audio_vbuffer->tail + frames) % audio_vbuffer->frame_count;
     }
-
-    pthread_mutex_unlock (&audio_vbuffer->lock);
-    return frames_read;
+    out->unavailable = false;
+    adev->active_output = out;
+    return 0;
 }
 
-struct generic_stream_out {
-    struct audio_stream_out stream;                 // Constant after init
-    pthread_mutex_t lock;
-    struct generic_audio_device *dev;               // Constant after init
-    uint32_t num_devices;                           // Protected by this->lock
-    audio_devices_t devices[AUDIO_PATCH_PORTS_MAX]; // Protected by this->lock
-    struct audio_config req_config;                 // Constant after init
-    struct pcm_config pcm_config;                   // Constant after init
-    audio_vbuffer_t buffer;                         // Constant after init
-
-    // Time & Position Keeping
-    bool standby;                      // Protected by this->lock
-    uint64_t underrun_position;        // Protected by this->lock
-    struct timespec underrun_time;     // Protected by this->lock
-    uint64_t last_write_time_us;       // Protected by this->lock
-    uint64_t frames_total_buffered;    // Protected by this->lock
-    uint64_t frames_written;           // Protected by this->lock
-    uint64_t frames_rendered;          // Protected by this->lock
-
-    // Worker
-    pthread_t worker_thread;          // Constant after init
-    pthread_cond_t worker_wake;       // Protected by this->lock
-    bool worker_standby;              // Protected by this->lock
-    bool worker_exit;                 // Protected by this->lock
-
-    audio_io_handle_t handle;          // Constant after init
-    audio_patch_handle_t patch_handle; // Protected by this->dev->lock
-
-    struct listnode stream_node;       // Protected by this->dev->lock
-};
-
-struct generic_stream_in {
-    struct audio_stream_in stream;    // Constant after init
-    pthread_mutex_t lock;
-    struct generic_audio_device *dev; // Constant after init
-    audio_devices_t device;           // Protected by this->lock
-    struct audio_config req_config;   // Constant after init
-    struct pcm *pcm;                  // Protected by this->lock
-    struct pcm_config pcm_config;     // Constant after init
-    int16_t *stereo_to_mono_buf;      // Protected by this->lock
-    size_t stereo_to_mono_buf_size;   // Protected by this->lock
-    audio_vbuffer_t buffer;           // Protected by this->lock
-
-    // Time & Position Keeping
-    bool standby;                     // Protected by this->lock
-    int64_t standby_position;         // Protected by this->lock
-    struct timespec standby_exit_time;// Protected by this->lock
-    int64_t standby_frames_read;      // Protected by this->lock
-
-    // Worker
-    pthread_t worker_thread;          // Constant after init
-    pthread_cond_t worker_wake;       // Protected by this->lock
-    bool worker_standby;              // Protected by this->lock
-    bool worker_exit;                 // Protected by this->lock
-
-    audio_io_handle_t handle;          // Constant after init
-    audio_patch_handle_t patch_handle; // Protected by this->dev->lock
-
-    struct listnode stream_node;       // Protected by this->dev->lock
-};
-
-static struct pcm_config pcm_config_out = {
-    .channels = 2,
-    .rate = 0,
-    .period_size = 0,
-    .period_count = OUT_PERIOD_COUNT,
-    .format = PCM_FORMAT_S16_LE,
-    .start_threshold = 0,
-};
-
-static struct pcm_config pcm_config_in = {
-    .channels = 2,
-    .rate = 0,
-    .period_size = 0,
-    .period_count = IN_PERIOD_COUNT,
-    .format = PCM_FORMAT_S16_LE,
-    .start_threshold = 0,
-    .stop_threshold = INT_MAX,
-};
-
-static pthread_mutex_t adev_init_lock = PTHREAD_MUTEX_INITIALIZER;
-static unsigned int audio_device_ref_count = 0;
-
 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    return out->req_config.sample_rate;
+    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
+    return out->config.rate;
 }
 
 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
 {
+    ALOGV("out_set_sample_rate: %d", 0);
     return -ENOSYS;
 }
 
 static size_t out_get_buffer_size(const struct audio_stream *stream)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    int size = out->pcm_config.period_size *
-                audio_stream_out_frame_size(&out->stream);
+    ALOGV("out_get_buffer_size: %d", 4096);
 
-    return size;
+    /* return the closest majoring multiple of 16 frames, as
+     * audioflinger expects audio buffers to be a multiple of 16 frames */
+    size_t size = PLAYBACK_PERIOD_SIZE;
+    size = ((size + 15) / 16) * 16;
+    return size * audio_stream_out_frame_size((struct audio_stream_out *)stream);
 }
 
 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    return out->req_config.channel_mask;
+    ALOGV("out_get_channels");
+    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
+    return audio_channel_out_mask_from_count(out->config.channels);
 }
 
 static audio_format_t out_get_format(const struct audio_stream *stream)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-
-    return out->req_config.format;
+    ALOGV("out_get_format");
+    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
+    return audio_format_from_pcm_format(out->config.format);
 }
 
 static int out_set_format(struct audio_stream *stream, audio_format_t format)
 {
+    ALOGV("out_set_format: %d",format);
     return -ENOSYS;
 }
 
+static int do_output_standby(struct alsa_stream_out *out)
+{
+    struct alsa_audio_device *adev = out->dev;
+
+    fir_reset(out->speaker_eq);
+
+    if (!out->standby) {
+        pcm_close(out->pcm);
+        out->pcm = NULL;
+        adev->active_output = NULL;
+        out->standby = 1;
+    }
+    aec_set_spk_running(adev->aec, false);
+    return 0;
+}
+
+static int out_standby(struct audio_stream *stream)
+{
+    ALOGV("out_standby");
+    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
+    int status;
+
+    pthread_mutex_lock(&out->dev->lock);
+    pthread_mutex_lock(&out->lock);
+    status = do_output_standby(out);
+    pthread_mutex_unlock(&out->lock);
+    pthread_mutex_unlock(&out->dev->lock);
+    return status;
+}
+
 static int out_dump(const struct audio_stream *stream, int fd)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    pthread_mutex_lock(&out->lock);
-    dprintf(fd, "\tout_dump:\n"
-                "\t\tsample rate: %u\n"
-                "\t\tbuffer size: %zu\n"
-                "\t\tchannel mask: %08x\n"
-                "\t\tformat: %d\n"
-                "\t\tdevice(s): ",
-                out_get_sample_rate(stream),
-                out_get_buffer_size(stream),
-                out_get_channels(stream),
-                out_get_format(stream));
-    if (out->num_devices == 0) {
-        dprintf(fd, "%08x\n", AUDIO_DEVICE_NONE);
-    } else {
-        for (uint32_t i = 0; i < out->num_devices; i++) {
-            if (i != 0) {
-                dprintf(fd, ", ");
-            }
-            dprintf(fd, "%08x", out->devices[i]);
-        }
-        dprintf(fd, "\n");
-    }
-    dprintf(fd, "\t\taudio dev: %p\n\n", out->dev);
-    pthread_mutex_unlock(&out->lock);
+    ALOGV("out_dump");
     return 0;
 }
 
 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
 {
+    ALOGV("out_set_parameters");
+    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
+    struct alsa_audio_device *adev = out->dev;
     struct str_parms *parms;
     char value[32];
-    int success;
-    int ret = -EINVAL;
+    int ret, val = 0;
 
-    if (kvpairs == NULL || kvpairs[0] == 0) {
-        return 0;
-    }
     parms = str_parms_create_str(kvpairs);
-    success = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
-            value, sizeof(value));
-    // As the hal version is 3.0, it must not use set parameters API to set audio devices.
-    // Instead, it should use create_audio_patch API.
-    assert(("Must not use set parameters API to set audio devices", success < 0));
 
-    if (str_parms_has_key(parms, AUDIO_PARAMETER_STREAM_FORMAT)) {
-        // match the return value of out_set_format
-        ret = -ENOSYS;
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
+    if (ret >= 0) {
+        val = atoi(value);
+        pthread_mutex_lock(&adev->lock);
+        pthread_mutex_lock(&out->lock);
+        if (((out->devices & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) {
+            out->devices &= ~AUDIO_DEVICE_OUT_ALL;
+            out->devices |= val;
+        }
+        pthread_mutex_unlock(&out->lock);
+        pthread_mutex_unlock(&adev->lock);
     }
 
     str_parms_destroy(parms);
-
-    if (ret == -EINVAL) {
-        ALOGW("%s(), unsupported parameter %s", __func__, kvpairs);
-        // There is not any key supported for set_parameters API.
-        // Return error when there is non-null value passed in.
-    }
-    return ret;
+    return 0;
 }
 
 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    struct str_parms *query = str_parms_create_str(keys);
-    char *str = NULL;
-    char value[256];
-    struct str_parms *reply = str_parms_create();
-    int ret;
-    bool get = false;
-
-    ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
-    if (ret >= 0) {
-        pthread_mutex_lock(&out->lock);
-        audio_devices_t device = AUDIO_DEVICE_NONE;
-        for (uint32_t i = 0; i < out->num_devices; i++) {
-            device |= out->devices[i];
-        }
-        str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, device);
-        pthread_mutex_unlock(&out->lock);
-        get = true;
-    }
-
-    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
-        value[0] = 0;
-        strcat(value, "AUDIO_FORMAT_PCM_16_BIT");
-        str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_FORMATS, value);
-        get = true;
-    }
-
-    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_FORMAT)) {
-        value[0] = 0;
-        strcat(value, "AUDIO_FORMAT_PCM_16_BIT");
-        str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_FORMAT, value);
-        get = true;
-    }
-
-    if (get) {
-        str = str_parms_to_str(reply);
-    }
-    else {
-        ALOGD("%s Unsupported parameter: %s", __FUNCTION__, keys);
-    }
-
-    str_parms_destroy(query);
-    str_parms_destroy(reply);
-    return str;
+    ALOGV("out_get_parameters");
+    return strdup("");
 }
 
 static uint32_t out_get_latency(const struct audio_stream_out *stream)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    return (out->pcm_config.period_size * 1000) / out->pcm_config.rate;
+    ALOGV("out_get_latency");
+    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
+    return (PLAYBACK_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT * 1000) / out->config.rate;
 }
 
 static int out_set_volume(struct audio_stream_out *stream, float left,
-                          float right)
+        float right)
 {
+    ALOGV("out_set_volume: Left:%f Right:%f", left, right);
     return -ENOSYS;
 }
 
-static void *out_write_worker(void * args)
+static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
+        size_t bytes)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)args;
-    struct pcm *pcm = NULL;
-    uint8_t *buffer = NULL;
-    int buffer_frames;
-    int buffer_size;
-    bool restart = false;
-    bool shutdown = false;
-    while (true) {
-        pthread_mutex_lock(&out->lock);
-        while (out->worker_standby || restart) {
-            restart = false;
-            if (pcm) {
-                pcm_close(pcm); // Frees pcm
-                pcm = NULL;
-                free(buffer);
-                buffer=NULL;
-            }
-            if (out->worker_exit) {
-                break;
-            }
-            pthread_cond_wait(&out->worker_wake, &out->lock);
-        }
+    int ret;
+    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
+    struct alsa_audio_device *adev = out->dev;
+    size_t frame_size = audio_stream_out_frame_size(stream);
+    size_t out_frames = bytes / frame_size;
 
-        if (out->worker_exit) {
-            if (!out->worker_standby) {
-                ALOGE("Out worker not in standby before exiting");
-            }
-            shutdown = true;
-        }
+    ALOGV("%s: devices: %d, bytes %zu", __func__, out->devices, bytes);
 
-        while (!shutdown && audio_vbuffer_live(&out->buffer) == 0) {
-            pthread_cond_wait(&out->worker_wake, &out->lock);
-        }
-
-        if (shutdown) {
-            pthread_mutex_unlock(&out->lock);
-            break;
-        }
-
-        if (!pcm) {
-            pcm = pcm_open(PCM_CARD, PCM_DEVICE,
-                          PCM_OUT | PCM_MONOTONIC, &out->pcm_config);
-            if (!pcm_is_ready(pcm)) {
-                ALOGE("pcm_open(out) failed: %s: channels %d format %d rate %d",
-                  pcm_get_error(pcm),
-                  out->pcm_config.channels,
-                  out->pcm_config.format,
-                  out->pcm_config.rate
-                   );
-                pthread_mutex_unlock(&out->lock);
-                break;
-            }
-            buffer_frames = out->pcm_config.period_size;
-            buffer_size = pcm_frames_to_bytes(pcm, buffer_frames);
-            buffer = malloc(buffer_size);
-            if (!buffer) {
-                ALOGE("could not allocate write buffer");
-                pthread_mutex_unlock(&out->lock);
-                break;
-            }
-        }
-        int frames = audio_vbuffer_read(&out->buffer, buffer, buffer_frames);
-        pthread_mutex_unlock(&out->lock);
-        int ret = pcm_write(pcm, buffer, pcm_frames_to_bytes(pcm, frames));
-        if (ret != 0) {
-            ALOGE("pcm_write failed %s", pcm_get_error(pcm));
-            restart = true;
-        }
-    }
-    if (buffer) {
-        free(buffer);
-    }
-
-    return NULL;
-}
-
-// Call with in->lock held
-static void get_current_output_position(struct generic_stream_out *out,
-                                       uint64_t * position,
-                                       struct timespec * timestamp) {
-    struct timespec curtime = { .tv_sec = 0, .tv_nsec = 0 };
-    clock_gettime(CLOCK_MONOTONIC, &curtime);
-    const int64_t now_us = (curtime.tv_sec * 1000000000LL + curtime.tv_nsec) / 1000;
-    if (timestamp) {
-        *timestamp = curtime;
-    }
-    int64_t position_since_underrun;
-    if (out->standby) {
-        position_since_underrun = 0;
-    } else {
-        const int64_t first_us = (out->underrun_time.tv_sec * 1000000000LL +
-                                  out->underrun_time.tv_nsec) / 1000;
-        position_since_underrun = (now_us - first_us) *
-                out_get_sample_rate(&out->stream.common) /
-                1000000;
-        if (position_since_underrun < 0) {
-            position_since_underrun = 0;
-        }
-    }
-    *position = out->underrun_position + position_since_underrun;
-
-    // The device will reuse the same output stream leading to periods of
-    // underrun.
-    if (*position > out->frames_written) {
-        ALOGW("Not supplying enough data to HAL, expected position %" PRIu64 " , only wrote "
-              "%" PRIu64,
-              *position, out->frames_written);
-
-        *position = out->frames_written;
-        out->underrun_position = *position;
-        out->underrun_time = curtime;
-        out->frames_total_buffered = 0;
-    }
-}
-
-
-static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
-                         size_t bytes)
-{
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    const size_t frames =  bytes / audio_stream_out_frame_size(stream);
-
+    /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
+     * on the output stream mutex - e.g. executing select_mode() while holding the hw device
+     * mutex
+     */
+    pthread_mutex_lock(&adev->lock);
     pthread_mutex_lock(&out->lock);
-
-    if (out->worker_standby) {
-        out->worker_standby = false;
-    }
-
-    uint64_t current_position;
-    struct timespec current_time;
-
-    get_current_output_position(out, &current_position, &current_time);
-    const uint64_t now_us = (current_time.tv_sec * 1000000000LL +
-                             current_time.tv_nsec) / 1000;
     if (out->standby) {
-        out->standby = false;
-        out->underrun_time = current_time;
-        out->frames_rendered = 0;
-        out->frames_total_buffered = 0;
+        ret = start_output_stream(out);
+        if (ret != 0) {
+            pthread_mutex_unlock(&adev->lock);
+            goto exit;
+        }
+        out->standby = 0;
+        aec_set_spk_running(adev->aec, true);
     }
 
-    size_t frames_written = audio_vbuffer_write(&out->buffer, buffer, frames);
-    pthread_cond_signal(&out->worker_wake);
+    pthread_mutex_unlock(&adev->lock);
 
-    /* Implementation just consumes bytes if we start getting backed up */
-    out->frames_written += frames;
-    out->frames_rendered += frames;
-    out->frames_total_buffered += frames;
-
-    // We simulate the audio device blocking when it's write buffers become
-    // full.
-
-    // At the beginning or after an underrun, try to fill up the vbuffer.
-    // This will be throttled by the PlaybackThread
-    int frames_sleep = out->frames_total_buffered < out->buffer.frame_count ? 0 : frames;
-
-    uint64_t sleep_time_us = frames_sleep * 1000000LL /
-                            out_get_sample_rate(&stream->common);
-
-    // If the write calls are delayed, subtract time off of the sleep to
-    // compensate
-    uint64_t time_since_last_write_us = now_us - out->last_write_time_us;
-    if (time_since_last_write_us < sleep_time_us) {
-        sleep_time_us -= time_since_last_write_us;
-    } else {
-        sleep_time_us = 0;
+    if (out->speaker_eq != NULL) {
+        fir_process_interleaved(out->speaker_eq, (int16_t*)buffer, (int16_t*)buffer, out_frames);
     }
-    out->last_write_time_us = now_us + sleep_time_us;
 
+    ret = pcm_write(out->pcm, buffer, out_frames * frame_size);
+    if (ret == 0) {
+        out->frames_written += out_frames;
+
+        struct aec_info info;
+        get_pcm_timestamp(out->pcm, out->config.rate, &info, true /*isOutput*/);
+        out->timestamp = info.timestamp;
+        info.bytes = out_frames * frame_size;
+        int aec_ret = write_to_reference_fifo(adev->aec, (void *)buffer, &info);
+        if (aec_ret) {
+            ALOGE("AEC: Write to speaker loopback FIFO failed!");
+        }
+    }
+
+exit:
     pthread_mutex_unlock(&out->lock);
 
-    if (sleep_time_us > 0) {
-        usleep(sleep_time_us);
+    if (ret != 0) {
+        usleep((int64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
+                out_get_sample_rate(&stream->common));
     }
 
-    if (frames_written < frames) {
-        ALOGW("Hardware backing HAL too slow, could only write %zu of %zu frames", frames_written, frames);
-    }
-
-    /* Always consume all bytes */
     return bytes;
 }
 
+static int out_get_render_position(const struct audio_stream_out *stream,
+        uint32_t *dsp_frames)
+{
+    ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
+    return -ENOSYS;
+}
+
 static int out_get_presentation_position(const struct audio_stream_out *stream,
                                    uint64_t *frames, struct timespec *timestamp)
-
 {
     if (stream == NULL || frames == NULL || timestamp == NULL) {
         return -EINVAL;
     }
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
+    struct alsa_stream_out* out = (struct alsa_stream_out*)stream;
 
-    pthread_mutex_lock(&out->lock);
-    get_current_output_position(out, frames, timestamp);
-    pthread_mutex_unlock(&out->lock);
+    *frames = out->frames_written;
+    *timestamp = out->timestamp;
+    ALOGV("%s: frames: %" PRIu64 ", timestamp (nsec): %" PRIu64, __func__, *frames,
+          audio_utils_ns_from_timespec(timestamp));
 
     return 0;
 }
 
-static int out_get_render_position(const struct audio_stream_out *stream,
-                                   uint32_t *dsp_frames)
-{
-    if (stream == NULL || dsp_frames == NULL) {
-        return -EINVAL;
-    }
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    pthread_mutex_lock(&out->lock);
-    *dsp_frames = out->frames_rendered;
-    pthread_mutex_unlock(&out->lock);
-    return 0;
-}
-
-// Must be called with out->lock held
-static void do_out_standby(struct generic_stream_out *out)
-{
-    int frames_sleep = 0;
-    uint64_t sleep_time_us = 0;
-    if (out->standby) {
-        return;
-    }
-    while (true) {
-        get_current_output_position(out, &out->underrun_position, NULL);
-        frames_sleep = out->frames_written - out->underrun_position;
-
-        if (frames_sleep == 0) {
-            break;
-        }
-
-        sleep_time_us = frames_sleep * 1000000LL /
-                        out_get_sample_rate(&out->stream.common);
-
-        pthread_mutex_unlock(&out->lock);
-        usleep(sleep_time_us);
-        pthread_mutex_lock(&out->lock);
-    }
-    out->worker_standby = true;
-    out->standby = true;
-}
-
-static int out_standby(struct audio_stream *stream)
-{
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    pthread_mutex_lock(&out->lock);
-    do_out_standby(out);
-    pthread_mutex_unlock(&out->lock);
-    return 0;
-}
 
 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
 {
-    // out_add_audio_effect is a no op
+    ALOGV("out_add_audio_effect: %p", effect);
     return 0;
 }
 
 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
 {
-    // out_remove_audio_effect is a no op
+    ALOGV("out_remove_audio_effect: %p", effect);
     return 0;
 }
 
 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
-                                        int64_t *timestamp)
+        int64_t *timestamp)
 {
+    *timestamp = 0;
+    ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
     return -ENOSYS;
 }
 
+/** audio_stream_in implementation **/
+
+/* must be called with hw device and input stream mutexes locked */
+static int start_input_stream(struct alsa_stream_in *in)
+{
+    struct alsa_audio_device *adev = in->dev;
+    in->unavailable = true;
+    unsigned int pcm_retry_count = PCM_OPEN_RETRIES;
+    int in_card = get_audio_card(PCM_IN, PORT_BUILTIN_MIC);
+
+    while (1) {
+        in->pcm = pcm_open(in_card, PORT_BUILTIN_MIC, PCM_IN | PCM_MONOTONIC, &in->config);
+        if ((in->pcm != NULL) && pcm_is_ready(in->pcm)) {
+            break;
+        } else {
+            ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
+            if (in->pcm != NULL) {
+                pcm_close(in->pcm);
+                in->pcm = NULL;
+            }
+            if (--pcm_retry_count == 0) {
+                ALOGE("Failed to open pcm_in after %d tries", PCM_OPEN_RETRIES);
+                return -ENODEV;
+            }
+            usleep(PCM_OPEN_WAIT_TIME_MS * 1000);
+        }
+    }
+    in->unavailable = false;
+    adev->active_input = in;
+    return 0;
+}
+
+static void get_mic_characteristics(struct audio_microphone_characteristic_t* mic_data,
+                                    size_t* mic_count) {
+    *mic_count = 1;
+    memset(mic_data, 0, sizeof(struct audio_microphone_characteristic_t));
+    strlcpy(mic_data->device_id, "builtin_mic", AUDIO_MICROPHONE_ID_MAX_LEN - 1);
+    strlcpy(mic_data->address, "top", AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
+    memset(mic_data->channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED,
+           sizeof(mic_data->channel_mapping));
+    mic_data->device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+    mic_data->sensitivity = -37.0;
+    mic_data->max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+    mic_data->min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+    mic_data->orientation.x = 0.0f;
+    mic_data->orientation.y = 0.0f;
+    mic_data->orientation.z = 0.0f;
+    mic_data->geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+    mic_data->geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+    mic_data->geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+}
+
 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
 {
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    return in->req_config.sample_rate;
+    struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
+    return in->config.rate;
 }
 
 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
 {
+    ALOGV("in_set_sample_rate: %d", rate);
     return -ENOSYS;
 }
 
-static int refine_output_parameters(uint32_t *sample_rate, audio_format_t *format, audio_channel_mask_t *channel_mask)
-{
-    static const uint32_t sample_rates [] = {8000,11025,16000,22050,24000,32000,
-                                            44100,48000};
-    static const int sample_rates_count = sizeof(sample_rates)/sizeof(uint32_t);
-    bool inval = false;
-    if (*format != AUDIO_FORMAT_PCM_16_BIT) {
-        *format = AUDIO_FORMAT_PCM_16_BIT;
-        inval = true;
-    }
-
-    int channel_count = popcount(*channel_mask);
-    if (channel_count != 1 && channel_count != 2) {
-        *channel_mask = AUDIO_CHANNEL_IN_STEREO;
-        inval = true;
-    }
-
-    int i;
-    for (i = 0; i < sample_rates_count; i++) {
-        if (*sample_rate < sample_rates[i]) {
-            *sample_rate = sample_rates[i];
-            inval=true;
-            break;
-        }
-        else if (*sample_rate == sample_rates[i]) {
-            break;
-        }
-        else if (i == sample_rates_count-1) {
-            // Cap it to the highest rate we support
-            *sample_rate = sample_rates[i];
-            inval=true;
-        }
-    }
-
-    if (inval) {
-        return -EINVAL;
-    }
-    return 0;
-}
-
-static int refine_input_parameters(uint32_t *sample_rate, audio_format_t *format, audio_channel_mask_t *channel_mask)
-{
-    static const uint32_t sample_rates [] = {8000, 11025, 16000, 22050, 44100, 48000};
-    static const int sample_rates_count = sizeof(sample_rates)/sizeof(uint32_t);
-    bool inval = false;
-    // Only PCM_16_bit is supported. If this is changed, stereo to mono drop
-    // must be fixed in in_read
-    if (*format != AUDIO_FORMAT_PCM_16_BIT) {
-        *format = AUDIO_FORMAT_PCM_16_BIT;
-        inval = true;
-    }
-
-    int channel_count = popcount(*channel_mask);
-    if (channel_count != 1 && channel_count != 2) {
-        *channel_mask = AUDIO_CHANNEL_IN_STEREO;
-        inval = true;
-    }
-
-    int i;
-    for (i = 0; i < sample_rates_count; i++) {
-        if (*sample_rate < sample_rates[i]) {
-            *sample_rate = sample_rates[i];
-            inval=true;
-            break;
-        }
-        else if (*sample_rate == sample_rates[i]) {
-            break;
-        }
-        else if (i == sample_rates_count-1) {
-            // Cap it to the highest rate we support
-            *sample_rate = sample_rates[i];
-            inval=true;
-        }
-    }
-
-    if (inval) {
-        return -EINVAL;
-    }
-    return 0;
-}
-
-static int check_input_parameters(uint32_t sample_rate, audio_format_t format,
-                                  audio_channel_mask_t channel_mask)
-{
-    return refine_input_parameters(&sample_rate, &format, &channel_mask);
-}
-
-static size_t get_input_buffer_size(uint32_t sample_rate, audio_format_t format,
-                                    audio_channel_mask_t channel_mask)
-{
-    size_t size;
-    int channel_count = popcount(channel_mask);
-    if (check_input_parameters(sample_rate, format, channel_mask) != 0)
-        return 0;
-
-    size = sample_rate*IN_PERIOD_MS/1000;
-    // Audioflinger expects audio buffers to be multiple of 16 frames
-    size = ((size + 15) / 16) * 16;
-    size *= sizeof(short) * channel_count;
-
-    return size;
-}
-
-
-static size_t in_get_buffer_size(const struct audio_stream *stream)
-{
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    int size = get_input_buffer_size(in->req_config.sample_rate,
-                                 in->req_config.format,
-                                 in->req_config.channel_mask);
-
-    return size;
+static size_t get_input_buffer_size(size_t frames, audio_format_t format,
+                                    audio_channel_mask_t channel_mask) {
+    /* return the closest majoring multiple of 16 frames, as
+     * audioflinger expects audio buffers to be a multiple of 16 frames */
+    frames = ((frames + 15) / 16) * 16;
+    size_t bytes_per_frame = audio_channel_count_from_in_mask(channel_mask) *
+                            audio_bytes_per_sample(format);
+    size_t buffer_size = frames * bytes_per_frame;
+    return buffer_size;
 }
 
 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
 {
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    return in->req_config.channel_mask;
+    struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
+    ALOGV("in_get_channels: %d", in->config.channels);
+    return audio_channel_in_mask_from_count(in->config.channels);
 }
 
 static audio_format_t in_get_format(const struct audio_stream *stream)
 {
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    return in->req_config.format;
+    struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
+    ALOGV("in_get_format: %d", in->config.format);
+    return audio_format_from_pcm_format(in->config.format);
 }
 
 static int in_set_format(struct audio_stream *stream, audio_format_t format)
@@ -825,388 +534,294 @@
     return -ENOSYS;
 }
 
-static int in_dump(const struct audio_stream *stream, int fd)
+static size_t in_get_buffer_size(const struct audio_stream *stream)
 {
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
+    struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
+    size_t frames = CAPTURE_PERIOD_SIZE;
+    if (in->source == AUDIO_SOURCE_ECHO_REFERENCE) {
+        frames = CAPTURE_PERIOD_SIZE * PLAYBACK_CODEC_SAMPLING_RATE / CAPTURE_CODEC_SAMPLING_RATE;
+    }
+
+    size_t buffer_size =
+            get_input_buffer_size(frames, stream->get_format(stream), stream->get_channels(stream));
+    ALOGV("in_get_buffer_size: %zu", buffer_size);
+    return buffer_size;
+}
+
+static int in_get_active_microphones(const struct audio_stream_in* stream,
+                                     struct audio_microphone_characteristic_t* mic_array,
+                                     size_t* mic_count) {
+    ALOGV("in_get_active_microphones");
+    if ((mic_array == NULL) || (mic_count == NULL)) {
+        return -EINVAL;
+    }
+    struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
+    struct audio_hw_device* dev = (struct audio_hw_device*)in->dev;
+    bool mic_muted = false;
+    adev_get_mic_mute(dev, &mic_muted);
+    if ((in->source == AUDIO_SOURCE_ECHO_REFERENCE) || mic_muted) {
+        *mic_count = 0;
+        return 0;
+    }
+    adev_get_microphones(dev, mic_array, mic_count);
+    return 0;
+}
+
+static int do_input_standby(struct alsa_stream_in *in)
+{
+    struct alsa_audio_device *adev = in->dev;
+
+    if (!in->standby) {
+        pcm_close(in->pcm);
+        in->pcm = NULL;
+        adev->active_input = NULL;
+        in->standby = true;
+    }
+    return 0;
+}
+
+static int in_standby(struct audio_stream *stream)
+{
+    struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
+    int status;
 
     pthread_mutex_lock(&in->lock);
-    dprintf(fd, "\tin_dump:\n"
-                "\t\tsample rate: %u\n"
-                "\t\tbuffer size: %zu\n"
-                "\t\tchannel mask: %08x\n"
-                "\t\tformat: %d\n"
-                "\t\tdevice: %08x\n"
-                "\t\taudio dev: %p\n\n",
-                in_get_sample_rate(stream),
-                in_get_buffer_size(stream),
-                in_get_channels(stream),
-                in_get_format(stream),
-                in->device,
-                in->dev);
+    pthread_mutex_lock(&in->dev->lock);
+    status = do_input_standby(in);
+    pthread_mutex_unlock(&in->dev->lock);
     pthread_mutex_unlock(&in->lock);
+    return status;
+}
+
+static int in_dump(const struct audio_stream *stream, int fd)
+{
+    struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
+    if (in->source == AUDIO_SOURCE_ECHO_REFERENCE) {
+        return 0;
+    }
+
+    struct audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
+    size_t mic_count;
+
+    get_mic_characteristics(mic_array, &mic_count);
+
+    dprintf(fd, "  Microphone count: %zd\n", mic_count);
+    size_t idx;
+    for (idx = 0; idx < mic_count; idx++) {
+        dprintf(fd, "  Microphone: %zd\n", idx);
+        dprintf(fd, "    Address: %s\n", mic_array[idx].address);
+        dprintf(fd, "    Device: %d\n", mic_array[idx].device);
+        dprintf(fd, "    Sensitivity (dB): %.2f\n", mic_array[idx].sensitivity);
+    }
+
     return 0;
 }
 
 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
 {
-    struct str_parms *parms;
-    char value[32];
-    int success;
-    int ret = -EINVAL;
-
-    if (kvpairs == NULL || kvpairs[0] == 0) {
-        return 0;
-    }
-    parms = str_parms_create_str(kvpairs);
-    success = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
-            value, sizeof(value));
-    // As the hal version is 3.0, it must not use set parameters API to set audio device.
-    // Instead, it should use create_audio_patch API.
-    assert(("Must not use set parameters API to set audio devices", success < 0));
-
-    if (str_parms_has_key(parms, AUDIO_PARAMETER_STREAM_FORMAT)) {
-        // match the return value of in_set_format
-        ret = -ENOSYS;
-    }
-
-    str_parms_destroy(parms);
-
-    if (ret == -EINVAL) {
-        ALOGW("%s(), unsupported parameter %s", __func__, kvpairs);
-        // There is not any key supported for set_parameters API.
-        // Return error when there is non-null value passed in.
-    }
-    return ret;
+    return 0;
 }
 
 static char * in_get_parameters(const struct audio_stream *stream,
-                                const char *keys)
+        const char *keys)
 {
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    struct str_parms *query = str_parms_create_str(keys);
-    char *str = NULL;
-    char value[256];
-    struct str_parms *reply = str_parms_create();
-    int ret;
-    bool get = false;
-
-    ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
-    if (ret >= 0) {
-        str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, in->device);
-        get = true;
-    }
-
-    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
-        value[0] = 0;
-        strcat(value, "AUDIO_FORMAT_PCM_16_BIT");
-        str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_FORMATS, value);
-        get = true;
-    }
-
-    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_FORMAT)) {
-        value[0] = 0;
-        strcat(value, "AUDIO_FORMAT_PCM_16_BIT");
-        str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_FORMAT, value);
-        get = true;
-    }
-
-    if (get) {
-        str = str_parms_to_str(reply);
-    }
-    else {
-        ALOGD("%s Unsupported parameter: %s", __FUNCTION__, keys);
-    }
-
-    str_parms_destroy(query);
-    str_parms_destroy(reply);
-    return str;
+    return strdup("");
 }
 
 static int in_set_gain(struct audio_stream_in *stream, float gain)
 {
-    // in_set_gain is a no op
     return 0;
 }
 
-// Call with in->lock held
-static void get_current_input_position(struct generic_stream_in *in,
-                                       int64_t * position,
-                                       struct timespec * timestamp) {
-    struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
-    clock_gettime(CLOCK_MONOTONIC, &t);
-    const int64_t now_us = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
-    if (timestamp) {
-        *timestamp = t;
-    }
-    int64_t position_since_standby;
-    if (in->standby) {
-        position_since_standby = 0;
-    } else {
-        const int64_t first_us = (in->standby_exit_time.tv_sec * 1000000000LL +
-                                  in->standby_exit_time.tv_nsec) / 1000;
-        position_since_standby = (now_us - first_us) *
-                in_get_sample_rate(&in->stream.common) /
-                1000000;
-        if (position_since_standby < 0) {
-            position_since_standby = 0;
-        }
-    }
-    *position = in->standby_position + position_since_standby;
-}
-
-// Must be called with in->lock held
-static void do_in_standby(struct generic_stream_in *in)
-{
-    if (in->standby) {
-        return;
-    }
-    in->worker_standby = true;
-    get_current_input_position(in, &in->standby_position, NULL);
-    in->standby = true;
-}
-
-static int in_standby(struct audio_stream *stream)
-{
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    pthread_mutex_lock(&in->lock);
-    do_in_standby(in);
-    pthread_mutex_unlock(&in->lock);
-    return 0;
-}
-
-static void *in_read_worker(void * args)
-{
-    struct generic_stream_in *in = (struct generic_stream_in *)args;
-    struct pcm *pcm = NULL;
-    uint8_t *buffer = NULL;
-    size_t buffer_frames;
-    int buffer_size;
-
-    bool restart = false;
-    bool shutdown = false;
-    while (true) {
-        pthread_mutex_lock(&in->lock);
-        while (in->worker_standby || restart) {
-            restart = false;
-            if (pcm) {
-                pcm_close(pcm); // Frees pcm
-                pcm = NULL;
-                free(buffer);
-                buffer=NULL;
-            }
-            if (in->worker_exit) {
-                break;
-            }
-            pthread_cond_wait(&in->worker_wake, &in->lock);
-        }
-
-        if (in->worker_exit) {
-            if (!in->worker_standby) {
-                ALOGE("In worker not in standby before exiting");
-            }
-            shutdown = true;
-        }
-        if (shutdown) {
-            pthread_mutex_unlock(&in->lock);
-            break;
-        }
-        if (!pcm) {
-            pcm = pcm_open(PCM_CARD, PCM_DEVICE,
-                          PCM_IN | PCM_MONOTONIC, &in->pcm_config);
-            if (!pcm_is_ready(pcm)) {
-                ALOGE("pcm_open(in) failed: %s: channels %d format %d rate %d",
-                  pcm_get_error(pcm),
-                  in->pcm_config.channels,
-                  in->pcm_config.format,
-                  in->pcm_config.rate
-                   );
-                pthread_mutex_unlock(&in->lock);
-                break;
-            }
-            buffer_frames = in->pcm_config.period_size;
-            buffer_size = pcm_frames_to_bytes(pcm, buffer_frames);
-            buffer = malloc(buffer_size);
-            if (!buffer) {
-                ALOGE("could not allocate worker read buffer");
-                pthread_mutex_unlock(&in->lock);
-                break;
-            }
-        }
-        pthread_mutex_unlock(&in->lock);
-        int ret = pcm_read(pcm, buffer, pcm_frames_to_bytes(pcm, buffer_frames));
-        if (ret != 0) {
-            ALOGW("pcm_read failed %s", pcm_get_error(pcm));
-            restart = true;
-            continue;
-        }
-
-        pthread_mutex_lock(&in->lock);
-        size_t frames_written = audio_vbuffer_write(&in->buffer, buffer, buffer_frames);
-        pthread_mutex_unlock(&in->lock);
-
-        if (frames_written != buffer_frames) {
-            ALOGW("in_read_worker only could write %zu / %zu frames", frames_written, buffer_frames);
-        }
-    }
-    if (buffer) {
-        free(buffer);
-    }
-    return NULL;
-}
-
 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
-                       size_t bytes)
+        size_t bytes)
 {
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    struct generic_audio_device *adev = in->dev;
-    const size_t frames =  bytes / audio_stream_in_frame_size(stream);
-    bool mic_mute = false;
-    size_t read_bytes = 0;
+    int ret;
+    struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
+    struct alsa_audio_device *adev = in->dev;
+    size_t frame_size = audio_stream_in_frame_size(stream);
+    size_t in_frames = bytes / frame_size;
 
-    adev_get_mic_mute(&adev->device, &mic_mute);
-    pthread_mutex_lock(&in->lock);
+    ALOGV("in_read: stream: %d, bytes %zu", in->source, bytes);
 
-    if (in->worker_standby) {
-        in->worker_standby = false;
-    }
-    pthread_cond_signal(&in->worker_wake);
+    /* Special handling for Echo Reference: simply get the reference from FIFO.
+     * The format and sample rate should be specified by arguments to adev_open_input_stream. */
+    if (in->source == AUDIO_SOURCE_ECHO_REFERENCE) {
+        struct aec_info info;
+        info.bytes = bytes;
 
-    int64_t current_position;
-    struct timespec current_time;
-
-    get_current_input_position(in, &current_position, &current_time);
-    if (in->standby) {
-        in->standby = false;
-        in->standby_exit_time = current_time;
-        in->standby_frames_read = 0;
-    }
-
-    const int64_t frames_available = current_position - in->standby_position - in->standby_frames_read;
-    assert(frames_available >= 0);
-
-    const size_t frames_wait = ((uint64_t)frames_available > frames) ? 0 : frames - frames_available;
-
-    int64_t sleep_time_us  = frames_wait * 1000000LL /
-                             in_get_sample_rate(&stream->common);
-
-    pthread_mutex_unlock(&in->lock);
-
-    if (sleep_time_us > 0) {
-        usleep(sleep_time_us);
-    }
-
-    pthread_mutex_lock(&in->lock);
-    int read_frames = 0;
-    if (in->standby) {
-        ALOGW("Input put to sleep while read in progress");
-        goto exit;
-    }
-    in->standby_frames_read += frames;
-
-    if (popcount(in->req_config.channel_mask) == 1 &&
-        in->pcm_config.channels == 2) {
-        // Need to resample to mono
-        if (in->stereo_to_mono_buf_size < bytes*2) {
-            in->stereo_to_mono_buf = realloc(in->stereo_to_mono_buf,
-                                             bytes*2);
-            if (!in->stereo_to_mono_buf) {
-                ALOGE("Failed to allocate stereo_to_mono_buff");
-                goto exit;
+        const uint64_t time_increment_nsec = (uint64_t)bytes * NANOS_PER_SECOND /
+                                             audio_stream_in_frame_size(stream) /
+                                             in_get_sample_rate(&stream->common);
+        if (!aec_get_spk_running(adev->aec)) {
+            if (in->timestamp_nsec == 0) {
+                struct timespec now;
+                clock_gettime(CLOCK_MONOTONIC, &now);
+                const uint64_t timestamp_nsec = audio_utils_ns_from_timespec(&now);
+                in->timestamp_nsec = timestamp_nsec;
+            } else {
+                in->timestamp_nsec += time_increment_nsec;
+            }
+            memset(buffer, 0, bytes);
+            const uint64_t time_increment_usec = time_increment_nsec / 1000;
+            usleep(time_increment_usec);
+        } else {
+            int ref_ret = get_reference_samples(adev->aec, buffer, &info);
+            if ((ref_ret) || (info.timestamp_usec == 0)) {
+                memset(buffer, 0, bytes);
+                in->timestamp_nsec += time_increment_nsec;
+            } else {
+                in->timestamp_nsec = 1000 * info.timestamp_usec;
             }
         }
+        in->frames_read += in_frames;
 
-        read_frames = audio_vbuffer_read(&in->buffer, in->stereo_to_mono_buf, frames);
-
-        // Currently only pcm 16 is supported.
-        uint16_t *src = (uint16_t *)in->stereo_to_mono_buf;
-        uint16_t *dst = (uint16_t *)buffer;
-        size_t i;
-        // Resample stereo 16 to mono 16 by dropping one channel.
-        // The stereo stream is interleaved L-R-L-R
-        for (i = 0; i < frames; i++) {
-            *dst = *src;
-            src += 2;
-            dst += 1;
+#if DEBUG_AEC
+        FILE* fp_ref = fopen("/data/local/traces/aec_ref.pcm", "a+");
+        if (fp_ref) {
+            fwrite((char*)buffer, 1, bytes, fp_ref);
+            fclose(fp_ref);
+        } else {
+            ALOGE("AEC debug: Could not open file aec_ref.pcm!");
         }
-    } else {
-        read_frames = audio_vbuffer_read(&in->buffer, buffer, frames);
+        FILE* fp_ref_ts = fopen("/data/local/traces/aec_ref_timestamps.txt", "a+");
+        if (fp_ref_ts) {
+            fprintf(fp_ref_ts, "%" PRIu64 "\n", in->timestamp_nsec);
+            fclose(fp_ref_ts);
+        } else {
+            ALOGE("AEC debug: Could not open file aec_ref_timestamps.txt!");
+        }
+#endif
+        return info.bytes;
+    }
+
+    /* Microphone input stream read */
+
+    /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
+     * on the input stream mutex - e.g. executing select_mode() while holding the hw device
+     * mutex
+     */
+    pthread_mutex_lock(&in->lock);
+    pthread_mutex_lock(&adev->lock);
+    if (in->standby) {
+        ret = start_input_stream(in);
+        if (ret != 0) {
+            pthread_mutex_unlock(&adev->lock);
+            ALOGE("start_input_stream failed with code %d", ret);
+            goto exit;
+        }
+        in->standby = false;
+    }
+
+    pthread_mutex_unlock(&adev->lock);
+
+    ret = pcm_read(in->pcm, buffer, in_frames * frame_size);
+    struct aec_info info;
+    get_pcm_timestamp(in->pcm, in->config.rate, &info, false /*isOutput*/);
+    if (ret == 0) {
+        in->frames_read += in_frames;
+        in->timestamp_nsec = audio_utils_ns_from_timespec(&info.timestamp);
+    }
+    else {
+        ALOGE("pcm_read failed with code %d", ret);
     }
 
 exit:
-    read_bytes = read_frames*audio_stream_in_frame_size(stream);
-
-    if (mic_mute) {
-        read_bytes = 0;
-    }
-
-    if (read_bytes < bytes) {
-        memset (&((uint8_t *)buffer)[read_bytes], 0, bytes-read_bytes);
-    }
-
     pthread_mutex_unlock(&in->lock);
 
+    bool mic_muted = false;
+    adev_get_mic_mute((struct audio_hw_device*)adev, &mic_muted);
+    if (mic_muted) {
+        memset(buffer, 0, bytes);
+    }
+
+    if (ret != 0) {
+        usleep((int64_t)bytes * 1000000 / audio_stream_in_frame_size(stream) /
+                in_get_sample_rate(&stream->common));
+    } else {
+        /* Process AEC if available */
+        /* TODO move to a separate thread */
+        if (!mic_muted) {
+            info.bytes = bytes;
+            int aec_ret = process_aec(adev->aec, buffer, &info);
+            if (aec_ret) {
+                ALOGE("process_aec returned error code %d", aec_ret);
+            }
+        }
+    }
+
+#if DEBUG_AEC && !defined(AEC_HAL)
+    FILE* fp_in = fopen("/data/local/traces/aec_in.pcm", "a+");
+    if (fp_in) {
+        fwrite((char*)buffer, 1, bytes, fp_in);
+        fclose(fp_in);
+    } else {
+        ALOGE("AEC debug: Could not open file aec_in.pcm!");
+    }
+    FILE* fp_mic_ts = fopen("/data/local/traces/aec_in_timestamps.txt", "a+");
+    if (fp_mic_ts) {
+        fprintf(fp_mic_ts, "%" PRIu64 "\n", in->timestamp_nsec);
+        fclose(fp_mic_ts);
+    } else {
+        ALOGE("AEC debug: Could not open file aec_in_timestamps.txt!");
+    }
+#endif
+
     return bytes;
 }
 
+static int in_get_capture_position(const struct audio_stream_in* stream, int64_t* frames,
+                                   int64_t* time) {
+    if (stream == NULL || frames == NULL || time == NULL) {
+        return -EINVAL;
+    }
+    struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
+
+    *frames = in->frames_read;
+    *time = in->timestamp_nsec;
+    ALOGV("%s: source: %d, timestamp (nsec): %" PRIu64, __func__, in->source, *time);
+
+    return 0;
+}
+
 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
 {
     return 0;
 }
 
-static int in_get_capture_position(const struct audio_stream_in *stream,
-                                int64_t *frames, int64_t *time)
-{
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    pthread_mutex_lock(&in->lock);
-    struct timespec current_time;
-    get_current_input_position(in, frames, &current_time);
-    *time = (current_time.tv_sec * 1000000000LL + current_time.tv_nsec);
-    pthread_mutex_unlock(&in->lock);
-    return 0;
-}
-
-static int in_get_active_microphones(const struct audio_stream_in *stream,
-                                     struct audio_microphone_characteristic_t *mic_array,
-                                     size_t *mic_count)
-{
-    return adev_get_microphones(NULL, mic_array, mic_count);
-}
-
 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
 {
-    // in_add_audio_effect is a no op
     return 0;
 }
 
 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
 {
-    // in_add_audio_effect is a no op
     return 0;
 }
 
 static int adev_open_output_stream(struct audio_hw_device *dev,
-                                   audio_io_handle_t handle,
-                                   audio_devices_t devices,
-                                   audio_output_flags_t flags,
-                                   struct audio_config *config,
-                                   struct audio_stream_out **stream_out,
-                                   const char *address __unused)
+        audio_io_handle_t handle,
+        audio_devices_t devices,
+        audio_output_flags_t flags,
+        struct audio_config *config,
+        struct audio_stream_out **stream_out,
+        const char *address __unused)
 {
-    struct generic_audio_device *adev = (struct generic_audio_device *)dev;
-    struct generic_stream_out *out;
-    int ret = 0;
+    ALOGV("adev_open_output_stream...");
 
-    if (refine_output_parameters(&config->sample_rate, &config->format, &config->channel_mask)) {
-        ALOGE("Error opening output stream format %d, channel_mask %04x, sample_rate %u",
-              config->format, config->channel_mask, config->sample_rate);
-        ret = -EINVAL;
-        goto error;
+    struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
+    int out_port = get_audio_output_port(devices);
+    int out_card = get_audio_card(PCM_OUT, out_port);
+    struct pcm_params* params = pcm_params_get(out_card, out_port, PCM_OUT);
+    if (!params) {
+        return -ENOSYS;
     }
 
-    out = (struct generic_stream_out *)calloc(1, sizeof(struct generic_stream_out));
-
-    if (!out)
+    struct alsa_stream_out* out =
+            (struct alsa_stream_out*)calloc(1, sizeof(struct alsa_stream_out));
+    if (!out) {
         return -ENOMEM;
+    }
 
     out->stream.common.get_sample_rate = out_get_sample_rate;
     out->stream.common.set_sample_rate = out_set_sample_rate;
@@ -1224,141 +839,141 @@
     out->stream.set_volume = out_set_volume;
     out->stream.write = out_write;
     out->stream.get_render_position = out_get_render_position;
-    out->stream.get_presentation_position = out_get_presentation_position;
     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
+    out->stream.get_presentation_position = out_get_presentation_position;
 
-    out->handle = handle;
+    out->config.channels = CHANNEL_STEREO;
+    out->config.rate = PLAYBACK_CODEC_SAMPLING_RATE;
+    out->config.format = PCM_FORMAT_S16_LE;
+    out->config.period_size = PLAYBACK_PERIOD_SIZE;
+    out->config.period_count = PLAYBACK_PERIOD_COUNT;
 
-    pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
-    out->dev = adev;
-    // Only 1 device is expected despite the argument being named 'devices'
-    out->num_devices = 1;
-    out->devices[0] = devices;
-    memcpy(&out->req_config, config, sizeof(struct audio_config));
-    memcpy(&out->pcm_config, &pcm_config_out, sizeof(struct pcm_config));
-    out->pcm_config.rate = config->sample_rate;
-    out->pcm_config.period_size = out->pcm_config.rate*OUT_PERIOD_MS/1000;
-
-    out->standby = true;
-    out->underrun_position = 0;
-    out->underrun_time.tv_sec = 0;
-    out->underrun_time.tv_nsec = 0;
-    out->last_write_time_us = 0;
-    out->frames_total_buffered = 0;
-    out->frames_written = 0;
-    out->frames_rendered = 0;
-
-    ret = audio_vbuffer_init(&out->buffer,
-                      out->pcm_config.period_size*out->pcm_config.period_count,
-                      out->pcm_config.channels *
-                      pcm_format_to_bits(out->pcm_config.format) >> 3);
-    if (ret == 0) {
-        pthread_cond_init(&out->worker_wake, NULL);
-        out->worker_standby = true;
-        out->worker_exit = false;
-        pthread_create(&out->worker_thread, NULL, out_write_worker, out);
-
+    if (out->config.rate != config->sample_rate ||
+           audio_channel_count_from_out_mask(config->channel_mask) != CHANNEL_STEREO ||
+               out->config.format !=  pcm_format_from_audio_format(config->format) ) {
+        config->sample_rate = out->config.rate;
+        config->format = audio_format_from_pcm_format(out->config.format);
+        config->channel_mask = audio_channel_out_mask_from_count(CHANNEL_STEREO);
+        goto error_1;
     }
 
-    pthread_mutex_lock(&adev->lock);
-    list_add_tail(&adev->out_streams, &out->stream_node);
-    pthread_mutex_unlock(&adev->lock);
+    ALOGI("adev_open_output_stream selects channels=%d rate=%d format=%d, devices=%d",
+          out->config.channels, out->config.rate, out->config.format, devices);
 
-    *stream_out = &out->stream;
+    out->dev = ladev;
+    out->standby = 1;
+    out->unavailable = false;
+    out->devices = devices;
 
-error:
+    config->format = out_get_format(&out->stream.common);
+    config->channel_mask = out_get_channels(&out->stream.common);
+    config->sample_rate = out_get_sample_rate(&out->stream.common);
 
-    return ret;
-}
-
-// This must be called with adev->lock held.
-struct generic_stream_out *get_stream_out_by_io_handle_l(
-        struct generic_audio_device *adev, audio_io_handle_t handle) {
-    struct listnode *node;
-
-    list_for_each(node, &adev->out_streams) {
-        struct generic_stream_out *out = node_to_item(
-                node, struct generic_stream_out, stream_node);
-        if (out->handle == handle) {
-            return out;
+    out->speaker_eq = NULL;
+    if (out_port == PORT_INTERNAL_SPEAKER) {
+        out_set_eq(out);
+        if (out->speaker_eq == NULL) {
+            ALOGE("%s: Failed to initialize speaker EQ", __func__);
         }
     }
-    return NULL;
+
+    int aec_ret = init_aec_reference_config(ladev->aec, out);
+    if (aec_ret) {
+        ALOGE("AEC: Speaker config init failed!");
+        goto error_2;
+    }
+
+    *stream_out = &out->stream;
+    return 0;
+
+error_2:
+    fir_release(out->speaker_eq);
+error_1:
+    free(out);
+    return -EINVAL;
 }
 
 static void adev_close_output_stream(struct audio_hw_device *dev,
-                                     struct audio_stream_out *stream)
+        struct audio_stream_out *stream)
 {
-    struct generic_stream_out *out = (struct generic_stream_out *)stream;
-    pthread_mutex_lock(&out->lock);
-    do_out_standby(out);
-
-    out->worker_exit = true;
-    pthread_cond_signal(&out->worker_wake);
-    pthread_mutex_unlock(&out->lock);
-
-    pthread_join(out->worker_thread, NULL);
-    pthread_mutex_destroy(&out->lock);
-    audio_vbuffer_destroy(&out->buffer);
-
-    struct generic_audio_device *adev = (struct generic_audio_device *) dev;
-    pthread_mutex_lock(&adev->lock);
-    list_remove(&out->stream_node);
-    pthread_mutex_unlock(&adev->lock);
+    ALOGV("adev_close_output_stream...");
+    struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
+    destroy_aec_reference_config(adev->aec);
+    struct alsa_stream_out* out = (struct alsa_stream_out*)stream;
+    fir_release(out->speaker_eq);
     free(stream);
 }
 
 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
 {
-    return 0;
+    ALOGV("adev_set_parameters");
+    return -ENOSYS;
 }
 
 static char * adev_get_parameters(const struct audio_hw_device *dev,
-                                  const char *keys)
+        const char *keys)
 {
+    ALOGV("adev_get_parameters");
     return strdup("");
 }
 
+static int adev_get_microphones(const struct audio_hw_device* dev,
+                                struct audio_microphone_characteristic_t* mic_array,
+                                size_t* mic_count) {
+    ALOGV("adev_get_microphones");
+    if ((mic_array == NULL) || (mic_count == NULL)) {
+        return -EINVAL;
+    }
+    get_mic_characteristics(mic_array, mic_count);
+    return 0;
+}
+
 static int adev_init_check(const struct audio_hw_device *dev)
 {
+    ALOGV("adev_init_check");
     return 0;
 }
 
 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
 {
-    // adev_set_voice_volume is a no op (simulates phones)
-    return 0;
+    ALOGV("adev_set_voice_volume: %f", volume);
+    return -ENOSYS;
 }
 
 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
 {
+    ALOGV("adev_set_master_volume: %f", volume);
     return -ENOSYS;
 }
 
 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
 {
+    ALOGV("adev_get_master_volume: %f", *volume);
     return -ENOSYS;
 }
 
 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
 {
+    ALOGV("adev_set_master_mute: %d", muted);
     return -ENOSYS;
 }
 
 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
 {
+    ALOGV("adev_get_master_mute: %d", *muted);
     return -ENOSYS;
 }
 
 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
 {
-    // adev_set_mode is a no op (simulates phones)
+    ALOGV("adev_set_mode: %d", mode);
     return 0;
 }
 
 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
 {
-    struct generic_audio_device *adev = (struct generic_audio_device *)dev;
+    ALOGV("adev_set_mic_mute: %d",state);
+    struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
     pthread_mutex_lock(&adev->lock);
     adev->mic_mute = state;
     pthread_mutex_unlock(&adev->lock);
@@ -1367,456 +982,211 @@
 
 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
 {
-    struct generic_audio_device *adev = (struct generic_audio_device *)dev;
+    ALOGV("adev_get_mic_mute");
+    struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
     pthread_mutex_lock(&adev->lock);
     *state = adev->mic_mute;
     pthread_mutex_unlock(&adev->lock);
     return 0;
 }
 
-
 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
-                                         const struct audio_config *config)
+        const struct audio_config *config)
 {
-    return get_input_buffer_size(config->sample_rate, config->format, config->channel_mask);
+    size_t buffer_size =
+            get_input_buffer_size(CAPTURE_PERIOD_SIZE, config->format, config->channel_mask);
+    ALOGV("adev_get_input_buffer_size: %zu", buffer_size);
+    return buffer_size;
 }
 
-// This must be called with adev->lock held.
-struct generic_stream_in *get_stream_in_by_io_handle_l(
-        struct generic_audio_device *adev, audio_io_handle_t handle) {
-    struct listnode *node;
+static int adev_open_input_stream(struct audio_hw_device* dev, audio_io_handle_t handle,
+                                  audio_devices_t devices, struct audio_config* config,
+                                  struct audio_stream_in** stream_in,
+                                  audio_input_flags_t flags __unused, const char* address __unused,
+                                  audio_source_t source) {
+    ALOGV("adev_open_input_stream...");
 
-    list_for_each(node, &adev->in_streams) {
-        struct generic_stream_in *in = node_to_item(
-                node, struct generic_stream_in, stream_node);
-        if (in->handle == handle) {
-            return in;
-        }
-    }
-    return NULL;
-}
+    struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
 
-static void adev_close_input_stream(struct audio_hw_device *dev,
-                                   struct audio_stream_in *stream)
-{
-    struct generic_stream_in *in = (struct generic_stream_in *)stream;
-    pthread_mutex_lock(&in->lock);
-    do_in_standby(in);
-
-    in->worker_exit = true;
-    pthread_cond_signal(&in->worker_wake);
-    pthread_mutex_unlock(&in->lock);
-    pthread_join(in->worker_thread, NULL);
-
-    if (in->stereo_to_mono_buf != NULL) {
-        free(in->stereo_to_mono_buf);
-        in->stereo_to_mono_buf_size = 0;
+    int in_card = get_audio_card(PCM_IN, PORT_BUILTIN_MIC);
+    struct pcm_params* params = pcm_params_get(in_card, PORT_BUILTIN_MIC, PCM_IN);
+    if (!params) {
+        return -ENOSYS;
     }
 
-    pthread_mutex_destroy(&in->lock);
-    audio_vbuffer_destroy(&in->buffer);
-
-    struct generic_audio_device *adev = (struct generic_audio_device *) dev;
-    pthread_mutex_lock(&adev->lock);
-    list_remove(&in->stream_node);
-    pthread_mutex_unlock(&adev->lock);
-    free(stream);
-}
-
-
-static int adev_open_input_stream(struct audio_hw_device *dev,
-                                  audio_io_handle_t handle,
-                                  audio_devices_t devices,
-                                  struct audio_config *config,
-                                  struct audio_stream_in **stream_in,
-                                  audio_input_flags_t flags __unused,
-                                  const char *address __unused,
-                                  audio_source_t source __unused)
-{
-    struct generic_audio_device *adev = (struct generic_audio_device *)dev;
-    struct generic_stream_in *in;
-    int ret = 0;
-    if (refine_input_parameters(&config->sample_rate, &config->format, &config->channel_mask)) {
-        ALOGE("Error opening input stream format %d, channel_mask %04x, sample_rate %u",
-              config->format, config->channel_mask, config->sample_rate);
-        ret = -EINVAL;
-        goto error;
-    }
-
-    in = (struct generic_stream_in *)calloc(1, sizeof(struct generic_stream_in));
+    struct alsa_stream_in* in = (struct alsa_stream_in*)calloc(1, sizeof(struct alsa_stream_in));
     if (!in) {
-        ret = -ENOMEM;
-        goto error;
+        return -ENOMEM;
     }
 
     in->stream.common.get_sample_rate = in_get_sample_rate;
-    in->stream.common.set_sample_rate = in_set_sample_rate;         // no op
+    in->stream.common.set_sample_rate = in_set_sample_rate;
     in->stream.common.get_buffer_size = in_get_buffer_size;
     in->stream.common.get_channels = in_get_channels;
     in->stream.common.get_format = in_get_format;
-    in->stream.common.set_format = in_set_format;                   // no op
+    in->stream.common.set_format = in_set_format;
     in->stream.common.standby = in_standby;
     in->stream.common.dump = in_dump;
     in->stream.common.set_parameters = in_set_parameters;
     in->stream.common.get_parameters = in_get_parameters;
-    in->stream.common.add_audio_effect = in_add_audio_effect;       // no op
-    in->stream.common.remove_audio_effect = in_remove_audio_effect; // no op
-    in->stream.set_gain = in_set_gain;                              // no op
+    in->stream.common.add_audio_effect = in_add_audio_effect;
+    in->stream.common.remove_audio_effect = in_remove_audio_effect;
+    in->stream.set_gain = in_set_gain;
     in->stream.read = in_read;
-    in->stream.get_input_frames_lost = in_get_input_frames_lost;    // no op
+    in->stream.get_input_frames_lost = in_get_input_frames_lost;
     in->stream.get_capture_position = in_get_capture_position;
     in->stream.get_active_microphones = in_get_active_microphones;
 
-    pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
-    in->dev = adev;
-    in->device = devices;
-    memcpy(&in->req_config, config, sizeof(struct audio_config));
-    memcpy(&in->pcm_config, &pcm_config_in, sizeof(struct pcm_config));
-    in->pcm_config.rate = config->sample_rate;
-    in->pcm_config.period_size = in->pcm_config.rate*IN_PERIOD_MS/1000;
-
-    in->stereo_to_mono_buf = NULL;
-    in->stereo_to_mono_buf_size = 0;
-
-    in->standby = true;
-    in->standby_position = 0;
-    in->standby_exit_time.tv_sec = 0;
-    in->standby_exit_time.tv_nsec = 0;
-    in->standby_frames_read = 0;
-
-    ret = audio_vbuffer_init(&in->buffer,
-                      in->pcm_config.period_size*in->pcm_config.period_count,
-                      in->pcm_config.channels *
-                      pcm_format_to_bits(in->pcm_config.format) >> 3);
-    if (ret == 0) {
-        pthread_cond_init(&in->worker_wake, NULL);
-        in->worker_standby = true;
-        in->worker_exit = false;
-        pthread_create(&in->worker_thread, NULL, in_read_worker, in);
+    in->config.channels = CHANNEL_STEREO;
+    if (source == AUDIO_SOURCE_ECHO_REFERENCE) {
+        in->config.rate = PLAYBACK_CODEC_SAMPLING_RATE;
+    } else {
+        in->config.rate = CAPTURE_CODEC_SAMPLING_RATE;
     }
-    in->handle = handle;
+    in->config.format = PCM_FORMAT_S32_LE;
+    in->config.period_size = CAPTURE_PERIOD_SIZE;
+    in->config.period_count = CAPTURE_PERIOD_COUNT;
 
-    pthread_mutex_lock(&adev->lock);
-    list_add_tail(&adev->in_streams, &in->stream_node);
-    pthread_mutex_unlock(&adev->lock);
+    if (in->config.rate != config->sample_rate ||
+           audio_channel_count_from_in_mask(config->channel_mask) != CHANNEL_STEREO ||
+               in->config.format !=  pcm_format_from_audio_format(config->format) ) {
+        config->format = in_get_format(&in->stream.common);
+        config->channel_mask = in_get_channels(&in->stream.common);
+        config->sample_rate = in_get_sample_rate(&in->stream.common);
+        goto error_1;
+    }
+
+    ALOGI("adev_open_input_stream selects channels=%d rate=%d format=%d source=%d",
+          in->config.channels, in->config.rate, in->config.format, source);
+
+    in->dev = ladev;
+    in->standby = true;
+    in->unavailable = false;
+    in->source = source;
+    in->devices = devices;
+
+    if (is_aec_input(in)) {
+        int aec_ret = init_aec_mic_config(ladev->aec, in);
+        if (aec_ret) {
+            ALOGE("AEC: Mic config init failed!");
+            goto error_1;
+        }
+    }
+
+#if DEBUG_AEC
+    remove("/data/local/traces/aec_ref.pcm");
+    remove("/data/local/traces/aec_in.pcm");
+    remove("/data/local/traces/aec_ref_timestamps.txt");
+    remove("/data/local/traces/aec_in_timestamps.txt");
+#endif
 
     *stream_in = &in->stream;
-
-error:
-    return ret;
-}
-
-
-static int adev_dump(const audio_hw_device_t *dev, int fd)
-{
     return 0;
-}
 
-static int adev_get_microphones(const audio_hw_device_t *dev,
-                                struct audio_microphone_characteristic_t *mic_array,
-                                size_t *mic_count)
-{
-    if (mic_count == NULL) {
-        return -ENOSYS;
-    }
-
-    if (*mic_count == 0) {
-        *mic_count = 1;
-        return 0;
-    }
-
-    if (mic_array == NULL) {
-        return -ENOSYS;
-    }
-
-    strncpy(mic_array->device_id, "mic_goldfish", AUDIO_MICROPHONE_ID_MAX_LEN - 1);
-    mic_array->device = AUDIO_DEVICE_IN_BUILTIN_MIC;
-    strncpy(mic_array->address, AUDIO_BOTTOM_MICROPHONE_ADDRESS,
-            AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
-    memset(mic_array->channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED,
-           sizeof(mic_array->channel_mapping));
-    mic_array->location = AUDIO_MICROPHONE_LOCATION_UNKNOWN;
-    mic_array->group = 0;
-    mic_array->index_in_the_group = 0;
-    mic_array->sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
-    mic_array->max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
-    mic_array->min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
-    mic_array->directionality = AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
-    mic_array->num_frequency_responses = 0;
-    mic_array->geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
-    mic_array->geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
-    mic_array->geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
-    mic_array->orientation.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
-    mic_array->orientation.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
-    mic_array->orientation.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
-
-    *mic_count = 1;
-    return 0;
-}
-
-static int adev_create_audio_patch(struct audio_hw_device *dev,
-                                   unsigned int num_sources,
-                                   const struct audio_port_config *sources,
-                                   unsigned int num_sinks,
-                                   const struct audio_port_config *sinks,
-                                   audio_patch_handle_t *handle) {
-    if (num_sources != 1 || num_sinks == 0 || num_sinks > AUDIO_PATCH_PORTS_MAX) {
-        return -EINVAL;
-    }
-
-    if (sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
-        // If source is a device, the number of sinks should be 1.
-        if (num_sinks != 1 || sinks[0].type != AUDIO_PORT_TYPE_MIX) {
-            return -EINVAL;
-        }
-    } else if (sources[0].type == AUDIO_PORT_TYPE_MIX) {
-        // If source is a mix, all sinks should be device.
-        for (unsigned int i = 0; i < num_sinks; i++) {
-            if (sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
-                ALOGE("%s() invalid sink type %#x for mix source", __func__, sinks[i].type);
-                return -EINVAL;
-            }
-        }
-    } else {
-        // All other cases are invalid.
-        return -EINVAL;
-    }
-
-    struct generic_audio_device* adev = (struct generic_audio_device*) dev;
-    int ret = 0;
-    bool generatedPatchHandle = false;
-    pthread_mutex_lock(&adev->lock);
-    if (*handle == AUDIO_PATCH_HANDLE_NONE) {
-        *handle = ++adev->next_patch_handle;
-        generatedPatchHandle = true;
-    }
-
-    // Only handle patches for mix->devices and device->mix case.
-    if (sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
-        struct generic_stream_in *in =
-                get_stream_in_by_io_handle_l(adev, sinks[0].ext.mix.handle);
-        if (in == NULL) {
-            ALOGE("%s()can not find stream with handle(%d)", __func__, sources[0].ext.mix.handle);
-            ret = -EINVAL;
-            goto error;
-        }
-
-        // Check if the patch handle match the recorded one if a valid patch handle is passed.
-        if (!generatedPatchHandle && in->patch_handle != *handle) {
-            ALOGE("%s() the patch handle(%d) does not match recorded one(%d) for stream "
-                  "with handle(%d) when creating audio patch for device->mix",
-                  __func__, *handle, in->patch_handle, in->handle);
-            ret = -EINVAL;
-            goto error;
-        }
-        pthread_mutex_lock(&in->lock);
-        in->device = sources[0].ext.device.type;
-        pthread_mutex_unlock(&in->lock);
-        in->patch_handle = *handle;
-    } else {
-        struct generic_stream_out *out =
-                get_stream_out_by_io_handle_l(adev, sources[0].ext.mix.handle);
-        if (out == NULL) {
-            ALOGE("%s()can not find stream with handle(%d)", __func__, sources[0].ext.mix.handle);
-            ret = -EINVAL;
-            goto error;
-        }
-
-        // Check if the patch handle match the recorded one if a valid patch handle is passed.
-        if (!generatedPatchHandle && out->patch_handle != *handle) {
-            ALOGE("%s() the patch handle(%d) does not match recorded one(%d) for stream "
-                  "with handle(%d) when creating audio patch for mix->device",
-                  __func__, *handle, out->patch_handle, out->handle);
-            ret = -EINVAL;
-            pthread_mutex_unlock(&out->lock);
-            goto error;
-        }
-        pthread_mutex_lock(&out->lock);
-        for (out->num_devices = 0; out->num_devices < num_sinks; out->num_devices++) {
-            out->devices[out->num_devices] = sinks[out->num_devices].ext.device.type;
-        }
-        pthread_mutex_unlock(&out->lock);
-        out->patch_handle = *handle;
-    }
-
-error:
-    if (ret != 0 && generatedPatchHandle) {
-        *handle = AUDIO_PATCH_HANDLE_NONE;
-    }
-    pthread_mutex_unlock(&adev->lock);
-    return 0;
-}
-
-// This must be called with adev->lock held.
-struct generic_stream_out *get_stream_out_by_patch_handle_l(
-        struct generic_audio_device *adev, audio_patch_handle_t patch_handle) {
-    struct listnode *node;
-
-    list_for_each(node, &adev->out_streams) {
-        struct generic_stream_out *out = node_to_item(
-                node, struct generic_stream_out, stream_node);
-        if (out->patch_handle == patch_handle) {
-            return out;
-        }
-    }
-    return NULL;
-}
-
-// This must be called with adev->lock held.
-struct generic_stream_in *get_stream_in_by_patch_handle_l(
-        struct generic_audio_device *adev, audio_patch_handle_t patch_handle) {
-    struct listnode *node;
-
-    list_for_each(node, &adev->in_streams) {
-        struct generic_stream_in *in = node_to_item(
-                node, struct generic_stream_in, stream_node);
-        if (in->patch_handle == patch_handle) {
-            return in;
-        }
-    }
-    return NULL;
-}
-
-static int adev_release_audio_patch(struct audio_hw_device *dev,
-                                    audio_patch_handle_t patch_handle) {
-    struct generic_audio_device *adev = (struct generic_audio_device *) dev;
-
-    pthread_mutex_lock(&adev->lock);
-    struct generic_stream_out *out = get_stream_out_by_patch_handle_l(adev, patch_handle);
-    if (out != NULL) {
-        pthread_mutex_lock(&out->lock);
-        out->num_devices = 0;
-        memset(out->devices, 0, sizeof(out->devices));
-        pthread_mutex_unlock(&out->lock);
-        out->patch_handle = AUDIO_PATCH_HANDLE_NONE;
-        pthread_mutex_unlock(&adev->lock);
-        return 0;
-    }
-    struct generic_stream_in *in = get_stream_in_by_patch_handle_l(adev, patch_handle);
-    if (in != NULL) {
-        pthread_mutex_lock(&in->lock);
-        in->device = AUDIO_DEVICE_NONE;
-        pthread_mutex_unlock(&in->lock);
-        in->patch_handle = AUDIO_PATCH_HANDLE_NONE;
-        pthread_mutex_unlock(&adev->lock);
-        return 0;
-    }
-
-    pthread_mutex_unlock(&adev->lock);
-    ALOGW("%s() cannot find stream for patch handle: %d", __func__, patch_handle);
+error_1:
+    free(in);
     return -EINVAL;
 }
 
-static int adev_close(hw_device_t *dev)
+static void adev_close_input_stream(struct audio_hw_device *dev,
+        struct audio_stream_in *stream)
 {
-    struct generic_audio_device *adev = (struct generic_audio_device *)dev;
-    int ret = 0;
-    if (!adev)
-        return 0;
-
-    pthread_mutex_lock(&adev_init_lock);
-
-    if (audio_device_ref_count == 0) {
-        ALOGE("adev_close called when ref_count 0");
-        ret = -EINVAL;
-        goto error;
+    ALOGV("adev_close_input_stream...");
+    struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
+    if (is_aec_input(in)) {
+        destroy_aec_mic_config(in->dev->aec);
     }
+    free(stream);
+    return;
+}
 
-    if ((--audio_device_ref_count) == 0) {
-        if (adev->mixer) {
-            mixer_close(adev->mixer);
-        }
-        free(adev);
-    }
+static int adev_dump(const audio_hw_device_t *device, int fd)
+{
+    ALOGV("adev_dump");
+    return 0;
+}
 
-error:
-    pthread_mutex_unlock(&adev_init_lock);
-    return ret;
+static int adev_close(hw_device_t *device)
+{
+    ALOGV("adev_close");
+
+    struct alsa_audio_device *adev = (struct alsa_audio_device *)device;
+    release_aec(adev->aec);
+    audio_route_free(adev->audio_route);
+    mixer_close(adev->mixer);
+    free(device);
+    return 0;
 }
 
 static int adev_open(const hw_module_t* module, const char* name,
-                     hw_device_t** device)
+        hw_device_t** device)
 {
-    static struct generic_audio_device *adev;
+    ALOGV("adev_open: %s", name);
 
-    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
+    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
         return -EINVAL;
-
-    pthread_mutex_lock(&adev_init_lock);
-    if (audio_device_ref_count != 0) {
-        *device = &adev->device.common;
-        audio_device_ref_count++;
-        ALOGV("%s: returning existing instance of adev", __func__);
-        ALOGV("%s: exit", __func__);
-        goto unlock;
-    }
-    adev = calloc(1, sizeof(struct generic_audio_device));
-
-    pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL);
-
-    adev->device.common.tag = HARDWARE_DEVICE_TAG;
-    adev->device.common.version = AUDIO_DEVICE_API_VERSION_3_0;
-    adev->device.common.module = (struct hw_module_t *) module;
-    adev->device.common.close = adev_close;
-
-    adev->device.init_check = adev_init_check;               // no op
-    adev->device.set_voice_volume = adev_set_voice_volume;   // no op
-    adev->device.set_master_volume = adev_set_master_volume; // no op
-    adev->device.get_master_volume = adev_get_master_volume; // no op
-    adev->device.set_master_mute = adev_set_master_mute;     // no op
-    adev->device.get_master_mute = adev_get_master_mute;     // no op
-    adev->device.set_mode = adev_set_mode;                   // no op
-    adev->device.set_mic_mute = adev_set_mic_mute;
-    adev->device.get_mic_mute = adev_get_mic_mute;
-    adev->device.set_parameters = adev_set_parameters;       // no op
-    adev->device.get_parameters = adev_get_parameters;       // no op
-    adev->device.get_input_buffer_size = adev_get_input_buffer_size;
-    adev->device.open_output_stream = adev_open_output_stream;
-    adev->device.close_output_stream = adev_close_output_stream;
-    adev->device.open_input_stream = adev_open_input_stream;
-    adev->device.close_input_stream = adev_close_input_stream;
-    adev->device.dump = adev_dump;
-    adev->device.get_microphones = adev_get_microphones;
-    adev->device.create_audio_patch = adev_create_audio_patch;
-    adev->device.release_audio_patch = adev_release_audio_patch;
-
-    *device = &adev->device.common;
-
-    adev->next_patch_handle = AUDIO_PATCH_HANDLE_NONE;
-    list_init(&adev->out_streams);
-    list_init(&adev->in_streams);
-
-    adev->mixer = mixer_open(PCM_CARD);
-    struct mixer_ctl *ctl;
-
-    // Set default mixer ctls
-    // Enable channels and set volume
-    for (int i = 0; i < (int)mixer_get_num_ctls(adev->mixer); i++) {
-        ctl = mixer_get_ctl(adev->mixer, i);
-        ALOGD("mixer %d name %s", i, mixer_ctl_get_name(ctl));
-        if (!strcmp(mixer_ctl_get_name(ctl), "Master Playback Volume") ||
-            !strcmp(mixer_ctl_get_name(ctl), "Capture Volume")) {
-            for (int z = 0; z < (int)mixer_ctl_get_num_values(ctl); z++) {
-                ALOGD("set ctl %d to %d", z, 100);
-                mixer_ctl_set_percent(ctl, z, 100);
-            }
-            continue;
-        }
-        if (!strcmp(mixer_ctl_get_name(ctl), "Master Playback Switch") ||
-            !strcmp(mixer_ctl_get_name(ctl), "Capture Switch")) {
-            for (int z = 0; z < (int)mixer_ctl_get_num_values(ctl); z++) {
-                ALOGD("set ctl %d to %d", z, 1);
-                mixer_ctl_set_value(ctl, z, 1);
-            }
-            continue;
-        }
     }
 
-    audio_device_ref_count++;
+    struct alsa_audio_device* adev = calloc(1, sizeof(struct alsa_audio_device));
+    if (!adev) {
+        return -ENOMEM;
+    }
 
-unlock:
-    pthread_mutex_unlock(&adev_init_lock);
+    adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
+    adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
+    adev->hw_device.common.module = (struct hw_module_t *) module;
+    adev->hw_device.common.close = adev_close;
+    adev->hw_device.init_check = adev_init_check;
+    adev->hw_device.set_voice_volume = adev_set_voice_volume;
+    adev->hw_device.set_master_volume = adev_set_master_volume;
+    adev->hw_device.get_master_volume = adev_get_master_volume;
+    adev->hw_device.set_master_mute = adev_set_master_mute;
+    adev->hw_device.get_master_mute = adev_get_master_mute;
+    adev->hw_device.set_mode = adev_set_mode;
+    adev->hw_device.set_mic_mute = adev_set_mic_mute;
+    adev->hw_device.get_mic_mute = adev_get_mic_mute;
+    adev->hw_device.set_parameters = adev_set_parameters;
+    adev->hw_device.get_parameters = adev_get_parameters;
+    adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
+    adev->hw_device.open_output_stream = adev_open_output_stream;
+    adev->hw_device.close_output_stream = adev_close_output_stream;
+    adev->hw_device.open_input_stream = adev_open_input_stream;
+    adev->hw_device.close_input_stream = adev_close_input_stream;
+    adev->hw_device.dump = adev_dump;
+    adev->hw_device.get_microphones = adev_get_microphones;
+
+    *device = &adev->hw_device.common;
+
+    int out_card = get_audio_card(PCM_OUT, 0);
+    adev->mixer = mixer_open(out_card);
+    if (!adev->mixer) {
+        ALOGE("Unable to open the mixer, aborting.");
+        goto error_1;
+    }
+
+    adev->audio_route = audio_route_init(out_card, MIXER_XML_PATH);
+    if (!adev->audio_route) {
+        ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
+        goto error_2;
+    }
+
+    pthread_mutex_lock(&adev->lock);
+    if (init_aec(CAPTURE_CODEC_SAMPLING_RATE, NUM_AEC_REFERENCE_CHANNELS,
+                    CHANNEL_STEREO, &adev->aec)) {
+        pthread_mutex_unlock(&adev->lock);
+        goto error_3;
+    }
+    pthread_mutex_unlock(&adev->lock);
+
     return 0;
+
+error_3:
+    audio_route_free(adev->audio_route);
+error_2:
+    mixer_close(adev->mixer);
+error_1:
+    free(adev);
+    return -EINVAL;
 }
 
 static struct hw_module_methods_t hal_module_methods = {
@@ -1829,7 +1199,7 @@
         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
         .hal_api_version = HARDWARE_HAL_API_VERSION,
         .id = AUDIO_HARDWARE_MODULE_ID,
-        .name = "Generic audio HW HAL",
+        .name = "Yukawa audio HW HAL",
         .author = "The Android Open Source Project",
         .methods = &hal_module_methods,
     },
diff --git a/audio/audio_hw.h b/audio/audio_hw.h
new file mode 100644
index 0000000..2e45e02
--- /dev/null
+++ b/audio/audio_hw.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef _YUKAWA_AUDIO_HW_H_
+#define _YUKAWA_AUDIO_HW_H_
+
+#include <hardware/audio.h>
+#include <tinyalsa/asoundlib.h>
+
+#include "fir_filter.h"
+
+#define PORT_HDMI 0
+#define PORT_INTERNAL_SPEAKER 1
+#define PORT_BUILTIN_MIC 3
+
+#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml"
+/* Minimum granularity - Arbitrary but small value */
+#define CODEC_BASE_FRAME_COUNT 32
+
+#define CHANNEL_STEREO 2
+
+#ifdef AEC_HAL
+#define NUM_AEC_REFERENCE_CHANNELS 1
+#else
+/* App AEC uses 2-channel reference */
+#define NUM_AEC_REFERENCE_CHANNELS 2
+#endif /* #ifdef AEC_HAL */
+
+#define DEBUG_AEC 0
+
+#define PCM_OPEN_RETRIES 100
+#define PCM_OPEN_WAIT_TIME_MS 20
+
+/* Capture codec parameters */
+/* Set up a capture period of 32 ms:
+ * CAPTURE_PERIOD = PERIOD_SIZE / SAMPLE_RATE, so (32e-3) = PERIOD_SIZE / (16e3)
+ * => PERIOD_SIZE = 512 frames, where each "frame" consists of 1 sample of every channel (here, 2ch) */
+#define CAPTURE_PERIOD_MULTIPLIER 16
+#define CAPTURE_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * CAPTURE_PERIOD_MULTIPLIER)
+#define CAPTURE_PERIOD_COUNT 4
+#define CAPTURE_PERIOD_START_THRESHOLD 0
+#define CAPTURE_CODEC_SAMPLING_RATE 16000
+
+/* Playback codec parameters */
+/* number of base blocks in a short period (low latency) */
+#define PLAYBACK_PERIOD_MULTIPLIER 32  /* 21 ms */
+/* number of frames per short period (low latency) */
+#define PLAYBACK_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * PLAYBACK_PERIOD_MULTIPLIER)
+/* number of pseudo periods for low latency playback */
+#define PLAYBACK_PERIOD_COUNT 4
+#define PLAYBACK_PERIOD_START_THRESHOLD 2
+#define PLAYBACK_CODEC_SAMPLING_RATE 48000
+#define MIN_WRITE_SLEEP_US      5000
+
+#define SPEAKER_EQ_FILE "/vendor/etc/speaker_eq.fir"
+#define SPEAKER_MAX_EQ_LENGTH 512
+
+struct alsa_audio_device {
+    struct audio_hw_device hw_device;
+
+    pthread_mutex_t lock;   /* see notes in in_read/out_write on mutex acquisition order */
+    struct alsa_stream_in *active_input;
+    struct alsa_stream_out *active_output;
+    struct audio_route *audio_route;
+    struct mixer *mixer;
+    bool mic_mute;
+    struct aec_t *aec;
+};
+
+struct alsa_stream_in {
+    struct audio_stream_in stream;
+
+    pthread_mutex_t lock;   /* see note in in_read() on mutex acquisition order */
+    audio_devices_t devices;
+    struct pcm_config config;
+    struct pcm *pcm;
+    bool unavailable;
+    bool standby;
+    struct alsa_audio_device *dev;
+    int read_threshold;
+    unsigned int frames_read;
+    uint64_t timestamp_nsec;
+    audio_source_t source;
+};
+
+struct alsa_stream_out {
+    struct audio_stream_out stream;
+
+    pthread_mutex_t lock;   /* see note in out_write() on mutex acquisition order */
+    audio_devices_t devices;
+    struct pcm_config config;
+    struct pcm *pcm;
+    bool unavailable;
+    int standby;
+    struct alsa_audio_device *dev;
+    int write_threshold;
+    unsigned int frames_written;
+    struct timespec timestamp;
+    fir_filter_t* speaker_eq;
+};
+
+/* 'bytes' are the number of bytes written to audio FIFO, for which 'timestamp' is valid.
+ * 'available' is the number of frames available to read (for input) or yet to be played
+ * (for output) frames in the PCM buffer.
+ * timestamp and available are updated by pcm_get_htimestamp(), so they use the same
+ * datatypes as the corresponding arguments to that function. */
+struct aec_info {
+    struct timespec timestamp;
+    uint64_t timestamp_usec;
+    unsigned int available;
+    size_t bytes;
+};
+
+#endif /* #ifndef _YUKAWA_AUDIO_HW_H_ */
diff --git a/audio/fifo_wrapper.cpp b/audio/fifo_wrapper.cpp
new file mode 100644
index 0000000..7bc9079
--- /dev/null
+++ b/audio/fifo_wrapper.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "audio_utils_fifo_wrapper"
+// #define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <errno.h>
+#include <log/log.h>
+#include <audio_utils/fifo.h>
+#include "fifo_wrapper.h"
+
+struct audio_fifo_itfe {
+    audio_utils_fifo *p_fifo;
+    audio_utils_fifo_reader *p_fifo_reader;
+    audio_utils_fifo_writer *p_fifo_writer;
+    int8_t *p_buffer;
+};
+
+void *fifo_init(uint32_t bytes, bool reader_throttles_writer) {
+    struct audio_fifo_itfe *interface = new struct audio_fifo_itfe;
+    interface->p_buffer = new int8_t[bytes];
+    if (interface->p_buffer == NULL) {
+        ALOGE("Failed to allocate fifo buffer!");
+        return NULL;
+    }
+    interface->p_fifo = new audio_utils_fifo(bytes, 1, interface->p_buffer, reader_throttles_writer);
+    interface->p_fifo_writer = new audio_utils_fifo_writer(*interface->p_fifo);
+    interface->p_fifo_reader = new audio_utils_fifo_reader(*interface->p_fifo);
+
+    return (void *)interface;
+}
+
+void fifo_release(void *fifo_itfe) {
+    struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
+    delete interface->p_fifo_writer;
+    delete interface->p_fifo_reader;
+    delete interface->p_fifo;
+    delete[] interface->p_buffer;
+    delete interface;
+}
+
+ssize_t fifo_read(void *fifo_itfe, void *buffer, size_t bytes) {
+    struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
+    return interface->p_fifo_reader->read(buffer, bytes);
+}
+
+ssize_t fifo_write(void *fifo_itfe, void *buffer, size_t bytes) {
+    struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
+    return interface->p_fifo_writer->write(buffer, bytes);
+}
+
+ssize_t fifo_available_to_read(void *fifo_itfe) {
+    struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
+    return interface->p_fifo_reader->available();
+}
+
+ssize_t fifo_available_to_write(void *fifo_itfe) {
+    struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
+    return interface->p_fifo_writer->available();
+}
+
+ssize_t fifo_flush(void *fifo_itfe) {
+    struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
+    return interface->p_fifo_reader->flush();
+}
diff --git a/audio/fifo_wrapper.h b/audio/fifo_wrapper.h
new file mode 100644
index 0000000..e9469ef
--- /dev/null
+++ b/audio/fifo_wrapper.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef _AUDIO_FIFO_WRAPPER_H_
+#define _AUDIO_FIFO_WRAPPER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *fifo_init(uint32_t bytes, bool reader_throttles_writer);
+void fifo_release(void *fifo_itfe);
+ssize_t fifo_read(void *fifo_itfe, void *buffer, size_t bytes);
+ssize_t fifo_write(void *fifo_itfe, void *buffer, size_t bytes);
+ssize_t fifo_available_to_read(void *fifo_itfe);
+ssize_t fifo_available_to_write(void *fifo_itfe);
+ssize_t fifo_flush(void *fifo_itfe);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* #ifndef _AUDIO_FIFO_WRAPPER_H_ */
diff --git a/audio/fir_filter.c b/audio/fir_filter.c
new file mode 100644
index 0000000..c648fc0
--- /dev/null
+++ b/audio/fir_filter.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "audio_hw_fir_filter"
+//#define LOG_NDEBUG 0
+
+#include <assert.h>
+#include <audio_utils/primitives.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <log/log.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "fir_filter.h"
+
+#ifdef __ARM_NEON
+#include "arm_neon.h"
+#endif /* #ifdef __ARM_NEON */
+
+fir_filter_t* fir_init(uint32_t channels, fir_filter_mode_t mode, uint32_t filter_length,
+                       uint32_t input_length, int16_t* coeffs) {
+    if ((channels == 0) || (filter_length == 0) || (coeffs == NULL)) {
+        ALOGE("%s: Invalid channel count, filter length or coefficient array.", __func__);
+        return NULL;
+    }
+
+    fir_filter_t* fir = (fir_filter_t*)calloc(1, sizeof(fir_filter_t));
+    if (fir == NULL) {
+        ALOGE("%s: Unable to allocate memory for fir_filter.", __func__);
+        return NULL;
+    }
+
+    fir->channels = channels;
+    fir->filter_length = filter_length;
+    /* Default: same filter coeffs for all channels */
+    fir->mode = FIR_SINGLE_FILTER;
+    uint32_t coeff_bytes = fir->filter_length * sizeof(int16_t);
+    if (mode == FIR_PER_CHANNEL_FILTER) {
+        fir->mode = FIR_PER_CHANNEL_FILTER;
+        coeff_bytes = fir->filter_length * fir->channels * sizeof(int16_t);
+    }
+
+    fir->coeffs = (int16_t*)malloc(coeff_bytes);
+    if (fir->coeffs == NULL) {
+        ALOGE("%s: Unable to allocate memory for FIR coeffs", __func__);
+        goto exit_1;
+    }
+    memcpy(fir->coeffs, coeffs, coeff_bytes);
+
+    fir->buffer_size = (input_length + fir->filter_length) * fir->channels;
+    fir->state = (int16_t*)malloc(fir->buffer_size * sizeof(int16_t));
+    if (fir->state == NULL) {
+        ALOGE("%s: Unable to allocate memory for FIR state", __func__);
+        goto exit_2;
+    }
+
+#ifdef __ARM_NEON
+    ALOGI("%s: Using ARM Neon", __func__);
+#endif /* #ifdef __ARM_NEON */
+
+    fir_reset(fir);
+    return fir;
+
+exit_2:
+    free(fir->coeffs);
+exit_1:
+    free(fir);
+    return NULL;
+}
+
+void fir_release(fir_filter_t* fir) {
+    if (fir == NULL) {
+        return;
+    }
+    free(fir->state);
+    free(fir->coeffs);
+    free(fir);
+}
+
+void fir_reset(fir_filter_t* fir) {
+    if (fir == NULL) {
+        return;
+    }
+    memset(fir->state, 0, fir->buffer_size * sizeof(int16_t));
+}
+
+void fir_process_interleaved(fir_filter_t* fir, int16_t* input, int16_t* output, uint32_t samples) {
+    assert(fir != NULL);
+
+    int start_offset = (fir->filter_length - 1) * fir->channels;
+    memcpy(&fir->state[start_offset], input, samples * fir->channels * sizeof(int16_t));
+    // int ch;
+    bool use_2nd_set_coeffs = (fir->channels > 1) && (fir->mode == FIR_PER_CHANNEL_FILTER);
+    int16_t* p_coeff_A = &fir->coeffs[0];
+    int16_t* p_coeff_B = use_2nd_set_coeffs ? &fir->coeffs[fir->filter_length] : &fir->coeffs[0];
+    int16_t* p_output;
+    for (int ch = 0; ch < fir->channels; ch += 2) {
+        p_output = &output[ch];
+        int offset = start_offset + ch;
+        for (int s = 0; s < samples; s++) {
+            int32_t acc_A = 0;
+            int32_t acc_B = 0;
+
+#ifdef __ARM_NEON
+            int32x4_t acc_vec = vdupq_n_s32(0);
+            for (int k = 0; k < fir->filter_length; k++, offset -= fir->channels) {
+                int16x4_t coeff_vec = vdup_n_s16(p_coeff_A[k]);
+                coeff_vec = vset_lane_s16(p_coeff_B[k], coeff_vec, 1);
+                int16x4_t input_vec = vld1_s16(&fir->state[offset]);
+                acc_vec = vmlal_s16(acc_vec, coeff_vec, input_vec);
+            }
+            acc_A = vgetq_lane_s32(acc_vec, 0);
+            acc_B = vgetq_lane_s32(acc_vec, 1);
+#else
+            for (int k = 0; k < fir->filter_length; k++, offset -= fir->channels) {
+                int32_t input_A = (int32_t)(fir->state[offset]);
+                int32_t coeff_A = (int32_t)(p_coeff_A[k]);
+                int32_t input_B = (int32_t)(fir->state[offset + 1]);
+                int32_t coeff_B = (int32_t)(p_coeff_B[k]);
+                acc_A += (input_A * coeff_A);
+                acc_B += (input_B * coeff_B);
+            }
+#endif /* #ifdef __ARM_NEON */
+
+            *p_output = clamp16(acc_A >> 15);
+            if (ch < fir->channels - 1) {
+                *(p_output + 1) = clamp16(acc_B >> 15);
+            }
+            /* Move to next sample */
+            p_output += fir->channels;
+            offset += (fir->filter_length + 1) * fir->channels;
+        }
+        if (use_2nd_set_coeffs) {
+            p_coeff_A += (fir->filter_length << 1);
+            p_coeff_B += (fir->filter_length << 1);
+        }
+    }
+    memmove(fir->state, &fir->state[samples * fir->channels],
+            (fir->filter_length - 1) * fir->channels * sizeof(int16_t));
+}
diff --git a/audio/fir_filter.h b/audio/fir_filter.h
new file mode 100644
index 0000000..d8c6e91
--- /dev/null
+++ b/audio/fir_filter.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef FIR_FILTER_H
+#define FIR_FILTER_H
+
+#include <stdint.h>
+
+typedef enum fir_filter_mode { FIR_SINGLE_FILTER = 0, FIR_PER_CHANNEL_FILTER } fir_filter_mode_t;
+
+typedef struct fir_filter {
+    fir_filter_mode_t mode;
+    uint32_t channels;
+    uint32_t filter_length;
+    uint32_t buffer_size;
+    int16_t* coeffs;
+    int16_t* state;
+} fir_filter_t;
+
+fir_filter_t* fir_init(uint32_t channels, fir_filter_mode_t mode, uint32_t filter_length,
+                       uint32_t input_length, int16_t* coeffs);
+void fir_release(fir_filter_t* fir);
+void fir_reset(fir_filter_t* fir);
+void fir_process_interleaved(fir_filter_t* fir, int16_t* input, int16_t* output, uint32_t samples);
+
+#endif /* #ifndef FIR_FILTER_H */
diff --git a/compatibility_matrix.xml b/compatibility_matrix.xml
index 3082485..f10b6bd 100644
--- a/compatibility_matrix.xml
+++ b/compatibility_matrix.xml
@@ -1,13 +1,5 @@
 <compatibility-matrix version="1.0" type="device">
     <hal format="hidl" optional="false">
-        <name>android.frameworks.schedulerservice</name>
-        <version>1.0</version>
-        <interface>
-            <name>ISchedulingPolicyService</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
         <name>android.frameworks.sensorservice</name>
         <version>1.0</version>
         <interface>
diff --git a/db845c.mk b/db845c.mk
index df377f7..b2dd524 100644
--- a/db845c.mk
+++ b/db845c.mk
@@ -1,5 +1,5 @@
 ifndef TARGET_KERNEL_USE
-TARGET_KERNEL_USE := 5.4
+TARGET_KERNEL_USE := 5.10
 endif
 DB845C_KERNEL_DIR ?= device/linaro/dragonboard-kernel/android-$(TARGET_KERNEL_USE)
 
@@ -21,8 +21,6 @@
 ifeq ($(DB845C_USES_GKI), true)
   DB845C_MODS := $(wildcard $(DB845C_KERNEL_DIR)/*.ko)
   ifneq ($(DB845C_MODS),)
-    BOARD_VENDOR_KERNEL_MODULES += $(DB845C_MODS)
-    DB845C_ONLY_VENDOR := %/msm.ko
-    BOARD_VENDOR_RAMDISK_KERNEL_MODULES := $(filter-out $(DB845C_ONLY_VENDOR),$(DB845C_MODS))
+    BOARD_VENDOR_RAMDISK_KERNEL_MODULES := $(DB845C_MODS)
   endif
 endif
diff --git a/db845c/BoardConfig.mk b/db845c/BoardConfig.mk
index 9d31f97..d668719 100644
--- a/db845c/BoardConfig.mk
+++ b/db845c/BoardConfig.mk
@@ -6,10 +6,16 @@
 
 TARGET_NO_KERNEL := false
 BOARD_INCLUDE_DTB_IN_BOOTIMG := true
-BOARD_BOOT_HEADER_VERSION := 2
+ifeq ($(TARGET_USES_BOOT_HDR_V3), true)
+ BOARD_BOOT_HEADER_VERSION := 3
+ BOARD_KERNEL_PAGESIZE := 4096
+ BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE := 67108864 #64M
+else
+ BOARD_BOOT_HEADER_VERSION := 2
+ BOARD_KERNEL_PAGESIZE := 2048
+endif
 BOARD_MKBOOTIMG_ARGS := --header_version $(BOARD_BOOT_HEADER_VERSION)
 BOARD_KERNEL_BASE := 0x80000000
-BOARD_KERNEL_PAGESIZE := 2048
 BOARD_KERNEL_CMDLINE := earlycon firmware_class.path=/vendor/firmware/ androidboot.hardware=db845c
 BOARD_KERNEL_CMDLINE += init=/init androidboot.boot_devices=soc@0/1d84000.ufshc printk.devkmsg=on
 BOARD_KERNEL_CMDLINE += deferred_probe_timeout=30
@@ -20,6 +26,6 @@
 BOARD_FLASH_BLOCK_SIZE := 512
 # Super partition
 BOARD_SUPER_PARTITION_SIZE := 12437225472
-BOARD_DB_DYNAMIC_PARTITIONS_SIZE := 12437225472
+BOARD_DB_DYNAMIC_PARTITIONS_SIZE := 12433031168 # Reserve 4M for DAP metadata
 BOARD_SUPER_PARTITION_METADATA_DEVICE := super
 BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE := true
diff --git a/db845c/device.mk b/db845c/device.mk
index c6825a3..502b0fe 100644
--- a/db845c/device.mk
+++ b/db845c/device.mk
@@ -20,6 +20,20 @@
 # setup dalvik vm configs
 $(call inherit-product, frameworks/native/build/tablet-10in-xhdpi-2048-dalvik-heap.mk)
 
+# Enable Virtual A/B
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS += \
+    product \
+    system \
+    system_ext \
+    vendor
+
+ifeq ($(TARGET_USES_BOOT_HDR_V3), true)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk)
+else
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
+endif
+
 PRODUCT_COPY_FILES := \
     $(DB845C_KERNEL_DIR)/Image.gz:kernel \
     $(DB845C_KERNEL_DIR)/sdm845-db845c.dtb:dtb.img \
@@ -32,6 +46,12 @@
 # Build generic Audio HAL
 PRODUCT_PACKAGES := audio.primary.db845c
 
+# BootControl HAL
+PRODUCT_PACKAGES += \
+    android.hardware.boot@1.2-impl \
+    android.hardware.boot@1.2-impl.recovery \
+    android.hardware.boot@1.2-service
+
 PRODUCT_PACKAGES += \
     pd-mapper \
     qrtr-ns \
@@ -41,6 +61,7 @@
     tqftpserv
 
 PRODUCT_COPY_FILES += \
+    device/linaro/dragonboard/qcom/set_udc.sh:$(TARGET_COPY_OUT_VENDOR)/bin/set_udc.sh \
     device/linaro/dragonboard/qcom/init.qcom.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.qcom.rc
 
 # Install scripts to set Ethernet MAC address
@@ -48,5 +69,10 @@
     $(LOCAL_PATH)/eth_mac_addr.rc:/system/etc/init/eth_mac_addr.rc \
     $(LOCAL_PATH)/eth_mac_addr.sh:/system/bin/eth_mac_addr.sh
 
+PRODUCT_VENDOR_PROPERTIES += ro.soc.manufacturer=Qualcomm
+PRODUCT_VENDOR_PROPERTIES += ro.soc.model=SDM845
+
+PRODUCT_PROPERTY_OVERRIDES += ro.sf.lcd_density=160
+
 # Copy firmware files
 $(call inherit-product-if-exists, $(LOCAL_PATH)/firmware/device.mk)
diff --git a/db845c/firmware/Android.mk b/db845c/firmware/Android.mk
index 6c3dc4b..48fa451 100644
--- a/db845c/firmware/Android.mk
+++ b/db845c/firmware/Android.mk
@@ -15,7 +15,8 @@
     a630_zap.b01	\
     a630_zap.b02	\
     a630_zap.elf	\
-    a630_zap.mdt
+    a630_zap.mdt	\
+    a630_zap.mbn
 
 # DSP (adsp+cdsp)
 sdm845_firmware_files +=	\
@@ -34,6 +35,8 @@
     adsp.b12		\
     adsp.b13		\
     adsp.mdt		\
+    adsp.mbn		\
+    adspr.jsn		\
     adspua.jsn		\
     cdsp.b00		\
     cdsp.b01		\
@@ -43,7 +46,10 @@
     cdsp.b05		\
     cdsp.b06		\
     cdsp.b08		\
-    cdsp.mdt
+    cdsp.mdt		\
+    cdsp.mbn		\
+    cdspr.jsn		\
+
 
 # USB
 firmware_files +=	\
diff --git a/db845c/firmware/a630_sqe.fw b/db845c/firmware/a630_sqe.fw
index e0576f7..4e2937d 100644
--- a/db845c/firmware/a630_sqe.fw
+++ b/db845c/firmware/a630_sqe.fw
Binary files differ
diff --git a/db845c/firmware/a630_zap.mbn b/db845c/firmware/a630_zap.mbn
new file mode 100644
index 0000000..9e6f2ad
--- /dev/null
+++ b/db845c/firmware/a630_zap.mbn
Binary files differ
diff --git a/db845c/firmware/adsp.mbn b/db845c/firmware/adsp.mbn
new file mode 100644
index 0000000..271da7f
--- /dev/null
+++ b/db845c/firmware/adsp.mbn
Binary files differ
diff --git a/db845c/firmware/adspr.jsn b/db845c/firmware/adspr.jsn
new file mode 100644
index 0000000..0964c15
--- /dev/null
+++ b/db845c/firmware/adspr.jsn
@@ -0,0 +1,21 @@
+{
+    "sr_version": {
+        "major": 1,
+        "minor": 1,
+        "patch": 1
+    },
+    "sr_domain": {
+        "soc": "msm",
+        "domain": "adsp",
+        "subdomain": "root_pd",
+        "qmi_instance_id": 74
+    },
+    "sr_service": [
+        {
+            "provider": "tms",
+            "service": "servreg",
+            "service_data_valid": 0,
+            "service_data": 0
+        }
+    ]
+}
\ No newline at end of file
diff --git a/db845c/firmware/adspua.jsn b/db845c/firmware/adspua.jsn
index e75e83f..2d6824e 100644
--- a/db845c/firmware/adspua.jsn
+++ b/db845c/firmware/adspua.jsn
@@ -24,4 +24,4 @@
             "service_data": 0
         }
     ]
-}
+}
\ No newline at end of file
diff --git a/db845c/firmware/cdsp.mbn b/db845c/firmware/cdsp.mbn
new file mode 100644
index 0000000..a115cc8
--- /dev/null
+++ b/db845c/firmware/cdsp.mbn
Binary files differ
diff --git a/db845c/firmware/cdspr.jsn b/db845c/firmware/cdspr.jsn
new file mode 100644
index 0000000..5d976a6
--- /dev/null
+++ b/db845c/firmware/cdspr.jsn
@@ -0,0 +1,21 @@
+{
+    "sr_version": {
+        "major": 1,
+        "minor": 1,
+        "patch": 1
+    },
+    "sr_domain": {
+        "soc": "msm",
+        "domain": "cdsp",
+        "subdomain": "root_pd",
+        "qmi_instance_id": 76
+    },
+    "sr_service": [
+        {
+            "provider": "tms",
+            "service": "servreg",
+            "service_data_valid": 0,
+            "service_data": 0
+        }
+    ]
+}
\ No newline at end of file
diff --git a/db845c/firmware/device.mk b/db845c/firmware/device.mk
index 78a1d8f..e99a32f 100644
--- a/db845c/firmware/device.mk
+++ b/db845c/firmware/device.mk
@@ -9,7 +9,8 @@
     a630_zap.b01	\
     a630_zap.b02	\
     a630_zap.elf	\
-    a630_zap.mdt
+    a630_zap.mdt	\
+    a630_zap.mbn
 
 # DSP (adsp+cdsp)
 PRODUCT_PACKAGES +=	\
@@ -28,6 +29,8 @@
     adsp.b12		\
     adsp.b13		\
     adsp.mdt		\
+    adsp.mbn		\
+    adspr.jsn		\
     adspua.jsn		\
     cdsp.b00		\
     cdsp.b01		\
@@ -37,7 +40,9 @@
     cdsp.b05		\
     cdsp.b06		\
     cdsp.b08		\
-    cdsp.mdt
+    cdsp.mdt		\
+    cdsp.mbn		\
+    cdspr.jsn
 
 # USB (USB Host to PCIE)
 # For Ethernet and one of the USB-A host port to work
@@ -62,7 +67,8 @@
     venus.b02		\
     venus.b03		\
     venus.b04		\
-    venus.mdt
+    venus.mdt		\
+    venus.mbn
 
 # Wlan
 PRODUCT_PACKAGES +=	\
diff --git a/db845c/firmware/modemuw.jsn b/db845c/firmware/modemuw.jsn
index 4322190..88a400e 100644
--- a/db845c/firmware/modemuw.jsn
+++ b/db845c/firmware/modemuw.jsn
@@ -30,4 +30,4 @@
             "service_data": 0
         }
     ]
-}
+}
\ No newline at end of file
diff --git a/db845c/firmware/qcom/venus-5.2/Android.mk b/db845c/firmware/qcom/venus-5.2/Android.mk
index 4047e15..00146a5 100644
--- a/db845c/firmware/qcom/venus-5.2/Android.mk
+++ b/db845c/firmware/qcom/venus-5.2/Android.mk
@@ -8,6 +8,7 @@
     venus.b02		\
     venus.b03		\
     venus.b04		\
-    venus.mdt
+    venus.mdt		\
+    venus.mbn
 
 $(foreach f, $(firmware_files_venus), $(call add-qcom-firmware, $(f), $(TARGET_OUT_VENDOR)/firmware/qcom/venus-5.2/))
diff --git a/db845c/firmware/qcom/venus-5.2/venus.b00 b/db845c/firmware/qcom/venus-5.2/venus.b00
index 41b63be..96c1762 100644
--- a/db845c/firmware/qcom/venus-5.2/venus.b00
+++ b/db845c/firmware/qcom/venus-5.2/venus.b00
Binary files differ
diff --git a/db845c/firmware/qcom/venus-5.2/venus.b01 b/db845c/firmware/qcom/venus-5.2/venus.b01
index a9bae79..cb335f3 100644
--- a/db845c/firmware/qcom/venus-5.2/venus.b01
+++ b/db845c/firmware/qcom/venus-5.2/venus.b01
Binary files differ
diff --git a/db845c/firmware/qcom/venus-5.2/venus.b02 b/db845c/firmware/qcom/venus-5.2/venus.b02
index 22052a0..02a4409 100644
--- a/db845c/firmware/qcom/venus-5.2/venus.b02
+++ b/db845c/firmware/qcom/venus-5.2/venus.b02
Binary files differ
diff --git a/db845c/firmware/qcom/venus-5.2/venus.b03 b/db845c/firmware/qcom/venus-5.2/venus.b03
index 2ad2108..e5ff59d 100644
--- a/db845c/firmware/qcom/venus-5.2/venus.b03
+++ b/db845c/firmware/qcom/venus-5.2/venus.b03
Binary files differ
diff --git a/db845c/firmware/qcom/venus-5.2/venus.mbn b/db845c/firmware/qcom/venus-5.2/venus.mbn
new file mode 100644
index 0000000..0ea5feb
--- /dev/null
+++ b/db845c/firmware/qcom/venus-5.2/venus.mbn
Binary files differ
diff --git a/db845c/firmware/qcom/venus-5.2/venus.mdt b/db845c/firmware/qcom/venus-5.2/venus.mdt
index 3e39973..557cf8b 100644
--- a/db845c/firmware/qcom/venus-5.2/venus.mdt
+++ b/db845c/firmware/qcom/venus-5.2/venus.mdt
Binary files differ
diff --git a/device-common.mk b/device-common.mk
index 6fffd07..dec2c72 100644
--- a/device-common.mk
+++ b/device-common.mk
@@ -23,7 +23,7 @@
 # Build and run only ART
 PRODUCT_RUNTIMES := runtime_libart_default
 
-PRODUCT_SHIPPING_API_LEVEL := 29
+PRODUCT_SHIPPING_API_LEVEL := 31
 PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := false
 
 # Enable Scoped Storage related
@@ -44,27 +44,34 @@
 
 # Display
 PRODUCT_PACKAGES += \
-    android.hardware.drm@1.0-impl \
-    android.hardware.drm@1.0-service \
-    android.hardware.graphics.allocator@2.0-impl \
-    android.hardware.graphics.allocator@2.0-service \
-    android.hardware.graphics.composer@2.2-impl \
-    android.hardware.graphics.composer@2.2-service \
-    android.hardware.graphics.mapper@2.0-impl-2.1 \
-    gralloc.gbm \
-    hwcomposer.drm \
+    android.hardware.drm@1.3-service.clearkey \
+    android.hardware.drm@1.3-service.widevine \
     libGLES_mesa
 
 PRODUCT_PROPERTY_OVERRIDES += \
-    ro.hardware.gralloc=gbm \
+    ro.hardware.gralloc=minigbm_msm \
     ro.hardware.hwcomposer=drm \
-    debug.sf.no_hw_vsync=1 \
-    hwc.drm.use_framebuffer_target=1 \
-    hwc.drm.use_overlay_planes=0 \
-    ro.sf.lcd_density=160 \
     ro.opengles.version=196608 \
     persist.demo.rotationlock=1
 
+
+#
+# Hardware Composer HAL
+#
+PRODUCT_PACKAGES += \
+    hwcomposer.drm \
+    android.hardware.graphics.composer@2.3-impl \
+    android.hardware.graphics.composer@2.3-service
+
+#
+# Gralloc HAL
+#
+PRODUCT_PACKAGES += \
+    gralloc.minigbm_msm \
+    android.hardware.graphics.allocator@4.0-service.minigbm_msm \
+    android.hardware.graphics.mapper@4.0-impl.minigbm_msm
+
+
 # Use Launcher3QuickStep
 PRODUCT_PACKAGES += Launcher3QuickStep
 
@@ -74,8 +81,7 @@
     libwpa_client \
     wpa_supplicant \
     wpa_supplicant.conf \
-    wificond \
-    wifilogd
+    wificond
 
 PRODUCT_PROPERTY_OVERRIDES += \
     wifi.interface=wlan0 \
@@ -95,12 +101,25 @@
     frameworks/native/data/etc/android.hardware.bluetooth.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.bluetooth.xml \
     frameworks/native/data/etc/android.hardware.bluetooth_le.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.bluetooth_le.xml
 
+#
+# Power HAL
+#
+PRODUCT_PACKAGES += \
+    android.hardware.power-service.example
+
+#
+# PowerStats HAL
+#
+PRODUCT_PACKAGES += \
+    android.hardware.power.stats-service.example
+
+
 # Audio
 PRODUCT_PACKAGES += \
-    android.hardware.audio@4.0-impl:32 \
-    android.hardware.audio.effect@4.0-impl:32 \
-    android.hardware.audio@2.0-service \
-    android.hardware.soundtrigger@2.0-impl \
+    android.hardware.audio.service \
+    android.hardware.audio@7.0-impl \
+    android.hardware.audio.effect@7.0-impl \
+    android.hardware.soundtrigger@2.3-impl \
     android.hardware.bluetooth.audio@2.0-impl
 
 # Build default bluetooth a2dp and usb audio HALs
@@ -120,6 +139,7 @@
 # audio policy configuration
 USE_XML_AUDIO_POLICY_CONF := 1
 PRODUCT_COPY_FILES += \
+    $(LOCAL_PATH)/etc/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
     $(LOCAL_PATH)/etc/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(LOCAL_PATH)/etc/audio_policy_configuration_bluetooth_legacy_hal.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration_bluetooth_legacy_hal.xml \
     frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
@@ -139,17 +159,23 @@
     frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_audio.xml
 
 PRODUCT_COPY_FILES += \
+    $(LOCAL_PATH)/seccomp_policy/mediaswcodec.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/mediacodec.policy \
     $(LOCAL_PATH)/seccomp_policy/mediaswcodec.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/mediaswcodec.policy
 
 # Copy hardware config file(s)
 PRODUCT_COPY_FILES +=  \
         device/linaro/dragonboard/etc/permissions/android.software.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.xml
 
-# Memtrack
+
+# External Web Cam support
 PRODUCT_PACKAGES += \
-    memtrack.default \
-    android.hardware.memtrack@1.0-service \
-    android.hardware.memtrack@1.0-impl
+	android.hardware.camera.provider@2.4-impl \
+	android.hardware.camera.provider@2.4-external-service
+
+PRODUCT_COPY_FILES += \
+    frameworks/native/data/etc/android.hardware.camera.front.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.front.xml \
+    $(LOCAL_PATH)/etc/media_profiles.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml \
+    $(LOCAL_PATH)/etc/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml
 
 # Keymaster
 PRODUCT_PACKAGES += \
@@ -162,8 +188,12 @@
 
 # Health
 PRODUCT_PACKAGES += \
-    android.hardware.health@2.0-service \
-    android.hardware.health@2.0-impl
+    android.hardware.health@2.1-impl-cuttlefish \
+    android.hardware.health@2.1-service
+
+# TODO: disable this service once we implement system suspend
+PRODUCT_PACKAGES += \
+    suspend_blocker
 
 # mkbootimg host tool to build boot.img separately
 PRODUCT_HOST_PACKAGES := \
diff --git a/etc/audio_policy_configuration.xml b/etc/audio_policy_configuration.xml
index c94718e..fec99cc 100644
--- a/etc/audio_policy_configuration.xml
+++ b/etc/audio_policy_configuration.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2019 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.
@@ -15,15 +15,40 @@
 -->
 
 <audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
 
-    <globalConfiguration speaker_drc_enabled="false"/>
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="true"/>
 
+
+    <!-- Modules section:
+        There is one section per audio HW module present on the platform.
+        Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
+        The module names are the same as in current .conf file:
+                “primary”, “A2DP”, “remote_submix”, “USB”
+        Each module will contain the following sections:
+        “devicePorts”: a list of device descriptors for all input and output devices accessible via this
+        module.
+        This contains both permanently attached devices and removable devices.
+        “mixPorts”: listing all output and input streams exposed by the audio HAL
+        “routes”: list of possible connections between input and output devices or between stream and
+        devices.
+            "route": is defined by an attribute:
+                -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
+                -"sink": the sink involved in this route
+                -"sources": all the sources than can be connected to the sink via vis route
+        “attachedDevices”: permanently attached devices.
+        The attachedDevices section is a list of devices names. The names correspond to device names
+        defined in <devicePorts> section.
+        “defaultOutputDevice”: device to be used by default when no policy rule applies
+    -->
     <modules>
         <!-- Primary Audio HAL -->
-        <module name="primary" halVersion="2.0">
+        <module name="primary" halVersion="3.0">
             <attachedDevices>
                 <item>Speaker</item>
                 <item>Built-In Mic</item>
+                <item>Echo Reference</item>
             </attachedDevices>
             <defaultOutputDevice>Speaker</defaultOutputDevice>
             <mixPorts>
@@ -36,10 +61,17 @@
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                 </mixPort>
+                <mixPort name="echo reference" role="sink">
+                    <profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="48000"
+                             channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
             </mixPorts>
             <devicePorts>
                 <!-- Output devices declaration, i.e. Sink DEVICE PORT -->
-                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER">
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
                 </devicePort>
@@ -49,10 +81,6 @@
                 </devicePort>
                 <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
                 </devicePort>
-                <devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
-                </devicePort>
-                <devicePort tagName="Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
-                </devicePort>
 
                 <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
                 </devicePort>
@@ -60,6 +88,11 @@
                 </devicePort>
                 <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
                 </devicePort>
+                <devicePort tagName="Echo Reference" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
+                    <profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="48000"
+                             channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
             </devicePorts>
             <!-- route declaration, i.e. list all available sources for a given sink -->
             <routes>
@@ -69,16 +102,14 @@
                        sources="primary output"/>
                 <route type="mix" sink="Wired Headphones"
                        sources="primary output"/>
-                <route type="mix" sink="Aux Digital"
-                       sources="primary output"/>
                 <route type="mix" sink="BT SCO"
                        sources="primary output"/>
                 <route type="mix" sink="BT SCO Headset"
                        sources="primary output"/>
-                <route type="mix" sink="BT SCO Car Kit"
-                       sources="primary output"/>
                 <route type="mix" sink="primary input"
                        sources="Built-In Mic,Wired Headset Mic,BT SCO Headset Mic"/>
+                <route type="mix" sink="echo reference"
+                       sources="Echo Reference"/>
             </routes>
 
         </module>
diff --git a/etc/external_camera_config.xml b/etc/external_camera_config.xml
new file mode 100644
index 0000000..991ff40
--- /dev/null
+++ b/etc/external_camera_config.xml
@@ -0,0 +1,28 @@
+<ExternalCamera>
+    <Provider>
+        <ignore> <!-- Internal video devices to be ignored by external camera HAL -->
+        </ignore>
+    </Provider>
+    <!-- See ExternalCameraUtils.cpp for default values of Device configurations below -->
+    <Device>
+        <!-- Max JPEG buffer size in bytes-->
+        <MaxJpegBufferSize bytes="3145728"/> <!-- 3MB (~= 1080p YUV420) -->
+        <!-- Size of v4l2 buffer queue when streaming >= 30fps -->
+        <!-- Larger value: more request can be cached pipeline (less janky)  -->
+        <!-- Smaller value: use less memory -->
+        <NumVideoBuffers count="4"/>
+        <!-- Size of v4l2 buffer queue when streaming < 30fps -->
+        <NumStillBuffers count="2"/>
+
+        <!-- List of maximum fps for various output sizes -->
+        <!-- Any image size smaller than the size listed in Limit row will report
+            fps (as minimum frame duration) up to the fpsBound value. -->
+        <FpsList>
+            <!-- width/height must be increasing, fpsBound must be decreasing-->
+            <Limit width="640" height="480" fpsBound="30.0"/>
+            <Limit width="1280" height="720" fpsBound="15.0"/>
+            <Limit width="1920" height="1080" fpsBound="10.0"/>
+            <!-- image size larger than the last entry will not be supported-->
+        </FpsList>
+    </Device>
+</ExternalCamera>
diff --git a/etc/media_profiles.xml b/etc/media_profiles.xml
new file mode 100644
index 0000000..2ffb7a3
--- /dev/null
+++ b/etc/media_profiles.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, 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.
+*/
+-->
+<!DOCTYPE MediaSettings SYSTEM "/system/etc/media_profiles_V1_0.dtd">
+<MediaSettings>
+    <!-- Each camcorder profile defines a set of predefined configuration parameters -->
+    <CamcorderProfiles cameraId="0">
+	<!-- Iffy! Lets pretend vga (640x480) is 480p! -->
+        <EncoderProfile quality="480p" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="6000000"
+                   width="640"
+                   height="480"
+                   frameRate="30" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="h264"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="30" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <EncoderOutputFileFormat name="3gp" />
+    <EncoderOutputFileFormat name="mp4" />
+
+    <!--
+         If a codec is not enabled, it is invisible to the applications
+         In other words, the applications won't be able to use the codec
+         or query the capabilities of the codec at all if it is disabled
+    -->
+    <VideoEncoderCap name="h264" enabled="true"
+        minBitRate="64000" maxBitRate="12000000"
+        minFrameWidth="176" maxFrameWidth="1280"
+        minFrameHeight="144" maxFrameHeight="720"
+        minFrameRate="15" maxFrameRate="30" />
+
+    <VideoEncoderCap name="h263" enabled="true"
+        minBitRate="64000" maxBitRate="12000000"
+        minFrameWidth="176" maxFrameWidth="1280"
+        minFrameHeight="144" maxFrameHeight="720"
+        minFrameRate="15" maxFrameRate="30" />
+
+    <VideoEncoderCap name="m4v" enabled="true"
+        minBitRate="64000" maxBitRate="12000000"
+        minFrameWidth="176" maxFrameWidth="1280"
+        minFrameHeight="144" maxFrameHeight="720"
+        minFrameRate="15" maxFrameRate="30" />
+
+    <AudioEncoderCap name="aac" enabled="true"
+        minBitRate="8000" maxBitRate="96000"
+        minSampleRate="8000" maxSampleRate="48000"
+        minChannels="1" maxChannels="1" />
+
+    <AudioEncoderCap name="amrwb" enabled="true"
+        minBitRate="6600" maxBitRate="23050"
+        minSampleRate="16000" maxSampleRate="16000"
+        minChannels="1" maxChannels="1" />
+
+    <AudioEncoderCap name="amrnb" enabled="true"
+        minBitRate="5525" maxBitRate="12200"
+        minSampleRate="8000" maxSampleRate="8000"
+        minChannels="1" maxChannels="1" />
+
+    <!--
+        FIXME:
+        We do not check decoder capabilities at present
+        At present, we only check whether windows media is visible
+        for TEST applications. For other applications, we do
+        not perform any checks at all.
+    -->
+    <VideoDecoderCap name="wmv" enabled="false"/>
+    <AudioDecoderCap name="wma" enabled="false"/>
+</MediaSettings>
diff --git a/etc/mixer_paths.xml b/etc/mixer_paths.xml
new file mode 100644
index 0000000..dc28741
--- /dev/null
+++ b/etc/mixer_paths.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<mixer>
+	<!-- Enable HDMI out -->
+	<ctl name="QUAT_MI2S_RX Audio Mixer MultiMedia1" value="1" />
+</mixer>
diff --git a/fstab.common b/fstab.common
index 1cdac6e..f1bd034 100644
--- a/fstab.common
+++ b/fstab.common
@@ -1,8 +1,8 @@
-system		/system		ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
-/dev/block/platform/soc@0/1d84000.ufshc/by-name/userdata /data		ext4	discard,noatime,noauto_da_alloc,data=ordered,user_xattr,barrier=1,inlinecrypt	wait,formattable,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,quota
-/dev/block/platform/soc@0/1d84000.ufshc/by-name/metadata	/metadata	ext4	noatime,nosuid,nodev,discard					wait,formattable
-/dev/block/platform/soc@0/1d84000.ufshc/by-name/cache /cache	 ext4	nodev,noatime,nosuid,errors=panic wait
+system		/system		ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount,slotselect
+/dev/block/platform/soc@0/1d84000.ufshc/by-name/userdata /data		ext4	discard,noatime,noauto_da_alloc,data=ordered,user_xattr,barrier=1,inlinecrypt	latemount,wait,formattable,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota
+/dev/block/platform/soc@0/1d84000.ufshc/by-name/metadata	/metadata	ext4	noatime,nosuid,nodev,discard					wait,formattable,first_stage_mount,check
+/dev/block/platform/soc@0/1d84000.ufshc/by-name/misc /misc emmc defaults defaults
 /devices/platform/soc@0/8804000.sdhci/mmc_host/mmc*	auto	auto	defaults	voldmanaged=sdcard1:auto
-vendor		/vendor		ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
-system_ext	/system_ext	ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
-product	/product	ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
+vendor		/vendor		ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount,slotselect
+system_ext	/system_ext	ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount,slotselect
+product	/product	ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount,slotselect
diff --git a/gralloc/Android.mk b/gralloc/Android.mk
deleted file mode 100644
index ec1c38e..0000000
--- a/gralloc/Android.mk
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	gralloc_gbm.cpp \
-	gralloc.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libdrm \
-	libgbm_mesa \
-	liblog \
-	libcutils
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-	$(LOCAL_PATH)
-
-LOCAL_C_INCLUDES += system/core/include hardware/libhardware/include
-LOCAL_C_INCLUDES += system/core/libsystem/include system/core
-
-LOCAL_MODULE := gralloc.gbm
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-	$(LOCAL_PATH)
-
-LOCAL_MODULE := libgralloc_drm
-LOCAL_MODULE_TAGS := optional
-LOCAL_PROPRIETARY_MODULE := true
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/gralloc/gralloc.cpp b/gralloc/gralloc.cpp
deleted file mode 100644
index 1cc9f55..0000000
--- a/gralloc/gralloc.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
- * Copyright (C) 2010-2011 LunarG Inc.
- * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#define LOG_TAG "GRALLOC-GBM"
-
-#include <log/log.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <pthread.h>
-#include <errno.h>
-
-#include <hardware/gralloc.h>
-#include <system/graphics.h>
-
-#include <gbm.h>
-
-#include "gralloc_drm.h"
-#include "gralloc_gbm_priv.h"
-
-struct gbm_module_t {
-	gralloc_module_t base;
-
-	pthread_mutex_t mutex;
-	struct gbm_device *gbm;
-};
-
-/*
- * Initialize the DRM device object
- */
-static int gbm_init(struct gbm_module_t *dmod)
-{
-	int err = 0;
-
-	pthread_mutex_lock(&dmod->mutex);
-	if (!dmod->gbm) {
-		dmod->gbm = gbm_dev_create();
-		if (!dmod->gbm)
-			err = -EINVAL;
-	}
-	pthread_mutex_unlock(&dmod->mutex);
-
-	return err;
-}
-
-static int gbm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
-	va_list args;
-	int err;
-	uint32_t uop = static_cast<uint32_t>(op);
-
-	err = gbm_init(dmod);
-	if (err)
-		return err;
-
-	va_start(args, op);
-	switch (uop) {
-	case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
-		{
-			int *fd = va_arg(args, int *);
-			*fd = gbm_device_get_fd(dmod->gbm);
-			err = 0;
-		}
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-	va_end(args);
-
-	return err;
-}
-
-static int gbm_mod_register_buffer(const gralloc_module_t *mod,
-		buffer_handle_t handle)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
-	int err;
-
-	err = gbm_init(dmod);
-	if (err)
-		return err;
-
-	pthread_mutex_lock(&dmod->mutex);
-	err = gralloc_gbm_handle_register(handle, dmod->gbm);
-	pthread_mutex_unlock(&dmod->mutex);
-
-	return err;
-}
-
-static int gbm_mod_unregister_buffer(const gralloc_module_t *mod,
-		buffer_handle_t handle)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
-	int err;
-
-	pthread_mutex_lock(&dmod->mutex);
-	err = gralloc_gbm_handle_unregister(handle);
-	pthread_mutex_unlock(&dmod->mutex);
-
-	return err;
-}
-
-static int gbm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
-		int usage, int x, int y, int w, int h, void **ptr)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
-	int err;
-
-	pthread_mutex_lock(&dmod->mutex);
-
-	err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, ptr);
-	ALOGV("buffer %p lock usage = %08x", handle, usage);
-
-	pthread_mutex_unlock(&dmod->mutex);
-	return err;
-}
-
-static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
-	int err;
-
-	pthread_mutex_lock(&dmod->mutex);
-	err = gralloc_gbm_bo_unlock(handle);
-	pthread_mutex_unlock(&dmod->mutex);
-
-	return err;
-}
-
-static int gbm_mod_lock_ycbcr(gralloc_module_t const *mod, buffer_handle_t handle,
-		int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
-	int err;
-
-	pthread_mutex_lock(&dmod->mutex);
-	err = gralloc_gbm_bo_lock_ycbcr(handle, usage, x, y, w, h, ycbcr);
-	pthread_mutex_unlock(&dmod->mutex);
-
-	return err;
-}
-
-static int gbm_mod_close_gpu0(struct hw_device_t *dev)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module;
-	struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
-
-	gbm_dev_destroy(dmod->gbm);
-	delete alloc;
-
-	return 0;
-}
-
-static int gbm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
-
-	pthread_mutex_lock(&dmod->mutex);
-	gbm_free(handle);
-	native_handle_close(handle);
-	delete handle;
-
-	pthread_mutex_unlock(&dmod->mutex);
-	return 0;
-}
-
-static int gbm_mod_alloc_gpu0(alloc_device_t *dev,
-		int w, int h, int format, int usage,
-		buffer_handle_t *handle, int *stride)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
-	int err = 0;
-
-	pthread_mutex_lock(&dmod->mutex);
-
-	*handle = gralloc_gbm_bo_create(dmod->gbm, w, h, format, usage, stride);
-	if (!*handle)
-		err = -errno;
-
-	ALOGV("buffer %p usage = %08x", *handle, usage);
-	pthread_mutex_unlock(&dmod->mutex);
-	return err;
-}
-
-static int gbm_mod_open_gpu0(struct gbm_module_t *dmod, hw_device_t **dev)
-{
-	struct alloc_device_t *alloc;
-	int err;
-
-	err = gbm_init(dmod);
-	if (err)
-		return err;
-
-	alloc = new alloc_device_t();
-	if (!alloc)
-		return -EINVAL;
-
-	alloc->common.tag = HARDWARE_DEVICE_TAG;
-	alloc->common.version = 0;
-	alloc->common.module = &dmod->base.common;
-	alloc->common.close = gbm_mod_close_gpu0;
-
-	alloc->alloc = gbm_mod_alloc_gpu0;
-	alloc->free = gbm_mod_free_gpu0;
-
-	*dev = &alloc->common;
-
-	return 0;
-}
-
-static int gbm_mod_open(const struct hw_module_t *mod,
-		const char *name, struct hw_device_t **dev)
-{
-	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
-	int err;
-
-	if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
-		err = gbm_mod_open_gpu0(dmod, dev);
-	else
-		err = -EINVAL;
-
-	return err;
-}
-
-static struct hw_module_methods_t gbm_mod_methods = {
-	.open = gbm_mod_open
-};
-
-struct gbm_module_t HAL_MODULE_INFO_SYM = {
-	.base = {
-		.common = {
-			.tag = HARDWARE_MODULE_TAG,
-			.version_major = 1,
-			.version_minor = 0,
-			.id = GRALLOC_HARDWARE_MODULE_ID,
-			.name = "GBM Memory Allocator",
-			.author = "Rob Herring - Linaro",
-			.methods = &gbm_mod_methods
-		},
-		.registerBuffer = gbm_mod_register_buffer,
-		.unregisterBuffer = gbm_mod_unregister_buffer,
-		.lock = gbm_mod_lock,
-		.unlock = gbm_mod_unlock,
-		.lock_ycbcr = gbm_mod_lock_ycbcr,
-		.perform = gbm_mod_perform
-	},
-
-	.mutex = PTHREAD_MUTEX_INITIALIZER,
-	.gbm = NULL,
-};
diff --git a/gralloc/gralloc_drm.h b/gralloc/gralloc_drm.h
deleted file mode 100644
index 0ece652..0000000
--- a/gralloc/gralloc_drm.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
- * Copyright (C) 2010-2011 LunarG Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _GRALLOC_DRM_H_
-#define _GRALLOC_DRM_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
-	/* perform(const struct gralloc_module_t *mod,
-	 *	   int op,
-	 *	   int *fd);
-	 */
-	GRALLOC_MODULE_PERFORM_GET_DRM_FD                = 0x40000002,
-};
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _GRALLOC_DRM_H_ */
diff --git a/gralloc/gralloc_gbm.cpp b/gralloc/gralloc_gbm.cpp
deleted file mode 100644
index 29d11cd..0000000
--- a/gralloc/gralloc_gbm.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
- * Copyright (C) 2010-2011 LunarG Inc.
- * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#define LOG_TAG "GRALLOC-GBM"
-
-#include <log/log.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#include <hardware/gralloc.h>
-#include <system/graphics.h>
-
-#include <gbm.h>
-
-#include "gralloc_gbm_priv.h"
-#include <android/gralloc_handle.h>
-
-#include <unordered_map>
-
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-#define unlikely(x) __builtin_expect(!!(x), 0)
-
-static std::unordered_map<buffer_handle_t, struct gbm_bo *> gbm_bo_handle_map;
-
-struct bo_data_t {
-	void *map_data;
-	int lock_count;
-	int locked_for;
-};
-
-void gralloc_gbm_destroy_user_data(struct gbm_bo *bo, void *data)
-{
-	struct bo_data_t *bo_data = (struct bo_data_t *)data;
-	delete bo_data;
-
-	(void)bo;
-}
-
-static struct bo_data_t *gbm_bo_data(struct gbm_bo *bo) {
-	return (struct bo_data_t *)gbm_bo_get_user_data(bo);
-}
-
-
-static uint32_t get_gbm_format(int format)
-{
-	uint32_t fmt;
-
-	switch (format) {
-	case HAL_PIXEL_FORMAT_RGBA_8888:
-		fmt = GBM_FORMAT_ABGR8888;
-		break;
-	case HAL_PIXEL_FORMAT_RGBX_8888:
-		fmt = GBM_FORMAT_XBGR8888;
-		break;
-	case HAL_PIXEL_FORMAT_RGB_888:
-		fmt = GBM_FORMAT_RGB888;
-		break;
-	case HAL_PIXEL_FORMAT_RGB_565:
-		fmt = GBM_FORMAT_RGB565;
-		break;
-	case HAL_PIXEL_FORMAT_BGRA_8888:
-		fmt = GBM_FORMAT_ARGB8888;
-		break;
-	case HAL_PIXEL_FORMAT_YV12:
-		/* YV12 is planar, but must be a single buffer so ask for GR88 */
-		fmt = GBM_FORMAT_GR88;
-		break;
-	case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-	case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-	default:
-		fmt = 0;
-		break;
-	}
-
-	return fmt;
-}
-
-static int gralloc_gbm_get_bpp(int format)
-{
-	int bpp;
-
-	switch (format) {
-	case HAL_PIXEL_FORMAT_RGBA_8888:
-	case HAL_PIXEL_FORMAT_RGBX_8888:
-	case HAL_PIXEL_FORMAT_BGRA_8888:
-		bpp = 4;
-		break;
-	case HAL_PIXEL_FORMAT_RGB_888:
-		bpp = 3;
-		break;
-	case HAL_PIXEL_FORMAT_RGB_565:
-	case HAL_PIXEL_FORMAT_YCbCr_422_I:
-		bpp = 2;
-		break;
-	/* planar; only Y is considered */
-	case HAL_PIXEL_FORMAT_YV12:
-	case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-	case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-		bpp = 1;
-		break;
-	default:
-		bpp = 0;
-		break;
-	}
-
-	return bpp;
-}
-
-static unsigned int get_pipe_bind(int usage)
-{
-	unsigned int bind = 0;
-
-	if (usage & (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN))
-		bind |= GBM_BO_USE_LINEAR;
-	if (usage & GRALLOC_USAGE_CURSOR)
-		;//bind |= GBM_BO_USE_CURSOR;
-	if (usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE))
-		bind |= GBM_BO_USE_RENDERING;
-	if (usage & GRALLOC_USAGE_HW_FB)
-		bind |= GBM_BO_USE_SCANOUT;
-	if (usage & GRALLOC_USAGE_HW_COMPOSER)
-		bind |= GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
-
-	return bind;
-}
-
-static struct gbm_bo *gbm_import(struct gbm_device *gbm,
-		buffer_handle_t _handle)
-{
-	struct gbm_bo *bo;
-	struct gralloc_handle_t *handle = gralloc_handle(_handle);
-	#ifdef GBM_BO_IMPORT_FD_MODIFIER
-	struct gbm_import_fd_modifier_data data;
-	#else
-	struct gbm_import_fd_data data;
-	#endif
-
-	int format = get_gbm_format(handle->format);
-	if (handle->prime_fd < 0)
-		return NULL;
-
-	memset(&data, 0, sizeof(data));
-	data.width = handle->width;
-	data.height = handle->height;
-	data.format = format;
-	/* Adjust the width and height for a GBM GR88 buffer */
-	if (handle->format == HAL_PIXEL_FORMAT_YV12) {
-		data.width /= 2;
-		data.height += handle->height / 2;
-	}
-
-	#ifdef GBM_BO_IMPORT_FD_MODIFIER
-	data.num_fds = 1;
-	data.fds[0] = handle->prime_fd;
-	data.strides[0] = handle->stride;
-	data.modifier = handle->modifier;
-	bo = gbm_bo_import(gbm, GBM_BO_IMPORT_FD_MODIFIER, &data, 0);
-	#else
-	data.fd = handle->prime_fd;
-	data.stride = handle->stride;
-	bo = gbm_bo_import(gbm, GBM_BO_IMPORT_FD, &data, 0);
-	#endif
-
-	return bo;
-}
-
-static struct gbm_bo *gbm_alloc(struct gbm_device *gbm,
-		buffer_handle_t _handle)
-{
-	struct gbm_bo *bo;
-	struct gralloc_handle_t *handle = gralloc_handle(_handle);
-	int format = get_gbm_format(handle->format);
-	int usage = get_pipe_bind(handle->usage);
-	int width, height;
-
-	width = handle->width;
-	height = handle->height;
-	if (usage & GBM_BO_USE_CURSOR) {
-		if (handle->width < 64)
-			width = 64;
-		if (handle->height < 64)
-			height = 64;
-	}
-
-	/*
-	 * For YV12, we request GR88, so halve the width since we're getting
-	 * 16bpp. Then increase the height by 1.5 for the U and V planes.
-	 */
-	if (handle->format == HAL_PIXEL_FORMAT_YV12) {
-		width /= 2;
-		height += handle->height / 2;
-	}
-
-	ALOGV("create BO, size=%dx%d, fmt=%d, usage=%x",
-	      handle->width, handle->height, handle->format, usage);
-	bo = gbm_bo_create(gbm, width, height, format, usage);
-	if (!bo) {
-		ALOGE("failed to create BO, size=%dx%d, fmt=%d, usage=%x",
-		      handle->width, handle->height, handle->format, usage);
-		return NULL;
-	}
-
-	handle->prime_fd = gbm_bo_get_fd(bo);
-	handle->stride = gbm_bo_get_stride(bo);
-	#ifdef GBM_BO_IMPORT_FD_MODIFIER
-	handle->modifier = gbm_bo_get_modifier(bo);
-	#endif
-
-	return bo;
-}
-
-void gbm_free(buffer_handle_t handle)
-{
-	struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
-
-	if (!bo)
-		return;
-
-	gbm_bo_handle_map.erase(handle);
-	gbm_bo_destroy(bo);
-}
-
-/*
- * Return the bo of a registered handle.
- */
-struct gbm_bo *gralloc_gbm_bo_from_handle(buffer_handle_t handle)
-{
-	return gbm_bo_handle_map[handle];
-}
-
-static int gbm_map(buffer_handle_t handle, int x, int y, int w, int h,
-		int enable_write, void **addr)
-{
-	int err = 0;
-	int flags = GBM_BO_TRANSFER_READ;
-	struct gralloc_gbm_handle_t *gbm_handle = gralloc_handle(handle);
-	struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
-	struct bo_data_t *bo_data = gbm_bo_data(bo);
-	uint32_t stride;
-
-	if (bo_data->map_data)
-		return -EINVAL;
-
-	if (gbm_handle->format == HAL_PIXEL_FORMAT_YV12) {
-		if (x || y)
-			ALOGE("can't map with offset for planar %p", bo);
-		w /= 2;
-		h += h / 2;
-	}
-
-	if (enable_write)
-		flags |= GBM_BO_TRANSFER_WRITE;
-
-	*addr = gbm_bo_map(bo, 0, 0, x + w, y + h, flags, &stride, &bo_data->map_data);
-	ALOGV("mapped bo %p (%d, %d)-(%d, %d) at %p", bo, x, y, w, h, *addr);
-	if (*addr == NULL)
-		return -ENOMEM;
-
-	assert(stride == gbm_bo_get_stride(bo));
-
-	return err;
-}
-
-static void gbm_unmap(struct gbm_bo *bo)
-{
-	struct bo_data_t *bo_data = gbm_bo_data(bo);
-
-	gbm_bo_unmap(bo, bo_data->map_data);
-	bo_data->map_data = NULL;
-}
-
-void gbm_dev_destroy(struct gbm_device *gbm)
-{
-	int fd = gbm_device_get_fd(gbm);
-
-	gbm_device_destroy(gbm);
-	close(fd);
-}
-
-struct gbm_device *gbm_dev_create(void)
-{
-	struct gbm_device *gbm;
-	char path[PROPERTY_VALUE_MAX];
-	int fd;
-
-	property_get("gralloc.gbm.device", path, "/dev/dri/renderD128");
-	fd = open(path, O_RDWR | O_CLOEXEC);
-	if (fd < 0) {
-		ALOGE("failed to open %s", path);
-		return NULL;
-	}
-
-	gbm = gbm_create_device(fd);
-	if (!gbm) {
-		ALOGE("failed to create gbm device");
-		close(fd);
-	}
-
-	return gbm;
-}
-
-/*
- * Register a buffer handle.
- */
-int gralloc_gbm_handle_register(buffer_handle_t _handle, struct gbm_device *gbm)
-{
-	struct gbm_bo *bo;
-
-	if (!_handle)
-		return -EINVAL;
-
-	if (gbm_bo_handle_map.count(_handle))
-		return -EINVAL;
-
-	bo = gbm_import(gbm, _handle);
-	if (!bo)
-		return -EINVAL;
-
-	gbm_bo_handle_map.emplace(_handle, bo);
-
-	return 0;
-}
-
-/*
- * Unregister a buffer handle.  It is no-op for handles created locally.
- */
-int gralloc_gbm_handle_unregister(buffer_handle_t handle)
-{
-	gbm_free(handle);
-
-	return 0;
-}
-
-/*
- * Create a bo.
- */
-buffer_handle_t gralloc_gbm_bo_create(struct gbm_device *gbm,
-		int width, int height, int format, int usage, int *stride)
-{
-	struct gbm_bo *bo;
-	native_handle_t *handle;
-
-	handle = gralloc_handle_create(width, height, format, usage);
-	if (!handle)
-		return NULL;
-
-	bo = gbm_alloc(gbm, handle);
-	if (!bo) {
-		native_handle_delete(handle);
-		return NULL;
-	}
-
-	gbm_bo_handle_map.emplace(handle, bo);
-
-	/* in pixels */
-	*stride = gralloc_handle(handle)->stride / gralloc_gbm_get_bpp(format);
-
-	return handle;
-}
-
-/*
- * Lock a bo.  XXX thread-safety?
- */
-int gralloc_gbm_bo_lock(buffer_handle_t handle,
-		int usage, int x, int y, int w, int h,
-		void **addr)
-{
-	struct gralloc_handle_t *gbm_handle = gralloc_handle(handle);
-	struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
-	struct bo_data_t *bo_data;
-
-	if (!bo)
-		return -EINVAL;
-
-	if ((gbm_handle->usage & usage) != (uint32_t)usage) {
-		/* make FB special for testing software renderer with */
-
-		if (!(gbm_handle->usage & GRALLOC_USAGE_SW_READ_OFTEN) &&
-				!(gbm_handle->usage & GRALLOC_USAGE_HW_FB) &&
-				!(gbm_handle->usage & GRALLOC_USAGE_HW_TEXTURE)) {
-			ALOGE("bo.usage:x%X/usage:x%X is not GRALLOC_USAGE_HW_FB or GRALLOC_USAGE_HW_TEXTURE",
-				gbm_handle->usage, usage);
-			return -EINVAL;
-		}
-	}
-
-	bo_data = gbm_bo_data(bo);
-	if (!bo_data) {
-		bo_data = new struct bo_data_t();
-		gbm_bo_set_user_data(bo, bo_data, gralloc_gbm_destroy_user_data);
-	}
-
-	ALOGV("lock bo %p, cnt=%d, usage=%x", bo, bo_data->lock_count, usage);
-
-	/* allow multiple locks with compatible usages */
-	if (bo_data->lock_count && (bo_data->locked_for & usage) != usage)
-		return -EINVAL;
-
-	usage |= bo_data->locked_for;
-
-	/*
-	 * Some users will lock with an null crop rect.
-	 * Interpret this as no-crop (full buffer WxH).
-	 */
-	if (w == 0 && h == 0) {
-		w = gbm_handle->width;
-		h = gbm_handle->height;
-	}
-
-	if (usage & (GRALLOC_USAGE_SW_WRITE_MASK |
-		     GRALLOC_USAGE_SW_READ_MASK)) {
-		/* the driver is supposed to wait for the bo */
-		int write = !!(usage & GRALLOC_USAGE_SW_WRITE_MASK);
-		int err = gbm_map(handle, x, y, w, h, write, addr);
-		if (err)
-			return err;
-	}
-	else {
-		/* kernel handles the synchronization here */
-	}
-
-	bo_data->lock_count++;
-	bo_data->locked_for |= usage;
-
-	return 0;
-}
-
-/*
- * Unlock a bo.
- */
-int gralloc_gbm_bo_unlock(buffer_handle_t handle)
-{
-	struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
-	struct bo_data_t *bo_data;
-	if (!bo)
-		return -EINVAL;
-
-	bo_data = gbm_bo_data(bo);
-
-	int mapped = bo_data->locked_for &
-		(GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK);
-
-	if (!bo_data->lock_count)
-		return 0;
-
-	if (mapped)
-		gbm_unmap(bo);
-
-	bo_data->lock_count--;
-	if (!bo_data->lock_count)
-		bo_data->locked_for = 0;
-
-	return 0;
-}
-
-#define GRALLOC_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
-
-int gralloc_gbm_bo_lock_ycbcr(buffer_handle_t handle,
-		int usage, int x, int y, int w, int h,
-		struct android_ycbcr *ycbcr)
-{
-	struct gralloc_handle_t *hnd = gralloc_handle(handle);
-	int ystride, cstride;
-	void *addr = 0;
-	int err;
-
-	ALOGV("handle %p, hnd %p, usage 0x%x", handle, hnd, usage);
-
-	err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, &addr);
-	if (err)
-		return err;
-
-	memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
-
-	switch (hnd->format) {
-	case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-		ystride = cstride = GRALLOC_ALIGN(hnd->width, 16);
-		ycbcr->y = addr;
-		ycbcr->cr = (unsigned char *)addr + ystride * hnd->height;
-		ycbcr->cb = (unsigned char *)addr + ystride * hnd->height + 1;
-		ycbcr->ystride = ystride;
-		ycbcr->cstride = cstride;
-		ycbcr->chroma_step = 2;
-		break;
-	case HAL_PIXEL_FORMAT_YV12:
-		ystride = hnd->width;
-		cstride = GRALLOC_ALIGN(ystride / 2, 16);
-		ycbcr->y = addr;
-		ycbcr->cr = (unsigned char *)addr + ystride * hnd->height;
-		ycbcr->cb = (unsigned char *)addr + ystride * hnd->height + cstride * hnd->height / 2;
-		ycbcr->ystride = ystride;
-		ycbcr->cstride = cstride;
-		ycbcr->chroma_step = 1;
-		break;
-	default:
-		ALOGE("Can not lock buffer, invalid format: 0x%x", hnd->format);
-		return -EINVAL;
-	}
-
-	return 0;
-}
diff --git a/gralloc/gralloc_gbm_priv.h b/gralloc/gralloc_gbm_priv.h
deleted file mode 100644
index cbe9256..0000000
--- a/gralloc/gralloc_gbm_priv.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
- * Copyright (C) 2010-2011 LunarG Inc.
- * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _GRALLOC_GBM_PRIV_H_
-#define _GRALLOC_GBM_PRIV_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct gbm_device;
-struct gbm_bo;
-
-int gralloc_gbm_handle_register(buffer_handle_t handle, struct gbm_device *gbm);
-int gralloc_gbm_handle_unregister(buffer_handle_t handle);
-
-buffer_handle_t gralloc_gbm_bo_create(struct gbm_device *gbm,
-		int width, int height, int format, int usage, int *stride);
-void gbm_free(buffer_handle_t handle);
-
-struct gbm_bo *gralloc_gbm_bo_from_handle(buffer_handle_t handle);
-buffer_handle_t gralloc_gbm_bo_get_handle(struct gbm_bo *bo);
-int gralloc_gbm_get_gem_handle(buffer_handle_t handle);
-
-int gralloc_gbm_bo_lock(buffer_handle_t handle, int usage, int x, int y, int w, int h, void **addr);
-int gralloc_gbm_bo_unlock(buffer_handle_t handle);
-int gralloc_gbm_bo_lock_ycbcr(buffer_handle_t handle, int usage,
-		int x, int y, int w, int h, struct android_ycbcr *ycbcr);
-
-struct gbm_device *gbm_dev_create(void);
-void gbm_dev_destroy(struct gbm_device *gbm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _GRALLOC_GBM_PRIV_H_ */
diff --git a/init.common.rc b/init.common.rc
index 247a161..f15640a 100644
--- a/init.common.rc
+++ b/init.common.rc
@@ -1,14 +1,20 @@
 import init.${ro.hardware}.usb.rc
 import init.${ro.hardware}.power.rc
 
+on early-fs
+    start vold
+
 on fs
-    mount_all /vendor/etc/fstab.${ro.hardware}
+    mount_all /vendor/etc/fstab.${ro.hardware} --early
     swapon_all /vendor/etc/fstab.${ro.hardware}
 
 on post-fs
     # set RLIMIT_MEMLOCK to 64MB
     setrlimit 8 67108864 67108864
 
+on late-fs
+    mount_all /vendor/etc/fstab.${ro.hardware} --late
+
 on init
     # For legacy support
     # See storage config details at http://source.android.com/tech/storage/
@@ -61,3 +67,9 @@
     class main
     disabled
     oneshot
+
+# TODO: disable this service once we implement system suspend
+service suspend_blocker /vendor/bin/suspend_blocker
+    class early_hal # Start together with system_suspend HAL
+    group system
+    user root
diff --git a/init.common.usb.rc b/init.common.usb.rc
index 06ccd54..79d4d58 100644
--- a/init.common.usb.rc
+++ b/init.common.usb.rc
@@ -26,13 +26,15 @@
     mkdir /dev/usb-ffs/ptp 0770 mtp mtp
     mount functionfs mtp /dev/usb-ffs/mtp rmode=0770,fmode=0660,uid=1024,gid=1024,no_disconnect=1
     mount functionfs ptp /dev/usb-ffs/ptp rmode=0770,fmode=0660,uid=1024,gid=1024,no_disconnect=1
-    setprop sys.usb.controller "a600000.dwc3"
 
     setprop sys.usb.mtp.device_type 3
     setprop sys.usb.configfs 1
     setprop sys.usb.ffs.aio_compat 1
     symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1
 
+on property:vendor.usb.controller=*
+    setprop sys.usb.controller ${vendor.usb.controller}
+
 on property:sys.usb.config=none && property:sys.usb.configfs=1
     write /config/usb_gadget/g1/os_desc/use 0
 
@@ -88,3 +90,13 @@
 
 on property:sys.usb.config=accessory,audio_source,adb && property:sys.usb.configfs=1
     write /config/usb_gadget/g1/idProduct 0x2d05
+
+on post-fs
+    start set_udc
+
+service set_udc /vendor/bin/set_udc.sh
+    class core
+    user root
+    group system
+    disabled
+    oneshot
diff --git a/installer/db845c/README b/installer/db845c/README
index 61c3a3b..3b86aa9 100644
--- a/installer/db845c/README
+++ b/installer/db845c/README
@@ -38,16 +38,11 @@
 
 Flash the board:
 ----------------
-Once the board is in fastboot mode, you can then flash it by
-running the following from the
+Once the board is in fastboot mode, you can then flash bootloader
+binaries and AOSP images by running the following script from
 device/linaro/dragonboard/installer/db845c/ directory:
 
-  $ ./flash-all-aosp.sh <optional_kernel_binary>
-
-
-This will flash the bootloader binaries, AOSP images (userdata.img
-and super.img), and will also generate and flash boot.img if kernel
-binary (in Image.gz-dtb format) is passed to the script.
+  $ ./flash-all-aosp.sh
 
 
 Troubleshooting:
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/MD5SUMS.txt b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/MD5SUMS.txt
index 61b9063..b28964e 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/MD5SUMS.txt
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/MD5SUMS.txt
@@ -1,4 +1,4 @@
-9e5bd5524c1379c511dd92ea33393ad7  abl.elf
+bebec2693af4135bd0e55a9733330d4c  abl.elf
 71c6dd41e387ddb12c8553091928ec39  aop.mbn
 b6d81b360a5672d80c27430f39153e2c  boot-erase.img
 40e97319f57ab9d0b60009163ff940c2  BTFM.bin
@@ -7,29 +7,29 @@
 699e4dc2a0dbac11b255c79422744b44  devcfg.mbn
 d5cf22da99f6a871d4c7d43ce8eb801a  dspso.bin
 4400827c0a6689bfe118a67d79b4fcd7  flashall
-61362db524d6b1a082aa3e68c5ce5226  gpt_backup0.bin
-10711bd7b6c795b396ec7acc6546641b  gpt_backup1.bin
-1384ab8fa504bed08282b9fdbedd1256  gpt_backup2.bin
-f9f43f922865a282bd340731e2e4c05c  gpt_backup3.bin
-c98f59260b9d839fd66c7a799344763b  gpt_backup4.bin
-f1dd799d40155b2fb0a13e74dc708ef0  gpt_backup5.bin
-62809acaa9deeafbcf228ab3dec80fba  gpt_both0.bin
-1a45d3cc41bf1f7ab52c35a8dafde7c2  gpt_both1.bin
-26156f1cf28c2b03a52dc645e0776a6a  gpt_both2.bin
-836794cd35e92ac1865bca5bceb3afa8  gpt_both3.bin
-2a728d731064cb62a253e05fda09584c  gpt_both4.bin
-9b30da0d32e99c239a51c3d868960fde  gpt_both5.bin
-d3d913561434b15f1fd42b5c26b6e514  gpt_main0.bin
-42d103f66ffadf2fabe079c864d6ad2f  gpt_main1.bin
-33f9210eb72379fa4d737f7d968d69fe  gpt_main2.bin
-41530c11400b67d4efaca893a7bbc99f  gpt_main3.bin
-2ac0679ed66a373fc2a863dcb17bf6bf  gpt_main4.bin
-866e4769d16b95bb473441fa79b39d23  gpt_main5.bin
+d04ddc2ba6ddc3f46277be0f5110b89c  gpt_backup0.bin
+419282dd351676dd57bbdbf9071d3e0d  gpt_backup1.bin
+e4ec698b620dc22e21f8535d0e86974d  gpt_backup2.bin
+ac76f9ed9c900519ac2674ec57bb3567  gpt_backup3.bin
+3344e3a3f0cc9bd6724a6daf54795999  gpt_backup4.bin
+5abe36752afdf6906a34446fb07ba577  gpt_backup5.bin
+95ee7f7e67da134eb78feaba2632ea88  gpt_both0.bin
+2262a9ca99e9a4d0f14e82d72ef3875e  gpt_both1.bin
+3f5b9188752af8559b62dca9734a412b  gpt_both2.bin
+beae90cc33e3e49030ea4ae55506d7d5  gpt_both3.bin
+1e96d0067787380a271877f03a0d697f  gpt_both4.bin
+d3e137333ddfad50e598b96d0bfd9099  gpt_both5.bin
+1d36ec2fd30f8a36b572912c68b84cd5  gpt_main0.bin
+c7430987eba9d90f439b8ee4553cc82d  gpt_main1.bin
+4545b1e540e2b974a267b431c201a6b5  gpt_main2.bin
+d2e476646595d7b7a1e10ca80cb00db4  gpt_main3.bin
+f3fab8efdf25c1321e76c46e3706996d  gpt_main4.bin
+a5e59821587d028dfca32d751b94cb25  gpt_main5.bin
 94794668fb0a63c599e754cba52f6517  hyp.mbn
 35cc47772102f785807556e03135764a  imagefv.elf
 1fbaef77827cc531b5b7372ad1ee4937  keymaster64.mbn
 cbbe399f2c983ad51768f4561587f000  LICENSE
-c1c770a035a596c4b13a08789a76a137  patch0.xml
+7da8e656c3c01e6471479328af510728  patch0.xml
 0780990ee59934bdcaffc918cac99aed  patch1.xml
 81036277fd056a16c0e418a756a5a835  patch2.xml
 f1e955eeee449ed57767ac0b87552cf1  patch3.xml
@@ -37,7 +37,7 @@
 ab5847dcda2a52572616499f37ff1676  patch5.xml
 61e29ca7d21884af0e3a813d3bd0ade1  prog_firehose_ddr.elf
 57f570d8896ef6c0e55af6c3dc0940e1  qupv3fw.elf
-aea48fb241747a7db9741b05d2cc8a5e  rawprogram0.xml
+a4335c18367bd7edd478f59482259476  rawprogram0.xml
 078978d92fc3c2a0ad0744e5e905e806  rawprogram1.xml
 e829b09f11eeed7f44caca1b592c91bf  rawprogram2.xml
 e03411d04b290ffe1ea9b993d1f23074  rawprogram3.xml
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/abl.elf b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/abl.elf
index a8e5195..74101e0 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/abl.elf
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/abl.elf
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup0.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup0.bin
index c293d6c..724c269 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup0.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup0.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup1.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup1.bin
index a7df42f..03ea3ce 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup1.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup1.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup2.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup2.bin
index 9768f0d..5e4df8f 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup2.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup2.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup3.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup3.bin
index 308f3d7..fe98cdc 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup3.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup3.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup4.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup4.bin
index 047e1b0..93d0b16 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup4.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup4.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup5.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup5.bin
index 51e1a4c..8e601c7 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup5.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_backup5.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both0.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both0.bin
index ecb66bf..9c20853 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both0.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both0.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both1.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both1.bin
index c16f0bd..dd0730b 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both1.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both1.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both2.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both2.bin
index bd359d5..691646b 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both2.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both2.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both3.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both3.bin
index ae4516f..4d534b4 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both3.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both3.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both4.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both4.bin
index bc2cf44..e96ae6b 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both4.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both4.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both5.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both5.bin
index 47be07d..adf440c 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both5.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_both5.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main0.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main0.bin
index 9fffcb8..79e1cae 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main0.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main0.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main1.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main1.bin
index 33c7c99..b7bbaba 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main1.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main1.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main2.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main2.bin
index ea6d98f..cc3f0eb 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main2.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main2.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main3.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main3.bin
index ed6134e..12d0a41 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main3.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main3.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main4.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main4.bin
index e690bd8..534e26e 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main4.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main4.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main5.bin b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main5.bin
index f7c071c..7c12784 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main5.bin
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/gpt_main5.bin
Binary files differ
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/patch0.xml b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/patch0.xml
index 3548ee3..28f4a18 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/patch0.xml
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/patch0.xml
@@ -3,10 +3,10 @@
   <!--NOTE: This is an ** Autogenerated file **-->
   <!--NOTE: Patching is in little endian format, i.e. 0xAABBCCDD will look like DD CC BB AA in the file or on disk-->
   <!--NOTE: This file is used by Trace32 - So make sure to add decimals, i.e. 0x10-10=0, *but* 0x10-10.=6.-->
-  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="936" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 8 'userdata' with actual size in Primary Header."/>
-  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="936" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 8 'userdata' with actual size in Primary Header."/>
-  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="936" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="0" value="NUM_DISK_SECTORS-6." what="Update last partition 8 'userdata' with actual size in Backup Header."/>
-  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="936" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-5." value="NUM_DISK_SECTORS-6." what="Update last partition 8 'userdata' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="0" value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-5." value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Backup Header."/>
   <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
   <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
   <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
diff --git a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/rawprogram0.xml b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/rawprogram0.xml
index f9ec76b..f0a03e8 100644
--- a/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/rawprogram0.xml
+++ b/installer/db845c/dragonboard-845c-bootloader-ufs-aosp/rawprogram0.xml
@@ -3,8 +3,10 @@
   <!--NOTE: This is an ** Autogenerated file **-->
   <!--NOTE: Sector size is 4096bytes-->
   <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="persist" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0x6000" start_sector="6"/>
-  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="system_a" num_partition_sectors="1518216" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="6072864.0" sparse="false" start_byte_hex="0x2006000" start_sector="8198"/>
-  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="system_b" num_partition_sectors="1518216" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="6072864.0" sparse="false" start_byte_hex="0x174a8e000" start_sector="1526414"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="system_a" num_partition_sectors="1501832" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="6007328.0" sparse="false" start_byte_hex="0x2006000" start_sector="8198"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="system_b" num_partition_sectors="1501832" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="6007328.0" sparse="false" start_byte_hex="0x170a8e000" start_sector="1510030"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vendor_boot_a" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x2df516000" start_sector="3011862"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vendor_boot_b" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x2e3516000" start_sector="3028246"/>
   <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="super" num_partition_sectors="3036432" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="12145728.0" sparse="false" start_byte_hex="0x2e7516000" start_sector="3044630"/>
   <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="systemrw" num_partition_sectors="4096" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="16384.0" sparse="false" start_byte_hex="0x5cca26000" start_sector="6081062"/>
   <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="cache" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x5cda26000" start_sector="6085158"/>
diff --git a/installer/db845c/flash-all-aosp.sh b/installer/db845c/flash-all-aosp.sh
index b3c677b..dd6c755 100755
--- a/installer/db845c/flash-all-aosp.sh
+++ b/installer/db845c/flash-all-aosp.sh
@@ -40,9 +40,11 @@
 fastboot flash boot "${ANDROID_PRODUCT_OUT}"/boot.img
 echo "FLASH-ALL-AOSP: Flash super/dynamic image"
 fastboot flash super "${ANDROID_PRODUCT_OUT}"/super.img
-echo "FLASH-ALL-AOSP: Flash cache image"
-fastboot flash cache "${ANDROID_PRODUCT_OUT}"/cache.img
 echo "FLASH-ALL-AOSP: Flash userdata image"
 fastboot flash userdata "${ANDROID_PRODUCT_OUT}"/userdata.img
+echo "FLASH-ALL-AOSP: Flash vendor_boot image"
+fastboot flash vendor_boot "${ANDROID_PRODUCT_OUT}"/vendor_boot.img
+echo "FLASH-ALL-AOSP: Formatting metadata"
+fastboot format:ext4 metadata
 
 fastboot reboot
diff --git a/installer/rb5/README b/installer/rb5/README
new file mode 100644
index 0000000..ee59bdb
--- /dev/null
+++ b/installer/rb5/README
@@ -0,0 +1,70 @@
+These instructions will help you flashing the prebuilt bootloader
+and AOSP images(built from sources) on rb5.
+
+First, make sure you have built the AOSP images for RB5 by
+running the rb5-userdebug lunch target.
+
+
+Boot the board into fastboot mode:
+----------------------------------
+The easiest way to boot into fastboot mode is to run something
+like "adb reboot bootloader" from the host, or
+"reboot bootloader" on the device.  However, this
+functionality may depend on the software installed on the board
+to work, so you may need to manually enter fastboot mode as
+follows.
+
+To manually enter fastboot mode:
+--------------------------------
+* To manually boot the board into fastboot mode, press DOWN arrow
+  key over serial UART console when restarting the board.
+
+                         OR
+
+* Follow the instructions here
+https://www.96boards.org/documentation/consumer/dragonboard/qualcomm-robotics-rb5/installation/board-recovery.md.html#booting-into-fastboot
+
+
+Flash the board:
+----------------
+Once the board is in fastboot mode, you can then flash bootloader
+binaries and AOSP images by running the following script from
+device/linaro/dragonboard/installer/rb5/ directory:
+
+  $ ./flash-all-aosp.sh
+
+
+Troubleshooting:
+----------------
+* If you have flashed AOSP images and you can see the boot logs
+  on Serial prompt but no UI then try updating the lt9611uxc
+  firmware version. Factory shipped RB5 has an older version of
+  lt9611uxc firmware flashed on it and it is incompatible with
+  upstream kernel. Try updating the firmware version by running
+  the following adb shell commands:
+
+  $ adb wait-for-device; adb root; adb shell "echo 1 > /sys/bus/i2c/devices/5-002b/lt9611uxc_firmware"
+
+* Make sure the USB-C cable is connected. As it has to be
+  removed to fully power the device down, it is easy to forget
+  to reconnect it!
+
+* If you cannot get the board into fastboot mode, or for some
+  reason the flash-all-aosp.sh script does not work, you can do
+  a full recovery flash of the board using the following
+  instructions.
+
+
+Recovery:
+--------
+First boot into recovery mode by follwing the recovery
+instructions from here:
+https://www.96boards.org/documentation/consumer/dragonboard/qualcomm-robotics-rb5/installation/board-recovery.md.html
+
+Then run the recovery script from the
+device/linaro/dragonboard/installer/rb5/ directory:
+
+  $ ./recovery.sh
+
+This will do a recovery flash of the ptable and bootloader
+binaries.
diff --git a/installer/rb5/flash-all-aosp.sh b/installer/rb5/flash-all-aosp.sh
new file mode 100755
index 0000000..9eea95b
--- /dev/null
+++ b/installer/rb5/flash-all-aosp.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+INSTALLER_DIR="`dirname ${0}`"
+
+FIRMWARE_DIR="rb5-bootloader-ufs-aosp"
+
+# for cases that don't run "lunch rb5-userdebug"
+if [ -z "${ANDROID_BUILD_TOP}" ]; then
+    ANDROID_BUILD_TOP=${INSTALLER_DIR}/../../../../../
+    ANDROID_PRODUCT_OUT="${ANDROID_BUILD_TOP}/out/target/product/rb5"
+fi
+
+if [ ! -d "${ANDROID_PRODUCT_OUT}" ]; then
+    echo "FLASH-ALL-AOSP: error in locating out/target directory, check if it exist"
+    exit
+fi
+
+echo "android out dir:${ANDROID_PRODUCT_OUT}"
+
+# TODO: Pull one-time recovery/qdl path out of standard install
+# Flash bootloader firmware files
+if [ ! -d "${INSTALLER_DIR}/${FIRMWARE_DIR}/" ]; then
+    echo "FLASH-ALL-AOSP: No firmware directory? Make sure binaries have been provided"
+    exit
+fi
+
+pushd "${INSTALLER_DIR}/${FIRMWARE_DIR}" > /dev/null
+./flashall
+popd > /dev/null
+
+echo "FLASH-ALL-AOSP: Flash boot img"
+fastboot flash boot "${ANDROID_PRODUCT_OUT}"/boot.img
+echo "FLASH-ALL-AOSP: Flash super/dynamic image"
+fastboot flash super "${ANDROID_PRODUCT_OUT}"/super.img
+echo "FLASH-ALL-AOSP: Flash userdata image"
+fastboot flash userdata "${ANDROID_PRODUCT_OUT}"/userdata.img
+echo "FLASH-ALL-AOSP: Flash vendor_boot image"
+fastboot flash vendor_boot "${ANDROID_PRODUCT_OUT}"/vendor_boot.img
+echo "FLASH-ALL-AOSP: Formatting metadata"
+fastboot format:ext4 metadata
+
+fastboot reboot
+
+echo "FLASH-ALL-AOSP: Updating lt9611uxc firmware version"
+adb wait-for-device
+VERSION=`adb shell su 0 cat /sys/bus/i2c/devices/5-002b/lt9611uxc_firmware`
+if [ "$VERSION" -lt "43" ] ; then
+    echo "FLASH-ALL-AOSP: lt9611uxc 5-002b: Updating firmware... May take up to 120 seconds. Do not switch off the device"
+    adb shell "echo 1 | su 0 tee /sys/bus/i2c/devices/5-002b/lt9611uxc_firmware > /dev/null"
+    echo "FLASH-ALL-AOSP: lt9611uxc 5-002b: Firmware updates successfully"
+    echo "FLASH-ALL-AOSP: Rebooting"
+    adb reboot
+fi
+echo "FLASH-ALL-AOSP: Done"
diff --git a/installer/rb5/qdl b/installer/rb5/qdl
new file mode 100755
index 0000000..fc45c0a
--- /dev/null
+++ b/installer/rb5/qdl
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/LICENSE b/installer/rb5/rb5-bootloader-ufs-aosp/LICENSE
new file mode 100644
index 0000000..6b9a0a2
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/LICENSE
@@ -0,0 +1,206 @@
+PLEASE READ THIS LICENSE AGREEMENT ("AGREEMENT") CAREFULLY.  THIS AGREEMENT IS

+A BINDING LEGAL AGREEMENT ENTERED INTO BY AND BETWEEN YOU (OR IF YOU ARE

+ENTERING INTO THIS AGREEMENT ON BEHALF OF AN ENTITY, THEN THE ENTITY THAT YOU

+REPRESENT) AND QUALCOMM TECHNOLOGIES, INC. ("QTI" "WE" "OUR" OR "US").  THIS IS

+THE AGREEMENT THAT APPLIES TO YOUR USE OF THE DESIGNATED AND/OR LINKED

+APPLICATIONS, THE ENCLOSED QUALCOMM TECHNOLOGIES' MATERIALS, INCLUDING RELATED

+DOCUMENTATION AND ANY UPDATES OR IMPROVEMENTS THEREOF

+(COLLECTIVELY, "MATERIALS").  BY USING OR COMPLETING THE INSTALLATION OF THE

+MATERIALS, YOU ARE ACCEPTING THIS AGREEMENT AND YOU AGREE TO BE BOUND BY ITS

+TERMS AND CONDITIONS.  IF YOU DO NOT AGREE TO THESE TERMS, QTI IS UNWILLING TO

+AND DOES NOT LICENSE THE MATERIALS TO YOU. IF YOU DO NOT AGREE TO THESE TERMS

+YOU MUST DISCONTINUE THE INSTALLATION PROCESS AND YOU MAY NOT USE THE MATERIALS

+OR RETAIN ANY COPIES OF THE MATERIALS. ANY USE OR POSSESSION OF THE MATERIALS

+BY YOU IS SUBJECT TO THE TERMS AND CONDITIONS SET FORTH IN THIS AGREEMENT.

+

+1. RIGHT TO USE DELIVERABLES; RESTRICTIONS.

+

+  1.1 License.  Subject to the terms and conditions of this Agreement,

+  including, without limitation, the restrictions, conditions, limitations and

+  exclusions set forth in this Agreement, QTI hereby grants to you a

+  nonexclusive, limited license under QTI's copyrights to:  (i) install and use

+  the Materials; and (ii) to reproduce and redistribute the binary code portions

+  of the Materials (the "Redistributable Binary Code").  You may make and use a

+  reasonable number of copies of any documentation.

+

+  1.2 Redistribution Restrictions.  Distribution of the Redistributable Binary

+  Code is subject to the following restrictions: (i) Redistributable Binary Code

+  may only be distributed in binary format and may not be distributed in source

+  code format:; (ii)  the Redistributable Binary Code may only operate in

+  conjunction with platforms incorporating Qualcomm Technologies, Inc. chipsets;

+  (iii) redistribution of the Redistributable Binary Code must include the .txt

+  file setting forth the terms and condition of this Agreement; (iv) you may not

+  use Qualcomm Technologies' or its affiliates or subsidiaries name, logo or

+  trademarks; and (v) copyright, trademark, patent and any other notices that

+  appear on the Materials may not be removed or obscured.

+

+  1.3 Additional Restrictions.  Except as expressly permitted by this Agreement,

+  you shall have no right to sublicense, transfer or otherwise disclose the

+  Materials to any third party.  You shall not reverse engineer, reverse

+  assemble, reverse translate, decompile or reduce to source code form any

+  portion of the Materials provided in object code form or executable form.

+  Except for the purposes expressly permitted in this Agreement, You shall not

+  use the Materials for any other purpose.  QTI (or its licensors) shall retain

+  title and all ownership rights in and to the Materials and any alterations,

+  modifications (including all derivative works), translations or adaptations

+  made of the Materials, and all copies thereof, and nothing herein shall be

+  deemed to grant any right to You under any of QTI's or its affiliates'

+  patents.  You shall not subject the Materials to any third party license

+  terms (e.g., open source license terms).  You shall not use the Materials for

+  the purpose of identifying or providing evidence to support any potential

+  patent infringement claim against QTI, its affiliates, or any of QTI's or

+  QTI's affiliates' suppliers and/or direct or indirect customers.  QTI hereby

+  reserves all rights not expressly granted herein.

+

+  1.4 Third Party Software and Materials.  The Software may contain or link to

+  certain software and/or materials that are written or owned by third parties.

+  Such third party code and materials may be licensed under separate or

+  different terms and conditions and are not licensed to you under the terms of

+  this Agreement.  You agree to comply with all terms and conditions imposed on

+  you in the applicable third party licenses.  Such terms and conditions may

+  impose certain obligations on you as a condition to the permitted use of such

+  third party code and materials.  QTI does not represent or warrant that such

+  third party licensors have or will continue to license or make available their

+  code and materials to you.

+

+  1.5 Feedback.  QTI may from time to time receive suggestions, feedback or

+  other information from You regarding the Materials.  Any suggestions, feedback

+  or other disclosures received from You are and shall be entirely voluntary on

+  the part of You.  Notwithstanding any other term in this Agreement, QTI shall

+  be free to use suggestions, feedback or other information received from You,

+  without obligation of any kind to You.  The Parties agree that all inventions,

+  product improvements, and modifications conceived of or made by QTI that are

+  based, either in whole or in part, on ideas, feedback, suggestions, or

+  recommended improvements received from You are the exclusive property of QTI,

+  and all right, title and interest in and to any such inventions, product

+  improvements, and modifications will vest solely in QTI.

+

+  1.6 No Technical Support.  QTI is under no obligation to provide any form of

+  technical support for the Materials, and if QTI, in its sole discretion,

+  chooses to provide any form of support or information relating to the

+  Materials, such support and information shall be deemed confidential and

+  proprietary to QTI.

+

+2. WARRANTY DISCLAIMER.  YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT THE USE OF

+THE MATERIALS IS AT YOUR SOLE RISK.  THE MATERIALS AND TECHNICAL SUPPORT, IF

+ANY, ARE PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR

+IMPLIED.  QTI ITS LICENSORS AND AFFILIATES MAKE NO WARRANTIES, EXPRESS OR

+IMPLIED, WITH RESPECT TO THE MATERIALS OR ANY OTHER INFORMATION OR DOCUMENTATION

+PROVIDED UNDER THIS AGREEMENT, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF

+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR AGAINST INFRINGEMENT, OR

+ANY EXPRESS OR IMPLIED WARRANTY ARISING OUT OF TRADE USAGE OR OUT OF A COURSE OF

+DEALING OR COURSE OF PERFORMANCE.  NOTHING CONTAINED IN THIS AGREEMENT SHALL BE

+CONSTRUED AS (I) A WARRANTY OR REPRESENTATION BY QTI, ITS LICENSORS OR

+AFFILIATES AS TO THE VALIDITY OR SCOPE OF ANY PATENT, COPYRIGHT OR OTHER

+INTELLECTUAL PROPERTY RIGHT OR (II) A WARRANTY OR REPRESENTATION BY QTI THAT ANY

+MANUFACTURE OR USE WILL BE FREE FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR

+OTHER INTELLECTUAL PROPERTY RIGHTS OF OTHERS, AND IT SHALL BE THE SOLE

+RESPONSIBILITY OF YOU TO MAKE SUCH DETERMINATION AS IS NECESSARY WITH RESPECT TO

+THE ACQUISITION OF LICENSES UNDER PATENTS AND OTHER INTELLECTUAL PROPERTY OF

+THIRD PARTIES.

+

+3. NO OTHER LICENSES OR INTELLECTUAL PROPERTY RIGHTS. Neither this Agreement,

+nor any act by QTI or any of its affiliates pursuant to this Agreement or

+relating to the Materials (including, without limitation, the provision by QTI

+or its affiliates of the Materials), shall provide to You any license or any

+other rights whatsoever under any patents, trademarks, trade secrets, copyrights

+or any other intellectual property of QTI or any of its affiliates, except for

+the copyright rights expressly licensed under this Agreement. You understand and

+agree that:

+

+  (i) Neither this Agreement, nor delivery of the Materials, grants any right to

+  practice, or any other right at all with respect to, any patent of QTI or any

+  of its affiliates; and

+

+  (ii) A separate license agreement from QUALCOMM Incorporated is needed to use

+  or practice any patent of QUALCOMM Incorporated. You agree not to contend in

+  any context that, as a result of the provision or use of the Materials, either

+  QTI or any of its affiliates has any obligation to extend, or You or any other

+  party has obtained any right to, any license, whether express or implied, with

+  respect to any patent of QTI or any of its affiliates for any purpose.

+

+4. TERMINATION.  This Agreement shall be effective upon acceptance, or access or

+use of the Materials (whichever occurs first) by You and shall continue until

+terminated. You may terminate the Agreement at any time by deleting and

+destroying all copies of the Materials and all related information in Your

+possession or control. This Agreement terminates immediately and automatically,

+with or without notice, if You fail to comply with any provision hereof.

+Additionally, QTI may at any time terminate this Agreement, without cause, upon

+notice to You. Upon termination You must, to the extent possible, delete or

+destroy all copies of the Materials in Your possession and the license granted

+to You in this Agreement shall terminate. Sections 1.2 through 10 shall survive

+the termination of this Agreement. In the event that any restrictions,

+conditions, limitations are found to be either invalid or unenforceable, the

+rights granted to You in Section 1 (License) shall be null, void and ineffective

+from the Effective Date, and QTI shall also have the right to terminate this

+Agreement immediately, and with retroactive effect to the effective date.

+

+5. LIMITATION OF LIABILITY.  IN NO EVENT SHALL QTI, QTI's AFFILIATES OR ITS

+LICENSORS BE LIABLE TO YOU FOR ANY INCIDENTAL, CONSEQUENTIAL OR SPECIAL DAMAGES,

+INCLUDING BUT NOT LIMITED TO ANY LOST PROFITS, LOST SAVINGS, OR OTHER INCIDENTAL

+DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE, OR THE DELIVERY OR FAILURE

+TO DELIVER, ANY OF THE DELIVERABLES, OR ANY BREACH OF ANY OBLIGATION UNDER THIS

+AGREEMENT, EVEN IF QTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

+THE FOREGOING LIMITATION OF LIABILITY SHALL REMAIN IN FULL FORCE AND EFFECT

+REGARDLESS OF WHETHER YOUR REMEDIES HEREUNDER ARE DETERMINED TO HAVE FAILED OF

+THEIR ESSENTIAL PURPOSE.  THE ENTIRE LIABILITY OF QTI, QTI's AFFILIATES AND ITS

+LICENSORS, AND THE SOLE AND EXCLUSIVE REMEDY OF YOU, FOR ANY CLAIM OR CAUSE OF

+ACTION ARISING HEREUNDER (WHETHER IN CONTRACT, TORT, OR OTHERWISE) SHALL NOT

+EXCEED US$50.

+

+6. INDEMNIFICATION.  You agree to indemnify and hold harmless QTI and its

+officers, directors, employees and successors and assigns against any and all

+third party claims, demands, causes of action, losses, liabilities, damages,

+costs and expenses, incurred by QTI (including but not limited to costs of

+defense, investigation and reasonable attorney's fees) arising out of, resulting

+from or related to: (i) any breach of this Agreement by You; and (ii) your acts,

+omissions, products and services.  If requested by QTI, You agree to defend QTI

+in connection with any third party claims, demands, or causes of action

+resulting from, arising out of or in connection with any of the foregoing.

+

+7. ASSIGNMENT.  You shall not assign this Agreement or any right or interest

+under this Agreement, nor delegate any obligation to be performed under this

+Agreement, without QTI's prior written consent.  For purposes of this Section 7,

+an "assignment" by You under this Section shall be deemed to include, without

+limitation, any merger, consolidation, sale of all or substantially all of its

+assets, or any substantial change in the management or control of You.

+Any attempted assignment in contravention of this Section 9 shall be void.

+QTI may freely assign this Agreement or delegate any or all of its rights and

+obligations hereunder to any third party.

+

+8. COMPLIANCE WITH LAWS; APPLICABLE LAW.  You agree to comply with all

+applicable local, international and national laws and regulations and with U.S.

+Export Administration Regulations, as they apply to the subject matter of this

+Agreement.  This Agreement is governed by the laws of the State of California,

+excluding California's choice of law rules.

+

+9. CONTRACTING PARTIES.  If the Materials are downloaded on any computer owned

+by a corporation or other legal entity, then this Agreement is formed by and

+between QTI and such entity.  The individual accepting the terms of this

+Agreement represents and warrants to QTI that they have the authority to bind

+such entity to the terms and conditions of this Agreement.

+

+10. MISCELLANEOUS PROVISIONS.  This Agreement, together with all exhibits

+attached hereto, which are incorporated herein by this reference, constitutes

+the entire agreement between QTI and You and supersedes all prior negotiations,

+representations and agreements between the parties with respect to the subject

+matter hereof.  No addition or modification of this Agreement shall be effective

+unless made in writing and signed by the respective representatives of QTI and

+You.  The restrictions, limitations, exclusions and conditions set forth in this

+Agreement shall apply even if QTI or any of its affiliates becomes aware of or

+fails to act in a manner to address any violation or failure to comply

+therewith.  You hereby acknowledge and agree that the restrictions, limitations,

+conditions and exclusions imposed in this Agreement on the rights granted in

+this Agreement are not a derogation of the benefits of such rights.  You further

+acknowledges that, in the absence of such restrictions, limitations, conditions

+and exclusions, QTI would not have entered into this Agreement with You.  Each

+party shall be responsible for and shall bear its own expenses in connection

+with this Agreement.  If any of the provisions of this Agreement are determined

+to be invalid, illegal, or otherwise unenforceable, the remaining provisions

+shall remain in full force and effect.  This Agreement is entered into solely

+in the English language, and if for any reason any other language version is

+prepared by any party, it shall be solely for convenience and the English

+version shall govern and control all aspects.  If You are located in the

+province of Quebec, Canada, the following applies: The Parties hereby confirm

+they have requested this Agreement and all related documents be prepared

+in English..
\ No newline at end of file
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/MD5SUMS.txt b/installer/rb5/rb5-bootloader-ufs-aosp/MD5SUMS.txt
new file mode 100644
index 0000000..d7ba37d
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/MD5SUMS.txt
@@ -0,0 +1,52 @@
+568936f0565ed1e3e7e5b391b5ed93bf  abl.elf
+269902643091ab740bab845c09db6a40  aop.mbn
+21fe4f0eb68aa45c57ab85930dda1fa6  apdp.mbn
+b6d81b360a5672d80c27430f39153e2c  boot-erase.img
+123c63fdb9f5f70671c49ccae8bbe9e7  cdt.bin
+bdd8e32ccfac703d18747ba277ce47ac  cmnlib64.mbn
+d95347ba2a5e7373e44d708c8c85c87e  cmnlib.mbn
+cde2a2dd4b83eecab92f9c9f3786b58e  devcfg.mbn
+45cb353504ae1176d478b0fa22666965  dspso.bin
+8aff5a3fae2919ca4c0bcf20f5b68910  featenabler.mbn
+1404205e5a27b992d274924220fc7390  flashall
+c3bed6261a596ef94a8251d3ee413082  gpt_backup0.bin
+53f9ed2be13a80c40bee670217a4dda6  gpt_backup1.bin
+212280e5a0189fe98f2f516f05ec2a68  gpt_backup2.bin
+27b573b83ede2f6abbcf832dbd1cb101  gpt_backup3.bin
+c4cd72a9ef3f62f35854cb157b9b37bb  gpt_backup4.bin
+239251d3ad9e675077a705c2119878ea  gpt_backup5.bin
+2de913f702fa9dd37ceae2cba168d12f  gpt_both0.bin
+522a55738614ba65a27373fae893064f  gpt_both1.bin
+28cd76d1b097c304b6aa05ba64f2928e  gpt_both2.bin
+8a10fef96db6e1e7c1bd91cad8026d51  gpt_both3.bin
+b19a8d8df046a012c40cdb213437f747  gpt_both4.bin
+a8eba85c1595891aa2fcc449b6bdb114  gpt_both5.bin
+8e8cac4e2a927ea323efba51a3ebd808  gpt_main0.bin
+1f495395c505d90ef8891eb8c31f80dc  gpt_main1.bin
+0d3ccfcd106d4020fb1654cd298205fc  gpt_main2.bin
+7ccf5d8c547fba5b93cf0def32710f4a  gpt_main3.bin
+945ccf9667484466e270abf817a24b33  gpt_main4.bin
+9eca5eec2e3248341d0ad20acdeceef7  gpt_main5.bin
+6bcbfe1866a7fde271785744ac832796  hyp.mbn
+3c84eaaffd53577b9aaeedd10e8abb62  km4.mbn
+cbbe399f2c983ad51768f4561587f000  LICENSE
+4a9c85ffbb610f1e6b728e9919e23ff9  multi_image.mbn
+7da8e656c3c01e6471479328af510728  patch0.xml
+0780990ee59934bdcaffc918cac99aed  patch1.xml
+81036277fd056a16c0e418a756a5a835  patch2.xml
+491532d01cc4be1604e3d6784d6f4a13  patch3.xml
+353c75b108136948c60aed81024affa8  patch4.xml
+e525e811f1a46cd927aa3740ad47e584  patch5.xml
+4ea6f2187bce07cd3d1e02a70e3f83c3  prog_firehose_ddr.elf
+ce8ace958f7f5c0479a69c0dd331f30e  qupv3fw.elf
+a4335c18367bd7edd478f59482259476  rawprogram0.xml
+078978d92fc3c2a0ad0744e5e905e806  rawprogram1.xml
+e829b09f11eeed7f44caca1b592c91bf  rawprogram2.xml
+e6bc33009e6df9a3d3f0edd968dc742b  rawprogram3.xml
+968badca129dbc54e197a49bbcc2fbca  rawprogram4.xml
+e21b2fb50b5692a081ebcfa730bc125f  rawprogram5.xml
+da53d17a35d3f0bbb2e6ec2ee7cc20e1  spunvm.bin
+dfb500dc0b15b035694dc1f664cd3968  tz.mbn
+363aeec966c040a50bb8f918de88c3f9  uefi_sec.mbn
+9fc1b09f5efb86f5c87a98860223c416  xbl_config.elf
+803e1f9fd99c91fd68935f398b5aed29  xbl.elf
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/abl.elf b/installer/rb5/rb5-bootloader-ufs-aosp/abl.elf
new file mode 100644
index 0000000..39a0059
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/abl.elf
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/aop.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/aop.mbn
new file mode 100644
index 0000000..f6fc5a3
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/aop.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/apdp.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/apdp.mbn
new file mode 100644
index 0000000..9042418
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/apdp.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/boot-erase.img b/installer/rb5/rb5-bootloader-ufs-aosp/boot-erase.img
new file mode 100644
index 0000000..9e0f96a
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/boot-erase.img
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/cdt.bin b/installer/rb5/rb5-bootloader-ufs-aosp/cdt.bin
new file mode 100644
index 0000000..a98a6a0
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/cdt.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/cmnlib.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/cmnlib.mbn
new file mode 100644
index 0000000..3b395f9
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/cmnlib.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/cmnlib64.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/cmnlib64.mbn
new file mode 100644
index 0000000..c582d2e
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/cmnlib64.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/devcfg.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/devcfg.mbn
new file mode 100644
index 0000000..c172a76
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/devcfg.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/dspso.bin b/installer/rb5/rb5-bootloader-ufs-aosp/dspso.bin
new file mode 100644
index 0000000..b63ece9
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/dspso.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/featenabler.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/featenabler.mbn
new file mode 100644
index 0000000..886afe7
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/featenabler.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/flashall b/installer/rb5/rb5-bootloader-ufs-aosp/flashall
new file mode 100755
index 0000000..966d670
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/flashall
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+fastboot flash partition:0 gpt_both0.bin
+fastboot flash partition:1 gpt_both1.bin
+fastboot flash partition:2 gpt_both2.bin
+fastboot flash partition:3 gpt_both3.bin
+fastboot flash partition:4 gpt_both4.bin
+fastboot flash partition:5 gpt_both5.bin
+
+#fastboot flash ImageFv_a imagefv.elf
+fastboot flash aop_a aop.mbn
+fastboot flash apdp apdp.mbn
+#fastboot flash bluetooth_a BTFM.bin
+fastboot flash cmnlib64_a cmnlib64.mbn
+fastboot flash cmnlib_a cmnlib.mbn
+fastboot flash cdt cdt.bin
+fastboot erase ddr
+fastboot flash devcfg_a devcfg.mbn
+fastboot flash dsp_a dspso.bin
+fastboot flash featenabler_a featenabler.mbn
+fastboot flash hyp_a hyp.mbn
+fastboot flash keymaster_a km4.mbn
+#fastboot flash logfs logfs_ufs_8mb.bin
+#fastboot flash modem_a NON-HLOS.bin
+fastboot flash multiimgoem_a multi_image.mbn
+fastboot flash qupfw_a qupv3fw.elf
+fastboot flash spunvm spunvm.bin
+fastboot flash tz_a tz.mbn
+fastboot flash uefisecapp_a uefi_sec.mbn
+fastboot flash xbl_a xbl.elf
+fastboot flash xbl_config_a xbl_config.elf
+
+fastboot flash abl_a abl.elf
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup0.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup0.bin
new file mode 100644
index 0000000..dd35587
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup0.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup1.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup1.bin
new file mode 100644
index 0000000..b86291a
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup1.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup2.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup2.bin
new file mode 100644
index 0000000..2db116d
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup2.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup3.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup3.bin
new file mode 100644
index 0000000..f103eba
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup3.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup4.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup4.bin
new file mode 100644
index 0000000..87eb2e8
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup4.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup5.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup5.bin
new file mode 100644
index 0000000..dcb51c0
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_backup5.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both0.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both0.bin
new file mode 100644
index 0000000..fdf162c
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both0.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both1.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both1.bin
new file mode 100644
index 0000000..88e369c
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both1.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both2.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both2.bin
new file mode 100644
index 0000000..af0cab4
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both2.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both3.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both3.bin
new file mode 100644
index 0000000..7eb23ab
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both3.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both4.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both4.bin
new file mode 100644
index 0000000..2a80e6f
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both4.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both5.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both5.bin
new file mode 100644
index 0000000..fbf8892
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_both5.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main0.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main0.bin
new file mode 100644
index 0000000..c784a6c
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main0.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main1.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main1.bin
new file mode 100644
index 0000000..3b782de
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main1.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main2.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main2.bin
new file mode 100644
index 0000000..23e7128
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main2.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main3.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main3.bin
new file mode 100644
index 0000000..ecec672
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main3.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main4.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main4.bin
new file mode 100644
index 0000000..646ee2d
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main4.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main5.bin b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main5.bin
new file mode 100644
index 0000000..d3b1f26
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/gpt_main5.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/hyp.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/hyp.mbn
new file mode 100644
index 0000000..8c9854c
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/hyp.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/km4.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/km4.mbn
new file mode 100644
index 0000000..23e5153
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/km4.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/multi_image.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/multi_image.mbn
new file mode 100644
index 0000000..1ab0654
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/multi_image.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/patch0.xml b/installer/rb5/rb5-bootloader-ufs-aosp/patch0.xml
new file mode 100644
index 0000000..28f4a18
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/patch0.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<patches>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Patching is in little endian format, i.e. 0xAABBCCDD will look like DD CC BB AA in the file or on disk-->
+  <!--NOTE: This file is used by Trace32 - So make sure to add decimals, i.e. 0x10-10=0, *but* 0x10-10.=6.-->
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="0" value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1192" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-5." value="NUM_DISK_SECTORS-6." what="Update last partition 10 'userdata' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="DISK" physical_partition_number="0" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="0" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="4" start_sector="4" value="CRC32(0,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="0" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-5.,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main0.bin" physical_partition_number="0" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="0" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="0" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="4" start_sector="4" value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup0.bin" physical_partition_number="0" size_in_bytes="4" start_sector="4" value="CRC32(4,92)" what="Update Backup Header with CRC of Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="0" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="0" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-1.,92)" what="Update Backup Header with CRC of Backup Header."/>
+</patches>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/patch1.xml b/installer/rb5/rb5-bootloader-ufs-aosp/patch1.xml
new file mode 100644
index 0000000..f22f118
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/patch1.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<patches>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Patching is in little endian format, i.e. 0xAABBCCDD will look like DD CC BB AA in the file or on disk-->
+  <!--NOTE: This file is used by Trace32 - So make sure to add decimals, i.e. 0x10-10=0, *but* 0x10-10.=6.-->
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="gpt_main1.bin" physical_partition_number="1" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="DISK" physical_partition_number="1" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="gpt_backup1.bin" physical_partition_number="1" size_in_bytes="8" start_sector="0" value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="DISK" physical_partition_number="1" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-5." value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_main1.bin" physical_partition_number="1" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="1" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_backup1.bin" physical_partition_number="1" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="1" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="gpt_main1.bin" physical_partition_number="1" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="DISK" physical_partition_number="1" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="gpt_backup1.bin" physical_partition_number="1" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="DISK" physical_partition_number="1" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="gpt_backup1.bin" physical_partition_number="1" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="DISK" physical_partition_number="1" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_main1.bin" physical_partition_number="1" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="1" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_backup1.bin" physical_partition_number="1" size_in_bytes="4" start_sector="4" value="CRC32(0,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="1" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-5.,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main1.bin" physical_partition_number="1" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main1.bin" physical_partition_number="1" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="1" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="1" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup1.bin" physical_partition_number="1" size_in_bytes="4" start_sector="4" value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup1.bin" physical_partition_number="1" size_in_bytes="4" start_sector="4" value="CRC32(4,92)" what="Update Backup Header with CRC of Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="1" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="1" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-1.,92)" what="Update Backup Header with CRC of Backup Header."/>
+</patches>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/patch2.xml b/installer/rb5/rb5-bootloader-ufs-aosp/patch2.xml
new file mode 100644
index 0000000..3a21339
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/patch2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<patches>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Patching is in little endian format, i.e. 0xAABBCCDD will look like DD CC BB AA in the file or on disk-->
+  <!--NOTE: This file is used by Trace32 - So make sure to add decimals, i.e. 0x10-10=0, *but* 0x10-10.=6.-->
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="gpt_main2.bin" physical_partition_number="2" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="DISK" physical_partition_number="2" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="gpt_backup2.bin" physical_partition_number="2" size_in_bytes="8" start_sector="0" value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="296" filename="DISK" physical_partition_number="2" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-5." value="NUM_DISK_SECTORS-6." what="Update last partition 3 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_main2.bin" physical_partition_number="2" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="2" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_backup2.bin" physical_partition_number="2" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="2" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="gpt_main2.bin" physical_partition_number="2" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="DISK" physical_partition_number="2" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="gpt_backup2.bin" physical_partition_number="2" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="DISK" physical_partition_number="2" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="gpt_backup2.bin" physical_partition_number="2" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="DISK" physical_partition_number="2" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_main2.bin" physical_partition_number="2" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="2" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_backup2.bin" physical_partition_number="2" size_in_bytes="4" start_sector="4" value="CRC32(0,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="2" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-5.,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main2.bin" physical_partition_number="2" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main2.bin" physical_partition_number="2" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="2" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="2" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup2.bin" physical_partition_number="2" size_in_bytes="4" start_sector="4" value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup2.bin" physical_partition_number="2" size_in_bytes="4" start_sector="4" value="CRC32(4,92)" what="Update Backup Header with CRC of Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="2" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="2" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-1.,92)" what="Update Backup Header with CRC of Backup Header."/>
+</patches>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/patch3.xml b/installer/rb5/rb5-bootloader-ufs-aosp/patch3.xml
new file mode 100644
index 0000000..432fa22
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/patch3.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<patches>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Patching is in little endian format, i.e. 0xAABBCCDD will look like DD CC BB AA in the file or on disk-->
+  <!--NOTE: This file is used by Trace32 - So make sure to add decimals, i.e. 0x10-10=0, *but* 0x10-10.=6.-->
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="552" filename="gpt_main3.bin" physical_partition_number="3" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 5 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="552" filename="DISK" physical_partition_number="3" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 5 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="552" filename="gpt_backup3.bin" physical_partition_number="3" size_in_bytes="8" start_sector="0" value="NUM_DISK_SECTORS-6." what="Update last partition 5 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="552" filename="DISK" physical_partition_number="3" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-5." value="NUM_DISK_SECTORS-6." what="Update last partition 5 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_main3.bin" physical_partition_number="3" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="3" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_backup3.bin" physical_partition_number="3" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="3" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="gpt_main3.bin" physical_partition_number="3" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="DISK" physical_partition_number="3" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="gpt_backup3.bin" physical_partition_number="3" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="DISK" physical_partition_number="3" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="gpt_backup3.bin" physical_partition_number="3" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="DISK" physical_partition_number="3" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_main3.bin" physical_partition_number="3" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="3" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_backup3.bin" physical_partition_number="3" size_in_bytes="4" start_sector="4" value="CRC32(0,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="3" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-5.,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main3.bin" physical_partition_number="3" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main3.bin" physical_partition_number="3" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="3" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="3" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup3.bin" physical_partition_number="3" size_in_bytes="4" start_sector="4" value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup3.bin" physical_partition_number="3" size_in_bytes="4" start_sector="4" value="CRC32(4,92)" what="Update Backup Header with CRC of Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="3" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="3" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-1.,92)" what="Update Backup Header with CRC of Backup Header."/>
+</patches>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/patch4.xml b/installer/rb5/rb5-bootloader-ufs-aosp/patch4.xml
new file mode 100644
index 0000000..8e55310
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/patch4.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<patches>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Patching is in little endian format, i.e. 0xAABBCCDD will look like DD CC BB AA in the file or on disk-->
+  <!--NOTE: This file is used by Trace32 - So make sure to add decimals, i.e. 0x10-10=0, *but* 0x10-10.=6.-->
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="3624" filename="gpt_main4.bin" physical_partition_number="4" size_in_bytes="8" start_sector="3" value="NUM_DISK_SECTORS-6." what="Update last partition 61 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="3624" filename="DISK" physical_partition_number="4" size_in_bytes="8" start_sector="3" value="NUM_DISK_SECTORS-6." what="Update last partition 61 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="3624" filename="gpt_backup4.bin" physical_partition_number="4" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update last partition 61 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="3624" filename="DISK" physical_partition_number="4" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-4." value="NUM_DISK_SECTORS-6." what="Update last partition 61 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_main4.bin" physical_partition_number="4" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="4" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_backup4.bin" physical_partition_number="4" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="4" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="gpt_main4.bin" physical_partition_number="4" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="DISK" physical_partition_number="4" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="gpt_backup4.bin" physical_partition_number="4" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="DISK" physical_partition_number="4" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="gpt_backup4.bin" physical_partition_number="4" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="DISK" physical_partition_number="4" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_main4.bin" physical_partition_number="4" size_in_bytes="4" start_sector="1" value="CRC32(2,8192)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="4" size_in_bytes="4" start_sector="1" value="CRC32(2,8192)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_backup4.bin" physical_partition_number="4" size_in_bytes="4" start_sector="4" value="CRC32(0,8192)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="4" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-5.,8192)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main4.bin" physical_partition_number="4" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main4.bin" physical_partition_number="4" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="4" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="4" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup4.bin" physical_partition_number="4" size_in_bytes="4" start_sector="4" value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup4.bin" physical_partition_number="4" size_in_bytes="4" start_sector="4" value="CRC32(4,92)" what="Update Backup Header with CRC of Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="4" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="4" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-1.,92)" what="Update Backup Header with CRC of Backup Header."/>
+</patches>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/patch5.xml b/installer/rb5/rb5-bootloader-ufs-aosp/patch5.xml
new file mode 100644
index 0000000..3371551
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/patch5.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<patches>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Patching is in little endian format, i.e. 0xAABBCCDD will look like DD CC BB AA in the file or on disk-->
+  <!--NOTE: This file is used by Trace32 - So make sure to add decimals, i.e. 0x10-10=0, *but* 0x10-10.=6.-->
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1832" filename="gpt_main5.bin" physical_partition_number="5" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 15 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1832" filename="DISK" physical_partition_number="5" size_in_bytes="8" start_sector="2" value="NUM_DISK_SECTORS-6." what="Update last partition 15 'last_parti' with actual size in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1832" filename="gpt_backup5.bin" physical_partition_number="5" size_in_bytes="8" start_sector="0" value="NUM_DISK_SECTORS-6." what="Update last partition 15 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="1832" filename="DISK" physical_partition_number="5" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-5." value="NUM_DISK_SECTORS-6." what="Update last partition 15 'last_parti' with actual size in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_main5.bin" physical_partition_number="5" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="5" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-6." what="Update Primary Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="gpt_backup5.bin" physical_partition_number="5" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="48" filename="DISK" physical_partition_number="5" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-6." what="Update Backup Header with LastUseableLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="gpt_main5.bin" physical_partition_number="5" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="32" filename="DISK" physical_partition_number="5" size_in_bytes="8" start_sector="1" value="NUM_DISK_SECTORS-1." what="Update Primary Header with BackupGPT Header Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="gpt_backup5.bin" physical_partition_number="5" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="24" filename="DISK" physical_partition_number="5" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1." value="NUM_DISK_SECTORS-1." what="Update Backup Header with CurrentLBA."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="gpt_backup5.bin" physical_partition_number="5" size_in_bytes="8" start_sector="4" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="DISK" physical_partition_number="5" size_in_bytes="8" start_sector="NUM_DISK_SECTORS-1" value="NUM_DISK_SECTORS-5." what="Update Backup Header with Partition Array Location."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_main5.bin" physical_partition_number="5" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="5" size_in_bytes="4" start_sector="1" value="CRC32(2,4096)" what="Update Primary Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="gpt_backup5.bin" physical_partition_number="5" size_in_bytes="4" start_sector="4" value="CRC32(0,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="88" filename="DISK" physical_partition_number="5" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-5.,4096)" what="Update Backup Header with CRC of Partition Array."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main5.bin" physical_partition_number="5" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_main5.bin" physical_partition_number="5" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="5" size_in_bytes="4" start_sector="1" value="0" what="Zero Out Header CRC in Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="5" size_in_bytes="4" start_sector="1" value="CRC32(1,92)" what="Update Primary Header with CRC of Primary Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup5.bin" physical_partition_number="5" size_in_bytes="4" start_sector="4" value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="gpt_backup5.bin" physical_partition_number="5" size_in_bytes="4" start_sector="4" value="CRC32(4,92)" what="Update Backup Header with CRC of Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="5" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="0" what="Zero Out Header CRC in Backup Header."/>
+  <patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="16" filename="DISK" physical_partition_number="5" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="CRC32(NUM_DISK_SECTORS-1.,92)" what="Update Backup Header with CRC of Backup Header."/>
+</patches>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/prog_firehose_ddr.elf b/installer/rb5/rb5-bootloader-ufs-aosp/prog_firehose_ddr.elf
new file mode 100644
index 0000000..cfd509c
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/prog_firehose_ddr.elf
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/qupv3fw.elf b/installer/rb5/rb5-bootloader-ufs-aosp/qupv3fw.elf
new file mode 100644
index 0000000..b484124
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/qupv3fw.elf
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram0.xml b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram0.xml
new file mode 100644
index 0000000..f0a03e8
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram0.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<data>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Sector size is 4096bytes-->
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="persist" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0x6000" start_sector="6"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="system_a" num_partition_sectors="1501832" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="6007328.0" sparse="false" start_byte_hex="0x2006000" start_sector="8198"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="system_b" num_partition_sectors="1501832" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="6007328.0" sparse="false" start_byte_hex="0x170a8e000" start_sector="1510030"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vendor_boot_a" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x2df516000" start_sector="3011862"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vendor_boot_b" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x2e3516000" start_sector="3028246"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="super" num_partition_sectors="3036432" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="12145728.0" sparse="false" start_byte_hex="0x2e7516000" start_sector="3044630"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="systemrw" num_partition_sectors="4096" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="16384.0" sparse="false" start_byte_hex="0x5cca26000" start_sector="6081062"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="cache" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x5cda26000" start_sector="6085158"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="metadata" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x5d1a26000" start_sector="6101542"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="userdata" num_partition_sectors="0" partofsingleimage="false" physical_partition_number="0" readbackverify="false" size_in_KB="0" sparse="false" start_byte_hex="0x5d5a26000" start_sector="6117926"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_main0.bin" label="PrimaryGPT" num_partition_sectors="6" partofsingleimage="true" physical_partition_number="0" readbackverify="false" size_in_KB="24.0" sparse="false" start_byte_hex="0x0" start_sector="0"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_backup0.bin" label="BackupGPT" num_partition_sectors="5" partofsingleimage="true" physical_partition_number="0" readbackverify="false" size_in_KB="20.0" sparse="false" start_byte_hex="(4096*NUM_DISK_SECTORS)-20480." start_sector="NUM_DISK_SECTORS-5."/>
+</data>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram1.xml b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram1.xml
new file mode 100644
index 0000000..1793287
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram1.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<data>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Sector size is 4096bytes-->
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="xbl.elf" label="xbl_a" num_partition_sectors="896" partofsingleimage="false" physical_partition_number="1" readbackverify="false" size_in_KB="3584.0" sparse="false" start_byte_hex="0x6000" start_sector="6"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="xbl_config.elf" label="xbl_config_a" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="1" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x386000" start_sector="902"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="last_parti" num_partition_sectors="0" partofsingleimage="false" physical_partition_number="1" readbackverify="false" size_in_KB="0" sparse="false" start_byte_hex="0x3a6000" start_sector="934"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_main1.bin" label="PrimaryGPT" num_partition_sectors="6" partofsingleimage="true" physical_partition_number="1" readbackverify="false" size_in_KB="24.0" sparse="false" start_byte_hex="0x0" start_sector="0"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_backup1.bin" label="BackupGPT" num_partition_sectors="5" partofsingleimage="true" physical_partition_number="1" readbackverify="false" size_in_KB="20.0" sparse="false" start_byte_hex="(4096*NUM_DISK_SECTORS)-20480." start_sector="NUM_DISK_SECTORS-5."/>
+</data>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram2.xml b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram2.xml
new file mode 100644
index 0000000..e8aa1b8
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram2.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<data>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Sector size is 4096bytes-->
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="xbl.elf" label="xbl_b" num_partition_sectors="896" partofsingleimage="false" physical_partition_number="2" readbackverify="false" size_in_KB="3584.0" sparse="false" start_byte_hex="0x6000" start_sector="6"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="xbl_config.elf" label="xbl_config_b" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="2" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x386000" start_sector="902"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="last_parti" num_partition_sectors="0" partofsingleimage="false" physical_partition_number="2" readbackverify="false" size_in_KB="0" sparse="false" start_byte_hex="0x3a6000" start_sector="934"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_main2.bin" label="PrimaryGPT" num_partition_sectors="6" partofsingleimage="true" physical_partition_number="2" readbackverify="false" size_in_KB="24.0" sparse="false" start_byte_hex="0x0" start_sector="0"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_backup2.bin" label="BackupGPT" num_partition_sectors="5" partofsingleimage="true" physical_partition_number="2" readbackverify="false" size_in_KB="20.0" sparse="false" start_byte_hex="(4096*NUM_DISK_SECTORS)-20480." start_sector="NUM_DISK_SECTORS-5."/>
+</data>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram3.xml b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram3.xml
new file mode 100644
index 0000000..75a1d39
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram3.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<data>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Sector size is 4096bytes-->
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="ALIGN_TO_128K_1" num_partition_sectors="26" partofsingleimage="false" physical_partition_number="3" readbackverify="false" size_in_KB="104.0" sparse="false" start_byte_hex="0x6000" start_sector="6"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="cdt.bin" label="cdt" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="3" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x20000" start_sector="32"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="ddr" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="3" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x40000" start_sector="64"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdmddr" num_partition_sectors="256" partofsingleimage="false" physical_partition_number="3" readbackverify="false" size_in_KB="1024.0" sparse="false" start_byte_hex="0x240000" start_sector="576"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="last_parti" num_partition_sectors="0" partofsingleimage="false" physical_partition_number="3" readbackverify="false" size_in_KB="0" sparse="false" start_byte_hex="0x340000" start_sector="832"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_main3.bin" label="PrimaryGPT" num_partition_sectors="6" partofsingleimage="true" physical_partition_number="3" readbackverify="false" size_in_KB="24.0" sparse="false" start_byte_hex="0x0" start_sector="0"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_backup3.bin" label="BackupGPT" num_partition_sectors="5" partofsingleimage="true" physical_partition_number="3" readbackverify="false" size_in_KB="20.0" sparse="false" start_byte_hex="(4096*NUM_DISK_SECTORS)-20480." start_sector="NUM_DISK_SECTORS-5."/>
+</data>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram4.xml b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram4.xml
new file mode 100644
index 0000000..474113f
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram4.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" ?>
+<data>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Sector size is 4096bytes-->
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="aop.mbn" label="aop_a" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x6000" start_sector="6"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="tz.mbn" label="tz_a" num_partition_sectors="1024" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4096.0" sparse="false" start_byte_hex="0x86000" start_sector="134"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="hyp.mbn" label="hyp_a" num_partition_sectors="2048" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="8192.0" sparse="false" start_byte_hex="0x486000" start_sector="1158"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="modem_a" num_partition_sectors="101120" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="404480.0" sparse="false" start_byte_hex="0xc86000" start_sector="3206"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="BTFM.bin" label="bluetooth_a" num_partition_sectors="256" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="1024.0" sparse="false" start_byte_hex="0x19786000" start_sector="104326"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdtpsecapp_a" num_partition_sectors="1024" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4096.0" sparse="false" start_byte_hex="0x19886000" start_sector="104582"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdtp_a" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0x19c86000" start_sector="105606"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="abl.elf" label="abl_a" num_partition_sectors="256" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="1024.0" sparse="false" start_byte_hex="0x1bc86000" start_sector="113798"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="dspso.bin" label="dsp_a" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x1bd86000" start_sector="114054"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="km4.mbn" label="keymaster_a" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x1fd86000" start_sector="130438"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="boot_a" num_partition_sectors="24576" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="98304.0" sparse="false" start_byte_hex="0x1fe06000" start_sector="130566"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="cmnlib.mbn" label="cmnlib_a" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x25e06000" start_sector="155142"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="cmnlib64.mbn" label="cmnlib64_a" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x25e86000" start_sector="155270"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="devcfg.mbn" label="devcfg_a" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x25f06000" start_sector="155398"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="qupv3fw.elf" label="qupfw_a" num_partition_sectors="20" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="80.0" sparse="false" start_byte_hex="0x25f26000" start_sector="155430"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vbmeta_a" num_partition_sectors="16" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="64.0" sparse="false" start_byte_hex="0x25f3a000" start_sector="155450"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="dtbo_a" num_partition_sectors="6144" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="24576.0" sparse="false" start_byte_hex="0x25f4a000" start_sector="155466"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="uefi_sec.mbn" label="uefisecapp_a" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x2774a000" start_sector="161610"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="multi_image.mbn" label="multiimgoem_a" num_partition_sectors="8" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32.0" sparse="false" start_byte_hex="0x2794a000" start_sector="162122"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="multiimgqti_a" num_partition_sectors="8" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32.0" sparse="false" start_byte_hex="0x27952000" start_sector="162130"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vm-linux_a" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0x2795a000" start_sector="162138"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="featenabler.mbn" label="featenabler_a" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x2995a000" start_sector="170330"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="imagefv.elf" label="imagefv_a" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x2997a000" start_sector="170362"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="aop.mbn" label="aop_b" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x29b7a000" start_sector="170874"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="tz.mbn" label="tz_b" num_partition_sectors="1024" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4096.0" sparse="false" start_byte_hex="0x29bfa000" start_sector="171002"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="hyp.mbn" label="hyp_b" num_partition_sectors="2048" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="8192.0" sparse="false" start_byte_hex="0x29ffa000" start_sector="172026"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="modem_b" num_partition_sectors="101120" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="404480.0" sparse="false" start_byte_hex="0x2a7fa000" start_sector="174074"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="BTFM.bin" label="bluetooth_b" num_partition_sectors="256" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="1024.0" sparse="false" start_byte_hex="0x432fa000" start_sector="275194"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdtpsecapp_b" num_partition_sectors="1024" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4096.0" sparse="false" start_byte_hex="0x433fa000" start_sector="275450"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdtp_b" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0x437fa000" start_sector="276474"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="abl.elf" label="abl_b" num_partition_sectors="256" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="1024.0" sparse="false" start_byte_hex="0x457fa000" start_sector="284666"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="dspso.bin" label="dsp_b" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x458fa000" start_sector="284922"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="km4.mbn" label="keymaster_b" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x498fa000" start_sector="301306"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="boot-erase.img" label="boot_b" num_partition_sectors="24576" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="98304.0" sparse="false" start_byte_hex="0x4997a000" start_sector="301434"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="cmnlib.mbn" label="cmnlib_b" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x4f97a000" start_sector="326010"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="cmnlib64.mbn" label="cmnlib64_b" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x4f9fa000" start_sector="326138"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="devcfg.mbn" label="devcfg_b" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x4fa7a000" start_sector="326266"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="qupv3fw.elf" label="qupfw_b" num_partition_sectors="20" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="80.0" sparse="false" start_byte_hex="0x4fa9a000" start_sector="326298"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vbmeta_b" num_partition_sectors="16" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="64.0" sparse="false" start_byte_hex="0x4faae000" start_sector="326318"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="dtbo_b" num_partition_sectors="6144" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="24576.0" sparse="false" start_byte_hex="0x4fabe000" start_sector="326334"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="uefi_sec.mbn" label="uefisecapp_b" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x512be000" start_sector="332478"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="multi_image.mbn" label="multiimgoem_b" num_partition_sectors="8" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32.0" sparse="false" start_byte_hex="0x514be000" start_sector="332990"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="multiimgqti_b" num_partition_sectors="8" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32.0" sparse="false" start_byte_hex="0x514c6000" start_sector="332998"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vm-linux_b" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0x514ce000" start_sector="333006"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="featenabler.mbn" label="featenabler_b" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x534ce000" start_sector="341198"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="imagefv.elf" label="imagefv_b" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x534ee000" start_sector="341230"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="devinfo" num_partition_sectors="1" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4.0" sparse="false" start_byte_hex="0x536ee000" start_sector="341742"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="dip" num_partition_sectors="256" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="1024.0" sparse="false" start_byte_hex="0x536ef000" start_sector="341743"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="apdp.mbn" label="apdp" num_partition_sectors="64" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="256.0" sparse="false" start_byte_hex="0x537ef000" start_sector="341999"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="msadp" num_partition_sectors="64" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="256.0" sparse="false" start_byte_hex="0x5382f000" start_sector="342063"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="spunvm.bin" label="spunvm" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0x5386f000" start_sector="342127"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="limits" num_partition_sectors="1" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4.0" sparse="false" start_byte_hex="0x5586f000" start_sector="350319"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="limits-cdsp" num_partition_sectors="1" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4.0" sparse="false" start_byte_hex="0x55870000" start_sector="350320"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="logfs_ufs_8mb.bin" label="logfs" num_partition_sectors="2048" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="8192.0" sparse="false" start_byte_hex="0x55871000" start_sector="350321"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="logdump" num_partition_sectors="16384" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="65536.0" sparse="false" start_byte_hex="0x56071000" start_sector="352369"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="storsec" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x5a071000" start_sector="368753"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="uefivarstore" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x5a091000" start_sector="368785"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="secdata" num_partition_sectors="7" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="28.0" sparse="false" start_byte_hex="0x5a111000" start_sector="368913"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vm-keystore" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x5a118000" start_sector="368920"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="vm-data" num_partition_sectors="1024" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="4096.0" sparse="false" start_byte_hex="0x5a138000" start_sector="368952"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="last_parti" num_partition_sectors="0" partofsingleimage="false" physical_partition_number="4" readbackverify="false" size_in_KB="0" sparse="false" start_byte_hex="0x5a538000" start_sector="369976"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_main4.bin" label="PrimaryGPT" num_partition_sectors="6" partofsingleimage="true" physical_partition_number="4" readbackverify="false" size_in_KB="24.0" sparse="false" start_byte_hex="0x0" start_sector="0"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_backup4.bin" label="BackupGPT" num_partition_sectors="5" partofsingleimage="true" physical_partition_number="4" readbackverify="false" size_in_KB="20.0" sparse="false" start_byte_hex="(4096*NUM_DISK_SECTORS)-20480." start_sector="NUM_DISK_SECTORS-5."/>
+</data>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram5.xml b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram5.xml
new file mode 100644
index 0000000..52a39dc
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/rawprogram5.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<data>
+  <!--NOTE: This is an ** Autogenerated file **-->
+  <!--NOTE: Sector size is 4096bytes-->
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="ALIGN_TO_128K_2" num_partition_sectors="26" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="104.0" sparse="false" start_byte_hex="0x6000" start_sector="6"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="modemst1" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x20000" start_sector="32"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="modemst2" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x220000" start_sector="544"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="fsg" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x420000" start_sector="1056"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="fsc" num_partition_sectors="32" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="128.0" sparse="false" start_byte_hex="0x620000" start_sector="1568"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdm1m9kefs3" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x640000" start_sector="1600"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdm1m9kefs1" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0x840000" start_sector="2112"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdm1m9kefs2" num_partition_sectors="512" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="2048.0" sparse="false" start_byte_hex="0xa40000" start_sector="2624"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="mdm1m9kefsc" num_partition_sectors="1" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="4.0" sparse="false" start_byte_hex="0xc40000" start_sector="3136"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="ssd" num_partition_sectors="2" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="8.0" sparse="false" start_byte_hex="0xc41000" start_sector="3137"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="persist" num_partition_sectors="8192" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="32768.0" sparse="false" start_byte_hex="0xc43000" start_sector="3139"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="misc" num_partition_sectors="256" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="1024.0" sparse="false" start_byte_hex="0x2c43000" start_sector="11331"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="keystore" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x2d43000" start_sector="11587"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="frp" num_partition_sectors="128" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="512.0" sparse="false" start_byte_hex="0x2dc3000" start_sector="11715"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="" label="last_parti" num_partition_sectors="0" partofsingleimage="false" physical_partition_number="5" readbackverify="false" size_in_KB="0" sparse="false" start_byte_hex="0x2e43000" start_sector="11843"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_main5.bin" label="PrimaryGPT" num_partition_sectors="6" partofsingleimage="true" physical_partition_number="5" readbackverify="false" size_in_KB="24.0" sparse="false" start_byte_hex="0x0" start_sector="0"/>
+  <program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="gpt_backup5.bin" label="BackupGPT" num_partition_sectors="5" partofsingleimage="true" physical_partition_number="5" readbackverify="false" size_in_KB="20.0" sparse="false" start_byte_hex="(4096*NUM_DISK_SECTORS)-20480." start_sector="NUM_DISK_SECTORS-5."/>
+</data>
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/spunvm.bin b/installer/rb5/rb5-bootloader-ufs-aosp/spunvm.bin
new file mode 100644
index 0000000..54b48b6
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/spunvm.bin
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/tz.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/tz.mbn
new file mode 100644
index 0000000..1f97ae4
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/tz.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/uefi_sec.mbn b/installer/rb5/rb5-bootloader-ufs-aosp/uefi_sec.mbn
new file mode 100644
index 0000000..295dab4
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/uefi_sec.mbn
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/xbl.elf b/installer/rb5/rb5-bootloader-ufs-aosp/xbl.elf
new file mode 100644
index 0000000..8e4c277
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/xbl.elf
Binary files differ
diff --git a/installer/rb5/rb5-bootloader-ufs-aosp/xbl_config.elf b/installer/rb5/rb5-bootloader-ufs-aosp/xbl_config.elf
new file mode 100644
index 0000000..90c2212
--- /dev/null
+++ b/installer/rb5/rb5-bootloader-ufs-aosp/xbl_config.elf
Binary files differ
diff --git a/installer/rb5/recovery.sh b/installer/rb5/recovery.sh
new file mode 100755
index 0000000..5541209
--- /dev/null
+++ b/installer/rb5/recovery.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+INSTALLER_DIR="`dirname ${0}`"
+
+QDL="`readlink -f ${INSTALLER_DIR}/qdl`"
+FIRMWARE_DIR="rb5-bootloader-ufs-aosp"
+
+# for cases that don't run "lunch rb5-userdebug"
+if [ -z "${ANDROID_BUILD_TOP}" ]; then
+    ANDROID_BUILD_TOP=${INSTALLER_DIR}/../../../../../
+    ANDROID_PRODUCT_OUT="${ANDROID_BUILD_TOP}/out/target/product/rb5"
+fi
+
+if [ ! -d "${ANDROID_PRODUCT_OUT}" ]; then
+    echo "RECOVERY: error in locating out directory, check if it exist"
+    exit
+fi
+
+echo "android out dir:${ANDROID_PRODUCT_OUT}"
+
+# TODO: Pull one-time recovery/qdl path out of standard install
+# Flash bootloader firmware files
+if [ ! -d "${INSTALLER_DIR}/${FIRMWARE_DIR}/" ]; then
+    echo "RECOVERY: No firmware directory? Make sure binaries have been provided"
+    exit
+fi
+
+pushd "${INSTALLER_DIR}/${FIRMWARE_DIR}" > /dev/null
+sudo "${QDL}" prog_firehose_ddr.elf rawprogram?.xml patch?.xml
+popd > /dev/null
+
+echo
+echo
+echo "RECOVERY: Please boot the RB5 into fastboot mode, and use the flash-all-aosp.sh script!"
+echo
diff --git a/libmemtrack/Android.mk b/libmemtrack/Android.mk
deleted file mode 100644
index 913cb22..0000000
--- a/libmemtrack/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2017 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.
-
-LOCAL_PATH := $(call my-dir)
-
-# HAL module implemenation stored in
-# hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_C_INCLUDES += hardware/libhardware/include
-LOCAL_CFLAGS := -Wconversion -Wall -Werror -Wno-sign-conversion
-LOCAL_CLANG  := true
-LOCAL_SHARED_LIBRARIES := liblog libhardware
-LOCAL_SRC_FILES := memtrack_dragonboard.c
-LOCAL_MODULE := memtrack.default
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libmemtrack/memtrack_dragonboard.c b/libmemtrack/memtrack_dragonboard.c
deleted file mode 100644
index b7da750..0000000
--- a/libmemtrack/memtrack_dragonboard.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <errno.h>
-
-#include <hardware/memtrack.h>
-
-int dragonboard_memtrack_init(const struct memtrack_module *module)
-{
-    if (!module)
-        return -1;
-
-    return 0;
-}
-
-static struct hw_module_methods_t memtrack_module_methods = {
-    .open = NULL,
-};
-
-struct memtrack_module HAL_MODULE_INFO_SYM = {
-    .common = {
-        .tag = HARDWARE_MODULE_TAG,
-        .module_api_version = MEMTRACK_MODULE_API_VERSION_0_1,
-        .hal_api_version = HARDWARE_HAL_API_VERSION,
-        .id = MEMTRACK_HARDWARE_MODULE_ID,
-        .name = "Dummy Memory Tracker HAL for Dragonboards",
-        .author = "The Android Open Source Project",
-        .methods = &memtrack_module_methods,
-    },
-
-    .init = dragonboard_memtrack_init,
-};
diff --git a/manifest.xml b/manifest.xml
index 10362de..99c8500 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -1,8 +1,8 @@
-<manifest version="1.0" type="device" target-level="2">
+<manifest version="1.0" type="device" target-level="6">
     <hal format="hidl">
         <name>android.hardware.audio</name>
         <transport>hwbinder</transport>
-        <version>4.0</version>
+        <version>7.0</version>
         <interface>
             <name>IDevicesFactory</name>
             <instance>default</instance>
@@ -11,7 +11,7 @@
     <hal format="hidl">
         <name>android.hardware.audio.effect</name>
         <transport>hwbinder</transport>
-        <version>4.0</version>
+        <version>7.0</version>
         <interface>
             <name>IEffectsFactory</name>
             <instance>default</instance>
@@ -27,15 +27,6 @@
         </interface>
     </hal>
     <hal format="hidl">
-        <name>android.hardware.bluetooth.a2dp</name>
-        <transport>hwbinder</transport>
-        <version>1.0</version>
-        <interface>
-            <name>IBluetoothAudioOffload</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
         <name>android.hardware.bluetooth.audio</name>
         <transport>hwbinder</transport>
         <version>2.0</version>
@@ -45,18 +36,19 @@
         </interface>
     </hal>
     <hal format="hidl">
-        <name>android.hardware.configstore</name>
+        <name>android.hardware.camera.provider</name>
         <transport>hwbinder</transport>
-        <version>1.1</version>
+        <impl level="generic"></impl>
+        <version>2.4</version>
         <interface>
-            <name>ISurfaceFlingerConfigs</name>
-            <instance>default</instance>
+            <name>ICameraProvider</name>
+            <instance>external/0</instance>
         </interface>
     </hal>
     <hal format="hidl">
         <name>android.hardware.drm</name>
         <transport>hwbinder</transport>
-        <version>1.0</version>
+        <version>1.3</version>
         <interface>
             <name>ICryptoFactory</name>
             <instance>default</instance>
@@ -67,42 +59,15 @@
         </interface>
     </hal>
     <hal format="hidl">
-        <name>android.hardware.graphics.allocator</name>
-        <transport>hwbinder</transport>
-        <version>2.0</version>
-        <interface>
-            <name>IAllocator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
         <name>android.hardware.graphics.composer</name>
         <transport>hwbinder</transport>
-        <version>2.2</version>
+        <version>2.3</version>
         <interface>
             <name>IComposer</name>
             <instance>default</instance>
         </interface>
     </hal>
     <hal format="hidl">
-        <name>android.hardware.graphics.mapper</name>
-        <transport arch="32+64">passthrough</transport>
-        <version>2.1</version>
-        <interface>
-            <name>IMapper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.health</name>
-        <transport>hwbinder</transport>
-        <version>2.0</version>
-        <interface>
-            <name>IHealth</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <transport>hwbinder</transport>
         <version>3.0</version>
@@ -124,19 +89,10 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl">
-        <name>android.hardware.memtrack</name>
-        <transport>hwbinder</transport>
-        <version>1.0</version>
-        <interface>
-            <name>IMemtrack</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
+   <hal format="hidl">
         <name>android.hardware.soundtrigger</name>
         <transport>hwbinder</transport>
-        <version>2.0</version>
+        <version>2.3</version>
         <interface>
             <name>ISoundTriggerHw</name>
             <instance>default</instance>
diff --git a/pixel3_mainline.mk b/pixel3_mainline.mk
index 97351ea..1b205c2 100644
--- a/pixel3_mainline.mk
+++ b/pixel3_mainline.mk
@@ -21,28 +21,6 @@
   BOARD_VENDOR_KERNEL_MODULES += $(PIXEL3_MODS)
   P3_ONLY_VENDOR := %/msm.ko %/dwc3.ko %/dwc3-qcom.ko %/hci_uart.ko %/btqca.ko %/incrementalfs.ko
   P3_ONLY_VENDOR += %/ath10k_core.ko %/ath10k_pci.ko %/ath10k_snoc.ko %/ath.ko
-  P3_ONLY_VENDOR += %/apr.ko %/qcom_q6v5_ipa_notify.ko
-  P3_ONLY_VENDOR += %/ns.ko %/qcom_q6v5.ko %/qrtr.ko %/qcom_q6v5_mss.ko %/qrtr-smd.ko
-  P3_ONLY_VENDOR += %/qcom_q6v5_pas.ko %/qrtr-tun.ko %/snd-soc-hdmi-codec.ko
-  P3_ONLY_VENDOR += %/qcom_q6v5_wcss.ko
-  P3_ONLY_VENDOR += %/rmtfs_mem.ko
-  P3_ONLY_VENDOR += %/wcn36xx.ko %/wcnss_ctrl.ko
-  P3_ONLY_VENDOR += %/qcom_wcnss_pil.ko %/mdt_loader.ko
-  P3_ONLY_VENDOR += %/qcom_q6v5_adsp.ko
-  P3_ONLY_VENDOR += %/ehci-hcd.ko %/ehci-pci.ko %/ehci-platform.ko %/xhci-hcd.ko %/xhci-pci.ko %/xhci-pci-renesas.ko %/xhci-plat-hcd.ko
-  P3_ONLY_VENDOR += %/lt9611.ko %/panel-tianma-nt36672a.ko %/ax88179_178a.ko %/msm_serial.ko %/asix.ko
-  P3_ONLY_VENDOR += %/qcom-wdt.ko %/i2c-qup.ko %/i2c-gpio.ko %/phy-qcom-usb-hs.ko %/ulpi.ko %/extcon-usb-gpio.ko
-  P3_ONLY_VENDOR += %/nvmem_qfprom.ko %/pm8916_wdt.ko %/llcc-qcom.ko
-  P3_ONLY_VENDOR += %/i2c-qcom-geni.ko %/qcom-pon.ko %/syscon-reboot-mode.ko %/reboot-mode.ko
-  P3_ONLY_VENDOR += %/fastrpc.ko %/ohci-hcd.ko %/ohci-pci.ko %/ohci-platform.ko %/phy-qcom-qusb2.ko
-  P3_ONLY_VENDOR += %/spmi-pmic-arb.ko %/rtc-pm8xxx.ko %/socinfo.ko
-  P3_ONLY_VENDOR += %/smsm.ko %/smp2p.ko %/smem.ko %/qcom_smd.ko %/qcom_glink_smem.ko %/qcom_glink.ko %/qcom_glink_rpm.ko %/qcom_common.ko
-  P3_ONLY_VENDOR += %/regmap-spmi.ko %/qcom-spmi-pmic.ko
-  P3_ONLY_VENDOR += %/qcom_sysmon.ko
-  P3_ONLY_VENDOR += %/qmi_helpers.ko %/pdr_interface.ko
-  P3_ONLY_VENDOR += %/icc-bcm-voter.ko %/icc-rpmh.ko %/qnoc-sdm845.ko
-  P3_ONLY_VENDOR += %/qcom_gsbi.ko %/pm8941-pwrkey.ko
-  P3_ONLY_VENDOR += %/pinctrl-spmi-mpp.ko %/ocmem.ko %/gcc-msm8998.ko %/clk-scmi.ko
 
   BOARD_VENDOR_RAMDISK_KERNEL_MODULES := $(filter-out $(P3_ONLY_VENDOR),$(PIXEL3_MODS))
 endif
diff --git a/pixel3_mainline/BoardConfig.mk b/pixel3_mainline/BoardConfig.mk
index 26fd66a..1ee5544 100644
--- a/pixel3_mainline/BoardConfig.mk
+++ b/pixel3_mainline/BoardConfig.mk
@@ -19,5 +19,5 @@
 BOARD_FLASH_BLOCK_SIZE := 131072
 # Super partition
 BOARD_SUPER_PARTITION_SIZE := 2952790016
-BOARD_DB_DYNAMIC_PARTITIONS_SIZE := 2952790016
+BOARD_DB_DYNAMIC_PARTITIONS_SIZE := 2948595712  # Reserve 4M for DAP metadata
 BOARD_SUPER_PARTITION_METADATA_DEVICE := system_b
diff --git a/pixel3_mainline/device.mk b/pixel3_mainline/device.mk
index e394c60..f1af165 100644
--- a/pixel3_mainline/device.mk
+++ b/pixel3_mainline/device.mk
@@ -19,13 +19,13 @@
 $(call inherit-product, frameworks/native/build/phone-xhdpi-2048-dalvik-heap.mk)
 
 PRODUCT_COPY_FILES := \
-    device/linaro/dragonboard/fstab.common:$(TARGET_COPY_OUT_RAMDISK)/fstab.pixel3_mainline \
-    device/linaro/dragonboard/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.pixel3_mainline \
+    device/linaro/dragonboard/pixel3_mainline/fstab.pixel3_mainline:$(TARGET_COPY_OUT_RAMDISK)/fstab.pixel3_mainline \
+    device/linaro/dragonboard/pixel3_mainline/fstab.pixel3_mainline:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.pixel3_mainline \
     device/linaro/dragonboard/init.common.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.pixel3_mainline.rc \
     device/linaro/dragonboard/init.common.usb.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.pixel3_mainline.usb.rc \
     device/linaro/dragonboard/common.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/pixel3_mainline.kl
 
-ifneq ("$(wildcard $(PIXEL3_KERNEL_DIR)/Image.gz-dtb)","")
+ifneq (,$(wildcard $(PIXEL3_KERNEL_DIR)/Image.gz-dtb))
     PRODUCT_COPY_FILES += $(PIXEL3_KERNEL_DIR)/Image.gz-dtb:kernel
     PIXEL3_KERNEL_FOUND := true
 else
@@ -35,5 +35,8 @@
 # Build generic Audio HAL
 PRODUCT_PACKAGES := audio.primary.pixel3_mainline
 
+PRODUCT_PROPERTY_OVERRIDES += \
+    ro.sf.lcd_density=443
+
 # Copy firmware files
 $(call inherit-product-if-exists, $(LOCAL_PATH)/firmware/device.mk)
diff --git a/pixel3_mainline/fstab.pixel3_mainline b/pixel3_mainline/fstab.pixel3_mainline
new file mode 100644
index 0000000..5d82515
--- /dev/null
+++ b/pixel3_mainline/fstab.pixel3_mainline
@@ -0,0 +1,8 @@
+system		/system		ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
+/dev/block/platform/soc@0/1d84000.ufshc/by-name/userdata /data		ext4	discard,noatime,noauto_da_alloc,data=ordered,user_xattr,barrier=1,inlinecrypt	wait,formattable,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,quota
+/dev/block/platform/soc@0/1d84000.ufshc/by-name/metadata	/metadata	ext4	noatime,nosuid,nodev,discard					wait,formattable
+#/dev/block/platform/soc@0/1d84000.ufshc/by-name/misc /misc emmc defaults defaults
+/devices/platform/soc@0/8804000.sdhci/mmc_host/mmc*	auto	auto	defaults	voldmanaged=sdcard1:auto
+vendor		/vendor		ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
+system_ext	/system_ext	ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
+product	/product	ext4	noatime,ro,errors=panic		wait,logical,first_stage_mount
diff --git a/qcom/init.qcom.rc b/qcom/init.qcom.rc
index 94e9038..f97b502 100644
--- a/qcom/init.qcom.rc
+++ b/qcom/init.qcom.rc
@@ -32,31 +32,6 @@
 
 on post-fs
     start pd_mapper
-    exec - root -- /system/bin/sleep 1
-    exec - system audio -- /system/bin/tinymix "QUAT_MI2S_RX Audio Mixer MultiMedia1" 1
-    exec - system audio -- /system/bin/tinymix "QUAT_MI2S_RX Audio Mixer MultiMedia2" 1
-    exec - system audio -- /system/bin/tinymix "SLIM RX0 MUX" AIF1_PB
-    exec - system audio -- /system/bin/tinymix "SLIM RX0 MUX" ZERO
-    exec - system audio -- /system/bin/tinymix "SLIM RX1 MUX" ZERO
-    exec - system audio -- /system/bin/tinymix "SLIM RX2 MUX" ZERO
-    exec - system audio -- /system/bin/tinymix "SLIM RX3 MUX" ZERO
-    exec - system audio -- /system/bin/tinymix "SLIM RX4 MUX" ZERO
-    exec - system audio -- /system/bin/tinymix "SLIM RX5 MUX" ZERO
-    exec - system audio -- /system/bin/tinymix "SLIM RX6 MUX" AIF1_PB
-    exec - system audio -- /system/bin/tinymix "SLIM RX7 MUX" AIF1_PB
-    exec - system audio -- /system/bin/tinymix "RX INT7_1 MIX1 INP0" RX6
-    exec - system audio -- /system/bin/tinymix "RX INT8_1 MIX1 INP0" RX7
-    exec - system audio -- /system/bin/tinymix "COMP7 Switch" 1
-    exec - system audio -- /system/bin/tinymix "COMP8 Switch" 1
-    exec - system audio -- /system/bin/tinymix "SpkrLeft COMP Switch" 1
-    exec - system audio -- /system/bin/tinymix "SpkrLeft BOOST Switch" 1
-    exec - system audio -- /system/bin/tinymix "SpkrLeft VISENSE Switch" 0
-    exec - system audio -- /system/bin/tinymix "SpkrLeft DAC Switch" 1
-    exec - system audio -- /system/bin/tinymix "SpkrRight COMP Switch" 1
-    exec - system audio -- /system/bin/tinymix "SpkrRight BOOST Switch" 1
-    exec - system audio -- /system/bin/tinymix "SpkrRight VISENSE Switch" 0
-    exec - system audio -- /system/bin/tinymix "SpkrRight DAC Switch" 1
-    exec - system audio -- /system/bin/tinymix "SLIMBUS_0_RX Audio Mixer MultiMedia2" 1
 
 on post-fs-data
     mkdir /data/vendor
diff --git a/qcom/pd-mapper/Android.bp b/qcom/pd-mapper/Android.bp
index 3bdbc32..7e86231 100644
--- a/qcom/pd-mapper/Android.bp
+++ b/qcom/pd-mapper/Android.bp
@@ -1,3 +1,22 @@
+package {
+    default_applicable_licenses: [
+        "device_linaro_dragonboard_qcom_pd-mapper_license",
+    ],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "device_linaro_dragonboard_qcom_pd-mapper_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: [
+        "LICENSE",
+    ],
+}
+
 cc_binary {
     name: "pd-mapper",
     vendor: true,
diff --git a/qcom/pd-mapper/assoc.c b/qcom/pd-mapper/assoc.c
index 692c882..460f0d0 100644
--- a/qcom/pd-mapper/assoc.c
+++ b/qcom/pd-mapper/assoc.c
@@ -128,7 +128,7 @@
 {
 	unsigned long it = *iter;
 
-	while (!assoc->keys[it] && it < assoc->size)
+	while (it < assoc->size && !assoc->keys[it])
 		it++;
 
 	if (it == assoc->size)
diff --git a/qcom/qrtr/Android.bp b/qcom/qrtr/Android.bp
index 9544a75..8103bb6 100644
--- a/qcom/qrtr/Android.bp
+++ b/qcom/qrtr/Android.bp
@@ -1,3 +1,22 @@
+package {
+    default_applicable_licenses: [
+        "device_linaro_dragonboard_qcom_qrtr_license",
+    ],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "device_linaro_dragonboard_qcom_qrtr_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: [
+        "LICENSE",
+    ],
+}
+
 cc_library {
     name: "libqrtr",
     vendor: true,
diff --git a/qcom/rmtfs/Android.bp b/qcom/rmtfs/Android.bp
index 7865a99..82cf7e1 100644
--- a/qcom/rmtfs/Android.bp
+++ b/qcom/rmtfs/Android.bp
@@ -1,3 +1,22 @@
+package {
+    default_applicable_licenses: [
+        "device_linaro_dragonboard_qcom_rmtfs_license",
+    ],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "device_linaro_dragonboard_qcom_rmtfs_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: [
+        "LICENSE",
+    ],
+}
+
 cc_binary {
     name: "rmtfs",
     vendor: true,
diff --git a/qcom/set_udc.sh b/qcom/set_udc.sh
new file mode 100755
index 0000000..571c25d
--- /dev/null
+++ b/qcom/set_udc.sh
@@ -0,0 +1,17 @@
+#! /vendor/bin/sh
+# Grep and set the vendor.usb.controller property from
+# /sys/class/udc at the boot time.
+#
+# Upstream commit eb9b7bfd5954 ("arm64: dts: qcom: Harmonize DWC
+# USB3 DT nodes name") (v5.14-rc1) changed the DTS USB node names,
+# breaking the sys.usb.controller property hardcoded in the
+# platform specific init.usb.common.rc
+#
+# This script will get rid of the static/hardcoded property name
+# which we set in init.<hw>.usb.rc and set it to the available
+# on-board USB controller from /sys/class/udc instead.
+
+# Searching for db845c's DWC3 UDC explicitly
+UDC_ADDRESS=a600000
+UDC=`/vendor/bin/ls /sys/class/udc/ | /vendor/bin/grep $UDC_ADDRESS`
+setprop vendor.usb.controller $UDC
diff --git a/qcom/tqftpserv/Android.bp b/qcom/tqftpserv/Android.bp
index b2c5090..248c323 100644
--- a/qcom/tqftpserv/Android.bp
+++ b/qcom/tqftpserv/Android.bp
@@ -1,3 +1,22 @@
+package {
+    default_applicable_licenses: [
+        "device_linaro_dragonboard_qcom_tqftpserv_license",
+    ],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "device_linaro_dragonboard_qcom_tqftpserv_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: [
+        "LICENSE",
+    ],
+}
+
 cc_binary {
     name: "tqftpserv",
     vendor: true,
diff --git a/rb5.mk b/rb5.mk
new file mode 100644
index 0000000..dc70674
--- /dev/null
+++ b/rb5.mk
@@ -0,0 +1,27 @@
+ifndef TARGET_KERNEL_USE
+TARGET_KERNEL_USE := mainline
+endif
+RB5_KERNEL_DIR := device/linaro/dragonboard-kernel/android-$(TARGET_KERNEL_USE)
+
+# Inherit the full_base and device configurations
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, device/linaro/dragonboard/rb5/device.mk)
+$(call inherit-product, device/linaro/dragonboard/device-common.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk)
+
+# Product overrides
+PRODUCT_NAME := rb5
+PRODUCT_DEVICE := rb5
+PRODUCT_BRAND := Android
+
+ifndef RB5_USES_GKI
+  RB5_USES_GKI := true
+endif
+
+ifeq ($(RB5_USES_GKI), true)
+  RB5_MODS := $(wildcard $(RB5_KERNEL_DIR)/*.ko)
+  ifneq ($(RB5_MODS),)
+    RB5_SKIP_MODS := %/venus-core.ko %/venus-dec.ko %/venus-enc.ko
+    BOARD_VENDOR_RAMDISK_KERNEL_MODULES := $(filter-out $(RB5_SKIP_MODS),$(RB5_MODS))
+  endif
+endif
diff --git a/rb5/BoardConfig.mk b/rb5/BoardConfig.mk
new file mode 100644
index 0000000..415cff1
--- /dev/null
+++ b/rb5/BoardConfig.mk
@@ -0,0 +1,30 @@
+include device/linaro/dragonboard/BoardConfigCommon.mk
+
+# Board Information
+TARGET_BOOTLOADER_BOARD_NAME := rb5
+TARGET_BOARD_PLATFORM := rb5
+
+TARGET_NO_KERNEL := false
+BOARD_KERNEL_BASE := 0x80000000
+BOARD_KERNEL_PAGESIZE := 4096
+
+BOARD_INCLUDE_DTB_IN_BOOTIMG := true
+BOARD_BOOT_HEADER_VERSION := 3
+BOARD_MKBOOTIMG_ARGS := --header_version $(BOARD_BOOT_HEADER_VERSION)
+
+BOARD_KERNEL_CMDLINE := earlycon firmware_class.path=/vendor/firmware/ androidboot.hardware=rb5
+BOARD_KERNEL_CMDLINE += init=/init androidboot.boot_devices=soc@0/1d84000.ufshc printk.devkmsg=on
+BOARD_KERNEL_CMDLINE += pcie_pme=nomsi #For WiFi to work
+BOARD_KERNEL_CMDLINE += deferred_probe_timeout=30
+
+# Image Configuration
+BOARD_BOOTIMAGE_PARTITION_SIZE := 67108864 #64M
+BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE := 67108864 #64M
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 21474836480
+BOARD_FLASH_BLOCK_SIZE := 131072
+
+# Super/Dynamic partition
+BOARD_SUPER_PARTITION_SIZE := 12437225472
+BOARD_DB_DYNAMIC_PARTITIONS_SIZE := 12433031168 # Reserve 4M for DAP metadata
+BOARD_SUPER_PARTITION_METADATA_DEVICE := super
+BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE := true
diff --git a/rb5/device.mk b/rb5/device.mk
new file mode 100644
index 0000000..cab614f
--- /dev/null
+++ b/rb5/device.mk
@@ -0,0 +1,69 @@
+#
+# Copyright (C) 2011 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.
+#
+
+PRODUCT_SOONG_NAMESPACES += \
+    device/linaro/dragonboard
+
+# setup dalvik vm configs
+$(call inherit-product, frameworks/native/build/tablet-10in-xhdpi-2048-dalvik-heap.mk)
+
+# Enable Virtual A/B
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS += \
+    product \
+    system \
+    system_ext \
+    vendor
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk)
+
+PRODUCT_COPY_FILES := \
+    $(RB5_KERNEL_DIR)/Image.gz:kernel \
+    $(RB5_KERNEL_DIR)/qrb5165-rb5.dtb:dtb.img \
+    $(LOCAL_PATH)/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    device/linaro/dragonboard/fstab.common:$(TARGET_COPY_OUT_RAMDISK)/fstab.rb5 \
+    device/linaro/dragonboard/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.rb5 \
+    device/linaro/dragonboard/init.common.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.rb5.rc \
+    device/linaro/dragonboard/init.common.usb.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.rb5.usb.rc \
+    device/linaro/dragonboard/common.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/rb5.kl
+
+# Build generic Audio HAL
+PRODUCT_PACKAGES := audio.primary.rb5
+
+# BootControl HAL
+PRODUCT_PACKAGES += \
+    android.hardware.boot@1.2-impl \
+    android.hardware.boot@1.2-impl.recovery \
+    android.hardware.boot@1.2-service
+
+PRODUCT_PACKAGES += \
+    pd-mapper \
+    qrtr-ns \
+    qrtr-cfg \
+    qrtr-lookup \
+    rmtfs \
+    tqftpserv
+
+PRODUCT_COPY_FILES += \
+    device/linaro/dragonboard/qcom/init.qcom.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.qcom.rc
+
+PRODUCT_VENDOR_PROPERTIES += ro.soc.manufacturer=Qualcomm
+PRODUCT_VENDOR_PROPERTIES += ro.soc.model=QRB5165
+
+PRODUCT_PROPERTY_OVERRIDES += ro.sf.lcd_density=160
+
+# Copy firmware files
+$(call inherit-product-if-exists, $(LOCAL_PATH)/firmware/device.mk)
diff --git a/rb5/firmware/a650_gmu.bin b/rb5/firmware/a650_gmu.bin
new file mode 100644
index 0000000..e497a14
--- /dev/null
+++ b/rb5/firmware/a650_gmu.bin
Binary files differ
diff --git a/rb5/firmware/a650_sqe.fw b/rb5/firmware/a650_sqe.fw
new file mode 100644
index 0000000..6cbef9b
--- /dev/null
+++ b/rb5/firmware/a650_sqe.fw
Binary files differ
diff --git a/rb5/firmware/a650_zap.b00 b/rb5/firmware/a650_zap.b00
new file mode 100644
index 0000000..1a708db
--- /dev/null
+++ b/rb5/firmware/a650_zap.b00
Binary files differ
diff --git a/rb5/firmware/a650_zap.b01 b/rb5/firmware/a650_zap.b01
new file mode 100644
index 0000000..4dd0de3
--- /dev/null
+++ b/rb5/firmware/a650_zap.b01
Binary files differ
diff --git a/rb5/firmware/a650_zap.b02 b/rb5/firmware/a650_zap.b02
new file mode 100644
index 0000000..fcfe901
--- /dev/null
+++ b/rb5/firmware/a650_zap.b02
Binary files differ
diff --git a/rb5/firmware/a650_zap.elf b/rb5/firmware/a650_zap.elf
new file mode 100644
index 0000000..ef5624c
--- /dev/null
+++ b/rb5/firmware/a650_zap.elf
Binary files differ
diff --git a/rb5/firmware/a650_zap.mbn b/rb5/firmware/a650_zap.mbn
new file mode 100644
index 0000000..ef5624c
--- /dev/null
+++ b/rb5/firmware/a650_zap.mbn
Binary files differ
diff --git a/rb5/firmware/a650_zap.mdt b/rb5/firmware/a650_zap.mdt
new file mode 100644
index 0000000..3c294a3
--- /dev/null
+++ b/rb5/firmware/a650_zap.mdt
Binary files differ
diff --git a/rb5/firmware/ath11k/QCA6390/hw2.0/Notice.txt b/rb5/firmware/ath11k/QCA6390/hw2.0/Notice.txt
new file mode 100644
index 0000000..d762020
--- /dev/null
+++ b/rb5/firmware/ath11k/QCA6390/hw2.0/Notice.txt
@@ -0,0 +1,1971 @@
+This Notice.txt file contains certain notices of software components included 
+with the software that Qualcomm Atheros, Inc. ("Qualcomm Atheros") is required
+to provide you. Except where prohibited by the open source license, the content 
+of this notices file is only provided to satisfy Qualcomm Atheros's attribution 
+and notice requirement; your use of these software components together with the 
+Qualcomm Atheros software (Qualcomm Atheros software hereinafter referred to 
+as "Software") is subject to the terms of your agreement from Qualcomm Atheros. 
+Compliance with all copyright laws and software license agreements included in 
+the notice section of this file are the responsibility of the user. Except as 
+may be granted by separate express written agreement, this file provides no 
+license to any patents, trademarks, copyrights, or other intellectual property 
+ 
+ 
+of Qualcomm Incorporated or any of its subsidiaries. 
+Qualcomm is a trademark of Qualcomm Incorporated, registered in the United States 
+and other countries. All Qualcomm Incorporated trademarks are used with permission. 
+Other products and brand names may be trademarks or registered trademarks of their 
+respective owners.
+ 
+NOTICES:
+ 
+=============================================================================
+
+* Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+* 2014 Qualcomm Atheros, Inc.
+* All Rights Reserved.
+* Confidential and Proprietary - Qualcomm Technologies, Inc.
+ *Notifications and licenses are retained for attribution purposes only *
+
+Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+// All rights reserved.
+// $ATH_LICENSE_NULL$
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer,
+//    without modification.
+// 2. Redistributions in binary form must reproduce at minimum a disclaimer
+//    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+//    redistribution must be conditioned upon including a substantially
+//    similar Disclaimer requirement for further binary redistribution.
+// 3. Neither the names of the above-listed copyright holders nor the names
+//    of any contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// Alternatively, this software may be distributed under the terms of the
+// GNU General Public License ("GPL") version 2 as published by the Free
+// Software Foundation.
+//
+// NO WARRANTY
+// 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 NONINFRINGEMENT, MERCHANTIBILITY
+// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+
+*For this file, which was received with alternative licensing options for  
+* distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+
+NOTICES:
+
+
+/*
+ * FILE:	sha2.c
+ * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) 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.
+ *
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/nan/sha2.c
+
+/*
+ * FILE:	sha2.h
+ * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) 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.
+ *
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/romexport/AR6320/hw.3/include/sha2.h
+
+/*
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/romexport/AR6320/hw.3/include/usb.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc. 
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * WPA Supplicant / wrapper functions for crypto libraries
+ * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ *
+ * This file defines the cryptographic functions that need to be implemented
+ * for wpa_supplicant and hostapd. When TLS is not used, internal
+ * implementation of MD5, SHA1, and AES is used and no external libraries are
+ * required. When TLS is enabled (e.g., by enabling EAP-TLS or EAP-PEAP), the
+ * crypto library used by the TLS implementation is expected to be used for
+ * non-TLS needs, too, in order to save space by not implementing these
+ * functions twice.
+ *
+ * Wrapper code for using each crypto library is in its own file (crypto*.c)
+ * and one of these files is build and linked in to provide the functions
+ * defined here.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/crypto.h
+
+/*
+ * Copyright 2016, 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.
+ */
+ p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/offloads/l2/bpf/bpf_filter.c
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * WPA Supplicant / Configuration file structures
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/config.h
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * WPA Supplicant - Common definitions
+ * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/suppl_auth_api.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * wpa_supplicant - WPA definitions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/wpa.h
+
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * wpa_supplicant - Internal WPA state machine definitions
+ * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/wpa_i.h
+
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * SHA256 hash implementation and interface functions
+ * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/sha256.h
+
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * WPA Supplicant - IEEE 802.11r - Fast BSS Transition
+ * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/mywpa_ft.h
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * SHA-256 hash implementation and interface functions
+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/sha256.c
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * WPA Supplicant - WPA state machine and EAPOL-Key processing
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/mywpa.c
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * WPA Supplicant - IEEE 802.11r - Fast BSS Transition
+ * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/mywpa_ft.c
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * WPA definitions shared between hostapd and wpa_supplicant
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/mywpa_common.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * MD5 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/include/md5_api.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * AES-based functions
+ *
+ * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * - One-Key CBC MAC (OMAC1) hash with AES-128
+ * - AES-128 CTR mode encryption
+ * - AES-128 EAX mode encryption/decryption
+ * - AES-128 CBC
+ *
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/romexport/AR6320/hw.3/include/aes_wrap.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/romexport/AR6320/hw.3/include/sha1.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * wpa_supplicant/hostapd / common helper functions, etc.
+ * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/romexport/AR6320/hw.3/include/common.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+/*
+ * Common helper macros, etc.
+ * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/romexport/AR6320/hw.3/include/seccommon.h
+
+/*
+ *  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
+ *  code or tables extracted from it, as desired without restriction.
+ *
+ *  First, the polynomial itself and its table of feedback terms.  The
+ *  polynomial is
+ *  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
+ *
+ *  Note that we take it "backwards" and put the highest-order term in
+ *  the lowest-order bit.  The X^32 term is "implied"; the LSB is the
+ *  X^31 term, etc.  The X^0 term (usually shown as "+1") results in
+ *  the MSB being 1
+ *
+ *  Note that the usual hardware shift register implementation, which
+ *  is what we're using (we're merely optimizing it by doing eight-bit
+ *  chunks at a time) shifts bits into the lowest-order term.  In our
+ *  implementation, that means shifting towards the right.  Why do we
+ *  do it this way?  Because the calculated CRC must be transmitted in
+ *  order from highest-order term to lowest-order term.  UARTs transmit
+ *  characters in order from LSB to MSB.  By storing the CRC this way
+ *  we hand it to the UART in the order low-byte to high-byte; the UART
+ *  sends each low-bit to hight-bit; and the result is transmission bit
+ *  by bit from highest- to lowest-order term without requiring any bit
+ *  shuffling on our part.  Reception works similarly
+ *
+ *  The feedback terms table consists of 256, 32-bit entries.  Notes
+ *
+ *      The table can be generated at runtime if desired; code to do so
+ *      is shown later.  It might not be obvious, but the feedback
+ *      terms simply represent the results of eight shift/xor opera
+ *      tions for all combinations of data and CRC register values
+ *
+ *      The values must be right-shifted by eight bits by the "updcrc
+ *      logic; the shift must be unsigned (bring in zeroes).  On some
+ *      hardware you could probably optimize the shift in assembler by
+ *      using byte-swap instructions
+ *      polynomial $edb88320
+ *
+ *
+ * CRC32 code derived from work by Gary S. Brown.
+*/
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/2.0/src/mgmt_txrx/ieee_crc32.c
+
+
+//
+// Copyright (c) 1991, 1993
+//  The Regents of the University of California.  All rights reserved.
+// $ATH_LICENSE_NULL$
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. 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.
+// 3. All advertising materials mentioning features or use of this software
+//    must display the following acknowledgement:
+//      This product includes software developed by the University of
+//      California, Berkeley and its contributors.
+// 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+//
+//  @(#)queue.h 8.5 (Berkeley) 8/20/94
+// $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $
+// $Id: //components/rel/wlanfw_cmn.cnss/1.0/cnss_proc/wlan/fwcommon/include/queue.h#1 $
+//
+p4://qctp411.qualcomm.com/components/rel/wlanfw_cmn.cnss/1.0.0/include/queue.h
+
+
+/*
+ * Copyright (c) 2012-2017 Qualcomm Technologies, Inc.
+ * 2012 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ */
+
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+//-
+// Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+// All rights reserved.
+// $ATH_LICENSE_NULL$
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer,
+//    without modification.
+// 2. Redistributions in binary form must reproduce at minimum a disclaimer
+//    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+//    redistribution must be conditioned upon including a substantially
+//    similar Disclaimer requirement for further binary redistribution.
+// 3. Neither the names of the above-listed copyright holders nor the names
+//    of any contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// Alternatively, this software may be distributed under the terms of the
+// GNU General Public License ("GPL") version 2 as published by the Free
+// Software Foundation.
+//
+// NO WARRANTY
+// 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 NONINFRINGEMENT, MERCHANTIBILITY
+// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+//
+// $Id: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/wlan/proto/include/if_llc.h#3 $
+// $NetBSD: if_llc.h,v 1.12 1999/11/19 20:41:19 thorpej Exp $
+// $Id: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/wlan/proto/include/if_llc.h#3 $
+//
+
+/*
+ * Copyright (c) 1988, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+ *
+ *      @(#)if_llc.h    8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_llc.h,v 1.9 2002/09/23 06:25:08 alfred Exp $
+ */
+                                                                             
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/if_llc.h
+
+/*
+ * Copyright (c) 2012-2017 Qualcomm Technologies, Inc.
+ * 2012 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ */
+
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+//-
+// Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+// All rights reserved.
+// $ATH_LICENSE_NULL$
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer,
+//    without modification.
+// 2. Redistributions in binary form must reproduce at minimum a disclaimer
+//    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+//    redistribution must be conditioned upon including a substantially
+//    similar Disclaimer requirement for further binary redistribution.
+// 3. Neither the names of the above-listed copyright holders nor the names
+//    of any contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// Alternatively, this software may be distributed under the terms of the
+// GNU General Public License ("GPL") version 2 as published by the Free
+// Software Foundation.
+//
+// NO WARRANTY
+// 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 NONINFRINGEMENT, MERCHANTIBILITY
+// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+//
+
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/if_ethersubr.h
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/patch/AR6320/v3/sha1_patch.c
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+ 
+/*
+ * WPA/RSN - Shared functions for supplicant and authenticator
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/mywpa_common.c
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+ 
+/*
+ * WPA definitions shared between hostapd and wpa_supplicant
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
+ 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/mywpa_common.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * $ATH_LICENSE_NULL$
+ */
+
+/*
+ * WPA Supplicant - ESE Fast Roaming with CCKM Enhancements
+ * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2010-2011, embWiSe Technologies
+ *
+ * Licensed under a proprietary license.
+ * Notifications and licenses are retained for attribution purposes only.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ */
+/*original files: ese_cckm.c and part of wpa_common.c in proprietary patch
+ * of open source supplicant */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/supplicant/mywpa_cckm.c
+
+/*
+ * Copyright (c) 2012-2017 Qualcomm Technologies, Inc.
+ * 2012 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ */
+
+/*
+ * For this file, which was received with alternative licensing options for   
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+//-
+// Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+// All rights reserved.
+// $ATH_LICENSE_NULL$
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer,
+//    without modification.
+// 2. Redistributions in binary form must reproduce at minimum a disclaimer
+//    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+//    redistribution must be conditioned upon including a substantially
+//    similar Disclaimer requirement for further binary redistribution.
+// 3. Neither the names of the above-listed copyright holders nor the names
+//    of any contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// Alternatively, this software may be distributed under the terms of the
+// GNU General Public License ("GPL") version 2 as published by the Free
+// Software Foundation.
+//
+// NO WARRANTY
+// 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 NONINFRINGEMENT, MERCHANTIBILITY
+// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+//
+// $Id: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/wlan/proto/include/if_llc.h#3 $
+// $NetBSD: if_llc.h,v 1.12 1999/11/19 20:41:19 thorpej Exp $
+// $Id: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/wlan/proto/include/if_llc.h#3 $
+//
+
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+ *
+ *	@(#)if_llc.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_llc.h,v 1.9 2002/09/23 06:25:08 alfred Exp $
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/if_llc.h
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * AES (Rijndael) cipher
+ *
+ * Modifications to public domain implementation:
+ * - support only 128-bit keys
+ * - cleanup
+ * - use C pre-processor to make it easier to change S table access
+ * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
+ *   cost of reduced throughput (quite small difference on Pentium 4,
+ *   10-25% when using -O1 or -O2 optimization)
+ *
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+/*
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS 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.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/misc/crypto/aes.c
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * AES-based functions
+ *
+ * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * - One-Key CBC MAC (OMAC1) hash with AES-128
+ * - AES-128 CTR mode encryption
+ * - AES-128 EAX mode encryption/decryption
+ * - AES-128 CBC
+ *
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/misc/crypto/aes_wrap.c
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/misc/crypto/sha1.c
+
+/*
+ * Copyright (c) 2013 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/src/wmi/wmi_tlv_platform.c
+
+/*
+ * Copyright (c) 2012, Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_protocol_cmn.cnss/1.0.0/include/qvit/qvit_init_api.h
+
+/*
+ * Copyright (c) 2013 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_cmn.cnss/1.0.0/fw_interface/include/wmi_version_whitelist.c
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc. 
+ * $ATH_LICENSE_TARGET_C$
+ */
+
+//
+// $Id: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/misc/crypto/md5.c#3 $
+//
+// This code implements the MD5 message-digest algorithm.
+// The algorithm is due to Ron Rivest.  This code was
+// written by Colin Plumb in 1993, no copyright is claimed.
+// This code is in the public domain; do with it what you wish.
+//
+// Equivalent code is available from RSA Data Security, Inc.
+// This code has been tested against that, and is equivalent,
+// except that you don't need to include two pages of legalese
+// with every copy.
+//
+// To compute the message digest of a chunk of bytes, declare an
+// MD5Context structure, pass it to MD5Init, call MD5Update as
+// needed on buffers full of bytes, and then call MD5Final, which
+// will fill a supplied 16-byte array with the digest.
+//
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/misc/crypto/md5.c
+
+
+/*===========================================================================
+  @file secrsa_encryption.c
+  
+   This file provides RSA PKCS #1 v1.5 encryption/decryption implementation.
+  ===========================================================================
+
+                           EDIT HISTORY FOR FILE
+  $Header: //components/dev/wlanfw.cnss/1.0.1/dennis.rome_emu_es2_rel_fw/cnss_proc/wlan/fw/target/src/misc/binsig/rsa.c#2 $
+  $DateTime: 2013/10/21 08:09:59 $ 
+  $Author: changhon $
+
+  when       who     what, where, why
+  --------   ---     ----------------------------------------------------------
+  04/11/11   qxu     initial version
+
+  Copyright (c) 2011 by QUALCOMM Technologies, Incorporated.  All Rights Reserved.
+  =============================================================================*/
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/misc/binsig/rsa.c
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/include/cil.h $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/include/cil.h
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/include/dev.h $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/include/dev.h
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/include/pcd.h $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/include/pcd.h
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/soc/usbhwcore/drv/snps/cil.c $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+
+/** @file
+ *
+ * The Core Interface Layer provides basic services for accessing and
+ * managing the DWC_usb3 hardware. These services are used by both the
+ * Peripheral Controller Driver and the On The Go Driver.
+ *
+ * The CIL manages the memory map for the core so that the PCD and OTG drivers
+ * don't have to do this separately. The CIL also performs basic services
+ * that are not specific to either the Device or OTG modes of operation.
+ * These services include all functionality that requires specific
+ * knowledge of the CSR layout or the DMA descriptor (TRB) layout. Also
+ * included are services for invoking each of the commands provided by
+ * the DGCMD and DEPCMD registers (see the "Control and Status Registers"
+ * chapter of the USB3 controller databook for details).
+ *
+ * The Core Interface Layer has the following requirements:
+ * - Provides basic controller operations.
+ * - Minimal use of OS services.
+ * - The OS services used will be abstracted by using inline functions
+ *   or macros.
+ *
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/soc/usbhwcore/drv/snps/cil.c
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/soc/usbhwcore/drv/snps/pcd_intr.c $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+
+/** @file
+ * This file contains the implementation of the PCD Interrupt handlers.
+ *
+ * The PCD handles the device interrupts. Many conditions can cause a
+ * device interrupt. When an interrupt occurs, the device interrupt
+ * service routine determines the cause of the interrupt and
+ * dispatches handling to the appropriate routine. These interrupt
+ * handling routines are described below.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/soc/usbhwcore/drv/snps/pcd_intr.c
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/include/os_dev.h $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/include/os_dev.h
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/soc/usbhwcore/drv/snps/cil_intr.c $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+
+/** @file
+ *
+ * The Core Interface Layer provides basic services for accessing and
+ * managing the DWC_usb3 hardware. These services are used by both the
+ * Peripheral Controller Driver and the On The Go Driver.
+ *
+ * This file contains the common interrupt handling functions.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/soc/usbhwcore/drv/snps/cil_intr.c
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/soc/usbhwcore/drv/snps/pcd.c $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+
+/** @file
+ * This file implements the Peripheral Controller Driver.
+ *
+ * The Peripheral Controller Driver (PCD) is responsible for translating
+ * requests from the Function Driver into the appropriate actions on the
+ * DWC_usb3 controller. It isolates the Function Driver from the specifics
+ * of the controller by providing an API to the Function Driver.
+ *
+ * The Peripheral Controller Driver for Linux will implement the Gadget API,
+ * so that the existing Gadget drivers can be used. (Gadget Driver is the
+ * Linux terminology for a Function Driver.)
+ *
+ * The Linux Gadget API is defined in the header file
+ * <code><linux/usb/gadget.h></code>. The USB EP operations API is defined
+ * in the structure <code>usb_ep_ops</code> and the USB Controller API is
+ * defined in the structure <code>usb_gadget_ops</code>.
+ *
+ * An important function of the PCD is managing interrupts generated by the
+ * DWC_usb3 controller. The implementation of the DWC_usb3 device mode
+ * interrupt service routines is in pcd_intr.c.
+ */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/src/soc/usbhwcore/drv/snps/pcd.c
+
+/* ==========================================================================
+ * $File: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/include/usb3_hw.h $
+ * $Revision: #3 $
+ * $Date: 2013/08/06 $
+ * $Change: 2161544 $
+ *
+ * Synopsys SS USB3 Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+p4://qctp411.qualcomm.com/components/rel/wlanfw_mac_core.cnss/1.0/include/usb3_hw.h
+
+
+
+
+
+==================================================================================
+
+Open source code.
+Component Name: <COMMON NAME>
+Component Version: <ACTUAL VERSION USED>
+Source: <PACKAGE/URL>
+License: 
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+ 
+ ====================================================================================
+ 
+ Open source code.
+ Component Name: <COMMON NAME>
+ Component Version: <ACTUAL VERSION USED>
+ Source: <PACKAGE/URL>
+ License: /*
+  * Copyright (c) 2012-2017 Qualcomm Technologies, Inc.
+  * 2012 Qualcomm Atheros, Inc.
+  * All Rights Reserved.
+  * Confidential and Proprietary - Qualcomm Technologies, Inc.
+  */
+ 
+ /*
+  * For this file, which was received with alternative licensing options for   
+  * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+  */
+ 
+ //-
+ // Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+ // All rights reserved.
+ // $ATH_LICENSE_NULL$
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions
+ // are met:
+ // 1. Redistributions of source code must retain the above copyright
+ //    notice, this list of conditions and the following disclaimer,
+ //    without modification.
+ // 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ //    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ //    redistribution must be conditioned upon including a substantially
+ //    similar Disclaimer requirement for further binary redistribution.
+ // 3. Neither the names of the above-listed copyright holders nor the names
+ //    of any contributors may be used to endorse or promote products derived
+ //    from this software without specific prior written permission.
+ //
+ // Alternatively, this software may be distributed under the terms of the
+ // GNU General Public License ("GPL") version 2 as published by the Free
+ // Software Foundation.
+ //
+ // NO WARRANTY
+ // 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 NONINFRINGEMENT, MERCHANTIBILITY
+ // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ //
+ // $Id: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/wlan/proto/include/if_ethersubr.h#3 $
+//
+
+===============================================================================================================
+
+/*
+ * Copyright (c) 2014-2017 Qualcomm Technologies, Inc.
+ * 2014 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+ 
+ ===========================================================================
+ 
+ /*
+  * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+  * 2011 Qualcomm Atheros, Inc.
+  * All Rights Reserved.
+  * Confidential and Proprietary - Qualcomm Technologies, Inc.
+  * Notifications and licenses are retained for attribution purposes only.
+  */
+ /*
+  * For this file, which was received with alternative licensing options for
+  * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+  */
+ 
+ /*
+  * AES-based functions
+  *
+  * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+  * - One-Key CBC MAC (OMAC1) hash with AES-128
+  * - AES-128 CTR mode encryption
+  * - AES-128 EAX mode encryption/decryption
+  * - AES-128 CBC
+  *
+  * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+  * Alternatively, this software may be distributed under the terms of BSD
+  * license.
+  *
+  * See README and COPYING for more details.
+ */
+ 
+ ==============================================================================
+ 
+ /*
+  * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+  * 2011 Qualcomm Atheros, Inc.
+  * All Rights Reserved.
+  * Confidential and Proprietary - Qualcomm Technologies, Inc.
+  * Notifications and licenses are retained for attribution purposes only.
+  */
+ /*
+  * For this file, which was received with alternative licensing options for
+  * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+  */
+ 
+ /*
+  * wpa_supplicant/hostapd / common helper functions, etc.
+  * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+  * Alternatively, this software may be distributed under the terms of BSD
+  * license.
+  *
+  * See README and COPYING for more details.
+ */
+ 
+ ==========================================================================
+ 
+ 
+ /*
+  * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+  * 2011 Qualcomm Atheros, Inc.
+  * All Rights Reserved.
+  * Confidential and Proprietary - Qualcomm Technologies, Inc.
+  * Notifications and licenses are retained for attribution purposes only.
+  */
+ /*
+  * For this file, which was received with alternative licensing options for
+  * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+  */
+ 
+ /*
+  * WPA Supplicant / wrapper functions for crypto libraries
+  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+  * Alternatively, this software may be distributed under the terms of BSD
+  * license.
+  *
+  * See README and COPYING for more details.
+  *
+  * This file defines the cryptographic functions that need to be implemented
+  * for wpa_supplicant and hostapd. When TLS is not used, internal
+  * implementation of MD5, SHA1, and AES is used and no external libraries are
+  * required. When TLS is enabled (e.g., by enabling EAP-TLS or EAP-PEAP), the
+  * crypto library used by the TLS implementation is expected to be used for
+  * non-TLS needs, too, in order to save space by not implementing these
+  * functions twice.
+  *
+  * Wrapper code for using each crypto library is in its own file (crypto*.c)
+  * and one of these files is build and linked in to provide the functions
+  * defined here.
+ */
+ 
+ ===============================================================================
+ 
+ /*
+  * Copyright (c) 2012-2017 Qualcomm Technologies, Inc.
+  * 2011 Qualcomm Atheros, Inc.
+  * All Rights Reserved.
+  * Confidential and Proprietary - Qualcomm Technologies, Inc.
+  */
+ 
+ /*
+  * For this file, which was received with alternative licensing options for   
+  * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+  */
+ 
+ //-
+ // Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+ // All rights reserved.
+ // $ATH_LICENSE_NULL$
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions
+ // are met:
+ // 1. Redistributions of source code must retain the above copyright
+ //    notice, this list of conditions and the following disclaimer,
+ //    without modification.
+ // 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ //    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ //    redistribution must be conditioned upon including a substantially
+ //    similar Disclaimer requirement for further binary redistribution.
+ // 3. Neither the names of the above-listed copyright holders nor the names
+ //    of any contributors may be used to endorse or promote products derived
+ //    from this software without specific prior written permission.
+ //
+ // Alternatively, this software may be distributed under the terms of the
+ // GNU General Public License ("GPL") version 2 as published by the Free
+ // Software Foundation.
+ //
+ // NO WARRANTY
+ // 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 NONINFRINGEMENT, MERCHANTIBILITY
+ // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ //
+ // $Id: //components/rel/wlanfw.cnss/1.0.1/cnss_proc/wlan/fw/target/src/wlan/proto/include/if_ethersubr.h#3 $
+//
+
+===============================================================================================================
+
+/*
+ * Copyright (c) 2011-2017 Qualcomm Technologies, Inc.
+ * 2011 Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Confidential and Proprietary - Qualcomm Technologies, Inc.
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * For this file, which was received with alternative licensing options for
+ * distribution, Qualcomm Atheros, Inc. has selected the BSD license.
+ */
+
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+ 
+ =============================================================================
+
diff --git a/rb5/firmware/ath11k/QCA6390/hw2.0/amss.bin b/rb5/firmware/ath11k/QCA6390/hw2.0/amss.bin
new file mode 100644
index 0000000..1d9d34a
--- /dev/null
+++ b/rb5/firmware/ath11k/QCA6390/hw2.0/amss.bin
Binary files differ
diff --git a/rb5/firmware/ath11k/QCA6390/hw2.0/board.bin b/rb5/firmware/ath11k/QCA6390/hw2.0/board.bin
new file mode 100644
index 0000000..fac5963
--- /dev/null
+++ b/rb5/firmware/ath11k/QCA6390/hw2.0/board.bin
Binary files differ
diff --git a/rb5/firmware/ath11k/QCA6390/hw2.0/m3.bin b/rb5/firmware/ath11k/QCA6390/hw2.0/m3.bin
new file mode 100644
index 0000000..1ffaab0
--- /dev/null
+++ b/rb5/firmware/ath11k/QCA6390/hw2.0/m3.bin
Binary files differ
diff --git a/rb5/firmware/device.mk b/rb5/firmware/device.mk
new file mode 100644
index 0000000..e4f0c3a
--- /dev/null
+++ b/rb5/firmware/device.mk
@@ -0,0 +1,34 @@
+# Copy firmware files
+
+PRODUCT_COPY_FILES := \
+    $(LOCAL_PATH)/a650_gmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_gmu.bin			\
+    $(LOCAL_PATH)/a650_sqe.fw:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_sqe.fw			\
+    $(LOCAL_PATH)/a650_zap.b00:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_zap.b00			\
+    $(LOCAL_PATH)/a650_zap.b01:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_zap.b01			\
+    $(LOCAL_PATH)/a650_zap.b02:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_zap.b02			\
+    $(LOCAL_PATH)/a650_zap.elf:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_zap.elf			\
+    $(LOCAL_PATH)/a650_zap.mbn:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_zap.mbn			\
+    $(LOCAL_PATH)/a650_zap.mdt:$(TARGET_COPY_OUT_VENDOR)/firmware/a650_zap.mdt			\
+    $(LOCAL_PATH)/lt9611uxc_fw.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/lt9611uxc_fw.bin		\
+    $(LOCAL_PATH)/a650_gmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_gmu.bin	\
+    $(LOCAL_PATH)/a650_sqe.fw:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_sqe.fw	\
+    $(LOCAL_PATH)/a650_zap.b00:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_zap.b00	\
+    $(LOCAL_PATH)/a650_zap.b01:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_zap.b01	\
+    $(LOCAL_PATH)/a650_zap.b02:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_zap.b02	\
+    $(LOCAL_PATH)/a650_zap.elf:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_zap.elf	\
+    $(LOCAL_PATH)/a650_zap.mbn:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_zap.mbn	\
+    $(LOCAL_PATH)/a650_zap.mdt:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/a650_zap.mdt
+
+PRODUCT_COPY_FILES += \
+    $(LOCAL_PATH)/qcom/sm8250/adsp.mbn:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/adsp.mbn		\
+    $(LOCAL_PATH)/qcom/sm8250/adspr.jsn:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/adspr.jsn	\
+    $(LOCAL_PATH)/qcom/sm8250/adspua.jsn:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/adspua.jsn	\
+    $(LOCAL_PATH)/qcom/sm8250/cdsp.mbn:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/cdsp.mbn		\
+    $(LOCAL_PATH)/qcom/sm8250/cdspr.jsn:$(TARGET_COPY_OUT_VENDOR)/firmware/qcom/sm8250/cdspr.jsn
+
+PRODUCT_COPY_FILES += \
+    $(LOCAL_PATH)/ath11k/QCA6390/hw2.0/amss.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/ath11k/QCA6390/hw2.0/amss.bin	\
+    $(LOCAL_PATH)/ath11k/QCA6390/hw2.0/board.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/ath11k/QCA6390/hw2.0/board.bin	\
+    $(LOCAL_PATH)/ath11k/QCA6390/hw2.0/m3.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/ath11k/QCA6390/hw2.0/m3.bin		\
+    $(LOCAL_PATH)/qca/htbtfw20.tlv:$(TARGET_COPY_OUT_VENDOR)/firmware/qca/htbtfw20.tlv					\
+    $(LOCAL_PATH)/qca/htnv20.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/qca/htnv20.bin
diff --git a/rb5/firmware/lt9611uxc_fw.bin b/rb5/firmware/lt9611uxc_fw.bin
new file mode 100644
index 0000000..c6398d2
--- /dev/null
+++ b/rb5/firmware/lt9611uxc_fw.bin
Binary files differ
diff --git a/rb5/firmware/qca/htbtfw20.tlv b/rb5/firmware/qca/htbtfw20.tlv
new file mode 100644
index 0000000..f7d8aa9
--- /dev/null
+++ b/rb5/firmware/qca/htbtfw20.tlv
Binary files differ
diff --git a/rb5/firmware/qca/htnv20.bin b/rb5/firmware/qca/htnv20.bin
new file mode 100644
index 0000000..61732d4
--- /dev/null
+++ b/rb5/firmware/qca/htnv20.bin
Binary files differ
diff --git a/rb5/firmware/qcom/sm8250/adsp.mbn b/rb5/firmware/qcom/sm8250/adsp.mbn
new file mode 100644
index 0000000..274cb40
--- /dev/null
+++ b/rb5/firmware/qcom/sm8250/adsp.mbn
Binary files differ
diff --git a/rb5/firmware/qcom/sm8250/adspr.jsn b/rb5/firmware/qcom/sm8250/adspr.jsn
new file mode 100644
index 0000000..0964c15
--- /dev/null
+++ b/rb5/firmware/qcom/sm8250/adspr.jsn
@@ -0,0 +1,21 @@
+{
+    "sr_version": {
+        "major": 1,
+        "minor": 1,
+        "patch": 1
+    },
+    "sr_domain": {
+        "soc": "msm",
+        "domain": "adsp",
+        "subdomain": "root_pd",
+        "qmi_instance_id": 74
+    },
+    "sr_service": [
+        {
+            "provider": "tms",
+            "service": "servreg",
+            "service_data_valid": 0,
+            "service_data": 0
+        }
+    ]
+}
\ No newline at end of file
diff --git a/rb5/firmware/qcom/sm8250/adspua.jsn b/rb5/firmware/qcom/sm8250/adspua.jsn
new file mode 100644
index 0000000..2d6824e
--- /dev/null
+++ b/rb5/firmware/qcom/sm8250/adspua.jsn
@@ -0,0 +1,27 @@
+{
+    "sr_version": {
+        "major": 1,
+        "minor": 1,
+        "patch": 1
+    },
+    "sr_domain": {
+        "soc": "msm",
+        "domain": "adsp",
+        "subdomain": "audio_pd",
+        "qmi_instance_id": 74
+    },
+    "sr_service": [
+        {
+            "provider": "tms",
+            "service": "servreg",
+            "service_data_valid": 0,
+            "service_data": 0
+        },
+        {
+            "provider": "avs",
+            "service": "audio",
+            "service_data_valid": 0,
+            "service_data": 0
+        }
+    ]
+}
\ No newline at end of file
diff --git a/rb5/firmware/qcom/sm8250/cdsp.mbn b/rb5/firmware/qcom/sm8250/cdsp.mbn
new file mode 100644
index 0000000..f8b6653
--- /dev/null
+++ b/rb5/firmware/qcom/sm8250/cdsp.mbn
Binary files differ
diff --git a/rb5/firmware/qcom/sm8250/cdspr.jsn b/rb5/firmware/qcom/sm8250/cdspr.jsn
new file mode 100644
index 0000000..5d976a6
--- /dev/null
+++ b/rb5/firmware/qcom/sm8250/cdspr.jsn
@@ -0,0 +1,21 @@
+{
+    "sr_version": {
+        "major": 1,
+        "minor": 1,
+        "patch": 1
+    },
+    "sr_domain": {
+        "soc": "msm",
+        "domain": "cdsp",
+        "subdomain": "root_pd",
+        "qmi_instance_id": 76
+    },
+    "sr_service": [
+        {
+            "provider": "tms",
+            "service": "servreg",
+            "service_data_valid": 0,
+            "service_data": 0
+        }
+    ]
+}
\ No newline at end of file
diff --git a/rb5/mixer_paths.xml b/rb5/mixer_paths.xml
new file mode 100644
index 0000000..86e67fc
--- /dev/null
+++ b/rb5/mixer_paths.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<mixer>
+	<!-- Enable HDMI out -->
+	<ctl name="TERT_MI2S_RX Audio Mixer MultiMedia1" value="1" />
+</mixer>
diff --git a/sepolicy/file.te b/sepolicy/file.te
index 4a0ada7..54de779 100644
--- a/sepolicy/file.te
+++ b/sepolicy/file.te
@@ -2,6 +2,7 @@
 type sysfs_mss, fs_type, sysfs_type;
 type sysfs_rmtfs, fs_type, sysfs_type;
 type sysfs_remoteproc, fs_type, sysfs_type;
+type sysfs_udc, fs_type, sysfs_type;
 type dri_device, dev_type;
 type rmtfs_device, dev_type;
 type modem_block_device, dev_type;
diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts
index bc69fcc..1022689 100644
--- a/sepolicy/file_contexts
+++ b/sepolicy/file_contexts
@@ -4,7 +4,7 @@
 /dev/block/platform/soc@0/1d84000\.ufshc/by-name/metadata	u:object_r:metadata_block_device:s0
 /dev/block/platform/soc@0/1d84000\.ufshc/by-name/super		u:object_r:super_block_device:s0
 /dev/block/platform/soc@0/1d84000\.ufshc/by-name/userdata	u:object_r:userdata_block_device:s0
-/dev/block/platform/soc@0/1d84000\.ufshc/by-name/cache		u:object_r:cache_block_device:s0
+/dev/block/platform/soc@0/1d84000\.ufshc/by-name/misc		u:object_r:misc_block_device:s0
 
 /dev/dri				u:object_r:dri_device:s0
 /dev/dri/card0				u:object_r:graphics_device:s0
@@ -13,16 +13,35 @@
 /dev/ttyMSM0				u:object_r:console_device:s0
 
 /sys/bus/platform/drivers/qcom-q6v5-mss							u:object_r:sysfs_mss:s0
+/sys/module/qcom_q6v5_mss								u:object_r:sysfs_mss:s0
 /sys/devices/platform/88f00000.memory/rmtfs						u:object_r:sysfs_rmtfs:s0
 
 /sys/devices/platform/soc@0/4080000.remoteproc						u:object_r:sysfs_remoteproc:s0
+/sys/devices/platform/soc@0/8300000.remoteproc						u:object_r:sysfs_remoteproc:s0
+/sys/devices/platform/soc@0/17300000.remoteproc						u:object_r:sysfs_remoteproc:s0
 /sys/devices/platform/soc@0/ae00000.mdss						u:object_r:sysfs_gpu:s0
-/sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/rtc	u:object_r:sysfs_rtc:s0
+
+#wakeups on db845c
+/sys/devices/platform/soc@0/1c00000.pci/pci0000:00/0000:00:00.0/0000:01:00.0/wakeup/wakeup1						u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/a6f8800.usb/wakeup/wakeup2											u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/a8f8800.usb/wakeup/wakeup3											u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:pon@800/c440000.spmi:pmic@0:pon@800:pwrkey/wakeup/wakeup4	u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:pon@800/c440000.spmi:pmic@0:pon@800:resin/wakeup/wakeup5	u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/wakeup/wakeup6					u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/rtc/rtc0/alarmtimer.2.auto/wakeup/wakeup7		u:object_r:sysfs_wakeup:s0
+
+#wakeups on RB5
+/sys/devices/platform/soc@0/a6f8800.usb/wakeup/wakeup0											u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/a8f8800.usb/wakeup/wakeup1											u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/wakeup/wakeup3					u:object_r:sysfs_wakeup:s0
+/sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/rtc/rtc0/alarmtimer.1.auto/wakeup/wakeup4		u:object_r:sysfs_wakeup:s0
 
 /sys/class/remoteproc									u:object_r:sysfs_remoteproc:s0
 /sys/devices/platform/remoteproc-adsp/remoteproc					u:object_r:sysfs_remoteproc:s0
 /sys/devices/platform/remoteproc-cdsp/remoteproc					u:object_r:sysfs_remoteproc:s0
 
+/sys/class/udc										u:object_r:sysfs_udc:s0
+
 /data/vendor/tmp(/.*)?									u:object_r:tqftpserv_vendor_data_file:s0
 /data/vendor/readwrite(/.*)?								u:object_r:tqftpserv_vendor_data_file:s0
 /data/vendor/readonly(/.*)?								u:object_r:tqftpserv_vendor_data_file:s0
@@ -30,17 +49,25 @@
 /system/bin/eth_mac_addr\.sh								u:object_r:eth_mac_addr_exec:s0
 /system/bin/tinymix									u:object_r:tinymix_exec:s0
 
+/vendor/bin/grep									u:object_r:vendor_toolbox_exec:s0
 /vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service\.software			u:object_r:hal_gatekeeper_default_exec:s0
+/vendor/bin/hw/android\.hardware\.graphics\.allocator@4\.0-service\.minigbm_msm		u:object_r:hal_graphics_allocator_default_exec:s0
 /vendor/bin/pd-mapper									u:object_r:pd_mapper_exec:s0
 /vendor/bin/qrtr-cfg									u:object_r:qrtr_exec:s0
 /vendor/bin/qrtr-ns									u:object_r:qrtr_exec:s0
 /vendor/bin/rmtfs									u:object_r:rmtfs_exec:s0
 /vendor/bin/tqftpserv									u:object_r:tqftpserv_exec:s0
+/vendor/bin/suspend_blocker								u:object_r:suspend_blocker_exec:s0
+/vendor/bin/set_udc\.sh									u:object_r:set_udc_exec:s0
 
 /vendor/lib(64)?/dri/.*									u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/hw/gralloc\.gbm\.so							u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/hw/android\.hardware\.health@2\.0-impl-2\.1-cuttlefish\.so		u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/hw/gralloc\.minigbm_msm\.so						u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/hw/android\.hardware\.graphics\.mapper@4\.0-impl\.minigbm_msm\.so	u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libdrm\.so								u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libdrm_freedreno\.so							u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libgbm_mesa\.so							u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libglapi\.so								u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libminigbm_gralloc_msm\.so						u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libqrtr\.so								u:object_r:same_process_hal_file:s0
diff --git a/sepolicy/genfs_contexts b/sepolicy/genfs_contexts
index ee8b953..95ce0cc 100644
--- a/sepolicy/genfs_contexts
+++ b/sepolicy/genfs_contexts
@@ -2,5 +2,22 @@
 genfscon sysfs   /devices/platform/remoteproc-adsp/remoteproc					u:object_r:sysfs_remoteproc:s0
 genfscon sysfs   /devices/platform/remoteproc-cdsp/remoteproc					u:object_r:sysfs_remoteproc:s0
 genfscon sysfs   /devices/platform/soc@0/4080000.remoteproc					u:object_r:sysfs_remoteproc:s0
+genfscon sysfs   /devices/platform/soc@0/8300000.remoteproc					u:object_r:sysfs_remoteproc:s0
+genfscon sysfs   /devices/platform/soc@0/17300000.remoteproc					u:object_r:sysfs_remoteproc:s0
 genfscon sysfs   /devices/platform/soc@0/ae00000.mdss						u:object_r:sysfs_gpu:s0
-genfscon sysfs   /devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000	u:object_r:sysfs_rtc:s0
+genfscon sysfs   /class/udc									u:object_r:sysfs_udc:s0
+
+#wakeups on db845c
+genfscon sysfs   /devices/platform/soc@0/1c00000.pci/pci0000:00/0000:00:00.0/0000:01:00.0/wakeup/wakeup1					u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/a6f8800.usb/wakeup/wakeup2										u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/a8f8800.usb/wakeup/wakeup3										u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:pon@800/c440000.spmi:pmic@0:pon@800:pwrkey/wakeup/wakeup4	u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:pon@800/c440000.spmi:pmic@0:pon@800:resin/wakeup/wakeup5	u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/wakeup/wakeup6					u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/rtc/rtc0/alarmtimer.2.auto/wakeup/wakeup7	u:object_r:sysfs_wakeup:s0
+
+#wakeups on RB5
+genfscon sysfs   /devices/platform/soc@0/a6f8800.usb/wakeup/wakeup0										u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/a8f8800.usb/wakeup/wakeup1										u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/wakeup/wakeup3					u:object_r:sysfs_wakeup:s0
+genfscon sysfs   /devices/platform/soc@0/c440000.spmi/spmi-0/0-00/c440000.spmi:pmic@0:rtc@6000/rtc/rtc0/alarmtimer.1.auto/wakeup/wakeup4	u:object_r:sysfs_wakeup:s0
diff --git a/sepolicy/hal_camera.te b/sepolicy/hal_camera.te
new file mode 100644
index 0000000..6bbc346
--- /dev/null
+++ b/sepolicy/hal_camera.te
@@ -0,0 +1,15 @@
+vndbinder_use(hal_camera_default);
+
+allow hal_camera_default hal_graphics_mapper_hwservice:hwservice_manager find;
+hal_client_domain(hal_camera_default, hal_graphics_allocator);
+hal_client_domain(hal_camera_default, hal_graphics_composer);
+
+# for external camera
+allow cameraserver device:dir r_dir_perms;
+allow cameraserver video_device:dir r_dir_perms;
+allow cameraserver video_device:chr_file rw_file_perms;
+
+allow hal_camera_default gpu_device:chr_file { open read write ioctl map getattr };
+allow hal_camera_default dri_device:dir { open read search };
+allow cameraserver dri_device:dir { open read write search getattr };
+allow cameraserver gpu_device:chr_file { open read write ioctl map getattr };
diff --git a/sepolicy/hal_graphics_composer.te b/sepolicy/hal_graphics_composer.te
index 40dbe25..cc45ebf 100644
--- a/sepolicy/hal_graphics_composer.te
+++ b/sepolicy/hal_graphics_composer.te
@@ -1 +1,3 @@
+allow hal_graphics_composer_server hal_graphics_allocator_default_tmpfs:file read;
+
 gpu_access(hal_graphics_composer_server)
diff --git a/sepolicy/hal_graphics_composer_default.te b/sepolicy/hal_graphics_composer_default.te
index 9c310f6..56e03aa 100644
--- a/sepolicy/hal_graphics_composer_default.te
+++ b/sepolicy/hal_graphics_composer_default.te
@@ -1,3 +1,8 @@
+hal_client_domain(hal_graphics_composer_default, hal_graphics_allocator);
 vndbinder_use(hal_graphics_composer_default)
 
 allow hal_graphics_composer_default self:netlink_kobject_uevent_socket { bind create read };
+
+# Suppress warnings for drm_hwcomposer trying to read some vendor.hwc.*
+# properties as dragonboard never configures these properties.
+dontaudit hal_graphics_composer_default default_prop:file read;
diff --git a/sepolicy/mediacodec.te b/sepolicy/mediacodec.te
new file mode 100644
index 0000000..6119c90
--- /dev/null
+++ b/sepolicy/mediacodec.te
@@ -0,0 +1 @@
+gpu_access(mediacodec)
diff --git a/sepolicy/property_contexts b/sepolicy/property_contexts
new file mode 100644
index 0000000..0d68bd3
--- /dev/null
+++ b/sepolicy/property_contexts
@@ -0,0 +1 @@
+vendor.usb.controller  u:object_r:vendor_usb_prop:s0
diff --git a/sepolicy/set_udc.te b/sepolicy/set_udc.te
new file mode 100644
index 0000000..d810bd2
--- /dev/null
+++ b/sepolicy/set_udc.te
@@ -0,0 +1,11 @@
+type set_udc, domain;
+type set_udc_exec, exec_type, vendor_file_type, file_type;
+init_daemon_domain(set_udc);
+
+vendor_public_prop(vendor_usb_prop)
+set_prop(set_udc, vendor_usb_prop)
+get_prop(vendor_init, vendor_usb_prop)
+
+allow set_udc vendor_shell_exec:file rx_file_perms;
+allow set_udc vendor_toolbox_exec:file rx_file_perms;
+allow set_udc sysfs_udc:dir { open read search };
diff --git a/sepolicy/suspend_blocker.te b/sepolicy/suspend_blocker.te
new file mode 100644
index 0000000..fa6e02a
--- /dev/null
+++ b/sepolicy/suspend_blocker.te
@@ -0,0 +1,6 @@
+type suspend_blocker, domain;
+type suspend_blocker_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(suspend_blocker);
+
+wakelock_use(suspend_blocker);
diff --git a/sepolicy/te_macros b/sepolicy/te_macros
index 3123f6b..a50bec1 100644
--- a/sepolicy/te_macros
+++ b/sepolicy/te_macros
@@ -4,6 +4,7 @@
 define(`gpu_access', `
 allow $1 dri_device:dir { open read search };
 allow $1 sysfs_gpu:dir search;
+allow $1 gpu_device:chr_file { getattr ioctl map open read write };
+allow $1 graphics_device:chr_file { getattr };
 allow $1 sysfs_gpu:file { getattr open read };
-dontaudit $1 graphics_device:chr_file getattr;
 ')
diff --git a/ueventd.common.rc b/ueventd.common.rc
index b87dccf..8ae7d94 100644
--- a/ueventd.common.rc
+++ b/ueventd.common.rc
@@ -1,4 +1,5 @@
-modalias_handling enabled
+subsystem usbmisc
+    devname uevent_devname
 
 /dev/sw_sync              0660   root       graphics
 
@@ -8,3 +9,7 @@
 
 # media.codec2
 /dev/ion 0664 system system
+
+# usb webcam?
+/dev/video0 0660 system camera
+/dev/video1 0660 system camera